Bug Summary

File:programs/Utilities/hddm_merge_events/hddm_merge_events.cc
Location:line 89, column 42
Description:Dereference of null pointer

Annotated Source Code

1// $Id: mcsmear.cc 2388 2007-01-10 16:46:03Z davidl $
2//
3// Created June 22, 2005 David Lawrence
4
5#include <iostream>
6#include <iomanip>
7#include <vector>
8using namespace std;
9
10#include <signal.h>
11#include <time.h>
12
13#include "HDDM/hddm_s.h"
14
15void Smear(s_HDDM_t *hddm_s);
16void ParseCommandLineArguments(int narg, char* argv[]);
17void Usage(void);
18void ctrlCHandle(int x);
19
20vector<int> Nevents_to_merge;
21vector<bool> loop_source;
22vector<char*> INFILENAMES;
23char *OUTFILENAME = NULL__null;
24int QUIT = 0;
25int MAXEVENTS=-1;
26
27
28#define _DBG_cout<<"hddm_merge_events.cc"<<":"<<28<<
" "
cout<<__FILE__"hddm_merge_events.cc"<<":"<<__LINE__28<<" "
29#define _DBG__cout<<"hddm_merge_events.cc"<<":"<<29<<
endl
cout<<__FILE__"hddm_merge_events.cc"<<":"<<__LINE__29<<endl
30
31
32//-----------
33// main
34//-----------
35int main(int narg,char* argv[])
36{
37 // Set up to catch SIGINTs for graceful exits
38 signal(SIGINT2,ctrlCHandle);
39
40 ParseCommandLineArguments(narg, argv);
41
42 // Dummy check
43 if(Nevents_to_merge.size() != INFILENAMES.size()){
1
Taking false branch
44 _DBG_cout<<"hddm_merge_events.cc"<<":"<<44<<
" "
<<"Size of Nevents_to_merge and INFILENAMES vectors not the same!"<<endl;
45 _DBG_cout<<"hddm_merge_events.cc"<<":"<<45<<
" "
<<"This indicates a bug in the program. Exiting ..."<<endl;
46 exit(-1);
47 }
48 if(Nevents_to_merge.size() != loop_source.size()){
2
Taking false branch
49 _DBG_cout<<"hddm_merge_events.cc"<<":"<<49<<
" "
<<"Size of Nevents_to_merge and loop_source vectors not the same!"<<endl;
50 _DBG_cout<<"hddm_merge_events.cc"<<":"<<50<<
" "
<<"This indicates a bug in the program. Exiting ..."<<endl;
51 exit(-1);
52 }
53
54 // Open Input file(s)
55 vector<s_iostream_t*> instreams;
56 for(unsigned int i=0; i<INFILENAMES.size(); i++){
3
Loop condition is false. Execution continues on line 68
57 cout<<" input file: "<<INFILENAMES[i]<<" ("<<Nevents_to_merge[i]<<" events)"<<endl;
58 s_iostream_t *fin = open_s_HDDM(INFILENAMES[i]);
59 if(!fin){
60 cout<<" Error opening input file \""<<INFILENAMES[i]<<"\"!"<<endl;
61 exit(-1);
62 }
63
64 instreams.push_back(fin);
65 }
66
67 // Output file
68 cout<<" output file: "<<OUTFILENAME<<endl;
69 s_iostream_t *fout = init_s_HDDM(OUTFILENAME);
70 if(!fout){
4
Taking false branch
71 cout<<" Error opening output file \""<<OUTFILENAME<<"\"!"<<endl;
72 exit(-1);
73 }
74
75 // Loop over output events until one of the inputs does not
76 // have enough events to make an output
77 int NEvents = 0;
78 int NEvents_read = 0;
79 time_t last_time = time(NULL__null);
80 while(true){
5
Loop condition is true. Entering loop body
81 // First, read in all events we want to combine
82 vector<s_HDDM_t*> events;
83
84 // Loop over inputs
85 bool done=false;
86 events.clear();
87 for(unsigned int i=0; i<instreams.size(); i++){
6
Loop condition is true. Entering loop body
88 // Loop over events to merge for this input
89 for(unsigned int j=0; j<(unsigned int)Nevents_to_merge[i]; j++){
7
Dereference of null pointer
90 s_HDDM_t *hddm_s = read_s_HDDM(instreams[i]);
91 if(!hddm_s){
92 // Looks like this source is out of events. Check if we need
93 // to re-open this input to keep reading events from it.
94 if(loop_source[i]){
95 close_s_HDDM(instreams[i]);
96 instreams[i] = open_s_HDDM(INFILENAMES[i]);
97 cout<<endl<<"Reopened \""<<INFILENAMES[i]<<"\" ..."<<endl;
98 hddm_s = read_s_HDDM(instreams[i]);
99 }
100 }
101 if(!hddm_s){
102 done = true;
103 break;
104 }
105 events.push_back(hddm_s);
106 NEvents_read++;
107 }
108 if(done)break;
109 }
110 if(done)break;
111
112 // Make a new output event
113 s_HDDM_t* output_hddm_s = make_s_HDDM();
114
115 // An input file's event may have more than 1 PhysicsEvent already.
116 // Loop through and find the total number of Physics events we
117 // need to allocate for.
118 int Nphysics_events = 0;
119 for(unsigned int i=0; i<events.size(); i++)Nphysics_events += events[i]->physicsEvents->mult;
120
121 // Add enough PhysicsEvents to hold all of our inputs
122 output_hddm_s->physicsEvents = make_s_PhysicsEvents(Nphysics_events);
123
124 // Copy PhysicsEvents for inputs, transferring ownership to
125 // output event and freeing memory from the "heads" of the
126 // input events.
127 unsigned int &mult = output_hddm_s->physicsEvents->mult;
128 mult = 0;
129 for(unsigned int i=0; i<events.size(); i++){
130 s_HDDM_t* input_hddm_s = events[i];
131
132 // Loop over PhysicsEvents inside this input event
133 for(unsigned int j=0; j<input_hddm_s->physicsEvents->mult; j++){
134 output_hddm_s->physicsEvents->in[mult++] = input_hddm_s->physicsEvents->in[j];
135
136 // Set the 2 pointers in PhysicsEvent to HDDM_NULL so they aren't freed
137 // when the input event is freed.
138 input_hddm_s->physicsEvents->in[j].reactions = (s_Reactions_t*)HDDM_NULL(void*)&hddm_s_nullTarget;
139 input_hddm_s->physicsEvents->in[j].hitView = (s_HitView_t*)HDDM_NULL(void*)&hddm_s_nullTarget;
140 }
141
142 // Free this input event
143 flush_s_HDDM(input_hddm_s, NULL__null);
144 }
145
146 // Write this output event to file and free its memory
147 flush_s_HDDM(output_hddm_s, fout);
148 NEvents++;
149
150 // Update ticker
151 time_t now = time(NULL__null);
152 if(now != last_time){
153 cout<<" "<<NEvents_read<<" events read ("<<NEvents<<" event written) \r";cout.flush();
154 last_time = now;
155 }
156
157 if(QUIT)break;
158 if(MAXEVENTS>0){
159 if(NEvents>=MAXEVENTS)break;
160 }
161 }
162
163 // Close all inputs
164 for(unsigned int i=0; i<instreams.size(); i++)close_s_HDDM(instreams[i]);
165 close_s_HDDM(fout);
166
167 cout<<" "<<NEvents<<" events read"<<endl;
168
169 return 0;
170}
171
172//-----------
173// ParseCommandLineArguments
174//-----------
175void ParseCommandLineArguments(int narg, char* argv[])
176{
177 int Nmerge = 1;
178 bool loop = false;
179
180 INFILENAMES.clear();
181 loop_source.clear();
182 Nevents_to_merge.clear();
183
184 for(int i=1; i<narg; i++){
185 char *ptr = argv[i];
186
187 if(ptr[0] == '-'){
188 switch(ptr[1]){
189 case 'h': Usage(); break;
190 case 'N': Nmerge=atoi(&ptr[2]); break;
191 case 'M': MAXEVENTS=atoi(&ptr[2]); break;
192 case 'o': OUTFILENAME=&ptr[2]; break;
193 case 'l': loop=true; break;
194 case 's': loop=false; break;
195 }
196 }else{
197 INFILENAMES.push_back(argv[i]);
198 loop_source.push_back(loop);
199 Nevents_to_merge.push_back(Nmerge);
200 }
201 }
202
203 if(INFILENAMES.size()==0){
204 cout<<endl<<"You must enter a filename!"<<endl<<endl;
205 Usage();
206 }
207
208 if(OUTFILENAME==NULL__null){
209 char *default_outfile = (char*)malloc(20);
210 OUTFILENAME = strcpy(default_outfile,"merged.hddm");
211 }
212}
213
214
215//-----------
216// Usage
217//-----------
218void Usage(void)
219{
220 cout<<endl<<"Usage:"<<endl;
221 cout<<" hddm_merge_events [-Mmaxevents] [-oOutputfile] [-l|s -Nnum] file1.hddm [-l|s -Nnum] file2.hddm ..."<<endl;
222 cout<<endl;
223 cout<<"options:"<<endl;
224 cout<<" -oOutputfile Set output filename (def. merged.hddm)"<<endl;
225 cout<<" -Mmaxevents Do not write out more than maxevents events"<<endl;
226 cout<<" -Nnum Merge together num events from each of the following input files"<<endl;
227 cout<<" -l Continually loop over events from the following inputs"<<endl;
228 cout<<" -s Stop when all events from the following inputs have been read"<<endl;
229 cout<<endl;
230 cout<<" This will take events from 1 or more HDDM files and merge them"<<endl;
231 cout<<" into events written to an output HDDM file. This works by simply"<<endl;
232 cout<<" copying the s_PhysicsEvent objects into a single event that gets"<<endl;
233 cout<<" written to the output file."<<endl;
234 cout<<" "<<endl;
235 cout<<" Multiple input files can be specified and for each, the number of"<<endl;
236 cout<<" events to merge. This allows one to do things such as merge 3 events"<<endl;
237 cout<<" from a file of background events with a single event from a file of"<<endl;
238 cout<<" signal events to get a sample of events with 3 times the backaground"<<endl;
239 cout<<" rate overlayed on the signal."<<endl;
240 cout<<" "<<endl;
241 cout<<" By specifying the -l flag, certain input sources can be looped over"<<endl;
242 cout<<" to recycle thier events. This is useful if one has a sample of"<<endl;
243 cout<<" background events that is smaller than the sample of signal events."<<endl;
244 cout<<" See the examples below."<<endl;
245 cout<<" "<<endl;
246 cout<<" NOTE: Events are not merged such that double hits are"<<endl;
247 cout<<" merged. Hits are only copied so it is possible for"<<endl;
248 cout<<" the output event to have two hits on the same wire"<<endl;
249 cout<<" at the same time."<<endl;
250 cout<<" "<<endl;
251 cout<<" Example 1:"<<endl;
252 cout<<" hddm_merge_events -N2 file.hddm"<<endl;
253 cout<<" "<<endl;
254 cout<<" This will combine every 2 events from file.hddm into a single in the"<<endl;
255 cout<<" output. Since no output file name is specified, the file \"merged.hddm\""<<endl;
256 cout<<" will be used."<<endl;
257 cout<<" "<<endl;
258 cout<<" "<<endl;
259 cout<<" Example 2:"<<endl;
260 cout<<" hddm_merge_events signal.hddm -N10 em_bkgnd.hddm -N1 hadronic_bkgnd.hddm"<<endl;
261 cout<<" "<<endl;
262 cout<<" This will combine 1 event from signal.hddm, 10 events from em_bkgnd.hddm,"<<endl;
263 cout<<" and 1 event from hadronic_bkgnd.hdm into a single output event."<<endl;
264 cout<<" "<<endl;
265 cout<<" "<<endl;
266 cout<<" Example 3:"<<endl;
267 cout<<" hddm_merge_events -N3 file1.hddm file2.hddm file3.hddm -N1 file4.hddm"<<endl;
268 cout<<" "<<endl;
269 cout<<" This will combine 3 events from each of file1.hddm, file2.hddm, and"<<endl;
270 cout<<" file3.hddm with 1 event from file4.hddm."<<endl;
271 cout<<" "<<endl;
272 cout<<" "<<endl;
273 cout<<" Example 4:"<<endl;
274 cout<<" hddm_merge_events signal.hddm -l -N10 background.hddm"<<endl;
275 cout<<" "<<endl;
276 cout<<" This will combine 1 signal event with 10 background events to create"<<endl;
277 cout<<" and output event. The events in the background file will be looped"<<endl;
278 cout<<" over continuosly as needed until all of the signal events have been"<<endl;
279 cout<<" processed."<<endl;
280 cout<<" "<<endl;
281 cout<<" "<<endl;
282 cout<<endl;
283
284 exit(0);
285}
286
287//-----------------------------------------------------------------
288// ctrlCHandle
289//-----------------------------------------------------------------
290void ctrlCHandle(int x)
291{
292 QUIT++;
293 cerr<<endl<<"SIGINT received ("<<QUIT<<")....."<<endl;
294}