diff --git a/algo/evbuild/EventBuilder.cxx b/algo/evbuild/EventBuilder.cxx index baac61a175db8984043321015173730b8cdfa706..8186c792f07f257056943275ad718b6fe2a0f5b5 100644 --- a/algo/evbuild/EventBuilder.cxx +++ b/algo/evbuild/EventBuilder.cxx @@ -4,9 +4,7 @@ #include "EventBuilder.h" -#include <algorithm> #include <cassert> -#include <vector> using std::is_sorted; using std::vector; @@ -15,7 +13,6 @@ namespace cbm { namespace algo { - // --- Execution std::vector<CbmDigiEvent> EventBuilder::operator()(const CbmDigiTimeslice& ts, const vector<double> triggers) const { @@ -26,19 +23,75 @@ namespace cbm return eventVec; } - // --- Build a single event CbmDigiEvent EventBuilder::BuildEvent(const CbmDigiTimeslice& ts, double trigger) const { CbmDigiEvent event; event.fTime = trigger; - double tMin = trigger + fTriggerWindows.find(ECbmModuleId::kSts)->second.first; - double tMax = trigger + fTriggerWindows.find(ECbmModuleId::kSts)->second.second; - 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); - return event; - } + // --- Loop over systems + for (const auto& system : fSystems) { + // --- 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; + + // --- 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); + break; + } + case ECbmModuleId::kTrd: { + assert( + is_sorted(ts.fData.fTrd.fDigis.begin(), ts.fData.fTrd.fDigis.end(), IsBefore<CbmTrdDigi, CbmTrdDigi>)); + 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); + break; + } + case ECbmModuleId::kPsd: { + assert( + is_sorted(ts.fData.fPsd.fDigis.begin(), ts.fData.fPsd.fDigis.end(), IsBefore<CbmPsdDigi, CbmPsdDigi>)); + event.fData.fPsd.fDigis = CopyRange(ts.fData.fPsd.fDigis, tMin, tMax); + break; + } + case ECbmModuleId::kT0: { //T0 has Tof digis + assert(is_sorted(ts.fData.fT0.fDigis.begin(), ts.fData.fT0.fDigis.end(), IsBefore<CbmTofDigi, CbmTofDigi>)); + 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); + } + } + } + return event; + } } // namespace algo } // namespace cbm diff --git a/algo/evbuild/EventBuilder.h b/algo/evbuild/EventBuilder.h index 94f3d94d92280b4b54a5327d6353a10ed4edd734..e224963781d02da689bf601d3868c164ddb4c40f 100644 --- a/algo/evbuild/EventBuilder.h +++ b/algo/evbuild/EventBuilder.h @@ -5,11 +5,12 @@ #ifndef CBM_ALGO_EVENTBUILDER_H #define CBM_ALGO_EVENTBUILDER_H 1 - #include "CbmDefs.h" #include "CbmDigiEvent.h" #include "CbmDigiTimeslice.h" +#include <FairLogger.h> + #include <algorithm> #include <map> #include <vector> @@ -26,7 +27,6 @@ namespace cbm return obj1.GetTime() < obj2.GetTime(); } - /** @class EventBuilder ** @author Volker Friese <v.friese@gsi.de> ** @since 2021 @@ -48,11 +48,9 @@ namespace cbm /** @brief Constructor **/ EventBuilder() {}; - /** @brief Destructor **/ virtual ~EventBuilder() {}; - /** @brief Execution ** @param ts Digi source (timeslice) ** @param triggers List of trigger times @@ -60,7 +58,6 @@ namespace cbm **/ 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 @@ -68,6 +65,14 @@ namespace cbm **/ 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 @@ -76,10 +81,14 @@ namespace cbm **/ void SetTriggerWindow(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); } - private: // methods /** @brief Copy data objects in a given time interval from the source to the target vector ** @param source Source data vector @@ -101,7 +110,6 @@ namespace cbm template<typename Data> static typename std::vector<Data> CopyRange(const std::vector<Data>& source, double tMin, double tMax) { - //auto comp = [](const Data& obj, double value) { return obj.GetTime() < value; }; auto comp1 = [](const Data& obj, double value) { return obj.GetTime() < value; }; auto comp2 = [](double value, const Data& obj) { return value < obj.GetTime(); }; auto lower = std::lower_bound(source.begin(), source.end(), tMin, comp1); @@ -109,12 +117,10 @@ 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 }; - - } // namespace algo } // namespace cbm diff --git a/macro/reco/reco_digi.C b/macro/reco/reco_digi.C index 75328e1f34c043b2e87882bc3d98c72a14af02e3..2958207696a4d7471225ace7c7dc3a20f0c90118 100644 --- a/macro/reco/reco_digi.C +++ b/macro/reco/reco_digi.C @@ -127,7 +127,8 @@ void reco_digi(TString input = "", Int_t nTimeSlices = -1, Int_t firstTimeSlice // ----- Event building ----------------------------------------------- auto evtBuild = std::make_unique<CbmTaskBuildEvents>(); - evtBuild->SetTimeWindow(-20., 30.); // event building time window for STS + evtBuild->AddSystem(ECbmModuleId::kSts); + evtBuild->SetTimeWindow(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 b25049c375e6137c07978f8f965ce658f44c21bf..e71a2ef1dbddeda3b4d82055f8bcfddb900f8035 100644 --- a/reco/tasks/CbmTaskBuildEvents.cxx +++ b/reco/tasks/CbmTaskBuildEvents.cxx @@ -2,14 +2,12 @@ SPDX-License-Identifier: GPL-3.0-only Authors: Volker Friese [committer] */ - #include "CbmTaskBuildEvents.h" -#include "CbmDefs.h" #include "CbmDigiBranchBase.h" -#include "CbmDigiEvent.h" #include "CbmDigiManager.h" #include "CbmDigiTimeslice.h" +#include "CbmModuleList.h" #include <FairLogger.h> @@ -18,14 +16,9 @@ #include <cassert> #include <iomanip> #include <iostream> -#include <vector> - -#include "EventBuilder.h" - using namespace std; - // ----- Constructor ----------------------------------------------------- CbmTaskBuildEvents::CbmTaskBuildEvents() : FairTask("BuildEvents") {} // --------------------------------------------------------------------------- @@ -39,6 +32,68 @@ CbmTaskBuildEvents::~CbmTaskBuildEvents() // --------------------------------------------------------------------------- +// ------ Construct a DigiTimeslice from the data in CbmDigiManager ---------- +CbmDigiTimeslice CbmTaskBuildEvents::FillTimeSlice() +{ + CbmDigiTimeslice ts; + for (const auto& system : fSystems) { + 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()); + assert(digiVec); + ts.fData.fSts.fDigis = *digiVec; + break; + } + case ECbmModuleId::kTof: { + const vector<CbmTofDigi>* digiVec = + boost::any_cast<const vector<CbmTofDigi>*>(digiBranch->GetBranchContainer()); + assert(digiVec); + ts.fData.fTof.fDigis = *digiVec; + break; + } + case ECbmModuleId::kTrd: { + const vector<CbmTrdDigi>* digiVec = + boost::any_cast<const vector<CbmTrdDigi>*>(digiBranch->GetBranchContainer()); + assert(digiVec); + ts.fData.fTrd.fDigis = *digiVec; + break; + } + case ECbmModuleId::kRich: { + const vector<CbmRichDigi>* digiVec = + boost::any_cast<const vector<CbmRichDigi>*>(digiBranch->GetBranchContainer()); + assert(digiVec); + ts.fData.fRich.fDigis = *digiVec; + break; + } + case ECbmModuleId::kPsd: { + const vector<CbmPsdDigi>* digiVec = + boost::any_cast<const vector<CbmPsdDigi>*>(digiBranch->GetBranchContainer()); + assert(digiVec); + ts.fData.fPsd.fDigis = *digiVec; + break; + } + case ECbmModuleId::kT0: { //T0 has Tof digis + const vector<CbmTofDigi>* digiVec = + boost::any_cast<const vector<CbmTofDigi>*>(digiBranch->GetBranchContainer()); + assert(digiVec); + ts.fData.fT0.fDigis = *digiVec; + break; + } + default: LOG(fatal) << GetName() << ": Reading digis from unknown detector type!"; + } + } + return ts; +} + // ----- Execution ------------------------------------------------------- void CbmTaskBuildEvents::Exec(Option_t*) { @@ -53,11 +108,7 @@ void CbmTaskBuildEvents::Exec(Option_t*) // --- Construct a DigiTimeslice from the data in CbmDigiManager timerStep.Start(); - CbmDigiTimeslice ts; - CbmDigiBranchBase* stsBranch = fDigiMan->GetBranch(ECbmModuleId::kSts); - const vector<CbmStsDigi>* digiVec = boost::any_cast<const vector<CbmStsDigi>*>(stsBranch->GetBranchContainer()); - assert(digiVec); - ts.fData.fSts.fDigis = *digiVec; + CbmDigiTimeslice ts = FillTimeSlice(); timerStep.Stop(); fTimeFillTs += timerStep.RealTime(); @@ -121,7 +172,6 @@ void CbmTaskBuildEvents::Finish() // ----- Initialisation --------------------------------------------------- InitStatus CbmTaskBuildEvents::Init() { - // --- Get FairRootManager instance FairRootManager* ioman = FairRootManager::Instance(); assert(ioman); @@ -134,13 +184,14 @@ InitStatus CbmTaskBuildEvents::Init() LOG(info) << "=================================================="; LOG(info) << GetName() << ": Initialising..."; - - // --- Check input data (digis, STS only for the time being) - if (!fDigiMan->IsPresent(ECbmModuleId::kSts)) { - LOG(fatal) << GetName() << ": No digi branch for STS"; - return kFATAL; + // --- Check input data + 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 branch STS digi"; // --- Get input data (triggers) fTriggers = ioman->InitObjectAs<std::vector<double> const*>("Trigger"); @@ -164,9 +215,16 @@ InitStatus CbmTaskBuildEvents::Init() LOG(info) << "--- Registered branch DigiEvent"; // --- Configure algorithm - fAlgo.SetTriggerWindow(ECbmModuleId::kSts, fEvtTimeStsMin, fEvtTimeStsMax); - LOG(info) << "--- Use algo EventBuilder with event window [" << fEvtTimeStsMin << ", " << fEvtTimeStsMax << "] ns"; - + 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); + LOG(info) << "--- Use algo EventBuilder with event window [" << tMin << ", " << tMax << "] ns for " + << CbmModuleList::GetModuleNameCaps(system); + } LOG(info) << "=================================================="; std::cout << std::endl; diff --git a/reco/tasks/CbmTaskBuildEvents.h b/reco/tasks/CbmTaskBuildEvents.h index 41eb11be6654123383361658988d1d673a0079fd..83718f4600586deda476078075a815f7d5310aeb 100644 --- a/reco/tasks/CbmTaskBuildEvents.h +++ b/reco/tasks/CbmTaskBuildEvents.h @@ -2,11 +2,9 @@ SPDX-License-Identifier: GPL-3.0-only Authors: Volker Friese [committer] */ - #ifndef CBMTASKBUILDEVENTS_H #define CBMTASKBUILDEVENTS_H 1 - #include "CbmDefs.h" #include "CbmDigiEvent.h" @@ -18,7 +16,6 @@ class CbmDigiManager; - /** @class CbmTaskBuildEvents ** @brief Task class for associating digis to events ** @author Volker Friese <v.friese@gsi.de> @@ -32,47 +29,54 @@ class CbmDigiManager; **/ class CbmTaskBuildEvents : public FairTask { - 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 **/ - void SetTimeWindow(double tMin, double tMax) + void SetTimeWindow(ECbmModuleId system, double tMin, double tMax) { - fEvtTimeStsMin = tMin; - fEvtTimeStsMax = 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); } - private: // methods /** @brief Task initialisation **/ virtual InitStatus Init(); + /** @brief Construct a DigiTimeslice from the data in CbmDigiManager **/ + CbmDigiTimeslice FillTimeSlice(); private: // members CbmDigiManager* fDigiMan = nullptr; //! Input data (digis) @@ -80,8 +84,9 @@ private: // members std::vector<ECbmModuleId> fSystems {}; // List of detector systems std::vector<CbmDigiEvent>* fEvents = nullptr; //! Output data (events) cbm::algo::EventBuilder fAlgo {}; //! Algorithm - double fEvtTimeStsMin = 0.; - double fEvtTimeStsMax = 0.; + + std::map<ECbmModuleId, std::pair<double, double>> fTriggerWindows; + size_t fNumTs = 0; // Number of processed time slices size_t fNumTriggers = 0; // Number of triggers size_t fNumEvents = 0; // Number of produced events @@ -91,7 +96,6 @@ private: // members double fTimeBuildEvt = 0.; double fTimeTot = 0.; - ClassDef(CbmTaskBuildEvents, 1); };