R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BFileSource.cxx
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
3 * Copyright (C) 2019-2025 Members of R3B Collaboration *
4 * *
5 * This software is distributed under the terms of the *
6 * GNU General Public Licence (GPL) version 3, *
7 * copied verbatim in the file "LICENSE". *
8 * *
9 * In applying this license GSI does not waive the privileges and immunities *
10 * granted to it by virtue of its status as an Intergovernmental Organization *
11 * or submit itself to any jurisdiction. *
12 ******************************************************************************/
13
14// -----------------------------------------------------------
15// ----- R3BFileSource -----
16// ----- Created 12/05/21 by J.L. Rodriguez-Sanchez -----
17// -----------------------------------------------------------
18
19#include "R3BFileSource.h"
20#include "R3BLogger.h"
21
22#include "FairEventHeader.h"
23#include "FairFileHeader.h"
24#include "FairLogger.h"
25#include "FairMCEventHeader.h"
26#include "FairRootManager.h"
27#include "FairRuntimeDb.h"
28#include "R3BEventHeader.h"
29#include "TChainElement.h"
30#include "TFolder.h"
31#include "TObjArray.h"
32#include "TROOT.h"
33#include "TRandom.h"
34#include "TString.h"
35#include <TObjString.h>
36#include <algorithm>
37#include <list>
38#include <map>
39#include <set>
40#include <typeinfo>
41
42using std::map;
43using std::set;
44
45#include <cstdlib>
46#include <iostream>
47using namespace std;
48
49TMCThreadLocal R3BFileSource* R3BFileSource::fSourceInstance = 0;
50
51R3BFileSource::R3BFileSource(TFile* f, const char* Title, UInt_t)
52 : FairSource()
53 , fInputTitle(Title)
54 , fRootFile(f)
55 , fCurrentEntryNr(0)
56 , fFriendFileList()
57 , fInputChainList()
58 , fFriendTypeList()
59 , fCheckInputBranches()
60 , fInputLevel()
61 , fRunIdInfoAll()
62 , fInChain(0)
63 , fInTree(0)
64 , fListFolder(new TObjArray(16))
65 , fRtdb(FairRuntimeDb::instance())
66 , fFolderOut(0)
67 , fFolderIn(0)
68 , fSourceIdentifier(0)
69 , fNoOfEntries(-1)
70 , IsInitialized(kFALSE)
71 , fMCHeader(0)
72 , fEvtHeader(0)
73 , fFileHeader(0)
74 , fEventTimeInMCHeader(kTRUE)
75 , fEvtHeaderIsNew(kFALSE)
76 , fCurrentEntryNo(0)
77 , fTimeforEntryNo(-1)
78 , fEventTimeMin(0.)
79 , fEventTimeMax(0.)
80 , fEventTime(0.)
81 , fBeamTime(-1.)
82 , fGapTime(-1.)
83 , fEventMeanTime(0.)
84 , fTimeProb(0)
85 , fCheckFileLayout(kTRUE)
86 , fInputFile()
87 , fExpid(0)
88 , prevts(0)
89 , nextts(0)
90{
91 if (fSourceInstance)
92 {
93 R3BLOG(fatal, "Singleton instance already exists.");
94 return;
95 }
96 fSourceInstance = this;
97
98 if (fRootFile->IsZombie())
99 {
100 R3BLOG(fatal, "Error opening the Input file");
101 }
102 R3BLOG(debug, "R3BFileSource created------------");
103}
104
105R3BFileSource::R3BFileSource(const TString* RootFileName, const char* Title, UInt_t)
106 : FairSource()
107 , fInputTitle(Title)
108 , fRootFile(0)
109 , fCurrentEntryNr(0)
110 , fFriendFileList()
111 , fInputChainList()
112 , fFriendTypeList()
113 , fCheckInputBranches()
114 , fInputLevel()
115 , fRunIdInfoAll()
116 , fInChain(0)
117 , fInTree(0)
118 , fListFolder(new TObjArray(16))
119 , fRtdb(FairRuntimeDb::instance())
120 , fFolderOut(0)
121 , fFolderIn(0)
122 , fSourceIdentifier(0)
123 , fNoOfEntries(-1)
124 , IsInitialized(kFALSE)
125 , fMCHeader(0)
126 , fEvtHeader(0)
127 , fFileHeader(0)
128 , fEventTimeInMCHeader(kTRUE)
129 , fEvtHeaderIsNew(kFALSE)
130 , fCurrentEntryNo(0)
131 , fTimeforEntryNo(-1)
132 , fEventTimeMin(0.)
133 , fEventTimeMax(0.)
134 , fEventTime(0.)
135 , fBeamTime(-1.)
136 , fGapTime(-1.)
137 , fEventMeanTime(0.)
138 , fTimeProb(0)
139 , fCheckFileLayout(kTRUE)
140 , fInputFile()
141 , fExpid(0)
142 , prevts(0)
143 , nextts(0)
144{
145 if (fSourceInstance)
146 {
147 R3BLOG(fatal, "Singleton instance already exists.");
148 return;
149 }
150 fSourceInstance = this;
151
152 fRootFile = TFile::Open(RootFileName->Data());
153 if (fRootFile->IsZombie())
154 {
155 R3BLOG(fatal, "Error opening the Input file");
156 }
157 R3BLOG(debug, "R3BFileSource created------------");
158}
159
160R3BFileSource::R3BFileSource(const TString RootFileName, const char* Title, UInt_t)
161 : FairSource()
162 , fInputTitle(Title)
163 , fRootFile(0)
164 , fCurrentEntryNr(0)
165 , fFriendFileList()
166 , fInputChainList()
167 , fFriendTypeList()
168 , fCheckInputBranches()
169 , fInputLevel()
170 , fRunIdInfoAll()
171 , fInChain(0)
172 , fInTree(0)
173 , fListFolder(new TObjArray(16))
174 , fRtdb(FairRuntimeDb::instance())
175 , fFolderOut(0)
176 , fFolderIn(0)
177 , fSourceIdentifier(0)
178 , fNoOfEntries(-1)
179 , IsInitialized(kFALSE)
180 , fMCHeader(0)
181 , fEvtHeader(0)
182 , fFileHeader(0)
183 , fEventTimeInMCHeader(kTRUE)
184 , fEvtHeaderIsNew(kFALSE)
185 , fCurrentEntryNo(0)
186 , fTimeforEntryNo(-1)
187 , fEventTimeMin(0.)
188 , fEventTimeMax(0.)
189 , fEventTime(0.)
190 , fBeamTime(-1.)
191 , fGapTime(-1.)
192 , fEventMeanTime(0.)
193 , fTimeProb(0)
194 , fCheckFileLayout(kTRUE)
195 , fInputFile()
196 , fExpid(0)
197 , prevts(0)
198 , nextts(0)
199{
200 if (fSourceInstance)
201 {
202 R3BLOG(fatal, "Singleton instance already exists.");
203 return;
204 }
205 fSourceInstance = this;
206
207 fRootFile = TFile::Open(RootFileName.Data());
208 if (fRootFile->IsZombie())
209 {
210 R3BLOG(fatal, "Error opening the Input file");
211 }
212 R3BLOG(debug, "R3BFileSource created------------");
213}
214
215R3BFileSource* R3BFileSource::Instance() { return fSourceInstance; }
216
218{
219 LOG(debug) << "Enter Destructor of R3BFileSource";
220 if (fEvtHeader)
221 delete fEvtHeader;
222 LOG(debug) << "Leave Destructor of R3BFileSource";
223}
224
226{
227 R3BLOG(info, "");
228
229 if (IsInitialized)
230 {
231 R3BLOG(info, "R3BFileSource already initialized");
232 return kTRUE;
233 }
234 if (!fInChain)
235 {
236 fInChain = new TChain(FairRootManager::GetTreeName(), Form("/%s", FairRootManager::GetFolderName()));
237 R3BLOG(debug, "Chain created");
238 FairRootManager::Instance()->SetInChain(fInChain);
239 }
240 fInChain->Add(fRootFile->GetName());
241
242 // Get the folder structure from file which describes the input tree.
243 // There are two different names possible, so check both.
244 fFolderIn = dynamic_cast<TFolder*>(fRootFile->Get(FairRootManager::GetFolderName()));
245 if (!fFolderIn)
246 {
247 fFolderIn = dynamic_cast<TFolder*>(fRootFile->Get("r3broot"));
248 if (!fFolderIn)
249 {
250 fFolderIn = dynamic_cast<TFolder*>(fRootFile->Get("cbmout"));
251 if (!fFolderIn)
252 {
253 fFolderIn = dynamic_cast<TFolder*>(fRootFile->Get("cbmroot"));
254 if (!fFolderIn)
255 {
256 fFolderIn = gROOT->GetRootFolder()->AddFolder(FairRootManager::GetFolderName(), "Main Folder");
257 }
258 else
259 {
260 fFolderIn->SetName(FairRootManager::GetFolderName());
261 }
262 }
263 }
264 }
265 // Get The list of branches from the input file and add it to the
266 // actual list of existing branches.
267 // Add this list of branches also to the map of input trees, which
268 // stores the information which branches belong to which input tree.
269 // There is at least one primary input tree, but there can be many
270 // additional friend trees.
271 // This information is needed to add new files to the correct friend
272 // tree. With this information it is also possible to check if the
273 // input files which are added to the input chain all have the same
274 // branch structure. Without this check it is possible to add trees
275 // with a different branch structure but the same tree name. ROOT
276 // probably only checks if the name of the tree is the same.
277 TList* list = dynamic_cast<TList*>(fRootFile->Get("BranchList"));
278 if (list == 0)
279 {
280 R3BLOG(fatal, "No Branch list in input file");
281 }
282 TString chainName = fInputTitle;
283 TString ObjName;
284 fInputLevel.push_back(chainName);
285 fCheckInputBranches[chainName] = new std::list<TString>;
286 if (list)
287 {
288 TObjString* Obj = 0;
289 R3BLOG(debug, "Enteries in the list " << list->GetEntries());
290 for (Int_t i = 0; i < list->GetEntries(); i++)
291 {
292 Obj = dynamic_cast<TObjString*>(list->At(i));
293 if (Obj != 0)
294 {
295 ObjName = Obj->GetString();
296 R3BLOG(debug, "Branch name " << ObjName.Data());
297 fCheckInputBranches[chainName]->push_back(ObjName.Data());
298
299 FairRootManager::Instance()->AddBranchToList(ObjName.Data());
300 }
301 }
302 }
303
304 gROOT->GetListOfBrowsables()->Add(fFolderIn);
305 fListFolder->Add(fFolderIn);
306
307 // Store the information about the unique runids in the input file
308 // together with the filename and the number of events for each runid
309 // this information is needed later to check if inconsitencies exist
310 // between the main input chain and any of the friend chains.
311
312 // GetRunIdInfo(fInFile->GetName(), chainName);
313
314 // Add all additional input files to the input chain and do a
315 // consitency check
316 for (auto fileName : fInputChainList)
317 {
318 // Store global gFile pointer for safety reasons.
319 // Set gFile to old value at the end of the routine.R
320 TFile* temp = gFile;
321
322 // Temporarily open the input file to extract information which
323 // is needed to bring the friend trees in the correct order
324 TFile* inputFile = TFile::Open(fileName);
325 if (inputFile->IsZombie())
326 {
327 LOG(fatal) << "Error opening the file " << fileName.Data()
328 << " which should be added to the input chain or as friend chain";
329 }
330
331 if (fCheckFileLayout)
332 {
333 // Check if the branchlist is the same as for the first input file.
334 Bool_t isOk = CompareBranchList(inputFile, chainName);
335 if (!isOk)
336 {
337 LOG(fatal) << "Branch structure of the input file " << fRootFile->GetName()
338 << " and the file to be added " << fileName.Data() << " are different.";
339 return kFALSE;
340 }
341 }
342
343 // Add the runid information for all files in the chain.
344 // GetRunIdInfo(inputFile->GetName(), chainName);
345 // Add the file to the input chain
346 fInChain->Add(fileName);
347
348 // Close the temporarly file and restore the gFile pointer.
349 inputFile->Close();
350 gFile = temp;
351 }
352 fNoOfEntries = fInChain->GetEntries();
353
354 R3BLOG(debug, "Entries in this Source " << fNoOfEntries);
355
356 for (Int_t i = 0; i < fListFolder->GetEntriesFast(); i++)
357 {
358 TFolder* fold = static_cast<TFolder*>(fListFolder->At(i));
359 fEvtHeader = static_cast<R3BEventHeader*>(fold->FindObjectAny("EventHeader."));
360 fMCHeader = static_cast<FairMCEventHeader*>(fold->FindObjectAny("MCEventHeader."));
361 if (fEvtHeader)
362 {
363 ActivateObject(reinterpret_cast<TObject**>(&fEvtHeader), "EventHeader.");
364 }
365 if (fMCHeader)
366 {
367 ActivateObject(reinterpret_cast<TObject**>(&fMCHeader), "MCEventHeader.");
368 }
369 }
370
371 FairRootManager::Instance()->SetListOfFolders(fListFolder);
372
374
375 TList* timebasedlist = dynamic_cast<TList*>(fRootFile->Get("TimeBasedBranchList"));
376 if (timebasedlist == 0)
377 {
378 LOG(warn) << "No time based branch list in input file";
379 }
380 else
381 {
382 FairRootManager::Instance()->SetTimeBasedBranchNameList(timebasedlist);
383 }
384
385 // Open configuration file with runid values if needed in this step
386 fInputFile.open(fInputFileName.Data(), std::fstream::in);
387 if (!fInputFile.is_open())
388 {
389 R3BLOG(warn, "Input file for RunIds was not found, it is Ok!");
390 }
391 else
392 {
393 R3BLOG(info, "Input file for RunIds " << fInputFileName.Data() << " was found");
394 fInputFile.clear();
395 fInputFile.seekg(0, std::ios::beg);
396 }
397
398 if (fInputFile.is_open())
399 {
400 R3BLOG(info, "Reading RunId file");
401 Int_t rid;
402 Int_t expRun;
403 int64_t ts;
404 while (fInputFile >> hex >> rid >> expRun >> ts)
405 {
406 fRunid.push_back(rid);
407 fTimestamp.push_back(ts);
408 // Ignore the other stuff that might still be on that line
409 fInputFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
410 }
411
412 R3BLOG(info, "End of reading RunId file");
413 fInputFile.close();
414 }
415 else
416 {
417 nextts = 0;
418 }
419
420 return kTRUE;
421}
422
423void R3BFileSource::SetInTree(TTree* tempTree)
424{
425 fInTree = NULL;
426 fInTree = tempTree;
427 fRootFile = static_cast<TFile*>(tempTree->GetCurrentFile());
428 fInChain->Reset();
429 IsInitialized = kFALSE;
430 Init();
431}
432
433// ---- Method GetRunid -----------------------------------------------------
434Int_t R3BFileSource::GetRunid(uint64_t st)
435{
436 UInt_t fArraysize = fTimestamp.size();
437 if (fArraysize != fRunid.size())
438 {
439 R3BLOG(error, "\033[5m\033[31m Different number of RunIds and timestamps \033[0m");
440 prevts = 0;
441 nextts = 0;
442 return 1;
443 }
444
445 for (Int_t j = 0; j < fArraysize - 1; j++)
446 if (st >= fTimestamp[j] && st < fTimestamp[j + 1])
447 {
448 prevts = fTimestamp[j];
449 nextts = fTimestamp[j + 1];
450 R3BLOG(debug, "New timestamp " << nextts << " for RunId " << fRunid[j]);
451 return fRunid[j];
452 }
453
454 if (st >= fTimestamp[fArraysize - 1])
455 {
456 prevts = fTimestamp[fArraysize - 1];
457 nextts = fTimestamp[fArraysize - 1];
458 R3BLOG(debug, "Prev/next timestamp " << prevts << "/" << nextts << " for runid " << fRunid[fArraysize - 1]);
459 return fRunid[fArraysize - 1];
460 }
461
462 if (nextts > 0)
463 {
464 R3BLOG(warn, "\033[5m\033[33m RunId was not found, it will be 1 \033[0m");
465 }
466 prevts = 0;
467 nextts = 0;
468
469 return 1;
470}
471
472// ---- Method ReadEvent ----------------------------------------------------
474{
475 fCurrentEntryNo = i;
476 fEventTime = GetEventTime();
477
483 if (i > 0)
484 {
485 printf("Processed: \033[32m %d \033[0m of \033[34m %d \033[0m (\033[33m %.2f \033[0m of 100), current RunId "
486 "\033[31m %d \033[0m \r",
487 i + 1,
488 fNoOfEntries,
489 100. * i / (double)(fNoOfEntries),
490 fRunId);
491 fflush(stdout);
492 }
493
494 if (nextts > 0 && prevts >= 0 && (fEvtHeader->GetTimeStamp() > nextts || fEvtHeader->GetTimeStamp() < prevts))
495 {
496 fRunId = GetRunid(fEvtHeader->GetTimeStamp());
497 }
498
499 if (fInChain->GetEntry(i))
500 return 0;
501
502 return 1;
503}
504
506
508
509void R3BFileSource::AddFriend(TString fName) { fFriendFileList.push_back(fName); }
510
511void R3BFileSource::AddFile(TString FileName) { fInputChainList.push_back(FileName); }
512
514{
515 // Loop over all Friend files and extract the type. The type is defined by
516 // the tree which is stored in the file. If there is already a chain of with
517 // this type of tree then the file will be added to this chain.
518 // If there is no such chain it will be created.
519 //
520 // Check if the order of runids and the event numbers per runid for all
521 // friend chains is the same as the one defined by the input chain.
522 // TODO: Should the order be corrected or should the execution be stopped.
523 // The order in the input tree defined by the order in which the files have
524 // been added. A file is defined by the runid.
525
526 // In the old way it was needed sometimes to add a freind file more
527 // than once. This is not needed any longer, so we remove deuplicates
528 // from the list and display a warning.
529 std::list<TString> friendList;
530 for (auto fileName : fFriendFileList)
531 {
532 if (find(friendList.begin(), friendList.end(), fileName) == friendList.end())
533 {
534 friendList.push_back(fileName);
535 }
536 }
537 // TODO: print a warning if it was neccessary to remove a filname from the
538 // list. This can be chacked by comparing the size of both list
539
540 TFile* temp = gFile;
541
542 Int_t friendType = 1;
543 // Loop over all files which have been added as friends
544 for (auto fileName : friendList)
545 {
546 TString inputLevel;
547 // Loop over all already defined input levels to check if this type
548 // of friend tree is already added.
549 // If this type of friend tree already exist add the file to the
550 // then already existing friend chain. If this type of friend tree
551 // does not exist already create a new friend chain and add the file.
552 Bool_t inputLevelFound = kFALSE;
553 TFile* inputFile;
554 for (auto level : fInputLevel)
555 {
556 inputLevel = level;
557
558 inputFile = TFile::Open(fileName);
559 if (inputFile->IsZombie())
560 {
561 LOG(fatal) << "Error opening the file " << level.Data()
562 << " which should be added to the input chain or as friend chain";
563 }
564
565 // Check if the branchlist is already stored in the map. If it is
566 // already stored add the file to the chain.
567 Bool_t isOk = CompareBranchList(inputFile, inputLevel);
568 if (isOk)
569 {
570 inputLevelFound = kTRUE;
571 inputFile->Close();
572 continue;
573 }
574 inputFile->Close();
575 }
576 if (!inputLevelFound)
577 {
578 inputLevel = Form("FriendTree_%i", friendType);
579 CreateNewFriendChain(fileName, inputLevel);
580 friendType++;
581 }
582
583 TChain* chain = static_cast<TChain*>(fFriendTypeList[inputLevel]);
584 chain->AddFile(fileName, 1234567890, FairRootManager::GetTreeName());
585 }
586 gFile = temp;
587
588 // Check if all friend chains have the same runids and the same
589 // number of event numbers as the corresponding input chain
590 // CheckFriendChains();
591
592 // Add all the friend chains which have been created to the main input chain.
593 for (const auto& mi : fFriendTypeList)
594 {
595 TChain* chain = static_cast<TChain*>(mi.second);
596 fInChain->AddFriend(chain);
597 }
598
599 // Print some output about the input structure
601}
602
604{
605 // Print information about the input structure
606 // List files from the input chain together with all files of
607 // all friend chains
608
609 LOG(info) << "The input consists out of the following trees and files: ";
610 LOG(info) << " - " << fInChain->GetName();
611 TObjArray* fileElements = fInChain->GetListOfFiles();
612 TIter next(fileElements);
613 TChainElement* chEl = 0;
614 while ((chEl = static_cast<TChainElement*>(next())))
615 {
616 LOG(info) << " - " << chEl->GetTitle();
617 }
618
619 for (const auto& mi : fFriendTypeList)
620 {
621 TChain* chain = static_cast<TChain*>(mi.second);
622 LOG(info) << " - " << chain->GetName();
623 fileElements = chain->GetListOfFiles();
624 TIter next1(fileElements);
625 chEl = 0;
626 while ((chEl = static_cast<TChainElement*>(next1())))
627 {
628 LOG(info) << " - " << chEl->GetTitle();
629 }
630 }
631}
632
634{
635 std::multimap<TString, std::multimap<TString, TArrayI>>::iterator it1;
636 std::multimap<TString, TArrayI> map1;
637
638 // Get the structure from the input chain
639 it1 = fRunIdInfoAll.find("InputChain");
640 map1 = it1->second;
641 std::vector<Int_t> runid;
642 std::vector<Int_t> events;
643 for (auto& mmi : map1)
644 {
645 TArrayI bla = mmi.second;
646 runid.push_back(bla[0]);
647 events.push_back(bla[1]);
648 }
649
650 // Now loop over all chains except the input chain and comapare the
651 // runids and event numbers.
652 // If there is a mismatch stop the execution.
653 Int_t errorFlag = 0;
654 TString inputLevel;
655 for (auto level : fInputLevel)
656 {
657 inputLevel = level;
658 if (!inputLevel.Contains("InputChain"))
659 {
660 it1 = fRunIdInfoAll.find(inputLevel);
661 map1 = it1->second;
662 if (runid.size() != map1.size())
663 {
664 errorFlag = 1;
665 break;
666 }
667 Int_t counter = 0;
668 for (auto& mmi : map1)
669 {
670 TArrayI bla = mmi.second;
671 if ((bla[0] != runid[counter]) || (bla[1] != events[counter]))
672 {
673 errorFlag = 2;
674 break;
675 }
676 counter++;
677 }
678 if (errorFlag > 0)
679 {
680 break;
681 }
682 }
683 }
684
685 if (errorFlag > 0)
686 {
687 LOG(error) << "The input chain and the friend chain " << inputLevel.Data() << " have a different structure:";
688 if (errorFlag == 1)
689 {
690 LOG(error) << "The input chain has the following runids and event numbers:";
691 for (UInt_t i = 0; i < runid.size(); i++)
692 {
693 LOG(error) << " - Runid " << runid[i] << " with " << events[i] << " events";
694 }
695 LOG(error) << "The " << inputLevel.Data() << " chain has the following runids and event numbers:";
696 for (auto& mmi : map1)
697 {
698 TArrayI bla = mmi.second;
699 LOG(error) << " - Runid " << bla[0] << " with " << bla[1] << " events";
700 }
701 }
702 if (errorFlag == 2)
703 {
704 Int_t counter = 0;
705 for (auto& mmi : map1)
706 {
707 TArrayI bla = mmi.second;
708 LOG(error) << "Runid Input Chain, " << inputLevel.Data() << " chain: " << bla[0] << ", "
709 << runid[counter];
710 LOG(error) << "Event number Input Chain, " << inputLevel.Data() << " chain: " << bla[1] << ", "
711 << events[counter];
712 counter++;
713 }
714 }
715 LOG(fatal) << "Event structure mismatch";
716 }
717}
718
719void R3BFileSource::CreateNewFriendChain(TString inputFile, TString inputLevel)
720{
721
722 TFile* temp = gFile;
723 TFile* f = TFile::Open(inputFile);
724
725 TFolder* added = NULL;
726 TString folderName1 = FairRootManager::GetFolderName();
727 TString folderName = Form("/%s", folderName1.Data());
728 added = dynamic_cast<TFolder*>(f->Get(folderName1));
729 if (!added)
730 {
731 folderName = "/r3broot";
732 folderName1 = "r3broot";
733 added = dynamic_cast<TFolder*>(f->Get("r3broot"));
734 if (!added)
735 {
736 folderName = "/cbmout";
737 folderName1 = "cbmout";
738 added = dynamic_cast<TFolder*>(f->Get("cbmout"));
739 if (!added)
740 {
741 folderName = "/cbmroot";
742 folderName1 = "cbmroot";
743 added = dynamic_cast<TFolder*>(f->Get("cbmroot"));
744 if (!added)
745 {
746 LOG(fatal) << "Could not find folder r3broot, cbmout nor cbmroot.";
747 exit(-1);
748 }
749 }
750 }
751 }
752 folderName1 = folderName1 + "_" + inputLevel;
753 added->SetName(folderName1);
754 fListFolder->Add(added);
755
757 TList* list = dynamic_cast<TList*>(f->Get("BranchList"));
758 TString chainName = inputLevel;
759 fInputLevel.push_back(chainName);
760 fCheckInputBranches[chainName] = new std::list<TString>;
761 if (list)
762 {
763 TObjString* Obj = 0;
764 for (Int_t i = 0; i < list->GetEntries(); i++)
765 {
766 Obj = dynamic_cast<TObjString*>(list->At(i));
767 fCheckInputBranches[chainName]->push_back(Obj->GetString().Data());
768 std::cout << Obj->GetString().Data() << std::endl;
769 FairRootManager::Instance()->AddBranchToList(Obj->GetString().Data());
770 }
771 }
772
773 TChain* chain = new TChain(inputLevel, folderName);
774 fFriendTypeList[inputLevel] = chain;
775
776 f->Close();
777 gFile = temp;
778}
779
780Bool_t R3BFileSource::CompareBranchList(TFile* fileHandle, TString inputLevel)
781{
782 // fill a set with the original branch structure
783 // This allows to use functions find and erase
784 std::set<TString> branches;
785 for (auto li : *(fCheckInputBranches[inputLevel]))
786 {
787 branches.insert(li);
788 }
789
790 // To do so we have to loop over the branches in the file and to compare
791 // the branches in the file with the information stored in
792 // fCheckInputBranches["InputChain"]. If both lists are equal everything
793 // is okay
794
795 // Get The list of branches from the input file one by one and compare
796 // it to the reference list of branches which is defined for this tree.
797 // If a branch with the same name is found, this branch is removed from
798 // the list. If in the end no branch is left in the list everything is
799 // fine.
801 TList* list = dynamic_cast<TList*>(fileHandle->Get("BranchList"));
802 if (list)
803 {
804 TObjString* Obj = 0;
805 for (Int_t i = 0; i < list->GetEntries(); i++)
806 {
807 Obj = dynamic_cast<TObjString*>(list->At(i));
808 iter1 = branches.find(Obj->GetString().Data());
809 if (iter1 != branches.end())
810 {
811 branches.erase(iter1);
812 }
813 else
814 {
815 // Not found is an error because branch structure is
816 // different. It is impossible to add to tree with a
817 // different branch structure
818 return kFALSE;
819 }
820 }
821 }
822 // If the size of branches is !=0 after removing all branches also in the
823 // reference list, this is also a sign that both branch list are not the
824 // same
825 if (branches.size() != 0)
826 {
827 LOG(info) << "Compare Branch List will return kFALSE. The list has " << branches.size() << " branches:";
828 for (auto branchName : branches)
829 LOG(info) << " -> " << branchName;
830 return kFALSE;
831 }
832
833 return kTRUE;
834}
835
836Bool_t R3BFileSource::ActivateObject(TObject** obj, const char* BrName)
837{
838 if (fInTree)
839 {
840 fInTree->SetBranchStatus(BrName, 1);
841 fInTree->SetBranchAddress(BrName, obj);
842 }
843 if (fInChain)
844 {
845 fInChain->SetBranchStatus(BrName, 1);
846 fInChain->SetBranchAddress(BrName, obj);
847 }
848
849 return kTRUE;
850}
851
853{
854 fRootFile = TFile::Open(name.Data());
855 if (fRootFile->IsZombie())
856 {
857 LOG(fatal) << "Error opening the Input file";
858 }
859 LOG(info) << "R3BFileSource set------------";
860}
861
863{
864 Int_t MaxEventNo = 0;
865 if (EvtEnd != 0)
866 {
867 MaxEventNo = EvtEnd;
868 }
869 else
870 {
871 MaxEventNo = fInChain->GetEntries();
872 }
873 return MaxEventNo;
874}
875
877{
878 fEventMeanTime = mean;
879 fTimeProb = new TF1("TimeProb", "(1/[0])*exp(-x/[0])", 0., mean * 10);
880 fTimeProb->SetParameter(0, mean);
881 fTimeProb->GetRandom();
882 fEventTimeInMCHeader = kFALSE;
883}
884
885void R3BFileSource::SetEventTimeInterval(Double_t min, Double_t max)
886{
887 fEventTimeMin = min;
888 fEventTimeMax = max;
889 fEventMeanTime = (fEventTimeMin + fEventTimeMax) / 2.0;
890 fEventTimeInMCHeader = kFALSE;
891}
892
893void R3BFileSource::SetBeamTime(Double_t beamTime, Double_t gapTime)
894{
895 fBeamTime = beamTime;
896 fGapTime = gapTime;
897}
898
900{
901 // Check if the time for the current entry is already set
902 if (fTimeforEntryNo == fCurrentEntryNo)
903 return;
904 LOG(debug) << "Set event time for Entry = " << fTimeforEntryNo << " , where the current entry is "
905 << fCurrentEntryNo << " and eventTime is " << fEventTime;
906 if (fBeamTime < 0)
907 {
908 fEventTime += GetDeltaEventTime();
909 }
910 else
911 {
912 do
913 {
914 fEventTime += GetDeltaEventTime();
915 } while (fmod(fEventTime, fBeamTime + fGapTime) > fBeamTime);
916 }
917 LOG(debug) << "New time = " << fEventTime;
918 fTimeforEntryNo = fCurrentEntryNo;
919}
920
922{
923 Double_t deltaTime = 0;
924 if (fTimeProb != 0)
925 {
926 deltaTime = fTimeProb->GetRandom();
927 LOG(debug) << "Time set via sampling method : " << deltaTime;
928 }
929 else
930 {
931 deltaTime = gRandom->Uniform(fEventTimeMin, fEventTimeMax);
932 LOG(debug) << "Time set via Uniform Random : " << deltaTime;
933 }
934 return deltaTime;
935}
936
938{
939 LOG(debug) << "-- Get Event Time --";
940 if (!fEvtHeaderIsNew && fEvtHeader != 0)
941 {
942 Double_t EvtTime = fEvtHeader->GetEventTime();
943 if (!(EvtTime < 0))
944 {
945 return EvtTime;
946 }
947 }
948
949 if (fEventTimeInMCHeader && !fMCHeader)
950 {
951 LOG(debug) << "No MCEventHeader, time is set to 0";
952 return 0;
953 }
954 else if (fEventTimeInMCHeader && fMCHeader)
955 {
956 fEventTime = fMCHeader->GetT();
957 LOG(debug) << "Get event time from MCEventHeader : " << fEventTime << " ns";
958 return fEventTime;
959 }
960 else
961 {
962
963 if (fTimeforEntryNo != fCurrentEntryNo)
964 {
965 SetEventTime();
966 }
967 LOG(debug) << "Calculate event time from user input : " << fEventTime << " ns";
968 return fEventTime;
969 }
970}
971
972void R3BFileSource::ReadBranchEvent(const char* BrName)
973{
975 if (fEvtHeader == 0)
976 {
977 return;
978 } // No event header, Reading will start later
979 if (fInTree)
980 {
981 fInTree->FindBranch(BrName)->GetEntry(fEvtHeader->GetMCEntryNumber());
982 fEventTime = GetEventTime();
983 return;
984 }
985 if (fInChain)
986 {
987 fInChain->FindBranch(BrName)->GetEntry(fEvtHeader->GetMCEntryNumber());
988 fEventTime = GetEventTime();
989 return;
990 }
991 return;
992}
993
994void R3BFileSource::ReadBranchEvent(const char* BrName, Int_t Entry)
995{
996 fCurrentEntryNo = Entry;
997 if (fInTree)
998 {
999 fInTree->FindBranch(BrName)->GetEntry(Entry);
1000 fEventTime = GetEventTime();
1001 return;
1002 }
1003 if (fInChain)
1004 {
1005 fInChain->FindBranch(BrName)->GetEntry(Entry);
1006 fEventTime = GetEventTime();
1007 return;
1008 }
1009 return;
1010}
1011
1013{
1014 if (ReadEvent(0) == 0)
1015 return true;
1016
1017 return false;
1018}
1019
1020void R3BFileSource::FillEventHeader(FairEventHeader* feh)
1021{
1022 // see comment in R3BUcesbSource::FillEventHeader
1023 feh->SetRunId(fRunId);
1024 feh->SetInputFileId(0);
1025 return;
1026}
1027
ClassImp(R3BFileSource)
#define R3BLOG(severity, x)
Definition R3BLogger.h:35
void FillEventHeader(FairEventHeader *feh) override
Double_t GetEventTime()
static R3BFileSource * Instance()
static instance
Int_t ReadEvent(UInt_t i=0) override
void SetBeamTime(Double_t beamTime, Double_t gapTime)
Set the repetition time of the beam when it can interact (beamTime) and when no interaction happen (g...
void SetEventTimeInterval(Double_t min, Double_t max)
Set the min and max limit for event time in ns.
Int_t CheckMaxEventNo(Int_t EvtEnd=0) override
Check the maximum event number we can run to.
R3BFileSource(TFile *f, const char *Title="InputRootFile", UInt_t identifier=0)
Double_t GetDeltaEventTime()
void SetInTree(TTree *tempTree)
Set the input tree when running on PROOF worker.
void AddFriend(TString FileName)
Add a friend file (input) by name)
void AddFile(TString FileName)
Add ROOT file to input, the file will be chained to already added files.
Bool_t ActivateObject(TObject **obj, const char *BrName) override
Bool_t SpecifyRunId()
Read one event from source to find out which RunId to use.
void SetInputFile(TString name)
~R3BFileSource() override
void Close() override
Bool_t Init() override
void CreateNewFriendChain(TString inputFile, TString inputLevel)
void Reset() override
void ReadBranchEvent(const char *BrName) override
Read the tree entry on one branch.
Bool_t CompareBranchList(TFile *fileHandle, TString inputLevel)
void SetEventMeanTime(Double_t mean)
Set the mean time for the event in ns.
STL iterator class.