Project
Loading...
Searching...
No Matches
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
39FairRootFileSink::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
55FairRootFileSink::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
72FairRootFileSink::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
91TFile* 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
121void 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
198void 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
235void 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
249void 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 =
263 Form("/%s_%d", FairRootManager::GetFolderName(), FairRootManager::Instance()->GetInstanceId()),
264 99);
265 TruncateBranchNames();
267 }
268}
269
270namespace impl {
271// a helper function to demangle a type_name
272inline 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
309void 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
330Int_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
std::ostringstream debug
ClassImp(FairRootFileSink)
const int16_t bb
uint32_t res
Definition RawData.h:0
void StoreHistograms(TFile *sinkFile)
static FairMonitor * GetMonitor()
virtual bool CreatePersistentBranchesAny()
virtual TFile * OpenRootFile(TString fileName="")
virtual void WriteObject(TObject *f, const char *, Int_t option=0)
FairRootFileSink(TFile *f, const char *Title="OutputRootFile")
virtual void WriteFolder()
virtual void RegisterAny(const char *brname, const std::type_info &oi, const std::type_info &pi, void *obj)
virtual FairSink * CloneSink()
virtual void RegisterImpl(const char *, const char *, void *)
virtual void FillEventHeader(FairEventHeader *feh)
virtual Bool_t InitSink()
virtual void WriteGeometry()
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
static const char * GetFolderName()
void UpdateFileName(TString &fileName)
static const char * GetTreeName()
static FairRootManager * Instance()
Int_t GetInstanceId() const
std::map< std::string, std::unique_ptr< TypeAddressPair const > > fPersistentBranchesMap
Definition FairSink.h:92
TFolder * fOutFolder
Definition FairSink.h:88
GLuint const GLchar * name
Definition glcorearb.h:781
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
std::string demangle(const char *name)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"