FairRoot
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FairRootFileSink.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 version 3 (LGPL) version 3, *
6  * copied verbatim in the file "LICENSE" *
7  ********************************************************************************/
8 // -----------------------------------------------------------------------------
9 // ----- -----
10 // ----- FairRootFileSink -----
11 // ----- Created 22.12.2017 by R. Karabowicz -----
12 // ----- -----
13 // -----------------------------------------------------------------------------
14 
15 #include "FairRootFileSink.h"
16 
17 #include "FairEventHeader.h"
18 #include "FairLogger.h"
19 #include "FairMonitor.h" // to store histograms at the end
20 #include "FairRootManager.h" // to GetTreeName()
21 
22 #include <TBranch.h>
23 #include <TClass.h>
24 #include <TCollection.h>
25 #include <TFolder.h>
26 #include <TGeoManager.h> // for TGeoManager, gGeoManager
27 #include <TIterator.h>
28 #include <TNamed.h>
29 #include <TObjArray.h>
30 #include <TObject.h>
31 #include <TROOT.h>
32 #include <TString.h>
33 #include <TTree.h>
34 #include <cstdlib> // free
35 #include <cxxabi.h> // __cxa_demangle
36 #include <memory> // unique_ptr
37 #include <string> // string
38 
39 FairRootFileSink::FairRootFileSink(TFile* f, const char* Title)
40  : FairSink()
41  , fOutputTitle(Title)
42  , fRootFile(f)
43  , fOutTree(0)
44  , fListFolder(new TObjArray(16))
45  , fCbmout(0)
46  , fIsInitialized(kFALSE)
47  , fFileHeader(0)
48 {
49  if (fRootFile->IsZombie()) {
50  LOG(fatal) << "Error opening the Input file";
51  }
52  LOG(debug) << "FairRootFileSink created------------";
53 }
54 
55 FairRootFileSink::FairRootFileSink(const TString* RootFileName, const char* Title)
56  : FairSink()
57  , fOutputTitle(Title)
58  , fRootFile(0)
59  , fOutTree(0)
60  , fListFolder(new TObjArray(16))
61  , fCbmout(0)
62  , fIsInitialized(kFALSE)
63  , fFileHeader(0)
64 {
65  fRootFile = TFile::Open(RootFileName->Data(), "recreate");
66  if (fRootFile->IsZombie()) {
67  LOG(fatal) << "Error opening the Output file";
68  }
69  LOG(debug) << "FairRootFileSink created------------";
70 }
71 
72 FairRootFileSink::FairRootFileSink(const TString RootFileName, const char* Title)
73  : FairSink()
74  , fOutputTitle(Title)
75  , fRootFile(0)
76  , fOutTree(0)
77  , fListFolder(new TObjArray(16))
78  , fCbmout(0)
79  , fIsInitialized(kFALSE)
80  , fFileHeader(0)
81 {
82  fRootFile = TFile::Open(RootFileName.Data(), "recreate");
83  if (fRootFile->IsZombie()) {
84  LOG(fatal) << "Error opening the Input file";
85  }
86  LOG(debug) << "FairRootFileSink created------------";
87 }
88 
90 
91 TFile* FairRootFileSink::OpenRootFile(TString fileName)
92 {
93  if (fileName.Length() <= 5)
94  return nullptr;
95  return TFile::Open(fileName.Data(), "recreate");
96 }
97 
99 {
100  if (fIsInitialized) {
101  LOG(info) << "FairRootFileSink already initialized";
102  return kTRUE;
103  }
104  fIsInitialized = kTRUE;
105 
106  fRootFile->cd();
107 
108  // FairRun* fRun = FairRun::Instance();
110  fOutFolder = gROOT->GetRootFolder()->AddFolder(
111  Form("%s_%d", FairRootManager::GetFolderName(), FairRootManager::Instance()->GetInstanceId()), "Main Folder");
112  gROOT->GetListOfBrowsables()->Add(fOutFolder);
113 
114  LOG(info) << "FairRootFileSink initialized.";
115  LOG(info) << " - " << fOutFolder->GetName();
116  LOG(info) << " - " << fRootFile->GetName();
117 
118  return kTRUE;
119 }
120 
121 void FairRootFileSink::TruncateBranchNames()
122 {
133  TCollection* lf = fOutFolder->GetListOfFolders();
134  TIterator* iter = lf->MakeIterator();
135  TObjArray* Br = fOutTree->GetListOfBranches();
136  TIterator* BrIter = Br->MakeIterator();
137  TObject* obj;
138  TObject* BrObj;
139 
141  while ((obj = iter->Next())) {
147  TString ffn = (fOutFolder->GetName());
148  ffn = ffn + ".";
149  ffn = ffn + obj->GetName();
150  ffn = ffn + ".";
151 
158  BrIter->Reset();
159 
160  while ((BrObj = BrIter->Next())) {
161  TBranch* b = static_cast<TBranch*>(BrObj);
162  TruncateBranchNames(b, ffn);
163  }
164  }
165 
166  // Remove all occurence of FairMCEventHeader and from
167  // all branches containing that string.
168  // This is not the correct way to do it, but up tonow we don't understand
169  // why this part comes in when storing a derrived class from
170  // FairMCEventHeader or FairEventHeader.
171 
172  iter->Reset();
173  while ((obj = iter->Next())) {
174  TString ffn = ".FairMCEventHeader";
175  BrIter->Reset();
176 
177  while ((BrObj = BrIter->Next())) {
178  TBranch* b = static_cast<TBranch*>(BrObj);
179  TruncateBranchNames(b, ffn);
180  }
181  }
182 
183  iter->Reset();
184  while ((obj = iter->Next())) {
185  TString ffn = ".FairEventHeader";
186  BrIter->Reset();
187 
188  while ((BrObj = BrIter->Next())) {
189  TBranch* b = static_cast<TBranch*>(BrObj);
190  TruncateBranchNames(b, ffn);
191  }
192  }
193 
194  delete iter;
195  delete BrIter;
196 }
197 
198 void FairRootFileSink::TruncateBranchNames(TBranch* b, TString ffn)
199 {
206  TObject* BrObj;
207  TString nn = b->GetName();
208  LOG(debug) << "nn.Data before: " << nn.Data();
209  nn.ReplaceAll(ffn.Data(), "");
210  LOG(debug) << "nn.Data after: " << nn.Data();
211  LOG(debug) << "##################";
212  b->SetName(nn.Data());
213  TObjArray* Br = b->GetListOfBranches();
214  TIterator* BrIter = Br->MakeIterator();
215  BrIter->Reset();
216 
217  while ((BrObj = BrIter->Next())) {
218  TBranch* bb = static_cast<TBranch*>(BrObj);
219  TruncateBranchNames(bb, ffn);
220  }
221  delete BrIter;
222 }
223 
225 {
226  if (fRootFile) {
227  fRootFile->Close();
228  }
229 }
230 
232 
234 
235 void FairRootFileSink::RegisterImpl(const char* /* name */, const char* folderName, void* obj)
236 {
237  TFolder* folder = 0;
238  TFolder* f = 0;
239  f = static_cast<TFolder*>(fOutFolder->FindObjectAny(folderName));
240  if (f == 0) {
241  folder = fOutFolder->AddFolder(folderName, folderName);
242  } else {
243  folder = f;
244  }
245  // ((TNamed*)obj)->SetName(name);
246  folder->Add((TNamed*)obj);
247 }
248 
249 void FairRootFileSink::RegisterAny(const char* brname, const std::type_info& oi, const std::type_info& pi, void* obj)
250 {
251  fPersistentBranchesMap[brname] = std::unique_ptr<TypeAddressPair const>(new TypeAddressPair(oi, pi, obj));
252 }
253 
255 {
256  fRootFile->cd();
257  if (fOutFolder != 0) {
259 
260  // FairRun* fRun = FairRun::Instance();
261  fOutTree =
262  new TTree(FairRootManager::GetTreeName(),
263  Form("/%s_%d", FairRootManager::GetFolderName(), FairRootManager::Instance()->GetInstanceId()),
264  99);
265  TruncateBranchNames();
267  }
268 }
269 
270 namespace impl {
271 // a helper function to demangle a type_name
272 inline std::string demangle(const char* name)
273 {
274  int status = -4; // some arbitrary value to eliminate the compiler warning
275  std::unique_ptr<char, void (*)(void*)> res{abi::__cxa_demangle(name, nullptr, nullptr, &status), std::free};
276  return (status == 0) ? res.get() : name;
277 }
278 } // namespace impl
279 
281 {
282  for (auto& iter : fPersistentBranchesMap) {
283  LOG(info) << "CREATING BRANCH " << iter.first;
284  auto& tinfo = iter.second->persistenttypeinfo;
285  auto tname = impl::demangle(tinfo.name());
286 
287  // for the branch creation we need a TClass describing the object
288  // get it from ROOT via the type name
289  auto cl = TClass::GetClass(tinfo);
290  if (!cl) {
291  LOG(fatal) << "No TClass found for " << tname << "\n";
292  return false;
293  }
294 
295  if (!cl->HasDictionary()) {
296  LOG(fatal) << "No dictionary found for " << tname << "\n";
297  return false;
298  }
299 
300  // create the branch
301  auto obj = iter.second->ptraddr;
302 
303  LOG(info) << "Creating branch for " << iter.first.c_str() << " with address " << obj;
304  fOutTree->Branch(iter.first.c_str(), tname.c_str(), obj);
305  }
306  return true;
307 }
308 
309 void FairRootFileSink::WriteObject(TObject* f, const char* name, Int_t option)
310 {
311  fRootFile->cd();
312  f->Write(name, option);
313 }
314 
316 {
317  fRootFile->cd();
318  gGeoManager->Write();
319 }
320 
322 {
323  if (fOutTree != 0) {
324  fOutTree->Fill();
325  } else {
326  LOG(info) << " No Output Tree";
327  }
328 }
329 
330 Int_t FairRootFileSink::Write(const char*, Int_t, Int_t)
331 {
333  if (fOutTree != 0) {
340  // fOutTree->Print();
341 
342  fRootFile = fOutTree->GetCurrentFile();
344  LOG(debug) << "FairRootFileSink::Write to file: " << fRootFile->GetName();
345  fRootFile->cd();
346  fOutTree->Write();
347  } else {
348  LOG(info) << "No Output Tree";
349  }
350  return 0;
351 }
352 //_____________________________________________________________________________
353 
354 //_____________________________________________________________________________
356 {
358 
359  TString workerFileName = fRootFile->GetName();
360  tempMan->UpdateFileName(workerFileName);
361  FairRootFileSink* newSink = new FairRootFileSink(workerFileName);
362 
363  LOG(info) << "FairRootFileSink::CloneSink(). manager " << tempMan->GetInstanceId();
364  return newSink;
365 }
366 //_____________________________________________________________________________
367 
FairRootFileSink(TFile *f, const char *Title="OutputRootFile")
static char * GetTreeName()
virtual void Fill()
virtual void FillEventHeader(FairEventHeader *feh)
static FairMonitor * GetMonitor()
Definition: FairMonitor.cxx:66
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
static FairRootManager * Instance()
ClassImp(FairEventBuilder)
virtual ~FairRootFileSink()
virtual void RegisterAny(const char *brname, const std::type_info &oi, const std::type_info &pi, void *obj)
virtual bool CreatePersistentBranchesAny()
virtual void WriteGeometry()
virtual void Reset()
virtual void RegisterImpl(const char *, const char *, void *)
virtual FairSink * CloneSink()
std::string demangle(const char *name)
Int_t GetInstanceId() const
virtual void WriteFolder()
virtual void Close()
static char * GetFolderName()
void StoreHistograms(TFile *sinkFile)
void UpdateFileName(TString &fileName)
virtual Bool_t InitSink()
virtual void WriteObject(TObject *f, const char *, Int_t option=0)
virtual TFile * OpenRootFile(TString fileName="")
std::map< std::string, std::unique_ptr< TypeAddressPair const > > fPersistentBranchesMap
Definition: FairSink.h:89
TFolder * fOutFolder
Definition: FairSink.h:85