CbmRoot
Loading...
Searching...
No Matches
CaQa.cxx
Go to the documentation of this file.
1/* Copyright (C) 2023-2024 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 (!fpSender.get()) {
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 fQaData.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] = fQaData.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] = fQaData.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 fQaData.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] = fQaData.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] = fQaData.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] = fQaData.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", vsPointName[i]);
191 auto sTitl = format("#theta at {} hit; #theta", vsPointName[i]);
192 fvphTrkTheta[i] = fQaData.MakeObj<H1D>(sName, sTitl, 62, 0., 90.);
193 }
194 {
195 auto sName = format("track_{}_phi", vsPointName[i]);
196 auto sTitl = format("#phi at {} hit; #phi", vsPointName[i]);
197 fvphTrkPhi[i] = fQaData.MakeObj<H1D>(sName, sTitl, 62, -180., 180.);
198 }
199 {
200 auto sName = format("track_{}_thata_phi", vsPointName[i]);
201 auto sTitl = format("#theta vs #phi at {} hit; #phi; #theta", vsPointName[i]);
202 fvphTrkPhiTheta[i] = fQaData.MakeObj<H2D>(sName, sTitl, 62, -180., 180., 62, 0., 90.);
203 }
204 {
205 auto sName = format("track_{}_chi2_ndf", vsPointName[i]);
206 auto sTitl = format("#chi^{{2}}/NDF at {} hit; #chi^{{2}}/NDF", vsPointName[i]);
207 fvphTrkChi2Ndf[i] = fQaData.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 = "track_fst_lst_sta";
216 auto sTitl = "First vs. last station index;ID^{last}_{station};ID^{first}_{station}";
217 fphTrkFstLstSta = fQaData.MakeObj<H2D>(sName, sTitl, nBins, xMin, xMax, nBins, xMin, xMax);
218 }
219 fphTrkNofHits = fQaData.MakeObj<H1D>("n_hits", "Number of hits;N_{hit}", nBins, xMin, xMax);
220 }
221
222 // ---- Init canvases
223 {
224 // Input hits canvas
225 {
226 for (auto hitSet : kHitSets) {
227 auto setNm = EHitSet::Input == hitSet ? "input" : "used";
228 auto setTl = EHitSet::Input == hitSet ? "Input" : "Used";
229 { // XY
230 auto name = format("ca_hit_{}_occupancy_xy", setNm);
231 auto titl = format("{} hit occupancy in different stations in XY plane", setNm);
232 auto canv = CanvasConfig(name, titl);
233 for (int iSt = 0; iSt < nSt; ++iSt) {
234 auto pad = PadConfig();
235 pad.RegisterHistogram(fvphHitOccupXY[iSt][hitSet], "colz");
236 canv.AddPadConfig(pad);
237 }
239 }
240 { // ZX and ZY
241 auto name = format("ca_hit_{}_occupancy_zx_zy", setNm);
242 auto titl = format("{} hit occupancy in different stations in ZX and ZY planes", setTl);
243 auto canv = CanvasConfig(name, titl);
244 { // ZX
245 auto pad = PadConfig();
246 for (int iSt = 0; iSt < nSt; ++iSt) {
247 pad.RegisterHistogram(fvphHitOccupZX[iSt][hitSet], (iSt == 0 ? "colz" : "cols same"));
248 }
249 canv.AddPadConfig(pad);
250 }
251 if (kDebug) { // ZY
252 auto pad = PadConfig();
253 for (int iSt = 0; iSt < nSt; ++iSt) {
254 pad.RegisterHistogram(fvphHitOccupZY[iSt][hitSet], (iSt == 0 ? "colz" : "cols same"));
255 }
256 canv.AddPadConfig(pad);
257 }
259 }
260 }
261 if (kDebug) {
262 auto name = format("ca_hit_usage_xy");
263 auto titl = format("Hit usage in different stations in XY plane");
264 auto canv = CanvasConfig(name, titl);
265 for (int iSt = 0; iSt < nSt; ++iSt) {
266 auto pad = PadConfig();
267 pad.RegisterHistogram(fvphHitUsageXY[iSt], "colz");
268 canv.AddPadConfig(pad);
269 }
271 }
272 }
273
274 // Tracks canvas
275 {
276 auto canv = CanvasConfig("ca_tracks", "Tracking output QA");
277 {
278 auto pad = PadConfig(true, true, false, false, true);
279 pad.RegisterHistogram(fvphTrkPhiTheta[0], "colz");
280 canv.AddPadConfig(pad);
281 }
282 {
283 auto pad = PadConfig(true, true, false, true, false);
284 pad.RegisterHistogram(fvphTrkChi2Ndf[0], "hist");
285 canv.AddPadConfig(pad);
286 }
287 {
288 auto pad = PadConfig(true, true, false, true, false);
289 pad.RegisterHistogram(fphTrkNofHits, "hist");
290 canv.AddPadConfig(pad);
291 }
292 {
293 auto pad = PadConfig(true, true, false, false, true);
294 pad.RegisterHistogram(fphTrkFstLstSta, "colz");
295 canv.AddPadConfig(pad);
296 }
298 }
300 }
301}
302
303// ---------------------------------------------------------------------------------------------------------------------
304//
306{
307 if (!fpSender.get()) {
308 return;
309 }
310
311 if (!CheckInit()) {
312 L_(fatal) << "ca::Qa: instance is not initialized";
313 assert(false);
314 }
315
316 int nHitsInput = fpInputData->GetNhits();
317 // Map: if hit used in tracking
318 std::vector<unsigned char> vbHitUsed(nHitsInput, false);
319 for (int iH : (*fpvRecoHits)) {
320 vbHitUsed[iH] = true;
321 }
322
323 // Calculate max and min hit time
324 if constexpr (kDebug) {
325 const auto& hits = fpInputData->GetHits();
326 auto [minTimeIt, maxTimeIt] =
327 std::minmax_element(hits.cbegin(), hits.cend(), [](const auto& h1, const auto& h2) { return h1.T() < h2.T(); });
328 fMinHitTime = minTimeIt->T();
329 fMaxHitTime = maxTimeIt->T();
330 }
331
332 // Fill input hit histograms
333 {
334 for (int iH = 0; iH < nHitsInput; ++iH) {
335 const auto& hit = fpInputData->GetHit(iH);
337 if (vbHitUsed[iH]) {
339 }
340 if constexpr (kDebug) {
341 int iSt = hit.Station();
342 double x = hit.X();
343 double y = hit.Y();
344 fvphHitUsageXY[iSt]->Fill(x, y, static_cast<double>(vbHitUsed[iH]));
345 }
346 }
347 }
348
349 // Fill track histograms
350 {
351 int trkFirstHit = 0; // Index of hit in fpvRecoHits
352 for (auto trkIt = fpvTracks->begin(); trkIt != fpvTracks->end(); ++trkIt) {
353 auto& track = *trkIt;
354 int nHits = track.fNofHits;
355 // Indices of hits in fpInputData->GetHits()
356 int iFstHit = (*fpvRecoHits)[trkFirstHit];
357 int iLstHit = (*fpvRecoHits)[trkFirstHit + nHits - 1];
358
359 // Distributions in different track points
360 for (int ip = 0; ip < knTrkParPoints; ++ip) {
361 if (!kDebug && ip > 0) {
362 continue;
363 }
364 //int iHit = (ip == 0 ? iFstHit : iLstHit);
365 //const auto& hit = fpInputData->GetHit(iHit);
366 const auto& trkPar = (ip == 0 ? track.fParFirst : track.fParLast);
367 fvphTrkTheta[ip]->Fill(trkPar.GetTheta() * 180. / Pi);
368 fvphTrkPhi[ip]->Fill(trkPar.GetPhi() * 180. / Pi);
369 fvphTrkPhiTheta[ip]->Fill(trkPar.GetPhi() * 180. / Pi, trkPar.GetTheta() * 180. / Pi);
370 fvphTrkChi2Ndf[ip]->Fill(trkPar.GetChiSq() / trkPar.GetNdf());
371 }
372 // Other distributions
374 fphTrkNofHits->Fill(nHits);
375 trkFirstHit += nHits;
376 }
377 }
378
380}
381
382// ---------------------------------------------------------------------------------------------------------------------
383//
385{
386 int nSt = fpParameters->GetNstationsActive();
387 int iSt = hit.Station();
388 double x = hit.X();
389 double y = hit.Y();
390 double z = hit.Z();
391 fvphHitOccupXY[iSt][hitSet]->Fill(x, y);
392 fvphHitOccupZX[iSt][hitSet]->Fill(z, x);
393 if constexpr (kDebug) {
394 fvphHitOccupZY[iSt][hitSet]->Fill(z, y);
395 auto nKeys = static_cast<double>(fpInputData->GetNhitKeys());
396 fvphHitFrontKeyIndex[hitSet]->Fill(hit.FrontKey() / nKeys);
397 fvphHitBackKeyIndex[hitSet]->Fill(hit.BackKey() / nKeys);
398 double relTime = (hit.T() - fMinHitTime) / (fMaxHitTime - fMinHitTime);
399 fvphHitTime[iSt][hitSet]->Fill(relTime);
400 fvphHitTime[nSt][hitSet]->Fill(relTime);
401 }
402}
#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:305
bool CheckInit() const
Check initialization.
Definition CaQa.cxx:30
std::vector< HitSetArray_t< qa::H1D * > > fvphHitTime
Time distribution of hits.
Definition CaQa.h:145
OccupHistContainer_t fvphHitOccupXY
hist: Hit occupancy in different stations in XY plane
Definition CaQa.h:136
const Vector< Track > * fpvTracks
Pointer to tracks vector.
Definition CaQa.h:131
static constexpr int knStaMax
Max number of stations (histogram binning)
Definition CaQa.h:119
std::array< qa::H1D *, knTrkParPoints > fvphTrkPhi
hist: phi at first/last hit
Definition CaQa.h:149
qa::Data fQaData
QA data.
Definition CaQa.h:126
void Init()
Initializes the QA.
Definition CaQa.cxx:54
void FillHitDistributionsForHitSet(EHitSet hitSet, const ca::Hit &hit)
Fills hit distributions.
Definition CaQa.cxx:384
static constexpr HitSetArray_t< EHitSet > kHitSets
Array of EHitSet entries for iteration.
Definition CaQa.h:53
HitSetArray_t< qa::H1D * > fvphHitBackKeyIndex
Indices of back hit keys.
Definition CaQa.h:143
std::vector< qa::Prof2D * > fvphHitUsageXY
prof: Hit usage in different stations in XY plane
Definition CaQa.h:140
static constexpr double kXYZMargin
Margin for occupancy distributions in XY plane.
Definition CaQa.h:116
double fMinHitTime
Definition CaQa.h:122
HitSetArray_t< qa::H1D * > fvphHitFrontKeyIndex
Indices of front hit keys.
Definition CaQa.h:142
static constexpr int knTrkParPoints
Number of track points to build par distributions.
Definition CaQa.h:118
const Vector< HitIndex_t > * fpvRecoHits
Pointer to reco hit indices.
Definition CaQa.h:132
qa::H1D * fphTrkNofHits
hist: number of hits in track
Definition CaQa.h:154
OccupHistContainer_t fvphHitOccupZX
hist: Hit occupancy in different stations in ZX plane
Definition CaQa.h:137
qa::H2D * fphTrkFstLstSta
hist: fst vs lst station index
Definition CaQa.h:153
double fMaxHitTime
Definition CaQa.h:123
const InputData * fpInputData
Pointer to input data.
Definition CaQa.h:130
static constexpr bool kDebug
Additional histograms.
Definition CaQa.h:120
OccupHistContainer_t fvphHitOccupZY
hist: Hit occupancy in different stations in ZY plane
Definition CaQa.h:138
std::array< qa::H1D *, knTrkParPoints > fvphTrkChi2Ndf
hist: chi2/NDF at first/last hit
Definition CaQa.h:150
std::array< qa::H2D *, knTrkParPoints > fvphTrkPhiTheta
hist: theta vs. phi at first/last hit
Definition CaQa.h:151
std::array< qa::H1D *, knTrkParPoints > fvphTrkTheta
hist: theta at first/last hit
Definition CaQa.h:148
std::shared_ptr< HistogramSender > fpSender
Histogram sender.
Definition CaQa.h:128
const Parameters< fvec > * fpParameters
Pointer to tracking parameters.
Definition CaQa.h:129
EHitSet
Hit set entries.
Definition CaQa.h:42
@ Used
Hits used in tracks.
A canvas configuration for the histogram server.
Class to handle QA-objects in the online reconstruction.
Definition QaData.h:28
void AddCanvasConfig(const CanvasConfig &canvas)
Adds a canvas to the canvas config list.
Definition QaData.h:51
void Send(std::shared_ptr< HistogramSender > histoSender)
Sends QA data to the HistogramSender.
Definition QaData.cxx:72
void Init(std::shared_ptr< HistogramSender > histoSender)
Sends QA initialization information to the HistogramSender.
Definition QaData.cxx:18
Obj * MakeObj(Args... args)
Creates a QA-object and returns the pointer to it.
Definition QaData.h:85
1D-histogram
int Fill(double x, double w=1.)
Fills histogram.
Definition Histogram.h:473
2D-histogram
int Fill(double x, double y, double w=1.)
Fills histogram.
Definition Histogram.h:548
A pad configuration for the histogram server.
Definition PadConfig.h:26
constexpr double Pi
Value of PI, used in ROOT TMath.
Definition CaDefs.h:96
constexpr DetIdArray_t< const char * > kDetName
Detector subsystem names.