CbmRoot
Loading...
Searching...
No Matches
TrackingChain.cxx
Go to the documentation of this file.
1/* Copyright (C) 2023-2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Sergei Zharko [committer] */
4
9
11
12#include "CaDefs.h"
13#include "CaHit.h"
14#include "CaParameters.h"
15#include "CbmYaml.h"
18
19#include <boost/archive/binary_oarchive.hpp>
20
21#include <fstream>
22#include <set>
23#include <unordered_map>
24
25#include <fmt/format.h>
26#include <xpu/host.h>
27
35using cbm::algo::ca::constants::clrs::CL; // clear text
36using cbm::algo::ca::constants::clrs::GNb; // grin bald text
37
38// ---------------------------------------------------------------------------------------------------------------------
39//
40TrackingChain::TrackingChain(ECbmRecoMode recoMode, const std::unique_ptr<cbm::algo::qa::Manager>& qaManager,
41 std::string_view name)
42 : fQa(Qa(qaManager, name))
43 , fRecoMode(recoMode)
44{
45}
46
47// ---------------------------------------------------------------------------------------------------------------------
48//
49// FIXME: ParFiles -> std::string (full path to the Tracking chain config)
50void TrackingChain::Init(const std::string& caParPath)
51{
52 if (fpSetup.get() == nullptr) {
53 throw std::runtime_error("Tracking Chain: RecoSetup object was not registered");
54 }
55
56 // ------ Read parameters from binary
57 L_(info) << "Tracking Chain: CA parameters from " << GNb << caParPath << CL << '\n';
58 auto parameters = ca::ParametersIO::Load<fvec>(caParPath);
59 L_(info) << "Tracking Chain: parameters object: \n" << parameters.ToString(1) << '\n';
60
61 // ------ Used detector subsystem flags
62 fbDetUsed.fill(false);
63 // TODO: test disabling of detector subsystems
64 fbDetUsed[EDetectorID::kSts] = parameters.IsActive(EDetectorID::kSts);
65 fbDetUsed[EDetectorID::kTof] = parameters.IsActive(EDetectorID::kTof);
66 fbDetUsed[EDetectorID::kTrd] = parameters.IsActive(EDetectorID::kTrd);
67
68 // ------ Initialize CA framework
69 fCaMonitor.Reset();
71 fCaFramework.SetNofThreads(Opts().NumOMPThreads() == std::nullopt ? openmp::GetMaxThreads()
72 : *(Opts().NumOMPThreads()));
73 }
74 else {
75 fCaFramework.SetNofThreads(1);
76 }
77 fCaFramework.ReceiveParameters(std::move(parameters));
79
80 // ------ Initialize QA modules
81 if (fQa.IsActive()) {
82 fQa.RegisterParameters(&fCaFramework.GetParameters());
83 fQa.Init();
84 }
85 L_(info) << "TRACKING QA: " << fQa.IsActive();
86}
87
88// ---------------------------------------------------------------------------------------------------------------------
89//
91{
92 xpu::scoped_timer t_("CA"); // TODO: pass timings to monitoring for throughput?
93 fCaMonitorData.Reset();
95
96 // ----- Init input data ---------------------------------------------------------------------------------------------
98 this->PrepareInput(recoResults);
100
101 // ----- Run reconstruction ------------------------------------------------------------------------------------------
102 fCaFramework.SetMonitorData(fCaMonitorData);
103 fCaFramework.FindTracks();
104 fCaMonitorData = fCaFramework.GetMonitorData();
105
106 // ----- Init output data --------------------------------------------------------------------------------------------
107 return PrepareOutput();
108}
109
110// ---------------------------------------------------------------------------------------------------------------------
111//
113{
114 L_(info) << fCaMonitor.ToString();
115 if constexpr (kStoreMonitor) {
116 auto fileName = "./monitor.out";
117 std::ofstream ofs(fileName);
118 boost::archive::binary_oarchive oa(ofs);
119 oa << fCaMonitor;
120 }
121}
122
123// ---------------------------------------------------------------------------------------------------------------------
124//
126{
127 fNofHitKeys = 0;
128 int nHitsTot = recoResults.stsHits.NElements() + recoResults.tofHits.NElements() + recoResults.trdHits.NElements();
129 L_(debug) << "Tracking chain: input has " << nHitsTot << " hits";
130 fCaDataManager.ResetInputData(nHitsTot);
131 faHitExternalIndices.clear();
132 faHitExternalIndices.reserve(nHitsTot);
137 }
142 }
147 }
148 faHitExternalIndices.shrink_to_fit();
149 fCaDataManager.SetNhitKeys(fNofHitKeys);
150 L_(debug) << "Tracking chain: " << fCaDataManager.GetNofHits() << " hits will be passed to the ca::Framework";
152 fCaFramework.ReceiveInputData(fCaDataManager.TakeInputData());
154}
155
156// ---------------------------------------------------------------------------------------------------------------------
157//
159{
160 Output_t output;
161 output.tracks = std::move(fCaFramework.fRecoTracks);
162 int nTracks = output.tracks.size();
163
164 output.stsHitIndices.reset(nTracks);
165 output.tofHitIndices.reset(nTracks);
166 output.trdHitIndices.reset(nTracks);
167
168 int trackFirstHit = 0;
169 for (int iTrk = 0; iTrk < nTracks; ++iTrk) {
170 output.stsHitIndices[iTrk].clear();
171 output.tofHitIndices[iTrk].clear();
172 output.trdHitIndices[iTrk].clear();
173 int nHits = output.tracks[iTrk].fNofHits;
174 for (int iHit = 0; iHit < nHits; ++iHit) {
175 int iHitInternal = fCaFramework.GetInputData().GetHit(fCaFramework.fRecoHits[trackFirstHit + iHit]).Id();
176 const auto [detID, iPartition, iPartHit] = faHitExternalIndices[iHitInternal];
177 switch (detID) {
178 // FIXME: store a global hit index instead of (partition, hit)
179 case ca::EDetectorID::kSts: output.stsHitIndices[iTrk].push_back(std::make_pair(iPartition, iPartHit)); break;
180 case ca::EDetectorID::kTof: output.tofHitIndices[iTrk].push_back(std::make_pair(iPartition, iPartHit)); break;
181 case ca::EDetectorID::kTrd: output.trdHitIndices[iTrk].push_back(std::make_pair(iPartition, iPartHit)); break;
182 default: break;
183 }
184 }
185 fCaMonitorData.IncrementCounter(ca::ECounter::RecoStsHit, output.stsHitIndices[iTrk].size());
186 fCaMonitorData.IncrementCounter(ca::ECounter::RecoTofHit, output.tofHitIndices[iTrk].size());
187 fCaMonitorData.IncrementCounter(ca::ECounter::RecoTrdHit, output.trdHitIndices[iTrk].size());
188
189 trackFirstHit += nHits;
190 }
191
193 L_(info) << "TrackingChain: Timeslice contains " << fCaMonitorData.GetCounterValue(ca::ECounter::RecoTrack)
194 << " tracks, with " << fCaMonitorData.GetCounterValue(ca::ECounter::RecoStsHit) << " sts hits, "
195 << fCaMonitorData.GetCounterValue(ca::ECounter::RecoTofHit) << " tof hits, "
196 << fCaMonitorData.GetCounterValue(ca::ECounter::RecoTrdHit) << " trd hits"
197 << "; the FindTracks routine ran " << fCaMonitorData.GetTimer(ca::ETimer::FindTracks).GetTotal() << " s";
198 }
199
200 // QA
201 if (fQa.IsActive()) {
202 fCaMonitorData.StartTimer(ca::ETimer::Qa);
203 fQa.RegisterInputData(&fCaFramework.GetInputData());
204 fQa.RegisterTracks(&output.tracks);
205 fQa.RegisterRecoHitIndices(&fCaFramework.fRecoHits);
206 fQa.Exec();
208 }
209
211
212 if constexpr (kDEBUG) { // Monitor data per TS
213 if (fCaFramework.GetNofThreads() == 1 && fCaFramework.GetNofThreads() == 10) {
214 int tsIndex = fCaMonitor.GetCounterValue(ca::ECounter::TrackingCall);
215 auto fileName = fmt::format("./ca_monitor_nth_{}_ts{}.dat", fCaFramework.GetNofThreads(), tsIndex);
216 std::ofstream ofs(fileName);
217 boost::archive::binary_oarchive oa(ofs);
218 ca::TrackingMonitor monitorPerTS;
219 monitorPerTS.AddMonitorData(fCaMonitorData);
220 oa << monitorPerTS;
221 }
222 }
223
224 fCaMonitor.AddMonitorData(fCaMonitorData);
226
227 return output;
228}
229
230// ---------------------------------------------------------------------------------------------------------------------
231//
232template<EDetectorID DetID>
234{
235 int nSt = fCaFramework.GetParameters().GetNstationsActive();
236
237 using Hit_t = ca::HitTypes_t::at<DetID>;
238 constexpr bool IsMvd = (DetID == EDetectorID::kMvd);
239 constexpr bool IsSts = (DetID == EDetectorID::kSts);
240 constexpr bool IsMuch = (DetID == EDetectorID::kMuch);
241 constexpr bool IsTrd = (DetID == EDetectorID::kTrd);
242 constexpr bool IsTof = (DetID == EDetectorID::kTof);
243 const auto* pSetupUnit = fpSetup->Get<ToCbmModuleId(DetID)>();
244
245 xpu::t_add_bytes(hits.NElements() * sizeof(Hit_t)); // Assumes call from Run, for existence of timer!
246
247 int64_t dataStreamDet = static_cast<int64_t>(DetID) << 60; // detector part of the data stream
248 int64_t dataStream = 0;
249 for (size_t iPartition = 0; iPartition < hits.NPartitions(); ++iPartition, ++dataStream) {
250 const auto& [vHits, extHitAddress] = hits.Partition(iPartition);
251 // ---- Define data stream and station index
252 //int64_t dataStream = dataStreamDet | extHitAddress;
253 int iStLocal = pSetupUnit->GetTrackingStationId(extHitAddress);
254 if (iStLocal < 0) {
255 continue; // Station is not used for tracking (e.g. TOF SMtype 5)
256 }
257
258 int iStActive = fCaFramework.GetParameters().GetStationIndexActive(iStLocal, DetID);
259
260 //size_t iOffset = hits.Offsets()[iPartition];
261 if (iStActive < 0) {
262 continue; // legit
263 }
264 if (iStActive >= nSt) {
265 L_(error) << "TrackingChain: found hit with wrong active station index above the upper limit: " << iStActive
266 << ", detector: " << ca::kDetName[DetID];
267 continue;
268 }
269 double lastTime = -1e9;
270 //double prevTime = -1;
271 ca::HitKeyIndex_t firstHitKey = fNofHitKeys;
272 for (size_t iPartHit = 0; iPartHit < vHits.size(); ++iPartHit) {
273 const auto& hit = vHits[iPartHit];
274
275 //if constexpr (IsTrd) {
276 // switch (extHitAddress) {
277 // case 0x5:
278 // if (!(fabs(hit.Z() - 116.77) < 10)) {
279 // L_(info) << "DBG! " << extHitAddress << ' ' << hit.Z();
280 // }
281 // break;
282 // case 0x15:
283 // if (!(fabs(hit.Z() - 163.8) < 10)) {
284 // L_(info) << "DBG! " << extHitAddress << ' ' << hit.Z();
285 // }
286 // break;
287 // case 0x25:
288 // if (!(fabs(hit.Z() - 190.8) < 10)) {
289 // L_(info) << "DBG! " << extHitAddress << ' ' << hit.Z();
290 // }
291 // break;
292 // }
293 //}
294
295
296 //int iHitExt = iOffset + iPartHit;
297 // ---- Fill ca::Hit
299 ca::Hit caHit;
300 if constexpr (IsSts) {
301 caHit.SetFrontKey(firstHitKey + hit.fFrontClusterId);
302 caHit.SetBackKey(firstHitKey + hit.fBackClusterId);
303 //L_(info) << ", hit=" << iHitExt << ", f=" << hit.fFrontClusterId << ", b=" << hit.fBackClusterId;
304 }
305 else {
306 caHit.SetFrontKey(firstHitKey + iPartHit);
307 caHit.SetBackKey(caHit.FrontKey());
308 }
309
310 if constexpr (IsTof) {
311 // Cut the BMon hits (if any)
312 if (hit.Z() < 0.1) {
313 // FIXME: Provide BMon addresses explicitly in all the parameter files
314 continue;
315 }
316 }
317
318 auto misalignmentTolerance = fCaFramework.GetParameters().GetConfig().GetMisalignmentTolerance(DetID);
319 caHit.SetX(hit.X());
320 caHit.SetY(hit.Y());
321 caHit.SetZ(hit.Z());
322 caHit.SetT(hit.Time());
323 caHit.SetDx2(hit.Dx() * hit.Dx() + misalignmentTolerance.GetXsq());
324 caHit.SetDy2(hit.Dy() * hit.Dy() + misalignmentTolerance.GetYsq());
325 if constexpr (IsSts) caHit.SetDxy(hit.fDxy);
326 caHit.SetDt2(hit.TimeError() * hit.TimeError() + misalignmentTolerance.GetTimeSq());
328 //out << iStLocal << " " << extHitAddress << " " << hit.Z() << '\n';
329 caHit.SetRangeX(3.5 * hit.Dx());
330 caHit.SetRangeY(3.5 * hit.Dy());
331 caHit.SetRangeT(3.5 * hit.TimeError());
332 if constexpr (IsTrd) {
333 if (iStLocal == 0) {
334 caHit.SetRangeX(1.7);
335 caHit.SetRangeY(3.5);
336 caHit.SetRangeT(200.);
337 }
338 else if (iStLocal == 1) {
339 caHit.SetRangeY(sqrt(3.) * hit.Dy());
340 }
341 else {
342 caHit.SetRangeX(sqrt(3.) * hit.Dx());
343 }
344 }
345 caHit.SetStation(iStActive);
346 caHit.SetId(fCaDataManager.GetNofHits());
347 if (caHit.Check()) {
349 if ((caHit.T() < lastTime - 1000.) && (dataStream < 100000)) {
350 dataStream++;
351 }
352 lastTime = caHit.T();
353 fCaDataManager.PushBackHit(caHit, dataStreamDet | dataStream);
354 }
355 else {
356 fCaDataManager.PushBackHit(caHit); // A single data stream in event-by-event mode
357 }
358 faHitExternalIndices.push_back(std::make_tuple(DetID, iPartition, iPartHit));
359 if (fNofHitKeys <= caHit.FrontKey()) {
360 fNofHitKeys = caHit.FrontKey() + 1;
361 }
362 if (fNofHitKeys <= caHit.BackKey()) {
363 fNofHitKeys = caHit.BackKey() + 1;
364 }
365 }
366 else {
367 if constexpr (IsMvd) {
369 }
370 if constexpr (IsSts) {
372 }
373 if constexpr (IsMuch) {
375 }
376 if constexpr (IsTrd) {
378 }
379 if constexpr (IsTof) {
381 }
382 }
384 //prevTime = caHit.T();
385 // ---- Update number of hit keys
386 } // iPartHit
387 } // iPartition
388}
#define L_(level)
Compile-time constants definition for the CA tracking algorithm.
A generic hit for the CA tracker (header)
ECbmRecoMode
Reconstruct the full time slice or event-by-event.
Definition CbmDefs.h:202
static vector< vector< QAHit > > hits
friend fvec sqrt(const fvec &a)
This file contains the definition of the ParFiles class.
constexpr char GNb[]
bold green
Definition CaDefs.h:162
constexpr char CL[]
clear
Definition CaDefs.h:139
A chain class to execute CA tracking algorithm in online reconstruction (header)
TrackingChain(ECbmRecoMode recoMode, const std::unique_ptr< cbm::algo::qa::Manager > &qaManager=nullptr, std::string_view name="")
Constructor from parameters.
const Options & Opts() const
Definition SubChain.h:20
A chain for tracking algorithm.
Output_t Run(Input_t recoResults)
Provides action for a given time-slice.
ca::Framework fCaFramework
CA framework instance.
std::shared_ptr< RecoSetup > fpSetup
setup interface
static constexpr bool kStoreMonitor
Store monitor (debug)
void ReadHits(PartitionedSpan< const ca::HitTypes_t::at< DetID > > hits)
Reads from different detector subsystems.
Output_t PrepareOutput()
Prepares output data.
ca::TrackingMonitorData fCaMonitorData
CA monitor data object.
ca::Qa fQa
CA QA builder.
void PrepareInput(Input_t recoResults)
Prepares input data.
ca::DataManager fCaDataManager
CA data manager.
ca::Vector< std::tuple< ca::EDetectorID, uint32_t, uint32_t > > faHitExternalIndices
External indices of used hits.
void Init(const std::string &caParPath)
Provides action in the initialization of the run.
ECbmRecoMode fRecoMode
Reconstruction mode.
static constexpr bool kDEBUG
Debug mode.
ca::HitKeyIndex_t fNofHitKeys
Current number of hit keys (aux)
ca::TrackingMonitor fCaMonitor
CA internal monitor (debug purposes)
void Finalize()
Provides action in the end of the run.
ca::DetIdArray_t< bool > fbDetUsed
Flags of detector subsystems used in tracking.
ca::Hit class describes a generic hit for the CA tracker
Definition CaHit.h:32
void SetX(fscal x)
Set the X coordinate.
Definition CaHit.h:54
HitKeyIndex_t BackKey() const
Get the back key index.
Definition CaHit.h:99
void SetRangeT(fscal rangeT)
Set the +/- range of uncertainty of time.
Definition CaHit.h:84
void SetDt2(fscal dt2)
Set the uncertainty of time.
Definition CaHit.h:75
void SetDy2(fscal dy2)
Set the uncertainty of Y coordinate.
Definition CaHit.h:69
void SetRangeY(fscal rangeY)
Set the +/- range of uncertainty of Y coordinate.
Definition CaHit.h:81
void SetStation(int station)
Set the station index.
Definition CaHit.h:90
void SetDx2(fscal dx2)
Set the uncertainty of X coordinate.
Definition CaHit.h:66
void SetRangeX(fscal rangeX)
Set the +/- range of uncertainty of X coordinate.
Definition CaHit.h:78
void SetZ(fscal z)
Set the Z coordinate.
Definition CaHit.h:60
void SetBackKey(HitKeyIndex_t key)
Set the back key index.
Definition CaHit.h:51
void SetFrontKey(HitKeyIndex_t key)
Set the front key index.
Definition CaHit.h:48
void SetId(HitIndex_t id)
Set the hit id.
Definition CaHit.h:87
bool Check() const
Checks, if the hit is defined.
Definition CaHit.h:199
HitKeyIndex_t FrontKey() const
Get the front key index.
Definition CaHit.h:96
fscal T() const
Get the time.
Definition CaHit.h:111
void SetT(fscal t)
Set the time.
Definition CaHit.h:63
void SetDxy(fscal dxy)
Set the X/Y covariance.
Definition CaHit.h:72
void SetY(fscal y)
Set the Y coordinate.
Definition CaHit.h:57
void AddMonitorData(const MonitorData< ECounterKey, ETimerKey > &data, bool parallel=false)
Adds the other monitor data to this.
Definition CaMonitor.h:70
A container for all external parameters of the CA tracking algorithm.
Class representing an output track in the CA tracking algorithm.
Definition CaTrack.h:28
A monitor specialization for cbm::algo::ca::Framework class.
void push_back(Tinput value)
Pushes back a value to the vector.
Definition CaVector.h:190
void reset(std::size_t count, Tinput... value)
Clears vector and resizes it to the selected size with selected values.
Definition CaVector.h:135
constexpr char GNb[]
bold green
Definition CaDefs.h:162
constexpr char CL[]
clear
Definition CaDefs.h:139
unsigned int HitKeyIndex_t
Index of the hit key (e.g. front / back cluster id for STS)
Definition CaHit.h:28
@ RecoTrack
number of reconstructed tracks
@ RecoStsHit
number of STS hits in tracks
@ UndefinedTofHit
number of undefined TOF hits
@ TrackingCall
number of the routine calls
@ UndefinedTrdHit
number of undefined TRD hits
@ RecoTrdHit
number of TRD hits in tracks
@ UndefinedMvdHit
number of undefined MVD hits
@ RecoTofHit
number of TOF hits in tracks
@ UndefinedMuchHit
number of undefined MuCh hits
@ UndefinedStsHit
number of undefined STS hits
DetIdTypeArr_t< MvdHit, StsHit, MuchHit, TrdHit, TofHit > HitTypes_t
constexpr DetIdArray_t< const char * > kDetName
Detector subsystem names.
EDetectorID
Enumeration for the tracking detector subsystems in CBM-CA.
Definition CbmDefs.h:216
constexpr ECbmModuleId ToCbmModuleId(EDetectorID detID)
Conversion map from EDetectorID to ECbmModuleId.
Definition CbmDefs.h:228
int GetMaxThreads()
Definition OpenMP.h:46
Input to the TrackingChain.
PartitionedSpan< trd::Hit > trdHits
PartitionedSpan< sts::Hit > stsHits
PartitionedSpan< tof::Hit > tofHits
Output from the TrackingChain.
ca::Vector< ca::Track > tracks
Reconstructed tracks.
ca::TrackingMonitorData monitorData
Monitor data.
ca::Vector< std::vector< std::pair< uint32_t, uint32_t > > > trdHitIndices
TRD hit indices.
ca::Vector< std::vector< std::pair< uint32_t, uint32_t > > > tofHitIndices
TOF hit indices.
ca::Vector< std::vector< std::pair< uint32_t, uint32_t > > > stsHitIndices
STS hit indices.
std::tuple_element_t< static_cast< std::size_t >(DetID), std::tuple< Types... > > at
static Parameters< Float > Load(const std::string &fileName)
Loads parameters from file.