CbmRoot
Loading...
Searching...
No Matches
CaTripletConstructorSW.cxx
Go to the documentation of this file.
1/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Sergey Gorbunov [committer] */
4
8
10
12#include "CaDebugger.h"
13#include "CaDefines.h"
14#include "CaFramework.h"
15#include "CaGridArea.h"
16#include "KfTrackKalmanFilter.h"
17#include "KfTrackParam.h"
18
19#include <algorithm>
20#include <iostream>
21
22
23using namespace cbm::algo::ca;
24
26 WindowData& wData, const fscal mass, const ca::TrackingMode& mode)
27 : fFramework(framework)
28 , fParameters(pars)
29 , fSetup(fParameters.GetActiveSetup())
30 , fField(fSetup.GetField())
31 , fSwMaps(fParameters.GetSearchWindows())
32 , frWData(wData)
33 , fDefaultMass(mass)
34 , fTrackingMode(mode)
35{
36 // FIXME: SZh 24.08.2022
37 // This approach is suitable only for a case, when all the stations inside a magnetic field come right before
38 // all the stations outside of the field!
40 std::lower_bound(fSetup.GetActiveLayers().cbegin(), fSetup.GetActiveLayers().cbegin() + fSetup.GetNofLayers(),
41 0, // we are looking for the first zero element
42 [](const auto& s, int edge) { return s.IsInField() > edge; })
43 - fSetup.GetActiveLayers().cbegin();
44
45 fIsTargetField = !frWData.TargB().IsZero();
46
47 if constexpr (fDebugDublets) {
49 "event:iter:sta:p:q:vx:vy:vz:x0:y0:z0:x1:y1:z1:ax:ay:az:adx:ady:dx:dy:dz");
50 }
51
52 if constexpr (fDebugTriplets) {
53 //utils::Debugger::Instance().AddNtuple(
54 //"triplets", "ev:iter:i0:x0:y0:z0:i1:x1:y1:z1:i2:x2:y2:z2:mc:sta:p:vx:vy:vz:chi2:ndf:chi2time:ndfTime");
56 "tripletSW", "event:iter:sta:jumpL:jumpM:p:q:vx:vy:vz:x0:y0:z0:x1:y1:z1:x2:y2:z2:ax:ay:az:adx:ady:dx:dy:dz");
57 }
58
59 //utils::Debugger::Instance().AddNtuple(
60 //"fit", "good:event:iter:sta:jumpL:jumpM:p:q:vx:vy:vz:x:y:z:chi2:chi2kf:chi2kfS:chi2kfT");
61}
62
63
64bool TripletConstructorSW::InitStations(int istal, int istam, int istar)
65{
66 fIstaL = istal;
67 fIstaM = istam;
68 fIstaR = istar;
69
70 if (fIstaM >= fSetup.GetNofLayers()) {
71 return false;
72 }
73 fStaL = &fSetup.GetActiveLayer(fIstaL);
74 fStaM = &fSetup.GetActiveLayer(fIstaM);
75 fStaR = &fSetup.GetActiveLayer(fIstaR);
76
77 // FIXME: The following blocks do nothing => remove
78 { // two stations for approximating the field between the target and the left hit
79 const int sta1 = (fNfieldStations <= 1) ? 1 : std::clamp(fIstaL, 1, fNfieldStations - 1);
80 const int sta0 = sta1 / 2; // station between fIstaL and the target
81
82 assert(0 <= sta0 && sta0 < sta1 && sta1 < fSetup.GetNofLayers());
83 }
84
85 { // three stations for approximating the field between the left and the right hit
86
87 int sta0 = fIstaL;
88 int sta1 = fIstaM;
89 int sta2 = fIstaM + 1;
90 if (sta2 >= fSetup.GetNofLayers()) {
91 sta2 = fIstaM;
92 sta1 = fIstaM - 1;
93 sta0 = (sta1 <= 0) ? 0 : std::clamp(sta0, 0, sta1 - 1);
94 }
95 if (fSetup.GetNofLayers() >= 3) {
96 assert(0 <= sta0 && sta0 < sta1 && sta1 < sta2 && sta2 < fSetup.GetNofLayers());
97 }
98 }
99 return true;
100}
101
102
103void TripletConstructorSW::CreateTripletsForHit(Vector<ca::Triplet>& tripletsOut, int istal, int istam, int istar,
104 ca::HitIndex_t iHitL)
105{
106 tripletsOut.clear();
107
108 if (!InitStations(istal, istam, istar) || (fIstaR >= fSetup.GetNofLayers())) {
109 return;
110 }
111
112 fIhitL = iHitL;
113 const auto& hitl = frWData.Hit(fIhitL);
114
115 {
116 const bool matchMc = fParameters.GetConfig().DevMatchDoubletsViaMc();
117 //std::cout << "MC for hit " << fIhitL << ", " << hitl.Id() << " " << ca::Framework::GetMcTrackIdForCaHit(hitl.Id())
118 // << std::endl;
119 McMatch mc = matchMc ? fFramework.GetMcMatchForCaHit(hitl.Id()) : McMatch();
120 fDoubletData.clear();
121 if (mc.IsEmpty() && matchMc) {
122 return;
123 }
124
125 const DoubletSearchWindowMap& sa = fSwMaps.DoubletSw(frWData.CurrentIterationIndex(), fIstaM, istam - istal - 1);
126
128 sa.GetSearchWindow(hitl.X(), hitl.Y(), hitl.Z(), hitl.RangeX(), hitl.RangeY());
129
130 CollectHits(fDoubletData, area2D, hitl.T(), hitl.RangeT(), fIstaM,
131 sqrt(frWData.CurrentIteration()->GetDoubletChi2Cut()) / 3.5,
132 fParameters.GetConfig().GetMaxDoubletsPerSinglet(), mc);
133
134 if constexpr (fDebugDublets) {
135 if (!mc.IsEmpty() && mc.GetNofLinks() == 1) {
136 int trueHitId = FindClosestHitWithMc(area2D, fIstaM, mc);
137 if (trueHitId >= 0) {
138 const ca::Hit& trueHit = frWData.Hit(trueHitId);
139 const McTrack& mctr = fFramework.GetMcData()->GetTrack(mc.GetLink(0));
140 float x = 0.5 * (area2D.xMax + area2D.xMin);
141 float y = 0.5 * (area2D.yMax + area2D.yMin);
142 float z = fSetup.GetActiveLayer(fIstaM).GetZref()[0];
144 "doubletSW", mctr.GetEventId(), frWData.CurrentIterationIndex(), fIstaM, mctr.GetP(), mctr.GetCharge(),
145 mctr.GetStartX(), mctr.GetStartY(), mctr.GetStartZ(), hitl.X(), hitl.Y(), hitl.Z(), trueHit.X(),
146 trueHit.Y(), trueHit.Z(), x, y, z, 0.5 * (area2D.xMax - area2D.xMin), 0.5 * (area2D.yMax - area2D.yMin),
147 trueHit.X() - x, trueHit.Y() - y, trueHit.Z() - z);
148 }
149 }
150 }
151 }
152
154
156 FitTriplets(tripletsOut);
157
158 //tripletsOut.clear();
159 //FitTriplets(tripletsOut);
160}
161
162
164{
165 // ---- Add the middle hits to parameters estimation ----
167
168 const ca::Hit& hitl = frWData.Hit(fIhitL);
169
170 auto it2 = hitsM.begin();
171 for (auto it = hitsM.begin(); it != hitsM.end(); it++) {
172
173 const ca::HitIndex_t indM = *it;
174 const ca::Hit& hitm = frWData.Hit(indM);
175
176 if (frWData.IsHitSuppressed(indM)) {
177 continue;
178 }
179
180 // check if there are other hits close to the doublet on the same station
181 if (ca::kMcbm != fTrackingMode) {
182 // TODO: SG: adjust cuts, put them to parameters
183 fscal dz = hitm.Z() - hitl.Z();
184 fscal tx = (hitm.X() - hitl.X()) / dz;
185 fscal ty = (hitm.Y() - hitl.Y()) / dz;
186
187 for (auto itClone = it + 1; itClone != hitsM.end(); itClone++) {
188
189 const int indClone = *itClone;
190 const ca::Hit& hitClone = frWData.Hit(indClone);
191
192 const fscal dzc = hitClone.Z() - hitm.Z();
193
194 if (fStaM->IsTimeMeasured()) {
195 const fscal dt = hitm.T() - hitClone.T();
196 if (!(fabs(dt) <= hitm.RangeT() + hitClone.RangeT())) {
197 continue;
198 }
199 }
200
201 const fscal dx = hitm.X() + tx * dzc - hitClone.X();
202 if (!(fabs(dx) <= hitm.RangeX() + hitClone.RangeX())) {
203 continue;
204 }
205
206 const fscal dy = hitm.Y() + ty * dzc - hitClone.Y();
207 if (!(fabs(dy) <= hitm.RangeY() + hitClone.RangeY())) {
208 continue;
209 }
210
211 if (fParameters.GetConfig().DevSuppressOverlapHitsViaMc()) {
212 auto mc = fFramework.GetMcMatchForCaHit(hitl.Id());
213 if ((mc != fFramework.GetMcMatchForCaHit(hitm.Id()))
214 || (mc != fFramework.GetMcMatchForCaHit(hitClone.Id()))) {
215 continue;
216 }
217 }
218
219 frWData.SuppressHit(indClone);
220 }
221 }
222
223 *it2 = indM;
224 it2++;
225 } // it
226 hitsM.shrink(std::distance(hitsM.begin(), it2));
227}
228
229
231{
232 // ---- Find the triplets (right hit). Reformat data into portions of triplets. ----
233
234 Vector<ca::HitIndex_t>& hitsM = std::get<0>(fTripletData);
235 Vector<ca::HitIndex_t>& hitsR = std::get<1>(fTripletData);
236 Vector<fscal>& msM = std::get<2>(fTripletData);
237 {
238 const int maxTriplets = fDoubletData.size() * fParameters.GetConfig().GetMaxTripletsPerDoublet();
239 hitsM.clear();
240 hitsR.clear();
241 msM.clear();
242 hitsM.reserve(maxTriplets);
243 hitsR.reserve(maxTriplets);
244 msM.reserve(maxTriplets);
245 }
246
247 const TripletSearchWindowMap& swMap =
248 fSwMaps.TripletSw(frWData.CurrentIterationIndex(), fIstaR, fIstaR - fIstaL - 2, fIstaR - fIstaM - 1);
249
250
251 const double maxSlope = frWData.CurrentIteration()->GetMaxSlope();
252 const double tripletChi2Cut = frWData.CurrentIteration()->GetTripletChi2Cut();
253
254 Vector<ca::HitIndex_t> collectedHits;
255 collectedHits.reserve(fParameters.GetConfig().GetMaxTripletsPerDoublet());
256
257 const auto& sta = fSetup.GetActiveLayer(fIstaR);
258 const auto& grid = frWData.Grid(fIstaR);
259
260 for (unsigned int i2 = 0; i2 < fDoubletData.size(); i2++) {
261
262 const ca::Hit& h0 = frWData.Hit(fIhitL);
263 const ca::Hit& h1 = frWData.Hit(fDoubletData[i2]);
264
265 // TODO: better estimation of the extrapolated tx for the low-p tracks
266 fscal dz = h1.Z() - h0.Z();
267 fscal tx = (h1.X() - h0.X()) / dz;
268 fscal ty = (h1.Y() - h0.Y()) / dz;
269 if ((fabs(tx) > maxSlope) || (fabs(ty) > maxSlope)) {
270 continue;
271 }
272
273 McMatch mc;
274
275 if (fParameters.GetConfig().DevMatchTripletsViaMc()) {
276 mc = fFramework.GetMcMatchForCaHit(h0.Id());
277 auto mc1 = fFramework.GetMcMatchForCaHit(h1.Id());
278 if (mc.IsEmpty() || mc != mc1) {
279 continue;
280 }
281 }
282
283 auto [area2D, ms] = swMap.GetSearchWindowAndMs(h0.X(), h0.Y(), h0.Z(), h0.RangeX(), h0.RangeY(), h1.X(), h1.Y(),
284 h1.Z(), h1.RangeX(), h1.RangeY());
285
286 { // add correction to the hit differences in Z
287 fscal dz1 = grid.GetMinZ() - sta.GetZref()[0];
288 fscal dz2 = grid.GetMaxZ() - sta.GetZref()[0];
289 fscal dx1 = tx * dz1;
290 fscal dx2 = tx * dz2;
291 fscal dy1 = ty * dz1;
292 fscal dy2 = ty * dz2;
293 assert(std::min(dx1, dx2) <= 0.f && std::max(dx1, dx2) >= 0.f);
294 assert(std::min(dy1, dy2) <= 0.f && std::max(dy1, dy2) >= 0.f);
295 area2D.xMin += std::min(dx1, dx2);
296 area2D.xMax += std::max(dx1, dx2);
297 area2D.yMin += std::min(dy1, dy2);
298 area2D.yMax += std::max(dy1, dy2);
299 }
300
301 collectedHits.clear();
302 CollectHits(collectedHits, area2D, h1.T(), h1.RangeT(), fIstaR, sqrt(tripletChi2Cut) / 3.5,
303 fParameters.GetConfig().GetMaxTripletsPerDoublet(), mc);
304
305 if constexpr (fDebugTriplets) { // debug
306 auto mc1 = fFramework.GetMcMatchForCaHit(h0.Id());
307 auto mc2 = fFramework.GetMcMatchForCaHit(h1.Id());
308 if (!mc1.IsEmpty() && mc1 == mc2 && mc1.GetNofLinks() == 1 && mc2.GetNofLinks() == 1) {
309
310 int trueHitId = FindClosestHitWithMc(area2D, fIstaR, mc2);
311 if (trueHitId >= 0) {
312 const ca::Hit& trueHit = frWData.Hit(trueHitId);
313 const McTrack& mctr = fFramework.GetMcData()->GetTrack(mc2.GetLink(0));
314
315 float x = 0.5 * (area2D.xMax + area2D.xMin);
316 float y = 0.5 * (area2D.yMax + area2D.yMin);
317 float z = fSetup.GetActiveLayer(fIstaR).GetZref()[0];
318 //const auto& staR = fParameters.GetStation(fIstaR);
319
321 "tripletSW", mctr.GetEventId(), frWData.CurrentIterationIndex(), fIstaR, fIstaR - fIstaM - 1,
322 fIstaR - fIstaL - 2, mctr.GetP(), mctr.GetCharge(), mctr.GetStartX(), mctr.GetStartY(), mctr.GetStartZ(),
323 h0.X(), h0.Y(), h0.Z(), h1.X(), h1.Y(), h1.Z(), trueHit.X(), trueHit.Y(), trueHit.Z(), x, y, z,
324 0.5 * (area2D.xMax - area2D.xMin), 0.5 * (area2D.yMax - area2D.yMin), trueHit.X() - x, trueHit.Y() - y,
325 trueHit.Z() - z);
326 }
327 }
328 }
329
330 if (static_cast<int>(collectedHits.size()) >= fParameters.GetConfig().GetMaxTripletsPerDoublet()) {
331 // reject already created triplets for this doublet
332
333 // TODO: collect this cases and make a common warning at the end of the data processing
334 // LOG(debug) << "Ca: GetMaxTripletPerDoublets==" << fParameters.GetMaxTripletPerDoublets()
335 // << " reached in FindTripletHits()";
336
337 collectedHits.clear();
338 }
339
340 for (ca::HitIndex_t& irh : collectedHits) {
341 hitsM.push_back(fDoubletData[i2]);
342 hitsR.push_back(irh);
343 msM.push_back(ms);
344 }
345 } // i2
346}
347
348
350{
352
353 Vector<ca::HitIndex_t>& hitsM = std::get<0>(fTripletData);
354 Vector<ca::HitIndex_t>& hitsR = std::get<1>(fTripletData);
355 Vector<fscal>& msM = std::get<2>(fTripletData);
356 assert(hitsM.size() == hitsR.size());
357
358 //tripletsOut.clear();
359 //tripletsOut.reserve(hitsM.size());
360
361 const bool isMomentumFitted = ((fStaL->IsInField()) || (fStaM->IsInField()) || (fStaR->IsInField()));
362
363 if constexpr (fDebugTriplets) {
364 //cbm::ca::tools::Debugger::Instance().AddNtuple(
365 // "triplets", "ev:iter:i0:x0:y0:z0:i1:x1:y1:z1:i2:x2:y2:z2:mc:sta:p:vx:vy:vz:chi2:ndf:chi2time:ndfTime");
366 }
367
368 const ca::HitIndex_t ihitl = fIhitL;
369 const ca::Hit& hitL = frWData.Hit(ihitl);
370 auto fldValueL = fField.GetFieldValue(fIstaL, hitL.X(), hitL.Y());
371 const auto& target = fSetup.GetTarget();
372 const auto fldValueTarget = fField.GetPrimVertexField().Get(target.GetX(), target.GetY(), target.GetZ());
373
374 fscal c_light = fscal(1.e-5 * kf::defs::SpeedOfLight<double>);
375
376 for (size_t i3 = 0; i3 < hitsM.size(); ++i3) {
377
378 // prepare data
379
380 const ca::HitIndex_t ihitm = hitsM[i3];
381 const ca::HitIndex_t ihitr = hitsR[i3];
382
383 const ca::Hit& hitM = frWData.Hit(ihitm);
384 const ca::Hit& hitR = frWData.Hit(ihitr);
385
386 // find the field along the track
387
388 auto fldValueM =
389 fField.GetFieldValue(fIstaM, hitM.X(), hitM.Y()); // TODO: SZh 24.08.2022: check if fIstaM is in field region
390
391 auto fld =
393 fldValueM, //
394 fField.GetFieldValue(fIstaR, hitR.X(), hitR.Y())) //
395 );
396
397 //fscal hT = target.GetZ()[0] - hitM.Z();
398 fscal hL = hitL.Z() - hitM.Z();
399 fscal hR = hitR.Z() - hitM.Z();
400
401 fscal JxL4 = 0.;
402 fscal JyL4 = 0.;
403 fscal msX = 0., msY = 0.;
404
405 { // left hit
406 fscal tx = (hitL.X() - hitM.X()) / hL;
407 fscal ty = (hitL.Y() - hitM.Y()) / hL;
408 fscal xx = tx * tx;
409 fscal yy = ty * ty;
410 fscal xy = tx * ty;
411 fscal cL = c_light * sqrt(1.f + xx + yy);
412
413 auto [Sx, Sy, Sz] = fld.GetDoubleIntegrals(hitM.X(), hitM.Y(), hitM.Z(), hitL.X(), hitL.Y(), hitL.Z());
414
415 JxL4 = cL * (Sx * xy - Sy * (xx + 1.f) + Sz * ty);
416 JyL4 = cL * (Sx * (yy + 1.f) - Sy * xy - Sz * tx);
417
418 fscal a = msM[i3];
419 msX = (1.f + xx) * a;
420 msY = (1.f + yy) * a;
421 }
422
423 fscal JxR4 = 0.;
424 fscal JyR4 = 0.;
425 { // right hit
426 fscal tx = (hitR.X() - hitM.X()) / hR;
427 fscal ty = (hitR.Y() - hitM.Y()) / hR;
428 fscal xx = tx * tx;
429 fscal yy = ty * ty;
430 fscal xy = tx * ty;
431 fscal cL = c_light * sqrt(1.f + xx + yy);
432
433 auto [Sx, Sy, Sz] = fld.GetDoubleIntegrals(hitM.X(), hitM.Y(), hitM.Z(), hitR.X(), hitR.Y(), hitR.Z());
434
435 JxR4 = cL * (Sx * xy - Sy * (xx + 1.f) + Sz * ty);
436 JyR4 = cL * (Sx * (yy + 1.f) - Sy * xy - Sz * tx);
437 }
438
439 fscal qp, Cqp;
440 { // fit q/p
441 fscal d = hR * JxL4 - hL * JxR4;
442 qp = (hL * (hitM.X() - hitR.X()) + hR * (hitL.X() - hitM.X())) / d;
443 Cqp = (hL * hL * hitR.dX2() + (hL - hR) * (hL - hR) * hitM.dX2() + hR * hR * hitL.dX2() + hL * hL * hR * hR * msX)
444 / d / d;
445 }
446
447 fscal x = hitL.X();
448 fscal y = hitL.Y();
449 fscal z = hitL.Z();
450
451 fscal dz01 = 1. / (hitM.Z() - hitL.Z());
452
453 fscal tx = (hitM.X() - hitL.X()) * dz01;
454 fscal Ctx = 1.;
455 fscal chi2x = 0.;
456
457 fscal ty = (hitM.Y() - hitL.Y()) * dz01;
458 fscal Cty = 1.;
459 fscal chi2y = 0.;
460
461
462 { // get chi2 from y fit
463 fscal yL = hitL.Y() - JyL4 * qp;
464 fscal lS = hitL.dY2() + JyL4 * JyL4 * Cqp;
465
466 fscal yM = hitM.Y();
467 fscal mS = hitM.dY2();
468
469 fscal yR = hitR.Y() - JyR4 * qp;
470 fscal rS = hitR.dY2() + JyR4 * JyR4 * Cqp;
471
472 fscal zeta = (hL * (yM - yR) + hR * (yL - yM));
473 fscal c = hL * hL * rS + (hL - hR) * (hL - hR) * mS + hR * hR * lS + hR * hR * hL * hL * msY;
474
475 chi2y = zeta * zeta / c;
476 }
477
478 fscal chi2Tgt = 0.;
479
480 { // chi2 to the target
481
482 auto fldTarget = kf::FieldRegion<fscal>::CopyConvert(kf::FieldRegion<fvec>(fldValueTarget, fldValueL, fldValueM));
483
484 fscal xTarget = target.GetX()[0];
485 fscal yTarget = target.GetY()[0];
486 fscal zTarget = target.GetZ()[0];
487
488 fscal h = (zTarget - z);
489 fscal xx = tx * tx;
490 fscal yy = ty * ty;
491 fscal xy = tx * ty;
492
493 fscal cL = c_light * sqrt(fscal(1.) + xx + yy);
494
495 fscal Sx, Sy, Sz;
496 std::tie(Sx, Sy, Sz) = fldTarget.GetDoubleIntegrals(x, y, z, xTarget, yTarget, zTarget);
497
498 fscal JxTgt4 = cL * (Sx * xy - Sy * (xx + fscal(1.)) + Sz * ty);
499 fscal JyTgt4 = cL * (Sx * (yy + fscal(1.)) - Sy * xy - Sz * tx);
500
501 const kf::MeasurementXy<fvec>& m = frWData.TargetMeasurement();
502
503 fscal zeta0 = x + h * tx + JxTgt4 * qp - xTarget;
504 fscal zeta1 = y + h * ty + JyTgt4 * qp - yTarget;
505
506 fscal S00 = m.Dx2()[0] + JxTgt4 * JxTgt4 * Cqp;
507 fscal S10 = m.Dxy()[0] + JxTgt4 * JyTgt4 * Cqp;
508 fscal S11 = m.Dy2()[0] + JyTgt4 * JyTgt4 * Cqp;
509
510 fscal si = fscal(1.) / (S00 * S11 - S10 * S10);
511
512 fscal S00tmp = S00;
513 S00 = si * S11;
514 S10 = -si * S10;
515 S11 = si * S00tmp;
516
517 chi2Tgt = zeta0 * zeta0 * S00 + fscal(2.) * zeta0 * zeta1 * S10 + zeta1 * zeta1 * S11;
518 }
519
520
521 // TODO: SG: normalize chi2, separate cuts on time and space
522
523 fscal chi2 = chi2x + chi2y;
524
525 if (chi2 > frWData.CurrentIteration()->GetTripletFinalChi2Cut()) {
526 continue;
527 }
528
529 if (!std::isfinite(chi2) || chi2 < 0) {
530 continue;
531 }
532
533 chi2 += chi2Tgt;
534
535 tripletsOut.emplace_back(ihitl, ihitm, ihitr, fIstaL, fIstaM, fIstaR, 0, 0, 0, chi2, qp, Cqp, tx, Ctx, ty, Cty,
536 isMomentumFitted);
537 } //i3
538} // FitTriplets
539
540
542 const SearchWindowMap::SearchWindow& area2D, fscal time, fscal timeRange,
543 const int iSta, const fscal areaExtension, const int maxNhits, const McMatch& mc)
544{
546 collectedHits.clear();
547 collectedHits.reserve(maxNhits);
548
549 const auto& sta = fSetup.GetActiveLayer(iSta);
550 const auto& grid = frWData.Grid(iSta);
551
552 //const fvec maxDZ = frWData.CurrentIteration()->GetMaxDZ();
553
554 fscal areaX = 0.5 * (area2D.xMin + area2D.xMax);
555 fscal areaDx = 0.5 * (area2D.xMax - area2D.xMin);
556 fscal areaY = 0.5 * (area2D.yMin + area2D.yMax);
557 fscal areaDy = 0.5 * (area2D.yMax - area2D.yMin);
558 areaDx = areaExtension * areaDx;
559 areaDy = areaExtension * areaDy;
560
561 fscal dxExtended = areaDx + grid.GetMaxRangeX(); // + maxDZ * kf::utils::fabs(T.Tx()))[0];
562 fscal dyExtended = areaDy + grid.GetMaxRangeY(); // + maxDZ * kf::utils::fabs(T.Ty()))[0];
563 ca::GridArea area(grid, areaX, areaY, dxExtended, dyExtended);
564
565 if constexpr (fDebugCollectHits) {
566 LOG(info) << "search area: x " << areaX << " +-" << areaDx << ", y " << areaY << " +-" << areaDy;
567 }
568 if (fParameters.GetConfig().DevIgnoreHitSearchAreas()) {
570 }
571
572 // loop over station hits (index incremented in condition)
573 for (ca::HitIndex_t ih = 0; area.GetNextObjectId(ih) && ((int) collectedHits.size() < maxNhits);) {
574 if (frWData.IsHitSuppressed(ih)) {
575 continue;
576 }
577
578 const ca::Hit& hit = frWData.Hit(ih);
579 if constexpr (fDebugCollectHits) {
580 LOG(info) << "hit in the search area: " << hit.ToString();
581 LOG(info) << " check the hit.. ";
582 }
583
584
585 if (!mc.IsEmpty()) { // match via MC
586 if (mc != fFramework.GetMcMatchForCaHit(hit.Id())) {
587 if constexpr (fDebugCollectHits) {
588 LOG(info) << " hit mc does not match";
589 }
590 continue;
591 }
592 }
593
594 {
595 float dx = hit.X() - areaX;
596 float dy = hit.Y() - areaY;
597 if (fabs(dx) > areaDx + hit.RangeX() || fabs(dy) > areaDy + hit.RangeY()) {
598 continue;
599 }
600 }
601
602 // check time-boundaries
603
604 //TODO: move hardcoded cuts to parameters
605 if (sta.IsTimeMeasured()) {
606 if (fabs(time - hit.T()) > 1.4 * (timeRange + hit.RangeT())) {
607 if constexpr (fDebugCollectHits) {
608 LOG(info) << " hit time does not match";
609 }
610 continue;
611 }
612 }
613
614 collectedHits.push_back(ih);
615
616 } // loop over the hits in the area
617}
618
619
621 const McMatch& mc)
622{
624
625 if (mc.IsEmpty()) {
626 return -1;
627 }
628
629 const auto& grid = frWData.Grid(iSta);
630
631 fscal areaX = 0.5 * (area2D.xMin + area2D.xMax);
632 fscal areaY = 0.5 * (area2D.yMin + area2D.yMax);
633
634 ca::GridArea area(grid, areaX, areaY, 10000., 10000.);
635
637
638 int iret = -1;
639 double bestDist2 = 1.e10;
640 // loop over station hits (index incremented in condition)
641 for (ca::HitIndex_t ih = 0; area.GetNextObjectId(ih);) {
642 if (frWData.IsHitSuppressed(ih)) {
643 continue;
644 }
645
646 const ca::Hit& hit = frWData.Hit(ih);
647
648 if (mc == fFramework.GetMcMatchForCaHit(hit.Id())) {
649 double dx = areaX - hit.X();
650 double dy = areaY - hit.Y();
651 double dist2 = dx * dx + dy * dy;
652 if (dist2 < bestDist2) {
653 bestDist2 = dist2;
654 iret = ih;
655 }
656 }
657 }
658 return iret;
659}
Tracking Debugger class (implementation)
Macros for the CA tracking algorithm.
Triplet constructor for the CA tracker.
friend fvec sqrt(const fvec &a)
Track fit utilities for the CA tracking based on the Kalman filter.
Generates beam ions for transport simulation.
Class DoubletSearchWindowMap parameterisation for hit search area for doublets in the CA tracking.
SearchWindowMap::SearchWindow GetSearchWindow(float x, float y, float z, float dx, float dy) const
Class for accessing objects in the 2D area that are stored in ca::Grid.
Definition CaGridArea.h:17
bool GetNextObjectId(ca::HitIndex_t &objectId)
look up the next object id in the requested area
Definition CaGridArea.h:92
void DoLoopOverEntireGrid()
debug mode: loop over the entire GetEntries() vector ignoring the search area
Definition CaGridArea.h:103
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
fscal RangeX() const
Get the +/- range of uncertainty of X coordinate.
Definition CaHit.h:126
std::string ToString() const
Simple string representation of the hit class.
Definition CaHit.cxx:17
fscal dX2() const
Get the uncertainty of X coordinate.
Definition CaHit.h:114
fscal Y() const
Get the Y coordinate.
Definition CaHit.h:105
fscal RangeY() const
Get the +/- range of uncertainty of Y coordinate.
Definition CaHit.h:129
fscal RangeT() const
Get the +/- range of uncertainty of time.
Definition CaHit.h:132
fscal T() const
Get the time.
Definition CaHit.h:111
fscal X() const
Get the X coordinate.
Definition CaHit.h:102
HitIndex_t Id() const
Get the hit id.
Definition CaHit.h:135
fscal dY2() const
Get the uncertainty of Y coordinate.
Definition CaHit.h:117
double GetStartX() const
Gets x component of the track vertex [cm].
Definition CaMcTrack.h:187
double GetStartZ() const
Gets z component of the track vertex [cm].
Definition CaMcTrack.h:193
double GetCharge() const
Gets charge [e].
Definition CaMcTrack.h:85
int GetEventId() const
Gets index of MC event containing this track in external data structures.
Definition CaMcTrack.h:97
double GetP() const
Gets absolute momentum [GeV/c].
Definition CaMcTrack.h:148
double GetStartY() const
Gets y component of the track vertex [cm].
Definition CaMcTrack.h:190
A container for all external parameters of the CA tracking algorithm.
void CreateTripletsForHit(Vector< ca::Triplet > &tripletsOut, int istal, int istam, int istar, ca::HitIndex_t ihl)
---— FUNCTIONAL PART ---—
fscal fDefaultMass
mass of the propagated particle [GeV/c2]
const SearchWindowMapContainer & fSwMaps
Search windows.
TripletConstructorSW(const ca::Framework &framework, const ca::Parameters< fvec > &pars, WindowData &wData, const fscal mass, const ca::TrackingMode &mode)
---— Constructors and destructor ---—
void FitTriplets(Vector< ca::Triplet > &tripletsOut)
Fit triplets on station.
int FindClosestHitWithMc(const SearchWindowMap::SearchWindow &area2D, const int iSta, const McMatch &mc)
bool InitStations(int istal, int istam, int istar)
const kf::ActiveLayer< fvec > * fStaM
mid station
bool fIsTargetField
is the magnetic field present at the target
const Parameters< fvec > & fParameters
Object of Framework parameters class.
void CollectHits(Vector< ca::HitIndex_t > &collectedHits, const SearchWindowMap::SearchWindow &area2D, fscal time, fscal timeRange, const int iSta, const fscal areaExtension, const int maxNhits, const McMatch &mc)
const cbm::algo::kf::Setup< fvec > & fSetup
Reference to the setup.
const kf::ActiveLayer< fvec > * fStaR
right station
const cbm::algo::kf::Field< fvec > & fField
Reference to field.
void SuppressDoubletClones()
Find the doublets. Reformat data in the portion of doublets.
const kf::ActiveLayer< fvec > * fStaL
left station
const ca::Framework & fFramework
Reference to the Framework object.
ca::HitIndex_t fIhitL
index of the left hit in fAlgo->fWindowHits
Class TripletSearchWindowMap parameterisation for hit search area for Triplets in the CA tracking.
std::tuple< SearchWindowMap::SearchWindow, float > GetSearchWindowAndMs(float x1, float y1, float z1, float dx1, float dy1, float x2, float y2, float z2, float dx2, float dy2) const
void shrink(std::size_t count)
Reduces the vector to a given size.
Definition CaVector.h:164
void push_back(Tinput value)
Pushes back a value to the vector.
Definition CaVector.h:190
void reserve(std::size_t count)
Reserves a new size for the vector.
Definition CaVector.h:176
void emplace_back(Tinput &&... value)
Creates a parameter in the end of the vector.
Definition CaVector.h:210
Container for internal data, processed on a single time window.
static Debugger & Instance()
Instance.
virtual void FillNtuple(const char *name, float v[])=0
Add an entry to ntuple.
virtual void AddNtuple(const char *name, const char *varlist)=0
Set new ntuple.
Magnetic field region, corresponding to a hit triplet.
static FieldRegion CopyConvert(const FieldRegion< I > &other)
Creates a converted copy of the field with a different floating point type.
The class describes a 2D - measurement (x, y) in XY coordinate system.
TODO: SZh 8.11.2022: add selection of parameterisation.
Definition CaBranch.h:14
kf::fscal fscal
Definition CaSimd.h:14
unsigned int HitIndex_t
Index of ca::Hit.
Definition CaHit.h:27
constexpr auto SpeedOfLight
Speed of light [cm/ns].
Definition KfDefs.h:207
int GetNofLinks() const
Definition CaMcMatch.h:59
int GetLink(int i) const
Definition CaMcMatch.h:68
bool IsEmpty() const
Definition CaMcMatch.h:87