Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
evio_merge_events.cc
Go to the documentation of this file.
1 // $Id$
2 //
3 // Created June 10, 2014 David Lawrence
4 
5 #include <iostream>
6 #include <fstream>
7 #include <iomanip>
8 #include <vector>
9 using namespace std;
10 
11 #include <signal.h>
12 #include <time.h>
13 #include <stdlib.h>
14 
15 #include <evioFileChannel.hxx>
16 #include <evioUtil.hxx>
17 using namespace evio;
18 
19 
20 #ifndef _DBG_
21 #define _DBG_ cout<<__FILE__<<":"<<__LINE__<<" "
22 #define _DBG__ cout<<__FILE__<<":"<<__LINE__<<endl
23 #endif
24 
25 void ParseCommandLineArguments(int narg, char* argv[]);
26 void Usage(void);
27 void ctrlCHandle(int x);
28 void Process(unsigned int &NEvents, unsigned int &NEvents_read);
29 
30 vector<char*> INFILENAMES;
31 char *OUTFILENAME = NULL;
32 int QUIT = 0;
33 
34 
35 
36 //-----------
37 // main
38 //-----------
39 int main(int narg,char* argv[])
40 {
41  // Set up to catch SIGINTs for graceful exits
42  signal(SIGINT,ctrlCHandle);
43 
44  ParseCommandLineArguments(narg, argv);
45 
46  unsigned int NEvents = 0;
47  unsigned int NEvents_read = 0;
48 
49  // Process all events
50  Process(NEvents, NEvents_read);
51 
52  cout<<endl;
53  cout<<" "<<NEvents_read<<" events read, "<<NEvents<<" events written"<<endl;
54 
55  return 0;
56 }
57 
58 //-----------
59 // ParseCommandLineArguments
60 //-----------
61 void ParseCommandLineArguments(int narg, char* argv[])
62 {
63  INFILENAMES.clear();
64 
65  for(int i=1; i<narg; i++){
66  char *ptr = argv[i];
67 
68  if(ptr[0] == '-'){
69  switch(ptr[1]){
70  case 'h': Usage(); break;
71  case 'o': OUTFILENAME=&ptr[2]; break;
72  }
73  }else{
74  INFILENAMES.push_back(argv[i]);
75  }
76  }
77 
78  if(INFILENAMES.size()==0){
79  cout<<endl<<"You must enter a filename!"<<endl<<endl;
80  Usage();
81  }
82 
83  if(OUTFILENAME==NULL){
84  OUTFILENAME = new char[256];
85  sprintf(OUTFILENAME,"merged_files.evio");
86  }
87 }
88 
89 
90 //-----------
91 // Usage
92 //-----------
93 void Usage(void)
94 {
95  cout<<endl<<"Usage:"<<endl;
96  cout<<" evio_merge_events [-oOutputfile] file1.evio file2.evio ..."<<endl;
97  cout<<endl;
98  cout<<"options:"<<endl;
99  cout<<" -oOutputfile Set output filename (def. merged_files.evio)"<<endl;
100  cout<<endl;
101  cout<<" This will merge events from 1 or more EVIO files into a single EVIO file."<<endl;
102  cout<<"This is done at the event level by copying all EVIO banks from the top-level" << endl;
103  cout<<"bank into the top-level bank of the output file." << endl;
104  cout<<" "<<endl;
105  cout<<" "<<endl;
106  cout<<endl;
107 
108  exit(0);
109 }
110 
111 //-----------------------------------------------------------------
112 // ctrlCHandle
113 //-----------------------------------------------------------------
114 void ctrlCHandle(int x)
115 {
116  QUIT++;
117  cerr<<endl<<"SIGINT received ("<<QUIT<<")....."<<endl;
118 }
119 
120 //-----------
121 // Process
122 //-----------
123 void Process(unsigned int &NEvents, unsigned int &NEvents_read)
124 {
125  // Output file
126  cout<<" output file: "<<OUTFILENAME<<endl;
127  evioFileChannel ochan(OUTFILENAME, "w");
128  ochan.open();
129 
130  // Open all input files
131  vector<evioFileChannel*> ichan;
132  for(unsigned int i=0; i<INFILENAMES.size(); i++){
133  cout << "Opening input file : \"" << INFILENAMES[i] << "\"" << endl;
134  evioFileChannel *chan = new evioFileChannel(INFILENAMES[i], "r");
135  chan->open();
136  ichan.push_back(chan);
137  }
138 
139  // Loop until an input file runs out of events
140  time_t last_time = time(NULL);
141  while(true){
142 
143  // Read in event from each input file, creating a DOM tree for each
144  vector<evioDOMTree*> doms;
145  for(unsigned int i=0; i<ichan.size(); i++){
146  try{
147  if(! ichan[i]->read() ) {
148  cout << endl << "No more events in " << INFILENAMES[i] << endl;
149  break;
150  }
151  }catch(evioException e){
152  cerr << e.what() << endl;
153  QUIT=true;
154  break;
155  }
156  evioDOMTree *dom = new evioDOMTree(ichan[i]);
157  doms.push_back(dom);
158  }
159  if(QUIT) break;
160  if(doms.size() != ichan.size()) break;
161  NEvents_read++;
162 
163  // Merge DOM Trees into single DOM tree
164  evioDOMTreeP tree=NULL;
165  evioDOMNodeP root=NULL;
166  for(unsigned int i=0; i<doms.size(); i++){
167  evioDOMNodeListP nodes = doms[i]->getNodeList();
168  evioDOMNodeList::const_iterator ulIter;
169  for(ulIter=nodes->begin(); ulIter!=nodes->end(); ulIter++) {
170  evioDOMNodeP node = *ulIter;
171  if(node->getParent() != NULL ) continue; // only interested in top-level nodes
172  if(tree==NULL){
173  // Use the first node of the first file as the root node
174  root = node;
175  root->cut(); // remove from input file's DOM
176  tree = new evioDOMTree(root);
177  }else{
178  // Move all daughter nodes of this input file's top-level node
179  // into the root node of the merged event
180  evioDOMNodeListP mynodes = node->getChildren();
181  if(mynodes.get() == NULL) continue;
182  evioDOMNodeList::const_iterator myiter;
183  for(myiter=mynodes->begin(); myiter!=mynodes->end(); myiter++) {
184  try{
185  (*myiter)->move(root);
186  }catch(...){
187  QUIT = true;
188  break;
189  }
190  }
191  if(QUIT) break;
192  }
193  if(QUIT) break;
194  }
195  if(QUIT) break;
196  }
197 
198  // Write event to output file
199  if(!QUIT){
200  ochan.write(tree);
201  NEvents++;
202  }
203 
204  // Update ticker
205  time_t now = time(NULL);
206  if(now != last_time){
207  cout<<" "<<NEvents_read<<" events read ("<<NEvents<<" event written) \r";cout.flush();
208  last_time = now;
209  }
210 
211  if(QUIT)break;
212  }
213 
214  // Close all input files
215  for(unsigned int i=0; i<ichan.size(); i++){
216  try{
217  ichan[i]->close();
218  delete ichan[i];
219  }catch(...){}
220  }
221 
222  // Close output file
223  ochan.close();
224 
225 }
226 
void Process(unsigned int &NEvents, unsigned int &NEvents_read)
Double_t x[NCHANNELS]
Definition: st_tw_resols.C:39
sprintf(text,"Post KinFit Cut")
char * OUTFILENAME
TEllipse * e
void ParseCommandLineArguments(int &narg, char *argv[])
Definition: hd_dump.cc:124
static evioFileChannel * chan
int QUIT
vector< char * > INFILENAMES
void ctrlCHandle(int x)
void Usage(JApplication &app)
Definition: hd_ana.cc:33
int main(int argc, char *argv[])
Definition: gendoc.cc:6