FairRoot
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FairRootManager.h
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 #ifndef FAIR_ROOT_MANAGER_H
9 #define FAIR_ROOT_MANAGER_H
10 
11 #include "FairLogger.h"
12 #include "FairSink.h"
13 #include "FairSource.h"
14 
15 #include <Rtypes.h> // for Bool_t, Int_t, UInt_t, etc
16 #include <TChain.h> // for TChain
17 #include <TMCtls.h> // for multi-threading
18 #include <TObject.h> // for TObject
19 #include <TString.h> // for TString, operator<
20 #include <map> // for map, multimap, etc
21 #include <memory>
22 #include <string>
23 #include <type_traits> // is_pointer, remove_pointer, is_const, remove...
24 #include <typeinfo>
25 #include <vector>
26 
27 class BinaryFunctor;
28 class FairEventHeader;
29 class FairFileHeader;
30 class FairLink;
32 class FairWriteoutBuffer;
33 class TBranch;
34 class TClonesArray;
35 class TObjArray;
36 class TCollection;
37 class TFile;
38 class TFolder;
39 class TIterator;
40 class TList;
41 class TNamed;
42 class TRefArray;
43 class TTree;
44 
52 class FairRootManager : public TObject
53 {
54  public:
56  virtual ~FairRootManager();
57  Bool_t AllDataProcessed();
59  Int_t AddBranchToList(const char* name);
66  Int_t CheckBranch(const char* BrName);
67 
68  void CloseSink()
69  {
70  if (fSink) {
71  fSink->Close();
72  }
73  }
75  void CreateGeometryFile(const char* geofile);
76  void Fill();
77  void LastFill();
78  TClonesArray* GetEmptyTClonesArray(TString branchName);
79  TClonesArray* GetTClonesArray(TString branchName);
81  void UpdateBranches();
82 
84  TString GetBranchName(Int_t id);
86  Int_t GetBranchId(TString const& BrName);
87 
89  Int_t GetMCTrackBranchId() const { return fMCTrackBranchId; }
90 
92  TList* GetBranchNameList() { return fBranchNameList; }
94  const std::vector<std::string>& GetReqBranchNames() const { return fReqBrNames; }
95 
102  TObject* GetObject(const char* BrName);
103 
108  template<typename T>
109  T InitObjectAs(const char* BrName);
110 
112  Double_t GetEventTime();
114  TObject* GetCloneOfLinkData(const FairLink link);
121  TClonesArray* GetCloneOfTClonesArray(const FairLink link);
122 
123  void InitTSBuffer(TString branchName, BinaryFunctor* function);
124  TClonesArray* GetData(TString branchName, BinaryFunctor* function, Double_t parameter);
125  TClonesArray* GetData(TString branchName,
126  BinaryFunctor* startFunction,
127  Double_t startParameter,
128  BinaryFunctor* stopFunction,
129  Double_t stopParameter);
130  void RegisterTSBuffer(TString branchName, FairTSBufferFunctional* functionalBuffer)
131  {
132  fTSBufferMap[branchName] = functionalBuffer;
133  }
134  void TerminateTSBuffer(TString branchName);
135  void TerminateAllTSBuffer();
136  FairTSBufferFunctional* GetTSBuffer(TString branchName) { return fTSBufferMap[branchName]; }
137 
139  static FairRootManager* Instance();
140 
142  Int_t ReadEvent(Int_t i = 0);
144  Int_t ReadNonTimeBasedEventFromBranches(Int_t i = 0);
146  void ReadBranchEvent(const char* BrName);
148  void ReadBranchEvent(const char* BrName, Int_t entry);
149 
152  Int_t GetRunId();
153 
154  Bool_t ReadNextEvent(Double_t dt);
160  void Register(const char* name, const char* Foldername, TNamed* obj, Bool_t toFile);
166  void Register(const char* name, const char* Foldername, TCollection* obj, Bool_t toFile);
167 
169  template<typename T>
170  void RegisterAny(const char* name, T*& obj, Bool_t toFile);
175 
176  void RegisterInputObject(const char* name, TObject* obj);
177 
178  TClonesArray* Register(TString branchName, TString className, TString folderName, Bool_t toFile);
181  FairWriteoutBuffer* RegisterWriteoutBuffer(TString branchName, FairWriteoutBuffer* buffer);
185  void RunWithTimeStamps() { fTimeStamps = kTRUE; }
186 
188  void SetBranchNameList(TList* list);
190  void SetTimeBasedBranchNameList(TList* list);
191 
193  {
194  if (fSource)
195  fSource->FillEventHeader(feh);
196  }
197 
199  void SetLastFill(Bool_t val = kTRUE) { fFillLastData = val; }
204  Int_t Write(const char* name = 0, Int_t option = 0, Int_t bufsize = 0);
206  void WriteGeometry();
210  void WriteFolder();
211 
213  Int_t CheckMaxEventNo(Int_t EvtEnd = 0);
214 
215  void StoreWriteoutBufferData(Double_t eventTime);
218 
219  Int_t GetEntryNr() { return fEntryNr; }
220  void SetEntryNr(Int_t val) { fEntryNr = val; }
221 
222  void SetUseFairLinks(Bool_t val) { fUseFairLinks = val; };
223  Bool_t GetUseFairLinks() const { return fUseFairLinks; };
224 
229  /* void SetMixAllInputs(Bool_t Status) { */
230  /* fMixAllInputs=kTRUE; */
231  /* } */
232 
234  void SetSource(FairSource* tempSource) { fSource = tempSource; }
235  FairSource* GetSource() { return fSource; }
236  Bool_t InitSource();
237 
238  void SetSink(FairSink* tempSink) { fSink = tempSink; }
239  FairSink* GetSink() { return fSink; }
240  Bool_t InitSink();
241 
242  void SetListOfFolders(TObjArray* ta) { fListFolder = ta; }
243  TChain* GetInChain() { return fSourceChain; }
244  TChain* GetSignalChainNo(UInt_t i) { return fSignalChainList[i]; }
245  TTree* GetInTree()
246  {
247  if (fSourceChain)
248  return fSourceChain->GetTree();
249  return 0;
250  }
251  const TFile* GetRootFile()
252  {
253  if (fSourceChain)
254  return fSourceChain->GetFile();
255  return 0;
256  }
257  TFile* GetInFile()
258  {
259  if (fSourceChain)
260  return fSourceChain->GetFile();
261  return 0;
262  }
263  void SetInChain(TChain* tempChain, Int_t ident = -1);
264  /* /\**Set the input tree when running on PROOF worker*\/ */
265 
266  void SetFinishRun(Bool_t val = kTRUE) { fFinishRun = val; }
267  Bool_t FinishRun() { return fFinishRun; }
268 
269  static char* GetTreeName();
270 
271  static char* GetFolderName();
272 
274  Int_t GetInstanceId() const { return fId; }
275  void UpdateFileName(TString& fileName);
276 
277  // vvvvvvvvvv depracted functions, replaced by FairSink vvvvvvvvvv
279  TFile* GetOutFile();
281  TTree* GetOutTree();
282  // ^^^^^^^^^^ depracted functions, replaced by FairSink ^^^^^^^^^^
283 
285  Bool_t SpecifyRunId();
286 
287  private:
288  // helper struct since std::pair has problems with type_info
289  struct TypeAddressPair
290  {
291  TypeAddressPair(const std::type_info& oi, const std::type_info& pi, void* a)
292  : origtypeinfo(oi)
293  , persistenttypeinfo(pi)
294  , ptraddr(a)
295  {}
296  const std::type_info& origtypeinfo; // type_info of type addr points to
297  const std::type_info& persistenttypeinfo; // type_info of ROOT persistent branch (drops pointers)
298  void* ptraddr; // address of a pointer (pointing to origtypeinfo);
299  };
300 
303  FairRootManager();
305  FairRootManager& operator=(const FairRootManager&);
308  TObject* ActivateBranch(const char* BrName);
309  void AddFriends();
311  void AddMemoryBranch(const char*, TObject*);
312 
313  template<typename T>
314  void AddMemoryBranchAny(const char* name, T** obj);
315  template<typename T>
316  T GetMemoryBranchAny(const char* name) const;
317 
318  template<typename T>
319  void RegisterImpl(const char* name, const char* Foldername, T* obj, Bool_t toFile);
320 
327  Int_t CheckBranchSt(const char* BrName);
329  void CreatePerMap();
330  TObject* GetMemoryBranch(const char*);
331  // void GetRunIdInfo(TString fileName, TString inputLevel);
332 
333  FairWriteoutBuffer* GetWriteoutBuffer(TString branchName);
334 
335  // private helper function to emit a warning
336  void EmitMemoryBranchWrongTypeWarning(const char* brname, const char* typen1, const char* typen2) const;
337 
339  Int_t fOldEntryNr;
341  TFolder* fOutFolder;
343  TFolder* fRootFolder;
345  Double_t fCurrentTime;
346  TObject** fObj2;
347 
348  Int_t fNObj;
349 
353  std::map<TString, TObject*> fMap;
354 
358  std::map<std::string, std::unique_ptr<TypeAddressPair const>> fAnyBranchMap;
359  std::vector<std::string> fPersistentBranchesAny;
361 
363  Int_t fBranchSeqId;
365  TList* fBranchNameList;
366 
367  std::vector<std::string> fReqBrNames;
368 
370  Int_t fMCTrackBranchId;
371 
373  TList* fTimeBasedBranchNameList;
374 
375  std::map<TString, TClonesArray*> fActiveContainer;
377  std::map<TString, FairTSBufferFunctional*> fTSBufferMap;
378  std::map<TString, FairWriteoutBuffer*> fWriteoutBufferMap;
379  std::map<Int_t, TBranch*> fInputBranchMap;
380 
381  Bool_t fTimeStamps;
383  Bool_t fBranchPerMap;
385  std::map<TString, Int_t> fBrPerMap;
386 
387  std::map<TString, Int_t>::iterator fBrPerMapIter;
388 
390  UInt_t fCurrentEntryNo;
391 
392  UInt_t fTimeforEntryNo;
393  Bool_t fFillLastData;
394  Int_t fEntryNr;
395 
396  TObjArray* fListFolder;
397 
398  FairSource* fSource;
399 
400  TChain* fSourceChain;
401  std::map<UInt_t, TChain*> fSignalChainList;
402 
403  FairEventHeader* fEventHeader;
404 
405  FairSink* fSink;
406 
407  Bool_t fUseFairLinks;
408  Bool_t fFinishRun;
409 
410  TObjArray* fListOfBranchesFromInput;
411 
412  TIterator* fListOfBranchesFromInputIter;
413 
414  TRefArray* fListOfNonTimebasedBranches;
415 
416  TIterator* fListOfNonTimebasedBranchesIter;
417 
419  // global static data members
420  static Int_t fgCounter; // The counter of instances
421  // data members
422  Int_t fId; // This manager ID
423 
424  ClassDef(FairRootManager, 12);
425 };
426 
427 // FIXME: move to source since we can make it non-template dependent
428 template<typename T>
429 void FairRootManager::AddMemoryBranchAny(const char* brname, T** obj)
430 {
431  if (fAnyBranchMap.find(brname) == fAnyBranchMap.end()) {
432  auto& ot = typeid(T*);
433  auto& pt = typeid(T);
434  fAnyBranchMap[brname] = std::unique_ptr<TypeAddressPair const>(new TypeAddressPair(ot, pt, (void*)obj));
435  }
436 }
437 
438 // try to retrieve an object address from the registered branches/names
439 template<typename T>
440 T FairRootManager::GetMemoryBranchAny(const char* brname) const
441 {
442  static_assert(std::is_pointer<T>::value, "Return type of GetMemoryBranchAny has to be a pointer");
443  using P = typename std::remove_pointer<T>::type;
444  auto iter = fAnyBranchMap.find(brname);
445  if (iter != fAnyBranchMap.end()) {
446  // verify type consistency
447  if (typeid(P).hash_code() != iter->second->origtypeinfo.hash_code()) {
448  EmitMemoryBranchWrongTypeWarning(brname, typeid(P).name(), iter->second->origtypeinfo.name());
449  return nullptr;
450  }
451  return static_cast<T>(iter->second->ptraddr);
452  }
453  return nullptr;
454 }
455 
456 template<typename T>
457 void FairRootManager::RegisterAny(const char* brname, T*& obj, bool persistence)
458 {
459  AddBranchToList(brname);
460  // we are taking the address of the passed pointer
461  AddMemoryBranchAny<T>(brname, &obj);
462  if (persistence) {
463  auto& ot = typeid(T*);
464  auto& pt = typeid(T);
465  if (fSink)
466  fSink->RegisterAny(brname, ot, pt, &obj);
467  else
468  LOG(fatal) << "The sink does not exist to store persistent branches.";
469  }
470 }
471 
472 // this function serves as a factory (or lookup) for memory managed
473 // instances associated to branches
474 // it returns a pointer to unmodifiable instance of T
475 template<typename TPtr>
476 TPtr FairRootManager::InitObjectAs(const char* brname)
477 {
478  static_assert(std::is_pointer<TPtr>::value, "Return type of GetObjectAs has to be a pointer");
479  using X = typename std::remove_pointer<TPtr>::type;
480  static_assert(std::is_const<X>::value, "Return type of GetObjectAs has to be pointer to const class");
481  using T = typename std::remove_const<X>::type;
482 
483  // is there already an object associated to the branch in memory??
484  // then just return
485  T** obj = GetMemoryBranchAny<T**>(brname);
486  // obj is some address/instance holding TPtr instances
487  if (obj != nullptr)
488  return *obj;
489 
490  if (!fSource) {
491  return nullptr;
492  }
493 
494  // it does not seem to be the case, let us create the pointer which will be initialized
495  // with the data (pointer to T)
496  T** addr = new T*;
497  // init the pointee to a default obj which we can return
498  (*addr) = new T;
499  // try to find and activate in the source
500  auto succeeded = fSource->ActivateObjectAny((void**)addr, typeid(T), brname);
501 
502  if (!succeeded) {
503  delete (*addr);
504  delete addr;
505  return nullptr;
506  }
507  // add into branch list
508  AddMemoryBranchAny<T>(brname, addr);
509  // register as a **requested** branch
510  // (duplications are explicitely allowed)
511  fReqBrNames.emplace_back(brname);
512 
513  // NOTE: ideally we would do proper resource management for addr and *addr
514  // since the FairRootManager becomes owner of these pointers/instances; Unfortunately this
515  // is quite a difficult task since we would have to store something like std::unique_ptr<T> in a member
516  // container which we cannot know a priori; Some solutions we could think of in the future are
517  // a) use the Destructor mechanism of ROOT::TClass since we still have the type info.
518  // b) investigate if boost::any could be of help here
519  // In any case, this problem is not very critical in the sense that FairRootManager is a singleton and hence
520  // cannot really leak memory (Assuming that the destructors of T are not doing something non-trivial).
521  return *addr;
522 }
523 
524 #endif // FAIR_ROOT_MANAGER_H
static char * GetTreeName()
virtual Bool_t ActivateObjectAny(void **, const std::type_info &, const char *)
Definition: FairSource.h:44
void CreateGeometryFile(const char *geofile)
Int_t CheckMaxEventNo(Int_t EvtEnd=0)
void SetBranchNameList(TList *list)
virtual void RegisterAny(const char *brname, const std::type_info &oi, const std::type_info &pi, void *obj)=0
TObject * GetCloneOfLinkData(const FairLink link)
TChain * GetInChain()
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)
const std::vector< std::string > & GetReqBranchNames() const
T InitObjectAs(const char *BrName)
Int_t AddBranchToList(const char *name)
void InitTSBuffer(TString branchName, BinaryFunctor *function)
void WriteFileHeader(FairFileHeader *f)
void SetEntryNr(Int_t val)
void SetFinishRun(Bool_t val=kTRUE)
static FairRootManager * Instance()
void SetSink(FairSink *tempSink)
TObject * GetObject(const char *BrName)
Int_t ReadNonTimeBasedEventFromBranches(Int_t i=0)
TClonesArray * GetData(TString branchName, BinaryFunctor *function, Double_t parameter)
FairSink * GetSink()
Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
TList * GetBranchNameList()
void SetInChain(TChain *tempChain, Int_t ident=-1)
TClonesArray * GetTClonesArray(TString branchName)
FairTSBufferFunctional * GetTSBuffer(TString branchName)
void SetTimeBasedBranchNameList(TList *list)
FairSource * GetSource()
TChain * GetSignalChainNo(UInt_t i)
Int_t GetMCTrackBranchId() const
void StoreAllWriteoutBufferData()
void SetLastFill(Bool_t val=kTRUE)
Double_t GetEventTime()
Bool_t GetUseFairLinks() const
void SetListOfFolders(TObjArray *ta)
void RegisterInputObject(const char *name, TObject *obj)
Int_t GetInstanceId() const
TString GetBranchName(Int_t id)
void TerminateTSBuffer(TString branchName)
virtual void Close()=0
void Register(const char *name, const char *Foldername, TNamed *obj, Bool_t toFile)
TClonesArray * GetEmptyTClonesArray(TString branchName)
Bool_t ReadNextEvent(Double_t dt)
static char * GetFolderName()
void SetSource(FairSource *tempSource)
void UpdateFileName(TString &fileName)
void UpdateListOfTimebasedBranches()
const TFile * GetRootFile()
Int_t CheckBranch(const char *BrName)
void DeleteOldWriteoutBufferData()
Base class for all functors which are used in the FairTSBufferFunctional.
A container class to store digi data during events.
void StoreWriteoutBufferData(Double_t eventTime)
void ReadBranchEvent(const char *BrName)
void RegisterTSBuffer(TString branchName, FairTSBufferFunctional *functionalBuffer)
A class to access time ordered data in a root branch.
void RegisterAny(const char *name, T *&obj, Bool_t toFile)
Int_t GetBranchId(TString const &BrName)
void FillEventHeader(FairEventHeader *feh)
virtual ~FairRootManager()
bool CreatePersistentBranchesAny()
void SetUseFairLinks(Bool_t val)