/* $Id: */ // ------------------------------------------------------------------------- // ----- FairEventBuilder source file ----- // ----- Created 23/09/2013 by R. Karabowicz ----- // ------------------------------------------------------------------------- /** FairEventBuilder *@author Radoslaw Karabowicz *@since 23.09.2013 *@version 1.0 ** ** FairRoot general task for recreating events in Time-Based reconstruction mode. ** Various experiments should implement their own version of Event Builder. ** The main member of the task is vector of reconstructed events fRecoEvents. ** It also contains a vector of implementations of FairEventBuffers, that are ** responsible for feeding fRecoEvents vector via FindEvents() function. ** ** The heart of the experiment-specific implemenations is ** the AnalyzeAndExtractEvents() function, which should interpret ** the experimental data to reconstruct events. **/ #include "FairEventBuilder.h" #include "FairRecoEventHeader.h" #include "FairRootManager.h" #include "FairRunAna.h" #include "FairRuntimeDb.h" #include "TClonesArray.h" #include "TMath.h" #include "TRandom2.h" #include using std::cout; using std::cerr; using std::endl; using std::flush; using std::fixed; using std::right; using std::left; using std::setw; using std::setprecision; using std::set; using std::map; using std::sort; using std::iterator; using std::vector; // ----- Default constructor ------------------------------------------ FairEventBuilder::FairEventBuilder() : FairTask("FairEventBuilder", 0), fEventBuffers (), fPossibleEvents(), fOutEvent (NULL) { } // ------------------------------------------------------------------------- // ----- Constructor with name ----------------------------------------- FairEventBuilder::FairEventBuilder(const char* name, Int_t iVerbose) : FairTask(name, iVerbose), fEventBuffers (), fPossibleEvents(), fOutEvent (NULL) { } // ------------------------------------------------------------------------- // ----- Destructor ---------------------------------------------------- FairEventBuilder::~FairEventBuilder() { } // ------------------------------------------------------------------------- // ----- Public method Exec -------------------------------------------- void FairEventBuilder::Exec(Option_t* opt) { if ( fVerbose ) cout << "FairEventBuilder::Exec() begin" << endl; // for ( std::vector::iterator it = fEventBuffers.begin() ; it != fEventBuffers.end() ; ++it ) { // *it.FindEvents(); // } Double_t maxEventTimeAllowed = 10.e6; for ( Int_t ieb = 0 ; ieb < fEventBuffers.size() ; ieb++ ) { if ( fVerbose ) cout << "***** " << fEventBuffers[ieb]->GetName() << " *****" << endl; if ( fVerbose ) cout << " there are " << fPossibleEvents[ieb].size() << " possible events" << endl; std::vector > tempBuffer = fEventBuffers[ieb]->FindEvents(); if ( fVerbose ) cout << " event buffer " << fEventBuffers[ieb]->GetName() << " found " << tempBuffer.size() << " events" << endl; std::pair tempPair; for ( Int_t ipair = 0 ; ipair < tempBuffer.size() ; ipair++ ) { fPossibleEvents[ieb].push_back(tempBuffer[ipair]); if ( fVerbose ) cout << " added event " << fPossibleEvents[ieb][fPossibleEvents[ieb].size()-1].second << " at " << fPossibleEvents[ieb][fPossibleEvents[ieb].size()-1].second->GetEventTime() << " ns." << endl; } if ( fVerbose ) { // cout << "tempBuffer has " << tempBuffer.size() << " entries there" << endl; cout << " and now " << fPossibleEvents[ieb].size() << " possible events" << endl; } if ( fEventBuffers[ieb]->AllowedTime() < maxEventTimeAllowed ) maxEventTimeAllowed = fEventBuffers[ieb]->AllowedTime(); } if ( fVerbose ) cout << "++ CAN CREATE EVENTS THAT ARE SMALLER THAN " << maxEventTimeAllowed << " ns" << endl; // AnalyzeAndExtractEvents(); // works on fEventBuffers[ieb], should extract possible events, // in fact it should be part of experiment-specific implementation. For now here for CHEP;). // Maybe it would be better to store them in vector> // instead of TClonesArray, so that they are sorted automatically, and are simpler. CreateAndFillEvents(maxEventTimeAllowed); if ( fVerbose ) cout << "FairEventBuilder::Exec() finish" << endl; } // ------------------------------------------------------------------------- // ----- Public method CreateAndFillEvents ----------------------------- void FairEventBuilder::CreateAndFillEvents(Double_t maxEventTimeAllowed) { Double_t minEventTime = 10.e6; FairRecoEventHeader* tempREH = NULL; while ( 1==1 ) { minEventTime = 10.e6; // find smallest event time for ( Int_t ieb = 0 ; ieb < fEventBuffers.size() ; ieb++ ) { for ( Int_t iev = 0 ; iev < fPossibleEvents[ieb].size() ; iev++ ) { tempREH = (FairRecoEventHeader*)fPossibleEvents[ieb][iev].second; if ( fVerbose ) cout << " fPossibleEvents[" << fEventBuffers[ieb]->GetName() << "][" << iev << "] . " << fPossibleEvents[ieb][iev].first << endl; //" . " << ((FairRecoEventHeader*)fPossibleEvents[ieb][iev].second)->GetEventTime() << " -> " << tempREH->GetEventTime() << endl; if ( fPossibleEvents[ieb][iev].second->GetEventTime() < minEventTime ) // i think it is enough to take .first instead of .second->GetEventTime() minEventTime = fPossibleEvents[ieb][iev].second->GetEventTime(); } } if ( fVerbose ) cout << " minEventTime is now " << minEventTime << endl; // check if can be saved if ( maxEventTimeAllowed > -0.5 && minEventTime > maxEventTimeAllowed-5 ) { // cout << "sorry, larger than " << maxEventTimeAllowed-5 << endl; break; } if ( minEventTime > 9.9e6 ) break; // calculate mean event time and remove close events from the event times' TCAs // in fact it should be a mean event with all event characteristics Double_t meanEventTime = 0.; Double_t nofOfEvents = 0.; for ( Int_t ieb = 0 ; ieb < fEventBuffers.size() ; ieb++ ) { for ( Int_t iev = 0 ; iev < fPossibleEvents[ieb].size() ; iev++ ) { tempREH = (FairRecoEventHeader*)fPossibleEvents[ieb][iev].second; if ( TMath::Abs(tempREH->GetEventTime()-minEventTime) < 5. ) { meanEventTime += tempREH->GetEventTime(); nofOfEvents += 1.; fPossibleEvents[ieb][iev] = fPossibleEvents[ieb][fPossibleEvents[ieb].size()-1]; fPossibleEvents[ieb].pop_back(); } } } if ( nofOfEvents == 0 ) continue; if ( fVerbose ) cout << " CREATED EVENT AT " << meanEventTime/nofOfEvents << " OUT OF " << nofOfEvents << " EVENTS" << endl; fOutEvent->SetEventTime(meanEventTime/nofOfEvents); for ( Int_t ieb = 0 ; ieb < fEventBuffers.size() ; ieb++ ) { // if ( fVerbose ) cout << " store data from " << fEventBuffers[ieb]->GetName() << endl; fEventBuffers[ieb]->StoreEventData(fOutEvent); // if ( fVerbose ) cout << " write out data from " << fEventBuffers[ieb]->GetName() << endl; fEventBuffers[ieb]->WriteOutAllDeadTimeData(); // if ( fVerbose ) cout << "TCA filled " << fEventBuffers[ieb]->GetName() <Fill(); // if ( fVerbose ) cout << " FILLED" << endl; for ( Int_t ieb = 0 ; ieb < fEventBuffers.size() ; ieb++ ) { // if ( fVerbose ) cout << "will delete data from " << fEventBuffers[ieb]->GetName() << endl; fEventBuffers[ieb]->DeleteOldData(); // if ( fVerbose ) cout << "data deleted from " << fEventBuffers[ieb]->GetName() < > tcArray; fPossibleEvents.push_back(tcArray); if ( fVerbose ) cout << "*** FairEventBuilder. " << fEventBuffers.size() << " buffers registered (" << fPossibleEvents.size() << " events arrays)" << endl; } // ------------------------------------------------------------------------- // ----- Private method SetParContainers ------------------------------- void FairEventBuilder::SetParContainers() { // Get run and runtime database FairRunAna* run = FairRunAna::Instance(); if ( ! run ) Fatal("SetParContainers", "No analysis run"); FairRuntimeDb* db = run->GetRuntimeDb(); if ( ! db ) Fatal("SetParContainers", "No runtime database"); } // ------------------------------------------------------------------------- // ----- Private method Init ------------------------------------------- InitStatus FairEventBuilder::Init() { // Get input array FairRootManager* ioman = FairRootManager::Instance(); if ( ! ioman ) Fatal("Init", "No FairRootManager"); fOutEvent = new FairRecoEventHeader(); FairRootManager::Instance()->Register("FairRecoEventHeader.", "RecoEvent", fOutEvent, kTRUE); for ( Int_t ieb = 0 ; ieb < fEventBuffers.size() ; ieb++ ) { fEventBuffers[ieb]->Init(); } return kSUCCESS; } // ------------------------------------------------------------------------- // ----- Private method ReInit ------------------------------------------- InitStatus FairEventBuilder::ReInit() { return kSUCCESS; } // ------------------------------------------------------------------------- // ----- Private method ReInit ------------------------------------------- void FairEventBuilder::Finish() { if ( fVerbose ) cout << "FairEventBuilder finished. Not yet........, have to finsh all events and their filling." << endl; CreateAndFillEvents(-1.); if ( fVerbose ) cout << "Really finish!" << endl; } // ------------------------------------------------------------------------- ClassImp(FairEventBuilder)