Universita' di GenovaINFN Sezione di Genova  
AIRWATCH / EUSO Genova

SimuRootFileManager - source file

// $Id: SimuRootFileManager.cc,v 1.7 2005/10/28 13:38:23 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
//
//   fSaveLblTrackTrigger [bool]: enable/disable ELblTrackTrigger 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 "EDetector.hh"
#include "ERunParameters.hh"
#include "Config.hh"

#include "TTree.h"
#include "TBranchRef.h"
#include "TSystem.h"
#include "TTimeStamp.h"

ClassImp(SimuRootFileManager)

//_____________________________________________________________________________
 SimuRootFileManager::SimuRootFileManager() : fEvent(0), fRunPars(0), 
    fTree(0), fFile(0), fFileNumber(0) { //fRunTree(0)
    // 
    // Constructor
    //

    fEventBranches = EEvent::kAll;
    fDetectorPhotonFillable = kTRUE;

    //
    ConfigFileParser* pConfig = Config::Get()->GetCF("LightToEuso","StandardLightToEuso");
    string noevent = pConfig->GetStr("StandardLightToEuso.fGenerator");

    // read setting for the event
    if ( !Conf()->GetBool("SimuRootFileManager.fSaveShower") || (noevent == "noevent"))
        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;
    if ( !Conf()->GetBool("SimuRootFileManager.fSaveLblTrackTrigger") )
        fEventBranches &= ~EEvent::kLblTrackTrigger;

    // default: save photons in EDetector
    fDetectorPhotonFillable = Conf()->GetBool("SimuRootFileManager.fDetector.fPhotonFillable");
    fDetectorNightGlowFillable = Conf()->GetBool("SimuRootFileManager.fDetector.fNightGlowFillable");

    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(fTree);

    SafeDelete(fFile);
}

//_____________________________________________________________________________
 Bool_t SimuRootFileManager::Build() {
    // 
    // build event and run parameters and set the static pointers
    //

    if ( fEvent ) delete fEvent; fEvent = 0;
    
    fEvent = new EEvent( fEventBranches );
    EEvent::SetCurrent( fEvent );

    fRunPars = fEvent->GetRunPars();

    if ( fEvent->GetDetector() ) {
        fEvent->GetDetector()->SetPhotonFillable( fDetectorPhotonFillable );
        fEvent->GetDetector()->SetNightGlowFillable( fDetectorNightGlowFillable );
    }
    
    return kTRUE;
}

//_____________________________________________________________________________
 void SimuRootFileManager::Clear() {
    // 
    // Clear all objects
    //

    fEvent->Clear();

}

//_____________________________________________________________________________
 Bool_t SimuRootFileManager::Open( const char* name ) {
    // 
    // Open a new rootfile and set the trees up
    //

    TString ext = ".root";
    fFileName = name ? name : Conf()->GetStr("SimuRootFileManager.fRootOutputFile");

    if (!fFileName.EndsWith(ext))
    fFileName += ext;

    if ( !gSystem->AccessPathName(fFileName)  ) {
        // 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");

        TTimeStamp now;

        UInt_t hour, min, sec, year, month, day;
        now.GetDate(kFALSE,0,&year,&month,&day);
        now.GetTime(kFALSE,0,&hour,&min,&sec);
        TString time = Form(".%4d-%02d-%02d-%02dh%02dm%02ds",year,month,day,hour,min, sec);
        fFileName.Insert(fFileName.Length()-ext.Length(),time);

    }

    fFile = new TFile(fFileName,"CREATE");
    if (fFile->IsZombie()) 
        MsgForm(EsafMsg::Panic,"File %s cannot be opened",fFileName.Data());

    MsgForm(EsafMsg::Info,"Root file %s successfully opened",fFileName.Data());

    if ( fTree ) delete fTree;
    fTree = new TTree("etree","Events Tree");

    return kTRUE;
}


//______________________________________________________________________________
 void SimuRootFileManager::LockEvent() {
    //
    // Branch the tree but not the run parameters.
    // The run parameters will be added by hand in the Unlock
    //
    if ( !fTree ) return;

    fEvent->BranchTree( fTree, kFALSE );

}


//______________________________________________________________________________
 void SimuRootFileManager::UnlockEvent() {
    //
    // Disconnects the Event from the tree.
    //

    if ( !fTree ) return;
    
    // check the current file
    if ( ( fFile != fTree->GetCurrentFile() ) ) 
        MsgForm(EsafMsg::Warning, "Mismatch among tree files and opened file");

    if ( fEvent->IsLinked())
        MsgForm(EsafMsg::Warning,"The event is linked with the tree");
    
    // Clone parameters and store them in the tree
    TObject* pars = fEvent->GetRunPars()->Clone();
    fTree->GetUserInfo()->Add(pars);
    
    // Save the tree into the file
    fTree->Write();
    
    // Delete the tree
    SafeDelete(fTree);
}

//_____________________________________________________________________________
 Bool_t SimuRootFileManager::Close() {
    // 
    // Save all trees and close current rootfile
    //

    if ( !fFile ) return kFALSE;

    // check file
//    if ( ( fTree && fFile != fTree->GetCurrentFile() ) ) 
//        MsgForm(EsafMsg::Warning, "Mismatch among tree files and opened file");

    fFile->Write();

//    SafeDelete(fTree);
    //SafeDelete(fRunTree);

    fFile->Close();
    MsgForm(EsafMsg::Info,"%s closed.",fFile->GetName());

    SafeDelete(fFile)

    return kTRUE;
}

//______________________________________________________________________________
 Int_t SimuRootFileManager::FillEvent() {
    //
    // Calls fTree->Fill and updates fFile if nedded.
    // It is forseen that it will also handle automatic file splitting when
    // approacing to size limit.
    // 

    TString ext = ".root";

    if ( !fTree ) 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();
        
        fTree->Reset();
        
        // open the new file
        fFileNumber++;
        TString newfilename = fFileName;
        newfilename.Insert(newfilename.Length()-ext.Length(),Form("_%d",fFileNumber));
        TFile *newfile = new TFile(newfilename,"CREATE");

        if ( newfile->IsZombie() ) MsgForm(EsafMsg::Panic, "Cannot open %s",newfilename.Data());

        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;
        fTree->SetDirectory(newfile);
        TIter nextb(fTree->GetListOfBranches());
        while ((branch = (TBranch*)nextb())) {
            branch->SetFile(newfile);
        }
        
        if (fTree->GetBranchRef())
            fTree->GetBranchRef()->SetFile(newfile);

        delete fFile;
        fFile = newfile;

        //WARNING: what shall I do with the old tree?
        //fRunTree = newruntree;

    }

    Int_t bytes = fTree->Fill();
    fFile = fTree->GetCurrentFile();
    return bytes;
}

//______________________________________________________________________________
 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; 
}
About Us | EUSO Official Website | Web pages created by Roberto Pesce and Alessandro Thea - Last Update Wed Nov 16 16:57:39 2005 Wed Nov 16 16:29:22 2005