From c05f21ff66b904712ae4796e298f202ffe677a96 Mon Sep 17 00:00:00 2001 From: "s.zharko@gsi.de" <s.zharko@gsi.de> Date: Mon, 3 Feb 2025 20:39:35 +0100 Subject: [PATCH] online: online interface for the KFParticle and intialization of V0Finder --- algo/CMakeLists.txt | 3 + algo/evselector/RecoEventSelectorMonitor.h | 6 +- algo/global/ParFiles.cxx | 6 ++ algo/global/ParFiles.h | 4 + algo/kfp/CMakeLists.txt | 1 + algo/kfp/KfpV0Finder.cxx | 1 - algo/kfp/KfpV0Finder.h | 87 ++++++++++++++++++++++ algo/kfp/KfpV0FinderChain.cxx | 83 ++++++++++++++++++++- algo/kfp/interface/CMakeLists.txt | 42 +++++++++++ 9 files changed, 226 insertions(+), 7 deletions(-) create mode 100644 algo/kfp/CMakeLists.txt create mode 100644 algo/kfp/interface/CMakeLists.txt diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt index 0524146a4..6ba7a06c0 100644 --- a/algo/CMakeLists.txt +++ b/algo/CMakeLists.txt @@ -52,6 +52,7 @@ if (CBM_ONLINE_STANDALONE) add_subdirectory(../external external) endif() +add_subdirectory(kfp) add_subdirectory(log) add_subdirectory(data) add_subdirectory(kf) @@ -226,6 +227,7 @@ target_link_libraries(Algo external::fles_monitoring cppzmq poolstl + PRIVATE CbmKFParticleOnlineInterface ) target_compile_definitions(Algo PUBLIC NO_ROOT) xpu_attach(Algo ${DEVICE_SRCS}) @@ -299,6 +301,7 @@ if (NOT CBM_ONLINE_STANDALONE) external::fles_monitoring cppzmq poolstl + PRIVATE CbmKFParticleOfflineInterface ) xpu_attach(AlgoOffline ${DEVICE_SRCS}) diff --git a/algo/evselector/RecoEventSelectorMonitor.h b/algo/evselector/RecoEventSelectorMonitor.h index 330f70702..41bc2ff13 100644 --- a/algo/evselector/RecoEventSelectorMonitor.h +++ b/algo/evselector/RecoEventSelectorMonitor.h @@ -51,9 +51,9 @@ namespace cbm::algo::evselect Monitor() : ca::Monitor<ECounter, ETimer>("Event-selector Monitor") { SetCounterName(ECounter::EventsTotal, "total events"); - SetCounterName(ECounter::EventsNeStsHits, "events with not enough STS hits"); - SetCounterName(ECounter::EventsNeTofHits, "events with enough STS hits, but not enough TOF hits"); - SetCounterName(ECounter::EventsNeTracks, "events with enough STS and TOF hits, but not enough tracks"); + SetCounterName(ECounter::EventsNeStsHits, "events discarded by N STS hits"); + SetCounterName(ECounter::EventsNeTofHits, "events discarded by N TOF hits"); + SetCounterName(ECounter::EventsNeTracks, "events discarded by N tracks"); SetCounterName(ECounter::EventsSelected, "selected events"); SetTimerName(ETimer::EventReconstruction, "event reconstruction"); diff --git a/algo/global/ParFiles.cxx b/algo/global/ParFiles.cxx index ac2c3b410..38773a0e8 100644 --- a/algo/global/ParFiles.cxx +++ b/algo/global/ParFiles.cxx @@ -45,6 +45,8 @@ ParFiles::ParFiles(uint32_t runId) trd.hitfinder2d = "TrdHitfinder2DPar_mcbm2022.yaml"; ca.mainConfig = "TrackingChainConfig_mcbm2022.yaml"; + + kfp.V0FinderConfig = "mcbm_kfp_lambda.yaml"; break; case Setup::mCBM2024_03: @@ -68,6 +70,8 @@ ParFiles::ParFiles(uint32_t runId) trd.hitfinder2d = "TrdHitfinder2DPar_mcbm2024.yaml"; ca.mainConfig = "TrackingChainConfig_mcbm2024.yaml"; + + kfp.V0FinderConfig = "mcbm_kfp_lambda.yaml"; break; case Setup::mCBM2024_05: @@ -91,6 +95,8 @@ ParFiles::ParFiles(uint32_t runId) trd.hitfinder2d = "mcbm2024_05/TrdHitfinder2DPar.yaml"; ca.mainConfig = "mcbm2024_05/TrackingChainConfig.yaml"; + + kfp.V0FinderConfig = "mcbm_kfp_lambda.yaml"; break; case Setup::mCBM2025_02: diff --git a/algo/global/ParFiles.h b/algo/global/ParFiles.h index 691e27b39..0fe7b3094 100644 --- a/algo/global/ParFiles.h +++ b/algo/global/ParFiles.h @@ -54,6 +54,10 @@ namespace cbm::algo struct { fs::path mainConfig; } ca; + + struct { + fs::path V0FinderConfig; + } kfp; }; } // namespace cbm::algo diff --git a/algo/kfp/CMakeLists.txt b/algo/kfp/CMakeLists.txt new file mode 100644 index 000000000..cc41f095b --- /dev/null +++ b/algo/kfp/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(interface) diff --git a/algo/kfp/KfpV0Finder.cxx b/algo/kfp/KfpV0Finder.cxx index 58ca42939..52a8f0d03 100644 --- a/algo/kfp/KfpV0Finder.cxx +++ b/algo/kfp/KfpV0Finder.cxx @@ -11,7 +11,6 @@ using cbm::algo::kfp::V0Finder; - // --------------------------------------------------------------------------------------------------------------------- // void V0Finder::Init() {} diff --git a/algo/kfp/KfpV0Finder.h b/algo/kfp/KfpV0Finder.h index d0a8a451a..5240085b8 100644 --- a/algo/kfp/KfpV0Finder.h +++ b/algo/kfp/KfpV0Finder.h @@ -10,8 +10,12 @@ #pragma once #include "CbmEventTriggers.h" +#include "KFParticleTopoReconstructor.h" #include "global/RecoResults.h" +#include <memory> + + namespace cbm::algo::kfp { /// \class V0Finder @@ -36,12 +40,95 @@ namespace cbm::algo::kfp /// \brief Move assignment operator V0Finder& operator=(V0Finder&&) = delete; + /// \brief Adds particle to reconstruction list + /// \param pdg A PDG code of the particle to be reconstructed + void AddDecayToReconstructionList(int pdg) { GetKFParticleFinder()->AddDecayToReconstructionList(pdg); } + + /// \brief Mutable access to the KfParticleFinder of the run topology reconstructor + KFParticleFinder* GetKFParticleFinder() { return fpTopoReconstructor->GetKFParticleFinder(); } + + /// \brief Constant access to the KfParticleFinder of the run topology reconstructor + const KFParticleFinder* GetKFParticleFinder() const { return fpTopoReconstructor->GetKFParticleFinder(); } + /// \brief Initializes the instance (called in the beginning of the run) void Init(); /// \brief Processes a reconstructed data sample, returns a collection of fired triggers CbmEventTriggers Process(const RecoResults& recoEvent); + /// \brief Sets minimal pion DCA to primary vertex + /// \param dca DCA [cm] + void SetMinPionDca(double dca) { fMinPionDca = dca; } + + /// \brief Sets minimal proton DCA to primary vertex + /// \param dca DCA [cm] + void SetMinProtonDca(double dca) { fMinProtonDca = dca; } + + /// \brief Sets pion velocity range + /// \param vMin Minimal velocity [cm/ns] + /// \param vMax Maximal velocity [cm/ns] + void SetPionVelocityRange(double vMin, double vMax) + { + fMinBetaPion = vMin / kSpeedOfLight; + fMaxBetaPion = vMax / kSpeedOfLight; + } + + /// \brief Sets proton velocity range + /// \param vMin Minimal velocity [cm/ns] + /// \param vMax Maximal velocity [cm/ns] + void SetProtonVelocityRange(double vMin, double vMax) + { + fMinBetaProton = vMin / kSpeedOfLight; + fMaxBetaProton = vMax / kSpeedOfLight; + } + + /// \brief Sets the assigned PDG for primary particles + /// \param pdg PDG code of the particle + void SetPrimaryAssignedPdg(int pdg) { fPrimaryAssignedPdg = pdg; } + + /// \brief Assignes an uncertainty to the momentum measurement + /// \param uncertainty Relative uncertainty ( = sqrt(var(q/p)) / (q/p)) + void SetQpAssignedUncertainty(double uncertainty) { fQpAssignedUncertainty = uncertainty; } + + /// \brief Sets an offset to t0 + /// \param offset An offset [ns] + void SetTzeroOffset(double offset) { fTzeroOffset = offset; } + + //* Specific parameters for the KFParticleFinder + /// \brief Sets cut on the distance to the primary vertex from the decay vertex + /// \param cut Cut value [cm] + void SetLCut(float cut) { GetKFParticleFinder()->SetLCut(cut); } + + /// \brief Sets cut on \f$\chi^2_{prim}\f$ of each track for 2-daughter decays + /// \param cut Cut value + void SetChiPrimaryCut2D(float cut) { GetKFParticleFinder()->SetChiPrimaryCut2D(cut); } + + /// \brief Sets cut on \f$\chi^2_{geo}\f$ for 2-daughter decays + /// \param cut Cut value + void SetChi2Cut2D(float cut) { GetKFParticleFinder()->SetChi2Cut2D(cut); } + + /// \brief Sets cut on \f$l/\Delta l\f$ for 2-daughter decays + /// \param cut Cut value + void SetLdLCut2D(float cut) { GetKFParticleFinder()->SetLdLCut2D(cut); } + private: + //* Physical constants + static constexpr double kPionMass{0.13957039}; ///< Pion mass [GeV/c2] + static constexpr double kProtonMass{0.938272088}; ///< Proton mass [GeV/c2] + static constexpr double kSpeedOfLight{29.9792458}; ///< Speed of light [cm/ns] + + /// \brief An instance of the topology reconstructor + std::unique_ptr<KFParticleTopoReconstructor> fpTopoReconstructor{std::make_unique<KFParticleTopoReconstructor>()}; + + //* Different run-time cuts and flags (TODO: define in a config) + double fTzeroOffset{0.}; ///< Offset for T0 + double fMinPionDca{1.5}; ///< Minimum DCA to PV for pions + double fMinProtonDca{0.5}; ///< Minimum DCA to PV for protons + double fQpAssignedUncertainty{0.1}; ///< Assigned relative uncertainty for q/p estimation + int fPrimaryAssignedPdg{321}; ///< Assigned PDG hypothesis for primary particles + double fMinBetaProton{0.}; ///< Minimal proton velocity (beta) [c] + double fMaxBetaProton{1.}; ///< Maximal proton velocity (beta) [c] + double fMinBetaPion{0.}; ///< Minimal proton velocity (beta) [c] + double fMaxBetaPion{1.}; ///< Maximal proton velocity (beta) [c] }; } // namespace cbm::algo::kfp diff --git a/algo/kfp/KfpV0FinderChain.cxx b/algo/kfp/KfpV0FinderChain.cxx index a2a78be1c..1fb1a7a9d 100644 --- a/algo/kfp/KfpV0FinderChain.cxx +++ b/algo/kfp/KfpV0FinderChain.cxx @@ -9,7 +9,12 @@ #include "kfp/KfpV0FinderChain.h" +#include "global/ParFiles.h" +#include "kfp/KfpV0FinderConfig.h" #include "log/AlgoFairloggerCompat.h" +#include "yaml/Yaml.h" + +#include <sstream> using cbm::algo::V0FinderChain; @@ -20,9 +25,81 @@ void V0FinderChain::Finalize() {} // --------------------------------------------------------------------------------------------------------------------- // void V0FinderChain::Init() -{ - L_(info) << "Initializing the V0-finder chain ..."; - L_(info) << "Initializing the V0-finder chain ... done"; +try { + L_(info) << "kfp::V0FinderChain: initializing the V0-finder chain ..."; + + // ----- Read configuration file + ParFiles parFiles(Opts().RunId()); + auto config = yaml::ReadFromFile<kfp::V0FinderConfig>(Opts().ParamsDir() / parFiles.kfp.V0FinderConfig); + L_(info) << config.ToString(); + + //* Check the V0 type + if (config.reconstructPdg != 3122) { // At the moment only Lambda analysis is possible + std::stringstream msg; + msg << "kfp::V0FinderChain: at the moment only lambda finding is possible. Provided PDG: " << config.reconstructPdg; + throw std::runtime_error(msg.str()); + } + + //* Define daughter particles + auto& particles{config.cuts.particles}; + int iPion{-1}; + int iProton{-1}; + for (int iParticle = 0; iParticle < int(particles.size()); ++iParticle) { + const auto& particle = particles[iParticle]; + auto CheckOutParticle = [&](int pdg, int& iParticleToFind) { + if (particle.pdg == pdg) { + if (iParticleToFind == -1) { + iParticleToFind = iParticle; + } + else { + std::stringstream msg; + msg << "kfp::V0FinderChain: entry for pdg= " << pdg << " is defined more then one time in the "; + msg << "config.cuts.particles"; + throw std::runtime_error(msg.str()); + } + } + }; + CheckOutParticle(-211, iPion); + CheckOutParticle(2212, iProton); + } + if (iProton == -1 || iPion == -1) { + std::stringstream msg; + msg << "kfp::V0FinderChain: config cuts/particles: either pion or proton settings are not found"; + throw std::runtime_error(msg.str()); + } + const auto& pion{particles[iPion]}; + const auto& proton{particles[iProton]}; + + // ----- Set the V0-finder properties + // TODO: In future, there are will be a several instances of the V0Finder, each for a particular thread + { + //* Set particle PID properties + fV0Finder.SetMinPionDca(pion.minDca); + fV0Finder.SetMinProtonDca(proton.minDca); + fV0Finder.SetPionVelocityRange(pion.minVelocity, pion.maxVelocity); + fV0Finder.SetProtonVelocityRange(proton.minVelocity, proton.maxVelocity); + + //* Set KFParticleFinder properties + auto& kfpCuts{config.cuts.kfp}; + fV0Finder.SetLdLCut2D(kfpCuts.minDecayLDL); + fV0Finder.SetLCut(kfpCuts.minDecayLength); + fV0Finder.SetChi2Cut2D(kfpCuts.maxChi2NdfGeo); + fV0Finder.SetChiPrimaryCut2D(kfpCuts.maxChi2NdfPrim); + + //* Set other properties + fV0Finder.SetTzeroOffset(config.tZeroOffset); + fV0Finder.SetQpAssignedUncertainty(config.qpAssignedUncertainty); + fV0Finder.AddDecayToReconstructionList(config.reconstructPdg); + fV0Finder.SetPrimaryAssignedPdg(config.primaryAssignedPdg); + + //* Init the V0 finder + fV0Finder.Init(); + } + L_(info) << "kfp::V0FinderChain: initializing the V0-finder chain ... done"; +} +catch (const std::exception& err) { + L_(info) << "kfp::V0FinderChain: initializing the V0-finder chain ... failed. Reason: " << err.what(); + throw std::runtime_error("initialization of V0-finder chain failed"); } // --------------------------------------------------------------------------------------------------------------------- diff --git a/algo/kfp/interface/CMakeLists.txt b/algo/kfp/interface/CMakeLists.txt new file mode 100644 index 000000000..8b037a70e --- /dev/null +++ b/algo/kfp/interface/CMakeLists.txt @@ -0,0 +1,42 @@ +# The script creates two libraries: +# 1) CbmKFParticleOnlineInterface -- a specific KFParticle library interface for the CBM online reconstruction; +# 2) CbmKFParticleOfflineInterface -- a specific interface for the offline reconstruction in CBM. +# The both libraries contain only the KFParticle core and do not include KFParticleTest or KFParticlePerformance. + +set(KFP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../external/KFParticle/KFParticle) + +set(SRCS + ${KFP_SOURCE_DIR}/KFParticle.cxx + ${KFP_SOURCE_DIR}/KFParticleBase.cxx + ${KFP_SOURCE_DIR}/KFParticleBaseSIMD.cxx + ${KFP_SOURCE_DIR}/KFParticleDatabase.cxx + ${KFP_SOURCE_DIR}/KFParticleFinder.cxx + ${KFP_SOURCE_DIR}/KFParticlePVReconstructor.cxx + ${KFP_SOURCE_DIR}/KFParticleSIMD.cxx + ${KFP_SOURCE_DIR}/KFParticleTopoReconstructor.cxx + ${KFP_SOURCE_DIR}/KFPEmcCluster.cxx + ${KFP_SOURCE_DIR}/KFPTrack.cxx + ${KFP_SOURCE_DIR}/KFPTrackVector.cxx + ${KFP_SOURCE_DIR}/KFPVertex.cxx + ${KFP_SOURCE_DIR}/KFVertex.cxx +) + +### CbmKFParticleOnlineInterface +add_library(CbmKFParticleOnlineInterface INTERFACE) +target_include_directories(CbmKFParticleOnlineInterface INTERFACE) +target_compile_definitions(CbmKFParticleOnlineInterface + INTERFACE DO_TPCCATRACKER_EFF_PERFORMANCE NonhomogeneousField CBM USE_TIMERS) +target_link_libraries(CbmKFParticleOnlineInterface + INTERFACE ROOT::Core KFParticle) +install(TARGETS CbmKFParticleOnlineInterface DESTINATION lib) + +if(NOT CBM_ONLINE_STANDALONE) +### CbmKFParticleOfflineInterface + add_library(CbmKFParticleOfflineInterface INTERFACE) + target_include_directories(CbmKFParticleOfflineInterface INTERFACE) + target_compile_definitions(CbmKFParticleOfflineInterface + INTERFACE DO_TPCCATRACKER_EFF_PERFORMANCE NonhomogeneousField CBM USE_TIMERS) + target_link_libraries(CbmKFParticleOfflineInterface + INTERFACE ROOT::Core KFParticle) + install(TARGETS CbmKFParticleOfflineInterface DESTINATION lib) +endif() -- GitLab