// $Id: SimuRootFileManager.cc,v 1.17 2005/04/18 12:52:26 thea Exp $
// Author: A.Thea 29/06/2004
/*****************************************************************************
* ESAF: Euso Simulation and Analysis Framework *
* *
* Id: SimuRootFileManager *
* Package: Gui *
* Coordinator: Alessandro.Thea, Marco.Pallavicini *
* *
*****************************************************************************/
//_____________________________________________________________________________
//
// Simu Rootfile Manager
// =====================
//
// Manager of the simulation root file. This object handles the creation and
// the filling of the rootfile according to its configuration file.
//
// The manager controls creation and branching of the TTree and also is in
// charge to split the file when its size is bigger than fMaxSize.
//
// Config file parameters
// ======================
//
// fSaveShower [bool]: enable/disable EShower object in EEvent
//
// fSaveAtmosphere [bool]: enable/disable EAtmosphere object in EEvent
//
// fSaveDetector [bool]: enable/disable EDetector object in EEvent
//
// fSaveChipTrackTrigger [bool]: enable/disable EChipTrackTrigger in EEvent
//
// fDetector.fPhotonFillable [bool]: enable/disable EPhotons in EEvent
//
// fDetector.fNightGlowFillable [bool]: enable/disable all NightGlow EFee
// hits in EEvent
//
// fSaveRunTree [bool]: enable/disable runtree in rootfile
//
// fMaxFileSize [Mbyte]: Maximum file size.
//
#include "SimuRootFileManager.hh"
#include "EEvent.hh"
#include "ERunParameters.hh"
#include "TTree.h"
#include "TBranchRef.h"
#include "TSystem.h"
#include "TTime.h"
ClassImp(SimuRootFileManager)
//_____________________________________________________________________________
SimuRootFileManager::SimuRootFileManager() : fEvent(0), fRunPars(0),
fEventsTree(0), fRunTree(0), fFile(0), fFileNumber(0) {
//
// Constructor
//
fEventBranches = EEvent::kAll;
fDetectorPhotonFillable = kTRUE;
// read setting for the event
if ( !Conf()->GetBool("SimuRootFileManager.fSaveShower") )
fEventBranches &= ~EEvent::kShower;
if ( !Conf()->GetBool("SimuRootFileManager.fSaveAtmosphere") )
fEventBranches &= ~EEvent::kAtmosphere;
if ( !Conf()->GetBool("SimuRootFileManager.fSaveDetector") )
fEventBranches &= ~EEvent::kDetector;
if ( !Conf()->GetBool("SimuRootFileManager.fSaveChipTrackTrigger") )
fEventBranches &= ~EEvent::kChipTrackTrigger;
// default: save photons in EDetector
fDetectorPhotonFillable = Conf()->GetBool("SimuRootFileManager.fDetector.fPhotonFillable");
fDetectorNightGlowFillable = Conf()->GetBool("SimuRootFileManager.fDetector.fNightGlowFillable");
fSaveRunTree = Conf()->GetBool("SimuRootFileManager.fSaveRunTree");
fMaxFileSize = (Long64_t)Conf()->GetNum("SimuRootFileManager.fMaxFileSize")*1024*1024;
if ( fMaxFileSize > TTree::GetMaxTreeSize() ) {
// if fMaxFileSize exceeds the maximum size of a TTree, reset the size
// 100 Mb smaller than fgMaxTreeSize to avoid conflicts
fMaxFileSize = TTree::GetMaxTreeSize()-100*1024*1024;
MsgForm(EsafMsg::Warning,"fMaxFileSize exceeds TTree::GetMaxTreeSize()");
MsgForm(EsafMsg::Warning,"Setting fMaxFileSize = %ld",fMaxFileSize);
}
// build data containers
Build();
}
//_____________________________________________________________________________
SimuRootFileManager::~SimuRootFileManager() {
//
// Destructor
//
SafeDelete(fEvent);
SafeDelete(fRunPars);
SafeDelete(fEventsTree);
SafeDelete(fRunTree);
SafeDelete(fFile);
}
//_____________________________________________________________________________
Bool_t SimuRootFileManager::Build() {
//
// build event and run parameters and set the static pointers
//
if ( fEvent ) delete fEvent; fEvent = 0;
if ( fRunPars ) delete fRunPars; fRunPars = 0;
fEvent = new EEvent( fEventBranches );
EEvent::SetCurrent( fEvent );
if (fSaveRunTree) {
fRunPars = new ERunParameters();
ERunParameters::SetCurrent( fRunPars );
}
if ( fEvent->GetDetector() ) {
fEvent->GetDetector()->SetPhotonFillable( fDetectorPhotonFillable );
fEvent->GetDetector()->SetNightGlowFillable( fDetectorNightGlowFillable );
}
return kTRUE;
}
//_____________________________________________________________________________
void SimuRootFileManager::Clear() {
//
// Clear all objects
//
fEvent->Clear();
fRunPars->Clear();
}
//_____________________________________________________________________________
Bool_t SimuRootFileManager::Open( const char* name ) {
//
// Open a new rootfile and set the trees up
//
string ext = ".root";
if ( name == 0 )
fFileName = Conf()->GetStr("SimuRootFileManager.fRootOutputFile");
else
fFileName = name;
if (fFileName.rfind(ext) != (fFileName.size()-ext.size()))
fFileName += ext;
if ( !gSystem->AccessPathName(fFileName.c_str()) ) {
// fname.root exists. try to add current date
MsgForm(EsafMsg::Warning,"Error opening file");
MsgForm(EsafMsg::Warning,"Probably it already exists or there is no ");
MsgForm(EsafMsg::Warning,"write access permission to this directory");
fFileName.resize(fFileName.size()-5);
time_t t = time(NULL);
char buffer[64];
strftime(buffer, 64,".%d-%b-%G-%Hh%Mm%Ss", localtime(&t));
fFileName += buffer;
fFileName += ext;
}
fFile = new TFile(fFileName.c_str(),"CREATE");
if (fFile->IsZombie())
FatalError("Cannot open root file");
MsgForm(EsafMsg::Info,"Root file %s successfully opened",fFileName.c_str());
if ( fEventsTree ) delete fEventsTree;
fEventsTree = new TTree("etree","EventsTree");
fEvent->BranchTree( fEventsTree );
if ( fSaveRunTree ) {
// FIXME this tree must be removed
// RunPars should be saved just using Write() (no tree)
if ( fRunTree ) delete fRunTree;
fRunTree = new TTree("runtree","RunTree");
fRunTree->Branch("runpars","ERunParameters",&fRunPars);
}
return kTRUE;
}
//_____________________________________________________________________________
Bool_t SimuRootFileManager::Close() {
//
// Save all trees and close current rootfile
//
if ( !fFile ) return kFALSE;
// check file
if ( ( fEventsTree && fFile != fEventsTree->GetCurrentFile() ) ||
( fRunTree && fFile != fRunTree->GetCurrentFile() ) )
MsgForm(EsafMsg::Warning, "Mismatch among tree files and opened file");
fFile->Write();
SafeDelete(fEventsTree);
SafeDelete(fRunTree);
fFile->Close();
MsgForm(EsafMsg::Info,"%s closed.",fFile->GetName());
return kTRUE;
}
//______________________________________________________________________________
Int_t SimuRootFileManager::FillEventsTree() {
//
// Calls fEventsTree->Fill and updates fFile if nedded.
// It is forseen that it will also handle automatic file splitting when
// approacing to size limit.
//
if ( !fEventsTree ) return 0;
if ( fFile->GetEND() > fMaxFileSize ) {
Msg(EsafMsg::Warning) << "Current root file has reached the maximum allowed size."
<< " Switching to a new TFile" << MsgDispatch;
fFile->Write();
fEventsTree->Reset();
// open the new file
fFileNumber++;
string newfilename = fFileName;
newfilename.insert(newfilename.size()-5,Form("_%d",fFileNumber));
TFile *newfile = new TFile(newfilename.c_str(),"CREATE");
if ( newfile->IsZombie() ) FatalError("Cannot open "+newfilename);
Msg(EsafMsg::Warning) << newfilename << " succesfully open." << MsgDispatch;
//WARNING: does TTree:Clone() mantain the connecton with the branched objects?
TTree* newruntree = (TTree*)fRunTree->CloneTree();
// move events tree to the new file
TBranch* branch;
fEventsTree->SetDirectory(newfile);
TIter nextb(fEventsTree->GetListOfBranches());
while ((branch = (TBranch*)nextb())) {
branch->SetFile(newfile);
}
if (fEventsTree->GetBranchRef())
fEventsTree->GetBranchRef()->SetFile(newfile);
delete fFile;
fFile = newfile;
//WARNING: what shall I do with the old tree?
fRunTree = newruntree;
}
Int_t bytes = fEventsTree->Fill();
fFile = fEventsTree->GetCurrentFile();
return bytes;
}
//______________________________________________________________________________
Int_t SimuRootFileManager::FillRunTree() {
if ( !fRunTree )
return 0;
return fRunTree->Fill();
}
//______________________________________________________________________________
void SimuRootFileManager::ResetRunPars() {
//
// Reset run parameters and their reference
//
if (!fRunPars) return;
// clear object
fRunPars->Clear();
// reset unique id
fRunPars->SetUniqueID(0);
fRunPars->ResetBit(kHasUUID);
// generate a new UID
fRunParsRef = fRunPars;
}