diff --git a/MQ/mcbm/CbmDeviceEventBuilder.cxx b/MQ/mcbm/CbmDeviceEventBuilder.cxx index 878db861efb7c18eea772398f79f15e384760b06..8dad9cb974eb3ff9b8494bae5770581a4fa59005 100644 --- a/MQ/mcbm/CbmDeviceEventBuilder.cxx +++ b/MQ/mcbm/CbmDeviceEventBuilder.cxx @@ -129,6 +129,7 @@ try { } /// Extract detector to add if any + /* for (std::vector<std::string>::const_iterator itStrAdd = vsAddDet.begin(); itStrAdd != vsAddDet.end(); ++itStrAdd) { const ECbmModuleId addDet = GetDetectorId(*itStrAdd); if (ECbmModuleId::kNotExist != addDet) { fEvbuildAlgo.AddSystem(addDet); } @@ -139,6 +140,7 @@ try { continue; } } + */ /// Extract event builder window to add if any for (std::vector<std::string>::const_iterator itStrEvbuildWin = vsSetEvbuildWin.begin(); @@ -177,7 +179,7 @@ try { charPosDel++; double dWinEnd = std::stod(sNext.substr(charPosDel)); - fEvbuildAlgo.SetTriggerWindow(selDet, dWinBeg, dWinEnd); + fEvbuildAlgo.SetEventWindow(selDet, dWinBeg, dWinEnd); } } catch (InitTaskError& e) { diff --git a/algo/evbuild/EventBuilder.cxx b/algo/evbuild/EventBuilder.cxx index 8186c792f07f257056943275ad718b6fe2a0f5b5..04455c4d9bc83f3b26ba6824f76b9ecd5e402ed4 100644 --- a/algo/evbuild/EventBuilder.cxx +++ b/algo/evbuild/EventBuilder.cxx @@ -30,35 +30,30 @@ namespace cbm event.fTime = trigger; // --- Loop over systems - for (const auto& system : fSystems) { + for (auto entry : fEventWindows) { - // --- Look for trigger window in list - if (fTriggerWindows.find(system) == fTriggerWindows.end()) { - //LOG(fatal) << "EventBuilder::BuildEvent(): no trigger window supplied for requested detector."; - std::cout << "EventBuilder::BuildEvent(): no trigger window supplied for requested detector." << std::endl; - exit(1); - } - const double tMin = trigger + fTriggerWindows.find(system)->second.first; - const double tMax = trigger + fTriggerWindows.find(system)->second.second; + auto system = entry.first; + const double tMin = trigger + entry.second.first; + const double tMax = trigger + entry.second.second; // --- Build the event using trigger window switch (system) { - case ECbmModuleId::kMuch: { //we do not support the "MuchBeamTimeDigi" - assert(is_sorted(ts.fData.fMuch.fDigis.begin(), ts.fData.fMuch.fDigis.end(), - IsBefore<CbmMuchDigi, CbmMuchDigi>)); - event.fData.fMuch.fDigis = CopyRange(ts.fData.fMuch.fDigis, tMin, tMax); - break; - } case ECbmModuleId::kSts: { assert( is_sorted(ts.fData.fSts.fDigis.begin(), ts.fData.fSts.fDigis.end(), IsBefore<CbmStsDigi, CbmStsDigi>)); event.fData.fSts.fDigis = CopyRange(ts.fData.fSts.fDigis, tMin, tMax); break; } - case ECbmModuleId::kTof: { - assert( - is_sorted(ts.fData.fTof.fDigis.begin(), ts.fData.fTof.fDigis.end(), IsBefore<CbmTofDigi, CbmTofDigi>)); - event.fData.fTof.fDigis = CopyRange(ts.fData.fTof.fDigis, tMin, tMax); + case ECbmModuleId::kRich: { + assert(is_sorted(ts.fData.fRich.fDigis.begin(), ts.fData.fRich.fDigis.end(), + IsBefore<CbmRichDigi, CbmRichDigi>)); + event.fData.fRich.fDigis = CopyRange(ts.fData.fRich.fDigis, tMin, tMax); + break; + } + case ECbmModuleId::kMuch: { + assert(is_sorted(ts.fData.fMuch.fDigis.begin(), ts.fData.fMuch.fDigis.end(), + IsBefore<CbmMuchDigi, CbmMuchDigi>)); + event.fData.fMuch.fDigis = CopyRange(ts.fData.fMuch.fDigis, tMin, tMax); break; } case ECbmModuleId::kTrd: { @@ -67,10 +62,10 @@ namespace cbm event.fData.fTrd.fDigis = CopyRange(ts.fData.fTrd.fDigis, tMin, tMax); break; } - case ECbmModuleId::kRich: { - assert(is_sorted(ts.fData.fRich.fDigis.begin(), ts.fData.fRich.fDigis.end(), - IsBefore<CbmRichDigi, CbmRichDigi>)); - event.fData.fRich.fDigis = CopyRange(ts.fData.fRich.fDigis, tMin, tMax); + case ECbmModuleId::kTof: { + assert( + is_sorted(ts.fData.fTof.fDigis.begin(), ts.fData.fTof.fDigis.end(), IsBefore<CbmTofDigi, CbmTofDigi>)); + event.fData.fTof.fDigis = CopyRange(ts.fData.fTof.fDigis, tMin, tMax); break; } case ECbmModuleId::kPsd: { @@ -84,11 +79,7 @@ namespace cbm event.fData.fT0.fDigis = CopyRange(ts.fData.fT0.fDigis, tMin, tMax); break; } - default: { - //LOG(fatal) << "EventBuilder::BuildEvent():GetName(): Reading digis from unknown detector type!"; - std::cout << "EventBuilder::BuildEvent():GetName(): Reading digis from unknown detector type!" << std::endl; - exit(1); - } + default: break; } } return event; diff --git a/algo/evbuild/EventBuilder.h b/algo/evbuild/EventBuilder.h index e224963781d02da689bf601d3868c164ddb4c40f..bc34137464c139caaba9ccec1e251d72e2e35a18 100644 --- a/algo/evbuild/EventBuilder.h +++ b/algo/evbuild/EventBuilder.h @@ -48,65 +48,55 @@ namespace cbm /** @brief Constructor **/ EventBuilder() {}; + /** @brief Destructor **/ virtual ~EventBuilder() {}; + /** @brief Execution - ** @param ts Digi source (timeslice) - ** @param triggers List of trigger times - ** @return Vector of constructed events - **/ + ** @param ts Digi source (timeslice) + ** @param triggers List of trigger times + ** @return Vector of constructed events + **/ std::vector<CbmDigiEvent> operator()(const CbmDigiTimeslice& ts, const std::vector<double> triggers) const; + /** @brief Build a single event from a trigger time - ** @param ts Digi source (timeslice) - ** @param trigger Trigger time - ** @return Digi event - **/ + ** @param ts Digi source (timeslice) + ** @param trigger Trigger time + ** @return Digi event + **/ CbmDigiEvent BuildEvent(const CbmDigiTimeslice& ts, double trigger) const; - /** @brief Add a detector system - ** @param system System to be added - **/ - void AddSystem(ECbmModuleId system) - { - if (std::find(fSystems.begin(), fSystems.end(), system) != fSystems.end()) return; - fSystems.push_back(system); - } - /** @brief Configure the trigger windows - ** @param system Detector system identifier - ** @param tMin Trigger window start time w.r.t. trigger time - ** @param tMax Trigger window end time w.r.t. trigger time - **/ - void SetTriggerWindow(ECbmModuleId system, double tMin, double tMax) + /** @brief Configure the event windows + ** @param system Detector system identifier + ** @param tMin Event window start time w.r.t. event time + ** @param tMax Event window end time w.r.t. event time + **/ + void SetEventWindow(ECbmModuleId system, double tMin, double tMax) { - if (std::find(fSystems.begin(), fSystems.end(), system) == fSystems.end()) { - //LOG(fatal) << "EventBuilder::SetTriggerWindow(): setting trigger window for non-added detector."; - std::cout << "EventBuilder::SetTriggerWindow(): setting trigger window for non-added detector." << std::endl; - exit(1); - } - fTriggerWindows[system] = std::make_pair(tMin, tMax); + fEventWindows[system] = std::make_pair(tMin, tMax); } private: // methods /** @brief Copy data objects in a given time interval from the source to the target vector - ** @param source Source data vector - ** @param tMin Minimal time - ** @param tMax Maximal time - ** @return Target data vector - ** - ** The Data class specialisation must implement the method double GetTime(), which is used to - ** check whether the Data object falls into the specified time interval. - ** - ** The source vector must be ordered w.r.t. GetTime(), otherwise the behaviour is undefined. - ** - ** TODO: The current implementation searches, for each trigger, the entire source vector. This - ** can surely be optimised when the contract that the trigger vector be sorted is properly exploited, - ** e.g., by starting the search for the first digi in the trigger window from the start of the - ** previous trigger window. This, however, requires bookkeeping hardly to be realised without - ** changing the state of the class. I leave this for the future and for bright specialists. - **/ + ** @param source Source data vector + ** @param tMin Minimal time + ** @param tMax Maximal time + ** @return Target data vector + ** + ** The Data class specialisation must implement the method double GetTime(), which is used to + ** check whether the Data object falls into the specified time interval. + ** + ** The source vector must be ordered w.r.t. GetTime(), otherwise the behaviour is undefined. + ** + ** TODO: The current implementation searches, for each trigger, the entire source vector. This + ** can surely be optimised when the contract that the trigger vector be sorted is properly exploited, + ** e.g., by starting the search for the first digi in the trigger window from the start of the + ** previous trigger window. This, however, requires bookkeeping hardly to be realised without + ** changing the state of the class. I leave this for the future and for bright specialists. + **/ template<typename Data> static typename std::vector<Data> CopyRange(const std::vector<Data>& source, double tMin, double tMax) { @@ -117,9 +107,12 @@ namespace cbm return std::vector<Data>(lower, upper); } + private: // data members - std::map<ECbmModuleId, std::pair<double, double>> fTriggerWindows; - std::vector<ECbmModuleId> fSystems {}; // List of detector systems + /** Event time window relative to the trigger time for each detector system + ** Key is system identifier, value is (t_min, t_max). + **/ + std::map<ECbmModuleId, std::pair<double, double>> fEventWindows; }; } // namespace algo } // namespace cbm diff --git a/algo/test/_GTestEventBuilder.cxx b/algo/test/_GTestEventBuilder.cxx index acdc317e4c1ac1147bc509978a8df3ffa33ae5db..5a3ab80f0f787215354e52f1e6088275500be29a 100644 --- a/algo/test/_GTestEventBuilder.cxx +++ b/algo/test/_GTestEventBuilder.cxx @@ -12,20 +12,13 @@ TEST(_GTestEventBuilder, CheckEventBuilderAlgorithmSimple) //Initialize event builder cbm::algo::EventBuilder evbuild; - evbuild.AddSystem(ECbmModuleId::kMuch); - evbuild.AddSystem(ECbmModuleId::kSts); - evbuild.AddSystem(ECbmModuleId::kTof); - evbuild.AddSystem(ECbmModuleId::kTrd); - evbuild.AddSystem(ECbmModuleId::kRich); - evbuild.AddSystem(ECbmModuleId::kPsd); - evbuild.AddSystem(ECbmModuleId::kT0); - evbuild.SetTriggerWindow(ECbmModuleId::kMuch, -45.0, 45.0); - evbuild.SetTriggerWindow(ECbmModuleId::kSts, -45.0, 45.0); - evbuild.SetTriggerWindow(ECbmModuleId::kTof, -45.0, 45.0); - evbuild.SetTriggerWindow(ECbmModuleId::kTrd, -45.0, 45.0); - evbuild.SetTriggerWindow(ECbmModuleId::kRich, -45.0, 45.0); - evbuild.SetTriggerWindow(ECbmModuleId::kPsd, -45.0, 45.0); - evbuild.SetTriggerWindow(ECbmModuleId::kT0, -45.0, 45.0); + evbuild.SetEventWindow(ECbmModuleId::kMuch, -45.0, 45.0); + evbuild.SetEventWindow(ECbmModuleId::kSts, -45.0, 45.0); + evbuild.SetEventWindow(ECbmModuleId::kTof, -45.0, 45.0); + evbuild.SetEventWindow(ECbmModuleId::kTrd, -45.0, 45.0); + evbuild.SetEventWindow(ECbmModuleId::kRich, -45.0, 45.0); + evbuild.SetEventWindow(ECbmModuleId::kPsd, -45.0, 45.0); + evbuild.SetEventWindow(ECbmModuleId::kT0, -45.0, 45.0); CbmDigiTimeslice tsIn; const uint nInput = 1000; diff --git a/macro/reco/reco_digi.C b/macro/reco/reco_digi.C index 2958207696a4d7471225ace7c7dc3a20f0c90118..8b8c7b55157154842640ffec8c7923e51df50019 100644 --- a/macro/reco/reco_digi.C +++ b/macro/reco/reco_digi.C @@ -127,8 +127,7 @@ void reco_digi(TString input = "", Int_t nTimeSlices = -1, Int_t firstTimeSlice // ----- Event building ----------------------------------------------- auto evtBuild = std::make_unique<CbmTaskBuildEvents>(); - evtBuild->AddSystem(ECbmModuleId::kSts); - evtBuild->SetTimeWindow(ECbmModuleId::kSts, -20., 30.); // event building time window for STS + evtBuild->SetEventWindow(ECbmModuleId::kSts, -20., 30.); // event building time window for STS LOG(info) << myName << ": Added task " << evtBuild->GetName(); run->AddTask(evtBuild.release()); // ------------------------------------------------------------------------ diff --git a/reco/tasks/CbmTaskBuildEvents.cxx b/reco/tasks/CbmTaskBuildEvents.cxx index 2f25362b8e8956725ddf15aa481ca9b19a9e8749..a3983dd65f6f9f4f2e27c8461a2c3c61f5f4cda3 100644 --- a/reco/tasks/CbmTaskBuildEvents.cxx +++ b/reco/tasks/CbmTaskBuildEvents.cxx @@ -36,16 +36,10 @@ CbmTaskBuildEvents::~CbmTaskBuildEvents() CbmDigiTimeslice CbmTaskBuildEvents::FillTimeSlice() { CbmDigiTimeslice ts; - for (const auto& system : fSystems) { + for (const auto& entry : fEventWindows) { + auto system = entry.first; CbmDigiBranchBase* digiBranch = fDigiMan->GetBranch(system); switch (system) { - case ECbmModuleId::kMuch: { //we do not support the "MuchBeamTimeDigi" - const vector<CbmMuchDigi>* digiVec = - boost::any_cast<const vector<CbmMuchDigi>*>(digiBranch->GetBranchContainer()); - assert(digiVec); - ts.fData.fMuch.fDigis = *digiVec; - break; - } case ECbmModuleId::kSts: { const vector<CbmStsDigi>* digiVec = boost::any_cast<const vector<CbmStsDigi>*>(digiBranch->GetBranchContainer()); @@ -53,11 +47,18 @@ CbmDigiTimeslice CbmTaskBuildEvents::FillTimeSlice() ts.fData.fSts.fDigis = *digiVec; break; } - case ECbmModuleId::kTof: { - const vector<CbmTofDigi>* digiVec = - boost::any_cast<const vector<CbmTofDigi>*>(digiBranch->GetBranchContainer()); + case ECbmModuleId::kRich: { + const vector<CbmRichDigi>* digiVec = + boost::any_cast<const vector<CbmRichDigi>*>(digiBranch->GetBranchContainer()); assert(digiVec); - ts.fData.fTof.fDigis = *digiVec; + ts.fData.fRich.fDigis = *digiVec; + break; + } + case ECbmModuleId::kMuch: { + const vector<CbmMuchDigi>* digiVec = + boost::any_cast<const vector<CbmMuchDigi>*>(digiBranch->GetBranchContainer()); + assert(digiVec); + ts.fData.fMuch.fDigis = *digiVec; break; } case ECbmModuleId::kTrd: { @@ -67,11 +68,11 @@ CbmDigiTimeslice CbmTaskBuildEvents::FillTimeSlice() ts.fData.fTrd.fDigis = *digiVec; break; } - case ECbmModuleId::kRich: { - const vector<CbmRichDigi>* digiVec = - boost::any_cast<const vector<CbmRichDigi>*>(digiBranch->GetBranchContainer()); + case ECbmModuleId::kTof: { + const vector<CbmTofDigi>* digiVec = + boost::any_cast<const vector<CbmTofDigi>*>(digiBranch->GetBranchContainer()); assert(digiVec); - ts.fData.fRich.fDigis = *digiVec; + ts.fData.fTof.fDigis = *digiVec; break; } case ECbmModuleId::kPsd: { @@ -88,11 +89,13 @@ CbmDigiTimeslice CbmTaskBuildEvents::FillTimeSlice() ts.fData.fT0.fDigis = *digiVec; break; } - default: LOG(fatal) << GetName() << ": Reading digis from unknown detector type!"; + default: LOG(fatal) << GetName() << ": Unknown detector type!"; } } return ts; } +// --------------------------------------------------------------------------- + // ----- Execution ------------------------------------------------------- void CbmTaskBuildEvents::Exec(Option_t*) @@ -102,74 +105,44 @@ void CbmTaskBuildEvents::Exec(Option_t*) TStopwatch timerStep; TStopwatch timerTot; timerTot.Start(); + std::map<ECbmModuleId, size_t> numDigisTs; + std::map<ECbmModuleId, size_t> numDigisEv; // --- Clear output vector fEvents->clear(); - // --- Construct a DigiTimeslice from the data in CbmDigiManager - timerStep.Start(); - CbmDigiTimeslice ts = FillTimeSlice(); - timerStep.Stop(); - fTimeFillTs += timerStep.RealTime(); + // --- If the input is already CbmDigiTimeslice (from unpacking), use that directly + if (fTimeslice) { + LOG(info) << "Exec timeslice " << fNumTs << " with " << fTriggers->size() << " triggers" + << " from " << *(fTriggers->begin()) << " to " << fTriggers->back(); + timerStep.Start(); + *fEvents = fAlgo(*fTimeslice, *fTriggers); + timerStep.Stop(); + fTimeBuildEvt += timerStep.RealTime(); + for (const auto& entry : fEventWindows) + numDigisTs[entry.first] = GetNumDigis(fTimeslice->fData, entry.first); + } - // --- Call event builder algorithm - timerStep.Start(); - *fEvents = fAlgo(ts, *fTriggers); - timerStep.Stop(); - fTimeBuildEvt += timerStep.RealTime(); + // --- If input is not DigiTimeslice: construct a transientDigiTimeslice from the data in CbmDigiManager + else { + timerStep.Start(); + CbmDigiTimeslice ts = FillTimeSlice(); + for (const auto& entry : fEventWindows) + numDigisTs[entry.first] = GetNumDigis(ts.fData, entry.first); + timerStep.Stop(); + fTimeFillTs += timerStep.RealTime(); + timerStep.Start(); + *fEvents = fAlgo(ts, *fTriggers); + timerStep.Stop(); + fTimeBuildEvt += timerStep.RealTime(); + } // --- Timeslice statistics size_t numTriggers = fTriggers->size(); size_t numEvents = fEvents->size(); - std::map<ECbmModuleId, size_t> NumDigisTs; - std::map<ECbmModuleId, size_t> NumDigisEv; - - for (const auto& system : fSystems) { - NumDigisEv[system] = 0; - switch (system) { - case ECbmModuleId::kMuch: { - NumDigisTs[system] = ts.fData.fMuch.fDigis.size(); - for (auto& event : (*fEvents)) - NumDigisEv[system] += event.fData.fMuch.fDigis.size(); - break; - } - case ECbmModuleId::kSts: { - NumDigisTs[system] = ts.fData.fSts.fDigis.size(); - for (auto& event : (*fEvents)) - NumDigisEv[system] += event.fData.fSts.fDigis.size(); - break; - } - case ECbmModuleId::kTof: { - NumDigisTs[system] = ts.fData.fTof.fDigis.size(); - for (auto& event : (*fEvents)) - NumDigisEv[system] += event.fData.fTof.fDigis.size(); - break; - } - case ECbmModuleId::kTrd: { - NumDigisTs[system] = ts.fData.fTrd.fDigis.size(); - for (auto& event : (*fEvents)) - NumDigisEv[system] += event.fData.fTrd.fDigis.size(); - break; - } - case ECbmModuleId::kRich: { - NumDigisTs[system] = ts.fData.fRich.fDigis.size(); - for (auto& event : (*fEvents)) - NumDigisEv[system] += event.fData.fRich.fDigis.size(); - break; - } - case ECbmModuleId::kPsd: { - NumDigisTs[system] = ts.fData.fPsd.fDigis.size(); - for (auto& event : (*fEvents)) - NumDigisEv[system] += event.fData.fPsd.fDigis.size(); - break; - } - case ECbmModuleId::kT0: { - NumDigisTs[system] = ts.fData.fT0.fDigis.size(); - for (auto& event : (*fEvents)) - NumDigisEv[system] += event.fData.fT0.fDigis.size(); - break; - } - default: break; + for (const auto& entry : fEventWindows) { + for (auto& event : (*fEvents)) { + numDigisEv[entry.first] += GetNumDigis(event.fData, entry.first); } } @@ -181,9 +154,10 @@ void CbmTaskBuildEvents::Exec(Option_t*) logOut << fixed << setw(8) << setprecision(1) << right << timerTot.RealTime() * 1000. << " ms] "; logOut << "TS " << fNumTs << ", triggers " << numTriggers << ", events " << numEvents; - for (const auto& system : fSystems) { + for (const auto& entry : fEventWindows) { + auto system = entry.first; logOut << ", frac " << CbmModuleList::GetModuleNameCaps(system) << " digis " - << 100. * double(NumDigisEv[system]) / double(NumDigisTs[system]) << " %"; + << 100. * double(numDigisEv[system]) / double(numDigisTs[system]) << " %"; } LOG(info) << logOut.str(); @@ -193,9 +167,10 @@ void CbmTaskBuildEvents::Exec(Option_t*) fNumTriggers += numTriggers; fNumEvents += numEvents; - for (const auto& system : fSystems) { - fNumDigisTs[system] += NumDigisTs[system]; - fNumDigisEv[system] += NumDigisEv[system]; + for (const auto& entry : fEventWindows) { + auto system = entry.first; + fNumDigisTs[system] += numDigisTs[system]; + fNumDigisEv[system] += numDigisEv[system]; } } // ---------------------------------------------------------------------------- @@ -211,7 +186,8 @@ void CbmTaskBuildEvents::Finish() LOG(info) << "Triggers : " << fNumTriggers; LOG(info) << "Events : " << fNumEvents; - for (const auto& system : fSystems) { + for (const auto& entry : fEventWindows) { + auto system = entry.first; LOG(info) << CbmModuleList::GetModuleNameCaps(system) << " digis in timeslice : " << fNumDigisTs[system]; LOG(info) << CbmModuleList::GetModuleNameCaps(system) << " digis in events : " << fNumDigisEv[system] << " = " << fixed << setprecision(2) << 100. * double(fNumDigisEv[system]) / double(fNumDigisTs[system]) << " %"; @@ -227,6 +203,25 @@ void CbmTaskBuildEvents::Finish() // ---------------------------------------------------------------------------- +// ----- Number of digis in the timeslice ---------------------------------- +size_t CbmTaskBuildEvents::GetNumDigis(const CbmDigiData& data, ECbmModuleId system) +{ + size_t result = 0; + switch (system) { + case ECbmModuleId::kSts: result = data.fSts.fDigis.size(); break; + case ECbmModuleId::kRich: result = data.fRich.fDigis.size(); break; + case ECbmModuleId::kMuch: result = data.fMuch.fDigis.size(); break; + case ECbmModuleId::kTrd: result = data.fTrd.fDigis.size(); break; + case ECbmModuleId::kTof: result = data.fTof.fDigis.size(); break; + case ECbmModuleId::kPsd: result = data.fPsd.fDigis.size(); break; + case ECbmModuleId::kT0: result = data.fT0.fDigis.size(); break; + default: result = 0; break; + } + return result; +} +// ---------------------------------------------------------------------------- + + // ----- Initialisation --------------------------------------------------- InitStatus CbmTaskBuildEvents::Init() { @@ -243,16 +238,26 @@ InitStatus CbmTaskBuildEvents::Init() LOG(info) << GetName() << ": Initialising..."; // --- Check input data - for (const auto& system : fSystems) { - if (!fDigiMan->IsPresent(system)) { - LOG(fatal) << GetName() << ": No digi branch for " << CbmModuleList::GetModuleNameCaps(system); - return kFATAL; + // --- DigiTimeslice: Unpacked data from FLES + fTimeslice = ioman->InitObjectAs<const CbmDigiTimeslice*>("DigiTimeslice."); + if (fTimeslice) { LOG(info) << GetName() << ": Found branch DigiTimeslice."; } + // --- DigiManager: Simulated digi data + else { + fDigiMan = CbmDigiManager::Instance(); + fDigiMan->Init(); + for (const auto& entry : fEventWindows) { + auto system = entry.first; + if (!fDigiMan->IsPresent(system)) { + LOG(fatal) << GetName() << ": No digi branch for " << CbmModuleList::GetModuleNameCaps(system); + return kFATAL; + } + LOG(info) << "--- Found digi branch for " << CbmModuleList::GetModuleNameCaps(system); } - LOG(info) << "--- Found digi branch for " << CbmModuleList::GetModuleNameCaps(system); } // --- Initialize diagnostics - for (const auto& system : fSystems) { + for (const auto& entry : fEventWindows) { + auto system = entry.first; fNumDigisTs[system] = 0; fNumDigisEv[system] = 0; } @@ -279,13 +284,11 @@ InitStatus CbmTaskBuildEvents::Init() LOG(info) << "--- Registered branch DigiEvent"; // --- Configure algorithm - for (const auto& system : fSystems) { - if (fTriggerWindows.find(system) == fTriggerWindows.end()) { - LOG(fatal) << GetName() << ": no trigger window supplied for requested detector."; - } - const double tMin = fTriggerWindows.find(system)->second.first; - const double tMax = fTriggerWindows.find(system)->second.second; - fAlgo.SetTriggerWindow(system, tMin, tMax); + for (const auto& entry : fEventWindows) { + auto system = entry.first; + const double tMin = entry.second.first; + const double tMax = entry.second.second; + fAlgo.SetEventWindow(system, tMin, tMax); LOG(info) << "--- Use algo EventBuilder with event window [" << tMin << ", " << tMax << "] ns for " << CbmModuleList::GetModuleNameCaps(system); } diff --git a/reco/tasks/CbmTaskBuildEvents.h b/reco/tasks/CbmTaskBuildEvents.h index 4deee10f43368d6a3d5be805c8f65ed7c1557ee9..6cb231842e9fbc6b8dab56e1418712986e046d2f 100644 --- a/reco/tasks/CbmTaskBuildEvents.h +++ b/reco/tasks/CbmTaskBuildEvents.h @@ -33,59 +33,62 @@ public: /** @brief Constructor **/ CbmTaskBuildEvents(); + /** @brief Copy constructor (disabled) **/ CbmTaskBuildEvents(const CbmTaskBuildEvents&) = delete; + /** @brief Destructor **/ virtual ~CbmTaskBuildEvents(); + /** @brief Task execution **/ virtual void Exec(Option_t* opt); + /** @brief Finish timeslice **/ virtual void Finish(); + /** @brief Assignment operator (disabled) **/ CbmTaskBuildEvents& operator=(const CbmTaskBuildEvents&) = delete; - /** @brief Add a detector system to the event builder algorithm - ** @param system System to be added - **/ - void AddSystem(ECbmModuleId system) - { - fAlgo.AddSystem(system); - if (std::find(fSystems.begin(), fSystems.end(), system) != fSystems.end()) return; - fSystems.push_back(system); - } /** @brief Configure the event building time intervals ** @param system Detector system identifier - ** @param tMin Trigger window start time w.r.t. trigger time - ** @param tMax Trigger window end time w.r.t. trigger time + ** @param tMin Event window start time w.r.t. event time + ** @param tMax Event window end time w.r.t. event time **/ - void SetTimeWindow(ECbmModuleId system, double tMin, double tMax) + void SetEventWindow(ECbmModuleId system, double tMin, double tMax) { - if (std::find(fSystems.begin(), fSystems.end(), system) == fSystems.end()) { - LOG(fatal) << GetName() << ": setting time window for non-added detector."; - } - fTriggerWindows[system] = std::make_pair(tMin, tMax); + fEventWindows[system] = std::make_pair(tMin, tMax); } private: // methods /** @brief Task initialisation **/ virtual InitStatus Init(); + /** @brief Construct a DigiTimeslice from the data in CbmDigiManager **/ CbmDigiTimeslice FillTimeSlice(); + + /** @brief Number of digis for a given system + ** @param data CbmDigiData object (DigiTimeslice or DigiEvent) + ** @param system System identifier (enum ECbmModuleId) + ** @return Number of digis for the system + **/ + size_t GetNumDigis(const CbmDigiData& data, ECbmModuleId system); + + private: // members - CbmDigiManager* fDigiMan = nullptr; //! Input data (digis) + const CbmDigiTimeslice* fTimeslice = nullptr; //! Input data (from unpacking) + CbmDigiManager* fDigiMan = nullptr; //! Input data (from simulation) const std::vector<double>* fTriggers = nullptr; //! Input data (triggers) - std::vector<ECbmModuleId> fSystems {}; // List of detector systems - std::vector<CbmDigiEvent>* fEvents = nullptr; //! Output data (events) + std::vector<CbmDigiEvent>* fEvents = nullptr; //! Output data (events) cbm::algo::EventBuilder fAlgo {}; //! Algorithm - std::map<ECbmModuleId, std::pair<double, double>> fTriggerWindows; + std::map<ECbmModuleId, std::pair<double, double>> fEventWindows; // for diagnostics std::map<ECbmModuleId, size_t> fNumDigisTs; // Number of digis in timeslices diff --git a/reco/tasks/CbmTaskTriggerDigi.cxx b/reco/tasks/CbmTaskTriggerDigi.cxx index e284c946bad75440382345c3d173fa04a9fa2a69..de60973e9f9734613b9c1994fc5fd215decad49a 100644 --- a/reco/tasks/CbmTaskTriggerDigi.cxx +++ b/reco/tasks/CbmTaskTriggerDigi.cxx @@ -6,6 +6,7 @@ #include "CbmDefs.h" #include "CbmDigiManager.h" +#include "CbmDigiTimeslice.h" #include "CbmModuleList.h" #include "CbmMuchDigi.h" #include "CbmPsdDigi.h" @@ -46,43 +47,59 @@ void CbmTaskTriggerDigi::Exec(Option_t*) // --- Get digi times std::vector<double> digiTimes; - for (const auto& system : fSystems) { - CbmDigiBranchBase* digiBranch = fDigiMan->GetBranch(system); - std::vector<double> locDigiTimes; - switch (system) { - case ECbmModuleId::kMuch: { //we do not support the "MuchBeamTimeDigi" - locDigiTimes = GetDigiTimes<CbmMuchDigi>(digiBranch); - break; - } - case ECbmModuleId::kSts: { - locDigiTimes = GetDigiTimes<CbmStsDigi>(digiBranch); - break; - } - case ECbmModuleId::kTof: { - locDigiTimes = GetDigiTimes<CbmTofDigi>(digiBranch); - break; - } - case ECbmModuleId::kTrd: { - locDigiTimes = GetDigiTimes<CbmTrdDigi>(digiBranch); - break; - } - case ECbmModuleId::kRich: { - locDigiTimes = GetDigiTimes<CbmRichDigi>(digiBranch); - break; - } - case ECbmModuleId::kPsd: { - locDigiTimes = GetDigiTimes<CbmPsdDigi>(digiBranch); - break; - } - case ECbmModuleId::kT0: { //T0 has Tof digis - locDigiTimes = GetDigiTimes<CbmTofDigi>(digiBranch); - break; + + // --- Case: input CbmDigiTimeslice + if (fTimeslice) { + for (const auto& system : fSystems) { + std::vector<double> systemDigiTimes = GetDigiTimes(system); + digiTimes.insert(digiTimes.end(), systemDigiTimes.begin(), systemDigiTimes.end()); + } + if (fSystems.size() > 1) { std::sort(digiTimes.begin(), digiTimes.end()); } + } + + // --- Case: input digi branches + else { + for (const auto& system : fSystems) { + CbmDigiBranchBase* digiBranch = fDigiMan->GetBranch(system); + std::vector<double> locDigiTimes; + switch (system) { + case ECbmModuleId::kMuch: { //we do not support the "MuchBeamTimeDigi" + locDigiTimes = GetDigiTimes<CbmMuchDigi>(digiBranch); + break; + } + case ECbmModuleId::kSts: { + locDigiTimes = GetDigiTimes<CbmStsDigi>(digiBranch); + break; + } + case ECbmModuleId::kTof: { + locDigiTimes = GetDigiTimes<CbmTofDigi>(digiBranch); + break; + } + case ECbmModuleId::kTrd: { + locDigiTimes = GetDigiTimes<CbmTrdDigi>(digiBranch); + break; + } + case ECbmModuleId::kRich: { + locDigiTimes = GetDigiTimes<CbmRichDigi>(digiBranch); + break; + } + case ECbmModuleId::kPsd: { + locDigiTimes = GetDigiTimes<CbmPsdDigi>(digiBranch); + break; + } + case ECbmModuleId::kT0: { //T0 has Tof digis + locDigiTimes = GetDigiTimes<CbmTofDigi>(digiBranch); + break; + } + default: { + LOG(error) << GetName() << ": Unknown detector type!"; + break; + } } - default: LOG(fatal) << GetName() << ": Reading digis from unknown detector type!"; + digiTimes.insert(digiTimes.end(), locDigiTimes.begin(), locDigiTimes.end()); } - digiTimes.insert(digiTimes.end(), locDigiTimes.begin(), locDigiTimes.end()); + if (fSystems.size() > 1) { std::sort(digiTimes.begin(), digiTimes.end()); } } - if (fSystems.size() > 1) { std::sort(digiTimes.begin(), digiTimes.end()); } // --- Call the trigger algorithm timerStep.Start(); @@ -111,6 +128,72 @@ void CbmTaskTriggerDigi::Exec(Option_t*) // ---------------------------------------------------------------------------- +// ----- Get digi times from CbmDigiTimeslice ----------------------------- +std::vector<double> CbmTaskTriggerDigi::GetDigiTimes(ECbmModuleId system) +{ + assert(fTimeslice); + std::vector<double> result; + switch (system) { + case ECbmModuleId::kSts: { + result.resize(fTimeslice->fData.fSts.fDigis.size()); + auto it1 = fTimeslice->fData.fSts.fDigis.begin(); + auto it2 = fTimeslice->fData.fSts.fDigis.end(); + std::transform(it1, it2, result.begin(), [](const CbmStsDigi& digi) { return digi.GetTime(); }); + break; + } + case ECbmModuleId::kRich: { + result.resize(fTimeslice->fData.fRich.fDigis.size()); + auto it1 = fTimeslice->fData.fRich.fDigis.begin(); + auto it2 = fTimeslice->fData.fRich.fDigis.end(); + std::transform(it1, it2, result.begin(), [](const CbmRichDigi& digi) { return digi.GetTime(); }); + break; + } + case ECbmModuleId::kMuch: { + result.resize(fTimeslice->fData.fMuch.fDigis.size()); + auto it1 = fTimeslice->fData.fMuch.fDigis.begin(); + auto it2 = fTimeslice->fData.fMuch.fDigis.end(); + std::transform(it1, it2, result.begin(), [](const CbmMuchDigi& digi) { return digi.GetTime(); }); + break; + } + case ECbmModuleId::kTrd: { + result.resize(fTimeslice->fData.fTrd.fDigis.size()); + auto it1 = fTimeslice->fData.fTrd.fDigis.begin(); + auto it2 = fTimeslice->fData.fTrd.fDigis.end(); + std::transform(it1, it2, result.begin(), [](const CbmTrdDigi& digi) { return digi.GetTime(); }); + break; + } + case ECbmModuleId::kTof: { + result.resize(fTimeslice->fData.fTof.fDigis.size()); + auto it1 = fTimeslice->fData.fTof.fDigis.begin(); + auto it2 = fTimeslice->fData.fTof.fDigis.end(); + std::transform(it1, it2, result.begin(), [](const CbmTofDigi& digi) { return digi.GetTime(); }); + break; + } + case ECbmModuleId::kPsd: { + result.resize(fTimeslice->fData.fPsd.fDigis.size()); + auto it1 = fTimeslice->fData.fPsd.fDigis.begin(); + auto it2 = fTimeslice->fData.fPsd.fDigis.end(); + std::transform(it1, it2, result.begin(), [](const CbmPsdDigi& digi) { return digi.GetTime(); }); + break; + } + case ECbmModuleId::kT0: { + result.resize(fTimeslice->fData.fT0.fDigis.size()); + auto it1 = fTimeslice->fData.fT0.fDigis.begin(); + auto it2 = fTimeslice->fData.fT0.fDigis.end(); + std::transform(it1, it2, result.begin(), [](const CbmTofDigi& digi) { return digi.GetTime(); }); + break; + } + default: { + LOG(error) << GetName() << ": Unknown system " << system; + break; + } + } //? system + + return result; +} +// ---------------------------------------------------------------------------- + + // ----- End-of-timeslice action ------------------------------------------ void CbmTaskTriggerDigi::Finish() { @@ -139,21 +222,25 @@ InitStatus CbmTaskTriggerDigi::Init() FairRootManager* ioman = FairRootManager::Instance(); assert(ioman); - // --- DigiManager instance - fDigiMan = CbmDigiManager::Instance(); - fDigiMan->Init(); - std::cout << std::endl; LOG(info) << "=================================================="; LOG(info) << GetName() << ": Initialising..."; // --- Check input data - for (const auto& system : fSystems) { - if (!fDigiMan->IsPresent(system)) { - LOG(fatal) << GetName() << ": No digi branch for " << CbmModuleList::GetModuleNameCaps(system); - return kFATAL; + // --- DigiTimeslice: Unpacked data from FLES + fTimeslice = ioman->InitObjectAs<const CbmDigiTimeslice*>("DigiTimeslice."); + if (fTimeslice) { LOG(info) << GetName() << ": Found branch DigiTimeslice."; } + // --- DigiManager: Simulated digi data + else { + fDigiMan = CbmDigiManager::Instance(); + fDigiMan->Init(); + for (const auto& system : fSystems) { + if (!fDigiMan->IsPresent(system)) { + LOG(fatal) << GetName() << ": No digi branch for " << CbmModuleList::GetModuleNameCaps(system); + return kFATAL; + } + LOG(info) << "--- Found digi branch for " << CbmModuleList::GetModuleNameCaps(system); } - LOG(info) << "--- Found digi branch for " << CbmModuleList::GetModuleNameCaps(system); } // --- Register output array (Triggers) diff --git a/reco/tasks/CbmTaskTriggerDigi.h b/reco/tasks/CbmTaskTriggerDigi.h index 30453cc90e4149302164028fb7fc39b8105bb3d1..61060979847d39ad0ea7c89d56bd67f18d8e7340 100644 --- a/reco/tasks/CbmTaskTriggerDigi.h +++ b/reco/tasks/CbmTaskTriggerDigi.h @@ -19,6 +19,7 @@ class CbmDigiBranchBase; class CbmDigiManager; +struct CbmDigiTimeslice; using namespace std; @@ -105,11 +106,20 @@ private: // methods return digiTimes; } -private: // members - CbmDigiManager* fDigiMan = nullptr; //! Input data - std::vector<ECbmModuleId> fSystems {}; // List of detector systems - std::vector<double>* fTriggers = nullptr; //! Output data - cbm::algo::TimeClusterTrigger fAlgo {}; //! Algorithm + + /** @brief Extract digi times from CbmDigiTimeslice + ** @param system Detector system (enum ECbmModuleId) + ** @return Vector of digi times for the specified system + **/ + std::vector<double> GetDigiTimes(ECbmModuleId system); + + +private: // members + const CbmDigiTimeslice* fTimeslice = nullptr; //! Input data (from unpacking) + CbmDigiManager* fDigiMan = nullptr; //! Input data (from simulation) + std::vector<ECbmModuleId> fSystems {}; // List of detector systems + std::vector<double>* fTriggers = nullptr; //! Output data + cbm::algo::TimeClusterTrigger fAlgo {}; //! Algorithm double fTriggerWindow = 0.; int32_t fMinNumDigis = 0; double fDeadTime = 0.;