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 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////////
18 // Kalman filter based aligner:
19 // Aligns two tracking volumes (by default ITS and TPC)
20 // Determines the transformation of the second volume (TPC) wrt the first (ITS)
21 // additionally calculates some callibration parameters for TPC
22 // Fit parameters are:
24 // - 3 Cardan angles, psi, theta, phi (see definition in alignment docs),
25 // - TPC drift velocity correction (vel_true = vel*(1+correction)),
26 // - TPC offset correction.
29 // When aligning two volumes at any given time a single instance of
30 // the class should be active. The fit of the parameters is updated
31 // by adding new data using one of the Add.... methods.
34 // In collision events add an ESD track to update the fit,
35 // track will be automatically split in ITS and TPC tracklets
36 // and the fit of the alignment constants will be updated:
38 // Bool_t AddESDTrack( AliESDtrack* pTrack );
40 // You may also give it the AliTrackPointArray,
41 // the fit will be updated if there are enough ITS and TPC
42 // points in it. Again, all is done automatically:
44 // Bool_t AddTrackPointArray( AliTrackPointArray* pTrackPointArr );
46 // For cosmic data, the assumption is that the tracking is done separately
47 // for ITS and TPC and the tracklets are saved inside one AliESDEvent. The
50 // Bool_t AddCosmicEventSeparateTracking( AliESDEvent* pEvent );
52 // then searches the event for matching tracklets and upon succes it updates
53 // the fit. For cosmics the fitter switches to a 3 tracks mode, the 3 tracks
54 // being: 1 ITS and 2 TPC tracklets (upper and lower).
59 // Origin: Mikolaj Krzewicki, Nikhef, Mikolaj.Krzewicki@cern.ch
61 //////////////////////////////////////////////////////////////////////////////
63 #include <Riostream.h>
65 #include "AliRelAlignerKalman.h"
67 ClassImp(AliRelAlignerKalman)
69 //########################################################
73 //########################################################
75 AliRelAlignerKalman::AliRelAlignerKalman():
76 fPTrackPointArray1(new AliTrackPointArray(1)),
77 fPTrackPointArray2(new AliTrackPointArray(1)),
78 fPTrackPointArray2b(new AliTrackPointArray(1)),
79 fPVolIDArray1(new TArrayI(1)),
80 fPVolIDArray2(new TArrayI(1)),
81 fPVolIDArray2b(new TArrayI(1)),
83 fNMeasurementParams(fgkNMeasurementParams2TrackMode),
84 fNSystemParams(fgkNSystemParams),
87 fSortTrackPointsWithY(kTRUE),
88 fFixedMeasurementCovariance(kTRUE),
89 fCalibrationPass(kFALSE),
90 fCalibrationUpdated(kFALSE),
106 fMaxMatchingAngle(0.1),
107 fMaxMatchingDistance(1.), //in cm
113 //Default constructor
115 fPDir1 = new TVector3; //Direction
116 fPDir2 = new TVector3;
117 fPDir2b = new TVector3;
118 fPDir1Cov = new TMatrixDSym(3);
119 fPDir2Cov = new TMatrixDSym(3);
120 fPDir2bCov = new TMatrixDSym(3);
121 fPDir1ThetaPhiCov = new TMatrixDSym(2); //Direction vectors are unit vectors, therefore 2 independent components!
122 fPDir2ThetaPhiCov = new TMatrixDSym(2);
123 fPDir2bThetaPhiCov = new TMatrixDSym(2);
124 fPPoint1 = new TVector3;
125 fPPoint2 = new TVector3;
126 fPPoint2b = new TVector3;
127 fPPoint1Cov = new TMatrixDSym(3);
128 fPPoint2Cov = new TMatrixDSym(3);
129 fPPoint2bCov = new TMatrixDSym(3);
130 fPRefPoint = new TVector3(0.,0.,0.);
131 fPRefPointDir = new TVector3(0.,1.,0.);
132 Float_t refpointcov[6] = { 1., 0., 0.,
135 fPRefAliTrackPoint = new AliTrackPoint( 0.,0.,0.,refpointcov,0 );
136 fPMeasurement = new TVectorD( fNMeasurementParams );
137 fPMeasurementCov = new TMatrixDSym( fNMeasurementParams );
138 fPX = new TVectorD( fNSystemParams );
139 fPXcov = new TMatrixDSym( fNSystemParams );
140 fPH = new TMatrixD( fNMeasurementParams, fNSystemParams );
141 fPRotMat = new TMatrixD(3,3);
142 fPVec010 = new TVector3(0,1,0);
144 //default seed: zero, unit(large) errors
145 fPXcov->UnitMatrix();
148 fPPhiMesHist = new TH1D("phi","phi", 50, 0, 0);
149 fPThetaMesHist = new TH1D("theta","theta", 50, 0, 0);
150 fPXMesHist = new TH1D("x","x", 50, 0, 0);
151 fPZMesHist = new TH1D("z","z", 50, 0, 0);
152 fPPhiMesHist2 = new TH1D("phi_","phi_", 50, 0, 0);
153 fPThetaMesHist2 = new TH1D("theta_","theta_", 50, 0, 0);
154 fPXMesHist2 = new TH1D("x_","x_", 50, 0, 0);
155 fPZMesHist2 = new TH1D("z_","z_", 50, 0, 0);
158 Bool_t AliRelAlignerKalman::AddESDTrack( AliESDtrack* pTrack )
160 //Add an ESD track from a central event
161 //from the ESDtrack extract the pointarray
163 SetCosmicEvent(kFALSE);
165 const AliTrackPointArray *pTrackPointArrayConst = pTrack->GetTrackPointArray();
166 AliTrackPointArray* pTrackPointArray = const_cast < AliTrackPointArray* > (pTrackPointArrayConst);
167 if (pTrackPointArray == 0) return kFALSE;
169 if (!AddTrackPointArray( pTrackPointArray )) return kFALSE;
173 Bool_t AliRelAlignerKalman::AddTrackPointArray( AliTrackPointArray* pTrackPointArray )
175 //Add a trackpointarray from a central event
177 SetCosmicEvent(kFALSE);
180 if (!ExtractSubTrackPointArray( fPTrackPointArray1, fPVolIDArray1, pTrackPointArray, 1,6 ))
182 if (!ExtractSubTrackPointArray( fPTrackPointArray2, fPVolIDArray2, pTrackPointArray, 7,8 ))
185 if (!ProcessTrackPointArrays()) return kFALSE;
186 if (!PrepareUpdate()) return kFALSE;
187 if (!Update()) return kFALSE;
192 Bool_t AliRelAlignerKalman::AddCosmicEventSeparateTracking( AliESDEvent* pEvent )
194 //Add an cosmic with separately tracked ITS and TPC parts, do trackmatching
196 SetCosmicEvent(kTRUE); //set the cosmic flag
199 if (!FindCosmicInEvent( pEvent )) return kFALSE;
200 if (!ProcessTrackPointArrays()) return kFALSE;
202 if (!PrepareUpdate()) return kFALSE;
203 if (!Update()) return kFALSE;
204 printf("fpMeasurementCov:\n");
205 fPMeasurementCov->Print();
210 void AliRelAlignerKalman::Print()
212 //Print some useful info
213 printf("\nAliRelAlignerKalman:\n");
214 printf(" %i tracks, %i updates, %i outliers, ", fNTracks, fNUpdates, fNOutliers );
215 printf("%i not fitted, %i matched cosmic tracklets\n", fNUnfitted, fNMatchedCosmics );
216 printf(" psi(x): %.1f ± (%.1f) mrad\n", 1e3*(*fPX)(0),1e3*TMath::Sqrt((*fPXcov)(0,0)));
217 printf(" theta(y): %.1f ± (%.1f) mrad\n", 1e3*(*fPX)(1),1e3*TMath::Sqrt((*fPXcov)(1,1)));
218 printf(" phi(z): %.1f ± (%.1f) mrad\n", 1e3*(*fPX)(2),1e3*TMath::Sqrt((*fPXcov)(2,2)));
219 printf(" x: %.1f ± (%.1f) micron\n", 1e4*(*fPX)(3),1e4*TMath::Sqrt((*fPXcov)(3,3)));
220 printf(" y: %.1f ± (%.1f) micron\n", 1e4*(*fPX)(4),1e4*TMath::Sqrt((*fPXcov)(4,4)));
221 printf(" z: %.1f ± (%.1f) micron\n", 1e4*(*fPX)(5),1e4*TMath::Sqrt((*fPXcov)(5,5)));
222 printf(" TPC(drift corr) %.1f ± (%.1f) percent\n", 1e2*(*fPX)(6),1e2*TMath::Sqrt((*fPXcov)(6,6)));
223 printf(" TPC(offset) %.1f ± (%.1f) micron\n", 1e4*(*fPX)(7),1e4*TMath::Sqrt((*fPXcov)(7,7)));
227 void AliRelAlignerKalman::SetTrackParams1( const TVector3& point, const TMatrixDSym& pointcov, const TVector3& dir, const TMatrixDSym& dircov )
229 //Set the trackparameters for track in the first volume at reference
231 *fPPoint1Cov = pointcov;
236 void AliRelAlignerKalman::SetTrackParams2( const TVector3& point, const TMatrixDSym& pointcov, const TVector3& dir, const TMatrixDSym& dircov )
238 //Set the trackparameters for track in the second volume at reference
240 *fPPoint2Cov = pointcov;
245 void AliRelAlignerKalman::SetTrackParams2b( const TVector3& point, const TMatrixDSym& pointcov, const TVector3& dir, const TMatrixDSym& dircov )
247 //Set the trackparameters for second track in the second volume at reference
249 *fPPoint2bCov = pointcov;
251 *fPDir2bCov = dircov;
254 void AliRelAlignerKalman::SetRefSurface( const Double_t yref )
256 //set the reference surface
257 fPRefPoint->SetXYZ( 0., 1.*yref, 0. );
258 fPRefPointDir->SetXYZ( 0., 1., 0. );
259 Float_t refpointcov[6] = { 1., 0., 0.,
262 fPRefAliTrackPoint->SetXYZ( 0., 1.*yref, 0., refpointcov );
265 void AliRelAlignerKalman::SetRefSurface( const TVector3& point, const TVector3& dir )
267 //set the reference surface
269 *fPRefPointDir = dir;
272 void AliRelAlignerKalman::SetRefSurface( const AliTrackPoint& point, const Bool_t horizontal )
274 //set the reference surface
275 (*fPRefAliTrackPoint) = point;
277 (*fPRefPoint)(0) = point.GetX();
278 (*fPRefPoint)(1) = point.GetY();
279 (*fPRefPoint)(2) = point.GetZ();
283 (*fPRefPointDir)(0) = 0.;
284 (*fPRefPointDir)(1) = 1.;
285 (*fPRefPointDir)(2) = 0.;
287 Float_t refpointcov[6] = { 1., 0., 0.,
290 fPRefAliTrackPoint->SetXYZ( point.GetX(), point.GetY() , point.GetZ(), refpointcov );
295 Double_t angle = point.GetAngle();
296 (*fPRefPointDir)(0) = TMath::Cos(angle);
297 (*fPRefPointDir)(1) = TMath::Sin(angle);
298 (*fPRefPointDir)(2) = 0.;
299 *fPRefPointDir = fPRefPointDir->Unit();
303 void AliRelAlignerKalman::Set3TracksMode( Bool_t mode )
305 //set the mode where 2 tracklets are allowed in volume 2 (default:TPC)
306 //used for alignment with cosmics
311 if (fNMeasurementParams!=fgkNMeasurementParams3TrackMode) //do something only if necessary
313 fNMeasurementParams = fgkNMeasurementParams3TrackMode;
314 delete fPMeasurement;
315 delete fPMeasurementCov;
317 fPMeasurement = new TVectorD( fNMeasurementParams );
318 fPMeasurementCov = new TMatrixDSym( fNMeasurementParams );
319 fPH = new TMatrixD( fNMeasurementParams, fNSystemParams );
324 if (fNMeasurementParams!=fgkNMeasurementParams2TrackMode)
326 fNMeasurementParams = fgkNMeasurementParams2TrackMode;
327 delete fPMeasurement;
328 delete fPMeasurementCov;
330 fPMeasurement = new TVectorD( fNMeasurementParams );
331 fPMeasurementCov = new TMatrixDSym( fNMeasurementParams );
332 fPH = new TMatrixD( fNMeasurementParams, fNSystemParams );
337 Bool_t AliRelAlignerKalman::PrepareUpdate()
339 //Cast the extrapolated data (points and directions) into
340 //the internal Kalman filter data representation.
341 //takes the 3d coordinates of the points of intersection with
342 //the reference surface and projects them onto a 2D plane.
343 //does the same for angles, combines the result in one vector
345 if (!FillMeasurement()) return kFALSE;
346 if (!FillMeasurementMatrix()) return kFALSE;
350 Bool_t AliRelAlignerKalman::Update()
352 //perform the update - either kalman or calibration
353 if (fCalibrationPass) return UpdateCalibration();
354 else return UpdateEstimateKalman();
357 void AliRelAlignerKalman::RotMat( TMatrixD &R, const TVectorD& angles )
359 //Get Rotation matrix R given the Cardan angles psi, theta, phi (around x, y, z).
360 Double_t sinpsi = TMath::Sin(angles(0));
361 Double_t sintheta = TMath::Sin(angles(1));
362 Double_t sinphi = TMath::Sin(angles(2));
363 Double_t cospsi = TMath::Cos(angles(0));
364 Double_t costheta = TMath::Cos(angles(1));
365 Double_t cosphi = TMath::Cos(angles(2));
367 R(0,0) = costheta*cosphi;
368 R(0,1) = -costheta*sinphi;
370 R(1,0) = sinpsi*sintheta*cosphi + cospsi*sinphi;
371 R(1,1) = -sinpsi*sintheta*sinphi + cospsi*cosphi;
372 R(1,2) = -costheta*sinpsi;
373 R(2,0) = -cospsi*sintheta*cosphi + sinpsi*sinphi;
374 R(2,1) = cospsi*sintheta*sinphi + sinpsi*cosphi;
375 R(2,2) = costheta*cospsi;
379 Bool_t AliRelAlignerKalman::FillMeasurement()
381 //Take the track parameters and calculate the input to the Kalman filter
384 //Measured is the difference between the polar angles - convert to that
385 (*fPMeasurement)(0) = fPDir2->Theta() - fPDir1->Theta();
386 (*fPMeasurement)(1) = fPDir2->Phi() - fPDir1->Phi();
389 //Measured is the distance in XZ plane at Y of the reference point
390 (*fPMeasurement)(2) = fPPoint2->X() - fPPoint1->X();
391 (*fPMeasurement)(3) = fPPoint2->Z() - fPPoint1->Z();
393 //if 3 track mode set, set also the stuff for 2nd TPC track
396 (*fPMeasurement)(4) = fPDir2b->Theta() - fPDir1->Theta();
397 (*fPMeasurement)(5) = fPDir2b->Phi() - fPDir1->Phi();
398 (*fPMeasurement)(6) = fPPoint2b->X() - fPPoint1->X();
399 (*fPMeasurement)(7) = fPPoint2b->Z() - fPPoint1->Z();
402 //Fill the covariance
403 if (fFixedMeasurementCovariance) return kTRUE;
405 GetThetaPhiCov( *fPDir1ThetaPhiCov, *fPDir1, *fPDir1Cov );
406 GetThetaPhiCov( *fPDir2ThetaPhiCov, *fPDir2, *fPDir2Cov );
407 fPMeasurementCov->SetSub( 0, (*fPDir1ThetaPhiCov) + (*fPDir2ThetaPhiCov) );
410 (*fPMeasurementCov)(2,2) = (*fPPoint1Cov)(0,0)+(*fPPoint2Cov)(0,0);
411 (*fPMeasurementCov)(2,3) = (*fPPoint1Cov)(0,2)+(*fPPoint2Cov)(0,2);
412 (*fPMeasurementCov)(3,2) = (*fPPoint1Cov)(2,0)+(*fPPoint2Cov)(2,0);
413 (*fPMeasurementCov)(3,3) = (*fPPoint1Cov)(2,2)+(*fPPoint2Cov)(2,2);
415 //if 3 track mode set, set also the stuff for 2nd TPC track
418 GetThetaPhiCov( *fPDir2bThetaPhiCov, *fPDir2b, *fPDir2bCov );
419 fPMeasurementCov->SetSub( 4, (*fPDir1ThetaPhiCov) + (*fPDir2bThetaPhiCov) );
420 (*fPMeasurementCov)(6,6) = (*fPPoint1Cov)(0,0)+(*fPPoint2bCov)(0,0);
421 (*fPMeasurementCov)(6,7) = (*fPPoint1Cov)(0,2)+(*fPPoint2bCov)(0,2);
422 (*fPMeasurementCov)(7,6) = (*fPPoint1Cov)(2,0)+(*fPPoint2bCov)(2,0);
423 (*fPMeasurementCov)(7,7) = (*fPPoint1Cov)(2,2)+(*fPPoint2bCov)(2,2);
428 Bool_t AliRelAlignerKalman::FillMeasurementMatrix()
430 //Calculate the system matrix for the Kalman filter
431 //approximate the system using as reference the track in the first volume
433 Double_t delta = 1.e-8;
434 TVectorD z1( fNMeasurementParams );
435 TVectorD z2( fNMeasurementParams );
438 TMatrixD D( fNMeasurementParams, 1 );
439 for ( Int_t i=0; i<fNSystemParams; i++ )
445 if (!PredictMeasurement( z1, x1 )) return kFALSE;
446 if (!PredictMeasurement( z2, x2 )) return kFALSE;
447 for (Int_t j=0; j<fNMeasurementParams; j++ )
448 D.GetMatrixArray()[j] = (z2.GetMatrixArray()[j]-z1.GetMatrixArray()[j])/(2.*delta);
449 fPH->SetSub( 0, i, D );
454 Bool_t AliRelAlignerKalman::PredictMeasurement( TVectorD& pred, const TVectorD& state )
456 // Implements a system model for the Kalman fit
457 // pred is [dtheta, dphi, dx, dz, [dtheta', dphi', dx', dz'] ] - second part is for 2nd TPC track in cosmics
458 // state is [psi,theta,phi,x,y,z,driftTPC,offsetTPC]
460 TVector3 newPoint = *fPPoint1;
461 TVector3 newDir = *fPDir1;
463 //TPC drift correction
464 newDir(2) *= (1.+state(6));
465 newPoint(2) *= (1.+state(6));
467 if (newPoint(2)>0) newPoint(2) += state(7);
468 else newPoint(2) -= state(7);
470 TMatrixD rotmat(3,3);
471 RotMat( rotmat, state );
472 newDir = rotmat * newDir;
473 newPoint = rotmat * newPoint;
479 //Predicted measurement
480 if (!IntersectionLinePlane( newPoint, newPoint, newDir, *fPRefPoint, *fPVec010 )) return kFALSE;
481 pred(0) = newDir.Theta() - fPDir1->Theta();
482 pred(1) = newDir.Phi() - fPDir1->Phi();
483 pred(2) = newPoint(0) - fPPoint1->X();
484 pred(3) = newPoint(2) - fPPoint1->Z();
488 //Do the same for second TPC track
489 //should be the same as the first TPC track
498 Bool_t AliRelAlignerKalman::UpdateEstimateKalman()
500 //Kalman estimation of noisy constants: in the model A=1
501 //The arguments are (following the usual convention):
502 // x - the state vector (parameters)
503 // P - the state covariance matrix (parameter errors)
504 // z - measurement vector
505 // R - measurement covariance matrix
506 // H - measurement model matrix ( z = Hx + v ) v being measurement noise (error fR)
508 TMatrixDSym *P = fPXcov;
509 TVectorD *z = fPMeasurement;
510 TMatrixDSym *R = fPMeasurementCov;
513 TMatrixDSym I(TMatrixDSym::kUnit, *P); //unit matrix
516 *P = *P + fQ*I; //add some process noise (diagonal)
518 // update prediction with measurement
519 // calculate Kalman gain
521 TMatrixD PHT( *P, TMatrixD::kMultTranspose, *H ); //common factor (used twice)
522 TMatrixD HPHT( *H, TMatrixD::kMult, PHT );
524 TMatrixD K(PHT, TMatrixD::kMult, HPHT.Invert()); //compute K
526 // update the state and its covariance matrix
527 TVectorD xupdate(*x);
529 PredictMeasurement( Hx, *x );
530 xupdate = K*((*z)-Hx);
532 //SIMPLE OUTLIER REJECTION
534 (TMath::Abs(xupdate(0)) > fOutRejSigmas*TMath::Sqrt((*P)(0,0))) ||
535 (TMath::Abs(xupdate(1)) > fOutRejSigmas*TMath::Sqrt((*P)(1,1))) ||
536 (TMath::Abs(xupdate(2)) > fOutRejSigmas*TMath::Sqrt((*P)(2,2))) ||
537 (TMath::Abs(xupdate(3)) > fOutRejSigmas*TMath::Sqrt((*P)(3,3))) ||
538 (TMath::Abs(xupdate(4)) > fOutRejSigmas*TMath::Sqrt((*P)(4,4))) ||
539 (TMath::Abs(xupdate(5)) > fOutRejSigmas*TMath::Sqrt((*P)(5,5))) ||
540 (TMath::Abs(xupdate(6)) > fOutRejSigmas*TMath::Sqrt((*P)(6,6))) ||
541 (TMath::Abs(xupdate(7)) > fOutRejSigmas*TMath::Sqrt((*P)(7,7)))
549 TMatrixD KH( K, TMatrixD::kMult, *H );
552 TMatrixD IKHP( IKH, TMatrixD::kMult, *P ); // (I-KH)P
553 TMatrixDSym_from_TMatrixD( *P, IKHP );
558 void AliRelAlignerKalman::TMatrixDSym_from_TMatrixD( TMatrixDSym& matsym, const TMatrixD& mat )
560 //Produce a valid symmetric matrix out of a TMatrixD
562 //not very efficient, diagonals are computer twice, but who cares
563 for (Int_t i=0; i<mat.GetNcols(); i++)
565 for (Int_t j=i; j<mat.GetNcols(); j++)
567 Double_t average = (mat(i,j)+mat(j,i))/2.;
575 void AliRelAlignerKalman::GetThetaPhiCov( TMatrixDSym& cov, const TVector3& vec, const TMatrixDSym& vecCov )
577 //Given the covariance matrix of a vector in euclid.space
578 //give cov matrix of the 2 spherical angles
579 const Double_t delta = 1e-8;
583 for (Int_t i=0; i<3; i++)
589 T(0,i) = (vec2.Theta() - vec1.Theta())/delta;
590 T(1,i) = (vec2.Phi() - vec1.Phi())/delta;
592 TMatrixD tmp( T, TMatrixD::kMult, vecCov );
593 TMatrixD nscov( tmp, TMatrixD::kMultTranspose, T );
594 cov(0,0) = nscov(0,0); cov(0,1) = nscov(0,1);
595 cov(1,0) = nscov(0,1); cov(1,1) = nscov(1,1);
599 Bool_t AliRelAlignerKalman::IntersectionLinePlane( TVector3& intersection, const TVector3& linebase, const TVector3& linedir, const TVector3& planepoint, const TVector3& planenormal )
601 //calculate the intersection point between a straight line and a plane
602 //plane is defined with a point in it and a normal, line has a point and direction
603 if (planenormal==TVector3(0,1,0))
605 if (linedir(1)==0) return kFALSE;
606 Double_t t = ( planepoint(1) - linebase(1) ) / linedir(1);
607 intersection = linebase + t*linedir;
612 Double_t dirdotn = linedir.Dot(planenormal);
613 if (dirdotn==0) return kFALSE;
614 Double_t t = ( planepoint.Dot(planenormal) - linebase.Dot(planenormal) ) / dirdotn;
615 intersection = linebase + t*linedir;
620 void AliRelAlignerKalman::Angles( TVectorD &angles, const TMatrixD &rotmat )
622 //Calculate the Cardan angles (psi,theta,phi) from rotation matrix
625 angles(0) = TMath::ATan2( -rotmat(1,2), rotmat(2,2) );
626 angles(1) = TMath::ASin( rotmat(0,2) );
627 angles(2) = TMath::ATan2( -rotmat(0,1), rotmat(0,0) );
631 void AliRelAlignerKalman::PrintCorrelationMatrix()
633 //Print the correlation matrix for the fitted parameters
635 for ( Int_t j=0; j<fNSystemParams; j++ )
637 for ( Int_t i=0; i<fNSystemParams; i++ )
639 printf("%1.2f ", (*fPXcov)(i,j)/TMath::Sqrt( (*fPXcov)(i,i) * (*fPXcov)(j,j) ) );
647 Bool_t AliRelAlignerKalman::FindCosmicInEvent( AliESDEvent* pEvent )
649 //Find track point arrays belonging to one cosmic in a separately tracked ESD
650 //and put them in the apropriate data members
652 //Sanity cuts on tracks + check which tracks are ITS which are TPC
653 Int_t ntracks = pEvent->GetNumberOfTracks(); //printf("number of tracks in event: %i\n", ntracks);
654 if(ntracks<2) return kFALSE;
655 Float_t* phiArr = new Float_t[ntracks];
656 Float_t* thetaArr = new Float_t[ntracks];
657 Double_t* distanceFromVertexArr = new Double_t[ntracks];
658 Int_t* goodtracksArr = new Int_t[ntracks];
659 Int_t* ITStracksArr = new Int_t[ntracks];
660 Int_t* TPCtracksArr = new Int_t[ntracks];
661 Int_t* nPointsArr = new Int_t[ntracks];
662 Int_t nITStracks = 0;
663 Int_t nTPCtracks = 0;
664 Int_t nGoodTracks = 0;
665 AliESDtrack* pTrack = NULL;
667 const AliESDVertex* pVertex = pEvent->GetVertex();
668 Double_t vertexposition[3];
669 pVertex->GetXYZ(vertexposition);
671 Double_t magfield = pEvent->GetMagneticField();
674 for (Int_t itrack=0; itrack < ntracks; itrack++)
676 pTrack = pEvent->GetTrack(itrack);
677 if (!pTrack) {cout<<"no track!"<<endl;continue;}
678 if(pTrack->GetNcls(0)+pTrack->GetNcls(1) < fMinPointsVol1) continue;
679 Float_t phi = pTrack->GetAlpha()+TMath::ASin(pTrack->GetSnp());
680 Float_t theta = 0.5*TMath::Pi()-TMath::ATan(pTrack->GetTgl());
681 //printf("phi: %4.2f theta: %4.2f\n", phi, theta);
684 if(pTrack->GetP()<fMinMom || pTrack->GetP()>fMaxMom) continue;
685 Float_t abssinphi = TMath::Abs(TMath::Sin(phi));
686 if(abssinphi<fMinAbsSinPhi || abssinphi>fMaxAbsSinPhi) continue;
687 Float_t sintheta = TMath::Sin(theta);
688 if(sintheta<fMinSinTheta || sintheta>fMaxSinTheta) continue;
690 goodtracksArr[nGoodTracks]=itrack;
691 phiArr[nGoodTracks]=phi;
692 thetaArr[nGoodTracks]=theta;
694 pTrack->RelateToVertex( pVertex, magfield, 10000. );
695 Double_t trackposition[3];
696 pTrack->GetXYZ( trackposition );
697 distanceFromVertexArr[nGoodTracks] =
698 TMath::Sqrt((trackposition[0]-vertexposition[0])*(trackposition[0]-vertexposition[0])
699 + (trackposition[1]-vertexposition[1])*(trackposition[1]-vertexposition[1])
700 + (trackposition[2]-vertexposition[2])*(trackposition[2]-vertexposition[2]));
702 //check if track is ITS or TPC
703 if ( ((pTrack->GetStatus()&AliESDtrack::kITSin)>0)&&
704 !((pTrack->GetStatus()&AliESDtrack::kTPCin)>0) )
706 ITStracksArr[nITStracks] = nGoodTracks;
710 if ( ((pTrack->GetStatus()&AliESDtrack::kTPCin)>0)&&
711 !((pTrack->GetStatus()&AliESDtrack::kITSin)>0) )
713 TPCtracksArr[nTPCtracks] = nGoodTracks;
718 }//for itrack - sanity cuts
720 //printf("there are good tracks, %d in ITS and %d TPC.\n", nITStracks, nTPCtracks);
722 if( nITStracks < 2 || nTPCtracks < 2 )
724 delete [] goodtracksArr; goodtracksArr=0;
725 delete [] ITStracksArr; ITStracksArr=0;
726 delete [] TPCtracksArr; TPCtracksArr=0;
727 delete [] nPointsArr; nPointsArr=0;
728 delete [] phiArr; phiArr=0;
729 delete [] thetaArr; thetaArr=0;
730 delete [] distanceFromVertexArr; distanceFromVertexArr=0;
734 //find matching in TPC
735 Float_t min = 10000000.;
736 Int_t TPCgood1 = -1, TPCgood2 = -1;
737 for(Int_t itr1=0; itr1<nTPCtracks; itr1++)
739 for(Int_t itr2=itr1+1; itr2<nTPCtracks; itr2++)
741 Float_t deltatheta = TMath::Abs(TMath::Pi()-thetaArr[TPCtracksArr[itr1]]-thetaArr[TPCtracksArr[itr2]]);
742 if(deltatheta > fMaxMatchingAngle) continue;
743 Float_t deltaphi = TMath::Abs(TMath::Abs(phiArr[TPCtracksArr[itr1]]-phiArr[TPCtracksArr[itr2]])-TMath::Pi());
744 if(deltaphi > fMaxMatchingAngle) continue;
745 //printf("TPC: %f %f %f %f\n",deltaphi,deltatheta,thetaArr[TPCtracksArr[itr1]],thetaArr[TPCtracksArr[itr2]]);
746 if(deltatheta+deltaphi<min) //only the best matching pair
748 min=deltatheta+deltaphi;
749 TPCgood1 = TPCtracksArr[itr1]; //store the index of track in goodtracksArr[]
750 TPCgood2 = TPCtracksArr[itr2];
754 if (TPCgood1 < 0) //no dubble cosmic track
756 delete [] goodtracksArr; goodtracksArr=0;
757 delete [] ITStracksArr; ITStracksArr=0;
758 delete [] TPCtracksArr; TPCtracksArr=0;
759 delete [] nPointsArr; nPointsArr=0;
760 delete [] phiArr; phiArr=0;
761 delete [] thetaArr; thetaArr=0;
762 delete [] distanceFromVertexArr; distanceFromVertexArr=0;
766 //in ITS find 2 tracks that best match the found TPC cosmic
767 Double_t min1 = 10000000.;
768 Double_t min2 = 10000000.;
769 Int_t ITSgood1 = -1, ITSgood2 = -1;
770 for(Int_t itr1=0; itr1<nITStracks; itr1++)
772 if(distanceFromVertexArr[ITStracksArr[itr1]]>fMaxMatchingDistance) continue;
773 Float_t deltatheta = TMath::Abs(TMath::Pi()-thetaArr[ITStracksArr[itr1]]-thetaArr[TPCgood1]);
774 if(deltatheta > fMaxMatchingAngle) deltatheta = TMath::Abs( deltatheta - TMath::Pi() );
775 if(deltatheta > fMaxMatchingAngle) continue;
776 Float_t deltaphi = TMath::Abs(TMath::Abs(phiArr[ITStracksArr[itr1]]-phiArr[TPCgood1])-TMath::Pi());
777 if(deltaphi > fMaxMatchingAngle) deltaphi = TMath::Abs( deltaphi - TMath::Pi() );
778 if(deltaphi > fMaxMatchingAngle) continue;
779 //printf("ITS %i dtheta, dphi, vrtx: %.4f, %.4f, %.4f\n",ITStracksArr[itr1], deltatheta, deltaphi,distanceFromVertexArr[ITStracksArr[itr1]]);
780 if(deltatheta+deltaphi<min1) //only the best one
782 min1=deltatheta+deltaphi;
783 //ITSgood2 = ITSgood1;
784 ITSgood1 = ITStracksArr[itr1];
787 if(deltatheta+deltaphi<min2) //the second best
789 min2=deltatheta+deltaphi;
790 ITSgood2 = ITStracksArr[itr1];
794 if (ITSgood2 < 0) //no ITS cosmic track
796 delete [] goodtracksArr; goodtracksArr=0;
797 delete [] ITStracksArr; ITStracksArr=0;
798 delete [] TPCtracksArr; TPCtracksArr=0;
799 delete [] nPointsArr; nPointsArr=0;
800 delete [] phiArr; phiArr=0;
801 delete [] thetaArr; thetaArr=0;
802 delete [] distanceFromVertexArr; distanceFromVertexArr=0;
809 //////////////////////////////////////////////////////////////////////////////////////
810 // convert indexes from local goodtrackarrays to global track index
811 TPCgood1 = goodtracksArr[TPCgood1];
812 TPCgood2 = goodtracksArr[TPCgood2];
813 ITSgood1 = goodtracksArr[ITSgood1];
814 ITSgood2 = goodtracksArr[ITSgood2];
815 /////////////////////////////////////////////////////////////////////////////////////
817 AliESDtrack * pTPCtrack1 = pEvent->GetTrack(TPCgood1);
818 AliESDtrack * pTPCtrack2 = pEvent->GetTrack(TPCgood2);
819 AliESDtrack * pITStrack1 = pEvent->GetTrack(ITSgood1);
820 AliESDtrack * pITStrack2 = pEvent->GetTrack(ITSgood2);
821 const AliTrackPointArray* pTPCArray1 = pTPCtrack1->GetTrackPointArray();
822 const AliTrackPointArray* pTPCArray2 = pTPCtrack2->GetTrackPointArray();
823 const AliTrackPointArray* pITSArray1 = pITStrack1->GetTrackPointArray();
824 const AliTrackPointArray* pITSArray2 = pITStrack2->GetTrackPointArray();
826 AliTrackPointArray* pfullITStrackArray = new AliTrackPointArray(1);
827 JoinTrackArrays( pfullITStrackArray, pITSArray1, pITSArray2 );
829 //cout<<"selected tracks: TPC: "<<TPCgood1<<" "<<TPCgood2<<" ITS: "<<ITSgood1<<" "<<ITSgood2<<endl;
831 //Fill the final trackpointarrays
832 if (!ExtractSubTrackPointArray( fPTrackPointArray1, fPVolIDArray1, pfullITStrackArray, 1, 6 )) return kFALSE;
833 if (!ExtractSubTrackPointArray( fPTrackPointArray2, fPVolIDArray2, pTPCArray1, 7, 8 )) return kFALSE;
834 if (!ExtractSubTrackPointArray( fPTrackPointArray2b, fPVolIDArray2b, pTPCArray2, 7, 8 )) return kFALSE;
836 delete pfullITStrackArray; pfullITStrackArray=NULL;
837 delete [] goodtracksArr; goodtracksArr=NULL;
838 delete [] ITStracksArr; ITStracksArr=NULL;
839 delete [] TPCtracksArr; TPCtracksArr=NULL;
840 delete [] nPointsArr; nPointsArr=NULL;
841 delete [] phiArr; phiArr=NULL;
842 delete [] thetaArr; thetaArr=NULL;
843 delete [] distanceFromVertexArr; distanceFromVertexArr=NULL;
844 //printf("FindCosmicInEvent END\n");
848 Bool_t AliRelAlignerKalman::ExtractSubTrackPointArray( AliTrackPointArray* pTrackOut, TArrayI* pVolIDArrayOut, const AliTrackPointArray* pTrackIn, const Int_t firstlayer, const Int_t lastlayer )
850 //printf("ExtractSubTrackPointArray\n");
851 //From pTrackIn select points between firstlayer and lastlayer and put the result in pTrackOut.
852 //VolID's of selected points go in pVolIDArrayOut
853 //only good points selected.
854 //points can be ordered with z by setting fSortTrackPointsWithY
857 Int_t nPointsIn = pTrackIn->GetNPoints();
858 if (nPointsIn<TMath::Min(fMinPointsVol1,fMinPointsVol2)) return kFALSE;
859 Int_t iPointArr[1000];
860 Int_t VolIDArr[1000];
863 Int_t OuterLayerID=0;
866 //loop over trackpoints and record the good ones
867 for (Int_t i=0; i<nPointsIn; i++)
869 UShort_t VolIDshort = pTrackIn->GetVolumeID()[i];
870 Int_t layerID = AliGeomManager::VolUIDToLayer(VolIDshort);
871 //some points are very dirty: have nan's in coordinates or are otherwise sick
873 Float_t x = pTrackIn->GetX()[i];
874 Float_t y = pTrackIn->GetY()[i];
875 Float_t z = pTrackIn->GetZ()[i];
876 if ( ((TMath::Abs(x)<1.)||(TMath::Abs(x)>1000.))&&
877 ((TMath::Abs(y)<1.)||(TMath::Abs(y)>1000.))||
878 ((TMath::Abs(z)>1000.))
882 if ( (layerID >= firstlayer) && (layerID <= lastlayer) )
885 iPointArr[nGood] = i;
886 VolIDArr[nGood] = VolIDshort;
887 yArr[nGood] = pTrackIn->GetY()[i];
888 if (layerID>OuterLayerID)
890 OuterLayerID=layerID;
896 }//for i=0..nPointsIn
897 if (nGood<TMath::Min(fMinPointsVol1,fMinPointsVol2)) return kFALSE;
898 //Fill the output array of VolID's
899 delete pVolIDArrayOut;
900 pVolIDArrayOut = new TArrayI( nGood );
902 //fill the output trackarray
903 Int_t* iSortedYArr = new Int_t[nGood];
904 if (fSortTrackPointsWithY)
906 TMath::Sort( nGood, yArr, iSortedYArr, kFALSE );
909 pTrackOut = new AliTrackPointArray( nGood );
911 for ( Int_t i=0; i<nGood; i++)
913 pTrackIn->GetPoint( point, iPointArr[(fSortTrackPointsWithY)?iSortedYArr[i]:i] );
914 pTrackOut->AddPoint( i, &point );
915 pVolIDArrayOut->AddAt( VolIDArr[(fSortTrackPointsWithY)?iSortedYArr[i]:i], i );
917 //printf("ExtractSubTrackPointArray END\n");
921 void AliRelAlignerKalman::SortTrackPointArrayWithY( AliTrackPointArray* pout, const AliTrackPointArray* pinn, const Bool_t descending )
923 //sorts a given trackpointarray by y coordinate
925 Int_t npoints = pinn->GetNPoints();
926 const AliTrackPointArray* pin;
928 pin = new AliTrackPointArray(*pinn);
932 if (pout!=NULL) delete pout;
933 pout = new AliTrackPointArray(npoints);
936 Int_t* iarr = new Int_t[npoints];
938 TMath::Sort( npoints, pin->GetY(), iarr, descending );
941 for (Int_t i=0; i<npoints; i++)
943 pin->GetPoint( p, iarr[i] );
944 pout->AddPoint( i, &p );
949 Bool_t AliRelAlignerKalman::FitTrackPointArrayRieman( TVector3* pPoint, TMatrixDSym* pPointCov, TVector3* pDir, TMatrixDSym* pDirCov, AliTrackPointArray* pTrackPointArray, TArrayI* pVolIDs, AliTrackPoint* pRefPoint )
951 //printf("FitTrackPointArrayRieman\n");
952 //Use AliTrackFitterRieman to fit a track through given point array
954 AliTrackFitterRieman fitter;
955 AliTrackPoint trackPoint;
956 const Float_t* pointcov;
957 ////here's an ugly hack://///////
958 //AliTrackPointArray* pTrackPointArray = const_cast < AliTrackPointArray* > (pTrackPointArrayIn);
959 /////////////////////////////////
960 fitter.SetTrackPointArray( pTrackPointArray, kFALSE );
961 if ( !fitter.Fit( pVolIDs ) ) return kFALSE;
962 if ( !fitter.GetPCA( *fPRefAliTrackPoint, trackPoint ) ) return kFALSE;
963 Double_t xPoint = trackPoint.GetX();
964 pPoint->SetXYZ( xPoint, trackPoint.GetY(), trackPoint.GetZ() );
965 pDir->SetXYZ( 1., fitter.GetDYat(xPoint), fitter.GetDZat(xPoint) );
966 *pDir = pDir->Unit();
969 pointcov = trackPoint.GetCov();
970 (*pPointCov)(0,0) = pointcov[0];(*pPointCov)(0,1) = pointcov[1];(*pPointCov)(0,2) = pointcov[2];
971 (*pPointCov)(1,0) = pointcov[1];(*pPointCov)(1,1) = pointcov[3];(*pPointCov)(1,2) = pointcov[4];
972 (*pPointCov)(2,0) = pointcov[2];(*pPointCov)(2,1) = pointcov[4];(*pPointCov)(2,2) = pointcov[5];
974 //printf("FitTrackPointArrayRieman END\n");
978 Bool_t AliRelAlignerKalman::FitTrackPointArrayKalman( TVector3* pPoint, TMatrixDSym* pPointCov, TVector3* pDir, TMatrixDSym* pDirCov, AliTrackPointArray* pTrackPointArray, TArrayI* pVolIDs, AliTrackPoint* pRefPoint )
980 //printf("FitTrackPointArrayKalman\n");
981 //Use AliTrackFitterKalman to fit a track through given point array
984 AliTrackFitterKalman fitter;
985 AliTrackPoint trackPoint, trackPoint2;
987 pTrackPointArray->GetPoint( trackPoint, 0 );
988 pTrackPointArray->GetPoint( trackPoint2, 1 );
989 //Make sure all points count
990 fitter.SetMaxChi2(100000000.);
991 if (!fitter.MakeSeed( &trackPoint, &trackPoint2 )) return kFALSE;
992 Int_t npoints = pTrackPointArray->GetNPoints();
993 for (Int_t i=2; i<npoints; i++)
995 pTrackPointArray->GetPoint( trackPoint, i );
996 if (!fitter.AddPoint( &trackPoint )) continue;
998 TMatrixDSym fullcov = fitter.GetCovariance();
999 printf("FitTrackPointArrayKalman: the covariance matrix of the fit");
1002 //now propagate to ref plane - its a hack that depends on the implementation of AddPoint()!
1003 // - first set the maxchi2 to 0 so addpoint returns false, but
1004 //actually the trackparameters have already been been propagated to the new planei, it's safe
1005 //because AliTrackFitterKalman::Propagate() is always kTRUE.
1006 fitter.SetMaxChi2(0.);
1007 fitter.AddPoint( fPRefAliTrackPoint );
1009 const Double_t* pparams = fitter.GetParam();
1010 fullcov = fitter.GetCovariance();
1012 pDir->SetXYZ( pparams[3], 1., pparams[4] );
1013 pPoint->SetXYZ( pparams[0], pparams[1], pparams[2] );
1015 (*pPointCov)(0,0) = fullcov(0,0);(*pPointCov)(0,1) = fullcov(0,1);(*pPointCov)(0,2) = fullcov(0,2);
1016 (*pPointCov)(1,0) = fullcov(1,0);(*pPointCov)(1,1) = fullcov(1,1);(*pPointCov)(1,2) = fullcov(1,2);
1017 (*pPointCov)(2,0) = fullcov(2,0);(*pPointCov)(2,1) = fullcov(2,1);(*pPointCov)(2,2) = fullcov(2,2);
1019 (*pDirCov)(0,0)=fullcov(3,3); (*pDirCov)(0,1)=0.; (*pDirCov)(0,2)=fullcov(3,4);
1020 (*pDirCov)(1,0)=0.; (*pDirCov)(1,1)=0.; (*pDirCov)(1,2)=0.;
1021 (*pDirCov)(2,0)=fullcov(4,3); (*pDirCov)(2,1)=0.; (*pDirCov)(2,2)=fullcov(4,4);
1025 void AliRelAlignerKalman::SanitizeExtendedCovMatrix( TMatrixDSym& covout, const TMatrixDSym& pointcov, const TVector3& dir )
1027 //reverse the effect of extending of the covariance matrix along the track
1028 //direction as done by the AliTrackFitters
1030 //idea is to rotate to a system where track direction is y axis,
1031 //in that refsystem setting the y related components of covariance
1033 TVector3 yaxis(0,1,0);
1034 Double_t angle = dir.Angle(yaxis);
1035 TVector3 rotaxisvec = dir.Cross(yaxis);
1036 TVector3 rotaxis = rotaxisvec.Unit();
1039 //Fill the rotation matrix.
1040 Double_t ex=rotaxis(0);
1041 Double_t ey=rotaxis(1);
1042 Double_t ez=rotaxis(2);
1043 Double_t sin = TMath::Sin(angle);
1044 Double_t cos = TMath::Cos(angle);
1045 Double_t icos = 1 - cos;
1046 R(0,0) = cos + (ex*ex)*icos;
1047 R(0,1) = icos*ex*ey - ez*sin;
1048 R(0,2) = icos*ex*ez + ey*sin;
1049 R(1,0) = icos*ey*ex + ez*sin;
1050 R(1,1) = cos + (ey*ey)*icos;
1051 R(1,2) = icos*ey*ez - ex*sin;
1052 R(2,0) = icos*ez*ex - ey*sin;
1053 R(2,1) = icos*ez*ey + ex*sin;
1054 R(2,2) = cos + (ez*ez)*icos;
1056 //Transform covariance:
1057 TMatrixD covR( pointcov, TMatrixD::kMultTranspose, R);
1058 TMatrixD RcovR( R, TMatrixD::kMult, covR );
1059 TMatrixD newcov(3,3);
1060 newcov(0,0)=RcovR(0,0);
1061 newcov(0,2)=RcovR(0,2);
1062 newcov(2,0)=RcovR(2,0);
1063 newcov(2,2)=RcovR(2,2);
1064 newcov(1,1)=(newcov(0,0)+newcov(2,2))/2.; //this is a bit insane!!
1066 RcovR = R.T() * covR;
1067 TMatrixDSym_from_TMatrixD( covout, RcovR );
1070 void AliRelAlignerKalman::JoinTrackArrays( AliTrackPointArray* pout, const AliTrackPointArray* pin1, const AliTrackPointArray* pin2 )
1072 //Join two AliTrackPointArrays
1074 Int_t np1 = pin1->GetNPoints();
1075 Int_t np2 = pin2->GetNPoints();
1076 if (pout!=NULL) delete pout;
1077 pout = new AliTrackPointArray(np1+np2);
1079 for (Int_t i=0;i<np1;i++)
1081 pin1->GetPoint( p, i );
1082 pout->AddPoint( i, &p );
1084 for (Int_t i=0;i<np2;i++)
1086 pin2->GetPoint( p, i );
1087 pout->AddPoint( i+np1, &p );
1091 Bool_t AliRelAlignerKalman::ProcessTrackPointArrays()
1093 //Fit the track point arrays and update some household info
1095 fFitted=kFALSE; //not fitted yet
1096 if ( !FitTrackPointArrayKalman( fPPoint2, fPPoint2Cov, fPDir2, fPDir2Cov,
1097 fPTrackPointArray2, fPVolIDArray2, fPRefAliTrackPoint ) )
1105 if ( !FitTrackPointArrayKalman( fPPoint2b, fPPoint2bCov, fPDir2b, fPDir2bCov,
1106 fPTrackPointArray2b, fPVolIDArray2b, fPRefAliTrackPoint ) )
1113 if ( !FitTrackPointArrayKalman( fPPoint1, fPPoint1Cov, fPDir1, fPDir1Cov,
1114 fPTrackPointArray1, fPVolIDArray1, fPRefAliTrackPoint ) )
1121 //printf("ProcessTrackPointArrays: fitted!\n");
1125 Bool_t AliRelAlignerKalman::UpdateCalibration()
1127 //Update the calibration with new data, used in calibration pass
1129 fPThetaMesHist->Fill( (*fPMeasurement)(0) );
1130 fPPhiMesHist->Fill( (*fPMeasurement)(1) );
1131 fPXMesHist->Fill( (*fPMeasurement)(2) );
1132 fPZMesHist->Fill( (*fPMeasurement)(3) );
1135 fPThetaMesHist2->Fill( (*fPMeasurement)(4) );
1136 fPPhiMesHist2->Fill( (*fPMeasurement)(5) );
1137 fPXMesHist2->Fill( (*fPMeasurement)(6) );
1138 fPZMesHist2->Fill( (*fPMeasurement)(7) );
1140 fCalibrationUpdated=kTRUE;
1144 Bool_t AliRelAlignerKalman::SetCalibrationPass( Bool_t cp )
1146 //sets the calibration mode
1149 fCalibrationPass=kTRUE;
1154 if (!fCalibrationUpdated) return kFALSE;
1155 if (fCalibrationPass) // do it only after the calibration pass
1158 fPMeasurementCov->Zero(); //reset the covariance
1160 fPThetaMesHist->Fit("gaus");
1161 TF1* fitformula = fPThetaMesHist->GetFunction("gaus");
1162 tmp = fitformula->GetParameter(2);
1163 (*fPMeasurementCov)(0,0) = tmp*tmp;
1165 fPPhiMesHist->Fit("gaus");
1166 fitformula = fPPhiMesHist->GetFunction("gaus");
1167 tmp = fitformula->GetParameter(2);
1168 (*fPMeasurementCov)(1,1) = tmp*tmp;
1170 fPXMesHist->Fit("gaus");
1171 fitformula = fPXMesHist->GetFunction("gaus");
1172 tmp = fitformula->GetParameter(2);
1173 (*fPMeasurementCov)(2,2) = tmp*tmp;
1175 fPZMesHist->Fit("gaus");
1176 fitformula = fPZMesHist->GetFunction("gaus");
1177 tmp = fitformula->GetParameter(2);
1178 (*fPMeasurementCov)(3,3) = tmp*tmp;
1182 fPThetaMesHist2->Fit("gaus");
1183 fitformula = fPThetaMesHist2->GetFunction("gaus");
1184 tmp = fitformula->GetParameter(2);
1185 (*fPMeasurementCov)(4,4) = tmp*tmp;
1187 fPPhiMesHist2->Fit("gaus");
1188 fitformula = fPPhiMesHist2->GetFunction("gaus");
1189 tmp = fitformula->GetParameter(2);
1190 (*fPMeasurementCov)(5,5) = tmp*tmp;
1192 fPXMesHist2->Fit("gaus");
1193 fitformula = fPXMesHist2->GetFunction("gaus");
1194 tmp = fitformula->GetParameter(2);
1195 (*fPMeasurementCov)(6,6) = tmp*tmp;
1197 fPZMesHist2->Fit("gaus");
1198 fitformula = fPZMesHist2->GetFunction("gaus");
1199 tmp = fitformula->GetParameter(2);
1200 (*fPMeasurementCov)(7,7) = tmp*tmp;
1203 fCalibrationPass=kFALSE;
1204 fFixedMeasurementCovariance=kTRUE;
1205 fPMeasurementCov->Print();
1207 }//if (fCalibrationPass)
1213 void AliRelAlignerKalman::PrintDebugInfo()
1216 cout<<"AliRelAlignerKalman debug info"<<endl;
1217 printf("fPTrackPointArray1 y: ");
1218 for (Int_t i=0; i<fPTrackPointArray1->GetNPoints();i++)
1220 printf("%.2f ",fPTrackPointArray1->GetY()[i]);
1223 printf("fPTrackPointArray2 y: ");
1224 for (Int_t i=0; i<fPTrackPointArray2->GetNPoints();i++)
1226 printf("%.2f ",fPTrackPointArray2->GetY()[i]);
1229 printf("fPTrackPointArray2b y: ");
1230 for (Int_t i=0; i<fPTrackPointArray2b->GetNPoints();i++)
1232 printf("%.2f ",fPTrackPointArray2b->GetY()[i]);
1236 printf("Measurement covariance");
1237 fPMeasurementCov->Print();