BmnRoot
Loading...
Searching...
No Matches
MpdGetNumEvents.cxx
Go to the documentation of this file.
1#include "MpdGetNumEvents.h"
2
3#include "FairRootManager.h"
4#include "TChain.h"
5#include "TFile.h"
6#include "TKey.h"
7#include "TString.h"
8#include "TSystem.h"
9
10#include <iostream>
11using namespace std;
12
13MpdLibZ::MpdLibZ(const char* filename)
14{
15 fileName = filename;
16}
17
19{
20 if (file != NULL) {
21 close();
22 file = NULL;
23 }
24}
25
26/* Opens a gzip (.gz) file for reading or writing. The mode parameter
27 is as in fopen ("rb" or "wb") but can also include a compression level
28 ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
29 Huffman only compression as in "wb1h", or 'R' for run-length encoding
30 as in "wb1R". (See the description of deflateInit2 for more information
31 about the strategy parameter.)
32
33 gzopen can be used to read a file which is not in gzip format; in this
34 case gzread will directly read from the file without decompression.
35
36 gzopen returns NULL if the file could not be opened or if there was
37 insufficient memory to allocate the (de)compression state; errno
38 can be checked to distinguish the two cases (if errno is zero, the
39 zlib error is Z_MEM_ERROR). */
40int MpdLibZ::open(const char* mode)
41{
42 file = gzopen(fileName, mode);
43
44 if (file == NULL)
45 return -1;
46 else
47 return 0;
48}
49
50/* Returns 1 when EOF has previously been detected reading the given
51 input stream, otherwise zero. */
53{
54 return gzeof(file);
55}
56
57/* Flushes all pending output if necessary, closes the compressed file
58 and deallocates all the (de)compression state. The return value is the zlib
59 error number (see function gzerror below). */
61{
62 int ret = gzclose(file);
63 if (ret == 0)
64 file = NULL;
65
66 return ret;
67}
68
69/* Writes the given null-terminated string to the compressed file, excluding
70 the terminating null character.
71 gzputs returns the number of characters written, or -1 in case of error. */
72int MpdLibZ::puts(char* s)
73{
74 return gzputs(file, s);
75}
76
77/* Reads bytes from the compressed file until len-1 characters are read, or
78 a newline character is read and transferred to buf, or an end-of-file
79 condition is encountered. The string is then terminated with a null
80 character.
81 gzgets returns buf, or Z_NULL in case of error. */
82char* MpdLibZ::gets(char* buf, int len)
83{
84 return gzgets(file, buf, len);
85}
86
87/* Reads the given number of uncompressed bytes from the compressed file.
88 If the input file was not in gzip format, gzread copies the given number
89 of bytes into the buffer.
90 gzread returns the number of uncompressed bytes actually read (0 for
91 end of file, -1 for error). */
92int MpdLibZ::read(voidp buf, unsigned len)
93{
94 return gzread(file, buf, len);
95}
96
97/* Writes the given number of uncompressed bytes into the compressed file.
98 gzwrite returns the number of uncompressed bytes actually written
99 (0 in case of error). */
100int MpdLibZ::write(voidpc buf, unsigned len)
101{
102 return gzwrite(file, buf, len);
103}
104
105/* Sets the starting position for the next gzread or gzwrite on the given
106 compressed file. The offset represents a number of bytes in the
107 uncompressed data stream. The whence parameter is defined as in lseek(2);
108 the value SEEK_END is not supported.
109
110 If the file is opened for reading, this function is emulated but can be
111 extremely slow. If the file is opened for writing, only forward seeks are
112 supported; gzseek then compresses a sequence of zeroes up to the new
113 starting position.
114
115 gzseek returns the resulting offset location as measured in bytes from
116 the beginning of the uncompressed stream, or -1 in case of error, in
117 particular if the file is opened for writing and the new starting position
118 would be before the current position. */
119off_t MpdLibZ::seek(off_t pos, int whence)
120{
121 switch (whence) {
122 case 0:
123 return gzseek(file, pos, SEEK_SET);
124 case 1:
125 return gzseek(file, pos, SEEK_CUR);
126 case 2:
127 return gzseek(file, pos, SEEK_END);
128 }
129
130 return -1;
131}
132
133/* Returns the starting position for the next gzread or gzwrite on the given
134 compressed file. This position represents a number of bytes in the
135 uncompressed data stream, and is zero when starting, even if appending or
136 reading a gzip stream from the middle of a file using gzdopen().
137
138 gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) */
140{
141 return gztell(file);
142}
143
144// return event count in a given file produced by the PHSD event generator
145// filename - file path to the generator file, iVerbose - output level (0 - no output, 1 - only errors, 2 - full output)
146Int_t MpdGetNumEvents::GetNumPHSDEvents(const char* filename, int iVerbose)
147{
148 string file_path = filename;
149 TString strFilePath(file_path);
150 gSystem->ExpandPathName(strFilePath);
151 if (gSystem->AccessPathName(strFilePath.Data()) == true) {
152 if (iVerbose > 0)
153 cout << "GetNumEvents ERROR: No generator file was found: " << strFilePath << endl;
154 return -1;
155 }
156
157 MpdLibZ* libz = new MpdLibZ(filename);
158 int ret_code = libz->open("rb");
159 if (ret_code != 0) {
160 if (iVerbose > 0)
161 cout << "GetNumPHSDEvents ERROR while opening file: " << filename << endl;
162 return ret_code;
163 }
164
165 char fbuffer[256];
166 Int_t fntr;
167 Float_t fb;
168 int num = 0;
169
170 while (!libz->eof()) {
171 libz->gets(fbuffer, 256); // 1st line
172 if (libz->eof())
173 return -1; // end of file reached
174
175 int res = sscanf(fbuffer, "%d %*d %*d %e", &fntr, &fb);
176 if (res != 2) {
177 if (iVerbose > 0)
178 printf("GetNumPHSDEvents ERROR: selftest error in header, scan %d of 2\n", res);
179 return -2;
180 }
181
182 libz->gets(fbuffer, 256); // 2nd line
183 if (libz->eof()) {
184 if (iVerbose > 0)
185 printf("GetNumPHSDEvents ERROR: unexpected end of file\n");
186 return -2;
187 }
188
189 for (Int_t i = 1; i <= fntr; i++) {
190 /* read track */
191 libz->gets(fbuffer, 256);
192 if (libz->eof()) {
193 if (iVerbose > 0)
194 printf("GetNumPHSDEvents ERROR: unexpected end of file\n");
195 return -2;
196 } // if
197 } // for
198
199 num++;
200 } // while (!libz->eof())
201
202 libz->close();
203 delete libz;
204
205 if (iVerbose > 1)
206 cout << "The total number of events in the PHSD file will be processed - " << num << endl;
207
208 return num;
209}
210
211bool MpdGetNumEvents::GetQGSMEventHeader(char* ss, MpdLibZ* libz, Int_t& fQGSM_format_ID, int iVerbose)
212{
213 libz->gets(ss, 250);
214
215 // If end of input file is reached : close it and abort run
216 if (libz->eof()) {
217 libz->close();
218 return false;
219 }
220 bool wrong_file = false;
221
222 TString tss(ss);
223 if (tss.Contains("QGSM")) // 0
224 {
225 libz->gets(ss, 250);
226 tss = ss;
227 Int_t lines = 0;
228 while (!(tss.Contains("particles, b,bx,by"))) {
229 if (tss.Contains("QGSM format ID")) {
230 sscanf(ss, "QGSM format ID=%d", &fQGSM_format_ID);
231
232 // correction of incorrect format_ID in some data files
233 if (fQGSM_format_ID == 2) {
234 off_t file_pos = libz->tell();
235 for (int k = 0; k < 5; k++)
236 libz->gets(ss, 250);
237
238 if (strlen(ss) > 90)
239 fQGSM_format_ID = 3;
240
241 libz->seek(file_pos, SEEK_SET);
242 }
243 }
244
245 libz->gets(ss, 250);
246 tss = ss;
247 lines++;
248
249 if ((fQGSM_format_ID >= 2) && (lines >= 4))
250 return true;
251
252 if (lines > 25) {
253 wrong_file = true;
254 break;
255 }
256 } // while (!(tss.Contains("particles, b,bx,by")))
257 } else {
258 if (fQGSM_format_ID >= 2)
259 return true;
260
261 if (!tss.Contains("particles, b,bx,by")) {
262 libz->gets(ss, 250);
263 tss = ss;
264 }
265 } // else
266
267 if (wrong_file) {
268 if (iVerbose > 0)
269 cout << "GetQGSMEventHeader ERROR: Wrong file header! 1 " << endl;
270 libz->close();
271 return false;
272 }
273
274 // 3
275 if (!tss.Contains("event")) {
276 if (fQGSM_format_ID >= 2)
277 return true;
278 else {
279 if (iVerbose > 0)
280 cout << "GetQGSMEventHeader ERROR: Wrong event header! 2 " << endl;
281 if (iVerbose > 1)
282 printf("Format id:%d \n %s \n", fQGSM_format_ID, ss);
283 libz->close();
284 return false;
285 } // else
286 }
287
288 char tmp[250];
289
290 switch (fQGSM_format_ID) {
291 case 0:
292 case 1:
293 libz->gets(tmp, 250);
294 break;
295 case 2:
296 case 3:
297 case 4: {
298 libz->gets(ss, 250);
299 libz->gets(ss, 250);
300 break;
301 }
302 default:
303 break;
304 } // switch
305
306 return true;
307}
308
309// return event count in a given file produced by the QGSM/DCM-QGSM event generator
310// filename - file path to the generator file, iVerbose - output level (0 - no output, 1 - only errors, 2 - full output)
311Int_t MpdGetNumEvents::GetNumQGSMEvents(const char* filename, int iVerbose)
312{
313 string file_path = filename;
314 TString strFilePath(file_path);
315 gSystem->ExpandPathName(strFilePath);
316 if (gSystem->AccessPathName(strFilePath.Data()) == true) {
317 if (iVerbose > 0)
318 cout << "GetNumEvents ERROR: No generator file was found: " << strFilePath << endl;
319 return -1;
320 }
321
322 Int_t fQGSM_format_ID = 0;
323 MpdLibZ* libz = new MpdLibZ(filename);
324 int ret_code = libz->open("rb");
325 if (ret_code != 0) {
326 if (iVerbose > 0)
327 cout << "GetNumQGSMEvents ERROR while opening file: " << filename << endl;
328 return ret_code;
329 }
330
331 char ss[252];
332 TString sss = ss;
333 Int_t eventId = 0, nTracks = 0, num = 0;
334
335 while (GetQGSMEventHeader(ss, libz, fQGSM_format_ID, iVerbose)) {
336 num++;
337 sss = ss;
338
339 // read event
340 sscanf(ss, " %d %d", &eventId, &nTracks);
341 // Loop over tracks in the current event
342 for (Int_t itrack = 0; itrack < nTracks; itrack++)
343 libz->gets(ss, 250);
344 }
345
346 libz->close();
347 delete libz;
348
349 if (iVerbose > 1)
350 cout << "The total number of events in the QGSM file will be processed - " << num << endl;
351 return num;
352}
353
354// return event count in a given file produced by the UrQMD event generator
355// filename - file path to the generator file, iVerbose - output level (0 - no output, 1 - onstringly errors, 2 - full
356// output)
357Int_t MpdGetNumEvents::GetNumURQMDEvents(const char* filename, int iVerbose)
358{
359 string file_path = filename;
360 TString strFilePath(file_path);
361 gSystem->ExpandPathName(strFilePath);
362 if (gSystem->AccessPathName(strFilePath.Data()) == true) {
363 if (iVerbose > 0)
364 cout << "GetNumEvents ERROR: No generator file was found: " << strFilePath << endl;
365 return -1;
366 }
367
368 MpdLibZ* libz = new MpdLibZ(filename);
369 int ret_code = libz->open("rb");
370 if (ret_code != 0) {
371 if (iVerbose > 0)
372 cout << "GetNumURQMDEvents ERROR: Failure of opening file: " << filename << endl;
373 return ret_code;
374 }
375
376 char read[200];
377 int ntracks, num = 0;
378 while (!libz->eof()) {
379 // ---> Read and check first event header line from input file
380 libz->gets(read, 200);
381 Int_t urqmdVersion = 0;
382 sscanf(read, "UQMD version: %d 1000 %d output_file 14", &urqmdVersion, &urqmdVersion);
383
384 if (libz->eof()) {
385 // cout<<"GetNumURQMDEvents ERROR: Incorrect end of input file reached!"<<endl;
386 break;
387 }
388
389 if (read[0] != 'U') {
390 if (iVerbose > 0)
391 cout << "GetNumURQMDEvents ERROR: Wrong event header!" << endl;
392 return -2;
393 }
394
395 // ---> Read rest of event header
396 for (int iline = 0; iline < ((urqmdVersion == 30400) ? 16 : 13); iline++)
397 libz->gets(read, 200);
398
399 libz->gets(read, 200);
400 sscanf(read, "%d", &ntracks);
401 libz->gets(read, 200);
402
403 for (int itrack = 0; itrack < ntracks; itrack++)
404 libz->gets(read, 200);
405
406 num++;
407 }
408
409 libz->close();
410 delete libz;
411
412 if (iVerbose > 1)
413 cout << "The total number of events in the UrQMD file will be processed - " << num << endl;
414 return num;
415}
416
417// return event count in a given file produced by the DCM-SMM event generator
418// filename - file path to the generator file, iVerbose - output level (0 - no output, 1 - only errors, 2 - full output)
419Int_t MpdGetNumEvents::GetNumDCMSMMEvents(const char* filename, int iVerbose)
420{
421 string file_path = filename;
422 TString strFilePath(file_path);
423 gSystem->ExpandPathName(strFilePath);
424 if (gSystem->AccessPathName(strFilePath.Data()) == true) {
425 if (iVerbose > 0)
426 cout << "GetNumEvents ERROR: No generator file was found: " << strFilePath << endl;
427 return -1;
428 }
429
430 MpdLibZ* libz = new MpdLibZ(filename);
431 libz->open("rb");
432
433 char r200[200];
434 Int_t header_size = 1;
435 for (Int_t i = 0; i < header_size; i++) {
436 libz->gets(r200, 200);
437 if (i == 0) {
438 string str0(r200);
439 if (str0.find("Results of DCM-SMM") != string::npos) // new version
440 header_size = 20;
441 else if (str0.find("Results of QGSM") != string::npos) // old version
442 header_size = 3;
443 else {
444 if (iVerbose > 0)
445 cout << "GetNumDCMSMMEvents ERROR: Wrong input file format" << endl;
446 return -2;
447 }
448 }
449 }
450
451 char read[128];
452 int ntracks, num = 0;
453 Int_t evnr = 0, last_evnr = 0;
454 while (!libz->eof()) {
455 char* gets_res = libz->gets(read, 128);
456 if (gets_res == Z_NULL)
457 break; // EOF reached
458 sscanf(read, "%d", &evnr);
459 // if an event is skipped, print it
460 if (evnr - last_evnr != 1)
461 cout << "ERROR: the sequence of events was interrupted " << last_evnr << "-" << evnr << endl;
462 // if (evnr-num != 1) break; // otherwise it gives 1 more event after eof
463 last_evnr = evnr;
464 for (Int_t ibeam = 0; ibeam < 3; ibeam++) {
465 libz->gets(read, 128);
466 sscanf(read, "%d", &ntracks);
467 for (Int_t i = 0; i < ntracks; i++)
468 libz->gets(read, 128);
469 }
470 num++;
471 }
472
473 libz->close();
474 delete libz;
475
476 if (iVerbose > 1)
477 cout << "The total number of events in the DCMSMM file will be processed - " << num << endl;
478 return num;
479}
480
481string MpdGetNumEvents::FindFirstTree(const char* filename, int iVerbose)
482{
483 // open file to search for the first tree
484 TFile* rootFile = new TFile(filename, "READ");
485 if (!rootFile->IsOpen()) {
486 if (iVerbose > 0)
487 cout << "GetNumROOTEvents ERROR: could not open ROOT file: " << filename << endl;
488 return "";
489 }
490
491 TIter next(rootFile->GetListOfKeys());
492 TKey* key;
493 while ((key = static_cast<TKey*>(next())) != nullptr) {
494 if (strcmp(key->GetClassName(), "TTree") != 0)
495 continue;
496 string tree_name = (static_cast<TTree*>(key->ReadObj()))->GetName();
497 delete rootFile;
498 return tree_name;
499 }
500
501 delete rootFile;
502 if (iVerbose > 0)
503 cout << "GetNumROOTEvents ERROR: could not find a tree in the ROOT file: " << filename << endl;
504 return "";
505}
506
507// return event count in a given ROOT file as a number of records in a specfied tree
508// filename - file path to the ROOT file
509// treename - name of the tree in the ROOT file; "" - get FairRootManager default tree name, nullptr - get first tree
510// from the file iVerbose - output level (0 - no output, 1 - only errors, 2 - full output)
511Int_t MpdGetNumEvents::GetNumROOTEvents(const char* filename, const char* treename, int iVerbose)
512{
513 string file_path = filename;
514 TString strFilePath(file_path);
515 gSystem->ExpandPathName(strFilePath);
516 if (gSystem->AccessPathName(strFilePath.Data()) == true) {
517 if (iVerbose > 0)
518 cout << "GetNumEvents ERROR: No generator file was found: " << strFilePath << endl;
519 return -1;
520 }
521
522 TChain* fileTree;
523 if (treename == nullptr) {
524 string tree_name = FindFirstTree(filename, iVerbose);
525 if (tree_name == "")
526 return -2;
527 fileTree = new TChain(tree_name.c_str());
528 } else if (treename[0] == '\0')
529 fileTree = new TChain(FairRootManager::GetTreeName());
530 else
531 fileTree = new TChain(treename);
532 fileTree->Add(filename);
533
534 Int_t num = fileTree->GetEntries();
535
536 delete fileTree;
537
538 if (iVerbose > 1)
539 cout << "The total number of events in the ROOT file will be processed - " << num << endl;
540 return num;
541}
542
543// Return event count in a given file for an event generator defined automatically
544// filename - file path to the generator file, iVerbose - output level (0 - no output, 1 - only errors, 2 - full output)
545Int_t MpdGetNumEvents::GetNumEvents(const char* filename, int iVerbose)
546{
547 string file_path = filename;
548 TString strFilePath(file_path);
549 gSystem->ExpandPathName(strFilePath);
550 if (gSystem->AccessPathName(strFilePath.Data()) == true) {
551 if (iVerbose > 0)
552 cout << "GetNumEvents ERROR: No generator file was found: " << strFilePath << endl;
553 return -1;
554 }
555
556 if (strFilePath.Contains(".root", TString::kIgnoreCase))
557 return MpdGetNumEvents::GetNumROOTEvents(strFilePath.Data(), nullptr, iVerbose);
558
559 if (strFilePath.Contains(".f14", TString::kIgnoreCase))
560 return MpdGetNumEvents::GetNumURQMDEvents(strFilePath.Data(), iVerbose);
561
562 if (strFilePath.Contains(".r12", TString::kIgnoreCase)) {
563 // find generator name in a header of the ASCII file
564 MpdLibZ* libz = new MpdLibZ(filename);
565 libz->open("rb");
566
567 // iGenerator: 0 - not defined, 1 - QGSM, 2 - SMM
568 int iGenerator = 0;
569 char r200[200];
570 libz->gets(r200, 200);
571 string str0(r200);
572 if (str0.find("Results of QGSM") != string::npos)
573 iGenerator = 1;
574 else if (str0.find("Results of DCM-SMM") != string::npos)
575 iGenerator = 2;
576 else {
577 if (iVerbose > 0)
578 cout << "GetNumEvents ERROR: Wrong input file format, generator type was not defined" << endl;
579 return -2;
580 }
581
582 libz->close();
583 delete libz;
584
585 switch (iGenerator) {
586 case 1:
587 return MpdGetNumEvents::GetNumQGSMEvents(strFilePath.Data(), iVerbose);
588 case 2:
589 return MpdGetNumEvents::GetNumDCMSMMEvents(strFilePath.Data(), iVerbose);
590 default:
591 return -2;
592 }
593 }
594
595 return -3;
596}
int i
Definition P4_F32vec4.h:22
static Int_t GetNumROOTEvents(const char *filename, const char *treename="", int iVerbose=2)
static Int_t GetNumPHSDEvents(const char *filename, int iVerbose=2)
static Int_t GetNumQGSMEvents(const char *fileName, int iVerbose=2)
static Int_t GetNumEvents(const char *filename, int iVerbose=2)
static Int_t GetNumURQMDEvents(const char *fileName, int iVerbose=2)
static Int_t GetNumDCMSMMEvents(const char *fileName, int iVerbose=2)
int read(voidp buf, unsigned len)
virtual ~MpdLibZ()
int write(voidpc buf, unsigned len)
MpdLibZ(const char *filename)
int open(const char *mode)
int puts(char *s)
off_t seek(off_t pos, int whence)
char * gets(char *buf, int len)
STL namespace.