diff --git a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx index e43e8ae1891303e79495b44f986fb2b8c5d27908..f748a36cca443651e389726d879a1f0a96c9fd04 100644 --- a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx +++ b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx @@ -31,6 +31,9 @@ #include "TH2.h" #include "THttpServer.h" +template<> +void CbmAlgoBuildRawEvents::LoopOnSeeds<Double_t>(); + Bool_t CbmAlgoBuildRawEvents::InitAlgo() { LOG(info) << "CbmAlgoBuildRawEvents::InitAlgo => Starting sequence"; @@ -38,8 +41,21 @@ Bool_t CbmAlgoBuildRawEvents::InitAlgo() // Get a handle from the IO manager FairRootManager* ioman = FairRootManager::Instance(); - /// Check if reference detector data are available - if (kFALSE == CheckDataAvailable(fRefDet)) { LOG(fatal) << "No digi input for reference detector, stopping there!"; } + /// Check if reference detector is set and seed data are available, + /// otherwise look for explicit seed times + if (fRefDet.detId == ECbmModuleId::kNotExist) { + if (fSeedTimes == nullptr) { + LOG(fatal) << "No reference detector set and no seed times supplied, stopping there!"; + } + } + else { + if (fSeedTimes != nullptr) { + LOG(fatal) << "Cannot have explicit seed times and reference detector, stopping there!"; + } + if (kFALSE == CheckDataAvailable(fRefDet)) { + LOG(fatal) << "Reference detector set but no digi input found, stopping there!"; + } + } /// Check if data for detectors in selection list are available for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) { @@ -106,9 +122,12 @@ void CbmAlgoBuildRawEvents::ProcessTs() void CbmAlgoBuildRawEvents::InitTs() { /// Reset TS based variables (analysis per TS = no building over the border) + /// Reference detector - fRefDet.fuStartIndex = 0; - fRefDet.fuEndIndex = 0; + if (fRefDet.detId != ECbmModuleId::kNotExist) { + fRefDet.fuStartIndex = 0; + fRefDet.fuEndIndex = 0; + } /// Loop on detectors in selection list for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) { (*det).fuStartIndex = 0; @@ -189,6 +208,10 @@ void CbmAlgoBuildRawEvents::BuildEvents() LoopOnSeeds<CbmTofDigi>(); break; } + case ECbmModuleId::kNotExist: { //explicit seed times + LoopOnSeeds<Double_t>(); + break; + } default: { LOG(fatal) << "CbmAlgoBuildRawEvents::BuildEvents => " << "Trying to search event seeds with unsupported det: " << fRefDet.sName; @@ -197,6 +220,30 @@ void CbmAlgoBuildRawEvents::BuildEvents() } } +template<> +void CbmAlgoBuildRawEvents::LoopOnSeeds<Double_t>() +{ + if (ECbmModuleId::kNotExist == fRefDet.detId) { + const UInt_t uNbSeeds = fSeedTimes->size(); + /// Loop on size of vector + for (UInt_t uSeed = 0; uSeed < uNbSeeds; ++uSeed) { + LOG(debug) << Form("Checking seed %6u / %6u", uSeed, uNbSeeds); + Double_t dTime = fSeedTimes->at(uSeed); + + /// Check if seed in acceptance window (is this needed here?) + if (dTime < fdSeedWindowBeg) { continue; } + else if (fdSeedWindowEnd < dTime) { + break; + } + /// Check Seed and build event if needed + CheckSeed(dTime, uSeed); + } + } + else { + LOG(fatal) << "Trying to read explicit seeds while reference detector is set."; + } +} + template<class DigiSeed> void CbmAlgoBuildRawEvents::LoopOnSeeds() { @@ -229,12 +276,20 @@ void CbmAlgoBuildRawEvents::LoopOnSeeds() } } +Double_t CbmAlgoBuildRawEvents::GetSeedTimeWinRange() +{ + if (ECbmModuleId::kNotExist != fRefDet.detId) { return fRefDet.GetTimeWinRange(); } + else { + return fdSeedTimeWinEnd - fdSeedTimeWinBeg; + } +} + void CbmAlgoBuildRawEvents::CheckSeed(Double_t dSeedTime, UInt_t uSeedDigiIdx) { /// If previous event valid and event overlap not allowed, check if we are in overlap /// and react accordingly if (nullptr != fCurrentEvent - && (EOverlapModeRaw::AllowOverlap != fOverMode || dSeedTime - fdPrevEvtTime < fRefDet.GetTimeWinRange()) + && (EOverlapModeRaw::AllowOverlap != fOverMode || dSeedTime - fdPrevEvtTime < GetSeedTimeWinRange()) && dSeedTime - fdPrevEvtTime < fdWidestTimeWinRange) { /// Within overlap range switch (fOverMode) { @@ -270,15 +325,17 @@ void CbmAlgoBuildRawEvents::CheckSeed(Double_t dSeedTime, UInt_t uSeedDigiIdx) fCurrentEvent = new CbmEvent(fuCurEv, dSeedTime, 0.); } // else of if( prev Event exists and mode forbiden overlap present ) - /// If window open for reference detector, search for other reference Digis matching it - /// Otherwise only add the current seed - if (fRefDet.fdTimeWinBeg < fRefDet.fdTimeWinEnd) { - SearchMatches(dSeedTime, fRefDet); - /// Also add the seed if the window starts after the seed - if (0 < fRefDet.fdTimeWinBeg) AddDigiToEvent(fRefDet, uSeedDigiIdx); - } - else { - AddDigiToEvent(fRefDet, uSeedDigiIdx); + if (fRefDet.detId != ECbmModuleId::kNotExist) { + /// If window open for reference detector, search for other reference Digis matching it + /// Otherwise only add the current seed + if (fRefDet.fdTimeWinBeg < fRefDet.fdTimeWinEnd) { + SearchMatches(dSeedTime, fRefDet); + /// Also add the seed if the window starts after the seed + if (0 < fRefDet.fdTimeWinBeg) AddDigiToEvent(fRefDet, uSeedDigiIdx); + } + else { + AddDigiToEvent(fRefDet, uSeedDigiIdx); + } } /// Search for matches for each detector in selection list @@ -413,7 +470,7 @@ void CbmAlgoBuildRawEvents::CheckTriggerCondition(Double_t dSeedTime) /// from end of current window in order to save CPU and avoid duplicating if (EOverlapModeRaw::NoOverlap == fOverMode || EOverlapModeRaw::MergeOverlap == fOverMode) { /// Update reference detector - fRefDet.fuStartIndex = fRefDet.fuEndIndex; + if (fRefDet.detId != ECbmModuleId::kNotExist) { fRefDet.fuStartIndex = fRefDet.fuEndIndex; } /// Loop on selection detectors for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) { (*det).fuStartIndex = (*det).fuEndIndex; @@ -430,7 +487,9 @@ void CbmAlgoBuildRawEvents::CheckTriggerCondition(Double_t dSeedTime) Bool_t CbmAlgoBuildRawEvents::HasTrigger(CbmEvent* event) { /// Check first reference detector - if (kFALSE == CheckTriggerConditions(event, fRefDet)) { return kFALSE; } + if (fRefDet.detId != ECbmModuleId::kNotExist) { + if (kFALSE == CheckTriggerConditions(event, fRefDet)) { return kFALSE; } + } /// Loop on selection detectors for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) { if (kFALSE == CheckTriggerConditions(event, *det)) return kFALSE; @@ -844,9 +903,15 @@ void CbmAlgoBuildRawEvents::SetTriggerWindow(ECbmModuleId selDet, Double_t dWinB void CbmAlgoBuildRawEvents::UpdateTimeWinBoundariesExtrema() { - /// Initialize with reference detector - fdEarliestTimeWinBeg = fRefDet.fdTimeWinBeg; - fdLatestTimeWinEnd = fRefDet.fdTimeWinEnd; + /// Initialize with reference detector or explicit times + if (fRefDet.detId != ECbmModuleId::kNotExist) { + fdEarliestTimeWinBeg = fRefDet.fdTimeWinBeg; + fdLatestTimeWinEnd = fRefDet.fdTimeWinEnd; + } + else { + fdEarliestTimeWinBeg = fdSeedTimeWinBeg; + fdLatestTimeWinEnd = fdSeedTimeWinEnd; + } /// Loop on selection detectors for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) { @@ -858,7 +923,7 @@ void CbmAlgoBuildRawEvents::UpdateTimeWinBoundariesExtrema() void CbmAlgoBuildRawEvents::UpdateWidestTimeWinRange() { /// Initialize with reference detector - fdWidestTimeWinRange = fRefDet.fdTimeWinEnd - fRefDet.fdTimeWinBeg; + fdWidestTimeWinRange = GetSeedTimeWinRange(); /// Loop on selection detectors for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) { diff --git a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h index 1af66f824df9def61cd05c29f95a863f36a847e0..7ab53eb48c0b14da8ccbf946512c28c81826f2c7 100644 --- a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h +++ b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h @@ -151,6 +151,14 @@ public: fdTsOverLength = dTsOverLength; } + void SetSeedTimeWindow(Double_t timeWinBeg, Double_t timeWinEnd) + { + fdSeedTimeWinBeg = timeWinBeg; + fdSeedTimeWinEnd = timeWinEnd; + UpdateTimeWinBoundariesExtrema(); + UpdateWidestTimeWinRange(); + } + /// Control flags void SetEventOverlapMode(EOverlapModeRaw mode) { fOverMode = mode; } void SetIgnoreTsOverlap(Bool_t bFlagIn = kTRUE) { fbIgnoreTsOverlap = bFlagIn; } @@ -182,6 +190,8 @@ public: fMuchBeamTimeDigis = MuchBeamTimeDigis; } + void SetSeedTimes(std::vector<Double_t>* SeedTimes) { fSeedTimes = SeedTimes; } + /// Data output access std::vector<CbmEvent*>& GetEventVector() { return fEventVector; } void ClearEventVector(); @@ -198,6 +208,7 @@ private: template<class DigiSeed> void LoopOnSeeds(); + void CheckSeed(Double_t dSeedTime, UInt_t uSeedDigiIdx); void CheckTriggerCondition(Double_t dSeedTime); @@ -259,11 +270,18 @@ private: const std::vector<CbmRichDigi>* fRichDigis = nullptr; const std::vector<CbmPsdDigi>* fPsdDigis = nullptr; + // If explicit seed times are supplied. + const std::vector<Double_t>* fSeedTimes = nullptr; + Double_t fdSeedTimeWinBeg = -100.0; + Double_t fdSeedTimeWinEnd = 100.0; + bool CheckDataAvailable(ECbmModuleId detId); UInt_t GetNofDigis(ECbmModuleId detId); template<class Digi> const Digi* GetDigi(UInt_t uDigi); + Double_t GetSeedTimeWinRange(); + /// Data ouptut CbmEvent* fCurrentEvent = nullptr; //! pointer to the event which is currently build std::vector<CbmEvent*> fEventVector = {}; //! vector with all created events diff --git a/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx index 67e642bb4b255d27a86857c125040fd3f6ba622b..23445eda840c42a1f671783e5975d2cd195d4b1c 100644 --- a/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx +++ b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx @@ -113,6 +113,7 @@ InitStatus CbmTaskBuildRawEvents::Init() return kFATAL; } + InitStatus CbmTaskBuildRawEvents::ReInit() { return kSUCCESS; } void CbmTaskBuildRawEvents::Exec(Option_t* /*option*/) @@ -122,12 +123,16 @@ void CbmTaskBuildRawEvents::Exec(Option_t* /*option*/) //as the digi manager can return -1, which would be casted to +1 //during comparison, leading to an error. + //Reset explicit seed times if set + if (fSeedTimeDet != kRawEventBuilderDetUndef) { fSeedTimes->clear(); } + //Read STS digis if (fDigiMan->IsPresent(ECbmModuleId::kSts)) { fStsDigis->clear(); for (Int_t i = 0; i < fDigiMan->GetNofDigis(ECbmModuleId::kSts); i++) { const CbmStsDigi* Digi = fDigiMan->Get<CbmStsDigi>(i); fStsDigis->push_back(*Digi); + if (fSeedTimeDet.detId == ECbmModuleId::kSts) { fSeedTimes->push_back(Digi->GetTime()); } } LOG(debug) << "Read: " << fStsDigis->size() << " STS digis."; LOG(debug) << "In DigiManager: " << fDigiMan->GetNofDigis(ECbmModuleId::kSts) << " STS digis."; @@ -140,6 +145,7 @@ void CbmTaskBuildRawEvents::Exec(Option_t* /*option*/) for (Int_t i = 0; i < fDigiMan->GetNofDigis(ECbmModuleId::kMuch); i++) { const CbmMuchBeamTimeDigi* Digi = fDigiMan->Get<CbmMuchBeamTimeDigi>(i); fMuchBeamTimeDigis->push_back(*Digi); + if (fSeedTimeDet.detId == ECbmModuleId::kMuch) { fSeedTimes->push_back(Digi->GetTime()); } } LOG(debug) << "Read: " << fDigiMan->GetNofDigis(ECbmModuleId::kMuch) << " MUCH digis."; LOG(debug) << "In DigiManager: " << fMuchBeamTimeDigis->size() << " MUCH digis."; @@ -149,6 +155,7 @@ void CbmTaskBuildRawEvents::Exec(Option_t* /*option*/) for (Int_t i = 0; i < fDigiMan->GetNofDigis(ECbmModuleId::kMuch); i++) { const CbmMuchDigi* Digi = fDigiMan->Get<CbmMuchDigi>(i); fMuchDigis->push_back(*Digi); + if (fSeedTimeDet.detId == ECbmModuleId::kMuch) { fSeedTimes->push_back(Digi->GetTime()); } } LOG(debug) << "Read: " << fDigiMan->GetNofDigis(ECbmModuleId::kMuch) << " MUCH digis."; LOG(debug) << "In DigiManager: " << fMuchDigis->size() << " MUCH digis."; @@ -161,6 +168,7 @@ void CbmTaskBuildRawEvents::Exec(Option_t* /*option*/) for (Int_t i = 0; i < fDigiMan->GetNofDigis(ECbmModuleId::kTrd); i++) { const CbmTrdDigi* Digi = fDigiMan->Get<CbmTrdDigi>(i); fTrdDigis->push_back(*Digi); + if (fSeedTimeDet.detId == ECbmModuleId::kTrd) { fSeedTimes->push_back(Digi->GetTime()); } } LOG(debug) << "Read: " << fDigiMan->GetNofDigis(ECbmModuleId::kTrd) << " TRD digis."; LOG(debug) << "In DigiManager: " << fTrdDigis->size() << " TRD digis."; @@ -172,6 +180,7 @@ void CbmTaskBuildRawEvents::Exec(Option_t* /*option*/) for (Int_t i = 0; i < fDigiMan->GetNofDigis(ECbmModuleId::kTof); i++) { const CbmTofDigi* Digi = fDigiMan->Get<CbmTofDigi>(i); fTofDigis->push_back(*Digi); + if (fSeedTimeDet.detId == ECbmModuleId::kTof) { fSeedTimes->push_back(Digi->GetTime()); } } LOG(debug) << "Read: " << fDigiMan->GetNofDigis(ECbmModuleId::kTof) << " TOF digis."; LOG(debug) << "In DigiManager: " << fTofDigis->size() << " TOF digis."; @@ -183,6 +192,7 @@ void CbmTaskBuildRawEvents::Exec(Option_t* /*option*/) for (Int_t i = 0; i < fDigiMan->GetNofDigis(ECbmModuleId::kRich); i++) { const CbmRichDigi* Digi = fDigiMan->Get<CbmRichDigi>(i); fRichDigis->push_back(*Digi); + if (fSeedTimeDet.detId == ECbmModuleId::kRich) { fSeedTimes->push_back(Digi->GetTime()); } } LOG(debug) << "Read: " << fDigiMan->GetNofDigis(ECbmModuleId::kRich) << " RICH digis."; LOG(debug) << "In DigiManager: " << fRichDigis->size() << " RICH digis."; @@ -194,10 +204,12 @@ void CbmTaskBuildRawEvents::Exec(Option_t* /*option*/) for (Int_t i = 0; i < fDigiMan->GetNofDigis(ECbmModuleId::kPsd); i++) { const CbmPsdDigi* Digi = fDigiMan->Get<CbmPsdDigi>(i); fPsdDigis->push_back(*Digi); + if (fSeedTimeDet.detId == ECbmModuleId::kPsd) { fSeedTimes->push_back(Digi->GetTime()); } } LOG(debug) << "Read: " << fDigiMan->GetNofDigis(ECbmModuleId::kPsd) << " PSD digis."; LOG(debug) << "In DigiManager: " << fPsdDigis->size() << " PSD digis."; } + /// Call Algo ProcessTs method fpAlgo->ProcessTs(); diff --git a/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h index e736d634a227c7afe60aa552b4e25c6365854baa..267fa861411b6b26e6c8bda126ebba489037cbd6 100644 --- a/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h +++ b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h @@ -114,6 +114,22 @@ public: if (nullptr != fpAlgo) fpAlgo->ChangeMuchBeamtimeDigiFlag(bFlagIn); fbUseMuchBeamtimeDigi = bFlagIn; } + void SetSeedTimeFiller(RawEventBuilderDetector seedDet) + { + fSeedTimeDet = seedDet; + if (fSeedTimeDet != kRawEventBuilderDetUndef) { + if (fSeedTimes == nullptr) { fSeedTimes = new std::vector<Double_t>; } + } + else { + if (fSeedTimes != nullptr) { + fSeedTimes->clear(); + delete fSeedTimes; + fSeedTimes = nullptr; + } + } + fpAlgo->SetSeedTimes(fSeedTimes); + } + void SetSeedTimeWindow(Double_t beg, Double_t end) { fpAlgo->SetSeedTimeWindow(beg, end); } private: void FillOutput(); @@ -129,8 +145,12 @@ private: std::vector<CbmRichDigi>* fRichDigis = nullptr; std::vector<CbmPsdDigi>* fPsdDigis = nullptr; + std::vector<Double_t>* fSeedTimes = nullptr; + Bool_t fbUseMuchBeamtimeDigi = kTRUE; //! Switch between MUCH digi classes + RawEventBuilderDetector fSeedTimeDet = kRawEventBuilderDetUndef; + CbmAlgoBuildRawEvents* fpAlgo = nullptr; TClonesArray* fEvents = nullptr; //! output container of CbmEvents