47 auto nClusters = track.getNumberOfPoints();
48 auto lastLayer = track.getLayers()[(outward ? 0 :
nClusters - 1)];
51 std::cout <<
"Seed covariances: \n"
52 << track.getCovariances() << std::endl
59 if (!computeCluster(track,
nClusters, lastLayer)) {
66 if (!computeCluster(track, ncl, lastLayer)) {
73 std::cout <<
"Track Chi2 = " << track.getTrackChi2() << std::endl;
74 std::cout <<
" ***************************** Done fitting *****************************\n";
85 if constexpr (std::is_same<T, o2::mft::TrackLTF>::value) {
88 double chi2invqptquad;
90 auto nPoints = track.getNumberOfPoints();
92 auto Hz = std::copysign(1, mBZField);
95 std::cout <<
"\n ***************************** Start Fitting new track ***************************** \n";
96 std::cout <<
"N Clusters = " << nPoints << std::endl;
99 track.setInvQPtSeed(invQPt0);
100 track.setChi2QPtSeed(chi2invqptquad);
101 track.setInvQPt(invQPt0);
104 int first_cls, next_cls;
107 next_cls = nPoints - 1;
109 first_cls = nPoints - 1;
113 auto x0 = track.getXCoordinates()[first_cls];
114 auto y0 = track.getYCoordinates()[first_cls];
115 auto z0 = track.getZCoordinates()[first_cls];
118 auto deltaX = track.getXCoordinates()[1] - track.getXCoordinates()[0];
119 auto deltaY = track.getYCoordinates()[1] - track.getYCoordinates()[0];
120 auto deltaZ = track.getZCoordinates()[1] - track.getZCoordinates()[0];
121 auto deltaR = TMath::Sqrt(deltaX * deltaX + deltaY * deltaY);
122 auto tanl0 = -std::abs(deltaZ / deltaR);
125 deltaX = track.getXCoordinates()[first_cls] - track.getXCoordinates()[next_cls];
126 deltaY = track.getYCoordinates()[first_cls] - track.getYCoordinates()[next_cls];
127 deltaZ = track.getZCoordinates()[first_cls] - track.getZCoordinates()[next_cls];
128 deltaR = TMath::Sqrt(deltaX * deltaX + deltaY * deltaY);
131 phi0 = TMath::ATan2(-deltaY, -deltaX) - 0.5 * Hz * invQPt0 * deltaZ * k / tanl0;
133 phi0 = TMath::ATan2(deltaY, deltaX) - 0.5 * Hz * invQPt0 * deltaZ * k / tanl0;
141 track.setTanl(tanl0);
144 std::cout <<
" Init " << (track.isCA() ?
"CA Track " :
"LTF Track") << (outward ?
" (outward)" :
" (inward)") << std::endl;
145 auto model = (mTrackModel ==
Helix) ?
"Helix" : (mTrackModel ==
Quadratic) ?
"Quadratic"
146 : (mTrackModel ==
Optimized) ?
"Optimized"
148 std::cout <<
"Track Model: " << model << std::endl;
149 std::cout <<
" initTrack: X = " <<
x0 <<
" Y = " <<
y0 <<
" Z = " << z0 <<
" Tgl = " << tanl0 <<
" Phi = " << phi0 <<
" pz = " << track.getPz() <<
" q/pt = " << track.getInvQPt() << std::endl;
153 double qptsigma = TMath::Range(1., 10., std::abs(track.getInvQPt()));
155 lastParamCov(0, 0) = 1.;
156 lastParamCov(1, 1) = 1.;
157 lastParamCov(2, 2) = 1.;
158 lastParamCov(3, 3) = 1.;
159 lastParamCov(4, 4) = qptsigma;
161 track.setCovariances(lastParamCov);
162 track.setTrackChi2(0.);
167 double chi2invqptquad;
170 auto nPoints = track.getNumberOfPoints();
173 std::cout <<
"\n ***************************** Start Fitting new track ***************************** \n";
174 std::cout <<
"N Clusters = " << nPoints << std::endl;
177 track.setInvQPtSeed(0);
178 track.setChi2QPtSeed(0);
179 track.setInvQPt(invQPt0);
182 int first_cls, next_cls;
185 next_cls = nPoints - 1;
187 first_cls = nPoints - 1;
191 auto x0 = track.getXCoordinates()[first_cls];
192 auto y0 = track.getYCoordinates()[first_cls];
193 auto z0 = track.getZCoordinates()[first_cls];
195 auto deltaX = track.getXCoordinates()[first_cls] - track.getXCoordinates()[next_cls];
196 auto deltaY = track.getYCoordinates()[first_cls] - track.getYCoordinates()[next_cls];
197 auto deltaZ = track.getZCoordinates()[first_cls] - track.getZCoordinates()[next_cls];
198 auto deltaR = TMath::Sqrt(deltaX * deltaX + deltaY * deltaY);
199 auto tanl0 = -std::abs(deltaZ) / deltaR;
202 phi0 = TMath::ATan2(-deltaY, -deltaX);
204 phi0 = TMath::ATan2(deltaY, deltaX);
211 track.setTanl(tanl0);
214 std::cout <<
" Init " << (track.isCA() ?
"CA Track " :
"LTF Track") << (outward ?
" (outward)" :
" (inward)") << std::endl;
215 auto model =
"Linear";
216 std::cout <<
"Track Model: " << model << std::endl;
217 std::cout <<
" initTrack: X = " <<
x0 <<
" Y = " <<
y0 <<
" Z = " << z0 <<
" Tgl = " << tanl0 <<
" Phi = " << phi0 <<
" pz = " << track.getPz() <<
" q/pt = " << track.getInvQPt() << std::endl;
221 double qptsigma = TMath::Range(1., 10., std::abs(track.getInvQPt()));
223 lastParamCov(0, 0) = 1.;
224 lastParamCov(1, 1) = 1.;
225 lastParamCov(2, 2) = 1.;
226 lastParamCov(3, 3) = 1.;
227 lastParamCov(4, 4) = 0.;
229 track.setCovariances(lastParamCov);
230 track.setTrackChi2(0.);
241 if constexpr (std::is_same<T, o2::mft::TrackLTF>::value) {
243 switch (mTrackModel) {
245 track.propagateToZlinear(
z);
248 track.propagateToZquadratic(
z, mBZField);
251 track.propagateToZhelix(
z, mBZField);
254 track.propagateToZ(
z, mBZField);
257 std::cout <<
" Invalid track model.\n";
262 track.propagateToZlinear(
z);
269bool TrackFitter<T>::propagateToNextClusterWithMCS(T& track,
double z,
int& startingLayerID,
const int& newLayerID)
276 if (startingLayerID == newLayerID) {
278 std::cout <<
" => Propagate to next cluster with MCS : startingLayerID = " << startingLayerID <<
" = > "
279 <<
" newLayerID = " << newLayerID <<
" (NLayers = " << std::abs(newLayerID - startingLayerID);
280 std::cout <<
") ; track.getZ() = " << track.getZ() <<
" => ";
281 std::cout <<
"destination cluster z = " <<
z <<
" ; => Same layer: no MCS effects." << std::endl;
283 if (
z != track.getZ()) {
284 propagateToZ(track,
z);
290 auto startingZ = track.getZ();
293 auto signum = [](
auto a) {
294 return (0 <
a) - (
a < 0);
296 int direction = signum(newLayerID - startingLayerID);
297 auto currentLayer = startingLayerID;
300 std::cout <<
" => Propagate to next cluster with MCS : startingLayerID = " << startingLayerID <<
" = > "
301 <<
" newLayerID = " << newLayerID <<
" (NLayers = " << std::abs(newLayerID - startingLayerID);
302 std::cout <<
") ; track.getZ() = " << track.getZ() <<
" => ";
303 std::cout <<
"destination cluster z = " <<
z <<
" ; " << std::endl;
307 while (currentLayer != newLayerID) {
308 auto nextlayer = currentLayer + direction;
312 if (nextZ - track.getZ() > 0) {
313 NDisksMS = (currentLayer % 2 == 0) ? (currentLayer - nextlayer) / 2 : (currentLayer - nextlayer + 1) / 2;
315 NDisksMS = (currentLayer % 2 == 0) ? (nextlayer - currentLayer + 1) / 2 : (nextlayer - currentLayer) / 2;
319 std::cout <<
"currentLayer = " << currentLayer <<
" ; "
320 <<
"nextlayer = " << nextlayer <<
" ; ";
321 std::cout <<
"track.getZ() = " << track.getZ() <<
" ; ";
322 std::cout <<
"nextZ = " << nextZ <<
" ; ";
323 std::cout <<
"NDisksMS = " << NDisksMS << std::endl;
326 if ((NDisksMS * mMFTDiskThicknessInX0) != 0) {
327 track.addMCSEffect(NDisksMS * mMFTDiskThicknessInX0);
329 std::cout <<
"Track covariances after MCS effects: \n"
330 << track.getCovariances() << std::endl
336 std::cout <<
" BeforeExtrap: X = " << track.getX() <<
" Y = " << track.getY() <<
" Z = " << track.getZ() <<
" Tgl = " << track.getTanl() <<
" Phi = " << track.getPhi() <<
" pz = " << track.getPz() <<
" q/pt = " << track.getInvQPt() << std::endl;
339 propagateToZ(track, nextZ);
341 currentLayer = nextlayer;
343 if (
z != track.getZ()) {
344 propagateToZ(track,
z);
346 startingLayerID = newLayerID;
352bool TrackFitter<T>::computeCluster(T& track,
int cluster,
int& startingLayerID)
359 const auto& clx = track.getXCoordinates()[cluster];
360 const auto& cly = track.getYCoordinates()[cluster];
361 const auto& clz = track.getZCoordinates()[cluster];
362 const auto& sigmaX2 = track.getSigmasX2()[cluster] + mAlignResidual;
363 const auto& sigmaY2 = track.getSigmasY2()[cluster] + mAlignResidual;
364 const auto& newLayerID = track.getLayers()[cluster];
367 std::cout <<
"computeCluster: X = " << clx <<
" Y = " << cly <<
" Z = " << clz <<
" nCluster = " << cluster <<
" Layer = " << newLayerID << std::endl;
370 if (!propagateToNextClusterWithMCS(track, clz, startingLayerID, newLayerID)) {
375 std::cout <<
" AfterExtrap: X = " << track.getX() <<
" Y = " << track.getY() <<
" Z = " << track.getZ() <<
" Tgl = " << track.getTanl() <<
" Phi = " << track.getPhi() <<
" pz = " << track.getPz() <<
" q/pt = " << track.getInvQPt() << std::endl;
376 std::cout <<
"Track covariances after extrap: \n"
377 << track.getCovariances() << std::endl
382 const std::array<float, 2>&
pos = {clx, cly};
383 const std::array<float, 2>& cov = {sigmaX2, sigmaY2};
385 if (track.update(
pos, cov)) {
387 std::cout <<
" New Cluster: X = " << clx <<
" Y = " << cly <<
" Z = " << clz <<
" sigmaX2 = " << sigmaX2 <<
" sigmaY2 = " << sigmaY2 << std::endl;
388 std::cout <<
" AfterKalman: X = " << track.getX() <<
" Y = " << track.getY() <<
" Z = " << track.getZ() <<
" Tgl = " << track.getTanl() <<
" Phi = " << track.getPhi() <<
" pz = " << track.getPz() <<
" q/pt = " << track.getInvQPt() << std::endl;
389 std::cout << std::endl;
390 std::cout <<
"Track covariances after Kalman update: \n"
391 << track.getCovariances() << std::endl
401Double_t
invQPtFromFCF(
const T& track, Double_t bFieldZ, Double_t& sigmainvqptsq)
404 const std::array<Float_t, constants::mft::LayersNumber>& xPositions = track.getXCoordinates();
405 const std::array<Float_t, constants::mft::LayersNumber>& yPositions = track.getYCoordinates();
406 const std::array<Float_t, constants::mft::LayersNumber>& zPositions = track.getZCoordinates();
407 const std::array<Float_t, constants::mft::LayersNumber>& SigmasX2 = track.getSigmasX2();
408 const std::array<Float_t, constants::mft::LayersNumber>& SigmasY2 = track.getSigmasY2();
411 auto nPoints = track.getNumberOfPoints();
412 std::vector<double> xVal(nPoints);
413 std::vector<double> yVal(nPoints);
414 std::vector<double> zVal(nPoints);
415 std::vector<double> xErr(nPoints);
416 std::vector<double> yErr(nPoints);
417 std::vector<double> uVal(nPoints);
418 std::vector<double> vVal(nPoints);
419 std::vector<double> vErr(nPoints);
420 std::vector<double> fweight(nPoints);
421 std::vector<double> Rn(nPoints);
422 std::vector<double> Pn(nPoints);
423 Double_t
A, Aerr,
B, Berr, x2, y2, invx2y2,
a,
b,
r, sigmaRsq, u2, sigma;
424 Double_t F0, F1, F2, F3, F4, SumSRn, SumSPn, SumRn, SumUPn, SumRP;
426 SumSRn = SumSPn = SumRn = SumUPn = SumRP = 0.0;
427 F0 = F1 = F2 = F3 = F4 = 0.0;
429 for (
auto np = 0; np < nPoints; np++) {
430 xErr[np] = SigmasX2[np];
431 yErr[np] = SigmasY2[np];
433 xVal[np] = xPositions[np] - xPositions[0] + xVal[0];
434 yVal[np] = yPositions[np] - yPositions[0] + yVal[0];
439 zVal[np] = zPositions[np];
441 for (
int i = 0;
i < nPoints;
i++) {
442 x2 = xVal[
i] * xVal[
i];
443 y2 = yVal[
i] * yVal[
i];
444 invx2y2 = 1. / (x2 + y2);
445 uVal[
i] = xVal[
i] * invx2y2;
446 vVal[
i] = yVal[
i] * invx2y2;
447 vErr[
i] = std::sqrt(8. * xErr[
i] * xErr[
i] * x2 * y2 + 2. * yErr[
i] * yErr[
i] * (x2 - y2) * (x2 - y2)) * invx2y2 * invx2y2;
461 r = std::sqrt(
a *
a +
b *
b);
462 double_t invR = 1. /
r;
471 Double_t
x = xVal[nPoints - 1],
y = yVal[nPoints - 1],
z = zVal[nPoints - 1];
472 Double_t
slope = TMath::ATan2(
y,
x);
473 Double_t cosSlope = TMath::Cos(
slope);
474 Double_t sinSlope = TMath::Sin(
slope);
475 Double_t rxRot =
a * cosSlope +
b * sinSlope;
476 Double_t ryRot =
a * sinSlope -
b * cosSlope;
477 qfcf = (ryRot > 0.) ? -1 : +1;
479 invqpt_fcf = qfcf * invpt;
481 LOG(warn) <<
"LinearRegression failed!";
482 invqpt_fcf = 1. / 100.;
489Bool_t
LinearRegression(Int_t nVal, std::vector<double>& xVal, std::vector<double>& yVal, std::vector<double>& yErr, Double_t&
B, Double_t& Berr, Double_t&
A, Double_t& Aerr)
493 Double_t S1, SXY, SX, SY, SXX, SsXY, SsXX, SsYY, Xm, Ym, s, delta, difx;
496 S1 = SXY = SX = SY = SXX = 0.0;
497 SsXX = SsYY = SsXY = Xm = Ym = 0.;
499 for (Int_t
i = 0;
i < nVal;
i++) {
500 invYErr2 = 1. / (yErr[
i] * yErr[
i]);
502 SXY += xVal[
i] * yVal[
i] * invYErr2;
503 SX += xVal[
i] * invYErr2;
504 SY += yVal[
i] * invYErr2;
505 SXX += xVal[
i] * xVal[
i] * invYErr2;
507 difx += TMath::Abs(xVal[
i] - xVal[
i - 1]);
511 SsXX += xVal[
i] * xVal[
i];
512 SsYY += yVal[
i] * yVal[
i];
513 SsXY += xVal[
i] * yVal[
i];
515 delta = SXX * S1 - SX * SX;
519 B = (SXY * S1 - SX * SY) / delta;
520 A = (SY * SXX - SX * SXY) / delta;
522 Ym /= (Double_t)nVal;
523 Xm /= (Double_t)nVal;
524 SsYY -= (Double_t)nVal * (Ym * Ym);
525 SsXX -= (Double_t)nVal * (Xm * Xm);
526 SsXY -= (Double_t)nVal * (Ym * Xm);
527 Double_t eps = 1.E-24;
528 if ((nVal > 2) && (TMath::Abs(difx) > eps) && ((SsYY - (SsXY * SsXY) / SsXX) > 0.)) {
529 s = TMath::Sqrt((SsYY - (SsXY * SsXY) / SsXX) / (nVal - 2));
530 Aerr = s * TMath::Sqrt(1. / (Double_t)nVal + (Xm * Xm) / SsXX);
531 Berr = s / TMath::Sqrt(SsXX);
539template class TrackFitter<o2::mft::TrackLTF>;
540template class TrackFitter<o2::mft::TrackLTFL>;
General auxilliary methods.
Constants for the MFT; distance unit is cm.
A simple structure for the MFT cluster, used by the standalone track finder.
Definition of a class to fit a track to a set of clusters.
Standalone classes for the track found by the Linear-Track-Finder (LTF) and by the Cellular-Automaton...
Class to fit a forward track to a set of clusters.
bool initTrack(T &track, bool outward=false)
bool fit(T &track, bool outward=false)
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
GLuint GLfloat GLfloat y0
GLdouble GLdouble GLdouble z
Double_t fitGaus(const size_t nBins, const T *arr, const T xMin, const T xMax, std::vector< T > ¶m)
constexpr Double_t LayerZPosition[]
layer Z position to the middle of the CMOS sensor
Bool_t LinearRegression(Int_t nVal, std::vector< double > &xVal, std::vector< double > &yVal, std::vector< double > &yErr, Double_t &a, Double_t &ae, Double_t &b, Double_t &be)
Double_t invQPtFromFCF(const T &track, Double_t bFieldZ, Double_t &chi2)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"