CbmRoot
Loading...
Searching...
No Matches
CaSearchWindowMapContainerFactory.h
Go to the documentation of this file.
1/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Sergei Zharko [committer] */
4
10
11#pragma once
12
13#include "CaConfig.h"
14#include "CaDefs.h"
16#include "KfFieldRegion.h"
17#include "KfSetup.h"
18#include "KfTrackKalmanFilter.h"
19
20#include <vector>
21
22#include <fmt/format.h>
23
24namespace cbm::algo::ca
25{
29 public:
35 template<typename F>
36 static SearchWindowMapContainer Create(const kf::Setup<F>& actSetup, //
37 const kf::FieldFn_t& fieldFn, //
38 const ca::Config& config)
39 {
42
43 constexpr int MaxNofTripletGaps = SearchWindowMapContainer::kMaxNofTripletGaps;
44
45 // FIXME: Define these parameters in ca::Config::SwFactory
46 constexpr int BinsX{10};
47 constexpr int BinsY{20};
48 constexpr double MaxExtrapolationStep{10.}; // [cm]
49
50 auto field = kf::FieldRegion<double>(actSetup.GetField().GetFieldType(), fieldFn);
51 auto target = kf::Target<double>(actSetup.GetTarget());
52 auto stations = std::vector<kf::ActiveLayer<double>>{};
53 stations.reserve(actSetup.GetNofLayers());
54 for (const auto& layer : actSetup.GetActiveLayers()) { // Note: copy layers in double precision
55 stations.emplace_back(layer);
56 }
57
58 {
59 // Validate input
60 // FIXME: maybe move to another function (Validate(config, actSetup, ....))
61 // 1. Check, if first station is far enough from the target
62 double zFstSta = Cast<F, double>(actSetup.GetActiveLayer(0).GetZref());
63 if (zFstSta - target.GetZ() < 1.e-2) {
64 throw std::runtime_error(fmt::format("The first station (z={}) is too close to or before the target (z={})",
65 zFstSta, target.GetZ()));
66 }
67 }
68
69 // Doublet search window maps
70 for (int iIter = 0; iIter < config.GetNofIterations(); ++iIter) {
71 const auto& iter = config.GetIteration(iIter);
72 for (int iStaM = 0; iStaM < actSetup.GetNofLayers(); ++iStaM) {
73 const auto& staM = stations[iStaM]; // middle station
74 for (int iGap = 0; iGap < MaxNofTripletGaps; ++iGap) {
75 auto& swMap = res.DoubletSw(iIter, iStaM, iGap);
76 swMap.Init(target.GetX(), target.GetY(), target.GetZ(), //
77 staM.GetZref(), //
78 staM.GetXmin(), staM.GetXmax(), BinsX, //
79 staM.GetYmin(), staM.GetYmax(), BinsY);
80
81 // left station
82 int iStaL = iStaM - iGap - 1;
83 if (iStaL < 0) continue;
84 if (iGap > iter.GetMaxStationGap()) continue;
85 const auto& staL = stations[iStaL];
86
87 // 0.3 -> 0.333 ?
88 double stepXm = 0.3 * (staM.GetXmax() - staM.GetXmin()) / BinsX;
89 double stepYm = 0.3 * (staM.GetYmax() - staM.GetYmin()) / BinsY;
90 for (double xm = staM.GetXmin(); xm <= staM.GetXmax(); xm += stepXm) {
91 for (double ym = staM.GetYmin(); ym <= staM.GetYmax(); ym += stepYm) {
92 // Extrapolate a track from the target area through the left station
93 const double dzm = staM.GetZref() - target.GetZ();
94
96 fit.SetMaxExtrapolationStep(MaxExtrapolationStep);
98 fit.Linearization().qp = 0.; // zero linearization with qp = 0
99
100 // Initial track parameters (at target.GetZ())
101 auto& T = fit.Tr();
102 T.X() = target.GetX();
103 T.Y() = target.GetY();
104 T.Z() = target.GetZ();
105 T.Tx() = (xm - target.GetX()) / dzm;
106 T.Ty() = (ym - target.GetY()) / dzm;
107 T.Qp() = 0.;
108 T.Time() = 0.;
110
111 const double slopeVar = iter.GetMaxSlopePV() * iter.GetMaxSlopePV() / 9.;
112 const double maxQp = iter.GetMaxQp();
113 const double qpVar = maxQp * maxQp / 9.;
114
115 T.ResetErrors(0., 0., slopeVar, slopeVar, qpVar, 0., 1.e+10);
116 T.InitVelocityRange(1. / iter.GetMaxQp());
117 T.C00() = iter.GetTargetPosSigmaX() * iter.GetTargetPosSigmaX();
118 T.C10() = 0.;
119 T.C11() = iter.GetTargetPosSigmaY() * iter.GetTargetPosSigmaY();
120
121 // Extrapolate to the left station (to staL.GetZref())
122 fit.ExtrapolateLineInField(staL.GetZref(), field);
123
124 // Add the left hit to the covariance matrix (NOTE: initial hit errors are ignored)
125 fit.FilterXY(kf::MeasurementXy<double>(T.X(), T.Y(), 1.e-8, 1.e-8, 0., 1., 1.));
126
127 // Add material effects
128 fit.Linearization().qp = maxQp;
129 fit.MultipleScattering(actSetup.GetMaterial(iStaL).GetThicknessX0(T.GetX(), T.GetY()));
130 fit.Linearization().qp = 0.;
131
132 // Extrapolate to the middle station (to staM.GetZref())
133 fit.ExtrapolateLineInField(staM.GetZref(), field);
134
135 double dxM = 3.5 * std::sqrt(T.C00());
136 double dyM = 3.5 * std::sqrt(T.C11());
137 assert(std::isfinite(dxM));
138 assert(std::isfinite(dyM));
139 swMap.GetMap().Update(xm, ym, dxM, dyM, 0.);
140 } // loop over ym
141 } // loop over xm
142 } // loop over iGap
143 } // loop over iStaM
144 } // loop over iIter
145
146
147 // Triplet search window maps
148 for (int iIter = 0; iIter < config.GetNofIterations(); ++iIter) {
149 const auto& iter = config.GetIteration(iIter);
150 for (int iStaR = 0; iStaR < actSetup.GetNofLayers(); ++iStaR) {
151 const auto& staR = stations[iStaR];
152 for (int iGapL = 0; iGapL < MaxNofTripletGaps; ++iGapL) {
153 for (int iGapM = 0; iGapM < MaxNofTripletGaps; ++iGapM) {
154 auto& swMap = res.TripletSw(iIter, iStaR, iGapL, iGapM);
155 swMap.Init(target.GetX(), target.GetY(), target.GetZ(), //
156 staR.GetZref(), //
157 staR.GetXmin(), staR.GetXmax(), BinsX, //
158 staR.GetYmin(), staR.GetYmax(), BinsY);
159
160 int iStaL = iStaR - iGapL - 2;
161 int iStaM = iStaR - iGapM - 1;
162 if (iStaL < 0 || iStaL >= iStaM) continue;
163 if (iGapL > iter.GetMaxStationGap() || iGapM > iter.GetMaxStationGap()) continue;
164
165 const auto& staL = stations[iStaL];
166 const auto& staM = stations[iStaM];
167
168 // 0.3 -> 0.333 ?
169 double stepXr = 0.3 * (staR.GetXmax() - staR.GetXmin()) / BinsX;
170 double stepYr = 0.3 * (staR.GetYmax() - staR.GetYmin()) / BinsY;
171
172 for (double xr = staR.GetXmin(); xr <= staR.GetXmax(); xr += stepXr) {
173 for (double yr = staR.GetYmin(); yr <= staR.GetYmax(); yr += stepYr) {
174 // track from the target area
175 const double dzr = staR.GetZref() - target.GetZ();
176
178 fit.SetMaxExtrapolationStep(MaxExtrapolationStep);
179 fit.SetParticleMass(iter.GetElectronFlag() ? constants::phys::ElectronMass
181 fit.Linearization().qp = 0.;
182
183 // Initial track parameters (z = target.GetZ())
184 auto& T = fit.Tr();
185 T.X() = target.GetX();
186 T.Y() = target.GetY();
187 T.Z() = target.GetZ();
188 T.Tx() = (xr - target.GetX()) / dzr;
189 T.Ty() = (yr - target.GetY()) / dzr;
190 T.Qp() = 0.;
191 T.Time() = 0.;
193
194 const double slopeVar = iter.GetMaxSlopePV() * iter.GetMaxSlopePV() / 9.;
195 const double maxQp = iter.GetMaxQp();
196 const double qpVar = maxQp * maxQp / 9.;
197
198 T.ResetErrors(0., 0., slopeVar, slopeVar, qpVar, 0., 1.e+10);
199 T.InitVelocityRange(1. / maxQp);
200 T.C00() = iter.GetTargetPosSigmaX() * iter.GetTargetPosSigmaX();
201 T.C10() = 0.;
202 T.C11() = iter.GetTargetPosSigmaY() * iter.GetTargetPosSigmaY();
203
204 // Extrapolate to the left station (z = staL.GetZref())
205 fit.ExtrapolateLineInField(staL.GetZref(), field);
206
207 // Add the left hit XY-measurement without errors
208 fit.FilterXY(kf::MeasurementXy<double>(T.X(), T.Y(), 1.e-8, 1.e-8, 0., 1., 1.));
209
210 // Add material effects
211 fit.Linearization().qp = maxQp;
212 fit.MultipleScattering(actSetup.GetMaterial(iStaL).GetThicknessX0(T.GetX(), T.GetY()));
213 fit.Linearization().qp = 0.;
214 T.Qp() = 0.;
215
216 // Extrapolate to the middle station (z = staM.GetZref())
217 fit.ExtrapolateLineInField(staM.GetZref(), field);
218
219 // Add the middle hit without errors to the covariance matrix
220 fit.FilterXY(kf::MeasurementXy<double>(T.X(), T.Y(), 1.e-8, 1.e-8, 0., 1., 1.));
221
222 // Add material effects
223 fit.Linearization().qp = maxQp;
224 double radThick = actSetup.GetMaterial(iStaM).GetThicknessX0(T.GetX(), T.GetY());
225 {
226 double dz = staR.GetZref() - staM.GetZref();
227 double rX = T.GetX() + dz * T.Tx();
228 double rY = T.GetY() + dz * T.Ty();
229 radThick += actSetup.GetMaterial(iStaR).GetThicknessX0(rX, rY);
230 }
231 fit.MultipleScattering(radThick);
232
233 double ms;
234 {
235 double tx = T.Tx();
236 double ty = T.Ty();
237 double t = sqrt(1. + tx * tx + ty * ty);
238 double lg = 0.0136 * (1. + 0.038 * log(radThick * t));
239 if (lg < 0.) lg = 0.;
240 double qp = maxQp / 7.; // ??? correction is needed some reason. Investigate.
241 double s0 = lg * qp * t;
242 double mass = iter.GetElectronFlag() ? constants::phys::ElectronMass : constants::phys::MuonMass;
243 ms = (1. + mass * mass * qp * qp) * s0 * s0 * t * radThick;
244 }
245 fit.Linearization().qp = 0.;
246 T.Qp() = 0.;
247
248 // Extrapolate to the right station (z = staR.GetZref())
249 fit.ExtrapolateLineInField(staR.GetZref(), field);
250
251 double dxR = 3.5 * std::sqrt(T.C00());
252 double dyR = 3.5 * std::sqrt(T.C11());
253 assert(std::isfinite(dxR));
254 assert(std::isfinite(dyR));
255 swMap.GetMap().Update(xr, yr, dxR, dyR, ms);
256 } // loop over yr
257 } // loop over xr
258 } // loop over iGapM
259 } // loop over iGapL
260 } // loop over iStaR
261 } // loop over iIter
262
263 return res;
264 }
265 };
266} // namespace cbm::algo::ca
Configuration for the CA tracking algorithm (source)
Compile-time constants definition for the CA tracking algorithm.
A container for search window maps.
Magnetic flux density interpolation along the track vs. z-coordinate (header)
Setup representation for the Kalman-filter framework (header)
friend fvec sqrt(const fvec &a)
friend fvec log(const fvec &a)
Track fit utilities for the CA tracking based on the Kalman filter.
EFieldType GetFieldType() const
Gets field type.
Definition KfField.h:372
Configuration of the CA tracking (excluding geometry)
Definition CaConfig.h:36
int GetNofIterations() const
Gets number of CA iterations.
Definition CaConfig.h:150
const Iteration & GetIteration(int iIteration) const
Gets an iteraion.
Definition CaConfig.h:154
void Init(float targetX, float targetY, float targetZ, float refZ, float xMin, float xMax, int nBinsX, float yMin, float yMax, int nBinsY)
Constructor.
A factory class for seach window map container.
static SearchWindowMapContainer Create(const kf::Setup< F > &actSetup, const kf::FieldFn_t &fieldFn, const ca::Config &config)
Creates the map.
static constexpr int kMaxNofTripletGaps
Max number of gaps in triplets.
DoubletSearchWindowMap & DoubletSw(int iIter, int iSta, int iGap)
Mutable accessor to doublet search window map.
TripletSearchWindowMap & TripletSw(int iIter, int iSta, int iGapL, int iGapM)
Mutual accessor to triplet search window map.
void Init(float targetX, float targetY, float targetZ, float refZ, float xMin, float xMax, int nBinsX, float yMin, float yMax, int nBinsY)
Constructor.
Magnetic field region, corresponding to a hit triplet.
I GetThicknessX0(const I &x, const I &y) const
Gets material thickness in units of radiational length X0.
The class describes a 2D - measurement (x, y) in XY coordinate system.
KF-framework representation of the detector setup.
Definition KfSetup.h:37
const Field< F > & GetField() const
Makes an instance of the field depending on the template parameter.
Definition KfSetup.h:132
const auto & GetActiveLayers() const
Gets active layers container.
Definition KfSetup.h:118
const Target< F > & GetTarget() const
Gets target.
Definition KfSetup.h:163
int GetNofLayers() const
Gets number of geometry layers.
Definition KfSetup.h:152
const MaterialMap & GetMaterial(int iLayer) const
Gets material layer.
Definition KfSetup.h:136
const ActiveLayer< F > & GetActiveLayer(int iLayer) const
Gets active layer instance.
Definition KfSetup.h:115
A geometry layer in the target region.
Definition KfTarget.h:25
void SetMaxExtrapolationStep(double step)
set max extrapolation step [cm]
void MultipleScattering(DataT radThick, DataT tx0, DataT ty0, DataT qp0)
apply multiple scattering correction to the track with the given Qp0
void SetParticleMass(DataT mass)
set particle mass for the fit
kf::TrackParam< DataT > & Tr()
void FilterXY(const kf::MeasurementXy< DataT > &m, bool skipUnmeasuredCoordinates=false)
filter the track with the XY measurement
void ExtrapolateLineInField(DataT z_out, const kf::FieldRegion< DataT > &F)
extrapolate the track to the given Z using linearization at the straight line
T X() const
Gets x position [cm].
constexpr fscal ElectronMass
Electron mass [GeV/c2].
Definition CaDefs.h:93
constexpr fscal SpeedOfLightInv
Inverse speed of light [ns/cm].
Definition CaDefs.h:96
constexpr fscal MuonMass
Particle masses etc used for the track fit, fscal precision.
Definition CaDefs.h:90
TODO: SZh 8.11.2022: add selection of parameterisation.
Definition CaBranch.h:14
DataOut Cast(const DataT &val)
Converts a value of type DataT to type DataOut.
Definition KfUtils.h:212
std::function< std::tuple< double, double, double >(double, double, double)> FieldFn_t
Magnetic field function type Signature: tuple<Bx, By, Bz>(x, y, z);.
Definition KfDefs.h:169