EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
eventcombiner.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file eventcombiner.cc
1 #include "fileEventiterator.h"
2 #include "testEventiterator.h"
3 #include "phenixTypes.h"
4 #include "A_Event.h"
5 #include "ogzBuffer.h"
6 #include "ophBuffer.h"
7 #include "ospBuffer.h"
8 #include "EventTypes.h"
9 #include "oEvent.h"
10 
11 #include <cstdlib>
12 #include <unistd.h>
13 #include <cstdio>
14 
15 #include <string>
16 #include <vector>
17 
18 #ifdef HAVE_GETOPT_H
19 #include <getopt.h>
20 #endif
21 
22 #define DDEVENTITERATOR 1
23 #define FILEEVENTITERATOR 2
24 #define TESTEVENTITERATOR 3
25 #define DDPOOL 4
26 #define DFILE 5
27 #define DNULL 6
28 
29 #if defined(SunOS) || defined(Linux) || defined(OSF1)
30 #include <cstring>
31 #else
32 #include <bstring.h>
33 #endif
34 
35 
36 
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #include <fcntl.h>
40 
41 using namespace std;
42 
43 #if defined(SunOS) || defined(Linux) || defined(OSF1)
44 void sig_handler(int);
45 #else
46 void sig_handler(...);
47 #endif
48 
49 
50 void exitmsg()
51 {
52  COUT << "** usage: eventcombiner outputfile inputfile1 inputfile2 ..." << std::endl;
53  COUT << " eventcombiner -h for more help" << std::endl;
54  exit(0);
55 }
56 
57 void exithelp()
58 {
59  COUT << std::endl;
60  COUT << " Syntax:"<< std::endl;
61  COUT << std::endl;
62  COUT << " eventcombiner [-v] [-i] [-n number] [-u] [-p] [-h] inputfile1 inputfile2 ..."<< std::endl;
63  COUT << " e.g eventcombiner -v /export/rcfdata/dcm_data/built_evt/rc_3612.prdfz /export/rcfdata/dcm_data/rc/*3612*" << std::endl;
64  COUT << " will combine all the *3612* (from one run number) together in the file. "<< std::endl;
65  COUT << " Options:" << std::endl;
66  COUT << " -v verbose, without that it does its work silently" << std::endl;
67  COUT << " -i identify the events as they are processed, good for debugging" << std::endl;
68  COUT << " -e <event number> start with event number (number in evt. header)" << std::endl;
69  COUT << " -c <event number> start with nth event" << std::endl;
70  COUT << " -n <number> stop after so many events" << std::endl;
71  COUT << " -p read and write legacy PHENIX format data, default is sPHENIX "<< std::endl;
72  // COUT << " -u write uncompressed data, default is compressed "<< std::endl;
73  COUT << " -f force output file overwrite, normally you cannot overwrite an existing file (safety belt)"<< std::endl;
74  COUT << " -x ignore event numbers (allow non-matching evt nrs to be combined, DANGEROUS)"<< std::endl;
75  COUT << " -h this message" << std::endl;
76  exit(0);
77 }
78 
80 {
81  COUT << "** cannot specify both -e and -c!" << std::endl;
82  COUT << " type eventcombiner -h for more help" << std::endl;
83  exit(0);
84 }
85 
87 int fd;
88 int file_open = 0;
89 
90 int
91 main(int argc, char *argv[])
92 {
93  int c;
94  int status;
95 
96  int eventnumber =0;
97  int countnumber =0;
98  int forceflag =0;
99  int verbose = 0;
100  int identify = 0;
101  int maxevents = 0;
102  int eventnr = 0;
103  int ignoreeventnr = 0;
104  // int gzipcompress = 0;
105  int legacyphenix = 0;
106 
107  extern char *optarg;
108  extern int optind;
109 
110  PHDWORD *buffer;
111 
112  // initialize the pointers to 0;
113  fd = 0;
114  ob = 0;
115 
116  // COUT << "parsing input" << std::endl;
117  int buffer_size = 256*1024*64; // makes 32MB (specifies how many dwords, so *4)
118 
119 
120 
121  while ((c = getopt(argc, argv, "n:c:e:vipfhx")) != EOF)
122  {
123 
124  switch (c)
125  {
126 
127  case 'v': // verbose
128  verbose = 1;
129  break;
130 
131  case 'i': // identify
132  identify = 1;
133  break;
134 
135  case 'f': // force
136  forceflag = 1;
137  break;
138 
139  // case 'g': // do not gzip-compress
140  // gzipcompress = 1;
141  // break;
142 
143  case 'p': // do not gzip-compress
144  legacyphenix = 1;
145  break;
146 
147  case 'x': // do not gzip-compress
148  ignoreeventnr = 1;
149  break;
150 
151  case 'e':
152  if ( !sscanf(optarg, "%d", &eventnumber) ) exitmsg();
153  break;
154 
155  case 'c':
156  if ( !sscanf(optarg, "%d", &countnumber) ) exitmsg();
157  break;
158 
159  case 'n': // number of events
160  if ( !sscanf(optarg, "%d", &maxevents) ) exitmsg();
161  break;
162 
163  case 'h':
164  exithelp();
165  break;
166 
167  default:
168  break;
169 
170  }
171  }
172 
173  if (argc < 3) exitmsg();
174 
175  if ( eventnumber && countnumber) evtcountexitmsg();
176 
177  vector<Eventiterator *> it;
178  vector<Event *>evt;
179 
180  int index;
181 
182  string filename;
183 
184  filename =argv[optind];
185 
186  // try if the output file exists
187 
188  fd = open(filename.c_str(), O_RDONLY | O_LARGEFILE);
189  if (fd > 0 )
190  {
191  if ( ! forceflag)
192  {
193  COUT << "file " << filename << " exists - I won't override it" << std::endl;
194  COUT << " use -f to force" << std::endl;
195  exit(1);
196  }
197  close (fd);
198  }
199  for ( index = optind+1; index < argc; index++ )
200  {
201  COUT << "reading from file " << argv[index] << std::endl;
202  Eventiterator *itx = new fileEventiterator(argv[index], status);
203  if (status)
204  {
205  COUT << "could not open " << argv[index] << std::endl;
206  exit(1);
207  }
208  it.push_back(itx);
209 
210  }
211 
212  buffer = new PHDWORD [buffer_size];
213 
214 
215  int go_on = 1;
216 
217  unlink (filename.c_str());
218 
219  fd = open(filename.c_str(),
220  O_WRONLY | O_CREAT | O_EXCL | O_LARGEFILE ,
221  S_IRWXU | S_IROTH | S_IRGRP );
222 
223 
224  if ( fd < 0 )
225  {
226  COUT << "Could not open file: " << filename << std::endl;
227  exit (1);
228  }
229  if (verbose) COUT << "Opened file: " << filename << std::endl;
230 
231  if (legacyphenix)
232  {
233  ob = new ophBuffer (fd, buffer, buffer_size);
234  }
235  else
236  {
237  ob = new ospBuffer (fd, buffer, buffer_size);
238  }
239 
240  int count = 0;
241 
242  while ( ( maxevents == 0 || eventnr < maxevents) && go_on)
243  {
244  int total_length = 0;
245  int enr = 0;
246 
247  vector<Eventiterator *>::iterator it_itr;
248  Event *e = 0;
249 
250  for (it_itr = it.begin(); it_itr != it.end(); ++it_itr)
251  {
252  Event *e = (*it_itr)->getNextEvent();
253  if ( !e )
254  {
255  go_on = 0;
256  }
257  else
258  {
259  total_length += e->getEvtLength();
260  }
261  evt.push_back(e);
262  }
263  if (! go_on ) break;
264 
265  int *out = new int[total_length];
266 
267  int nwout;
268  int current = 0;
269  int take_this = 1;
270 
271  if ( eventnumber && e->getEvtSequence() < eventnumber) take_this = 0;
272 
273  if ( countnumber && count+1 < countnumber) take_this = 0;
274 
275  vector<Event *>::iterator evt_itr;
276  for (evt_itr = evt.begin(); evt_itr != evt.end(); ++evt_itr)
277  {
278  if (evt_itr == evt.begin() ) // event from 1st input file
279  {
280  enr = (*evt_itr)->getEvtSequence();
281  (*evt_itr)->Copy ( out , total_length , &nwout);
282  current = nwout;
283  delete (*evt_itr);
284  }
285  else
286  {
287  if (take_this ==0 || (ignoreeventnr ==0 && (*evt_itr)->getEvtSequence() != enr ))
288  {
289  take_this = 0;
290  }
291  else
292  {
293  (*evt_itr)->Copy ( &out[current] , total_length-current , &nwout, "DATA");
294  current += nwout;
295  out[0] += nwout;
296  delete (*evt_itr);
297  }
298  }
299  }
300 
301  if (take_this)
302  {
303  Event *E = new oncsEvent(out);
304  if (identify) E->identify();
305 
306  ob->addEvent(E);
307  delete E;
308  eventnr++;
309  }
310  count++;
311  delete [] out;
312  evt.clear();
313 
314  }
315  vector<Eventiterator *>::iterator it_itr;
316  for (it_itr = it.begin(); it_itr != it.end(); ++it_itr)
317  {
318  delete ( (*it_itr) ) ;
319  }
320 
321  delete ob;
322  close (fd);
323 }