6 Kalman filter(s) for fitting of the tracks together with calibration/transformation
9 Correction/Transformation are currently described by set (TObjArray) of primitive
10 correction/transformatio - AliTPCTransformation. Currently we assume that transformation
11 comute (in first order). AliTPCTransformation describe general non linear transformation.
13 Current calibration parameters and covariance stored (fCalibParam, fCalibCovar).
15 Currenly only linear track model implemented.
16 Fits to be implemented:
17 0. Plane fitting (Laser CE)
18 1. Primary vertex fitting.
19 2. Propagation in magnetic field and fit of planes
23 How to use it - see AliTPCkalmanFit::Test function
25 Simple test (see AliTPCkalmanFit::Test)
26 AliTPCTransformation::BuildBasicFormulas();
27 AliTPCkalmanFit *kalmanFit0 = AliTPCkalmanFit::Test(2000);
28 TFile f("kalmanfitTest.root");
30 Transformation visualization:
31 Transforamtion can be visualized using TFn (TF1,TF2 ...) and using tree->Draw()
33 kalmanFit0->SetInstance(kalmanFit0); //
34 kalmanFit0->InitTransformation(); //
35 TF2 fxRZdz("fxRZdz","sign(y)*1000*(AliTPCkalmanFit::SGetTPCDeltaXYZ(0,-1,x,0,y)-AliTPCkalmanFit::SGetTPCDeltaXYZ(0,-1,x,0,y-1))",85,245,-250,250);
47 #include "TLinearFitter.h"
49 #include "THnSparse.h"
53 #include "TTreeStream.h"
54 #include "AliTrackPointArray.h"
56 #include "AliTPCTransformation.h"
57 #include "AliTPCkalmanFit.h"
59 ClassImp(AliTPCkalmanFit)
61 AliTPCkalmanFit* AliTPCkalmanFit::fgInstance = 0;
63 AliTPCkalmanFit::AliTPCkalmanFit():
71 fCurrentAlpha(0), //! current rotation frame
72 fCA(0), //! cosine of current angle
73 fSA(0) //! sinus of current angle
76 // Default constructor
78 for (Int_t ihis=0; ihis<12; ihis++){
79 fLinearTrackDelta[ihis]=0;
80 fLinearTrackPull[ihis]=0;
84 void AliTPCkalmanFit::InitTransformation(){
86 // Initialize pointers to the transforamtion functions
89 Int_t ncalibs = fCalibration->GetEntries();
90 for (Int_t icalib=0;icalib<ncalibs; icalib++){
91 AliTPCTransformation * transform = (AliTPCTransformation *)fCalibration->At(icalib);
96 void AliTPCkalmanFit::Add(const AliTPCkalmanFit * kalman){
101 for (Int_t i=0;i<12;i++){
102 if (fLinearTrackDelta[i] && kalman->fLinearTrackDelta[i]){
103 fLinearTrackDelta[i]->Add(kalman->fLinearTrackDelta[i]);
105 if (fLinearTrackPull[i] && kalman->fLinearTrackPull[i]){
106 fLinearTrackPull[i]->Add(kalman->fLinearTrackPull[i]);
113 void AliTPCkalmanFit::Init(){
115 // Initialize parameter vector and covariance matrix
116 // To be called after initialization of all of the transformations
119 Int_t ncalibs = fCalibration->GetEntries();
120 fCalibParam = new TMatrixD(ncalibs,1);
121 fCalibCovar = new TMatrixD(ncalibs,ncalibs);
122 for (Int_t icalib=0;icalib<ncalibs; icalib++){
123 AliTPCTransformation * transform = (AliTPCTransformation *)fCalibration->At(icalib);
124 (*fCalibParam)(icalib,0) = transform->fParam;
125 for (Int_t jcalib=0;jcalib<ncalibs; jcalib++){
126 if (icalib!=jcalib) (*fCalibCovar)(icalib,jcalib)= 0;
127 if (icalib==jcalib) (*fCalibCovar)(icalib,jcalib) = transform->fSigma*transform->fSigma;
131 // Build QA histograms
133 Double_t mpi = TMath::Pi();
135 // delta alpha y0 z0 ky kz
136 Int_t binsQA[6] = {300, 36*4, 30, 25, 20, 20};
137 Double_t xminQA[6] = {-0.5, -mpi, -120, -250, -1, -1.};
138 Double_t xmaxQA[6] = { 0.5, mpi, 120, 250, 1, 1.};
139 TString axisName[6]={"#Delta",
146 TString deltaName[12]={"#Delta_{y}(cm)",
147 "100*#Delta_{#phi}(cm)",
148 "100^{2}dy0^{2}/dx0^{2}(cm)",
149 "100^{2}dy1^{2}/dx1^{2}(cm)",
151 "100*#Delta_{#theta}(cm)",
152 "100^{2}*dz0^{2}/dx0^{2}(cm)",
153 "100^{2}*dz1^{2}/dx1^{2}(cm)",
159 TString pullName[12]={"#Delta_{y}(unit)",
160 "100*#Delta_{#phi}(unit)",
161 "100^{2}dy0^{2}/dx0^{2}(unit)",
162 "100^{2}dy1^{2}/dx1^{2}(unit)",
164 "100*#Delta_{#theta}(unit)",
165 "100^{2}*dz0^{2}/dx0^{2}(unit)",
166 "100^{2}*dz1^{2}/dx1^{2}(unit)"
174 for (Int_t ihis=0; ihis<12; ihis++){
175 fLinearTrackDelta[ihis]=0;
176 fLinearTrackPull[ihis]=0;
177 xminQA[0]=-0.5; xmaxQA[0] = 0.5;
178 fLinearTrackDelta[ihis] = new THnSparseS(deltaName[ihis],deltaName[ihis], 6, binsQA,xminQA, xmaxQA);
179 xminQA[0]=-10; xmaxQA[0] = 10;
180 fLinearTrackPull[ihis] = new THnSparseS(pullName[ihis],pullName[ihis], 6, binsQA,xminQA, xmaxQA);
181 for (Int_t iaxis=1; iaxis<6; iaxis++){
182 fLinearTrackDelta[ihis]->GetAxis(iaxis)->SetName(axisName[iaxis]);
183 fLinearTrackDelta[ihis]->GetAxis(iaxis)->SetTitle(axisName[iaxis]);
184 fLinearTrackPull[ihis]->GetAxis(iaxis)->SetName(axisName[iaxis]);
185 fLinearTrackPull[ihis]->GetAxis(iaxis)->SetTitle(axisName[iaxis]);
187 fLinearTrackDelta[ihis]->GetAxis(0)->SetName(deltaName[ihis]);
188 fLinearTrackDelta[ihis]->GetAxis(0)->SetTitle(deltaName[ihis]);
189 fLinearTrackPull[ihis]->GetAxis(0)->SetName(deltaName[ihis]);
190 fLinearTrackPull[ihis]->GetAxis(0)->SetTitle(deltaName[ihis]);
196 void AliTPCkalmanFit::SetStatus(const char * mask, Bool_t setOn, Bool_t isOr){
198 // 0. To activate all transforamtion call SetStatus(0,kTRUE)
199 // 1. To disable everything SetStatus(0,kFALSE)
200 // 2. To activate/desactivate SetStatus("xxx",kTRUE/kFALSE,kFALSE)
201 Int_t ncalibs = fCalibration->GetEntries();
203 for (Int_t i=0; i<ncalibs;i++){
204 AliTPCTransformation * transform = (AliTPCTransformation *)fCalibration->At(i);
205 transform->SetActive(setOn);
209 for (Int_t i=0; i<ncalibs;i++){
210 AliTPCTransformation * transform = (AliTPCTransformation *)fCalibration->At(i);
211 TString strName(transform->GetName());
212 if (strName.Contains(mask)){
213 if (!isOr) transform->SetActive( transform->IsActive() && setOn);
214 if (isOr) transform->SetActive( transform->IsActive() || setOn);
221 void AliTPCkalmanFit::Update(const AliTPCkalmanFit * kalman){
223 // Update Kalman filter
225 Int_t ncalibs = fCalibration->GetEntries();
226 TMatrixD vecXk=*fCalibParam; // X vector
227 TMatrixD covXk=*fCalibCovar; // X covariance
228 TMatrixD &vecZk = *(kalman->fCalibParam);
229 TMatrixD &measR = *(kalman->fCalibCovar);
231 TMatrixD matHk(ncalibs,ncalibs); // vector to mesurement
232 TMatrixD vecYk(ncalibs,1); // Innovation or measurement residual
233 TMatrixD matHkT(ncalibs,ncalibs); // helper matrix Hk transpose
234 TMatrixD matSk(ncalibs,ncalibs); // Innovation (or residual) covariance
235 TMatrixD matKk(ncalibs,ncalibs); // Optimal Kalman gain
236 TMatrixD covXk2(ncalibs,ncalibs); // helper matrix
237 TMatrixD covXk3(ncalibs,ncalibs); // helper matrix
239 for (Int_t i=0;i<ncalibs;i++){
240 for (Int_t j=0;j<ncalibs;j++) matHk(i,j)=0;
243 vecYk = vecZk-matHk*vecXk; // Innovation or measurement residual
244 matHkT=matHk.T(); matHk.T();
245 matSk = (matHk*(covXk*matHkT))+measR; // Innovation (or residual) covariance
247 matKk = (covXk*matHkT)*matSk; // Optimal Kalman gain
248 vecXk += matKk*vecYk; // updated vector
249 covXk2= (matHk-(matKk*matHk));
250 covXk3 = covXk2*covXk;
252 (*fCalibParam) = vecXk;
253 (*fCalibCovar) = covXk;
260 void AliTPCkalmanFit::FitTrackLinear(AliTrackPointArray &points, TTreeSRedirector *debug){
265 AliError("Kalman Fit not initialized");
269 // 1. Make initial track hypothesis
271 TLinearFitter lfitY(2,"pol1");
272 TLinearFitter lfitZ(2,"pol1");
276 lfitY.StoreData(kTRUE);
277 lfitZ.StoreData(kTRUE);
280 Int_t npoints = points.GetNPoints();
281 if (npoints<2) return;
282 const Double_t kFac=npoints*npoints*100;
283 const Double_t kOff0=0.01*0.01;
284 const Double_t kOff1=kOff0/(250.*250.);
288 // AliTrackPointArray pointsc(points);
289 //ApplyCalibration(&pointsc, -1.);
291 // 1.a Choosing reference rotation alpha
293 fCurrentAlpha = TMath::ATan2(points.GetY()[npoints-1]-points.GetY()[0], points.GetX()[npoints-1]-points.GetX()[0]);
294 fCA = TMath::Cos(fCurrentAlpha);
295 fSA = TMath::Sin(fCurrentAlpha);
297 // 1.b Fit the track in the rotated frame - MakeSeed
299 for (Int_t ipoint=0; ipoint<npoints-1; ipoint++){
300 Double_t rx = fCA*points.GetX()[ipoint]+fSA*points.GetY()[ipoint];
301 Double_t ry = -fSA*points.GetX()[ipoint]+fCA*points.GetY()[ipoint];
302 Double_t rz = points.GetZ()[ipoint];
303 lfitY.AddPoint(&rx,ry,1);
304 lfitZ.AddPoint(&rx,rz,1);
308 lfitY.GetParameters(vecY);
309 lfitZ.GetParameters(vecZ);
311 // 2. Set initial parameters and the covariance matrix
313 Int_t ncalibs = fCalibration->GetEntries();
315 fLinearParam = new TMatrixD(ncalibs+4,1);
316 fLinearCovar = new TMatrixD(ncalibs+4,ncalibs+4);
319 for (Int_t i=0; i<ncalibs+4;i++){
320 (*fLinearParam)(i,0)=0;
321 if (i<ncalibs) (*fLinearParam)(i,0) = (*fCalibParam)(i,0);
322 for (Int_t j=0; j<ncalibs+4;j++){
323 (*fLinearCovar)(i,j)=0;
324 if (i<ncalibs&&j<ncalibs) (*fLinearCovar)(i,j) = (*fCalibCovar)(i,j);
327 Double_t chi2Y = lfitY.GetChisquare()/lfitY.GetNpoints();
328 Double_t chi2Z = lfitZ.GetChisquare()/lfitZ.GetNpoints();
329 (*fLinearParam)(ncalibs+0,0) = lfitY.GetParameter(0);
330 (*fLinearCovar)(ncalibs+0,ncalibs+0)= lfitY.GetCovarianceMatrixElement(0,0)*chi2Y*kFac+kOff0;
331 (*fLinearParam)(ncalibs+1,0) = lfitY.GetParameter(1);
332 (*fLinearCovar)(ncalibs+1,ncalibs+1)= lfitY.GetCovarianceMatrixElement(1,1)*chi2Y*kFac+kOff1;
334 (*fLinearParam)(ncalibs+2,0) = lfitZ.GetParameter(0);
335 (*fLinearCovar)(ncalibs+2,ncalibs+2)= lfitZ.GetCovarianceMatrixElement(0,0)*chi2Z*kFac+kOff0;
336 (*fLinearParam)(ncalibs+3,0) = lfitZ.GetParameter(1);
337 (*fLinearCovar)(ncalibs+3,ncalibs+3)= lfitZ.GetCovarianceMatrixElement(1,1)*chi2Z*kFac+kOff1;
339 // Fit thetrack together with correction
342 for (Int_t ipoint=0; ipoint<npoints-1; ipoint++){
344 if (!points.GetPoint(point,ipoint)) continue;
345 Double_t erry2 = chi2Y;
346 Double_t errz2 = chi2Z;
347 //set error - it is hack
348 Float_t *cov = (Float_t*) point.GetCov();
349 cov[1] = erry2+kOff0;
350 cov[2] = errz2+kOff0;
351 UpdateLinear(point,debug);
352 if (!points.GetPoint(point,npoints-1-ipoint)) continue;
353 //set error - it is hack
354 cov = (Float_t*) point.GetCov();
355 cov[1] = erry2+kOff0;
356 cov[2] = errz2+kOff0;
357 UpdateLinear(point,debug);
360 // save current param and covariance
361 for (Int_t i=0; i<ncalibs;i++){
362 AliTPCTransformation * transform = (AliTPCTransformation *)fCalibration->At(i);
363 transform->fParam= (*fLinearParam)(i,0);
364 (*fCalibParam)(i,0) = (*fLinearParam)(i,0);
365 for (Int_t j=0; j<ncalibs;j++){
366 (*fCalibCovar)(i,j) = (*fLinearCovar)(i,j);
369 if (debug){ // dump debug info
370 (*debug)<<"fitLinear"<<
375 "lP.="<<fLinearParam<<
376 "cP.="<<fCalibParam<<
377 "lC.="<<fLinearCovar<<
378 "cC.="<<fCalibCovar<<
383 void AliTPCkalmanFit::DumpTrackLinear(AliTrackPointArray &points, TTreeSRedirector *debug){
385 // Dump the track parameters before and after current calibration
387 // Track is divided to two parts -
388 // X mean is defined as middle point
392 AliError("Kalman Fit not initialized");
398 TLinearFitter *fitters[16];
399 TVectorD *params[16];
402 Int_t npoints = points.GetNPoints();
403 AliTrackPointArray pointsTrans(points);
404 ApplyCalibration(&pointsTrans,-1.);
405 for (Int_t ifit=0; ifit<8;ifit++){
406 fitters[ifit] = new TLinearFitter(2,"pol1");
407 params[ifit] = new TVectorD(2);
408 fitters[ifit+8]= new TLinearFitter(3,"pol2");
409 params[ifit+8] = new TVectorD(3);
410 errs[ifit] = new TVectorD(2);
411 errs[ifit+8] = new TVectorD(3);
414 // calculate mean x point and corrdinate frame
416 fCurrentAlpha = TMath::ATan2(points.GetY()[npoints-1]-points.GetY()[0], points.GetX()[npoints-1]-points.GetX()[0]);
417 fCA = TMath::Cos(fCurrentAlpha);
418 fSA = TMath::Sin(fCurrentAlpha);
419 Double_t xmean=0, sum=0;
420 for (Int_t ipoint=0; ipoint<npoints-1; ipoint++){
421 Double_t rx = fCA*points.GetX()[ipoint]+fSA*points.GetY()[ipoint];
427 for (Int_t ipoint=0; ipoint<npoints-1; ipoint++){
428 Double_t rx = fCA*points.GetX()[ipoint]+fSA*points.GetY()[ipoint];
429 Double_t ry = -fSA*points.GetX()[ipoint]+fCA*points.GetY()[ipoint];
430 Double_t rz = points.GetZ()[ipoint];
432 Double_t rxT = fCA*pointsTrans.GetX()[ipoint]+fSA*pointsTrans.GetY()[ipoint];
433 Double_t ryT = -fSA*pointsTrans.GetX()[ipoint]+fCA*pointsTrans.GetY()[ipoint];
434 Double_t rzT = pointsTrans.GetZ()[ipoint];
436 fitters[0]->AddPoint(&rxT, ryT,1);
437 fitters[2]->AddPoint(&rxT, rzT,1);
438 fitters[4]->AddPoint(&rx, ry,1);
439 fitters[6]->AddPoint(&rx, rz,1);
440 fitters[8]->AddPoint(&rxT, ryT,1);
441 fitters[10]->AddPoint(&rxT, rzT,1);
442 fitters[12]->AddPoint(&rx, ry,1);
443 fitters[14]->AddPoint(&rx, rz,1);
445 fitters[1]->AddPoint(&rxT, ryT,1);
446 fitters[3]->AddPoint(&rxT, rzT,1);
447 fitters[5]->AddPoint(&rx, ry,1);
448 fitters[7]->AddPoint(&rx, rz,1);
449 fitters[9]->AddPoint(&rxT, ryT,1);
450 fitters[11]->AddPoint(&rxT, rzT,1);
451 fitters[13]->AddPoint(&rx, ry,1);
452 fitters[15]->AddPoint(&rx, rz,1);
455 for (Int_t ifit=0;ifit<16;ifit++){
456 fitters[ifit]->Eval();
457 fitters[ifit]->GetParameters(*(params[ifit]));
458 fitters[ifit]->GetErrors(*(errs[ifit]));
459 chi2N[ifit] = TMath::Sqrt(fitters[ifit]->GetChisquare()/(fitters[ifit]->GetNpoints()-1));
460 (*(errs[ifit]))[0]*=chi2N[ifit];
461 (*(errs[ifit]))[1]*=chi2N[ifit];
462 if (ifit>=8) (*(errs[ifit]))[2]*=chi2N[ifit]; // second derivative
465 (*debug)<<"dumpLinear"<<
466 "alpha="<<fCurrentAlpha<<
476 "y0T2.="<<params[8]<<
477 "y1T2.="<<params[9]<<
478 "z0T2.="<<params[10]<<
479 "z1T2.="<<params[11]<<
480 "y0O2.="<<params[12]<<
481 "y1O2.="<<params[13]<<
482 "z0O2.="<<params[14]<<
483 "z1O2.="<<params[15]<<
484 "y0TErr.="<<errs[0]<<
485 "y1TErr.="<<errs[1]<<
486 "z0TErr.="<<errs[2]<<
487 "z1TErr.="<<errs[3]<<
488 "y0OErr.="<<errs[4]<<
489 "y1OErr.="<<errs[5]<<
490 "z0OErr.="<<errs[6]<<
491 "z1OErr.="<<errs[7]<<
492 "y0T2Err.="<<errs[8]<<
493 "y1T2Err.="<<errs[9]<<
494 "z0T2Err.="<<errs[10]<<
495 "z1T2Err.="<<errs[11]<<
496 "y0O2Err.="<<errs[12]<<
497 "y1O2Err.="<<errs[13]<<
498 "z0O2Err.="<<errs[14]<<
499 "z1O2Err.="<<errs[15]<<
504 // delta alpha y0 z0 ky kz
505 Double_t x[6]={0,0,0,0,0,0};
507 x[2]=(*params[0])[0];
508 x[3]=(*params[2])[0];
509 x[4]=(*params[0])[1];
510 x[5]=(*params[2])[1];
514 x[0]= (*params[1])[0]-(*params[0])[0];
515 fLinearTrackDelta[0]->Fill(x);
516 x[0]/=TMath::Sqrt((*errs[1])[0]*(*errs[1])[0]+(*errs[0])[0]*(*errs[0])[0]);
517 fLinearTrackPull[0]->Fill(x);
521 x[0]= 100*((*params[1])[1]-(*params[0])[1]);
522 fLinearTrackDelta[1]->Fill(x);
523 x[0]/=100*TMath::Sqrt((*errs[1])[1]*(*errs[1])[1]+(*errs[0])[1]*(*errs[0])[1]);
524 fLinearTrackPull[1]->Fill(x);
528 x[0]= 100*100*((*params[8])[2]);
529 fLinearTrackDelta[2]->Fill(x);
530 x[0]/=100*100*TMath::Sqrt((*errs[8])[2]*(*errs[8])[2]);
531 fLinearTrackPull[2]->Fill(x);
535 x[0]= 100*100*((*params[9])[2]);
536 fLinearTrackDelta[3]->Fill(x);
537 x[0]/=100*100*TMath::Sqrt((*errs[9])[2]*(*errs[9])[2]);
538 fLinearTrackPull[3]->Fill(x);
543 x[0]= (*params[3])[0]-(*params[2])[0];
544 fLinearTrackDelta[4]->Fill(x);
545 x[0]/=TMath::Sqrt((*errs[3])[0]*(*errs[3])[0]+(*errs[2])[0]*(*errs[2])[0]);
546 fLinearTrackPull[4]->Fill(x);
550 x[0]= 100*((*params[3])[1]-(*params[2])[1]);
551 fLinearTrackDelta[5]->Fill(x);
552 x[0]/=100*TMath::Sqrt((*errs[3])[1]*(*errs[3])[1]+(*errs[2])[1]*(*errs[2])[1]);
553 fLinearTrackPull[5]->Fill(x);
557 x[0]= 100*100*((*params[10])[2]);
558 fLinearTrackDelta[6]->Fill(x);
559 x[0]/=100*100*TMath::Sqrt((*errs[10])[2]*(*errs[10])[2]);
560 fLinearTrackPull[6]->Fill(x);
564 x[0]= 100*100*((*params[11])[2]);
565 fLinearTrackDelta[7]->Fill(x);
566 x[0]/=100*100*TMath::Sqrt((*errs[11])[2]*(*errs[11])[2]);
567 fLinearTrackPull[7]->Fill(x);
573 fLinearTrackDelta[8]->Fill(x);
575 fLinearTrackDelta[9]->Fill(x);
577 fLinearTrackDelta[10]->Fill(x);
579 fLinearTrackDelta[11]->Fill(x);
583 for (Int_t ifit=0; ifit<8;ifit++){
584 delete fitters[ifit];
586 delete fitters[ifit+8];
587 delete params[ifit+8];
594 void AliTPCkalmanFit::Propagate(TTreeSRedirector */*debug*/){
596 // Propagate the Kalman
601 void AliTPCkalmanFit::PropagateTime(Int_t time){
603 // Propagate the calibration in time
604 // - Increase covariance matrix
606 if (fCalibCovar) return;
607 Int_t ncalibs = fCalibration->GetEntries();
609 if (fLastTimeStamp>0) deltaT = (fLastTimeStamp-time)/(60*60.); // delta T in hours
610 fLastTimeStamp = time;
611 for (Int_t icalib=0;icalib<ncalibs; icalib++){
612 AliTPCTransformation * transform = (AliTPCTransformation *)fCalibration->At(icalib);
613 (*fCalibCovar)(icalib,icalib)+= transform->fSigma2Time*deltaT;
618 void AliTPCkalmanFit::UpdateLinear(AliTrackPoint &point, TTreeSRedirector *debug){
623 Int_t ncalibs = fCalibration->GetEntries();
625 Int_t nelem = ncalibs+4;
626 TMatrixD &vecXk=*fLinearParam; // X vector
627 TMatrixD &covXk=*fLinearCovar; // X covariance
629 TMatrixD matHk(kNmeas,nelem); // vector to mesurement
630 TMatrixD vecYk(kNmeas,1); // Innovation or measurement residual
631 TMatrixD vecZk(kNmeas,1); // Innovation or measurement residual
632 TMatrixD measR(kNmeas,kNmeas);
633 TMatrixD matHkT(nelem,kNmeas); // helper matrix Hk transpose
634 TMatrixD matSk(kNmeas,kNmeas); // Innovation (or residual) covariance
635 TMatrixD matKk(nelem,kNmeas); // Optimal Kalman gain
636 TMatrixD covXk2(nelem,nelem); // helper matrix
637 TMatrixD covXk3(nelem,nelem); // helper matrix
638 TMatrixD mat1(nelem,nelem);
641 for (Int_t iel=0;iel<nelem;iel++){
642 for (Int_t ip=0;ip<kNmeas;ip++) {
646 for (Int_t iel0=0;iel0<nelem;iel0++)
647 for (Int_t iel1=0;iel1<nelem;iel1++){
648 if (iel0!=iel1) mat1(iel0,iel1)=0;
649 if (iel0==iel1) mat1(iel0,iel1)=1;
654 Int_t volId = point.GetVolumeID();
655 Double_t gxyz[3]={point.GetX(), point.GetY(),point.GetZ()};
656 Double_t rxyz[3]={fCA*gxyz[0]+fSA*gxyz[1],-fSA*gxyz[0]+fCA*gxyz[1] ,point.GetZ()};
658 Double_t dxdydz[3]={0,0,0};
659 Double_t rdxdydz[3]={0,0,0};
661 for (Int_t icalib=0;icalib<ncalibs;icalib++){
662 AliTPCTransformation * transform = (AliTPCTransformation *)fCalibration->At(icalib);
663 dxdydz[0] = transform->GetDeltaXYZ(0,volId, 1, gxyz[0], gxyz[1], gxyz[2]);
664 dxdydz[1] = transform->GetDeltaXYZ(1,volId, 1, gxyz[0], gxyz[1], gxyz[2]);
665 dxdydz[2] = transform->GetDeltaXYZ(2,volId, 1, gxyz[0], gxyz[1], gxyz[2]);
666 rdxdydz[0] = fCA*dxdydz[0]+fSA*dxdydz[1];
667 rdxdydz[1] = -fSA*dxdydz[0]+fCA*dxdydz[1];
668 rdxdydz[2] = dxdydz[2];
670 matHk(0,icalib)= rdxdydz[1]-rdxdydz[0]*(*fLinearParam)(ncalibs+1,0); // shift y + shift x * angleY
671 matHk(1,icalib)= rdxdydz[2]-rdxdydz[0]*(*fLinearParam)(ncalibs+3,0); // shift z + shift x * angleZ
673 matHk(0,ncalibs+0)=1;
674 matHk(0,ncalibs+1)=rxyz[0];
675 matHk(1,ncalibs+2)=1;
676 matHk(1,ncalibs+3)=rxyz[0];
680 vecZk(0,0) = rxyz[1];
681 vecZk(1,0) = rxyz[2];
682 measR(0,0) = point.GetCov()[1]; measR(0,1)=0;
683 measR(1,1) = point.GetCov()[2]; measR(1,0)=0;
685 vecYk = vecZk-matHk*vecXk; // Innovation or measurement residual
686 matHkT=matHk.T(); matHk.T();
687 matSk = (matHk*(covXk*matHkT))+measR; // Innovation (or residual) covariance
689 matKk = (covXk*matHkT)*matSk; // Optimal Kalman gain
691 covXk2= (mat1-(matKk*matHk));
692 covXk3 = covXk2*covXk;
694 CheckCovariance(covXk3,100);
695 vecXk += matKk*vecYk; // updated vector
697 if (debug){ // dump debug info
698 (*debug)<<"updateLinear"<<
705 "matHkT.="<<&matHkT<<
708 "covXk2.="<<&covXk2<<
716 AliTrackPointArray * AliTPCkalmanFit::SortPoints(AliTrackPointArray &points){
718 //Creates the array - points sorted according radius - neccessay for kalman fit
721 // 0. choose the frame - rotation angle
723 Int_t npoints = points.GetNPoints();
724 if (npoints<1) return 0;
725 Double_t currentAlpha = TMath::ATan2(points.GetY()[npoints-1]-points.GetY()[0], points.GetX()[npoints-1]-points.GetX()[0]);
726 Double_t ca = TMath::Cos(currentAlpha);
727 Double_t sa = TMath::Sin(currentAlpha);
729 // 1. sort the points
731 Double_t *rxvector = new Double_t[npoints];
732 Int_t *indexes = new Int_t[npoints];
733 for (Int_t ipoint=0; ipoint<npoints-1; ipoint++){
734 rxvector[ipoint]=ca*points.GetX()[ipoint]+sa*points.GetY()[ipoint];
736 TMath::Sort(npoints, rxvector,indexes,kFALSE);
738 AliTrackPointArray *pointsSorted= new AliTrackPointArray(npoints);
739 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
740 if (!points.GetPoint(point,indexes[ipoint])) continue;
741 pointsSorted->AddPoint(ipoint,&point);
750 AliTrackPointArray * AliTPCkalmanFit::MakePointArrayLinear(Double_t alpha, Double_t y0, Double_t z0, Double_t ky, Double_t kz, Double_t err){
754 AliTrackPointArray array(500);
755 Float_t cov[10]; // dummy covariance
757 for (Int_t i=0;i<6;i++) cov[i]=0.001;
758 for (Int_t i=0;i<500;i++){
759 AliTrackPoint point(0, 0, 0, cov, -1,0,0);
760 array.AddPoint(npoints, &point);
764 for (Float_t ir = -245; ir<245; ir++){
767 if (TMath::Abs(ir)<80) continue;
768 Double_t ca = TMath::Cos(alpha);
769 Double_t sa = TMath::Sin(alpha);
771 Double_t ly = y0+lx*ky+gRandom->Gaus(0,err);
772 Double_t lz = z0+lx*kz+gRandom->Gaus(0,err);
773 Double_t gx = lx*ca-ly*sa;
774 Double_t gy = lx*sa+ly*ca;
776 Double_t galpha = TMath::ATan2(gy,gx);
777 Int_t isec = TMath::Nint((9*galpha/TMath::Pi()+0.5));
778 if (isec<0) isec+=18;
780 if (ir>130) isec+=36;
782 AliTrackPoint point(gx, gy, gz, cov, isec,0,0);
783 array.AddPoint(npoints, &point);
786 AliTrackPointArray *parray = new AliTrackPointArray(npoints);
788 for (Int_t i=0;i<npoints;i++){
789 array.GetPoint(point,i);
790 parray->AddPoint(i,&point);
796 void AliTPCkalmanFit::AddCalibration(AliTPCTransformation * calib){
800 if (!fCalibration) fCalibration = new TObjArray(2000);
801 fCalibration->AddLast(calib);
804 void AliTPCkalmanFit::ApplyCalibration(AliTrackPointArray *array, Double_t csign){
808 if (!fCalibration) return;
809 Int_t ncalibs = fCalibration->GetEntries();
810 if (ncalibs==0) return;
811 Int_t npoints = array->GetNPoints();
812 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
813 Int_t volId = array->GetVolumeID()[ipoint];
814 Double_t xyz[3]={array->GetX()[ipoint], array->GetY()[ipoint],array->GetZ()[ipoint]};
815 Double_t dxdydz[3]={0,0,0};
816 for (Int_t icalib=0; icalib<ncalibs; icalib++){
817 AliTPCTransformation * transform = (AliTPCTransformation *)fCalibration->At(icalib);
818 dxdydz[0] += transform->GetDeltaXYZ(0,volId, transform->fParam, xyz[0], xyz[1], xyz[2]);
819 dxdydz[1] += transform->GetDeltaXYZ(1,volId, transform->fParam, xyz[0], xyz[1], xyz[2]);
820 dxdydz[2] += transform->GetDeltaXYZ(2,volId, transform->fParam, xyz[0], xyz[1], xyz[2]);
822 ((Float_t*)array->GetX())[ipoint]+=csign*dxdydz[0];
823 ((Float_t*)array->GetY())[ipoint]+=csign*dxdydz[1];
824 ((Float_t*)array->GetZ())[ipoint]+=csign*dxdydz[2];
828 Bool_t AliTPCkalmanFit::DumpCorelation(Double_t threshold, const char *mask0, const char *mask1){
832 TMatrixD &mat = *fCalibCovar;
833 Int_t nrow= mat.GetNrows();
834 for (Int_t irow=0; irow<nrow; irow++){
835 AliTPCTransformation * trans0 = GetTransformation(irow);
836 TString strName0(trans0->GetName());
838 if (!strName0.Contains(mask0)) continue;
840 for (Int_t icol=irow+1; icol<nrow; icol++){
841 AliTPCTransformation * trans1 = GetTransformation(icol);
842 TString strName1(trans1->GetName());
844 if (!strName1.Contains(mask1)) continue;
847 Double_t diag = TMath::Sqrt(TMath::Abs(mat(irow,irow)*mat(icol,icol)));
849 printf("Negative covariance\t%d\t%d\t%f\n",irow,icol, mat(irow,icol));
852 Double_t corr0 = mat(irow,icol)/diag;
853 if (TMath::Abs(corr0)>threshold){
854 printf("%d\t%d\t%s\t%s\t%f\t%f\t%f\n", irow,icol, trans0->GetName(), trans1->GetName(),
855 TMath::Sqrt(mat(irow,irow)), TMath::Sqrt(mat(icol,icol)), corr0);
862 Bool_t AliTPCkalmanFit::DumpCalib(const char *mask){
864 // Print calibration entries - name, value, error
866 TMatrixD &mat = *fCalibCovar;
867 Int_t nrow= mat.GetNrows();
868 TString strMask(mask);
869 for (Int_t irow=0; irow<nrow; irow++){
870 AliTPCTransformation * trans0 = GetTransformation(irow);
871 TString strName(trans0->GetName());
873 if (!strName.Contains(mask)) continue;
875 printf("%d\t%s\t%f\t%f\n",
878 (*fCalibParam)(irow,0),
879 TMath::Sqrt(mat(irow,irow)));
885 Bool_t AliTPCkalmanFit::CheckCovariance(TMatrixD &mat, Float_t /*maxEl*/){
887 // Check consistency of covariance matrix
888 // + symetrize coavariance matrix
890 Int_t nrow= mat.GetNrows();
891 for (Int_t irow=0; irow<nrow; irow++){
892 if (mat(irow,irow)<=0){
893 printf("Negative covariance\t%d\t%f\n",irow,mat(irow,irow));
896 // if (mat(irow,irow)>maxEl){
897 // printf("Too big covariance\t%d\t%f\n",irow,mat(irow,irow));
901 for (Int_t icol=0; icol<nrow; icol++){
902 // if (mat(irow,irow)
903 Double_t diag = TMath::Sqrt(TMath::Abs(mat(irow,irow)*mat(icol,icol)));
905 printf("Negative covariance\t%d\t%d\t%f\n",irow,icol, mat(irow,icol));
909 Double_t cov0 = mat(irow,icol)/diag;
910 Double_t cov1 = mat(icol,irow)/diag;
911 if (TMath::Abs(cov0)>1 || TMath::Abs(cov1)>1 ){
912 printf("Covariance Problem %d\t%d\t%f\t%f\n",irow,icol, cov0, cov1);
915 if (TMath::Abs(cov0-cov1)>0.0000001){
916 printf("Asymetry problem %d\t%d\t%f\t%f\n",irow,icol, cov0, cov1);
920 // symetrize the covariance matrix
921 Double_t mean = (mat(irow,icol)+ mat(icol,irow))*0.5;
930 AliTPCkalmanFit * AliTPCkalmanFit::Test(Int_t ntracks){
932 // This is test example
936 // 1. Setup transformation
941 AliTPCTransformation * transformation=0;
942 AliTPCkalmanFit * kalmanFit0 = new AliTPCkalmanFit;
943 AliTPCkalmanFit * kalmanFit2 = new AliTPCkalmanFit;
947 for (Int_t iside=0; iside<=1; iside++)
948 for (Int_t ipar0=0; ipar0<3; ipar0++)
949 for (Int_t ipar1=0; ipar1<3; ipar1++){
952 if (ipar0+ipar1==0) continue;
953 Double_t param = (gRandom->Rndm()-0.5)*0.5; // generate random parameters
955 sprintf(tname,"tscalingR%d%dSide%d",ipar0,ipar1,iside);
956 transformation = new AliTPCTransformation(tname,AliTPCTransformation::BitsSide(iside),"TPCscalingRPol",0,0,1);
957 transformation->SetParams(0,5*0.25,0,&fpar);
958 kalmanFit0->AddCalibration(transformation);
959 transformation = new AliTPCTransformation(tname,AliTPCTransformation::BitsSide(iside),"TPCscalingRPol",0,0,1);
960 transformation->SetParams(param,0.25,0,&fpar);
961 kalmanFit2->AddCalibration(transformation);
966 // 2. Init transformation
972 // 3. Run kalman filter
974 Int_t ncalibs = kalmanFit0->fCalibration->GetEntries();
975 TVectorD err(ncalibs);
976 TTreeSRedirector *pcstream = new TTreeSRedirector("kalmanfitTest.root");
977 for (Int_t i=0;i<ntracks;i++){
978 if (i%100==0) printf("%d\n",i);
979 Double_t alpha = gRandom->Rndm()*TMath::TwoPi();
980 Double_t y0 = (gRandom->Rndm()-0.5)*180;
981 Double_t z0 = (gRandom->Rndm()-0.5)*250*2;
982 Double_t ky = (gRandom->Rndm()-0.5)*1;
983 Double_t kz = (gRandom->Rndm()-0.5)*1;
984 //generate random TPC track
985 AliTrackPointArray * array = AliTPCkalmanFit::MakePointArrayLinear(alpha,y0,z0, ky, kz,0.04);
986 AliTrackPointArray * arrayB = new AliTrackPointArray(*array); // backup
987 kalmanFit2->ApplyCalibration(array,1.); // misalign ideal track
988 for (Int_t icalib=0; icalib<ncalibs; icalib++){
989 err[icalib] = TMath::Sqrt((*kalmanFit0->fCalibCovar)(icalib,icalib));
992 (*pcstream)<<"dump0"<<
1000 "cparam.="<<kalmanFit0->fCalibParam<<
1001 "ccovar.="<<kalmanFit0->fCalibCovar<<
1003 "gparam.="<<kalmanFit2->fCalibParam<<
1004 "gcovar.="<<kalmanFit2->fCalibCovar<<
1007 kalmanFit0->FitTrackLinear(*array,pcstream); // fit track - dump intermediate results
1009 kalmanFit0->FitTrackLinear(*array,0); // fit track + calibration
1011 kalmanFit0->DumpTrackLinear(*array,pcstream); // dump track residuals to the tree + fill histograms
1013 pcstream->GetFile()->cd();
1014 kalmanFit0->Write("kalmanFit");
1020 Double_t AliTPCkalmanFit::GetTPCDeltaXYZ(Int_t coord, Int_t volID, Double_t x, Double_t y, Double_t z){
1022 // function for visualization purposes
1024 if (!fCalibration) return 0;
1025 Int_t ncalibs = fCalibration->GetEntries();
1026 if (ncalibs==0) return 0;
1027 Double_t dxdydz[3]={0,0,0};
1030 Double_t alpha = TMath::ATan2(y,x);
1031 Double_t r = TMath::Sqrt(y*y+x*x);
1032 volID = TMath::Nint(9*alpha/TMath::Pi()-0.5);
1033 if (volID<0) volID+=18;
1035 if (r>120) volID+=36;
1037 for (Int_t icalib=0; icalib<ncalibs; icalib++){
1038 AliTPCTransformation * transform = (AliTPCTransformation *)fCalibration->At(icalib);
1039 Double_t param = (*fCalibParam)(icalib,0);
1040 dxdydz[coord] += transform->GetDeltaXYZ(coord,volID, param, x, y,z);
1042 return dxdydz[coord];
1045 Double_t AliTPCkalmanFit::SGetTPCDeltaXYZ(Int_t coord, Int_t volID, Double_t x, Double_t y, Double_t z){
1049 if (AliTPCkalmanFit::fgInstance==0) return 0;
1050 return AliTPCkalmanFit::fgInstance->GetTPCDeltaXYZ(coord, volID,x,y,z);