1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
18 #include <Riostream.h>
22 #include "AliESDtrack.h"
23 #include "AliTRDgeometry.h"
24 #include "AliTRDcluster.h"
25 #include "AliTRDtrack.h"
26 #include "AliTRDtracklet.h"
30 ///////////////////////////////////////////////////////////////////////////////
32 // Represents a reconstructed TRD track //
33 // Local TRD Kalman track //
35 ///////////////////////////////////////////////////////////////////////////////
37 //_____________________________________________________________________________
38 AliTRDtrack::AliTRDtrack()
78 // AliTRDtrack default constructor
85 for (i = 0; i < kNplane; i++) {
86 for (j = 0; j < kNslice; j++) {
92 for (k = 0; k < kMAXCLUSTERSPERTRACK; k++) {
98 for (i = 0; i < 3; i++) {
104 //_____________________________________________________________________________
105 AliTRDtrack::AliTRDtrack(const AliTRDcluster *c, UInt_t index,
106 const Double_t xx[5], const Double_t cc[15],
107 Double_t xref, Double_t alpha)
147 // AliTRDtrack main constructor
154 if (fAlpha < -TMath::Pi()) {
155 fAlpha += 2.0 * TMath::Pi();
157 if (fAlpha >= TMath::Pi()) {
158 fAlpha -= 2.0 * TMath::Pi();
161 SaveLocalConvConst();
164 SetNumberOfClusters(1);
166 for (i = 0; i < kNplane; i++) {
167 for (j = 0; j < kNslice; j++) {
168 fdEdxPlane[i][j] = 0;
170 fTimBinPlane[i] = -1;
173 Double_t q = TMath::Abs(c->GetQ());
174 Double_t s = fX * fC - fE;
177 q *= TMath::Sqrt((1-s*s)/(1+t*t));
181 for (k = 1; k < kMAXCLUSTERSPERTRACK; k++) {
187 for (i = 0; i < 3; i++) {
193 //_____________________________________________________________________________
194 AliTRDtrack::AliTRDtrack(const AliTRDtrack &t)
196 ,fSeedLab(t.fSeedLab)
201 ,fStopped(t.fStopped)
224 ,fNRotate(t.fNRotate)
226 ,fNExpected(t.fNExpected)
228 ,fNExpectedLast(t.fNExpectedLast)
230 ,fChi2Last(t.fChi2Last)
241 for (i = 0; i < kNplane; i++) {
242 for (j = 0; j < kNslice; j++) {
243 fdEdxPlane[i][j] = t.fdEdxPlane[i][j];
245 fTimBinPlane[i] = t.fTimBinPlane[i];
246 fTracklets[i] = t.fTracklets[i];
249 Int_t n = t.GetNumberOfClusters();
250 for (i = 0; i < n; i++) {
251 fIndex[i] = t.fIndex[i];
252 fIndexBackup[i] = t.fIndex[i];
253 fdQdl[i] = t.fdQdl[i];
255 for (k = n; k < kMAXCLUSTERSPERTRACK; k++) {
261 for (i = 0; i < 6; i++) {
262 fTracklets[i] = t.fTracklets[i];
265 for (i = 0; i < 3; i++) {
266 fBudget[i] = t.fBudget[i];
271 //_____________________________________________________________________________
272 AliTRDtrack::AliTRDtrack(const AliKalmanTrack &t, Double_t alpha)
275 ,fdEdx(t.GetPIDsignal())
312 // Constructor from AliTPCtrack or AliITStrack .
320 SetNumberOfClusters(0);
322 for (i = 0; i < kNplane; i++) {
323 for (j = 0; j < kNslice; j++) {
324 fdEdxPlane[i][j] = 0.0;
326 fTimBinPlane[i] = -1;
329 if (fAlpha < -TMath::Pi()) {
330 fAlpha += 2.0 * TMath::Pi();
332 else if (fAlpha >= TMath::Pi()) {
333 fAlpha -= 2.0 * TMath::Pi();
338 t.GetExternalParameters(x,p);
343 x = GetLocalConvConst();
347 // Conversion of the covariance matrix
349 t.GetExternalCovariance(c);
356 Double_t c22 = fX*fX * c[14] - 2.0*fX*c[12] + c[ 5];
357 Double_t c32 = fX * c[13] - c[ 8];
358 Double_t c20 = fX * c[10] - c[ 3];
359 Double_t c21 = fX * c[11] - c[ 4];
360 Double_t c42 = fX * c[14] - c[12];
363 fCzy = c[ 1]; fCzz = c[ 2];
364 fCey = c20; fCez = c21; fCee = c22;
365 fCty = c[ 6]; fCtz = c[ 7]; fCte = c32; fCtt = c[ 9];
366 fCcy = c[10]; fCcz = c[11]; fCce = c42; fCct = c[13]; fCcc = c[14];
368 for (k = 0; k < kMAXCLUSTERSPERTRACK; k++) {
374 for (i = 0; i < 3; i++) {
380 //_____________________________________________________________________________
381 AliTRDtrack::AliTRDtrack(const AliESDtrack &t)
384 ,fdEdx(t.GetTRDsignal())
386 ,fAlpha(t.GetAlpha())
421 // Constructor from AliESDtrack
428 SetLabel(t.GetLabel());
430 SetMass(t.GetMass());
431 SetNumberOfClusters(t.GetTRDclusters(fIndex));
433 Int_t ncl = t.GetTRDclusters(fIndexBackup);
434 for (k = ncl; k < kMAXCLUSTERSPERTRACK; k++) {
439 for (i = 0; i < kNplane; i++) {
440 for (j = 0; j < kNslice; j++) {
441 fdEdxPlane[i][j] = t.GetTRDsignals(i,j);
443 fTimBinPlane[i] = t.GetTRDTimBin(i);
446 if (fAlpha < -TMath::Pi()) {
447 fAlpha += 2.0 * TMath::Pi();
449 else if (fAlpha >= TMath::Pi()) {
450 fAlpha -= 2.0 * TMath::Pi();
453 // Conversion of the covariance matrix
456 t.GetExternalParameters(x,p);
458 t.GetExternalCovariance(c);
459 if (t.GetStatus() & AliESDtrack::kTRDbackup) {
460 t.GetOuterExternalParameters(fAlpha,x,p);
461 t.GetOuterExternalCovariance(c);
462 if (fAlpha < -TMath::Pi()) {
463 fAlpha += 2.0 * TMath::Pi();
465 else if (fAlpha >= TMath::Pi()) {
466 fAlpha -= 2.0 * TMath::Pi();
473 SaveLocalConvConst();
475 x = GetLocalConvConst();
485 Double_t c22 = fX*fX * c[14] - 2.0*fX*c[12] + c[ 5];
486 Double_t c32 = fX * c[13] - c[ 8];
487 Double_t c20 = fX * c[10] - c[ 3];
488 Double_t c21 = fX * c[11] - c[ 4];
489 Double_t c42 = fX * c[14] - c[12];
492 fCzy = c[ 1]; fCzz = c[ 2];
493 fCey = c20; fCez = c21; fCee = c22;
494 fCty = c[ 6]; fCtz = c[ 7]; fCte = c32; fCtt = c[ 9];
495 fCcy = c[10]; fCcz = c[11]; fCce = c42; fCct = c[13]; fCcc = c[14];
497 for (k = 0; k < kMAXCLUSTERSPERTRACK; k++) {
499 //fIndex[k] = 0; //MI store indexes
502 for (i = 0; i < 3; i++) {
505 if ((t.GetStatus() & AliESDtrack::kTIME) == 0) {
511 t.GetIntegratedTimes(times);
512 SetIntegratedTimes(times);
513 SetIntegratedLength(t.GetIntegratedLength());
517 //____________________________________________________________________________
518 AliTRDtrack::~AliTRDtrack()
531 //____________________________________________________________________________
532 AliTRDtrack &AliTRDtrack::operator=(const AliTRDtrack &t)
535 // Assignment operator
550 fAlpha = t.GetAlpha();
551 if (fAlpha < -TMath::Pi()) {
552 fAlpha += 2.0 * TMath::Pi();
554 else if (fAlpha >= TMath::Pi()) {
555 fAlpha -= 2.0 * TMath::Pi();
562 //____________________________________________________________________________
563 Float_t AliTRDtrack::StatusForTOF()
566 // Defines the status of the TOF extrapolation
569 // Definition of res ????
570 Float_t res = (0.2 + 0.8 * (fN / (fNExpected + 5.0)))
571 * (0.4 + 0.6 * fTracklets[5].GetN() / 20.0);
572 res *= (0.25 + 0.8 * 40.0 / (40.0 + fBudget[2]));
575 // This part of the function is never reached ????
576 // What defines these parameters ????
578 if (GetNumberOfClusters() < 20) return 0;
580 (fChi2/(Float_t(fN)) < 3.0)) return 3; // Gold
582 (fChi2Last/(Float_t(fNLast)) < 3.0)) return 3; // Gold
584 (fChi2Last/(Float_t(fNLast)) < 2.0)) return 3; // Gold
585 if ((fNLast/(fNExpectedLast+3.0) > 0.8) &&
586 (fChi2Last/Float_t(fNLast) < 5.0) &&
587 (fNLast > 20)) return 2; // Silver
589 (((fNLast+1.0)/(fNExpectedLast+1.0)) > 0.8) &&
590 (fChi2Last/(fNLast-5.0) < 6.0)) return 1;
596 //_____________________________________________________________________________
597 void AliTRDtrack::GetExternalCovariance(Double_t cc[15]) const
600 // This function returns external representation of the covriance matrix.
603 Double_t a = GetLocalConvConst();
605 Double_t c22 = fX*fX*fCcc - 2.0*fX*fCce+fCee;
606 Double_t c32 = fX*fCct-fCte;
607 Double_t c20 = fX*fCcy-fCey;
608 Double_t c21 = fX*fCcz-fCez;
609 Double_t c42 = fX*fCcc-fCce;
612 cc[ 1]=fCzy; cc[ 2]=fCzz;
613 cc[ 3]=c20; cc[ 4]=c21; cc[ 5]=c22;
614 cc[ 6]=fCty; cc[ 7]=fCtz; cc[ 8]=c32; cc[ 9]=fCtt;
615 cc[10]=fCcy*a; cc[11]=fCcz*a; cc[12]=c42*a; cc[13]=fCct*a; cc[14]=fCcc*a*a;
619 //_____________________________________________________________________________
620 void AliTRDtrack::GetCovariance(Double_t cc[15]) const
623 // Returns the track covariance matrix
627 cc[ 1]=fCzy; cc[ 2]=fCzz;
628 cc[ 3]=fCey; cc[ 4]=fCez; cc[ 5]=fCee;
629 cc[ 6]=fCcy; cc[ 7]=fCcz; cc[ 8]=fCce; cc[ 9]=fCcc;
630 cc[10]=fCty; cc[11]=fCtz; cc[12]=fCte; cc[13]=fCct; cc[14]=fCtt;
634 //_____________________________________________________________________________
635 Int_t AliTRDtrack::Compare(const TObject *o) const
638 // Compares tracks according to their Y2 or curvature
641 AliTRDtrack *t = (AliTRDtrack *) o;
642 // Double_t co=t->GetSigmaY2();
643 // Double_t c =GetSigmaY2();
645 Double_t co = TMath::Abs(t->GetC());
646 Double_t c = TMath::Abs(GetC());
658 //_____________________________________________________________________________
659 void AliTRDtrack::CookdEdx(Double_t low, Double_t up)
662 // Calculates the truncated dE/dx within the "low" and "up" cuts.
667 // Array to sort the dEdx values according to amplitude
668 Float_t sorted[kMAXCLUSTERSPERTRACK];
670 // Number of clusters used for dedx
673 // Require at least 10 clusters for a dedx measurement
679 // Lower and upper bound
680 Int_t nl = Int_t(low * nc);
681 Int_t nu = Int_t( up * nc);
683 // Can fdQdl be negative ????
684 for (i = 0; i < nc; i++) {
685 sorted[i] = TMath::Abs(fdQdl[i]);
688 // Sort the dedx values by amplitude
689 Int_t *index = new Int_t[nc];
690 TMath::Sort(nc,sorted,index,kFALSE);
692 // Sum up the truncated charge between nl and nu
694 for (i = nl; i <= nu; i++) {
695 dedx += sorted[index[i]];
697 dedx /= (nu - nl + 1.0);
704 //_____________________________________________________________________________
705 Int_t AliTRDtrack::PropagateTo(Double_t xk,Double_t x0,Double_t rho)
708 // Propagates a track of particle with mass=pm to a reference plane
709 // defined by x=xk through media of density=rho and radiationLength=x0
716 if (TMath::Abs(fC*xk - fE) >= 0.9) {
720 Double_t lcc = GetLocalConvConst();
727 Double_t x2 = x1 + (xk - x1);
728 Double_t dx = x2 - x1;
731 Double_t c1 = fC*x1 - fE;
736 Double_t r1 = TMath::Sqrt(1.0 - c1*c1);
737 Double_t c2 = fC*x2 - fE;
742 Double_t r2 = TMath::Sqrt(1.0 - c2*c2);
744 fY += dx*(c1+c2) / (r1+r2);
745 fZ += dx*(c1+c2) / (c1*r2 + c2*r1) * fT;
751 Double_t f02 = -dx*(2*rr + cc*(c1/r1 + c2/r2))/(rr*rr);
752 Double_t f04 = dx*(rr*xx + cc*(c1*x1/r1+c2*x2/r2))/(rr*rr);
753 Double_t cr = c1*r2+c2*r1;
754 Double_t f12 = -dx*fT*(2*cr + cc*(c2*c1/r1-r1 + c1*c2/r2-r2))/(cr*cr);
755 Double_t f13 = dx*cc/cr;
756 Double_t f14 = dx*fT*(cr*xx-cc*(r1*x2-c2*c1*x1/r1+r2*x1-c1*c2*x2/r2))/(cr*cr);
759 Double_t b00 = f02*fCey + f04*fCcy;
760 Double_t b01 = f12*fCey + f14*fCcy + f13*fCty;
761 Double_t b10 = f02*fCez + f04*fCcz;
762 Double_t b11 = f12*fCez + f14*fCcz + f13*fCtz;
763 Double_t b20 = f02*fCee + f04*fCce;
764 Double_t b21 = f12*fCee + f14*fCce + f13*fCte;
765 Double_t b30 = f02*fCte + f04*fCct;
766 Double_t b31 = f12*fCte + f14*fCct + f13*fCtt;
767 Double_t b40 = f02*fCce + f04*fCcc;
768 Double_t b41 = f12*fCce + f14*fCcc + f13*fCct;
771 Double_t a00 = f02*b20 + f04*b40;
772 Double_t a01 = f02*b21 + f04*b41;
773 Double_t a11 = f12*b21 + f14*b41 + f13*b31;
775 // F*C*Ft = C + (a + b + bt)
776 fCyy += a00 + 2.0*b00;
777 fCzy += a01 + b01 + b10;
781 fCzz += a11 + 2.0*b11;
788 // Change of the magnetic field
789 SaveLocalConvConst();
791 fC *= lcc / GetLocalConvConst();
794 // Multiple scattering
796 Double_t d = TMath::Sqrt((x1-fX)*(x1-fX) + (y1-fY)*(y1-fY) + (z1-fZ)*(z1-fZ));
797 Double_t p2 = (1.0 + GetTgl()*GetTgl()) / (Get1Pt()*Get1Pt());
798 Double_t beta2 = p2 / (p2 + GetMass()*GetMass());
799 Double_t theta2 = 14.1*14.1 / (beta2*p2*1e6) * d / x0 * rho;
800 Double_t ey = fC*fX - fE;
803 Double_t zz1 = ez*ez + 1.0;
804 Double_t xy = fE + ey;
806 fCee += (2.0*ey*ez*ez*fE + 1.0 - ey*ey + ez*ez + fE*fE*ez*ez) * theta2;
807 fCte += ez*zz1*xy*theta2;
808 fCtt += zz1*zz1*theta2;
809 fCce += xz*ez*xy*theta2;
810 fCct += xz*zz1*theta2;
811 fCcc += xz*xz*theta2;
814 // What is 5940.0 ???? and 0.153e-3 ????
815 if ((5940.0*beta2 / (1.0 - beta2 + 1e-10) - beta2) < 0.0) {
818 Double_t dE = 0.153e-3/beta2 * (TMath::Log(5940.0*beta2 / (1.0 - beta2 + 1e-10)) - beta2)
820 Float_t budget = d * rho;
823 // Suspicious part - think about it ????
824 Double_t kinE = TMath::Sqrt(p2);
825 if (dE > 0.8 * kinE) {
829 dE = 0.0; // Not valid region for Bethe bloch
836 fC *= (1.0 - TMath::Sqrt(p2 + GetMass()*GetMass()) / p2 * dE);
837 fE += fX * (fC - cc);
839 // Energy loss fluctuation
841 Double_t sigmade = 0.07 * TMath::Sqrt(TMath::Abs(dE));
842 Double_t sigmac2 = sigmade*sigmade * fC*fC * (p2 + GetMass()*GetMass()) / (p2*p2);
844 fCee += fX*fX * sigmac2;
846 // Track time measurement
848 if (IsStartedTimeIntegral()) {
849 Double_t l2 = TMath::Sqrt((fX-oldX)*(fX-oldX)
850 + (fY-oldY)*(fY-oldY)
851 + (fZ-oldZ)*(fZ-oldZ));
852 if (TMath::Abs(l2*fC) > 0.0001){
853 // <ake correction for curvature if neccesary
854 l2 = 0.5 * TMath::Sqrt((fX-oldX)*(fX-oldX)
855 + (fY-oldY)*(fY-oldY));
856 l2 = 2.0 * TMath::ASin(l2 * fC) / fC;
857 l2 = TMath::Sqrt(l2*l2 + (fZ-oldZ)*(fZ-oldZ));
867 //_____________________________________________________________________________
868 Int_t AliTRDtrack::Update(const AliTRDcluster *c, Double_t chisq
869 , UInt_t index, Double_t h01)
872 // Assignes a found cluster to the track and updates track information
875 Bool_t fNoTilt = kTRUE;
876 // What is 0.003 ????
877 if (TMath::Abs(h01) > 0.003) {
881 // Add angular effect to the error contribution
882 Float_t tangent2 = (fC*fX-fE) * (fC*fX-fE);
883 if (tangent2 < 0.90000){
884 tangent2 = tangent2 / (1.0 - tangent2);
887 Float_t errang = tangent2 * 0.04;
888 Float_t padlength = TMath::Sqrt(c->GetSigmaZ2() * 12.0);
890 Double_t r00 = c->GetSigmaY2() + errang;
892 Double_t r11 = c->GetSigmaZ2() * 100.0;
896 Double_t det = r00*r11 - r01*r01;
902 Double_t k00 = fCyy*r00 + fCzy*r01;
903 Double_t k01 = fCyy*r01 + fCzy*r11;
904 Double_t k10 = fCzy*r00 + fCzz*r01;
905 Double_t k11 = fCzy*r01 + fCzz*r11;
906 Double_t k20 = fCey*r00 + fCez*r01;
907 Double_t k21 = fCey*r01 + fCez*r11;
908 Double_t k30 = fCty*r00 + fCtz*r01;
909 Double_t k31 = fCty*r01 + fCtz*r11;
910 Double_t k40 = fCcy*r00 + fCcz*r01;
911 Double_t k41 = fCcy*r01 + fCcz*r11;
913 Double_t dy = c->GetY() - fY;
914 Double_t dz = c->GetZ() - fZ;
915 Double_t cur = fC + k40*dy + k41*dz;
916 Double_t eta = fE + k20*dy + k21*dz;
920 if (TMath::Abs(cur*fX-eta) >= 0.9) {
923 fY += k00*dy + k01*dz;
924 fZ += k10*dy + k11*dz;
931 // Empirical factor set by C.Xu in the first tilt version
932 // Is this factor still ok ????
933 Double_t xuFactor = 100.0;
939 if (TMath::Abs(dz) > padlength/2.0) {
940 Float_t dy2 = c->GetY() - fY;
941 Float_t sign = (dz > 0.0) ? -1.0 : 1.0;
942 dy2 += h01 * sign * padlength/2.0;
947 r00 = c->GetSigmaY2() + errang + add;
949 r11 = c->GetSigmaZ2() * xuFactor;
950 r00 += (fCyy + 2.0*h01*fCzy + h01*h01*fCzz);
951 r01 += (fCzy + h01*fCzz);
954 det = r00*r11 - r01*r01;
960 k00 = fCyy*r00 + fCzy * (r01 + h01*r00);
961 k01 = fCyy*r01 + fCzy * (r11 + h01*r01);
962 k10 = fCzy*r00 + fCzz * (r01 + h01*r00);
963 k11 = fCzy*r01 + fCzz * (r11 + h01*r01);
964 k20 = fCey*r00 + fCez * (r01 + h01*r00);
965 k21 = fCey*r01 + fCez * (r11 + h01*r01);
966 k30 = fCty*r00 + fCtz * (r01 + h01*r00);
967 k31 = fCty*r01 + fCtz * (r11 + h01*r01);
968 k40 = fCcy*r00 + fCcz * (r01 + h01*r00);
969 k41 = fCcy*r01 + fCcz * (r11 + h01*r01);
971 cur = fC + k40*dy + k41*dz;
972 eta = fE + k20*dy + k21*dz;
973 if (TMath::Abs(cur*fX - eta) >= 0.9) {
977 fY += k00*dy + k01*dz;
978 fZ += k10*dy + k11*dz;
980 fT += k30*dy + k31*dz;
999 fCyy -= k00*fCyy + k01*fCzy;
1000 fCzy -= k00*c01 + k01*fCzz;
1001 fCey -= k00*c02 + k01*c12;
1002 fCty -= k00*c03 + k01*c13;
1003 fCcy -= k00*c04 + k01*c14;
1005 fCzz -= k10*c01 + k11*fCzz;
1006 fCez -= k10*c02 + k11*c12;
1007 fCtz -= k10*c03 + k11*c13;
1008 fCcz -= k10*c04 + k11*c14;
1010 fCee -= k20*c02 + k21*c12;
1011 fCte -= k20*c03 + k21*c13;
1012 fCce -= k20*c04 + k21*c14;
1014 fCtt -= k30*c03 + k31*c13;
1015 fCct -= k40*c03 + k41*c13;
1017 fCcc -= k40*c04 + k41*c14;
1019 Int_t n = GetNumberOfClusters();
1021 SetNumberOfClusters(n+1);
1023 SetChi2(GetChi2()+chisq);
1029 //_____________________________________________________________________________
1030 Int_t AliTRDtrack::UpdateMI(const AliTRDcluster *c, Double_t chisq
1031 , UInt_t index, Double_t h01
1035 // Assignes found cluster to the track and updates track information
1038 Bool_t fNoTilt = kTRUE;
1039 if (TMath::Abs(h01) > 0.003) {
1044 // Add angular effect to the error contribution and make correction
1045 // Still needed ????
1046 // AliTRDclusterCorrection *corrector = AliTRDclusterCorrection::GetCorrection();
1049 Double_t tangent2 = (fC*fX-fE) * (fC*fX-fE);
1050 if (tangent2 < 0.9) {
1051 tangent2 = tangent2 / (1.0 - tangent2);
1053 Double_t tangent = TMath::Sqrt(tangent2);
1054 if ((fC*fX-fE) < 0.0) {
1058 // Where are the parameters from ????
1059 Double_t errang = tangent2 * 0.04;
1060 Double_t errsys = 0.025*0.025 * 20.0; // Systematic error part
1062 Float_t extend = 1.0;
1063 if (c->GetNPads() == 4) extend = 2.0;
1065 /////////////////////////////////////////////////////////////////////////////
1067 // Is this still needed or will it be needed ????
1069 //if (c->GetNPads() == 5) extend = 3.0;
1070 //if (c->GetNPads() == 6) extend = 3.0;
1071 //if (c->GetQ() < 15) {
1075 // Will this be needed ????
1077 if (corrector !=0 ) {
1079 correction = corrector->GetCorrection(plane,c->GetLocalTimeBin(),tangent);
1080 if (TMath::Abs(correction)>0){
1082 errang = corrector->GetSigma(plane,c->GetLocalTimeBin(),tangent);
1084 errang += tangent2*0.04;
1089 // Double_t padlength = TMath::Sqrt(c->GetSigmaZ2()*12.);
1090 /////////////////////////////////////////////////////////////////////////////
1092 Double_t r00 = (c->GetSigmaY2() + errang + errsys) * extend;
1094 Double_t r11 = c->GetSigmaZ2()*10000.0;
1098 Double_t det =r00*r11 - r01*r01;
1104 Double_t k00 = fCyy*r00 + fCzy*r01;
1105 Double_t k01 = fCyy*r01 + fCzy*r11;
1106 Double_t k10 = fCzy*r00 + fCzz*r01;
1107 Double_t k11 = fCzy*r01 + fCzz*r11;
1108 Double_t k20 = fCey*r00 + fCez*r01;
1109 Double_t k21 = fCey*r01 + fCez*r11;
1110 Double_t k30 = fCty*r00 + fCtz*r01;
1111 Double_t k31 = fCty*r01 + fCtz*r11;
1112 Double_t k40 = fCcy*r00 + fCcz*r01;
1113 Double_t k41 = fCcy*r01 + fCcz*r11;
1115 Double_t dy = c->GetY() - fY;
1116 Double_t dz = c->GetZ() - fZ;
1117 Double_t cur = fC + k40*dy + k41*dz;
1118 Double_t eta = fE + k20*dy + k21*dz;
1122 if (TMath::Abs(cur*fX - eta) >= 0.9) {
1126 fY += k00*dy + k01*dz;
1127 fZ += k10*dy + k11*dz;
1134 Double_t padlength = TMath::Sqrt(c->GetSigmaZ2() * 12.0);
1135 // Empirical factor set by C.Xu in the first tilt version
1136 Double_t xuFactor = 1000.0;
1138 dy = c->GetY() - fY;
1139 dz = c->GetZ() - fZ;
1140 //dy = dy + h01*dz + correction; // Still needed ????
1142 Double_t tiltdz = dz;
1143 if (TMath::Abs(tiltdz) > padlength/2.0) {
1144 tiltdz = TMath::Sign(padlength/2.0,dz);
1146 dy = dy + h01*tiltdz;
1149 if (TMath::Abs(dz) > padlength/2.0) {
1150 //Double_t dy2 = c->GetY() - fY; // Still needed ????
1151 //Double_t sign = (dz>0) ? -1.: 1.;
1152 //dy2-=h01*sign*padlength/2.;
1157 Double_t s00 = (c->GetSigmaY2() + errang) * extend + errsys + add; // Error pad
1158 Double_t s11 = c->GetSigmaZ2() * xuFactor; // Error pad-row
1160 r00 = fCyy + 2*fCzy*h01 + fCzz*h01*h01 + s00;
1161 r01 = fCzy + fCzz*h01;
1163 det = r00*r11 - r01*r01;
1172 k00 = fCyy*r00 + fCzy * (r01 + h01*r00);
1173 k01 = fCyy*r01 + fCzy * (r11 + h01*r01);
1174 k10 = fCzy*r00 + fCzz * (r01 + h01*r00);
1175 k11 = fCzy*r01 + fCzz * (r11 + h01*r01);
1176 k20 = fCey*r00 + fCez * (r01 + h01*r00);
1177 k21 = fCey*r01 + fCez * (r11 + h01*r01);
1178 k30 = fCty*r00 + fCtz * (r01 + h01*r00);
1179 k31 = fCty*r01 + fCtz * (r11 + h01*r01);
1180 k40 = fCcy*r00 + fCcz * (r01 + h01*r00);
1181 k41 = fCcy*r01 + fCcz * (r11 + h01*r01);
1183 // Update measurement
1184 cur = fC + k40*dy + k41*dz;
1185 eta = fE + k20*dy + k21*dz;
1186 if (TMath::Abs(cur*fX - eta) >= 0.9) {
1189 fY += k00*dy + k01*dz;
1190 fZ += k10*dy + k11*dz;
1192 fT += k30*dy + k31*dz;
1203 // Update the covariance matrix
1204 Double_t oldyy = fCyy;
1205 Double_t oldzz = fCzz;
1206 //Double_t oldee = fCee;
1207 //Double_t oldcc = fCcc;
1208 Double_t oldzy = fCzy;
1209 Double_t oldey = fCey;
1210 Double_t oldty = fCty;
1211 Double_t oldcy = fCcy;
1212 Double_t oldez = fCez;
1213 Double_t oldtz = fCtz;
1214 Double_t oldcz = fCcz;
1215 //Double_t oldte = fCte;
1216 //Double_t oldce = fCce;
1217 //Double_t oldct = fCct;
1219 fCyy -= k00*oldyy + k01*oldzy;
1220 fCzy -= k10*oldyy + k11*oldzy;
1221 fCey -= k20*oldyy + k21*oldzy;
1222 fCty -= k30*oldyy + k31*oldzy;
1223 fCcy -= k40*oldyy + k41*oldzy;
1225 fCzz -= k10*oldzy + k11*oldzz;
1226 fCez -= k20*oldzy + k21*oldzz;
1227 fCtz -= k30*oldzy + k31*oldzz;
1228 fCcz -= k40*oldzy + k41*oldzz;
1230 fCee -= k20*oldey + k21*oldez;
1231 fCte -= k30*oldey + k31*oldez;
1232 fCce -= k40*oldey + k41*oldez;
1234 fCtt -= k30*oldty + k31*oldtz;
1235 fCct -= k40*oldty + k41*oldtz;
1237 fCcc -= k40*oldcy + k41*oldcz;
1239 Int_t n = GetNumberOfClusters();
1241 SetNumberOfClusters(n+1);
1243 SetChi2(GetChi2() + chisq);
1249 //_____________________________________________________________________________
1250 Int_t AliTRDtrack::UpdateMI(const AliTRDtracklet &tracklet)
1253 // Assignes found tracklet to the track and updates track information
1256 Double_t r00 = (tracklet.GetTrackletSigma2());
1258 Double_t r11 = 10000.0;
1263 Double_t det = r00*r11 - r01*r01;
1269 Double_t dy = tracklet.GetY() - fY;
1270 Double_t dz = tracklet.GetZ() - fZ;
1272 Double_t s00 = tracklet.GetTrackletSigma2(); // Error pad
1273 Double_t s11 = 100000.0; // Error pad-row
1274 Float_t h01 = tracklet.GetTilt();
1276 r00 = fCyy + fCzz*h01*h01 + s00;
1279 det = r00*r11 - r01*r01;
1288 Double_t k00 = fCyy*r00 + fCzy*r01;
1289 Double_t k01 = fCyy*r01 + fCzy*r11;
1290 Double_t k10 = fCzy*r00 + fCzz*r01;
1291 Double_t k11 = fCzy*r01 + fCzz*r11;
1292 Double_t k20 = fCey*r00 + fCez*r01;
1293 Double_t k21 = fCey*r01 + fCez*r11;
1294 Double_t k30 = fCty*r00 + fCtz*r01;
1295 Double_t k31 = fCty*r01 + fCtz*r11;
1296 Double_t k40 = fCcy*r00 + fCcz*r01;
1297 Double_t k41 = fCcy*r01 + fCcz*r11;
1299 // Update measurement
1300 Double_t cur = fC + k40*dy + k41*dz;
1301 Double_t eta = fE + k20*dy + k21*dz;
1302 if (TMath::Abs(cur*fX-eta) >= 0.9) {
1306 fY += k00*dy + k01*dz;
1307 fZ += k10*dy + k11*dz;
1309 fT += k30*dy + k31*dz;
1312 // Update the covariance matrix
1313 Double_t oldyy = fCyy;
1314 Double_t oldzz = fCzz;
1315 //Double_t oldee = fCee;
1316 //Double_t oldcc = fCcc;
1317 Double_t oldzy = fCzy;
1318 Double_t oldey = fCey;
1319 Double_t oldty = fCty;
1320 Double_t oldcy = fCcy;
1321 Double_t oldez = fCez;
1322 Double_t oldtz = fCtz;
1323 Double_t oldcz = fCcz;
1324 //Double_t oldte = fCte;
1325 //Double_t oldce = fCce;
1326 //Double_t oldct = fCct;
1328 fCyy -= k00*oldyy + k01*oldzy;
1329 fCzy -= k10*oldyy + k11*oldzy;
1330 fCey -= k20*oldyy + k21*oldzy;
1331 fCty -= k30*oldyy + k31*oldzy;
1332 fCcy -= k40*oldyy + k41*oldzy;
1334 fCzz -= k10*oldzy + k11*oldzz;
1335 fCez -= k20*oldzy + k21*oldzz;
1336 fCtz -= k30*oldzy + k31*oldzz;
1337 fCcz -= k40*oldzy + k41*oldzz;
1339 fCee -= k20*oldey + k21*oldez;
1340 fCte -= k30*oldey + k31*oldez;
1341 fCce -= k40*oldey + k41*oldez;
1343 fCtt -= k30*oldty + k31*oldtz;
1344 fCct -= k40*oldty + k41*oldtz;
1346 fCcc -= k40*oldcy + k41*oldcz;
1352 //_____________________________________________________________________________
1353 Int_t AliTRDtrack::Rotate(Double_t alpha, Bool_t absolute)
1356 // Rotates the track parameters in the R*phi plane,
1357 // if the absolute rotation alpha is in global system.
1358 // Otherwise the rotation is relative to the current rotation angle
1369 if (fAlpha < -TMath::Pi()) {
1370 fAlpha += 2.0 * TMath::Pi();
1372 if (fAlpha >= TMath::Pi()) {
1373 fAlpha -= 2.0 * TMath::Pi();
1378 Double_t ca = TMath::Cos(alpha);
1379 Double_t sa = TMath::Sin(alpha);
1380 Double_t r1 = fC*fX - fE;
1383 fY = -x1*sa + y1*ca;
1384 if ((r1*r1) > 1.0) {
1387 fE = fE*ca + (fC*y1 + TMath::Sqrt(1.0 - r1*r1)) * sa;
1389 Double_t r2 = fC*fX - fE;
1390 if (TMath::Abs(r2) >= 0.9) {
1391 Int_t n = GetNumberOfClusters();
1393 AliError(Form("Rotation failed N = %d !\n",n));
1398 if ((r2*r2) > 1.0) {
1401 Double_t y0 = fY + TMath::Sqrt(1.0 - r2*r2) / fC;
1402 if ((fY-y0)*fC >= 0.0) {
1403 Int_t n = GetNumberOfClusters();
1405 AliError(Form("Rotation failed N = %d !\n",n));
1411 Double_t f00 = ca-1.0;
1412 Double_t f24 = (y1 - r1*x1/TMath::Sqrt(1.0 - r1*r1)) * sa;
1413 Double_t f20 = fC*sa;
1414 Double_t f22 = (ca + sa*r1/TMath::Sqrt(1.0 - r1*r1)) - 1.0;
1417 Double_t b00 = fCyy*f00;
1418 Double_t b02 = fCyy*f20 + fCcy*f24 + fCey*f22;
1419 Double_t b10 = fCzy*f00;
1420 Double_t b12 = fCzy*f20 + fCcz*f24 + fCez*f22;
1421 Double_t b20 = fCey*f00;
1422 Double_t b22 = fCey*f20 + fCce*f24 + fCee*f22;
1423 Double_t b30 = fCty*f00;
1424 Double_t b32 = fCty*f20 + fCct*f24 + fCte*f22;
1425 Double_t b40 = fCcy*f00;
1426 Double_t b42 = fCcy*f20 + fCcc*f24 + fCce*f22;
1429 Double_t a00 = f00*b00;
1430 Double_t a02 = f00*b02;
1431 Double_t a22 = f20*b02 + f24*b42 + f22*b22;
1433 // F*C*Ft = C + (a + b + bt)
1434 fCyy += a00 + 2.0*b00;
1436 fCey += a02 + b20 + b02;
1441 fCee += a22 + 2.0*b22;
1448 //_____________________________________________________________________________
1449 Double_t AliTRDtrack::GetPredictedChi2(const AliTRDcluster *c, Double_t h01) const
1452 // Returns the track chi2
1455 Bool_t fNoTilt = kTRUE;
1456 if (TMath::Abs(h01) > 0.003) {
1468 dy = c->GetY() - fY;
1469 r00 = c->GetSigmaY2();
1470 chi2 = (dy*dy) / r00;
1475 Double_t padlength = TMath::Sqrt(c->GetSigmaZ2() * 12.0);
1477 r00 = c->GetSigmaY2();
1479 r11 = c->GetSigmaZ2();
1484 Double_t det = r00*r11 - r01*r01;
1485 if (TMath::Abs(det) < 1.e-10) {
1486 Int_t n = GetNumberOfClusters();
1488 AliError(Form("Singular matrix N = %d!\n",n));
1497 Double_t dy = c->GetY() - fY;
1498 Double_t dz = c->GetZ() - fZ;
1499 Double_t tiltdz = dz;
1500 if (TMath::Abs(tiltdz) > padlength/2.0) {
1501 tiltdz = TMath::Sign(padlength/2.0,dz);
1503 dy = dy + h01*tiltdz;
1505 chi2 = (dy*r00*dy + 2*r01*dy*dz + dz*r11*dz) / det;
1513 //_________________________________________________________________________
1514 void AliTRDtrack::GetPxPyPz(Double_t& px, Double_t& py, Double_t& pz) const
1517 // Returns reconstructed track momentum in the global system.
1520 Double_t pt = TMath::Abs(GetPt());
1521 Double_t r = fC*fX - fE;
1533 y0 = fY + TMath::Sqrt(1.0 - r*r) / fC;
1534 px = -pt * (fY - y0) * fC; //cos(phi);
1535 py = -pt * (fE - fX*fC); //sin(phi);
1539 Double_t tmp = px * TMath::Cos(fAlpha)
1540 - py * TMath::Sin(fAlpha);
1541 py = px * TMath::Sin(fAlpha)
1542 + py * TMath::Cos(fAlpha);
1547 //_________________________________________________________________________
1548 void AliTRDtrack::GetGlobalXYZ(Double_t& x, Double_t& y, Double_t& z) const
1551 // Returns reconstructed track coordinates in the global system.
1558 Double_t tmp = x * TMath::Cos(fAlpha)
1559 - y * TMath::Sin(fAlpha);
1560 y = x * TMath::Sin(fAlpha)
1561 + y * TMath::Cos(fAlpha);
1566 //_________________________________________________________________________
1567 void AliTRDtrack::ResetCovariance()
1570 // Resets covariance matrix
1574 fCzy = 0.0; fCzz *= 10.0;
1575 fCey = 0.0; fCez = 0.0; fCee *= 10.0;
1576 fCty = 0.0; fCtz = 0.0; fCte = 0.0; fCtt *= 10.0;
1577 fCcy = 0.0; fCcz = 0.0; fCce = 0.0; fCct = 0.0; fCcc *= 10.0;
1581 //_____________________________________________________________________________
1582 void AliTRDtrack::ResetCovariance(Float_t mult)
1585 // Resets covariance matrix
1589 fCzy *= 0.0; fCzz *= 1.0;
1590 fCey *= 0.0; fCez *= 0.0; fCee *= mult;
1591 fCty *= 0.0; fCtz *= 0.0; fCte *= 0.0; fCtt *= 1.0;
1592 fCcy *= 0.0; fCcz *= 0.0; fCce *= 0.0; fCct *= 0.0; fCcc *= mult;
1596 //_____________________________________________________________________________
1597 void AliTRDtrack::MakeBackupTrack()
1600 // Creates a backup track
1604 delete fBackupTrack;
1607 fBackupTrack = new AliTRDtrack(*this);
1611 //_____________________________________________________________________________
1612 Int_t AliTRDtrack::GetProlongation(Double_t xk, Double_t &y, Double_t &z)
1615 // Find prolongation at given x
1616 // Return 0 if it does not exist
1619 Double_t c1 = fC*fX - fE;
1620 if (TMath::Abs(c1) > 1.0) {
1624 Double_t r1 = TMath::Sqrt(1.0 - c1*c1);
1625 Double_t c2 = fC*xk - fE;
1626 if (TMath::Abs(c2) > 1.0) {
1630 Double_t r2 = TMath::Sqrt(1.0 - c2*c2);
1631 y = fY + (xk-fX)*(c1+c2)/(r1+r2);
1632 z = fZ + (xk-fX)*(c1+c2)/(c1*r2 + c2*r1)*fT;
1638 //_____________________________________________________________________________
1639 Int_t AliTRDtrack::PropagateToX(Double_t xr, Double_t step)
1642 // Propagate track to a given x position
1643 // Works inside of the 20 degree segmentation
1644 // (local cooordinate frame for TRD , TPC, TOF)
1646 // The material budget is taken from the geo manager
1654 // Critical alpha - cross sector indication
1655 const Double_t kAlphac = TMath::Pi()/9.0;
1656 const Double_t kTalphac = TMath::Tan(kAlphac*0.5);
1659 Double_t dir = (fX > xr) ? -1.0 : 1.0;
1661 for (Double_t x = fX + dir*step; dir*x < dir*xr; x += dir*step) {
1663 GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]);
1664 GetProlongation(x,y,z);
1665 xyz1[0] = x * TMath::Cos(fAlpha) + y * TMath::Sin(fAlpha);
1666 xyz1[1] = x * TMath::Sin(fAlpha) - y * TMath::Cos(fAlpha);
1669 AliKalmanTrack::MeanMaterialBudget(xyz0,xyz1,param);
1671 if ((param[0] > 0) &&
1673 PropagateTo(x,param[1],param[0]);
1675 if (fY > fX*kTalphac) {
1678 if (fY < -fX*kTalphac) {
1690 //_____________________________________________________________________________
1691 Int_t AliTRDtrack::PropagateToR(Double_t r,Double_t step)
1694 // Propagate a track to a given radial position
1695 // The rotation is always connected to the last track position
1704 Double_t radius = TMath::Sqrt(fX*fX + fY*fY);
1705 Double_t dir = (radius > r) ? -1.0 : 1.0;
1707 for (Double_t x = radius + dir*step; dir*x < dir*r; x += dir*step) {
1708 GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]);
1709 Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
1710 Rotate(alpha,kTRUE);
1711 GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]);
1712 GetProlongation(x,y,z);
1713 xyz1[0] = x * TMath::Cos(alpha) + y * TMath::Sin(alpha);
1714 xyz1[1] = x * TMath::Sin(alpha) - y * TMath::Cos(alpha);
1717 AliKalmanTrack::MeanMaterialBudget(xyz0,xyz1,param);
1718 if (param[1] <= 0.0) {
1719 param[1] = 100000000.0;
1721 PropagateTo(x,param[1],param[0]);
1724 GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]);
1725 Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
1726 Rotate(alpha,kTRUE);
1727 GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]);
1728 GetProlongation(r,y,z);
1729 xyz1[0] = r * TMath::Cos(alpha) + y * TMath::Sin(alpha);
1730 xyz1[1] = r * TMath::Sin(alpha) - y * TMath::Cos(alpha);
1733 AliKalmanTrack::MeanMaterialBudget(xyz0,xyz1,param);
1735 if (param[1] <= 0.0) {
1736 param[1] = 100000000.0;
1738 PropagateTo(r,param[1],param[0]);
1744 //_____________________________________________________________________________
1745 Int_t AliTRDtrack::GetSector() const
1748 // Return the current sector
1751 return Int_t(TVector2::Phi_0_2pi(fAlpha)
1752 / AliTRDgeometry::GetAlpha())
1753 % AliTRDgeometry::kNsect;
1757 //_____________________________________________________________________________
1758 Double_t AliTRDtrack::Get1Pt() const
1761 // Returns the inverse Pt (1/GeV/c)
1762 // (or 1/"most probable pt", if the field is too weak)
1765 if (TMath::Abs(GetLocalConvConst()) > kVeryBigConvConst) {
1766 return 1.0 / kMostProbableMomentum
1767 / TMath::Sqrt(1.0 + GetTgl()*GetTgl());
1770 return (TMath::Sign(1.0e-9,fC) + fC) * GetLocalConvConst();
1774 //_____________________________________________________________________________
1775 Double_t AliTRDtrack::GetP() const
1778 // Returns the total momentum
1781 return TMath::Abs(GetPt()) * TMath::Sqrt(1.0 + GetTgl()*GetTgl());
1785 //_____________________________________________________________________________
1786 Double_t AliTRDtrack::GetYat(Double_t xk) const
1789 // This function calculates the Y-coordinate of a track at
1790 // the plane x = xk.
1791 // Needed for matching with the TOF (I.Belikov)
1794 Double_t c1 = fC*fX - fE;
1795 Double_t r1 = TMath::Sqrt(1.0 - c1*c1);
1796 Double_t c2 = fC*xk - fE;
1797 Double_t r2 = TMath::Sqrt(1.0- c2*c2);
1799 return fY + (xk-fX)*(c1+c2)/(r1+r2);
1803 //_____________________________________________________________________________
1804 void AliTRDtrack::SetSampledEdx(Float_t q, Int_t i)
1807 // The sampled energy loss
1810 Double_t s = GetSnp();
1811 Double_t t = GetTgl();
1813 q *= TMath::Sqrt((1.0 - s*s) / (1.0 + t*t));
1818 //_____________________________________________________________________________
1819 void AliTRDtrack::SetSampledEdx(Float_t q)
1822 // The sampled energy loss
1825 Double_t s = GetSnp();
1826 Double_t t = GetTgl();
1828 q*= TMath::Sqrt((1.0 - s*s) / (1.0 + t*t));
1834 //_____________________________________________________________________________
1835 void AliTRDtrack::GetXYZ(Float_t r[3]) const
1838 // Returns the position of the track in the global coord. system
1841 Double_t cs = TMath::Cos(fAlpha);
1842 Double_t sn = TMath::Sin(fAlpha);
1843 r[0] = fX*cs - fY*sn;
1844 r[1] = fX*sn + fY*cs;