21#include <TGeoGlobalMagField.h>
34constexpr double TrackFitter::SDefaultChamberZ[10];
35constexpr double TrackFitter::SChamberThicknessInX0[10];
42 if (TGeoGlobalMagField::Instance()->GetField()) {
48 "A-A",
"$(O2_ROOT)/share/Common/maps/mfchebKGI_sym.root");
49 TGeoGlobalMagField::Instance()->SetField(field);
50 TGeoGlobalMagField::Instance()->Lock();
57 std::list<TrackParam>::reverse_iterator* itStartingParam,
58 bool skipLocalChi2Calculation)
68 auto itParam(track.
rbegin());
69 if (itStartingParam !=
nullptr) {
71 if (*itStartingParam == track.
rend()) {
74 itParam = *itStartingParam;
78 auto itPreviousParam(itParam);
81 if (itPreviousParam == track.
rend()) {
82 throw runtime_error(
"A track is made of at least 2 clusters in 2 different chambers");
84 }
while (itPreviousParam->getClusterPtr()->getChamberId() == itParam->getClusterPtr()->getChamberId());
85 initTrack(*itPreviousParam->getClusterPtr(), *itParam->getClusterPtr(), *itParam);
90 while (++itParam != track.
rend()) {
91 addCluster(*startingParam, *itParam->
getClusterPtr(), *itParam);
92 startingParam = &*itParam;
96 if (smooth && mSmooth) {
97 smoothTrack(track, finalize, skipLocalChi2Calculation);
110 double dZ = cl1.
getZ() - cl2.
getZ();
116 double bendingImpact = cl2.
getY() - cl2.
getZ() *
param.getBendingSlope();
118 param.setInverseBendingMomentum(inverseBendingMomentum);
121 TMatrixD lastParamCov(5, 5);
124 if (mUseChamberResolution) {
126 lastParamCov(0, 0) = mChamberResolutionX2;
127 lastParamCov(1, 1) = (1000. * mChamberResolutionX2 + lastParamCov(0, 0)) / dZ / dZ;
129 lastParamCov(2, 2) = mChamberResolutionY2;
130 cl1Ey2 = mChamberResolutionY2;
133 lastParamCov(0, 0) = cl2.
getEx2();
134 lastParamCov(1, 1) = (1000. * cl1.
getEx2() + lastParamCov(0, 0)) / dZ / dZ;
136 lastParamCov(2, 2) = cl2.
getEy2();
140 lastParamCov(0, 1) = -lastParamCov(0, 0) / dZ;
141 lastParamCov(1, 0) = lastParamCov(0, 1);
143 lastParamCov(2, 3) = -lastParamCov(2, 2) / dZ;
144 lastParamCov(3, 2) = lastParamCov(2, 3);
145 lastParamCov(3, 3) = (1000. * cl1Ey2 + lastParamCov(2, 2)) / dZ / dZ;
149 ((mBendingVertexDispersion2 +
150 (cl1.
getZ() * cl1.
getZ() * lastParamCov(2, 2) + cl2.
getZ() * cl2.
getZ() * 1000. * cl1Ey2) / dZ / dZ) /
151 bendingImpact / bendingImpact +
153 inverseBendingMomentum * inverseBendingMomentum;
154 lastParamCov(2, 4) = cl1.
getZ() * lastParamCov(2, 2) * inverseBendingMomentum / bendingImpact / dZ;
155 lastParamCov(4, 2) = lastParamCov(2, 4);
156 lastParamCov(3, 4) = -(cl1.
getZ() * lastParamCov(2, 2) + cl2.
getZ() * 1000. * cl1Ey2) * inverseBendingMomentum /
157 bendingImpact / dZ / dZ;
158 lastParamCov(4, 3) = lastParamCov(3, 4);
160 lastParamCov(4, 4) = inverseBendingMomentum * inverseBendingMomentum;
162 param.setCovariances(lastParamCov);
165 param.setClusterPtr(&cl2);
166 param.setTrackChi2(0.);
170void TrackFitter::addCluster(
const TrackParam& startingParam,
const Cluster& cl, TrackParam&
param)
177 if (cl.getZ() <= startingParam.getZ()) {
182 param.setParameters(startingParam.getParameters());
183 param.setZ(startingParam.getZ());
184 param.setCovariances(startingParam.getCovariances());
185 param.setTrackChi2(startingParam.getTrackChi2());
188 int currentChamber(startingParam.getClusterPtr()->getChamberId());
193 param.resetPropagator();
197 int expectedChamber(currentChamber - 1);
198 currentChamber = cl.getChamberId();
199 while (currentChamber < expectedChamber) {
214 param.setExtrapParameters(
param.getParameters());
215 param.setExtrapCovariances(
param.getCovariances());
219 param.setClusterPtr(&cl);
224void TrackFitter::smoothTrack(Track& track,
bool finalize,
bool skipLocalChi2Calculation)
231 auto itCurrentParam(track.begin());
232 auto itPreviousParam(itCurrentParam);
236 itPreviousParam->setSmoothParameters(itPreviousParam->getParameters());
237 itPreviousParam->setSmoothCovariances(itPreviousParam->getCovariances());
240 itPreviousParam->setLocalChi2(itPreviousParam->getTrackChi2() - itCurrentParam->getTrackChi2());
244 auto skipChi2 = skipLocalChi2Calculation || track.getNClusters() < 3;
246 runSmoother(*itPreviousParam, *itCurrentParam, skipChi2);
248 }
while (++itCurrentParam != track.end());
252 for (
auto&
param : track) {
253 param.setParameters(
param.getSmoothParameters());
254 param.setCovariances(
param.getSmoothCovariances());
271 TMatrixD clusterParam(5, 1);
273 clusterParam(0, 0) = cluster->
getX();
274 clusterParam(2, 0) = cluster->
getY();
278 if (paramWeight.Determinant() != 0) {
279 paramWeight.Invert();
285 TMatrixD clusterWeight(5, 5);
286 clusterWeight.Zero();
287 if (mUseChamberResolution) {
288 clusterWeight(0, 0) = 1. / mChamberResolutionX2;
289 clusterWeight(2, 2) = 1. / mChamberResolutionY2;
291 clusterWeight(0, 0) = 1. / cluster->
getEx2();
292 clusterWeight(2, 2) = 1. / cluster->
getEy2();
296 TMatrixD newParamCov(paramWeight, TMatrixD::kPlus, clusterWeight);
297 if (newParamCov.Determinant() != 0) {
298 newParamCov.Invert();
305 TMatrixD tmp(clusterParam, TMatrixD::kMinus,
param);
306 TMatrixD tmp2(clusterWeight, TMatrixD::kMult, tmp);
307 TMatrixD newParam(newParamCov, TMatrixD::kMult, tmp2);
314 TMatrixD tmp3(paramWeight, TMatrixD::kMult, tmp);
315 TMatrixD addChi2Track(tmp, TMatrixD::kTransposeMult, tmp3);
318 TMatrixD tmp4(clusterWeight, TMatrixD::kMult, tmp);
319 addChi2Track += TMatrixD(tmp, TMatrixD::kTransposeMult, tmp4);
331 const TMatrixD& filteredParameters =
param.getParameters();
335 const TMatrixD& filteredCovariances =
param.getCovariances();
339 TMatrixD extrapWeight(extrapCovariances);
340 if (extrapWeight.Determinant() != 0) {
341 extrapWeight.Invert();
345 TMatrixD smootherGain(filteredCovariances, TMatrixD::kMultTranspose, propagator);
346 smootherGain *= extrapWeight;
349 TMatrixD tmpParam(previousSmoothParameters, TMatrixD::kMinus, extrapParameters);
350 TMatrixD smoothParameters(smootherGain, TMatrixD::kMult, tmpParam);
351 smoothParameters += filteredParameters;
352 param.setSmoothParameters(smoothParameters);
355 TMatrixD tmpCov(previousSmoothCovariances, TMatrixD::kMinus, extrapCovariances);
356 TMatrixD tmpCov2(tmpCov, TMatrixD::kMultTranspose, smootherGain);
357 TMatrixD smoothCovariances(smootherGain, TMatrixD::kMult, tmpCov2);
358 smoothCovariances += filteredCovariances;
359 param.setSmoothCovariances(smoothCovariances);
362 if (skipLocalChi2Calculation) {
363 param.setLocalChi2(0.);
369 TMatrixD smoothResidual(2, 1);
370 smoothResidual.Zero();
371 smoothResidual(0, 0) = cluster->getX() - smoothParameters(0, 0);
372 smoothResidual(1, 0) = cluster->getY() - smoothParameters(2, 0);
375 TMatrixD smoothResidualWeight(2, 2);
376 if (mUseChamberResolution) {
377 smoothResidualWeight(0, 0) = mChamberResolutionX2 - smoothCovariances(0, 0);
378 smoothResidualWeight(1, 1) = mChamberResolutionY2 - smoothCovariances(2, 2);
380 smoothResidualWeight(0, 0) = cluster->getEx2() - smoothCovariances(0, 0);
381 smoothResidualWeight(1, 1) = cluster->getEy2() - smoothCovariances(2, 2);
383 smoothResidualWeight(0, 1) = -smoothCovariances(0, 2);
384 smoothResidualWeight(1, 0) = -smoothCovariances(2, 0);
385 if (smoothResidualWeight.Determinant() != 0) {
386 smoothResidualWeight.Invert();
392 TMatrixD tmpChi2(smoothResidual, TMatrixD::kTransposeMult, smoothResidualWeight);
393 TMatrixD localChi2(tmpChi2, TMatrixD::kMult, smoothResidual);
394 param.setLocalChi2(localChi2(0, 0));
Definition of a class to fit a track to a set of clusters.
Definition of the MagF class.
static MagneticField * createFieldMap(float l3Current=-30000., float diCurrent=-6000., Int_t convention=0, Bool_t uniform=kFALSE, float beamenergy=7000, const Char_t *btype="pp", const std::string path=std::string(gSystem->Getenv("VMCWORKDIR"))+std::string("/Common/maps/mfchebKGI_sym.root"))
HMPID cluster implementation.
void initField(float l3Current, float dipoleCurrent)
void fit(Track &track, bool smooth=true, bool finalize=true, std::list< TrackParam >::reverse_iterator *itStartingParam=nullptr, bool skipLocalChi2Calculation=false)
void runKalmanFilter(TrackParam &trackParam)
track parameters for internal use
const TMatrixD & getExtrapCovariances() const
const TMatrixD & getSmoothCovariances() const
void setTrackChi2(Double_t chi2)
set the chi2 of the track when the associated cluster was attached
Double_t getTrackChi2() const
return the chi2 of the track when the associated cluster was attached
const TMatrixD & getParameters() const
return track parameters
void setCovariances(const TMatrixD &covariances)
const TMatrixD & getPropagator() const
const TMatrixD & getCovariances() const
const TMatrixD & getExtrapParameters() const
void setParameters(const TMatrixD ¶meters)
set track parameters
const TMatrixD & getSmoothParameters() const
const Cluster * getClusterPtr() const
get pointer to associated cluster
auto rend()
Return a reverse iterator passing the track parameters at first cluster.
auto rbegin()
Return a reverse iterator to the track parameters at clusters (point to the last one)
RuntimeErrorRef runtime_error(const char *)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Defining DataPointCompositeObject explicitly as copiable.
cluster minimal structure
double getEx2() const
Return the cluster resolution square along x.
double getY() const
Return the cluster position along y as double.
double getX() const
Return the cluster position along x as double.
double getEy2() const
Return the cluster resolution square along y.
double getZ() const
Return the cluster position along z as double.