Universita' di GenovaINFN Sezione di Genova  
AIRWATCH / EUSO Genova

EusoApplication - source file

// implementation of EusoApplication
// $Id: EusoApplication.cc,v 1.59 2005/04/22 15:53:35 thea Exp $
// M. Pallavicini - created 28-12-2001
// 

#include <iostream>

#include "EusoApplication.hh"
#include "EsafMsgDispatcher.hh"
#include "Config.hh"

#include "Detector.hh"
#include "EusoDetector.hh"
#include "LightToEuso.hh"
#include "EusoElectronics.hh"
#include "ElectronicsFactory.hh"
#include "LightFactory.hh"
#include "OpticsAnalysisModule.hh"
#include "Telemetry.hh"
#include "PhotonsOnPupil.hh"
#include "EsafRandom.hh"

#include "EEvent.hh" 
#include "EAtmosphere.hh"
#include "EShower.hh"

#include <TBenchmark.h>
#include <TTree.h>
#include <TSysEvtHandler.h>
#include <TSystem.h>

#include <TObjectTable.h>
ClassImp(EusoApplication)

// static pointer to EusoApplication
EusoApplication *gEusoApplication = NULL;

//______________________________________________________________________________
EusoApplication::EusoApplication( Int_t argc, char **argv ) :
    TRint("Euso Detector Simulation", &argc, argv, 0, 0, kTRUE ),
    fLightToEuso(0), fDetector(0), fLock(0), fEvCount(0), fEvMax(1),
    fManager(0) {
    //
    // Constructor.
    // Parse inline parameters, build the detector and electronics
    // reload random seed if required
    //

    fWriteTelemetry     = kFALSE;
    fWriteRoot          = kTRUE;
    fDoOpticsAnalysis   = kFALSE;
    
    string cmd; 
    for (Int_t i(0); i<argc; i++) {
        cmd +=argv[i]; cmd += " ";
    }
 
    // initialize message dispatcher
    EsafMsgDispatcher::Get()->LoadConfig();

    // load standard configs
    Config::Get()->LoadStandardConfigs();

   
    Msg(EsafMsg::Debug) << "Simu command line:" << MsgDispatch;
    Msg(EsafMsg::Debug) << cmd << MsgDispatch;

    ParseCmdLine(argc,argv);
    
    Init();
    
	//FIXME handling of the special modes must be improved!
	if ( fDoOpticsAnalysis ) {
        EnableModule(kESAFLight, kFALSE);
        fWriteRoot      = kFALSE;
        fWriteTelemetry = kFALSE;
        gROOT->SetBatch(kTRUE);
	} else {
        
        // force all elements of the chain to be built (if required by Config)
        SetChanged(kESAFLight);
        SetChanged(kESAFDetector);

        // right now just enable both light and euso
        EnableModule(kESAFLight);
        EnableModule(kESAFDetector);

        try {	
        	Build();
		}
		catch (exception &e) {
        	cerr << "ESAF ERROR: " << e.what() << endl;
			exit(0);
    	}
    }

    gEusoApplication = this;
}

//______________________________________________________________________________
EusoApplication::~EusoApplication() {
    // destructor
    // close output file if open
    // save random engine status
    
    EndJob();
    SafeDelete( fManager );
}

//______________________________________________________________________________
 void EusoApplication::ParseCmdLine(  Int_t argc, char** argv ) {
    //
    // Parse the commandline and set the corresponding variables
    //
    
    for(Int_t i=1; i<argc; i++) { //FIXME parser is too stupid....
        if ( strlen(argv[i]) >= 2 && 
                (argv[i][0] == '-') &&
                (argv[i][0] != '-')) {
            MsgForm(EsafMsg::Warning,"Simu usage:");
            MsgForm(EsafMsg::Warning,"");
            MsgForm(EsafMsg::Warning,"     Simu [-b --events=<n> --seed=<n> --ofile=<fname> 
                    --no-telemetry --no-root --no-files--stdcfg=<cfg> --usrcfg=<cfg> 
                    --ClassName.VarName=val] ");
            
        } else if (strncmp(argv[i],"--events=",9)==0) {
            // Number of events
            sscanf(argv[i]+9,"%d",&fEvMax);
            
        } else if (strncmp(argv[i],"--seed=",7)==0) {
            // Set random seed
            string key = "EsafRandom";
            string value =  key+".fSeed="+(argv[i]+7);
            fUsrKeys.push_back(key);	
            fUsrValues.push_back(value);
            
        } else if (strncmp(argv[i],"--ofile=",8)==0) {
            // Superseed output file name

            string key = "Run";
            string value =  key+".fFilesPrefix="+(argv[i]+8);
            fUsrKeys.push_back(key);	
            fUsrValues.push_back(value);

            Msg(EsafMsg::Info) << "Output file name set to: " << (argv[i]+8) << MsgDispatch;
            
        } else if (strncmp(argv[i],"--odir=",7)==0) {
            // Set Custom output directory

            string key = "Run";
            string value =  key+".fOutputDir"+(argv[i]+7);
            fUsrKeys.push_back(key);	
            fUsrValues.push_back(value);

            Msg(EsafMsg::Info) << "Output directory set to: " << (argv[i]+7)<< MsgDispatch;
            
        } else if (strncmp(argv[i],"--runname=",10)==0) {
            // Add run name to the truth
            fRunName = argv[i]+10;

        } else if (strncmp(argv[i],"--no-telemetry",14)==0) {
            // Don't write telemery
            fWriteTelemetry=kFALSE;
            
        } else if (strncmp(argv[i],"--no-root",8)==0) {
            // Don't save rootfile
            fWriteRoot=kFALSE;
            
        } else if (strncmp(argv[i],"--no-files",8)==0) {
            // Don't write root AND telemetry
            fWriteTelemetry=kFALSE;
            fWriteRoot=kFALSE;
            
        } else if (strncmp(argv[i],"--stdcfg",8) == 0) {
            //Standard Configuration
            string s = argv[i]+8;
            size_t pos = s.find('=');
            if ( pos != string::npos )
                Config::Get()->DefineConfig( s.substr(pos+1) );
            else
                FatalError("Invalid parameter "+string(argv[i]));
            
        } else if (strncmp(argv[i],"--usrcfg",8) == 0 ) {
            // User Configuration
            string s = argv[i]+7;
            size_t pos = s.find('=');
            if ( pos != string::npos ) 
                fUsrCfg += s.substr(pos+1);
            else
                FatalError("Invalid parameter "+string(argv[i]));

        } else if (strncmp(argv[i],"--opticsanalysis",16)==0) { // Esaf Special Mode
            // Enable OpticsAnalysis then exit loop
            fDoOpticsAnalysis=true;
            
        } else 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);

        }    
    }

    // load user definition file first
    if (!fUsrCfg.empty()) Config::Get()->LoadUserConfig(fUsrCfg.c_str());
    
    // the apply custom parameters
    for (size_t i(0); i< fUsrKeys.size(); i++) {
        Config::Get()->AddUserDefinition(fUsrKeys[i],fUsrValues[i]);
    }
}

//______________________________________________________________________________
 void EusoApplication::Init() {
    //
    // Initialize Config and the message system
    //

    // initialize the file names.
    fOutFileName = Config::Get()->GetCF("General","Run")->GetStr("Run.fFilesPrefix");

    fOutDir = Config::Get()->GetCF("General","Run")->GetStr("Run.fOutputDir");

    if ( fOutDir.rfind('/') != fOutDir.size()-1 )
        fOutDir += '/';

    fFileNames[kLog]       = fOutDir+fOutFileName+".log";
    fFileNames[kDump]      = fOutDir+fOutFileName+".ConfigDump.cfg";
    fFileNames[kRoot]      = fOutDir+fOutFileName+".root";
    fFileNames[kTelemetry] = fOutDir+fOutFileName+".Telemetry.dat.gz";

    // open logfile
    EsafMsgDispatcher::Get()->OpenLog(fFileNames[kLog]);

    // set config dump
    Config::Get()->SetDumpFileName( fFileNames[kDump] );

    Msg(EsafMsg::Info) << "Logging to file "+fFileNames[kDump]+
        " started" << MsgDispatch;

    if (!fUsrCfg.empty())
        Msg(EsafMsg::Debug) << "Using custom config: "+fUsrCfg<< MsgDispatch;

    // add the user defined variables to the logfile
    for (size_t i(0); i< fUsrKeys.size(); i++) 
        Msg(EsafMsg::Debug) << "Cmd line option: class "+
            fUsrKeys[i]+", value "+fUsrValues[i] << MsgDispatch;



}

//______________________________________________________________________________
 void EusoApplication::EndJob() {
    // final clean up
    
    // delete Euso detector if it exists
    if ( Euso() ) {
        delete fDetector;
        fDetector = NULL;
    }

    // delete LightToEuso
    if ( Light() ) {
        delete fLightToEuso;
        fLightToEuso = NULL;
    }
    
    // save trees and close file
    Manager()->Close();

	// save standard config if required
	Config::Get()->SaveConfig();
}


//______________________________________________________________________________
 void EusoApplication::Build() {
    // build (or rebuild) application chain

    //FIXME: When Config is resetted all ESAF modules must be rebuilt due to 
    //	 the ConfigFileParser pointers.
    //	 Config::Reset must be modified to reset just one module at time.

    Config::Get()->Reset();

    SafeDelete( fManager );
    fManager = new SimuRootFileManager();

    if (fWriteRoot)
        Manager()->Open( fFileNames[kRoot] );
    
    // rebuild euso detector if required
    // set gEusoDetector to right value (global pointer defined in EusoDetector.hh) 
    if ( HasChanged(kESAFDetector) ) {
        if (fDetector)
            delete fDetector;
        fDetector = NULL;

        if ( isModuleEnabled(kESAFDetector) ) {
            // parameters are filled 
            Manager()->ResetRunPars();
            fDetector = ElectronicsFactory::Get()->MakeDetector();
            Manager()->FillRunTree();
        }

        SetChanged(kESAFDetector,kFALSE);
    }

    // rebuild shower generator if required
    if ( HasChanged(kESAFLight) ) {
        if ( fLightToEuso )  
            delete fLightToEuso;
        fLightToEuso=NULL;
        if ( isModuleEnabled(kESAFLight) )
            fLightToEuso = LightFactory::Get()->GetLightToEuso();
        else
            cout << "Light not enabledn";

        SetChanged(kESAFLight,kFALSE);
    } 
}


//______________________________________________________________________________
 void EusoApplication::Help(const char* line) {
    TApplication::Help(line);
}

//______________________________________________________________________________
 Bool_t EusoApplication::DoEvent(Bool_t WriteRoot, Bool_t WriteTelemetry) {
    // simulate and (if required) display a single event
    // WriteRoot=true          : writes event in Root file
    // WriteTelemetry=true     : writes in Telemetry (ASCII) file

    // time info
    TString s = Form("Event %d",fEvCount);
    TBenchmark gB;
    gB.Start(s);

    if ( isLocked() ) {
        MsgForm(EsafMsg::Warning, "Cannot run because application is lockedn");
        MsgForm(EsafMsg::Warning, "Close configuration windows before runningn");
        return kFALSE;
    }

    // clear root event
    if ( Event() ) {
        Event()->Clear();
        Event()->Build(GetRunNumber(),fEvCount, fRunName); 
        // save the status of the random number generator before simulating the new event
        Event()->GetHeader()->SetRandom(EsafRandom::Get());
    }  

    // event generation and radiative transport through atmosphere
    MCTruth* truth = 0;
    PhotonsOnPupil* photons=0;

    if ( Light() && Euso() ) {
        Light()->Reset();
        photons = Light()->Get(Euso()->GetGeometry());
        if ( photons == NULL ) {
            MsgForm(EsafMsg::Info,"PhotonsOnPupil objecti is null");
            return kTRUE;
        }
        truth = Light()->GetTruth();
    } else
        MsgForm(EsafMsg::Info,"LightToEuso is null.");

    // detector response simulation
    Telemetry* data = 0;
    if ( ( Euso() && photons && Light() ) || ( Euso() && (!Light()) )) {
        Euso()->Reset();
        data = Euso()->Get( photons );
    }

    // dump time info on screen
    gB.Stop(s);
    MsgForm(EsafMsg::Info,"Event %d REAL=%6.2f s   CPU=%6.2f s",
            fEvCount,gB.GetRealTime(s), gB.GetCpuTime(s) );  

    // write output data file (Telemetry format)
    if ( data && WriteTelemetry ) {
        data->SetTruth( truth );

        if ( !data->IsOpen() ) data->Open( fFileNames[kTelemetry].c_str() );
        data->Write();
    }

    // fill root file if enabled
    if ( Event() && WriteRoot )
        Manager()->FillEventsTree();

    fEvCount++;
    return kTRUE;


}

//______________________________________________________________________________
 Bool_t EusoApplication::DoAll() {
    //
    // Simulate all events available from the data source
    // DoEvent returns kFalse in case of error so the run will stop
    // if fEvMax is -1 it never stops until error or end of file
    //

    if ( fDoOpticsAnalysis ) {
        DoOpticsAnalysis();
        return kTRUE;
    }

    Int_t ev = fEvMax;
    ResetEvCounter();

    TString jobname = Form("Job with %d events",fEvMax);
    TBenchmark gB;
    gB.Start(jobname);
    SetRunNumber( (Int_t)Config::Get()->GetCF("General","Run")->GetNum("Run.fRunNumber"));
    while( ev-- ) {
        try {
            if ( !DoEvent(fWriteRoot,fWriteTelemetry) )
                return kFALSE;
        }
        catch (exception &e) {
            Msg(EsafMsg::Panic) << e.what() << MsgDispatch;
        }
    }
    gB.Stop(jobname);
    MsgForm(EsafMsg::Info,"Average time per event:  REAL=%6.2f s   CPU=%6.2f s",
            gB.GetRealTime(jobname)/fEvMax, (gB.GetCpuTime(jobname)/fEvMax) );  
    MsgForm(EsafMsg::Info,"Total time:  REAL=%6.2f s   CPU=%6.2f s",
            gB.GetRealTime(jobname), gB.GetCpuTime(jobname));

    return kTRUE;
}

//______________________________________________________________________________
 void EusoApplication::SetLock( Bool_t lk) {
    // 
    // Lock the application.
    // If locked, events are not processed
    //

    if ( lk )
        fLock++;
    else
        fLock--;
    if (fLock<0) fLock=0;
}

//______________________________________________________________________________
 Bool_t EusoApplication::DumpLastEvent(string* buffer ) {
    //
    // dump event on stdout or into a buffer 
    // buffer must be large enough
    // if buffer is NULL, dump on cout
    // return kFALSE if no data is available
    // 

    //  if ( ! E()->Data() )
    //    return kFALSE;
    //  if ( buffer )
    //    *buffer = E()->Data()->Dump();
    //  else {
    //    cout << endl << endl;
    //    cout << "EUSO DETECTOR SIMULATION DUMP.   Event=" << EventCounter() << endl;
    //    cout << E()->Data()->Dump() << endl << endl;
    //    cout.flush();
    //  }
    return kTRUE;
}


//______________________________________________________________________________
 void EusoApplication::EnableModule(EsafElement e, Bool_t val) {
    fEnModule[e]=val; 
    SetChanged(e);
    //Build();
}

//______________________________________________________________________________
 void EusoApplication::ResetCopies() { 
    // reset list of event copies
    // used for re-rerunning the same event with different parameters

    for ( Int_t i=0; i<fEventCopies.GetEntriesFast(); i++) {
        EEvent *pEv = (EEvent*)(fEventCopies[i]);
        if ( pEv ) 
            delete pEv;
    }
}



//______________________________________________________________________________
 void EusoApplication::DoOpticsAnalysis() {
    //
    // Enable and run OpticsAnalysis module
    //

    OpticsAnalysisModule *oam;
    oam = new OpticsAnalysisModule();

    oam->Init();
    oam->PreProcess();
    oam->Process();
    oam->PostProcess();
    oam->Done();

}

About Us | EUSO Official Website | Web pages created by Roberto Pesce and Alessandro Thea - Last Update 14-May-2005 21:31