#include "THaAnalyzer.h"
#include "THaRunBase.h"
#include "THaEvent.h"
#include "THaOutput.h"
#include "THaEvData.h"
#include "THaGlobals.h"
#include "THaSpectrometer.h"
#include "THaNamedList.h"
#include "THaCutList.h"
#include "THaCut.h"
#include "THaScalerGroup.h"
#include "THaPhysicsModule.h"
#include "THaCodaData.h"
#include "THaPostProcess.h"
#include "THaBenchmark.h"
#include "TList.h"
#include "TTree.h"
#include "TFile.h"
#include "TClass.h"
#include "TDatime.h"
#include "TClass.h"
#include "TError.h"
#include "TSystem.h"
#include "TROOT.h"
#include "TMath.h"
#include "TDirectory.h"
#include "THaCrateMap.h"
#include <fstream>
#include <algorithm>
#include <iomanip>
#include <cstring>
using namespace std;
const char* const THaAnalyzer::kMasterCutName = "master";
const char* const THaAnalyzer::kDefaultOdefFile = "output.def";
const int MAXSTAGE = 100;
const int MAXCOUNTER = 200;
THaAnalyzer* THaAnalyzer::fgAnalyzer = 0;
THaAnalyzer::THaAnalyzer() :
fFile(NULL), fOutput(NULL), fOdefFileName(kDefaultOdefFile), fEvent(NULL),
fNStages(0), fNCounters(0),
fStages(NULL), fCounters(NULL), fNev(0), fMarkInterval(1000), fCompress(1),
fVerbose(2), fCountMode(kCountRaw), fBench(NULL), fPrevEvent(NULL),
fRun(NULL), fEvData(NULL), fApps(NULL), fPhysics(NULL), fScalers(NULL),
fPostProcess(NULL),
fIsInit(kFALSE), fAnalysisStarted(kFALSE), fLocalEvent(kFALSE),
fUpdateRun(kTRUE), fOverwrite(kTRUE), fDoBench(kFALSE),
fDoHelicity(kFALSE), fDoPhysics(kTRUE), fDoOtherEvents(kTRUE),
fDoScalers(kTRUE), fDoSlowControl(kTRUE)
{
if( fgAnalyzer ) {
Error("THaAnalyzer", "only one instance of THaAnalyzer allowed.");
MakeZombie();
return;
}
fgAnalyzer = this;
fApps = gHaApps;
fScalers = gHaScalers;
fPhysics = gHaPhysics;
fBench = new THaBenchmark;
}
THaAnalyzer::~THaAnalyzer()
{
Close();
delete fPostProcess;
delete fBench;
delete [] fStages;
delete [] fCounters;
if( fgAnalyzer == this )
fgAnalyzer = NULL;
}
Int_t THaAnalyzer::AddPostProcess( THaPostProcess* module )
{
if( !module )
return 0;
if( fAnalysisStarted ) {
Error( "AddPostProcess", "Cannot add analysis modules while analysis "
"is in progress. Close() this analysis first." );
return 237;
}
if( fIsInit ) {
if( !fRun || !fRun->IsInit()) {
Error("AddPostProcess","fIsInit, but bad fRun?!?");
return 236;
}
TDatime run_time = fRun->GetDate();
Int_t retval = module->Init(run_time);
if( retval )
return retval;
}
if( !fPostProcess )
fPostProcess = new TList;
fPostProcess->Add(module);
return 0;
}
void THaAnalyzer::ClearCounters()
{
for( int i=0; i<fNCounters; i++ ) {
fCounters[i].count = 0;
}
}
void THaAnalyzer::Close()
{
TIter nextp(fPostProcess);
TObject *obj;
while((obj=nextp())) {
(static_cast<THaPostProcess*>(obj))->Close();
}
if( gHaRun && *gHaRun == *fRun )
gHaRun = NULL;
delete fEvData; fEvData = NULL;
delete fOutput; fOutput = NULL;
if( TROOT::Initialized() )
delete fFile;
fFile = NULL;
delete fRun; fRun = NULL;
if( fLocalEvent ) {
delete fEvent; fEvent = fPrevEvent = NULL;
}
fIsInit = fAnalysisStarted = kFALSE;
}
THaAnalyzer::Stage_t* THaAnalyzer::DefineStage( const Stage_t* item )
{
if( !item || item->key < 0 )
return NULL;
if( item->key >= MAXSTAGE ) {
Error("DefineStage", "Too many analysis stages.");
return NULL;
}
if( item->key >= fNStages ) {
Int_t newmax = item->key+1;
Stage_t* tmp = new Stage_t[newmax];
memcpy(tmp,fStages,fNStages*sizeof(Stage_t));
memset(tmp+fNStages,0,(newmax-fNStages)*sizeof(Stage_t));
delete [] fStages;
fStages = tmp;
fNStages = newmax;
}
return (Stage_t*)memcpy(fStages+item->key,item,sizeof(Stage_t));
}
THaAnalyzer::Counter_t* THaAnalyzer::DefineCounter( const Counter_t* item )
{
if( !item || item->key < 0 )
return NULL;
if( item->key >= MAXCOUNTER ) {
Error("DefineCounters", "Too many statistics counters.");
return NULL;
}
if( item->key >= fNCounters ) {
Int_t newmax = item->key+1;
Counter_t* tmp = new Counter_t[newmax];
memcpy(tmp,fCounters,fNCounters*sizeof(Counter_t));
memset(tmp+fNCounters,0,(newmax-fNCounters)*sizeof(Counter_t));
delete [] fCounters;
fCounters = tmp;
fNCounters = newmax;
}
return (Counter_t*)memcpy(fCounters+item->key,item,sizeof(Counter_t));
}
void THaAnalyzer::EnableBenchmarks( Bool_t b )
{
fDoBench = b;
}
void THaAnalyzer::EnableHelicity( Bool_t b )
{
fDoHelicity = b;
}
void THaAnalyzer::EnableRunUpdate( Bool_t b )
{
fUpdateRun = b;
}
void THaAnalyzer::EnableOtherEvents( Bool_t b )
{
fDoOtherEvents = b;
}
void THaAnalyzer::EnableOverwrite( Bool_t b )
{
fOverwrite = b;
}
void THaAnalyzer::EnablePhysicsEvents( Bool_t b )
{
fDoPhysics = b;
}
void THaAnalyzer::EnableScalers( Bool_t b )
{
fDoScalers = b;
}
void THaAnalyzer::EnableSlowControl( Bool_t b )
{
fDoSlowControl = b;
}
bool THaAnalyzer::EvalStage( int n )
{
if( fDoBench ) fBench->Begin("Cuts");
const Stage_t* theStage = fStages+n;
bool ret = true;
if( theStage->cut_list ) {
gHaCuts->EvalBlock( theStage->cut_list );
if( theStage->master_cut &&
!theStage->master_cut->GetResult() ) {
if( theStage->countkey >= 0 )
Incr(theStage->countkey);
ret = false;
}
}
if( fDoBench ) fBench->Stop("Cuts");
return ret;
}
void THaAnalyzer::InitStages()
{
if( fNStages>0 ) return;
const Stage_t stagedef[] = {
{ kRawDecode, kRawDecodeTest, "RawDecode" },
{ kDecode, kDecodeTest, "Decode" },
{ kCoarseTrack, kCoarseTrackTest, "CoarseTracking" },
{ kCoarseRecon, kCoarseReconTest, "CoarseReconstruct" },
{ kTracking, kTrackTest, "Tracking" },
{ kReconstruct, kReconstructTest, "Reconstruct" },
{ kPhysics, kPhysicsTest, "Physics" },
{ -1 }
};
const Stage_t* idef = stagedef;
while( DefineStage(idef++) ) {}
}
void THaAnalyzer::InitCounters()
{
if( fNCounters>0 ) return;
const Counter_t counterdef[] = {
{ kNevRead, "events read" },
{ kNevGood, "events decoded" },
{ kNevPhysics, "physics events" },
{ kNevScaler, "scaler events" },
{ kNevEpics, "slow control events" },
{ kNevOther, "other event types" },
{ kNevPostProcess, "events post-processed" },
{ kNevAnalyzed, "physics events analyzed" },
{ kNevAccepted, "events accepted" },
{ kEvFileTrunc, "event file truncated" },
{ kCodaErr, "CODA errors" },
{ kRawDecodeTest, "skipped after raw decoding" },
{ kDecodeTest, "skipped after Decode" },
{ kCoarseTrackTest, "skipped after Coarse Tracking" },
{ kCoarseReconTest, "skipped after Coarse Reconstruct" },
{ kTrackTest, "skipped after Tracking" },
{ kReconstructTest, "skipped after Reconstruct" },
{ kPhysicsTest, "skipped after Physics" },
{ -1 }
};
const Counter_t* jdef = counterdef;
while( DefineCounter(jdef++) ) {}
}
void THaAnalyzer::InitCuts()
{
for( int i=0; i<fNStages; i++ ) {
Stage_t* theStage = fStages+i;
theStage->cut_list = gHaCuts->FindBlock( theStage->name );
if( theStage->cut_list ) {
TString master_cut( theStage->name );
master_cut.Append( '_' );
master_cut.Append( kMasterCutName );
theStage->master_cut = gHaCuts->FindCut( master_cut );
} else
theStage->master_cut = NULL;
}
}
Int_t THaAnalyzer::InitModules( const TList* module_list, TDatime& run_time,
Int_t erroff, const char* baseclass )
{
static const char* const here = "InitModules()";
if( !module_list || !baseclass || !*baseclass )
return -3-erroff;
TIter next( module_list );
Int_t retval = 0;
TObject* obj;
while( (obj = next()) ) {
if( !obj->IsA()->InheritsFrom( baseclass )) {
Error( here, "Object %s (%s) is not a %s. Analyzer initialization "
"failed.", obj->GetName(), obj->GetTitle(), baseclass );
retval = -2;
break;
}
THaAnalysisObject* theModule = dynamic_cast<THaAnalysisObject*>( obj );
if( !theModule ) {
Error( here, "Object %s (%s) is not a THaAnalysisObject. Analyzer "
"initialization failed.", obj->GetName(), obj->GetTitle() );
retval = -2;
break;
} else if( theModule->IsZombie() ) {
Warning( here, "Removing zombie module %s (%s) from list of %s objects",
obj->GetName(), obj->GetTitle(), baseclass );
const_cast<TList*>(module_list)->Remove( theModule );
delete theModule;
continue;
}
retval = theModule->Init( run_time );
if( retval != kOK || !theModule->IsOK() ) {
Error( here, "Error %d initializing module %s (%s). Analyzer initial"
"ization failed.", retval, obj->GetName(), obj->GetTitle() );
if( retval == kOK )
retval = -1;
break;
}
}
if( retval != 0 ) retval -= erroff;
return retval;
}
Int_t THaAnalyzer::Init( THaRunBase* run )
{
if( !run ) return -1;
if( fDoBench ) fBench->Begin("Init");
Int_t retval = DoInit( run );
if( fDoBench ) fBench->Stop("Init");
return retval;
}
Int_t THaAnalyzer::DoInit( THaRunBase* run )
{
static const char* const here = "Init";
Int_t retval = 0;
if( fFile && fOutFileName != fFile->GetName()) {
#if 0
if( fAnalysisStarted ) {
Error( here, "Cannot change output file name after analysis has been "
"started. Close() first, then Init() or Process() again." );
return -11;
}
Close();
#endif
}
if( !fFile ) {
if( fOutFileName.IsNull() ) {
Error( here, "Must specify an output file. Set it with SetOutFile()." );
return -12;
}
if( gSystem->AccessPathName(fOutFileName) == kFALSE ) {
if( !fOverwrite ) {
Error( here, "Output file %s already exists. Choose a different "
"file name or enable overwriting with EnableOverwrite().",
fOutFileName.Data() );
return -13;
}
cout << "Overwriting existing";
} else
cout << "Creating new";
cout << " output file: " << fOutFileName << endl;
fFile = new TFile( fOutFileName.Data(), "RECREATE" );
}
if( !fFile || fFile->IsZombie() ) {
Error( here, "failed to create output file %s. Check file/directory "
"permissions.", fOutFileName.Data() );
Close();
return -10;
}
fFile->SetCompressionLevel(fCompress);
if( !fIsInit ) {
InitStages();
InitCounters();
}
bool new_event = false;
if( fEvent != fPrevEvent ) {
if( fAnalysisStarted ) {
Error( here, "Cannot change event structure for continuing analysis. "
"Close() this analysis, then Init() again." );
return 254;
} else if( fIsInit ) {
if( !fLocalEvent || fEvent )
new_event = true;
if( fLocalEvent && fEvent ) {
delete fPrevEvent; fPrevEvent = NULL;
fLocalEvent = kFALSE;
}
}
}
if( !fEvent ) {
fEvent = new THaEvent;
fLocalEvent = kTRUE;
new_event = true;
}
fPrevEvent = fEvent;
fEvent->Reset();
bool new_output = false;
if( !fOutput || new_event ) {
delete fOutput;
fOutput = new THaOutput;
new_output = true;
}
bool new_decoder = false;
if( !fEvData || fEvData->IsA() != gHaDecoder ) {
delete fEvData; fEvData = NULL;
if( gHaDecoder )
fEvData = static_cast<THaEvData*>(gHaDecoder->New());
if( !fEvData ) {
Error( here, "Failed to create decoder object. "
"Something is very wrong..." );
return 241;
}
new_decoder = true;
}
bool run_init = false;
if( !run->IsInit()) {
run_init = true;
retval = run->Init();
if( retval )
return retval;
}
bool new_run = ( !fRun || *fRun != *run );
bool need_init = ( !fIsInit || new_event || new_output || new_run ||
new_decoder || run_init );
#if 0
if( fAnalysisStarted && !new_run && fCountMode!=kCountRaw &&
((fRun->GetLastEvent() >= run->GetFirstEvent() &&
fRun->GetFirstEvent() < run->GetLastEvent()) ||
(fRun->GetFirstEvent() <= run->GetLastEvent() &&
fRun->GetLastEvent() > run->GetFirstEvent()) )) {
Warning( here, "You are analyzing the same run twice with "
"overlapping event ranges! prev: %d-%d, now: %d-%d",
fRun->GetFirstEvent(), fRun->GetLastEvent(),
run->GetFirstEvent(), run->GetLastEvent() );
if( !gROOT->IsBatch() ) {
cout << "Are you sure (y/n)?" << endl;
char c = 0;
while( c != 'y' && c != 'n' && c != EOF ) {
cin >> c;
}
if( c != 'y' && c != 'Y' )
return 240;
}
}
#endif
if( new_run || fRun->Compare(run) ) {
delete fRun;
fRun = static_cast<THaRunBase*>(run->IsA()->New());
if( !fRun )
return 252;
*fRun = *run;
}
gHaRun = fRun;
if( fVerbose>0 ) {
fRun->Print("STARTINFO");
}
if( !fAnalysisStarted )
ClearCounters();
if( !need_init )
return 0;
TDatime run_time = fRun->GetDate();
fEvData->SetRunTime( run_time.Convert());
if( !((retval = InitModules( fApps, run_time, 20, "THaApparatus")) ||
(retval = InitModules( fScalers, run_time, 30, "THaScalerGroup")) ||
(retval = InitModules( fPhysics, run_time, 40, "THaPhysicsModule"))
)) {
if( fCutFileName.IsNull() ) {
gHaCuts->Clear();
fLoadedCutFileName = "";
} else {
if( fCutFileName != fLoadedCutFileName ) {
gHaCuts->Load( fCutFileName );
fLoadedCutFileName = fCutFileName;
}
gHaCuts->Compile();
}
InitCuts();
TDirectory *olddir = gDirectory;
fFile->cd();
if( (retval = fOutput->Init( fOdefFileName )) < 0 ) {
Error( here, "Error initializing THaOutput." );
} else if( retval == 1 )
retval = 0;
else {
TTree* outputTree = fOutput->GetTree();
if( outputTree )
outputTree->Branch( "Event_Branch", fEvent->IsA()->GetName(),
&fEvent, 16000, 99 );
}
olddir->cd();
TIter nextp(fPostProcess);
TObject *obj;
while ( !retval && (obj=nextp()) ) {
retval = (static_cast<THaPostProcess*>(obj))->Init(run_time);
}
}
if ( retval == 0 ) {
if ( ! fOutput ) {
Error( here, "Error initializing THaOutput for objects(again!)" );
retval = -5;
} else {
(retval = InitOutput( fApps, 20, "THaApparatus")) ||
(retval = InitOutput( fPhysics, 40, "THaPhysicsModule"));
}
}
if( retval == 0 ) {
fIsInit = kTRUE;
}
return retval;
}
Int_t THaAnalyzer::InitOutput( const TList* module_list,
Int_t erroff, const char* baseclass )
{
static const char* const here = "InitOutput()";
if( !module_list )
return -3-erroff;
TIter next( module_list );
bool fail = false;
Int_t retval = 0;
TObject* obj;
while( !fail && (obj = next())) {
if( baseclass && !obj->IsA()->InheritsFrom( baseclass )) {
Error( here, "Object %s (%s) is not a %s. Analyzer initialization "
"failed.", obj->GetName(), obj->GetTitle(), baseclass );
retval = -2;
fail = true;
} else {
THaAnalysisObject* theModule = dynamic_cast<THaAnalysisObject*>( obj );
theModule->InitOutput( fOutput );
if( !theModule->IsOKOut() ) {
Error( here, "Error initializing output for %s (%s). "
"Analyzer initialization failed.",
obj->GetName(), obj->GetTitle() );
retval = -1;
fail = true;
}
}
}
return (retval == 0) ? 0 : retval - erroff;
}
Int_t THaAnalyzer::ReadOneEvent()
{
if( fDoBench ) fBench->Begin("RawDecode");
Int_t status = fRun->ReadEvent();
switch( status ) {
case S_SUCCESS:
status = fEvData->LoadEvent( fRun->GetEvBuffer() );
if( status == THaEvData::HED_OK )
status = S_SUCCESS;
Incr(kNevRead);
break;
case EOF:
break;
case S_EVFILE_TRUNC:
Incr(kEvFileTrunc);
break;
case CODA_ERROR:
Incr(kCodaErr);
break;
default:
Incr(kCodaErr);
break;
}
if( fDoBench ) fBench->Stop("RawDecode");
return status;
}
Int_t THaAnalyzer::SetCountMode( Int_t mode )
{
if( mode < 0 )
return fCountMode;
if( mode != kCountAll && mode != kCountPhysics && mode != kCountRaw )
return -mode;
fCountMode = mode;
return mode;
}
void THaAnalyzer::SetCrateMapFileName( const char* name )
{
if( !name || !*name || !strcmp( name, "cratemap" )
|| !strcmp( name, "db_cratemap.dat" ) ) {
THaEvData::SetCrateMapName("");
return;
}
TString fname(name);
if( fname.BeginsWith("db_") )
fname.Remove(0,3);
if( fname.EndsWith(".dat") )
fname.Remove( TMath::Max(fname.Length()-4, 0) );
THaEvData::SetCrateMapName( fname );
return;
}
void THaAnalyzer::Print( Option_t* ) const
{
if( fRun )
fRun->Print();
}
void THaAnalyzer::PrintCounters() const
{
UInt_t w = 0;
for (int i = 0; i < fNCounters; i++) {
if( GetCount(i) > w )
w = GetCount(i);
}
w = IntDigits(w);
bool first = true;
for (int i = 0; i < fNCounters; i++) {
const char* text = fCounters[i].description;
if( GetCount(i) != 0 && text && *text ) {
if( first ) {
cout << "Counter summary:" << endl;
first = false;
}
cout << setw(w) << GetCount(i) << " " << text << endl;
}
}
}
void THaAnalyzer::PrintScalers() const
{
bool first = true;
TIter next(fScalers);
while( THaScalerGroup* theScaler =
static_cast<THaScalerGroup*>( next() )) {
if( first ) {
cout << "Scaler summary:";
first = false;
}
cout << endl;
theScaler->PrintSummary();
}
if( !first ) cout << endl;
}
void THaAnalyzer::PrintCutSummary() const
{
if( gHaCuts->GetSize() > 0 ) {
cout << "Cut summary:" << endl;
if( fVerbose>1 )
gHaCuts->Print("STATS");
if( fSummaryFileName.Length() > 0 ) {
ofstream ostr(fSummaryFileName);
if( ostr ) {
streambuf* cout_buf = cout.rdbuf();
cout.rdbuf(ostr.rdbuf());
TDatime now;
cout << "Cut Summary for run " << fRun->GetNumber()
<< " completed " << now.AsString()
<< endl << endl;
gHaCuts->Print("STATS");
cout.rdbuf(cout_buf);
ostr.close();
}
}
}
}
Int_t THaAnalyzer::BeginAnalysis()
{
fFirstPhysics = kTRUE;
TIter nexta(fApps);
while( THaAnalysisObject* obj = static_cast<THaAnalysisObject*>(nexta()) ) {
obj->Begin( fRun );
}
TIter nextp(fPhysics);
while( THaAnalysisObject* obj = static_cast<THaAnalysisObject*>(nextp()) ) {
obj->Begin( fRun );
}
return 0;
}
Int_t THaAnalyzer::EndAnalysis()
{
TIter nexta(fApps);
while( THaAnalysisObject* obj = static_cast<THaAnalysisObject*>(nexta()) ) {
obj->End( fRun );
}
TIter nextp(fPhysics);
while( THaAnalysisObject* obj = static_cast<THaAnalysisObject*>(nextp()) ) {
obj->End( fRun );
}
return 0;
}
Int_t THaAnalyzer::PhysicsAnalysis( Int_t code )
{
if( code != kOK )
return code;
if( fNev < fRun->GetFirstEvent() )
return kSkip;
if( fFirstPhysics ) {
fFirstPhysics = false;
if( fVerbose>2 )
cout << "Starting physics analysis at event " << GetCount(kNevPhysics)
<< endl;
}
fRun->IncrNumAnalyzed();
Incr(kNevAnalyzed);
if( fDoBench ) fBench->Begin("Decode");
TIter next(fApps);
while( THaApparatus* theApparatus = static_cast<THaApparatus*>( next() )) {
theApparatus->Clear();
theApparatus->Decode( *fEvData );
}
if( fDoBench ) fBench->Stop("Decode");
if( !EvalStage(kDecode) ) return kSkip;
if( fDoBench ) fBench->Begin("CoarseTracking");
next.Reset();
while( TObject* obj = next() ) {
THaSpectrometer* theSpectro = dynamic_cast<THaSpectrometer*>(obj);
if( theSpectro )
theSpectro->CoarseTrack();
}
if( fDoBench ) fBench->Stop("CoarseTracking");
if( !EvalStage(kCoarseTrack) ) return kSkip;
if( fDoBench ) fBench->Begin("CoarseReconstruct");
next.Reset();
while( THaApparatus* theApparatus =
static_cast<THaApparatus*>( next() )) {
theApparatus->CoarseReconstruct();
}
if( fDoBench ) fBench->Stop("CoarseReconstruct");
if( !EvalStage(kCoarseRecon) ) return kSkip;
if( fDoBench ) fBench->Begin("Tracking");
next.Reset();
while( TObject* obj = next() ) {
THaSpectrometer* theSpectro = dynamic_cast<THaSpectrometer*>(obj);
if( theSpectro )
theSpectro->Track();
}
if( fDoBench ) fBench->Stop("Tracking");
if( !EvalStage(kTracking) ) return kSkip;
if( fDoBench ) fBench->Begin("Reconstruct");
next.Reset();
while( THaApparatus* theApparatus = static_cast<THaApparatus*>( next() )) {
theApparatus->Reconstruct();
}
if( fDoBench ) fBench->Stop("Reconstruct");
if( !EvalStage(kReconstruct) ) return kSkip;
if( fDoBench ) fBench->Begin("Physics");
TIter next_physics(fPhysics);
while( THaPhysicsModule* theModule =
static_cast<THaPhysicsModule*>( next_physics() )) {
theModule->Clear();
Int_t err = theModule->Process( *fEvData );
if( err == THaPhysicsModule::kTerminate )
code = kTerminate;
else if( err == THaPhysicsModule::kFatal ) {
code = kFatal;
break;
}
}
if( fDoBench ) fBench->Stop("Physics");
if( code == kFatal ) return kFatal;
if( !EvalStage(kPhysics) )
return (code == kOK) ? kSkip : code;
if( fDoBench ) fBench->Begin("Output");
if( fEvent ) {
fEvent->GetHeader()->Set( static_cast<UInt_t>(fEvData->GetEvNum()),
fEvData->GetEvType(),
fEvData->GetEvLength(),
fEvData->GetEvTime(),
fEvData->GetHelicity(),
fRun->GetNumber()
);
fEvent->Fill();
}
if( fOutput ) fOutput->Process();
if( fDoBench ) fBench->Stop("Output");
return code;
}
Int_t THaAnalyzer::SlowControlAnalysis( Int_t code )
{
if( code == kFatal )
return code;
if( fDoBench ) fBench->Begin("Output");
if( fOutput ) fOutput->ProcEpics(fEvData);
if( fDoBench ) fBench->Stop("Output");
if( code == kTerminate )
return code;
return kOK;
}
Int_t THaAnalyzer::ScalerAnalysis( Int_t code )
{
if( code == kFatal )
return code;
TIter next(fScalers);
while( THaScalerGroup* theScaler =
static_cast<THaScalerGroup*>( next() )) {
if( fDoBench ) fBench->Begin("Scaler");
theScaler->LoadData( *fEvData );
if( fDoBench ) fBench->Stop("Scaler");
if ( fOutput ) {
if( fDoBench ) fBench->Begin("Output");
fOutput->ProcScaler(theScaler);
if( fDoBench ) fBench->Stop("Output");
}
}
if( code == kTerminate )
return code;
return kOK;
}
Int_t THaAnalyzer::OtherAnalysis( Int_t code )
{
return code;
}
Int_t THaAnalyzer::PostProcess( Int_t code )
{
if( fDoBench ) fBench->Begin("PostProcess");
if( code == kFatal )
return code;
TIter next(fPostProcess);
while( THaPostProcess* obj = static_cast<THaPostProcess*>(next())) {
obj->Process(fEvData,fRun,code);
}
if( fDoBench ) fBench->Stop("PostProcess");
return code;
}
Int_t THaAnalyzer::MainAnalysis()
{
Int_t retval = kOK;
Incr(kNevGood);
bool rawfail = false;
if( !EvalStage(kRawDecode) ) {
retval = kSkip;
rawfail = true;
}
bool evdone = false;
if( fEvData->IsPhysicsTrigger() && fDoPhysics ) {
Incr(kNevPhysics);
retval = PhysicsAnalysis(retval);
evdone = true;
}
if( fEvData->IsEpicsEvent() && fDoSlowControl ) {
Incr(kNevEpics);
retval = SlowControlAnalysis(retval);
evdone = true;
}
if( fEvData->IsScalerEvent() && fDoScalers ) {
Incr(kNevScaler);
retval = ScalerAnalysis(retval);
evdone = true;
}
if( !evdone && fDoOtherEvents ) {
Incr(kNevOther);
retval = OtherAnalysis(retval);
}
if( fPostProcess ) {
Incr(kNevPostProcess);
retval = PostProcess(retval);
}
if( rawfail && retval != kSkip && GetCount(kRawDecodeTest)>0 )
fCounters[kRawDecodeTest].count--;
return retval;
}
Int_t THaAnalyzer::Process( THaRunBase* run )
{
static const char* const here = "Process";
if( !run ) {
if( fRun )
run = fRun;
else
return -1;
}
if( !fAnalysisStarted ) fBench->Reset();
fBench->Begin("Total");
Int_t status = Init( run );
if( status != 0 ) {
fBench->Stop("Total");
return status;
}
if( (status = fRun->Open()) ) {
Error( here, "Failed to re-open the input file. "
"Make sure the file still exists.");
fBench->Stop("Total");
return -4;
}
gHaRun = fRun;
fEvData->EnableHelicity( HelicityEnabled() );
fEvData->EnableScalers( ScalersEnabled() && (fScalers->GetSize()>0) );
fEvData->SetVerbose( (fVerbose>2) );
fEvData->SetDebug( (fVerbose>3) );
if( fVerbose>1 ) {
cout << "Decoder: helicity "
<< (fEvData->HelicityEnabled() ? "enabled" : "disabled")
<< endl;
cout << "Decoder: scalers "
<< (fEvData->ScalersEnabled() ? "enabled" : "disabled")
<< endl;
cout << endl << "Starting analysis" << endl;
}
if( fVerbose>2 && fRun->GetFirstEvent()>1 )
cout << "Skipping " << fRun->GetFirstEvent() << " events" << endl;
fNev = 0;
bool terminate = false, fatal = false;
UInt_t nlast = fRun->GetLastEvent();
fAnalysisStarted = kTRUE;
BeginAnalysis();
if( fFile ) {
fRun->Write("Run_Data");
}
while ( !terminate && (status = ReadOneEvent()) != EOF &&
fNev < nlast ) {
if( status ) {
if( status == THaEvData::HED_FATAL )
break;
continue;
}
UInt_t evnum = fEvData->GetEvNum();
switch(fCountMode) {
case kCountPhysics:
if( fEvData->IsPhysicsTrigger() )
fNev++;
break;
case kCountAll:
fNev++;
break;
case kCountRaw:
fNev = evnum;
break;
default:
break;
}
if( fVerbose>1 && evnum > 0 && (evnum % fMarkInterval == 0))
cout << dec << evnum << endl;
if( fUpdateRun )
fRun->Update( fEvData );
if( fDoBench ) fBench->Begin("Cuts");
gHaCuts->ClearAll();
if( fDoBench ) fBench->Stop("Cuts");
Int_t err = MainAnalysis();
switch( err ) {
case kOK:
break;
case kSkip:
continue;
case kFatal:
fatal = terminate = true;
continue;
case kTerminate:
terminate = true;
break;
default:
Error( here, "Unknown return code from MainAnalysis(): %d", err );
terminate = fatal = true;
continue;
}
Incr(kNevAccepted);
}
EndAnalysis();
fRun->Close();
*run = *fRun;
if( fDoBench ) fBench->Begin("Output");
if( fOutput && fOutput->GetTree() )
fFile = fOutput->GetTree()->GetCurrentFile();
if( fFile ) fFile->cd();
if( fOutput ) fOutput->End();
if( fFile ) {
fRun->Write("Run_Data");
fFile->Purge();
}
if( fDoBench ) fBench->Stop("Output");
fBench->Stop("Total");
if( fVerbose>0 ) {
cout << dec;
if( status == EOF )
cout << "End of file";
else if ( fNev == nlast )
cout << "Event limit reached.";
else if ( fatal )
cout << "Fatal processing error.";
else if ( terminate )
cout << "Terminated during processing.";
cout << endl;
PrintCounters();
if( fVerbose>1 )
PrintScalers();
}
PrintCutSummary();
if( fDoBench ) {
cout << "Timing summary:" << endl;
fBench->Print("Init");
fBench->Print("RawDecode");
fBench->Print("Decode");
fBench->Print("CoarseTracking");
fBench->Print("CoarseReconstruct");
fBench->Print("Tracking");
fBench->Print("Reconstruct");
fBench->Print("Physics");
fBench->Print("Output");
fBench->Print("Cuts");
fBench->Print("Scaler");
}
if( fVerbose>1 || fDoBench )
fBench->Print("Total");
return fNev;
}
ClassImp(THaAnalyzer)
Last change: Sat Nov 7 21:26:42 2009
Last generated: 2009-11-07 21:26
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.