// $Id: RecoFramework.cc,v 1.37 2005/11/01 12:11:31 naumov Exp $
// Author: Marco Pallavicini Oct, 16 2003
//
/*****************************************************************************
* ESAF: Euso Simulation and Analysis Framework *
* *
* Id: RecoFramework *
* Package: framework *
* Coordinator: Marco.Pallavicini *
* *
*****************************************************************************/
#include "RecoFramework.hh"
#include "Config.hh"
#include "ModuleFactory.hh"
#include "RecoModule.hh"
#include "InputModule.hh"
#include "RecoEvent.hh"
#include "RecoRootEvent.hh"
#include "TruthModule.hh"
#include "EsafMsgDispatcher.hh"
#include <TTree.h>
#include <TFile.h>
#include <TObjectTable.h>
#include <TDirectory.h>
#include <TBenchmark.h>
ClassImp(RecoFramework)
//_____________________________________________________________________________
RecoFramework::RecoFramework(int argc, char** argv) : EsafConfigurable(), EsafMsgSource(), fRootFile(NULL) {
//
// Costructor
//
ParseCommandLine(argc,argv);
const char log[] = "output/reco.root";
EsafMsgDispatcher::Get()->LoadConfig();
EsafMsgDispatcher::Get()->OpenLog(log);
Msg(EsafMsg::Info) << "Logging to file " << log <<".log" << " started" << MsgDispatch;
// get file name with module list
string sName = Conf()->GetStr("RecoFramework.ModuleFile");
sName = "./config/Reco/"+sName;
// build factory
ModuleFactory factory( sName );
// get unique input module
fInputModule = factory.GetInputModule();
if ( fInputModule == NULL ) {
Msg(EsafMsg::Panic) << "Cannot run without input module"<< MsgDispatch;
}
// get modules
Int_t counter=0;
while ( RecoModule *aModule = factory.GetModule() ) {
Msg(EsafMsg::Info) << "Loading module : " << aModule->GetName() << MsgDispatch;
fModules.push_back(aModule);
counter++;
}
Msg(EsafMsg::Info) << "RecoFramework: " << counter << " modules loaded" << MsgDispatch;
fCurrentEvent = 0;
}
//_____________________________________________________________________________
RecoFramework::~RecoFramework() {
//
// Destructor
//
}
//_____________________________________________________________________________
void RecoFramework::ParseCommandLine(int& argc, char** argv) {
//
// Parse a command line
//
map<string,string> cmdArgs;
for(Int_t i=1; i<argc; i++)
if (strncmp(argv[i],"--",2)==0) {
// Ok, it seems to be user-defined var
string s = argv[i]+2;
size_t pos = s.find('.');
if ( pos == string::npos )
FatalError("Invalid parameter "+string(argv[i]));
else
// user defined variable syntax
// ClassName::VarName
// fUsrKeys.push_back(s.substr(0,pos));
// fUsrValues.push_back(s);
cmdArgs[s.substr(0,pos)] = s;
}
map<string,string>::iterator it;
// for (size_t i(0); i< fUsrKeys.size(); i++) {
// Config::Get()->AddUserDefinition(fUsrKeys[i],fUsrValues[i]);
// }
for(it = cmdArgs.begin(); it!=cmdArgs.end(); it++)
Config::Get()->AddUserDefinition(it->first, it->second);
}
//_____________________________________________________________________________
void RecoFramework::Execute() {
//
// Execute a complete run
//
string dumpRootEvent = Conf()->GetStr("RecoFramework.DumpRootEvent");
// init input module
fInputModule->Init();
// init all modules
for( Int_t i=0; i<(Int_t)fModules.size(); i++ ) {
if ( !fModules[i]->Init() ) {
Msg(EsafMsg::Panic) << "Module " << fModules[i]->GetName() << " failed" << MsgDispatch;
}
}
OpenRoot();
TString jobname = Form("Reconstruction Job");
TBenchmark bJob;
bJob.Start(jobname);
// run
while ( RecoEvent *anEvent = fInputModule->GetEvent() ) {
fCurrentEvent++;
fRecoRootEvent->Clear();
if (fInputModule->GetName() == "Root")
fInputModule->SaveRootData(fRecoRootEvent);
if ( anEvent->GetHeader().GetNumActiveFee() != 0 ) {
TBenchmark bEvent;
TString s = Form("Event %d",fCurrentEvent);
bEvent.Start(s);
// execute all modules
for( Int_t i=0; i<(Int_t)fModules.size(); i++) {
if ( ! fModules[i]->PreProcess() )
break;
if ( ! fModules[i]->Process( anEvent ) )
break;
if ( ! fModules[i]->PostProcess() )
break;
if ( ! fModules[i]->SaveRootData(fRecoRootEvent) )
break;
// write the module data in the event
anEvent->PutRecoModuleData(fModules[i]->GetName(), fModules[i]->GetData());
}
if (dumpRootEvent == "yes" ) fRecoRootEvent->Dump();
fRecoTree->Fill();
// clean up
fInputModule->DestroyEvent(); // delete input event
for( Int_t i=0; i<(Int_t)fModules.size(); i++) {
fModules[i]->UserMemoryClean(); // delete user objects
fModules[i]->StandardMemoryClean(); // delete Int_t and Double_t maps
}
bEvent.Stop(s);
MsgForm(EsafMsg::Info,"Time per event %d: REAL=%6.2f s CPU=%6.2f s",fCurrentEvent,
bEvent.GetRealTime(s), bEvent.GetCpuTime(s));
}
else {
fInputModule->DestroyEvent();
}
} // end event loop
// end all modules
fInputModule->Done();
for( Int_t i=0; i<(Int_t)fModules.size(); i++) {
fModules[i]->Done();
}
CloseRoot();
bJob.Stop(jobname);
MsgForm(EsafMsg::Info,"Average time per event: REAL=%6.2f s CPU=%6.2f s",
bJob.GetRealTime(jobname)/fCurrentEvent, (bJob.GetCpuTime(jobname)/fCurrentEvent) );
MsgForm(EsafMsg::Info,"Total time: REAL=%6.2f s CPU=%6.2f s",
bJob.GetRealTime(jobname), bJob.GetCpuTime(jobname));
}
//_____________________________________________________________________________
void RecoFramework::Dump( ostream& os ) const {
//
// Dump the module list
//
Msg(EsafMsg::Debug) << "Framework Dump" << MsgDispatch;
Msg(EsafMsg::Debug) << "The following Modules where loaded:" << MsgDispatch;
Msg(EsafMsg::Debug) << "InputModule: " << fInputModule->GetName() << MsgDispatch;
for( Int_t i=0; i<(Int_t)fModules.size(); i++ ) {
Msg(EsafMsg::Debug) << "Module: " << i+1 << "t" << fModules[i]->GetName()<< MsgDispatch;
}
}
//_____________________________________________________________________________
void RecoFramework::OpenRoot() {
//
// Open output rootfile
//
string filename, rootname;
if (fInputModule->fInputFileName == "") {
filename = Form("output/reco.root");
} else {
filename = fInputModule->fInputFileName.c_str();
}
string ext = ".root";
if ( filename.rfind(ext) == ( filename.size()-ext.size() ) ) filename.resize(filename.size()-ext.size());
rootname = filename + ".reco.root";
fRootFile = new TFile(rootname.c_str(), "CREATE");
if ( fRootFile->IsZombie() ) {
delete fRootFile;
// try adding date and time to the name
char timestr[100];
time_t tt=time(NULL);
strftime(timestr,99,"%d-%b-%G:%H:%M:%S",localtime(&tt));
rootname = Form("%s.%s.reco.root",filename.c_str(),timestr);
fRootFile = new TFile(rootname.c_str(),"CREATE");
if (fRootFile->IsZombie())
throw runtime_error("Cannot open root file");
}
Msg(EsafMsg::Info) << "Root file " << filename << " successfully opened" << MsgDispatch;
fRecoTree = new TTree("recotree","RecoTree");
CreateRecoRootEvent();
fRecoTree->Branch("events","RecoRootEvent",&fRecoRootEvent);
}
//_____________________________________________________________________________
void RecoFramework::CreateRecoRootEvent() {
//
// Create RecoRootEvent
//
fRecoRootEvent = new RecoRootEvent();
}
//_____________________________________________________________________________
void RecoFramework::CloseRoot() {
//
// Close output rootfile
//
if ( fRootFile ) {
fRecoTree->Write();
fRecoTree->AutoSave("SelfSave");
Msg(EsafMsg::Info) << "************************ " << setw(4) <<
fRecoTree->GetEntries() << " events read ************************" <<
MsgDispatch;
Msg(EsafMsg::Info) << MsgDispatch;
Msg(EsafMsg::Info) << fRecoTree->GetEntries() << " entries are written into " << fRootFile->GetName()<< MsgDispatch;
fRootFile->Close();
delete fRootFile;
}
}