diff --git a/algo/base/Options.cxx b/algo/base/Options.cxx index ea9ecace39cfe29f8fff9cec2161871e9f08c569..abce4f27d969904068407a2022446d9cc36946c4 100644 --- a/algo/base/Options.cxx +++ b/algo/base/Options.cxx @@ -93,6 +93,7 @@ Options::Options(int argc, char** argv) ("compress-archive", po::bool_switch(&fCompressArchive)->default_value(false), "Enable compression for output archives") ("steps", po::value(&fRecoSteps)->multitoken()->default_value({Step::Unpack, Step::DigiTrigger, Step::LocalReco, Step::Tracking})->value_name("<steps>"), "space separated list of reconstruction steps (unpack, digitrigger, localreco, ...)") + ("event-reco", po::bool_switch(&fReconstructDigiEvents)->default_value(false), "runs digi event reconstruction (local reco, tracking, trigger)") ("systems,s", po::value(&fDetectors)->multitoken()->default_value({Subsystem::STS, Subsystem::TOF, Subsystem::BMON, Subsystem::MUCH, Subsystem::RICH, Subsystem::TRD, Subsystem::TRD2D})->value_name("<detectors>"), "space separated list of detectors to process (sts, mvd, ...)") ("child-id,c", po::value(&fChildId)->default_value("00")->value_name("<id>"), "online process id on node") diff --git a/algo/base/Options.h b/algo/base/Options.h index 5a9d232fcac8b006b54cfc0ab3f4cdbe5b62a535..f1b508a0699f5839a0b1f5b0e764f0d6a29f8e34 100644 --- a/algo/base/Options.h +++ b/algo/base/Options.h @@ -68,6 +68,8 @@ namespace cbm::algo bool Has(QaStep qastep) const; + bool ReconstructDigiEvents() const { return fReconstructDigiEvents; } + private: // members std::string fParamsDir; // TODO: can we make this a std::path? std::string fInputLocator; @@ -97,6 +99,7 @@ namespace cbm::algo uint64_t fRunId = 2391; uint64_t fRunStartTime = 0; bool fCollectAuxData = false; + bool fReconstructDigiEvents = false; }; } // namespace cbm::algo diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx index 087fbe57530c4754307feffcd7c551fbedd1a1c7..a990278ad2cf01f9ab5377f5b4f213a3f97d673b 100644 --- a/algo/global/Reco.cxx +++ b/algo/global/Reco.cxx @@ -241,6 +241,15 @@ void Reco::Init(const Options& opts) fTrdHitfind = std::make_unique<trd::Hitfind>(setup, setup2d); } + // Digi event reconstruction: + { + fbReconstructDigiEvents = Opts().ReconstructDigiEvents(); + // It makes no sence to reconstruct an event, if there is no STS, TRD or TOF + fbReconstructDigiEvents &= Opts().Has(fles::Subsystem::STS); + fbReconstructDigiEvents &= Opts().Has(fles::Subsystem::TRD); + fbReconstructDigiEvents &= Opts().Has(fles::Subsystem::TOF); + } + // Tracking if (Opts().Has(Step::Tracking)) { if (fQaManager != nullptr && Opts().Has(QaStep::Tracking)) { @@ -393,27 +402,16 @@ RecoResults Reco::Run(const fles::Timeslice& ts) QueueEvbuildMetrics(evbuildMonitor); } - // ***** DEBUG: BEGIN - if constexpr (0) { - int nEvents = events.size(); - size_t nBmonHitsOneChannel{0}; - size_t nBmonHitsTwoChannels{0}; - for (int iE = 0; iE < nEvents; ++iE) { - const auto& event = events[iE]; - // Calibrate TOF digis: - auto [bmonDigis, bmonCalMonitor] = (*fBmonCalibrator)(event.fBmon); - auto [bmonHits, hitmonitor, digiIndices] = (*fBmonHitFinder)(bmonDigis); - if (fBmonHitFinderQa != nullptr) { - fBmonHitFinderQa->RegisterDigis(&bmonDigis); - fBmonHitFinderQa->RegisterHits(&bmonHits); - fBmonHitFinderQa->RegisterDigiIndices(&digiIndices); - fBmonHitFinderQa->Exec(); + // --- Reconstruct and select digi events + if (Opts().ReconstructDigiEvents()) { + size_t nDiscardedEvents{0}; + for (const auto& event : events) { + if (!ReconstructEvent(event)) { + ++nDiscardedEvents; } } - L_(info) << "!!!! BMON hits with two channels: " << nBmonHitsTwoChannels << " / " - << (nBmonHitsTwoChannels + nBmonHitsOneChannel); + L_(info) << "Rate of discarded events " << double(nDiscardedEvents) / events.size(); } - // ***** DEBUG: END // --- Filter data for output if (Opts().HasOutput(RecoData::DigiTimeslice)) { @@ -491,6 +489,45 @@ void Reco::PrintTimings(xpu::timings& timings) } } +bool Reco::ReconstructEvent(const DigiEvent& digiEvent) +{ + RecoResults recoEvent; + //* STS hit reconstruction + { + auto stsResults = (*fStsHitFinder)(digiEvent.fSts); + if (stsResults.hits.NElements() < 2) { // TODO: Provide a config for cuts (testing mode for now) + return false; + } + recoEvent.stsHits = stsResults.hits; + } + + //* TOF hit reconstruction + { + auto [caldigis, calmonitor] = (*fTofCalibrator)(digiEvent.fTof); + auto [hits, hitmonitor, digiindices] = (*fTofHitFinder)(caldigis); + if (hits.NElements() < 1) { // TODO: Provide a config for cuts (testing mode for now) + return false; + } + recoEvent.tofHits = std::move(hits); + } + + //* TRD hit reconstruction + { + // FIXME: additional copy of digis, figure out how to pass 1d + 2d digis at once to hitfinder + const auto& digis1d = digiEvent.fTrd; + const auto& digis2d = digiEvent.fTrd2d; + PODVector<CbmTrdDigi> allDigis{}; + allDigis.reserve(digis1d.size() + digis2d.size()); + std::copy(digis1d.begin(), digis1d.end(), std::back_inserter(allDigis)); + std::copy(digis2d.begin(), digis2d.end(), std::back_inserter(allDigis)); + auto trdResults = (*fTrdHitfind)(allDigis); + recoEvent.trdHits = std::move(std::get<0>(trdResults)); + } + + return true; +} + + template<class Unpacker> auto Reco::RunUnpacker(const std::unique_ptr<Unpacker>& unpacker, const fles::Timeslice& ts) -> UnpackResult_t<Unpacker> { diff --git a/algo/global/Reco.h b/algo/global/Reco.h index 6182decdad9d289e7a654aabbb6b5db8650efe29..5a2c62e63a5c0b22bdf2d69175e00b511e4c2243 100644 --- a/algo/global/Reco.h +++ b/algo/global/Reco.h @@ -130,13 +130,16 @@ namespace cbm::algo void Init(const Options&); RecoResults Run(const fles::Timeslice&); + + bool ReconstructEvent(const DigiEvent& event); void Finalize(); void PrintTimings(xpu::timings&); void QueueProcessingExtraMetrics(const ProcessingExtraMonitor&); private: - bool fInitialized = false; + bool fInitialized = false; + bool fbReconstructDigiEvents = false; ChainContext fContext; xpu::timings fTimesliceTimesAcc; std::shared_ptr<HistogramSender> fSender;