FairRoot
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FairRootManager.cxx
Go to the documentation of this file.
1 /********************************************************************************
2  * Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH *
3  * *
4  * This software is distributed under the terms of the *
5  * GNU Lesser General Public Licence (LGPL) version 3, *
6  * copied verbatim in the file "LICENSE" *
7  ********************************************************************************/
8 // -------------------------------------------------------------------------
9 // ----- FairRootManager source file -----
10 // ----- Created 06/01/04 by M. Al-Turany/D. Bertini -----
11 // -------------------------------------------------------------------------
12 
13 // Class FairRootManager
14 // ------------------
15 // Class that takes care of Root IO.
16 #include "FairRootManager.h"
17 
18 #include "FairEventHeader.h" // for FairEventHeader
19 #include "FairFileHeader.h" // for FairFileHeader
20 #include "FairFileSource.h"
21 #include "FairLink.h" // for FairLink
22 #include "FairLinkManager.h" // for FairLinkManager
23 #include "FairLogger.h" // for FairLogger, MESSAGE_ORIGIN
24 #include "FairMonitor.h" // for FairMonitor
25 #include "FairRootFileSink.h" // to enable GetOutFile()
26 #include "FairRun.h" // for FairRun
27 #include "FairTSBufferFunctional.h" // for FairTSBufferFunctional, etc
28 #include "FairWriteoutBuffer.h" // for FairWriteoutBuffer
29 
30 #include <TBranch.h> // for TBranch
31 #include <TClonesArray.h> // for TClonesArray
32 #include <TCollection.h> // for TCollection, TIter
33 #include <TFile.h> // for TFile
34 #include <TFolder.h> // for TFolder
35 #include <TGeoManager.h> // for TGeoManager, gGeoManager
36 #include <TIterator.h> // for TIterator
37 #include <TList.h> // for TList
38 #include <TMCAutoLock.h>
39 #include <TNamed.h> // for TNamed
40 #include <TObjArray.h> // for TObjArray
41 #include <TObjString.h> // for TObjString
42 #include <TRefArray.h> // for TRefArray
43 #include <TTree.h> // for TTree
44 #include <algorithm> // for find
45 #include <cassert>
46 #include <cstdio>
47 #include <cstring> // for strcmp
48 #include <iostream> // for operator<<, basic_ostream, etc
49 #include <list> // for _List_iterator, list, etc
50 #include <map> // for map, _Rb_tree_iterator, etc
51 #include <set> // for set, set<>::iterator
52 #include <stdlib.h> // for exit
53 #include <utility> // for pair
54 #include <vector> // for vector
55 
56 using std::list;
57 using std::map;
58 using std::pair;
59 using std::set;
60 
61 namespace {
62 // Define mutexes per operation which modify shared data
63 TMCMutex createMutex = TMCMUTEX_INITIALIZER;
64 TMCMutex deleteMutex = TMCMUTEX_INITIALIZER;
65 } // namespace
66 
67 Int_t FairRootManager::fgCounter = 0;
68 
70 {
71  // Returns singleton instance.
72  // ---
73  static thread_local FairRootManager instance;
74  return &instance;
75 }
76 
77 FairRootManager::FairRootManager()
78  : TObject()
79  , fOldEntryNr(-1)
80  , fOutFolder(0)
81  , fRootFolder(0)
82  , fCurrentTime(0)
83  , fObj2(new TObject*[1000])
84  , fNObj(-1)
85  , fMap()
86  , fBranchSeqId(0)
87  , fBranchNameList(new TList())
88  , fMCTrackBranchId(-1)
89  , fTimeBasedBranchNameList(new TList())
90  , fActiveContainer()
91  , fTSBufferMap()
92  , fWriteoutBufferMap()
93  , fInputBranchMap()
94  , fTimeStamps(kFALSE)
95  , fBranchPerMap(kFALSE)
96  , fBrPerMap()
97  , fBrPerMapIter()
98  , fCurrentEntryNo(0)
99  , fTimeforEntryNo(0)
100  , fFillLastData(kFALSE)
101  , fEntryNr(0)
102  , fListFolder(0)
103  , fSource(0)
104  , fSourceChain(new TChain(GetTreeName(), Form("/%s", GetFolderName())))
105  , fSignalChainList()
106  , fEventHeader(new FairEventHeader())
107  , fSink(nullptr)
108  , fUseFairLinks(kFALSE)
109  , fFinishRun(kFALSE)
110  , fListOfBranchesFromInput(0)
111  , fListOfBranchesFromInputIter(0)
112  , fListOfNonTimebasedBranches(new TRefArray())
113  , fListOfNonTimebasedBranchesIter(0)
114  , fId(0)
115 {
116  LOG(debug) << "FairRootManager::FairRootManager: going to lock " << this;
117 
118  TMCAutoLock lk(&createMutex);
119 
120  // Set Id
121  fId = fgCounter;
122 
123  // Increment counter
124  ++fgCounter;
125 
126  lk.unlock();
127 
128  LOG(debug) << "Released lock and done FairRootManager::FairRootManager in " << fId << " " << this;
129 }
130 
132 {
133  //
134  LOG(debug) << "Enter Destructor of FairRootManager";
135 
136  delete[] fObj2;
137  fBranchNameList->Delete();
138  delete fBranchNameList;
139  LOG(debug) << "Leave Destructor of FairRootManager";
140  delete fEventHeader;
141  delete fSourceChain;
142  if (fSink)
143  delete fSink;
144  if (fSource)
145  delete fSource;
146 
147  // Global cleanup
148  TMCAutoLock lk(&deleteMutex);
149 
150  LOG(debug) << "FairRootManager::~FairRootManager: going to lock " << fId << " " << this;
151 
152  --fgCounter;
153 
154  //
155  lk.unlock();
156 
157  LOG(debug) << "Released lock and done FairRootManager::~FairRootManager in " << fId << " " << this;
158 }
159 
161 {
162 
163  LOG(debug) << "Call the initialiazer for the FairSource in FairRootManager ";
164  if (fSource) {
165  Bool_t sourceInitBool = fSource->Init();
166  fListOfBranchesFromInput = fSourceChain->GetListOfBranches();
167  TObject* obj;
168  if (fListOfBranchesFromInput) {
169  fListOfBranchesFromInputIter = fListOfBranchesFromInput->MakeIterator();
170  while ((obj = fListOfBranchesFromInputIter->Next())) {
171  if ((fTimeBasedBranchNameList->FindObject(obj->GetName())) == 0)
172  fListOfNonTimebasedBranches->Add(obj);
173  }
174  }
175  LOG(debug) << "Source is intialized and the list of branches is created in FairRootManager ";
176  fListOfNonTimebasedBranchesIter = fListOfNonTimebasedBranches->MakeIterator();
177  return sourceInitBool;
178  }
179  return kFALSE;
180 }
181 
183 {
184  if (fSink) {
185  fSink->InitSink();
186  }
187  return kTRUE;
188 }
189 
190 template<typename T>
191 void FairRootManager::RegisterImpl(const char* name, const char* folderName, T* obj, Bool_t toFile)
192 {
194  FairMonitor::GetMonitor()->RecordRegister(name, folderName, toFile);
195 
196  // Security check. If the the name is equal the folder name there are problems with reading
197  // back the data. Instead of the object inside the folder the RootManger will return a pointer
198  // to the folder. To avoid such problems we check here if both strings are equal and stop the
199  // execution with some error message if this is the case.
200  if (strcmp(name, folderName) == 0) {
201  LOG(fatal) << "The names for the object name " << name << " and the folder name " << folderName
202  << " are equal. This isn't allowed. So we stop the execution at this point. Pleae change either the "
203  "name or the folder name.";
204  }
205 
206  if (toFile) {
207  obj->SetName(name);
208  if (fSink) {
209  fSink->RegisterImpl(name, folderName, obj);
210  } else {
211  LOG(fatal) << "The sink does not exist to store persistent branches.";
212  }
213  }
214  AddMemoryBranch(name, obj);
215  AddBranchToList(name);
216 
217  if (toFile == kFALSE) {
219  }
220 }
221 
222 void FairRootManager::Register(const char* name, const char* folderName, TNamed* obj, Bool_t toFile)
223 {
224  RegisterImpl(name, folderName, obj, toFile);
225 }
226 
227 Int_t FairRootManager::AddBranchToList(const char* name)
228 {
229  if (fBranchNameList->FindObject(name) == 0) {
230  fBranchNameList->AddLast(new TObjString(name));
231  // check if we are setting the MCTrack Branch
232  if (strcmp(name, "MCTrack") == 0) {
233  fMCTrackBranchId = fBranchSeqId;
234  }
235  fBranchSeqId++;
236  }
237  return fBranchSeqId;
238 }
239 
240 void FairRootManager::Register(const char* name, const char* foldername, TCollection* obj, Bool_t toFile)
241 {
242  RegisterImpl(name, foldername, obj, toFile);
243 }
244 
245 void FairRootManager::RegisterInputObject(const char* name, TObject* obj)
246 {
247  AddMemoryBranch(name, obj);
248  AddBranchToList(name);
249 }
250 
251 TClonesArray* FairRootManager::Register(TString branchName, TString className, TString folderName, Bool_t toFile)
252 {
253  FairMonitor::GetMonitor()->RecordRegister(branchName, folderName, toFile);
254 
255  TClonesArray* outputArray;
256  if (fActiveContainer.find(branchName) == fActiveContainer.end()) {
257  fActiveContainer[branchName] = new TClonesArray(className);
258  outputArray = fActiveContainer[branchName];
259  Register(branchName, folderName, outputArray, toFile);
260  }
261 
262  return fActiveContainer[branchName];
263 }
264 
265 TClonesArray* FairRootManager::GetEmptyTClonesArray(TString branchName)
266 {
267  if (fActiveContainer.find(branchName)
268  != fActiveContainer.end()) { // if a TClonesArray is registered in the active container
269  if (fActiveContainer[branchName] == 0) { // the address of the TClonesArray is still valid
270  std::cout << "-E- FairRootManager::GetEmptyTClonesArray: Container deleted outside FairRootManager!"
271  << std::endl;
272  } else {
273  fActiveContainer[branchName]->Delete();
274  }
275  return fActiveContainer[branchName]; // return the container
276  } else {
277  std::cout << "-E- Branch: " << branchName << " not registered!"
278  << std::endl; // error if the branch is not registered
279  }
280  return 0;
281 }
282 
283 TClonesArray* FairRootManager::GetTClonesArray(TString branchName)
284 {
285  if (fActiveContainer.find(branchName) != fActiveContainer.end()) {
286  return fActiveContainer[branchName]; // return the container
287  } else {
288  LOG(info) << "Branch: " << branchName.Data() << " not registered!";
289  }
290  // error if the branch is not registered
291  return 0;
292 }
293 
295 {
297  if (id < fBranchSeqId) {
298  TObjString* ObjStr = static_cast<TObjString*>(fBranchNameList->At(id));
299  return ObjStr->GetString();
300  } else {
301  TString NotFound("Branch not found");
302  return NotFound;
303  }
304 }
305 
306 Int_t FairRootManager::GetBranchId(TString const& BrName)
307 {
309  TObjString* ObjStr;
310  Int_t Id = -1;
311  for (Int_t t = 0; t < fBranchNameList->GetEntries(); t++) {
312  ObjStr = static_cast<TObjString*>(fBranchNameList->TList::At(t));
313  if (BrName == ObjStr->GetString()) {
314  Id = t;
315  break;
316  }
317  }
318  return Id;
319 }
320 
321 void FairRootManager::InitTSBuffer(TString branchName, BinaryFunctor* function)
322 {
323  fTSBufferMap[branchName] = new FairTSBufferFunctional(branchName, GetInTree(), function);
324 }
325 
326 TClonesArray* FairRootManager::GetData(TString branchName, BinaryFunctor* function, Double_t parameter)
327 {
328  if (fTSBufferMap[branchName] == 0) {
329  fTSBufferMap[branchName] = new FairTSBufferFunctional(branchName, GetInTree(), function);
330  }
331  fTSBufferMap[branchName]->SetStopFunction(function);
332  return fTSBufferMap[branchName]->GetData(parameter);
333 }
334 
335 TClonesArray* FairRootManager::GetData(TString branchName,
336  BinaryFunctor* startFunction,
337  Double_t startParameter,
338  BinaryFunctor* stopFunction,
339  Double_t stopParameter)
340 {
341  if (fTSBufferMap[branchName] == 0) {
342  fTSBufferMap[branchName] = new FairTSBufferFunctional(branchName, GetInTree(), stopFunction, startFunction);
343  }
344  fTSBufferMap[branchName]->SetStopFunction(stopFunction);
345  fTSBufferMap[branchName]->SetStartFunction(startFunction);
346  return fTSBufferMap[branchName]->GetData(startParameter, stopParameter);
347 }
348 
349 void FairRootManager::TerminateTSBuffer(TString branchName)
350 {
351  if (fTSBufferMap.count(branchName) > 0) {
352  fTSBufferMap[branchName]->Terminate();
353  }
354 }
355 
357 {
358  for (auto& mi : fTSBufferMap) {
359  mi.second->Terminate();
360  }
361 }
362 
364 {
365  for (auto& mi : fTSBufferMap) {
366  if (mi.second->AllDataProcessed() == kFALSE && mi.second->TimeOut() == kFALSE) {
367  return kFALSE;
368  }
369  }
370  return kTRUE;
371 }
372 
374 {
375  if (fSink)
376  fSink->Fill();
377 }
378 
380 {
381  // FairMonitor::GetMonitor()->StoreHistograms(); MOVED TO FairRootFileSink
382  if (fFillLastData) {
383  if (fSink)
384  fSink->Fill();
385  }
386 }
387 
388 Int_t FairRootManager::Write(const char*, Int_t, Int_t)
389 {
392  LOG(debug) << "FairRootManager::Write " << this;
393 
394  if (fSink)
395  return (fSink->Write());
396 
397  return 0;
398 }
399 
401 {
403  if (fSink)
404  fSink->WriteGeometry();
405 }
406 
407 void FairRootManager::CreateGeometryFile(const char* geofile)
408 {
414  TFile* oldfile = gFile;
415  TFile* file = TFile::Open(geofile, "RECREATE");
416  file->cd();
417  gGeoManager->Write();
418  file->Close();
419  file->Delete();
420  gFile = oldfile;
421 }
422 
424 {
425  if (fSink) {
426  fSink->WriteFolder();
427  fSink->WriteObject(fBranchNameList, "BranchList", TObject::kSingleKey);
428  fSink->WriteObject(fTimeBasedBranchNameList, "TimeBasedBranchList", TObject::kSingleKey);
429  }
430 }
432 {
433  if (!fSource) {
434  LOG(fatal) << "No Source available";
435  return false;
436  }
437  Bool_t Result = fSource->SpecifyRunId();
438  fSource->FillEventHeader(fEventHeader);
439  LOG(info) << "---FairRootManager::SpecifyRunId --- ";
440  return Result;
441 }
443 {
444  if (!fSource)
445  return 0;
446 
447  fSource->Reset();
448 
449  SetEntryNr(i);
450 
451  if (!fSource) {
452  LOG(fatal) << "No Source available";
453  return -1;
454  }
455 
456  fCurrentEntryNo = i;
457 
458  Int_t readEventResult = fSource->ReadEvent(i);
459 
460  fSource->FillEventHeader(fEventHeader);
461  fCurrentTime = fEventHeader->GetEventTime();
462 
463  LOG(debug) << "--Event number --- " << fCurrentEntryNo << " with t0 time ---- " << fCurrentTime;
464 
465  return readEventResult;
466 }
467 
468 void FairRootManager::ReadBranchEvent(const char* BrName, Int_t entry)
469 {
470  if (!fSource)
471  return;
472  fSource->Reset();
473  SetEntryNr(entry);
474 
475  fSource->ReadBranchEvent(BrName, entry);
476  fSource->FillEventHeader(fEventHeader);
477  fCurrentTime = fEventHeader->GetEventTime();
478 }
479 
481 {
482  if (fSource) {
483  fSource->FillEventHeader(fEventHeader);
484  return fEventHeader->GetRunId();
485  }
486  return -1;
487 }
488 
489 void FairRootManager::ReadBranchEvent(const char* BrName)
490 {
491  if (fSource) {
492  fSource->ReadBranchEvent(BrName);
493  fSource->FillEventHeader(fEventHeader);
494  fCurrentTime = fEventHeader->GetEventTime();
495  }
496 }
497 
499 {
500  if (fSource) {
501  TObject* Obj;
502  fListOfNonTimebasedBranchesIter->Reset();
503  while ((Obj = fListOfNonTimebasedBranchesIter->Next())) {
504  fSource->ReadBranchEvent(Obj->GetName(), Entry);
505  fSource->FillEventHeader(fEventHeader);
506  fCurrentTime = fEventHeader->GetEventTime();
507  }
508  } else {
509  return 0;
510  }
511  return 1;
512 }
513 
515 {
516  Bool_t readentry = kFALSE;
518  return readentry;
519 }
520 
521 TObject* FairRootManager::GetObject(const char* BrName)
522 {
523  fReqBrNames.emplace_back(BrName);
525  TObject* Obj = nullptr;
526  LOG(debug2) << " Try to find if the object " << BrName << " is already activated by another task or call";
528  if (fOutFolder) {
529  Obj = fOutFolder->FindObjectAny(BrName);
530  if (Obj) {
531  LOG(debug2) << "Object " << BrName << " was already activated by another task";
532  }
533  }
535  if (!Obj) {
536  LOG(debug2) << "Try to find if the object " << BrName << " is a memory branch";
537  Obj = GetMemoryBranch(BrName);
538  if (Obj) {
539  LOG(debug2) << "Object " << BrName << " is a memory branch";
540  }
541  }
543  if (fRootFolder && !Obj) {
545  LOG(debug2) << "Object " << BrName
546  << " is not a memory branch and not yet activated, try the Input Tree (Chain)";
547  Obj = fRootFolder->FindObjectAny(BrName);
548  Obj = ActivateBranch(BrName);
549  }
550  if (!Obj) {
551  Obj = ActivateBranch(BrName);
552  }
553  if (Obj != nullptr)
555  return Obj;
556 }
557 
559 {
560  TObject* result = 0;
561 
562  // std::cout << "GetCloneOfLinkData: Link " << link << std::endl;
563  Int_t fileId = link.GetFile();
564  Int_t entryNr = link.GetEntry();
565  Int_t type = link.GetType();
566  Int_t index = link.GetIndex();
567 
568  Int_t oldEntryNr = GetEntryNr();
569 
570  // std::cout << "OldEntryNr: " << GetEntryNr();
571 
572  // std::cout << "GetLinkData: " << link << std::endl;
573 
574  TTree* dataTree; // get the correct Tree
575  if (fileId < 0) {
576  dataTree = GetInTree();
577  } else if (fileId == 0) {
578  dataTree = GetInChain();
579  } else {
580  dataTree = GetSignalChainNo(fileId);
581  }
582 
583  if (dataTree == 0) {
584  dataTree = GetInTree();
585  }
586 
587  if (type < 0) {
588  return 0;
589  }
590 
591  TBranch* dataBranch = 0;
592 
593  // std::cout << "DataType: " << GetBranchName(type) << std::endl;
594 
595  if (fileId < 0 && fInputBranchMap[type] != 0) {
596  dataBranch = fInputBranchMap[type];
597  } else if (fileId < 0) {
598  fInputBranchMap[type] = dataTree->GetBranch(GetBranchName(type));
599  dataBranch = fInputBranchMap[type];
600  } else {
601  dataBranch = dataTree->GetBranch(GetBranchName(type));
602  }
603 
604  if (dataBranch == 0) {
605  return 0;
606  }
607 
608  if (entryNr > -1) { // get the right entry (if entryNr < 0 then the current entry is taken
609  if (entryNr < dataBranch->GetEntries()) {
610  dataBranch->GetEntry(entryNr);
611  } else {
612  return 0;
613  }
614  } else { // the link entry nr is negative --> take the actual one
615 
616  // std::cout << "EntryNr: " << GetEntryNr() << std::endl;
617  // dataBranch->GetEntry(GetEntryNr());
618  }
619 
620  if (index < 0) { // if index is -1 then this is not a TClonesArray so only the Object is returned
621  result = GetObject(GetBranchName(type))->Clone();
622  } else {
623  TClonesArray* dataArray = static_cast<TClonesArray*>(GetObject(GetBranchName(type)));
624 
625  // std::cout << "FairRootManager::GetCloneOfLinkData() dataArray size: " << dataArray->GetEntriesFast()
626  // << std::endl;
627  if (index < dataArray->GetEntriesFast()) {
628  // std::cout << "DataArray at index " << index << " has Link: " <<
629  // ((FairMultiLinkedData*)dataArray->At(index))->GetNLinks() << std::cout;
630  result = dataArray->At(index)->Clone();
631  // std::cout << "Result: " << *((FairMultiLinkedData*)result) << std::endl;
632  }
633  }
634  if (entryNr > -1) {
635  dataBranch->GetEntry(oldEntryNr); // reset the dataBranch to the original entry
636  }
637  return result;
638 }
639 
641 {
642  TClonesArray* result = 0;
643 
644  // std::cout << "GetCloneOfLinkData: Link " << link << std::endl;
645  Int_t fileId = link.GetFile();
646  Int_t entryNr = link.GetEntry();
647  Int_t type = link.GetType();
648  Int_t index = link.GetIndex();
649 
650  Int_t oldEntryNr = GetEntryNr();
651 
652  // std::cout << "OldEntryNr: " << GetEntryNr();
653 
654  // std::cout << "GetLinkData: " << link << std::endl;
655 
656  TTree* dataTree; // get the correct Tree
657  if (fileId < 0) {
658  dataTree = GetInTree();
659  } else if (fileId == 0) {
660  dataTree = GetInChain();
661  } else {
662  dataTree = GetSignalChainNo(fileId);
663  }
664 
665  if (dataTree == 0) {
666  dataTree = GetInTree();
667  }
668 
669  if (type < 0) {
670  return 0;
671  }
672 
673  TBranch* dataBranch = 0;
674 
675  // std::cout << "DataType: " << GetBranchName(type) << std::endl;
676 
677  if (fileId < 0 && fInputBranchMap[type] != 0) {
678  dataBranch = fInputBranchMap[type];
679  } else if (fileId < 0) {
680  fInputBranchMap[type] = dataTree->GetBranch(GetBranchName(type));
681  dataBranch = fInputBranchMap[type];
682  } else {
683  dataBranch = dataTree->GetBranch(GetBranchName(type));
684  }
685 
686  if (dataBranch == 0) {
687  return 0;
688  }
689 
690  if (entryNr > -1) { // get the right entry (if entryNr < 0 then the current entry is taken
691  if (entryNr < dataBranch->GetEntries()) {
692  dataBranch->GetEntry(entryNr);
693  } else {
694  return 0;
695  }
696  } else { // the link entry nr is negative --> take the actual one
697 
698  // std::cout << "EntryNr: " << GetEntryNr() << std::endl;
699  // dataBranch->GetEntry(GetEntryNr());
700  }
701 
702  if (index < 0) { // if index is -1 then this is not a TClonesArray so only the Object is returned
703  result = 0;
704  } else {
705  result = static_cast<TClonesArray*>(GetObject(GetBranchName(type))->Clone());
706  }
707  if (entryNr > -1) {
708  dataBranch->GetEntry(oldEntryNr); // reset the dataBranch to the original entry
709  }
710  return result;
711 }
712 
713 Int_t FairRootManager::CheckBranch(const char* BrName)
714 {
716  if (!fBranchPerMap) {
717  CreatePerMap();
718  return CheckBranchSt(BrName);
719  } else {
720  fBrPerMapIter = fBrPerMap.find(BrName);
721  if (fBrPerMapIter != fBrPerMap.end()) {
722  return fBrPerMapIter->second;
723  } else {
724  return 0;
725  }
726  }
727 }
728 
730 {
731  if (list == nullptr)
732  return;
733  // otherwise clear existing and add via the standard interface
734  fBranchNameList->Clear();
735  fMCTrackBranchId = -1;
736  for (Int_t t = 0; t < list->GetEntries(); t++) {
737  AddBranchToList(static_cast<TObjString*>(list->At(t))->GetString().Data());
738  }
739 }
740 
741 void FairRootManager::SetInChain(TChain* tempChain, Int_t ident)
742 {
743  if (ident <= 0)
744  fSourceChain = tempChain;
745  else
746  fSignalChainList[ident] = tempChain;
747 }
748 
749 Double_t FairRootManager::GetEventTime() { return fCurrentTime; }
750 
752 {
753  for (Int_t iobj = 0; iobj <= fNObj; iobj++) {
754  if (fObj2[iobj]) {
755  LOG(info) << "FairRootManager::UpdateBranches \"" << fObj2[iobj]->GetName() << "\" (\""
756  << fObj2[iobj]->GetTitle() << "\")";
757  TString tempBranchName = fObj2[iobj]->GetName();
758  fSource->ActivateObject(&fObj2[fNObj], tempBranchName.Data());
759  }
760  }
761 }
762 
765 TObject* FairRootManager::ActivateBranch(const char* BrName)
766 {
773  fNObj++;
774  fObj2[fNObj] = GetMemoryBranch(BrName);
775  if (fObj2[fNObj]) {
776  return fObj2[fNObj];
777  }
779  LOG(debug) << "Try to find an object " << BrName << " describing the branch in the folder structure in file";
780  if (fListFolder) {
781  for (Int_t i = 0; i < fListFolder->GetEntriesFast(); i++) {
782  TFolder* fold = static_cast<TFolder*>(fListFolder->At(i));
783  fObj2[fNObj] = fold->FindObjectAny(BrName);
784  if (fObj2[fNObj]) {
785  LOG(info) << "Object " << BrName << " describing the branch in the folder structure was found";
786  break;
787  }
788  }
789  }
790 
791  if (!fObj2[fNObj]) {
795  LOG(info) << " Branch: " << BrName << " not found in Tree.";
796  // Fatal(" No Branch in the tree", BrName );
797  return 0;
798  } else {
799  if (fSource)
800  fSource->ActivateObject(&fObj2[fNObj], BrName);
801  }
802 
803  AddMemoryBranch(BrName, fObj2[fNObj]);
804  return fObj2[fNObj];
805 }
806 
807 void FairRootManager::AddMemoryBranch(const char* fName, TObject* pObj)
808 {
810  map<TString, TObject*>::iterator p;
811  TString BrName = fName;
812  p = fMap.find(BrName);
813  if (p != fMap.end()) {
814  } else {
815  fMap.insert(pair<TString, TObject*>(BrName, pObj));
816  }
817 }
818 
819 Int_t FairRootManager::CheckBranchSt(const char* BrName)
820 {
821  // cout <<"FairRootManager::CheckBranchSt : " << BrName << endl;
822  Int_t returnvalue = 0;
823  TObject* Obj1 = nullptr;
824 
825  if (fListFolder == 0) {
826  fListFolder = new TObjArray(16);
827  }
828 
829  // cout <<"FairRootManager::CheckBranchSt : " <<fRootFolder << endl;
830  if (fRootFolder) {
831  fListFolder->Add(fRootFolder);
832  Obj1 = fRootFolder->FindObjectAny(BrName);
833  }
834  if (fOutFolder && !Obj1) {
835  fListFolder->Add(fOutFolder);
836  Obj1 = fOutFolder->FindObjectAny(BrName); // Branch in output folder
837  }
838  if (!Obj1) {
839  for (Int_t i = 0; i < fListFolder->GetEntriesFast(); i++) {
840  // cout << "Search in Folder: " << i << " " << fListFolder->At(i) << endl;
841  TFolder* fold = dynamic_cast<TFolder*>(fListFolder->At(i));
842  if (fold != 0) {
843  Obj1 = fold->FindObjectAny(BrName);
844  }
845  if (Obj1) {
846  break;
847  }
848  }
849  }
850  TObject* Obj2 = nullptr;
851  Obj2 = GetMemoryBranch(BrName); // Branch in Memory
852  if (Obj1 != 0) {
853  returnvalue = 1;
854  } else if (Obj2 != 0) {
855  returnvalue = 2;
856  } else {
857  returnvalue = 0;
858  }
859 
864  return returnvalue;
865 }
866 
867 void FairRootManager::CreatePerMap()
868 {
869  // cout << " FairRootManager::CreatePerMap() " << endl;
870  fBranchPerMap = kTRUE;
871  for (Int_t i = 0; i < fBranchSeqId; i++) {
872  TObjString* name = static_cast<TObjString*>(fBranchNameList->At(i));
873  // cout << " FairRootManager::CreatePerMap() Obj At " << i << " is " << name->GetString() << endl;
874  TString BrName = name->GetString();
875  fBrPerMap.insert(pair<TString, Int_t>(BrName, CheckBranchSt(BrName.Data())));
876  }
877 }
878 
879 TObject* FairRootManager::GetMemoryBranch(const char* fName)
880 {
881 
882  // return fMap[BrName];
883  TString BrName = fName;
884  map<TString, TObject*>::iterator p;
885  p = fMap.find(BrName);
886 
887  if (p != fMap.end()) {
888  return p->second;
889  } else {
890  return 0;
891  }
892 }
893 
895 {
896  if (fSink)
897  fSink->WriteObject(f, "FileHeader", TObject::kSingleKey);
898 }
899 
901 {
902  if (fSource)
903  return fSource->CheckMaxEventNo(EvtEnd);
904  return 0;
905 }
906 
908 {
909  if (fWriteoutBufferMap[branchName] == 0) {
910  fWriteoutBufferMap[branchName] = buffer;
911  } else {
912  LOG(warn) << "Branch " << branchName.Data() << " is already registered in WriteoutBufferMap";
913  delete buffer;
914  }
915 
916  return fWriteoutBufferMap[branchName];
917 }
918 
920 {
925  for (auto& mi : fWriteoutBufferMap) {
926  if (mi.second->IsBufferingActivated())
927  fTimeBasedBranchNameList->AddLast(new TObjString(mi.first.Data()));
928  }
929 }
930 
932 {
937  if (list != 0) {
938  fTimeBasedBranchNameList->Delete();
939  delete fTimeBasedBranchNameList;
940  fTimeBasedBranchNameList = list;
941  }
942 }
943 
944 FairWriteoutBuffer* FairRootManager::GetWriteoutBuffer(TString branchName)
945 {
946  if (fWriteoutBufferMap.count(branchName) > 0) {
947  return fWriteoutBufferMap[branchName];
948  } else {
949  return 0;
950  }
951 }
952 
954 {
955  for (auto& mi : fWriteoutBufferMap) {
956  mi.second->WriteOutData(eventTime);
957  }
958 }
959 
961 {
962  Bool_t dataInBuffer = kFALSE;
963  for (auto& mi : fWriteoutBufferMap) {
964  if (mi.second->GetNData() > 0) {
965  dataInBuffer = kTRUE;
966  }
967  mi.second->WriteOutAllData();
968  }
969  fFillLastData = dataInBuffer;
970 }
971 
973 {
974  for (auto& mi : fWriteoutBufferMap) {
975  mi.second->DeleteOldData();
976  }
977 }
978 
980 {
981  char* default_name = (char*)"cbmsim";
982  char* workdir = getenv("VMCWORKDIR");
983  if (nullptr == workdir) {
984  return default_name;
985  }
986 
987  // Open file with output tree name
988  FILE* file = fopen(Form("%s/config/rootmanager.dat", workdir), "r");
989  // If file does not exist -> default
990  if (nullptr == file) {
991  return default_name;
992  }
993 
994  char str[100];
995  while (nullptr != fgets(str, 100, file)) {
996  if (TString(str).Contains("treename")) {
997  char* treename = new char[100];
998  if (1 == sscanf(str, "treename=%s", treename)) {
999  fclose(file);
1000  return treename;
1001  }
1002  delete[] treename;
1003  }
1004  }
1005 
1006  // Key "treename" was not found in file: return default
1007  fclose(file);
1008  return default_name;
1009 }
1010 
1012 {
1013  char* default_name = (char*)"cbmout";
1014  if (!FairRun::Instance()->IsAna()) {
1015  default_name = (char*)"cbmroot";
1016  }
1017  char* workdir = getenv("VMCWORKDIR");
1018  if (nullptr == workdir) {
1019  return default_name;
1020  }
1021 
1022  // Open file with output tree name
1023  FILE* file = fopen(Form("%s/config/rootmanager.dat", workdir), "r");
1024  // If file does not exist -> default
1025  if (nullptr == file) {
1026  return default_name;
1027  }
1028 
1029  char str[100];
1030  while (nullptr != fgets(str, 100, file)) {
1031  if (TString(str).Contains("foldername")) {
1032  char* foldername = new char[100];
1033  if (1 == sscanf(str, "foldername=%s", foldername)) {
1034  fclose(file);
1035  return foldername;
1036  }
1037  delete[] foldername;
1038  }
1039  }
1040 
1041  // Key "foldername" was not found in file: return default
1042  fclose(file);
1043  return default_name;
1044 }
1045 
1046 void FairRootManager::EmitMemoryBranchWrongTypeWarning(const char* brname, const char* type1, const char* type2) const
1047 {
1048  LOG(warn) << "Trying to read from memory branch " << brname << " with wrong type " << type1
1049  << " (expexted: " << type2 << " )";
1050 }
1051 
1052 void FairRootManager::UpdateFileName(TString& fileName)
1053 {
1054  TString tid = "_t";
1055  tid += GetInstanceId();
1056  fileName.Insert(fileName.Index(".root"), tid);
1057 }
1058 
1060 {
1061  LOG(WARNING) << "FairRootManager::GetOutFile() deprecated. Use separate file to store additional data.";
1062  auto sink = GetSink();
1063  assert(sink->GetSinkType() == kFILESINK);
1064  auto rootFileSink = static_cast<FairRootFileSink*>(sink);
1065  return rootFileSink->GetRootFile();
1066 }
1067 
1069 {
1070  LOG(WARNING) << "FairRootManager::GetOutTree() deprecated. Use separate file to store additional data.";
1071  auto sink = GetSink();
1072  assert(sink->GetSinkType() == kFILESINK);
1073  auto rootFileSink = static_cast<FairRootFileSink*>(sink);
1074  return rootFileSink->GetOutTree();
1075 }
1076 
static char * GetTreeName()
void CreateGeometryFile(const char *geofile)
virtual Int_t ReadEvent(UInt_t=0)=0
Int_t CheckMaxEventNo(Int_t EvtEnd=0)
void SetBranchNameList(TList *list)
TObject * GetCloneOfLinkData(const FairLink link)
TChain * GetInChain()
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)=0
Int_t ReadEvent(Int_t i=0)
virtual void FillEventHeader(FairEventHeader *feh)
Definition: FairSource.cxx:31
TClonesArray * GetCloneOfTClonesArray(const FairLink link)
FairWriteoutBuffer * RegisterWriteoutBuffer(TString branchName, FairWriteoutBuffer *buffer)
virtual void ReadBranchEvent(const char *)
Definition: FairSource.h:52
Int_t AddBranchToList(const char *name)
static FairRun * Instance()
Definition: FairRun.cxx:31
void InitTSBuffer(TString branchName, BinaryFunctor *function)
static FairMonitor * GetMonitor()
Definition: FairMonitor.cxx:66
void WriteFileHeader(FairFileHeader *f)
void SetEntryNr(Int_t val)
static FairRootManager * Instance()
ClassImp(FairEventBuilder)
void RecordGetting(const char *name)
virtual void WriteFolder()=0
TObject * GetObject(const char *BrName)
Int_t ReadNonTimeBasedEventFromBranches(Int_t i=0)
Double_t GetEventTime()
TClonesArray * GetData(TString branchName, BinaryFunctor *function, Double_t parameter)
void RecordRegister(const char *name, const char *folderName, Bool_t toFile)
FairSink * GetSink()
Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
void SetInChain(TChain *tempChain, Int_t ident=-1)
TClonesArray * GetTClonesArray(TString branchName)
virtual Bool_t SpecifyRunId()=0
void SetTimeBasedBranchNameList(TList *list)
TChain * GetSignalChainNo(UInt_t i)
static FairLinkManager * Instance()
void StoreAllWriteoutBufferData()
virtual Bool_t Init()=0
virtual Int_t CheckMaxEventNo(Int_t=0)
Definition: FairSource.h:50
virtual void AddIgnoreType(Int_t type)
Double_t GetEventTime()
void RegisterInputObject(const char *name, TObject *obj)
Int_t GetInstanceId() const
TString GetBranchName(Int_t id)
void TerminateTSBuffer(TString branchName)
virtual Bool_t InitSink()=0
void Register(const char *name, const char *Foldername, TNamed *obj, Bool_t toFile)
virtual void Fill()=0
TClonesArray * GetEmptyTClonesArray(TString branchName)
Bool_t ReadNextEvent(Double_t dt)
static char * GetFolderName()
virtual void RegisterImpl(const char *, const char *, void *)=0
void UpdateFileName(TString &fileName)
void UpdateListOfTimebasedBranches()
virtual void WriteGeometry()=0
Int_t CheckBranch(const char *BrName)
Bool_t IsAna()
Definition: FairRun.h:109
void DeleteOldWriteoutBufferData()
virtual void Reset()=0
virtual void WriteObject(TObject *f, const char *, Int_t option=0)=0
Base class for all functors which are used in the FairTSBufferFunctional.
virtual Bool_t ActivateObject(TObject **, const char *)
Definition: FairSource.h:43
A container class to store digi data during events.
void StoreWriteoutBufferData(Double_t eventTime)
void ReadBranchEvent(const char *BrName)
A class to access time ordered data in a root branch.
Int_t GetBranchId(TString const &BrName)
virtual ~FairRootManager()