CbmRoot
Loading...
Searching...
No Matches
CaQa.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
10#include "CaQa.h"
11
12#include "CaDefs.h"
13#include "CaInputData.h"
14#include "CaParameters.h"
15#include "CaTrack.h"
16#include "TrackingDefs.h"
17
18#include <algorithm>
19#include <fstream>
20#include <limits>
21
22#include <fmt/format.h>
23
27
28// ---------------------------------------------------------------------------------------------------------------------
29//
30bool Qa::CheckInit() const
31{
32 bool res = true;
33 if (!fpParameters) {
34 L_(error) << "cbm::algo::ca::OutputQa::Build(): parameters object is undefined";
35 res = false;
36 }
37 if (!fpInputData) {
38 L_(error) << "cbm::algo::ca::OutputQa::Build(): input data object is undefined";
39 res = false;
40 }
41 if (!fpvTracks) {
42 L_(error) << "cbm::algo::ca::OutputQa::Build(): track vector is undefined";
43 res = false;
44 }
45 if (!fpvRecoHits) {
46 L_(error) << "cbm::algo::ca::OutputQa::Build(): used hit index vector is undefined";
47 res = false;
48 }
49 return res;
50}
51
52// ---------------------------------------------------------------------------------------------------------------------
53//
55{
62 using fmt::format;
63
64 if (!IsActive()) {
65 return;
66 }
67
68 // ********************
69 // ** Hit distributions
70 int nSt = fpParameters->GetNstationsActive(); // Number of active tracking stations
71 {
72 // Occupancy distributions
73 fvphHitOccupXY.resize(nSt);
74 fvphHitOccupZX.resize(nSt);
75 if (kDebug) {
76 fvphHitOccupZY.resize(nSt);
77 fvphHitUsageXY.resize(nSt);
78 }
79
80 // Station sizes in transverse plane
81 std::vector<double> vMinX(nSt);
82 std::vector<double> vMaxX(nSt);
83 std::vector<double> vMinY(nSt);
84 std::vector<double> vMaxY(nSt);
85
86 int nBinsXY = 200;
87 int nBinsZ = 400;
88
89 for (int iSt = 0; iSt < nSt; ++iSt) {
90 const auto& station = fpParameters->GetStation(iSt);
91 vMaxX[iSt] = station.GetXmax<double>();
92 vMinX[iSt] = station.GetXmin<double>();
93 vMaxY[iSt] = station.GetYmax<double>();
94 vMinY[iSt] = station.GetYmin<double>();
95 double dy = (vMaxY[iSt] - vMinY[iSt]) * kXYZMargin;
96 double dx = (vMaxX[iSt] - vMinX[iSt]) * kXYZMargin;
97 vMaxX[iSt] += dx;
98 vMinX[iSt] -= dx;
99 vMaxY[iSt] += dy;
100 vMinY[iSt] -= dy;
101 }
102 // Station max
103 double xMinA = *std::min_element(vMinX.begin(), vMinX.end());
104 double xMaxA = *std::max_element(vMaxX.begin(), vMaxX.end());
105 double yMinA = *std::min_element(vMinY.begin(), vMinY.end());
106 double yMaxA = *std::max_element(vMaxY.begin(), vMaxY.end());
107 double zMinA = fpParameters->GetStation(0).GetZ<double>();
108 double zMaxA = fpParameters->GetStation(nSt - 1).GetZ<double>();
109 {
110 double dz = (zMaxA - zMinA) * kXYZMargin;
111 zMinA -= dz;
112 zMaxA += dz;
113 }
114 for (int iSt = 0; iSt < nSt; ++iSt) {
115 int iStGeo = fpParameters->GetActiveToGeoMap()[iSt];
116 auto [detID, iStLoc] = fpParameters->GetGeoToLocalIdMap()[iStGeo];
117 for (auto hitSet : kHitSets) {
118 auto setNm = EHitSet::Input == hitSet ? "input" : "used";
119 auto setTl = EHitSet::Input == hitSet ? "Input" : "Used";
120 {
121 auto name = format("hit_{}_occup_xy_sta_{}", setNm, iSt);
122 auto titl = format("{} hit occupancy in XY plane for station {} ({}{});x [cm];y [cm]", setTl, iSt,
123 kDetName[detID], iStLoc);
124 fvphHitOccupXY[iSt][hitSet] =
125 MakeObj<H2D>(name, titl, nBinsXY, vMinX[iSt], vMaxX[iSt], nBinsXY, vMinY[iSt], vMaxY[iSt]);
126 }
127 {
128 auto name = format("hit_{}_occup_zx_sta_{}", setNm, iSt);
129 auto titl = format("{} hit occupancy in ZX plane for station {} ({}{});z [cm];x [cm]", setTl, iSt,
130 kDetName[detID], iStLoc);
131 fvphHitOccupZX[iSt][hitSet] = MakeObj<H2D>(name, titl, nBinsZ, zMinA, zMaxA, nBinsXY, xMinA, xMaxA);
132 }
133 if (kDebug) {
134 auto name = format("hit_{}_occup_zy_sta_{}", setNm, iSt);
135 auto titl = format("{} hit occupancy in ZY plane for station {} ({}{});z [cm];y [cm]", setTl, iSt,
136 kDetName[detID], iStLoc);
137 fvphHitOccupZY[iSt][hitSet] = MakeObj<H2D>(name, titl, nBinsZ, zMinA, zMaxA, nBinsXY, yMinA, yMaxA);
138 }
139 }
140 if (kDebug) {
141 auto name = format("hit_usage_xy_sta_{}", iSt);
142 auto titl = format("Hit usage in XY plane for station {} ({}{});x [cm];y [cm]", iSt, kDetName[detID], iStLoc);
143 fvphHitUsageXY[iSt] =
144 MakeObj<Prof2D>(name, titl, nBinsXY, vMinX[iSt], vMaxX[iSt], nBinsXY, vMinY[iSt], vMaxY[iSt], 0., 1.);
145 }
146 }
147 if (kDebug) {
148 for (auto hitSet : kHitSets) {
149 constexpr int NBins = 1000000;
150 auto setNm = EHitSet::Input == hitSet ? "input" : "used";
151 auto setTl = EHitSet::Input == hitSet ? "Input" : "Used";
152 {
153 auto name = format("hit_{}_front_key_index", setNm);
154 auto titl = format("{} hit front key index;ID_{{key}}/N_{{keys}};Count", setTl);
155 fvphHitFrontKeyIndex[hitSet] = MakeObj<H1D>(name, titl, NBins, 0., 1.);
156 }
157 {
158 auto name = format("hit_{}_back_key_index", setNm);
159 auto titl = format("{} hit back key index;ID_{{key}}/N_{{keys}};Count", setTl);
160 fvphHitBackKeyIndex[hitSet] = MakeObj<H1D>(name, titl, NBins, 0., 1.);
161 }
162 }
163 }
164
165 // Hit time distributions
166 if (kDebug) {
167 fvphHitTime.resize(nSt + 1); // [nSt] - total over stations
168 for (int iSt = 0; iSt < nSt + 1; ++iSt) {
169 auto staNm = iSt == nSt ? "" : format("_sta_{}", iSt);
170 auto staTl = iSt == nSt ? "" : format(" in station {}", iSt);
171 for (auto hitSet : kHitSets) {
172 auto setNm = EHitSet::Input == hitSet ? "input" : "used";
173 auto setTl = EHitSet::Input == hitSet ? "Input" : "Used";
174 auto name = format("hit_{}_rel_time{}", setNm, staNm);
175 auto titl = format("{} hit relative time{}; #delta t_{{hit}};Count", setTl, staTl);
176 fvphHitTime[iSt][hitSet] = MakeObj<H1D>(name, titl, 10000, -0.1, 1.1);
177 }
178 }
179 }
180 }
181
182 // **********************
183 // ** Track distributions
184 std::vector<std::string> vsPointName = {"first", "last"};
185 for (int i = 0; i < knTrkParPoints; ++i) {
186 if (!kDebug && i > 0) {
187 continue;
188 }
189 {
190 auto sName = format("{}_track_{}_theta", GetTaskName(), vsPointName[i]);
191 auto sTitl = format("#theta at {} hit; #theta", vsPointName[i]);
192 fvphTrkTheta[i] = MakeObj<H1D>(sName, sTitl, 62, 0., 90.);
193 }
194 {
195 auto sName = format("{}_track_{}_phi", GetTaskName(), vsPointName[i]);
196 auto sTitl = format("#phi at {} hit; #phi", vsPointName[i]);
197 fvphTrkPhi[i] = MakeObj<H1D>(sName, sTitl, 62, -180., 180.);
198 }
199 {
200 auto sName = format("{}_track_{}_thata_phi", GetTaskName(), vsPointName[i]);
201 auto sTitl = format("#theta vs #phi at {} hit; #phi; #theta", vsPointName[i]);
202 fvphTrkPhiTheta[i] = MakeObj<H2D>(sName, sTitl, 62, -180., 180., 62, 0., 90.);
203 }
204 {
205 auto sName = format("{}_track_{}_chi2_ndf", GetTaskName(), vsPointName[i]);
206 auto sTitl = format("#chi^{{2}}/NDF at {} hit; #chi^{{2}}/NDF", vsPointName[i]);
207 fvphTrkChi2Ndf[i] = MakeObj<H1D>(sName, sTitl, 100, 0., 20.);
208 }
209 }
210 {
211 int nBins = knStaMax;
212 double xMin = -0.5;
213 double xMax = double(knStaMax) - 0.5;
214 {
215 auto sName = format("{}_track_fst_lst_sta", GetTaskName());
216 auto sTitl = "First vs. last station index;ID^{last}_{station};ID^{first}_{station}";
217 fphTrkFstLstSta = MakeObj<H2D>(sName, sTitl, nBins, xMin, xMax, nBins, xMin, xMax);
218 }
219 {
220 auto sName = format("{}_track_origin", GetTaskName());
221 auto sTitl = "Track origin;x [cm];y [cm]";
223 }
224 fphTrkNofHits = MakeObj<H1D>("n_hits", "Number of hits;N_{hit}", nBins, xMin, xMax);
225 }
226
227 // ---- Init canvases
228 {
229 // Input hits canvas
230 {
231 for (auto hitSet : kHitSets) {
232 auto setNm = EHitSet::Input == hitSet ? "input" : "used";
233 auto setTl = EHitSet::Input == hitSet ? "Input" : "Used";
234 { // XY
235 auto name = format("{}_ca_hit_{}_occupancy_xy", GetTaskName(), setNm);
236 auto titl = format("{} hit occupancy in different stations in XY plane", setNm);
237 auto canv = CanvasConfig(name, titl);
238 for (int iSt = 0; iSt < nSt; ++iSt) {
239 auto pad = PadConfig(false, false, false, false, true);
240 pad.RegisterHistogram(fvphHitOccupXY[iSt][hitSet], "colz");
241 canv.AddPadConfig(pad);
242 }
243 AddCanvasConfig(canv);
244 }
245 { // ZX and ZY
246 auto name = format("{}_ca_hit_{}_occupancy_zx_zy", GetTaskName(), setNm);
247 auto titl = format("{} hit occupancy in different stations in ZX and ZY planes", setTl);
248 auto canv = CanvasConfig(name, titl);
249 { // ZX
250 auto pad = PadConfig();
251 for (int iSt = 0; iSt < nSt; ++iSt) {
252 pad.RegisterHistogram(fvphHitOccupZX[iSt][hitSet], (iSt == 0 ? "colz" : "cols same"));
253 }
254 canv.AddPadConfig(pad);
255 }
256 if (kDebug) { // ZY
257 auto pad = PadConfig();
258 for (int iSt = 0; iSt < nSt; ++iSt) {
259 pad.RegisterHistogram(fvphHitOccupZY[iSt][hitSet], (iSt == 0 ? "colz" : "cols same"));
260 }
261 canv.AddPadConfig(pad);
262 }
263 AddCanvasConfig(canv);
264 }
265 }
266 if (kDebug) {
267 auto name = format("{}_ca_hit_usage_xy", GetTaskName());
268 auto titl = format("Hit usage in different stations in XY plane");
269 auto canv = CanvasConfig(name, titl);
270 for (int iSt = 0; iSt < nSt; ++iSt) {
271 auto pad = PadConfig();
272 pad.RegisterHistogram(fvphHitUsageXY[iSt], "colz");
273 canv.AddPadConfig(pad);
274 }
275 AddCanvasConfig(canv);
276 }
277 }
278
279 // Tracks canvas
280 {
281 auto canv = CanvasConfig(format("{}_ca_tracks", GetTaskName()), "Tracking output QA");
282 {
283 auto pad = PadConfig(true, true, false, false, true);
284 pad.RegisterHistogram(fvphTrkPhiTheta[0], "colz");
285 canv.AddPadConfig(pad);
286 }
287 {
288 auto pad = PadConfig(true, true, false, true, false);
289 pad.RegisterHistogram(fvphTrkChi2Ndf[0], "hist");
290 canv.AddPadConfig(pad);
291 }
292 {
293 auto pad = PadConfig(true, true, false, true, false);
294 pad.RegisterHistogram(fphTrkNofHits, "hist");
295 canv.AddPadConfig(pad);
296 }
297 {
298 auto pad = PadConfig(true, true, false, false, true);
299 pad.RegisterHistogram(fphTrkFstLstSta, "colz");
300 canv.AddPadConfig(pad);
301 }
302 {
303 auto pad = PadConfig(true, true, false, false, false);
304 pad.RegisterHistogram(fphTrkOriginXY, "colz");
305 canv.AddPadConfig(pad);
306 }
307 AddCanvasConfig(canv);
308 }
309 }
310}
311
312// ---------------------------------------------------------------------------------------------------------------------
313//
315{
316 if (!IsActive()) {
317 return;
318 }
319
320 if (!CheckInit()) {
321 L_(fatal) << "ca::Qa: instance is not initialized";
322 assert(false);
323 }
324
325 int nHitsInput = fpInputData->GetNhits();
326 // Map: if hit used in tracking
327 std::vector<unsigned char> vbHitUsed(nHitsInput, false);
328 for (int iH : (*fpvRecoHits)) {
329 vbHitUsed[iH] = true;
330 }
331
332 // Calculate max and min hit time
333 if constexpr (kDebug) {
334 const auto& hits = fpInputData->GetHits();
335 auto [minTimeIt, maxTimeIt] =
336 std::minmax_element(hits.cbegin(), hits.cend(), [](const auto& h1, const auto& h2) { return h1.T() < h2.T(); });
337 fMinHitTime = minTimeIt->T();
338 fMaxHitTime = maxTimeIt->T();
339 }
340
341 // Fill input hit histograms
342 {
343 for (int iH = 0; iH < nHitsInput; ++iH) {
344 const auto& hit = fpInputData->GetHit(iH);
346 if (vbHitUsed[iH]) {
348 }
349 if constexpr (kDebug) {
350 int iSt = hit.Station();
351 double x = hit.X();
352 double y = hit.Y();
353 fvphHitUsageXY[iSt]->Fill(x, y, static_cast<double>(vbHitUsed[iH]));
354 }
355 }
356 }
357
358 // Fill track histograms
359 {
360 int trkFirstHit = 0; // Index of hit in fpvRecoHits
361 for (auto trkIt = fpvTracks->begin(); trkIt != fpvTracks->end(); ++trkIt) {
362 auto& track = *trkIt;
363 int nHits = track.fNofHits;
364 // Indices of hits in fpInputData->GetHits()
365 int iFstHit = (*fpvRecoHits)[trkFirstHit];
366 int iLstHit = (*fpvRecoHits)[trkFirstHit + nHits - 1];
367
368 // Distributions in different track points
369 for (int ip = 0; ip < knTrkParPoints; ++ip) {
370 if (!kDebug && ip > 0) {
371 continue;
372 }
373 //int iHit = (ip == 0 ? iFstHit : iLstHit);
374 //const auto& hit = fpInputData->GetHit(iHit);
375 const auto& trkPar = (ip == 0 ? track.fParFirst : track.fParLast);
376 fvphTrkTheta[ip]->Fill(trkPar.GetTheta() * 180. / Pi);
377 fvphTrkPhi[ip]->Fill(trkPar.GetPhi() * 180. / Pi);
378 fvphTrkPhiTheta[ip]->Fill(trkPar.GetPhi() * 180. / Pi, trkPar.GetTheta() * 180. / Pi);
379 fvphTrkChi2Ndf[ip]->Fill(trkPar.GetChiSq() / trkPar.GetNdf());
380 }
381 // Other distributions
383 fphTrkNofHits->Fill(nHits);
384 fphTrkOriginXY->Fill(track.fParPV.X(), track.fParPV.Y());
385 trkFirstHit += nHits;
386 }
387 }
388}
389
390// ---------------------------------------------------------------------------------------------------------------------
391//
393{
394 int nSt = fpParameters->GetNstationsActive();
395 int iSt = hit.Station();
396 double x = hit.X();
397 double y = hit.Y();
398 double z = hit.Z();
399 fvphHitOccupXY[iSt][hitSet]->Fill(x, y);
400 fvphHitOccupZX[iSt][hitSet]->Fill(z, x);
401 if constexpr (kDebug) {
402 fvphHitOccupZY[iSt][hitSet]->Fill(z, y);
403 auto nKeys = static_cast<double>(fpInputData->GetNhitKeys());
404 fvphHitFrontKeyIndex[hitSet]->Fill(hit.FrontKey() / nKeys);
405 fvphHitBackKeyIndex[hitSet]->Fill(hit.BackKey() / nKeys);
406 double relTime = (hit.T() - fMinHitTime) / (fMaxHitTime - fMinHitTime);
407 fvphHitTime[iSt][hitSet]->Fill(relTime);
408 fvphHitTime[nSt][hitSet]->Fill(relTime);
409 }
410}
#define L_(level)
Compile-time constants definition for the CA tracking algorithm.
Structure for input data to the L1 tracking algorithm (declaration)
A QA module for CA tracking (header)
source file for the ca::Track class
static vector< vector< QAHit > > hits
Definitions for tracking in the online reconstruction.
ca::Hit class describes a generic hit for the CA tracker
Definition CaHit.h:32
fscal Z() const
Get the Z coordinate.
Definition CaHit.h:108
HitKeyIndex_t BackKey() const
Get the back key index.
Definition CaHit.h:99
fscal Y() const
Get the Y coordinate.
Definition CaHit.h:105
HitKeyIndex_t FrontKey() const
Get the front key index.
Definition CaHit.h:96
fscal T() const
Get the time.
Definition CaHit.h:111
fscal X() const
Get the X coordinate.
Definition CaHit.h:102
int Station() const
Get the station index.
Definition CaHit.h:138
HitIndex_t GetNhits() const
Gets number of hits in the hits vector.
Definition CaInputData.h:61
const Hit & GetHit(HitIndex_t index) const
Gets reference to hit by its index.
Definition CaInputData.h:55
int GetNhitKeys() const
Gets total number of stored keys.
Definition CaInputData.h:64
const Vector< Hit > & GetHits() const
Gets reference to hits vector.
Definition CaInputData.h:58
void Exec()
QA execution function.
Definition CaQa.cxx:314
bool CheckInit() const
Check initialization.
Definition CaQa.cxx:30
std::vector< HitSetArray_t< qa::H1D * > > fvphHitTime
Time distribution of hits.
Definition CaQa.h:143
OccupHistContainer_t fvphHitOccupXY
hist: Hit occupancy in different stations in XY plane
Definition CaQa.h:134
static constexpr double kOriginL
Track X(Y) at origin: lower bound [cm].
Definition CaQa.h:121
const Vector< Track > * fpvTracks
Pointer to tracks vector.
Definition CaQa.h:129
static constexpr int knStaMax
Max number of stations (histogram binning)
Definition CaQa.h:118
std::array< qa::H1D *, knTrkParPoints > fvphTrkPhi
hist: phi at first/last hit
Definition CaQa.h:147
void Init()
Initializes the QA.
Definition CaQa.cxx:54
void FillHitDistributionsForHitSet(EHitSet hitSet, const ca::Hit &hit)
Fills hit distributions.
Definition CaQa.cxx:392
static constexpr HitSetArray_t< EHitSet > kHitSets
Array of EHitSet entries for iteration.
Definition CaQa.h:54
HitSetArray_t< qa::H1D * > fvphHitBackKeyIndex
Indices of back hit keys.
Definition CaQa.h:141
std::vector< qa::Prof2D * > fvphHitUsageXY
prof: Hit usage in different stations in XY plane
Definition CaQa.h:138
static constexpr double kXYZMargin
Margin for occupancy distributions in XY plane.
Definition CaQa.h:115
double fMinHitTime
Definition CaQa.h:124
HitSetArray_t< qa::H1D * > fvphHitFrontKeyIndex
Indices of front hit keys.
Definition CaQa.h:140
static constexpr int knTrkParPoints
Number of track points to build par distributions.
Definition CaQa.h:117
const Vector< HitIndex_t > * fpvRecoHits
Pointer to reco hit indices.
Definition CaQa.h:130
qa::H2D * fphTrkOriginXY
hist: origin of tracks in x-y plane [cm]
Definition CaQa.h:151
qa::H1D * fphTrkNofHits
hist: number of hits in track
Definition CaQa.h:153
OccupHistContainer_t fvphHitOccupZX
hist: Hit occupancy in different stations in ZX plane
Definition CaQa.h:135
qa::H2D * fphTrkFstLstSta
hist: fst vs lst station index
Definition CaQa.h:152
double fMaxHitTime
Definition CaQa.h:125
const InputData * fpInputData
Pointer to input data.
Definition CaQa.h:128
static constexpr double kOriginU
Track X(Y) at origin: upper bound [cm].
Definition CaQa.h:122
static constexpr bool kDebug
Additional histograms.
Definition CaQa.h:119
OccupHistContainer_t fvphHitOccupZY
hist: Hit occupancy in different stations in ZY plane
Definition CaQa.h:136
std::array< qa::H1D *, knTrkParPoints > fvphTrkChi2Ndf
hist: chi2/NDF at first/last hit
Definition CaQa.h:148
std::array< qa::H2D *, knTrkParPoints > fvphTrkPhiTheta
hist: theta vs. phi at first/last hit
Definition CaQa.h:149
std::array< qa::H1D *, knTrkParPoints > fvphTrkTheta
hist: theta at first/last hit
Definition CaQa.h:146
static constexpr int kOriginB
Track X(Y) at origin: n bins.
Definition CaQa.h:120
const Parameters< fvec > * fpParameters
Pointer to tracking parameters.
Definition CaQa.h:127
EHitSet
Hit set entries.
Definition CaQa.h:43
@ Used
Hits used in tracks.
A canvas configuration for the histogram server.
Class to handle QA-objects in the online reconstruction.
Definition QaData.h:29
1D-histogram
int Fill(double x, double w=1.)
Fills histogram.
Definition Histogram.h:474
2D-histogram
int Fill(double x, double y, double w=1.)
Fills histogram.
Definition Histogram.h:549
A pad configuration for the histogram server.
Definition PadConfig.h:26
const std::string & GetTaskName()
Gets name of the task.
void AddCanvasConfig(const CanvasConfig &canvas)
Adds a canvas configuration.
bool IsActive() const
Checks, if the task is active.
Obj * MakeObj(Args... args)
Creates a QA-object and returns the pointer to it.
constexpr double Pi
Value of PI, used in ROOT TMath.
Definition CaDefs.h:96
constexpr DetIdArray_t< const char * > kDetName
Detector subsystem names.