Universita' di GenovaINFN Sezione di Genova  
AIRWATCH / EUSO Genova

SimuRootFileManager - source file

// $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; 
}
About Us | EUSO Official Website | Web pages created by Roberto Pesce and Alessandro Thea - Last Update 14-May-2005 21:31