25 , fSetup(fParameters.GetActiveSetup())
58 const int sta0 = sta1 / 2;
60 assert(0 <= sta0 && sta0 < sta1 && sta1 <
fParameters.GetNstationsActive());
73 sta0 = (sta1 <= 0) ? 0 : std::clamp(sta0, 0, sta1 - 1);
76 assert(0 <= sta0 && sta0 < sta1 && sta1 < sta2 && sta2 <
fParameters.GetNstationsActive());
118 T.Tx() = (hitl.X() -
fParameters.GetTargetPositionX()) * dzli;
119 T.Ty() = (hitl.Y() -
fParameters.GetTargetPositionY()) * dzli;
126 const fvec txErr2 = maxSlopePV * maxSlopePV /
fvec(9.);
127 const fvec qpErr2 = maxQp * maxQp /
fvec(9.);
129 T.ResetErrors(1., 1., txErr2, txErr2, qpErr2, (
fStaL->timeInfo ? hitl.dT2() : 1.e6), 1.e10);
132 T.C00() = hitl.dX2();
133 T.C10() = hitl.dXY();
134 T.C11() = hitl.dY2();
136 T.NdfTime() = (
fStaL->timeInfo ? 0 : -1);
168 auto FindDoubletHits = [&]() {
169 const bool matchMc =
fParameters.DevIsMatchDoubletsViaMc();
172 if (iMC < 0 && matchMc) {
207 auto it2 = hitsM.begin();
208 for (
auto it = hitsM.begin(); it != hitsM.end(); it++) {
240 const fscal tt = T2.
Vi()[0] *
sqrt(1. + tx * tx + ty * ty);
242 for (
auto itClone = it + 1; itClone != hitsM.end(); itClone++) {
244 const int indClone = *itClone;
247 const fscal dz = hitClone.
Z() - T2.
Z()[0];
250 const fscal dt = T2.
Time()[0] + tt * dz - hitClone.
T();
251 if (!(fabs(dt) <= 3.5 *
sqrt(T2.
C55()[0]) + hitClone.
RangeT())) {
256 const fscal dx = T2.
GetX()[0] + tx * dz - hitClone.
X();
257 if (!(fabs(dx) <= 3.5 *
sqrt(T2.
C00()[0]) + hitClone.
RangeX())) {
261 const fscal dy = T2.
Y()[0] + ty * dz - hitClone.
Y();
262 if (!(fabs(dy) <= 3.5 *
sqrt(T2.
C11()[0]) + hitClone.
RangeY())) {
282 hitsM.
shrink(std::distance(hitsM.begin(), it2));
302 const int maxTriplets = hitsM_2.size() *
fParameters.GetMaxTripletPerDoublets();
312 for (
unsigned int i2 = 0; i2 < hitsM_2.size(); i2++) {
324 const int ih0 = ihit[0];
325 const int ih1 = ihit[1];
329 LOG(info) <<
"\n====== Extrapolated Doublet : "
331 <<
fIstaM <<
"/" << ih1 <<
" " <<
fIstaR <<
"/?} xyz: {" << h0.
X() <<
" " << h0.
Y() <<
" " << h0.
Z()
332 <<
"}, {" << h1.
X() <<
" " << h1.
Y() <<
" " << h1.
Z() <<
"} chi2 " << T2.
GetChiSq()[0] <<
" ndf "
334 LOG(info) <<
" extr. track: " << T2.
ToString(0);
340 auto rejectDoublet = [&]() ->
bool {
344 if (T2.
C00()[0] < 0 || T2.
C11()[0] < 0 || T2.
C22()[0] < 0 || T2.
C33()[0] < 0 || T2.
C55()[0] < 0) {
347 if (fabs(T2.
Tx()[0]) > maxSlope) {
350 if (fabs(T2.
Ty()[0]) > maxSlope) {
354 int indM = hitsM_2[i2];
362 const bool isDoubletGood = !rejectDoublet();
366 LOG(info) <<
" extrapolated doublet accepted";
369 LOG(info) <<
" extrapolated doublet rejected";
370 LOG(info) <<
"======== end of extrapolated doublet ==== \n";
374 if (!isDoubletGood) {
381 if (collectedHits.size() >=
fParameters.GetMaxTripletPerDoublets()) {
387 collectedHits.clear();
390 LOG(info) <<
" collected " << collectedHits.size() <<
" hits on the right station ";
396 LOG(info) <<
" hit " << ihit <<
" " <<
h.ToString();
400 LOG(info) <<
" the hit is suppressed";
409 LOG(info) <<
"======== end of extrapolated doublet ==== \n";
416 constexpr int nIterations = 2;
421 assert(hitsM.size() == hitsR.size());
424 tracks.reserve(hitsM.size());
443 const bool isMomentumFitted = ((
fStaL->fieldStatus != 0) || (
fStaM->fieldStatus != 0) || (
fStaR->fieldStatus != 0));
444 const fvec ndfTrackModel = 4 + (isMomentumFitted ? 1 : 0);
446 for (
size_t i3 = 0; i3 < hitsM.size(); ++i3) {
458 if ((mc1 != mc2) || (mc1 != mc3)) {
466 fscal x[NHits],
y[NHits], z[NHits], t[NHits];
470 for (
int ih = 0; ih < NHits; ++ih) {
487 fvec tx[3] = {(
x[1] -
x[0]) / (z[1] - z[0]), (
x[2] -
x[0]) / (z[2] - z[0]), (
x[2] -
x[1]) / (z[2] - z[1])};
488 fvec ty[3] = {(
y[1] -
y[0]) / (z[1] - z[0]), (
y[2] -
y[0]) / (z[2] - z[0]), (
y[2] -
y[1]) / (z[2] - z[1])};
490 for (
int ih = 0; ih < NHits; ++ih) {
491 fvec dz = (sta[ih].
fZ - z[ih]);
495 fld.Set(B[0], sta[0].fZ, B[1], sta[1].fZ, B[2], sta[2].fZ);
502 fvec dz01 = 1. / (z[1] - z[0]);
503 T.Tx() = (
x[1] -
x[0]) * dz01;
504 T.Ty() = (
y[1] -
y[0]) * dz01;
510 for (
int iiter = 0; iiter < nIterations; ++iiter) {
512 auto fitTrack = [&](
int startIdx,
int endIdx,
int step,
kf::FitDirection direction) {
515 fit.
Qp0()(fit.
Qp0() > maxQp) = maxQp;
516 fit.
Qp0()(fit.
Qp0() < -maxQp) = -maxQp;
526 T.ResetErrors(1., 1., 1., 1., 100., (sta[ih0].timeInfo ? dt2[ih0] : 1.e6), 1.e2);
527 T.C00() = mxy[ih0].
Dx2();
528 T.C10() = mxy[ih0].
Dxy();
529 T.C11() = mxy[ih0].
Dy2();
531 T.Ndf() = -ndfTrackModel + 2;
532 T.NdfTime() = sta[ih0].
timeInfo ? 0 : -1;
538 for (
int ih = startIdx + step; ih != endIdx; ih += step) {
540 auto radThick =
fSetup.GetMaterial(ista[ih]).GetThicknessX0(T.X(), T.Y());
551 if (iiter == nIterations - 1)
break;
567 if (1 || (mc1 >= 0) && (mc1 == mc2) && (mc1 == mc3)) {
572 LOG(info) <<
"== fitted triplet: "
574 <<
fIstaM <<
"/" << ih1 <<
" " <<
fIstaR <<
"/" << ih2 <<
"} xyz: {" << h0.
X() <<
" " << h0.
Y()
575 <<
" " << h0.
Z() <<
"}, {" << h1.
X() <<
" " << h1.
Y() <<
" " << h1.
Z() <<
"}, {" << h2.
X() <<
", "
576 << h2.
Y() <<
", " << h2.
Z() <<
"} chi2 " << T.GetChiSq()[0] <<
" ndf " << T.Ndf()[0] <<
" chi2time "
577 << T.ChiSqTime()[0] <<
" ndfTime " << T.NdfTime()[0];
599 bool isMomentumFitted = ((
fStaL->fieldStatus != 0) || (
fStaM->fieldStatus != 0) || (
fStaR->fieldStatus != 0));
602 tripletsOut.
reserve(hitsM.size());
604 for (
size_t i3 = 0; i3 < hitsM.size(); ++i3) {
627 if (!std::isfinite(chi2) || chi2 < 0) {
639 tripletsOut.
emplace_back(ihitl, ihitm, ihitr,
fIstaL,
fIstaM,
fIstaR, 0, 0, 0, chi2, qp, Cqp, T3.
Tx()[0],
640 T3.
C22()[0], T3.
Ty()[0], T3.
C33()[0], isMomentumFitted);
646 const int iSta,
const double chi2Cut,
const int iMC,
const int maxNhits)
649 collectedHits.clear();
650 collectedHits.
reserve(maxNhits);
659 const fvec Pick_m22 = (
fvec(chi2Cut) - T.GetChiSq());
660 const fscal timeError2 = T.C55()[0];
661 const fscal time = T.Time()[0];
666 (sqrt(Pick_m22 * T.C00()) + grid.GetMaxRangeX() + maxDZ *
kf::utils::fabs(T.Tx()))[0],
667 (sqrt(Pick_m22 * T.C11()) + grid.GetMaxRangeY() + maxDZ *
kf::utils::fabs(T.Ty()))[0]);
669 LOG(info) <<
"search area: " << T.X()[0] <<
" " << T.Y()[0] <<
" "
670 << (
sqrt(Pick_m22 * T.C00()) + grid.GetMaxRangeX() + maxDZ *
kf::utils::fabs(T.Tx()))[0] <<
" "
686 LOG(info) <<
"hit in the search area: " << hit.
ToString();
687 LOG(info) <<
" check the hit.. ";
693 LOG(info) <<
" hit mc does not match";
702 if ((sta.
timeInfo) && (T.NdfTime()[0] >= 0)) {
703 if (fabs(time - hit.
T()) > 1.4 * (3.5 * sqrt(timeError2) + hit.
RangeT())) {
705 LOG(info) <<
" hit time does not match";
718 const fscal dY = hit.
Y() -
y[0];
720 if (fabs(dY) > dy_est) {
722 LOG(info) <<
" hit Y does not match";
730 const fscal dX = hit.
X() -
x[0];
732 if (fabs(dX) > dx_est) {
734 LOG(info) <<
" hit X does not match";
747 if (chi2x[0] > chi2Cut) {
749 LOG(info) <<
" hit chi2X is too large";
753 if (chi2u[0] > chi2Cut) {
755 LOG(info) <<
" hit chi2U is too large";
761 LOG(info) <<
" hit passed all the checks";
Macros for the CA tracking algorithm.
#define CBMCA_DEBUG_ASSERT(v)
Triplet constructor for the CA tracker.
friend fvec sqrt(const fvec &a)
Track fit utilities for the CA tracking based on the Kalman filter.
Data class with information on a STS local track.
static int GetMcTrackIdForCaHit(int iHit)
Gets number of stations before the pipe (MVD stations in CBM)
static int GetMcTrackIdForWindowHit(int iGridHit)
Get mc track ID for a hit (debug tool)
Class for accessing objects in the 2D area that are stored in ca::Grid.
bool GetNextObjectId(ca::HitIndex_t &objectId)
look up the next object id in the requested area
void DoLoopOverEntireGrid()
debug mode: loop over the entire GetEntries() vector ignoring the search area
ca::Hit class describes a generic hit for the CA tracker
fscal Z() const
Get the Z coordinate.
fscal RangeX() const
Get the +/- range of uncertainty of X coordinate.
fscal dT2() const
Get the uncertainty of time.
std::string ToString() const
Simple string representation of the hit class.
fscal dXY() const
Get the X/Y covariance.
fscal dX2() const
Get the uncertainty of X coordinate.
fscal Y() const
Get the Y coordinate.
fscal RangeY() const
Get the +/- range of uncertainty of Y coordinate.
fscal RangeT() const
Get the +/- range of uncertainty of time.
fscal T() const
Get the time.
fscal X() const
Get the X coordinate.
HitIndex_t Id() const
Get the hit id.
fscal dY2() const
Get the uncertainty of Y coordinate.
float GetTripletChi2Cut() const
Gets triplet chi2 upper cut.
float GetMaxSlope() const
Gets max slope (tx\ty) in 3D hit position of a triplet.
bool GetElectronFlag() const
flag check: electrons/positrons - true, heavy charged - false
float GetDoubletChi2Cut() const
Gets doublet chi2 upper cut.
float GetTripletFinalChi2Cut() const
Gets triplet chi2 upper cut.
bool GetTrackFromTripletsFlag() const
float GetMaxQp() const
Gets max considered q/p for tracks.
float GetMaxDZ() const
Gets correction for accounting overlaping and iff z.
const std::string & GetName() const
Gets the name of the iteration.
float GetMaxSlopePV() const
Gets max slope (tx\ty) in primary vertex.
A container for all external parameters of the CA tracking algorithm.
DataT fZ
z position of station [cm]
int timeInfo
flag: if time information can be used
kf::FieldSlice< DataT > fieldSlice
Magnetic field near the station.
static constexpr bool fDebugCollectHits
const cbm::algo::kf::Setup< fvec > & fSetup
Reference to the setup.
const Parameters< fvec > & fParameters
Object of Framework parameters class.
int fIstaR
right station index
kf::FieldRegion< fvec > fFldL
int fIstaM
middle station index
void SelectTriplets(Vector< ca::Triplet > &tripletsOut)
Select good triplets.
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]
void CollectHits(Vector< ca::HitIndex_t > &collectedHits, kf::TrackKalmanFilter< fvec > &fit, const int iSta, const double chi2Cut, const int iMC, const int maxNhits)
static constexpr bool fDebugDublets
static constexpr bool fDebugTriplets
const ca::Station< fvec > * fFld0Sta[2]
const ca::Station< fvec > * fFld1Sta[3]
bool InitStations(int istal, int istam, int istar)
void FindDoublets(kf::TrackKalmanFilter< fvec > &fit)
Find the doublets. Reformat data in the portion of doublets.
TripletConstructor(const ca::Parameters< fvec > &pars, WindowData &wData, const fscal mass, const ca::TrackingMode &mode)
---— Constructors and destructor ---—
void FindTriplets()
Find triplets on station.
ca::TrackingMode fTrackingMode
const ca::Station< fvec > * fStaR
right station
int fIstaL
left station index
ca::HitIndex_t fIhitL
index of the left hit in fAlgo->fWindowHits
const ca::Station< fvec > * fStaL
left station
const ca::Station< fvec > * fStaM
mid station
bool fIsTargetField
is the magnetic field present at the target
void shrink(std::size_t count)
Reduces the vector to a given size.
void push_back(Tinput value)
Pushes back a value to the vector.
void reserve(std::size_t count)
Reserves a new size for the vector.
void emplace_back(Tinput &&... value)
Creates a parameter in the end of the vector.
Container for internal data, processed on a single time window.
HitIndex_t & HitStartIndexOnStation(int iStation)
Index of the first hit on the station.
ca::Grid & Grid(int iStation)
Gets grid for station index.
void SuppressHit(int iHit)
Set hit suppression flag.
const Iteration * CurrentIteration() const
Accesses current iteration.
kf::FieldValue< fvec > & TargB()
Accesses magnetic field in starting point (target or first station)
uint8_t IsHitSuppressed(int iHit) const
Gets hit suppression flag.
kf::MeasurementXy< fvec > & TargetMeasurement()
Measurement of the target with the uncertainty.
ca::Hit & Hit(int iHit)
Gets hit by index.
Magnetic field region, corresponding to a hit triplet.
void Set(const FieldValue< T > &b0, const T &z0, const FieldValue< T > &b1, const T &z1, const FieldValue< T > &b2, const T &z2)
Interpolates the field by three nodal points with the second order polynomial.
constexpr FieldValue< T > GetFieldValue(const T &x, const T &y) const
Gets field value at a point on the transverse plane.
Magnetic flux density vector.
void Set(const I &bx, const I &by, const I &bz)
Constructor from components.
The class describes a 2D - measurement (x, y) in XY coordinate system.
void Extrapolate(DataT z, const kf::FieldRegion< DataT > &F)
void FilterWithTargetAtLine(DataT targZ, const kf::MeasurementXy< DataT > &targXYInfo, const kf::FieldRegion< DataT > &F)
add target measuremet to the track using linearisation at a straight line
void SetMask(const DataTmask &m)
std::pair< DataT, DataT > ExtrapolateLineYdY2(DataT z_out) const
static std::tuple< DataT, DataT > GetChi2XChi2U(kf::MeasurementXy< DataT > m, DataT x, DataT y, DataT C00, DataT C10, DataT C11)
git two chi^2 components of the track fit to measurement
void FilterXY(const kf::MeasurementXy< DataT > &m, bool skipUnmeasuredCoordinates=false)
filter the track with the XY measurement
void ExtrapolateLineNoField(DataT z_out)
extrapolate the track to the given Z assuming no magnetic field
kf::TrackParam< DataT > & Tr()
void MultipleScattering(DataT radThick, DataT tx0, DataT ty0, DataT qp0)
apply multiple scattering correction to the track with the given Qp0
void EnergyLossCorrection(DataT radThick, FitDirection direction)
DataT ExtrapolateLineDxy(DataT z_out) const
std::pair< DataT, DataT > ExtrapolateLineXdX2(DataT z_out) const
void FilterTime(DataT t, DataT dt2, const DataTmask &m)
filter the track with the time measurement
void SetParticleMass(DataT mass)
set particle mass for the fit
void SetTrack(const kf::TrackParam< T > &t)
void ExtrapolateLine(DataT z_out, const kf::FieldRegion< DataT > &F)
extrapolate the track to the given Z using linearization at the straight line
T C00() const
Individual getters for covariance matrix elements.
T Ndf() const
Gets NDF of track fit model.
T Vi() const
Gets inverse velocity [ns/cm].
T NdfTime() const
Gets NDF of time measurements.
T ChiSq() const
Gets Chi-square of track fit model.
T Tx() const
Gets slope along x-axis.
T ChiSqTime() const
Gets Chi-square of time measurements.
T GetQp() const
Gets charge over momentum [ec/GeV].
T Y() const
Gets y position [cm].
T GetChiSqTime() const
Gets Chi-square of time measurements.
T Qp() const
Gets charge over momentum [ec/GeV].
T Z() const
Gets z position [cm].
T Time() const
Gets time [ns].
T GetChiSq() const
Gets Chi-square of track fit model.
T Ty() const
Gets slope along y-axis.
std::string ToString(int i=-1) const
Prints parameters to a string.
T GetX() const
Gets x position [cm].
constexpr fscal ElectronMass
Electron mass [GeV/c2].
constexpr fscal SpeedOfLightInv
Inverse speed of light [ns/cm].
TODO: SZh 8.11.2022: add selection of parameterisation.
class cbm::algo::ca::WindowData _fvecalignment
unsigned int HitIndex_t
Index of ca::Hit.
TrackParam< fvec > TrackParamV