source: JEM-EUSO/esaf_lal/tags/v1_r0/esaf/packages/reconstruction/framework/src/RecoFramework.cc @ 117

Last change on this file since 117 was 117, checked in by moretto, 11 years ago

ESAF version compilable on mac OS

File size: 18.0 KB
Line 
1// $Id: RecoFramework.cc 2949 2011-06-26 18:39:34Z mabl $
2// Author: Marco Pallavicini Oct, 16 2003
3//
4/*****************************************************************************
5 * ESAF: Euso Simulation and Analysis Framework                              *
6 *                                                                           *
7 *  Id: RecoFramework                                                        *
8 *  Package: framework                                                       *
9 *  Coordinator: Marco.Pallavicini                                           *
10 *                                                                           *
11 *****************************************************************************/
12
13#include "RecoFramework.hh"
14#include "Config.hh"
15#include "ModuleFactory.hh"
16#include "RecoModule.hh"
17#include "InputModule.hh"
18#include "RecoEvent.hh"
19#include "RecoRootEvent.hh"
20#include "TruthModule.hh"
21#include "EsafMsgDispatcher.hh"
22#include "EsafSys.hh"
23
24#include <list>
25#include <TTree.h>
26#include <TFile.h>
27#include <TObjectTable.h>
28#include <TDirectory.h>
29#include <TBenchmark.h>
30#include <TSystem.h>
31#include <TTimeStamp.h>
32
33ClassImp(RecoFramework)
34
35//_____________________________________________________________________________
36RecoFramework::RecoFramework(int argc, char** argv) : EsafConfigurable(), EsafMsgSource(), fRootFile(NULL) {
37    //
38    // Constructor
39    //
40
41    Bool_t isLocal(kFALSE); //FIXME: this should be handled by a CmdLineParser object.
42    string str;
43    for (Int_t i(0); i<argc; str=argv[i++])
44        if (str == "--local")
45            isLocal = kTRUE;
46
47    const char esafsys[]="ESAFSYS";
48    string esafCfgPath;
49
50    TString esafPath;
51    if ( gSystem->Getenv(esafsys) && !isLocal )
52        esafPath = gSystem->Getenv(esafsys);
53    else
54        esafPath = gSystem->WorkingDirectory();
55
56    gEsafSys = new EsafSys(esafPath);
57
58
59    esafCfgPath = gEsafSys->GetCfgPath();
60
61    ConfigFileParser::ChangeConfigDir(esafCfgPath);
62
63    // initialize message dispatcher
64    EsafMsgDispatcher::Get()->LoadConfig();
65   
66    // load standard configs
67    Config::Get()->LoadStandardConfigs();
68
69
70    ParseCommandLine(argc,argv);
71   
72    Init();
73
74    // get file name with module list
75    string sName = Conf()->GetStrPath("RecoFramework.ModuleFile");
76   
77    // build factory
78    ModuleFactory factory( sName );
79   
80    // get unique input module
81    fInputModule = factory.GetInputModule();
82    if ( fInputModule == NULL ) {
83        Msg(EsafMsg::Panic) << "Cannot run without input module"<< MsgDispatch;
84    }
85   
86    // get modules
87    Int_t counter=0;
88    while ( RecoModule *aModule = factory.GetModule() ) {
89        Msg(EsafMsg::Info) <<  "Loading module : " << aModule->GetName() << MsgDispatch;
90        fModules.push_back(aModule);
91        counter++;
92    }
93    Msg(EsafMsg::Info) << "RecoFramework: " << counter << " modules loaded" << MsgDispatch;
94    fCurrentEvent = 0;
95
96}
97
98//_____________________________________________________________________________
99RecoFramework::~RecoFramework() {
100    //
101    // Destructor
102    //
103
104    End();
105}
106
107//_____________________________________________________________________________
108void RecoFramework::ParseCommandLine(int& argc, char** argv) {
109    //
110    // Parse a command line
111    //
112
113//    list<string> usrCfgs;
114//    list< pair<string,string> > cmdArgs;
115   
116    for(Int_t i=1; i<argc; i++)
117        if (strncmp(argv[i],"--",2)==0) {
118            // Ok, it seems to be user-defined var
119            string s = argv[i]+2;
120
121            if ( s=="local" ) {
122                Msg(EsafMsg::Info) << "ESAF-Reco running from the Current Working Directory" << MsgDispatch;
123            } else if ( s.substr(0,7) == "usrcfg=") {
124                fUsrCfgs.push_back(s.substr(7));
125            } else if ( s.substr(0,7) == "stdcfg=" ) {
126                //Standard Configuration
127                string stdcfg = s.substr(7);
128                if ( !Config::Get()->UseConfig( stdcfg ) )
129                    FatalError(stdcfg+" standard config not defined");
130
131            } else if ( s.substr(0,8) == "outpath=" ) {
132                //Standard Configuration
133                 fOutPath = s.substr(8);
134            } else if ( s.substr(0,8) == "outname=" ) {
135                //Standard Configuration
136                 fOutBaseName = s.substr(8);
137
138            }  else if ( s.substr(0,6) == "first=") {
139                string key = "RootInputModule";
140                string value = "RootInputModule.FirstEvent=";
141                value += s.substr(6);
142                fUsrKeys.push_back(key);       
143                fUsrValues.push_back(value);
144                //                Config::Get()->AddUserDefinition(key,value);
145            } else if ( s.substr(0,5) == "last=") {
146                string key = "RootInputModule";
147                string value = "RootInputModule.LastEvent=";
148                value += s.substr(5);
149                fUsrKeys.push_back(key);       
150                fUsrValues.push_back(value);
151                //                Config::Get()->AddUserDefinition(key,value);
152
153            } else{
154                size_t pos = s.find('.');
155                if ( pos == string::npos )
156                    FatalError("Invalid parameter "+string(argv[i]));
157                else {
158                    // user defined variable syntax
159                    // ClassName::VarName
160                    fUsrKeys.push_back(s.substr(0,pos));       
161                    fUsrValues.push_back(s);
162                }
163            }
164
165        } else if ( i == argc-1) {
166            //
167            // filename must be the last parameter
168            //
169
170
171            Msg(EsafMsg::Info) << "Filename set to " << argv[i]  << MsgDispatch;
172            string key = "RootInputModule";
173            string value = "RootInputModule.FileName=";
174            value+=argv[i];
175            fUsrKeys.push_back(key);   
176            fUsrValues.push_back(value);
177            //            Config::Get()->AddUserDefinition(key,value);
178
179        } else {
180             Msg(EsafMsg::Warning) << "Offending argument " << argv[i] << MsgDispatch;
181             Msg(EsafMsg::Info) << argv[0] << " usage:" << MsgDispatch;
182             Msg(EsafMsg::Info) << MsgDispatch;
183             Msg(EsafMsg::Info) << "\t"<< argv[0] << " [ --usrcfg=<file.cfg> --ClassName.VarName=<Value> ] [ file ]" << MsgDispatch;
184             Msg(EsafMsg::Info) << MsgDispatch;
185             
186             FatalError("Reco Terminated");
187        }
188
189
190
191    // load user definition file first
192    vector<string>::const_iterator itCfg;
193    for( itCfg=fUsrCfgs.begin(); itCfg!=fUsrCfgs.end(); itCfg++)
194        Config::Get()->LoadUserConfig(itCfg->c_str());
195
196    // the apply custom parameters
197    for (size_t i(0); i< fUsrKeys.size(); i++) {
198        Config::Get()->AddUserDefinition(fUsrKeys[i],fUsrValues[i]);
199    }
200
201}
202
203
204//______________________________________________________________________________
205void RecoFramework::Init() {
206    //
207    // Initialize reco
208    //
209
210    string filename, rootname, base, dir;
211
212    // FIXME
213//    filename = fInputModule->fInputFileName;
214    filename = Config::Get()->GetCF("Reco","RootInputModule")->GetStr("RootInputModule.FileName");
215   
216    string ext= ".root";
217    if ( filename.rfind(ext) == ( filename.size()-ext.size() ) )
218        filename.resize(filename.size()-ext.size());
219
220
221    if ( !(fOutBaseName.size()) )
222        fOutBaseName = gSystem->BaseName(filename.c_str());
223
224    //
225    // Strip the extension
226    //
227
228    if ( !(fOutPath.size()))
229        fOutPath = gSystem->DirName(filename.c_str());
230   
231    gEsafSys->SetOutPath(fOutPath.c_str());
232
233    string abs_outpath = gEsafSys->AbsolutePath( gEsafSys->GetOutPath());
234   
235    fFileNames[kRoot] = abs_outpath+fOutBaseName+".reco.root";
236    fFileNames[kLog]  = abs_outpath+fOutBaseName+".reco.log";
237    fFileNames[kDump] = abs_outpath+fOutBaseName+".reco.CfgDump.cfg";
238   
239    EsafMsgDispatcher::Get()->OpenLog(fFileNames[kLog]);
240
241    Msg(EsafMsg::Info) << "Logging to file "+fFileNames[kLog]+
242        " started" << MsgDispatch;
243
244    // header data
245    UInt_t len = 80;
246
247    TString head1('_',80); head1[0]=' '; head1[len-1]=' ';
248    TString head2(' ',80); head2[0]='|'; head2[len-1]='|';
249    TString head3('_',80); head3[0]='|'; head3[len-1]='|';
250    TString line, msg;
251
252    Msg(EsafMsg::Info) << head1 << MsgDispatch;
253    Msg(EsafMsg::Info) << head2 << MsgDispatch;
254
255    line = head2;
256    msg  = "ESAF Run Starting";
257    line.Replace(3,msg.Length(),msg.Data(),msg.Length());
258
259    Msg(EsafMsg::Info) << line << MsgDispatch;
260
261    TTimeStamp tStart;
262    line = head2;
263    msg  = Form("Local time: %s",tStart.AsString("l"));
264    line.Replace(5,msg.Length(),msg.Data(),msg.Length());
265
266    Msg(EsafMsg::Info) << line << MsgDispatch;
267
268    Msg(EsafMsg::Info) << head3 << MsgDispatch;
269    Msg(EsafMsg::Info) << MsgDispatch;
270   
271
272    MsgForm(EsafMsg::Info,"ESAF Environment:");
273    Msg(EsafMsg::Info) << MsgDispatch;
274    MsgForm(EsafMsg::Info,"   Current Directory: %s",gSystem->WorkingDirectory());
275    MsgForm(EsafMsg::Info,"   Reco Config Path : %s",gEsafSys->GetCfgPath());
276    MsgForm(EsafMsg::Info,"   Reco Auxilar Path: %s",gEsafSys->GetAuxPath());
277    MsgForm(EsafMsg::Info,"   Reco Tmp Path    : %s",gEsafSys->GetTmpPath());
278    MsgForm(EsafMsg::Info,"   Reco Output Path : %s",gEsafSys->GetOutPath());
279    MsgForm(EsafMsg::Info,"   Host Machine     : %s",gSystem->HostName());
280    Msg(EsafMsg::Info) << MsgDispatch;
281
282 
283    // set config dump
284    Config::Get()->SetCfgDump( fFileNames[kDump].c_str() );
285
286    vector<string>::const_iterator itCfg;
287    for( itCfg=fUsrCfgs.begin(); itCfg!=fUsrCfgs.end(); itCfg++)
288        Msg(EsafMsg::Debug) << "Using custom config: "+(*itCfg)<< MsgDispatch;
289
290    // add the user defined variables to the logfile
291    for (size_t i(0); i< fUsrKeys.size(); i++) 
292        Msg(EsafMsg::Debug) << "Cmd line option: class "+
293            fUsrKeys[i]+", value "+fUsrValues[i] << MsgDispatch;
294}
295
296//______________________________________________________________________________
297void RecoFramework::End() {
298    // save trees and close file
299    CloseRoot();
300
301    // Dump config file
302    Config::Get()->SaveConfig(fFileNames[kDump].c_str());
303
304    UInt_t len = 80;
305
306    TString head1('_',80); head1[0]=' '; head1[len-1]=' ';
307    TString head2(' ',80); head2[0]='|'; head2[len-1]='|';
308    TString head3('_',80); head3[0]='|'; head3[len-1]='|';
309    TString line, msg;
310
311    Msg(EsafMsg::Info) << head1 << MsgDispatch;
312    Msg(EsafMsg::Info) << head2 << MsgDispatch;
313
314    line = head2;
315    msg  = "ESAF Run Completed";
316    line.Replace(3,msg.Length(),msg.Data(),msg.Length());
317
318    Msg(EsafMsg::Info) << line << MsgDispatch;
319
320    TTimeStamp tEnd;
321    line = head2;
322    msg  = Form("Local time: %s",tEnd.AsString("l"));
323    line.Replace(5,msg.Length(),msg.Data(),msg.Length());
324
325    Msg(EsafMsg::Info) << line << MsgDispatch;
326
327    Msg(EsafMsg::Info) << head3 << MsgDispatch;
328    Msg(EsafMsg::Info) << MsgDispatch;
329}
330   
331//_____________________________________________________________________________
332void RecoFramework::Execute() {
333    //
334    // Execute a complete run
335    //
336
337    string dumpRootEvent = Conf()->GetStr("RecoFramework.DumpRootEvent");
338
339    // init input module
340    fInputModule->Init();
341
342    // init all modules
343    for( Int_t i=0; i<(Int_t)fModules.size(); i++ ) {
344        if ( !fModules[i]->Init() ) {
345            Msg(EsafMsg::Panic) << "Module " << fModules[i]->GetName() << " failed" << MsgDispatch;
346        }
347    }
348
349    OpenRoot();
350
351    TString jobname = Form("Reconstruction Job");
352    TBenchmark bJob;
353    bJob.Start(jobname);
354
355
356    TString opt;
357    if ( Conf()->GetBool("RecoFramework.HardMemCleaning") )
358        opt = "D";
359
360    // run
361    while ( RecoEvent *anEvent = fInputModule->GetEvent(opt) ) {
362
363        //-----------------------------------------------------
364        UInt_t len = 80;
365        TString divider('_',len);
366        TString head1('_',len); head1[0]=' '; head1[len-1]=' ';
367        TString head2(' ',len); head2[0]='|'; head2[len-1]='|';
368        TString head3('_',len); head3[0]='|'; head3[len-1]='|';
369        TString line, msg;
370
371        msg = Form("Event %d Started",fCurrentEvent);
372        line = head2;
373        line.Replace(3,msg.Length(),msg.Data(),msg.Length());
374
375        Msg(EsafMsg::Info) << head1 << MsgDispatch;
376        Msg(EsafMsg::Info) << head2 << MsgDispatch;
377        Msg(EsafMsg::Info) << line << MsgDispatch;
378        Msg(EsafMsg::Info) << head2 << MsgDispatch;
379        Msg(EsafMsg::Info) << MsgDispatch;
380        //-----------------------------------------------------
381
382
383        fRecoRootEvent->Clear();
384        anEvent->CleanGlobalData();
385        if (fInputModule->GetName() == "Root") 
386            fInputModule->SaveRootData(fRecoRootEvent);
387        if ( anEvent->GetHeader().GetNumActiveFee() != 0 ) {
388            TBenchmark bEvent;
389            TString s = Form("Event %d",fCurrentEvent);
390            bEvent.Start(s);
391            // execute all modules
392            for( Int_t i=0; i<(Int_t)fModules.size(); i++) {
393                if ( ! fModules[i]->PreProcess() )
394                    break;
395                if ( ! fModules[i]->Process( anEvent ) )
396                    break;
397                if ( ! fModules[i]->PostProcess() )
398                    break;
399                if ( ! fModules[i]->SaveRootData(fRecoRootEvent) )
400                    break;
401                // write the module data in the event
402                anEvent->PutRecoModuleData(fModules[i]->GetName(), fModules[i]->GetData());
403            }
404            if (dumpRootEvent == "yes" ) fRecoRootEvent->Dump();
405            fRecoTree->Fill();
406            // clean up
407            fInputModule->DestroyEvent();            // delete input event
408            for( Int_t i=0; i<(Int_t)fModules.size(); i++) {
409                fModules[i]->UserMemoryClean();      // delete user objects
410                fModules[i]->StandardMemoryClean();  // delete Int_t and Double_t maps
411            }
412            bEvent.Stop(s);
413
414            //-----------------------------------------------------
415            msg = Form("Event %d Completed, REAL=%6.2f s  CPU=%6.2f s",
416                    fCurrentEvent,
417                    bEvent.GetRealTime(s), bEvent.GetCpuTime(s) );
418            line.Replace(3,msg.Length(),msg.Data(),msg.Length());
419
420            Msg(EsafMsg::Info) << MsgDispatch;
421            Msg(EsafMsg::Info) << head2 << MsgDispatch;
422            Msg(EsafMsg::Info) << line << MsgDispatch;
423            Msg(EsafMsg::Info) << head3 << MsgDispatch;
424            Msg(EsafMsg::Info) << MsgDispatch;
425            //----------------------------------------------------
426        } else {
427            fInputModule->DestroyEvent();
428
429            //-----------------------------------------------------
430            msg = Form("Event %d Empty. Skipped", fCurrentEvent);
431            line.Replace(3,msg.Length(),msg.Data(),msg.Length());
432
433            Msg(EsafMsg::Info) << MsgDispatch;
434            Msg(EsafMsg::Info) << head2 << MsgDispatch;
435            Msg(EsafMsg::Info) << line << MsgDispatch;
436            Msg(EsafMsg::Info) << head3 << MsgDispatch;
437            Msg(EsafMsg::Info) << MsgDispatch;
438            //----------------------------------------------------}
439
440    }
441
442    fCurrentEvent++;
443
444
445} // end event loop
446
447    // end all modules
448    fInputModule->Done();
449    for( Int_t i=0; i<(Int_t)fModules.size(); i++) {
450        fModules[i]->Done();
451    }
452
453    bJob.Stop(jobname);
454    MsgForm(EsafMsg::Info,"Average time per event:  REAL=%6.2f s   CPU=%6.2f s",
455            bJob.GetRealTime(jobname)/fCurrentEvent, (bJob.GetCpuTime(jobname)/fCurrentEvent) ); 
456    MsgForm(EsafMsg::Info,"Total time:              REAL=%6.2f s   CPU=%6.2f s",
457            bJob.GetRealTime(jobname), bJob.GetCpuTime(jobname));
458
459}
460//_____________________________________________________________________________
461void RecoFramework::Dump( ostream& os ) const {
462    //
463    // Dump the module list
464    //
465   
466    Msg(EsafMsg::Debug) << "Framework Dump" << MsgDispatch;
467    Msg(EsafMsg::Debug) << "The following Modules where loaded:" << MsgDispatch;
468    Msg(EsafMsg::Debug) << "InputModule: " << fInputModule->GetName() << MsgDispatch;
469   
470    for( Int_t i=0; i<(Int_t)fModules.size(); i++ ) {
471        Msg(EsafMsg::Debug) << "Module: " << i+1 << "\t" << fModules[i]->GetName()<< MsgDispatch;
472    }
473}
474
475//_____________________________________________________________________________
476void RecoFramework::OpenRoot() {
477    //
478    // Open output rootfile
479    //
480
481    TString rootname = fFileNames[kRoot];
482    TString ext=".reco.root";
483
484    if ( !gSystem->AccessPathName(rootname)  ) {
485        // fname.root exists. try to add current date
486
487        MsgForm(EsafMsg::Warning,"Error opening file");
488        MsgForm(EsafMsg::Warning,"Probably it already exists or there is no ");
489        MsgForm(EsafMsg::Warning,"write access permission to this directory");
490
491        TTimeStamp now;
492
493        UInt_t hour, min, sec, year, month, day;
494        now.GetDate(kFALSE,0,&year,&month,&day);
495        now.GetTime(kFALSE,0,&hour,&min,&sec);
496        TString time = Form(".%4d-%02d-%02d-%02dh%02dm%02ds",year,month,day,hour,min, sec);
497        rootname.Insert(rootname.Length()-ext.Length(),time);
498
499    }
500   
501
502    fRootFile = new TFile(rootname, "CREATE");
503    if (fRootFile->IsZombie()) 
504        MsgForm(EsafMsg::Panic,"File %s cannot be opened",rootname.Data());
505
506
507
508    Msg(EsafMsg::Info) <<  "Root file " << rootname << " successfully opened" << MsgDispatch;
509    fRecoTree = new TTree("recotree","RecoTree");
510    CreateRecoRootEvent();
511    fRecoTree->Branch("events","RecoRootEvent",&fRecoRootEvent);
512}
513
514//_____________________________________________________________________________
515void RecoFramework::CreateRecoRootEvent() {
516    //
517    // Create RecoRootEvent
518    //
519    fRecoRootEvent = new RecoRootEvent();
520}
521
522//_____________________________________________________________________________
523void RecoFramework::CloseRoot() {
524    //
525    // Close output rootfile
526    //
527    if ( fRootFile ) {
528        fRecoTree->Write();
529        fRecoTree->AutoSave("SelfSave");
530        Msg(EsafMsg::Info) << "************************ " << setw(4) << 
531            fRecoTree->GetEntries() << " events read ************************" << 
532            MsgDispatch;
533        Msg(EsafMsg::Info) << MsgDispatch;
534        Msg(EsafMsg::Info) << fRecoTree->GetEntries() << " entries are written into " << fRootFile->GetName()<< MsgDispatch;
535        fRootFile->Close();
536        delete fRootFile;
537    }
538}
Note: See TracBrowser for help on using the repository browser.