Skip to content
Snippets Groups Projects
Commit 25b3a198 authored by Sergei Zharko's avatar Sergei Zharko
Browse files

linking KFParticle library to statndalone cbmreco

- using a KFParticle version with no ROOT dependencies
parent 172082af
No related branches found
No related tags found
1 merge request!2000Lambda-selector in cbmreco (first iteration)
Showing
with 253 additions and 135 deletions
......@@ -133,6 +133,7 @@ void TrackingChain::Init()
fQa.RegisterParameters(&fCaFramework.GetParameters());
fQa.Init();
}
L_(info) << "TRACKING QA: " << fQa.IsActive();
}
// ---------------------------------------------------------------------------------------------------------------------
......@@ -225,6 +226,7 @@ TrackingChain::Output_t TrackingChain::PrepareOutput()
int iHitInternal = fCaFramework.GetInputData().GetHit(fCaFramework.fRecoHits[trackFirstHit + iHit]).Id();
const auto [detID, iPartition, iPartHit] = faHitExternalIndices[iHitInternal];
switch (detID) {
// FIXME: store a global hit index instead of (partition, hit)
case ca::EDetectorID::kSts: output.stsHitIndices[iTrk].push_back(std::make_pair(iPartition, iPartHit)); break;
case ca::EDetectorID::kTof: output.tofHitIndices[iTrk].push_back(std::make_pair(iPartition, iPartHit)); break;
case ca::EDetectorID::kTrd: output.trdHitIndices[iTrk].push_back(std::make_pair(iPartition, iPartHit)); break;
......
......@@ -38,7 +38,7 @@ namespace cbm::algo::ca
public:
/// \brief Mutable access operator, indexed by enum entry
T& operator[](const E& entry)
T& operator[](const E entry)
{
return std::array<T, static_cast<std::size_t>(E::END)>::operator[](static_cast<U>(entry));
}
......
......@@ -187,22 +187,22 @@ void Qa::Init()
continue;
}
{
auto sName = format("track_{}_theta", vsPointName[i]);
auto sName = format("{}_track_{}_theta", GetTaskName(), vsPointName[i]);
auto sTitl = format("#theta at {} hit; #theta", vsPointName[i]);
fvphTrkTheta[i] = MakeObj<H1D>(sName, sTitl, 62, 0., 90.);
}
{
auto sName = format("track_{}_phi", vsPointName[i]);
auto sName = format("{}_track_{}_phi", GetTaskName(), vsPointName[i]);
auto sTitl = format("#phi at {} hit; #phi", vsPointName[i]);
fvphTrkPhi[i] = MakeObj<H1D>(sName, sTitl, 62, -180., 180.);
}
{
auto sName = format("track_{}_thata_phi", vsPointName[i]);
auto sName = format("{}_track_{}_thata_phi", GetTaskName(), vsPointName[i]);
auto sTitl = format("#theta vs #phi at {} hit; #phi; #theta", vsPointName[i]);
fvphTrkPhiTheta[i] = MakeObj<H2D>(sName, sTitl, 62, -180., 180., 62, 0., 90.);
}
{
auto sName = format("track_{}_chi2_ndf", vsPointName[i]);
auto sName = format("{}_track_{}_chi2_ndf", GetTaskName(), vsPointName[i]);
auto sTitl = format("#chi^{{2}}/NDF at {} hit; #chi^{{2}}/NDF", vsPointName[i]);
fvphTrkChi2Ndf[i] = MakeObj<H1D>(sName, sTitl, 100, 0., 20.);
}
......@@ -212,7 +212,7 @@ void Qa::Init()
double xMin = -0.5;
double xMax = double(knStaMax) - 0.5;
{
auto sName = "track_fst_lst_sta";
auto sName = format("{}_track_fst_lst_sta", GetTaskName());
auto sTitl = "First vs. last station index;ID^{last}_{station};ID^{first}_{station}";
fphTrkFstLstSta = MakeObj<H2D>(sName, sTitl, nBins, xMin, xMax, nBins, xMin, xMax);
}
......@@ -227,7 +227,7 @@ void Qa::Init()
auto setNm = EHitSet::Input == hitSet ? "input" : "used";
auto setTl = EHitSet::Input == hitSet ? "Input" : "Used";
{ // XY
auto name = format("ca_hit_{}_occupancy_xy", setNm);
auto name = format("{}_ca_hit_{}_occupancy_xy", GetTaskName(), setNm);
auto titl = format("{} hit occupancy in different stations in XY plane", setNm);
auto canv = CanvasConfig(name, titl);
for (int iSt = 0; iSt < nSt; ++iSt) {
......@@ -238,7 +238,7 @@ void Qa::Init()
AddCanvasConfig(canv);
}
{ // ZX and ZY
auto name = format("ca_hit_{}_occupancy_zx_zy", setNm);
auto name = format("{}_ca_hit_{}_occupancy_zx_zy", GetTaskName(), setNm);
auto titl = format("{} hit occupancy in different stations in ZX and ZY planes", setTl);
auto canv = CanvasConfig(name, titl);
{ // ZX
......@@ -259,7 +259,7 @@ void Qa::Init()
}
}
if (kDebug) {
auto name = format("ca_hit_usage_xy");
auto name = format("{}_ca_hit_usage_xy", GetTaskName());
auto titl = format("Hit usage in different stations in XY plane");
auto canv = CanvasConfig(name, titl);
for (int iSt = 0; iSt < nSt; ++iSt) {
......@@ -273,7 +273,7 @@ void Qa::Init()
// Tracks canvas
{
auto canv = CanvasConfig("ca_tracks", "Tracking output QA");
auto canv = CanvasConfig(format("{}_ca_tracks", GetTaskName()), "Tracking output QA");
{
auto pad = PadConfig(true, true, false, false, true);
pad.RegisterHistogram(fvphTrkPhiTheta[0], "colz");
......
......@@ -45,11 +45,14 @@ namespace cbm::algo::bmon
/// \param iThread Index of thread
Output_t operator()(gsl::span<CbmBmonDigi> digisIn, uint32_t iThread = 0);
private: // members
/// \brief Returns an index of the diamond by the address
/// \param address A hardware address of the digi
size_t GetDiamondIndex(uint32_t address) const { return ((fSelectionBitmask & address) >> fSelectionBitsOffset); }
/// \brief Gets diamond addresses vector
const PODVector<uint32_t>& GetDiamondAddresses() const { return fDiamondAddress; }
private: // members
uint32_t fNofThreads; ///< Number of threads
uint32_t fSelectionBitsOffset; ///< Number of bits to ther right from the first bit in the selection mask
uint32_t fSelectionBitmask; ///< Selection bitmask
......
......@@ -12,6 +12,9 @@
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <fmt/format.h>
namespace cbm::algo::tof
{
......@@ -49,6 +52,8 @@ namespace cbm::algo::tof
//Iterator-based version. Faster than index-based version.
Clusterizer::resultType Clusterizer::buildClusters(std::vector<inputType>& input)
{
size_t nInputDigis{
std::accumulate(input.begin(), input.end(), 0, [](size_t s, const auto& v) { return s + v.size(); })};
// Hit variables
Hit cluster;
......@@ -72,6 +77,10 @@ namespace cbm::algo::tof
lastChanPos.push_back(input[chan].begin());
}
size_t nInputDigisUsed{0};
if (nInputDigis > 0) {
//std::cout << "------------- call: buildClusters: number of digis: " << nInputDigis << '\n';
}
for (int32_t chan = 0; (size_t) chan < numChan; chan++) {
// Set partition vectors
......@@ -83,11 +92,18 @@ namespace cbm::algo::tof
chanSizes.back() = 0;
continue;
}
nInputDigisUsed += input[chan].size();
inputType& storDigi = input[chan];
auto digiIt = storDigi.begin();
if (std::distance(storDigi.begin(), storDigi.end())) {
//std::cout << "DISTANCE: " << std::distance(storDigi.begin(), storDigi.end()) << '\n';
for (const auto& digi : storDigi) {
std::string sAddress = fmt::format("{:#08x}", digi.first->GetAddress());
//std::cout << " " << digi.first->GetTime() << "ns, address: " << sAddress << '\n';
}
}
while (1 < std::distance(digiIt, storDigi.end())) {
while (digiIt->first->GetSide() == std::next(digiIt)->first->GetSide()) { // Not one Digi of each end!
digiIt++;
if (2 > std::distance(digiIt, storDigi.end())) {
......@@ -181,6 +197,10 @@ namespace cbm::algo::tof
storDigi.clear();
} // for( int32_t chan = 0; chan < iNbCh; chan++ )
//if (nInputDigis> 0) {
// std::cout << ">>>>>> " << nInputDigisUsed << "/" << nInputDigis << '\n';
//}
// Now check if another hit/cluster is started
// and save it if it's the case.
if (0 < cluster.numChan()) {
......
......@@ -28,7 +28,6 @@ namespace cbm::algo::tof
for (int32_t Sm = 0; Sm < NbSm; Sm++) {
for (int32_t Rpc = 0; Rpc < NbRpc; Rpc++) {
auto par = std::make_unique<cbm::algo::tof::ClusterizerRpcPar>();
HitfindSetup::Rpc rpcPar = setup.rpcs[SmType][Sm * NbRpc + Rpc];
......
/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Sergei Zharko [committer] */
/// \file KfpfV0FinderConfig.h
/// \date 29.01.2025
/// \brief Configuration structure for V0 selector in mCBM
/// \author Sergei Zharko <s.zharko@gsi.de>
#pragma once
#include "yaml/Yaml.h"
#include <vector>
namespace cbm::algo::kfpf
{
/// \struct CutsKfpf
/// \brief Cuts for the KFParticleFinder
struct CutsKfpf {
float minDecayLength; ///< Minimal decay length of particles [cm]
float minDecayLDL; ///< Minimal value of decay length to decay length error ratio
float maxChi2NdfPrim; ///< Maximal chi2/NDF for primary particles (coming from the PV)
float maxChi2NdfGeo; ///< Maximal chi2/NDF for V0 candidates
CBM_YAML_PROPERTIES(
yaml::Property(&CutsKfpf::minDecayLength, "min_decay_length", "Minimal decay length of particles [cm]"),
yaml::Property(&CutsKfpf::minDecayLDL, "min_decay_ldl", "Minimal value of decay length to decay length error ratio"),
yaml::Property(&CutsKfpf::maxChi2NdfPrim, "max_chi2_ndf_prim", "Maximal chi2/NDF for primary particles"),
yaml::Property(&CutsKfpf::maxChi2NdfGeo, "max_chi2_ndf_geo", "Maximal chi2/NDF for V0 candidates"));
};
/// \struct ParticlePid
/// \brief PID and pre-selection cuts for a given particle
struct ParticlePid {
int pdg; ///< PDG code for particle
double minDca; ///< Minimal DCA to PV [cm]
double minVelocity; ///< Minimal velocity [cm/ns]
double maxVelocity; ///< Maximal velocity [cm/ns]
CBM_YAML_PROPERTIES(
yaml::Property(&ParticlePid::pdg, "pdg", "PDG code of the particle"),
yaml::Property(&ParticlePid::minDca, "min_dca", "Minimal DCA to PV [cm]"),
yaml::Property(&ParticlePid::minVelocity, "min_velocity", "Minimal velocity [cm/ns]"),
yaml::Property(&ParticlePid::maxVelocity, "max_velocity", "Maximal velocity [cm/ns]"));
};
/// \struct Cuts;
struct Cuts {
CutsKfpf kfpf; ///< KFParticleFinder specific cuts
std::vector<ParticlePid> particles; ///< Daughter PID cuts and other properties
CBM_YAML_PROPERTIES(
yaml::Property(&Cuts::kfpf, "kfpf", "Specific cuts for the KFParticleFinder"),
yaml::Property(&Cuts::particles, "particles", "Particle identification cuts and properties"));
};
/// \struct LambdaFinderConfig
/// \brief Configuration for the V0 finder
struct V0FinderConfig {
Cuts cuts; ///< Different selection cuts
double tZeroOffset; ///< Offset for T0 [ns]
double qpAssignedUncertainty; ///< Assigned relative uncertainty for q/p estimation
int primaryAssignedPdg; ///< Assigned PDG hypothesis for primary particles
int reconstructPdg; ///< PDG of the particle, the decay of which is to be reconstructed
CBM_YAML_PROPERTIES(
yaml::Property(&V0FinderConfig::cuts, "cuts", "Different selection cuts"),
yaml::Property(&V0FinderConfig::tZeroOffset, "t0_offset", "The t0 offset [ns]"),
yaml::Property(&V0FinderConfig::qpAssignedUncertainty, "qa_uncertainty", "Assigned relative uncertainty for q/p"),
yaml::Property(&V0FinderConfig::primaryAssignedPdg, "primary_pdg", "Assigned PDG code for primary tracks"),
yaml::Property(&V0FinderConfig::reconstructPdg, "reconstruct_pdg", "PDG code of the particle to be reconstructed"));
};
} // namespace cbm::algo::kfpf
......@@ -19,11 +19,12 @@ namespace cbm::algo::evselect
/// \brief Counter keys for the event selector monitor
enum class ECounter
{
EventsTotal, ///< Total number of events processed
EventsNeStsHits, ///< Events with not enough STS hits
EventsNeTofHits, ///< Events with enough STS hits, but not enough TOF hits
EventsNeTracks, ///< Events with enough hits, but not enough tracks
EventsSelected, ///< Number of selected events
EventsTotal, ///< Total number of events processed
EventsNeStsHits, ///< Events with not enough STS hits
EventsNeTofHits, ///< Events with enough STS hits, but not enough TOF hits
EventsNeBmonHits, ///< Events with not enough BMon hits
EventsNeTracks, ///< Events with enough hits, but not enough tracks
EventsSelected, ///< Number of selected events
END
};
......@@ -32,6 +33,7 @@ namespace cbm::algo::evselect
/* clang-format off */
enum class ETimer {
EventReconstruction,
BmonHitFinder,
StsHitFinder,
TofHitFinder,
TrdHitFinder,
......@@ -53,10 +55,12 @@ namespace cbm::algo::evselect
SetCounterName(ECounter::EventsTotal, "total events");
SetCounterName(ECounter::EventsNeStsHits, "events discarded by N STS hits");
SetCounterName(ECounter::EventsNeTofHits, "events discarded by N TOF hits");
SetCounterName(ECounter::EventsNeBmonHits, "events discarded by N BMon hits");
SetCounterName(ECounter::EventsNeTracks, "events discarded by N tracks");
SetCounterName(ECounter::EventsSelected, "selected events");
SetTimerName(ETimer::EventReconstruction, "event reconstruction");
SetTimerName(ETimer::BmonHitFinder, "hit finding in Bmon");
SetTimerName(ETimer::StsHitFinder, "hit finding in STS");
SetTimerName(ETimer::TofHitFinder, "hit finding in TOF");
SetTimerName(ETimer::TrdHitFinder, "hit finding in TRD");
......
......@@ -46,7 +46,7 @@ ParFiles::ParFiles(uint32_t runId)
ca.mainConfig = "TrackingChainConfig_mcbm2022.yaml";
kfp.V0FinderConfig = "mcbm_kfp_lambda.yaml";
kfp.V0FinderConfig = "kfp_lambda_v22a.yaml";
break;
case Setup::mCBM2024_03:
......@@ -71,7 +71,7 @@ ParFiles::ParFiles(uint32_t runId)
ca.mainConfig = "TrackingChainConfig_mcbm2024.yaml";
kfp.V0FinderConfig = "mcbm_kfp_lambda.yaml";
kfp.V0FinderConfig = "kfp_lambda_v24a.yaml";
break;
case Setup::mCBM2024_05:
......@@ -96,7 +96,7 @@ ParFiles::ParFiles(uint32_t runId)
ca.mainConfig = "mcbm2024_05/TrackingChainConfig.yaml";
kfp.V0FinderConfig = "mcbm_kfp_lambda.yaml";
kfp.V0FinderConfig = "kfp_lambda_v24b.yaml";
break;
case Setup::mCBM2025_02:
......
......@@ -266,7 +266,7 @@ void Reco::Init(const Options& opts)
// Tracking in event reconstruction
if (fQaManager != nullptr && Opts().Has(QaStep::Tracking)) {
fTracking = std::make_unique<TrackingChain>(ECbmRecoMode::EventByEvent, fQaManager, "CaEvent");
fTrackingEvent = std::make_unique<TrackingChain>(ECbmRecoMode::EventByEvent, fQaManager, "CaEvent");
}
else {
fTrackingEvent = std::make_unique<TrackingChain>(ECbmRecoMode::EventByEvent);
......@@ -277,6 +277,7 @@ void Reco::Init(const Options& opts)
fV0Finder = std::make_unique<V0FinderChain>();
fV0Finder->SetContext(&fContext);
fV0Finder->SetBmonDefinedAddresses(fBmonHitFinder->GetDiamondAddresses());
fV0Finder->Init();
}
......@@ -524,8 +525,10 @@ bool Reco::ReconstructEvent(const DigiEvent& digiEvent)
RecoResults recoEvent;
//* BMON hit reconstruction
{
auto [calDigis, calMonitor] = (*fBmonCalibrator)(recoEvent.fBmon);
fEvSelectingMonitor.StartTimer(evselect::ETimer::BmonHitFinder);
auto [calDigis, calMonitor] = (*fBmonCalibrator)(digiEvent.fBmon);
auto [hits, hitMonitor, digiIndices] = (*fBmonHitFinder)(calDigis);
fEvSelectingMonitor.StopTimer(evselect::ETimer::BmonHitFinder);
if (fBmonHitFinderQa != nullptr) {
fBmonHitFinderQa->RegisterDigis(&calDigis);
fBmonHitFinderQa->RegisterHits(&hits);
......
......@@ -45,8 +45,8 @@ namespace cbm::algo
PartitionedVector<bmon::Hit> bmonHits;
ca::Vector<ca::Track> tracks;
ca::Vector<std::vector<std::pair<uint32_t, uint32_t>>> trackStsHitIndices;
ca::Vector<std::vector<std::pair<uint32_t, uint32_t>>> trackTofHitIndices;
ca::Vector<std::vector<std::pair<uint32_t, uint32_t>>> trackTrdHitIndices;
ca::Vector<std::vector<std::pair<uint32_t, uint32_t>>> trackStsHitIndices; // [trk][hit][(iPart, iHit)]
ca::Vector<std::vector<std::pair<uint32_t, uint32_t>>> trackTofHitIndices; // [trk][hit][(iPart, iHit)]
ca::Vector<std::vector<std::pair<uint32_t, uint32_t>>> trackTrdHitIndices; // [trk][hit][(iPart, iHit)]
};
} // namespace cbm::algo
......@@ -9,19 +9,87 @@
#include "kfp/KfpV0Finder.h"
#include "global/RecoResults.h"
#include <algorithm>
#include <limits>
#include <sstream>
using cbm::algo::RecoResults;
using cbm::algo::kfp::V0Finder;
// ---------------------------------------------------------------------------------------------------------------------
//
std::vector<double> V0Finder::CollectDca(const RecoResults& recoEvent) const
{
std::vector<double> dca(recoEvent.trackStsHitIndices.size(), std::numeric_limits<double>::signaling_NaN());
const auto& stsHitIndices = recoEvent.trackStsHitIndices;
for (size_t iTrk = 0; iTrk < stsHitIndices.size(); ++iTrk) {
const auto& stsHitIndicesInTrack = stsHitIndices[iTrk];
if (stsHitIndicesInTrack.size() < 2) { // less then two sts hits
continue;
}
auto [iPtFst, iHitFst] = stsHitIndicesInTrack[0];
auto [iPtSnd, iHitSnd] = stsHitIndicesInTrack[1];
dca[iTrk] = EstimateDca(recoEvent.stsHits[iPtFst][iHitFst], recoEvent.stsHits[iPtSnd][iHitSnd]);
}
return dca;
}
// ---------------------------------------------------------------------------------------------------------------------
//
std::vector<double> V0Finder::CollectT0(gsl::span<const bmon::Hit> bmonHits) const
{
std::vector<double> t0;
t0.reserve(bmonHits.size());
std::transform(bmonHits.begin(), bmonHits.end(), std::back_inserter(t0), [&](const auto& h) { return h.GetTime(); });
return t0;
}
// ---------------------------------------------------------------------------------------------------------------------
//
double V0Finder::EstimateDca(const sts::Hit& fst, const sts::Hit& snd) const
{
double factor{(fst.Z() - fOrigin[2]) / (snd.Z() - fst.Z())};
double dcaX{fst.X() - fOrigin[0] - factor * (snd.X() - fst.X())};
double dcaY{fst.Y() - fOrigin[1] - factor * (snd.Y() - fst.Y())};
return std::sqrt(dcaX * dcaX + dcaY * dcaY);
}
// ---------------------------------------------------------------------------------------------------------------------
//
void V0Finder::Init() {}
// ---------------------------------------------------------------------------------------------------------------------
//
CbmEventTriggers V0Finder::Process(const RecoResults&)
CbmEventTriggers V0Finder::Process(const RecoResults& recoEvent)
{
CbmEventTriggers res;
fEventMonitor.Reset();
fEventMonitor.StartTimer(ETimer::Event);
fEventMonitor.IncrementCounter(ECounter::EventsTotal);
// ----- Define T0
// So far we cannot preselect a hit from multiple ones, we will be using all of them iteratively to find lambdas
auto vT0 = CollectT0(recoEvent.bmonHits[fBmonPartitionIndex]);
if (vT0.empty()) {
fEventMonitor.IncrementCounter(ECounter::EventsWoTzero);
return res;
}
//L_(info) << "------- Event: ";
// ----- Estimate DCA of tracks
// If a track has less then two STS hits, and undefined DCA value is stored
std::vector<double> vDca = CollectDca(recoEvent);
// ***** DEBUG: BEGIN
//for (auto dca: vDca) {
// L_(info) << "dca=" << dca;
//}
// ***** DEBUG: END
fEventMonitor.StopTimer(ETimer::Event);
return res;
}
......@@ -14,6 +14,7 @@
#include "global/RecoResults.h"
#include "kfp/KfpV0FinderMonitor.h"
#include <limits>
#include <memory>
......@@ -60,7 +61,10 @@ namespace cbm::algo::kfp
/// \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
/// \brief Sets an address of a reference BMON diamond
/// \param iPartition An index of the BMON hit partition: used to selected the hits from the particular config
void SetBmonPartitionIndex(int iPartition) { fBmonPartitionIndex = iPartition; }
/// \param dca DCA [cm]
void SetMinPionDca(double dca) { fMinPionDca = dca; }
......@@ -68,6 +72,14 @@ namespace cbm::algo::kfp
/// \param dca DCA [cm]
void SetMinProtonDca(double dca) { fMinProtonDca = dca; }
/// \brief Sets origin
/// \param x X-coordinate of the origin [cm]
/// \param y Y-coordinate of the origin [cm]
/// \param z Z-coordinate of the origin [cm]
// FIXME: for now origin is defined as the target center, later it can be changed
void SetOrigin(double x, double y, double z) { fOrigin = {x, y, z}; }
/// \brief Sets minimal pion DCA to primary vertex
/// \brief Sets pion velocity range
/// \param vMin Minimal velocity [cm/ns]
/// \param vMax Maximal velocity [cm/ns]
......@@ -116,13 +128,29 @@ namespace cbm::algo::kfp
void SetLdLCut2D(float cut) { GetKFParticleFinder()->SetLdLCut2D(cut); }
private:
/// \brief Collects T0 values among the BMON hits
/// \param bmonHits A span of BMON hits
/// \return A vector of T0-s
///
/// If multiple T0-s are found, the routine will run multiple times, until V0-candidates are found
std::vector<double> CollectT0(gsl::span<const bmon::Hit> bmonHits) const;
/// \brief Collects a vector of DCA
/// \param recoEvent Instance of a reconstructed event
/// \return A vector of DCAs to origin
std::vector<double> CollectDca(const RecoResults& recoEvent) const;
/// \brief Estimate DCA of a track to origin
/// \param fst first STS hit
/// \param snd second STS hit
/// \return dca [cm]
double EstimateDca(const sts::Hit& fst, const sts::Hit& snd) const;
//* 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>()};
V0FinderMonitorData_t fEventMonitor; ///< Monitor data instance (per event)
......@@ -136,5 +164,15 @@ namespace cbm::algo::kfp
double fMaxBetaProton{1.}; ///< Maximal proton velocity (beta) [c]
double fMinBetaPion{0.}; ///< Minimal proton velocity (beta) [c]
double fMaxBetaPion{1.}; ///< Maximal proton velocity (beta) [c]
//* Run-time variables, provided by framework
int fBmonPartitionIndex{-1}; ///< Index of selected partition in BMON hit vector
std::array<double, 3> fOrigin{0., 0., 0.}; ///< Coordinates of origin [cm]
//* Auxilary variables
/// \brief An instance of the topology reconstructor
std::unique_ptr<KFParticleTopoReconstructor> fpTopoReconstructor{std::make_unique<KFParticleTopoReconstructor>()};
};
} // namespace cbm::algo::kfp
......@@ -70,10 +70,29 @@ try {
const auto& pion{particles[iPion]};
const auto& proton{particles[iProton]};
// ----- Define a BMON diamond
if (fBmonDefinedAddresses.empty()) {
throw std::runtime_error("kfp::V0FinderChain: BMON available addresses were not set");
}
int iBmonPartitionSelect = -1;
for (int iPart = 0; iPart < static_cast<int>(fBmonDefinedAddresses.size()); ++iPart) {
if (config.bmonAddress == fBmonDefinedAddresses[iPart]) {
iBmonPartitionSelect = iPart;
break;
}
}
if (iBmonPartitionSelect < 0) {
std::stringstream msg;
msg << "kfp::V0FinderChain: a reference BMON address ( " << std::hex << config.bmonAddress << std::dec
<< " ) differs from ones, provided by hitfinder. Please check your configuration";
throw std::runtime_error(msg.str());
}
// ----- 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
fFinder.SetBmonPartitionIndex(iBmonPartitionSelect);
fFinder.SetMinPionDca(pion.minDca);
fFinder.SetMinProtonDca(proton.minDca);
fFinder.SetPionVelocityRange(pion.minVelocity, pion.maxVelocity);
......
......@@ -10,6 +10,7 @@
#pragma once
#include "CbmEventTriggers.h"
#include "PODVector.h"
#include "base/SubChain.h"
#include "global/RecoResults.h"
#include "kfp/KfpV0Finder.h"
......@@ -49,16 +50,19 @@ namespace cbm::algo
/// \brief Finalizes the instance (called in the end of the run)
void Finalize();
/// \brief Sets BMON diamond addresses array
/// \note The addresses must be taken from bmon::Hitfind::GetDiamondAddresses()
void SetBmonDefinedAddresses(const PODVector<uint32_t>& addresses) { fBmonDefinedAddresses = addresses; }
/// \brief Initializes the instance (called in the beginning of the run)
void Init();
/// \brief Processes an event, returns a collection of fired triggers
EventOutput ProcessEvent(const RecoResults& recoEvent);
private:
kfp::V0Finder fFinder; ///< Instance of the V0-finding algorithm
kfp::V0FinderMonitor fMonitorRun; ///< Monitor per run
uint32_t fBmonAddress; ///< Address of selected BMON
kfp::V0Finder fFinder; ///< Instance of the V0-finding algorithm
kfp::V0FinderMonitor fMonitorRun; ///< Monitor per run
PODVector<uint32_t> fBmonDefinedAddresses; ///< Available addresses of BMON
};
} // namespace cbm::algo
......@@ -69,6 +69,7 @@ namespace cbm::algo::kfp
/// \brief Configuration for the V0 finder
struct V0FinderConfig {
Cuts cuts; ///< Different selection cuts
uint32_t bmonAddress; ///< Address of BMON diamond (if multiple alternative are present, only one must be selected)
double tZeroOffset; ///< Offset for T0 [ns]
double qpAssignedUncertainty; ///< Assigned relative uncertainty for q/p estimation
int primaryAssignedPdg; ///< Assigned PDG hypothesis for primary particles
......@@ -76,6 +77,7 @@ namespace cbm::algo::kfp
CBM_YAML_PROPERTIES(
yaml::Property(&V0FinderConfig::cuts, "cuts", "Different selection cuts"),
yaml::Property(&V0FinderConfig::bmonAddress, "bmon_address", "Address of reference BMON diamond"),
yaml::Property(&V0FinderConfig::tZeroOffset, "t0_offset", "The t0 offset [ns]"),
yaml::Property(&V0FinderConfig::qpAssignedUncertainty, "qa_uncertainty", "Assigned relative uncertainty for q/p"),
yaml::Property(&V0FinderConfig::primaryAssignedPdg, "primary_pdg", "Assigned PDG code for primary tracks"),
......
......@@ -3,35 +3,19 @@
# 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
### 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)
### CbmKFParticleOfflineInterface
add_library(CbmKFParticleOfflineInterface INTERFACE)
target_include_directories(CbmKFParticleOfflineInterface INTERFACE)
target_compile_definitions(CbmKFParticleOfflineInterface
......@@ -39,4 +23,31 @@ if(NOT CBM_ONLINE_STANDALONE)
target_link_libraries(CbmKFParticleOfflineInterface
INTERFACE ROOT::Core KFParticle)
install(TARGETS CbmKFParticleOfflineInterface DESTINATION lib)
else()
# Creating a replacement of the CbmKFParticleOnlineInterface library for a standalone mode
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
)
add_library(CbmKFParticleOnlineInterface SHARED ${SRCS})
target_include_directories(CbmKFParticleOnlineInterface PUBLIC ${KFP_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_definitions(CbmKFParticleOnlineInterface PUBLIC NonhomogeneousField CBM CBM_ONLINE)
target_link_libraries(CbmKFParticleOnlineInterface
PUBLIC Vc::Vc
ROOT::Core)
install(TARGETS CbmKFParticleOnlineInterface DESTINATION lib)
endif()
/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Sergei Zharko [committer] */
/// \file RootTypesDef.h
/// \date 11.02.2025
/// \brief A compatibility header for the KFParticle code
/// \author Sergei Zharko <s.zharko@gsi.de>
#pragma once
#if __has_include(<RtypesCore.h>)
#include <RtypesCore.h>
#else
using Bool_t = bool;
using Int_t = int;
using Float_t = float;
#endif
......@@ -57,6 +57,7 @@ try {
<< " with inconsistent flags (see HistogramMetadata::CheckFlags for detailes)";
throw std::runtime_error(msg.str());
}
L_(info) << " - task: " << task.fsName << ", histogram: " << h.GetName();
vHistCfgs.emplace_back(h.GetName() + "!" + h.GetMetadataString(), task.fsName);
};
fsTaskNames += fmt::format("{} ", task.fsName);
......
......@@ -73,7 +73,7 @@ class CbmEventTriggers {
std::string ToString() const;
private:
Trigger_t fTriggers;
Trigger_t fTriggers{0};
#if !defined(NO_ROOT) && !XPU_IS_HIP_CUDA
ClassDefNV(CbmEventTriggers, 1);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment