File: | programs/Utilities/hddm_merge_events/hddm_merge_events.cc |
Location: | line 89, column 42 |
Description: | Dereference of null pointer |
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> | |||
8 | using namespace std; | |||
9 | ||||
10 | #include <signal.h> | |||
11 | #include <time.h> | |||
12 | ||||
13 | #include "HDDM/hddm_s.h" | |||
14 | ||||
15 | void Smear(s_HDDM_t *hddm_s); | |||
16 | void ParseCommandLineArguments(int narg, char* argv[]); | |||
17 | void Usage(void); | |||
18 | void ctrlCHandle(int x); | |||
19 | ||||
20 | vector<int> Nevents_to_merge; | |||
21 | vector<bool> loop_source; | |||
22 | vector<char*> INFILENAMES; | |||
23 | char *OUTFILENAME = NULL__null; | |||
24 | int QUIT = 0; | |||
25 | int 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 | //----------- | |||
35 | int 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()){ | |||
| ||||
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()){ | |||
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++){ | |||
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){ | |||
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){ | |||
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++){ | |||
88 | // Loop over events to merge for this input | |||
89 | for(unsigned int j=0; j<(unsigned int)Nevents_to_merge[i]; j++){ | |||
| ||||
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 | //----------- | |||
175 | void 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 | //----------- | |||
218 | void 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 | //----------------------------------------------------------------- | |||
290 | void ctrlCHandle(int x) | |||
291 | { | |||
292 | QUIT++; | |||
293 | cerr<<endl<<"SIGINT received ("<<QUIT<<")....."<<endl; | |||
294 | } |