/* marian.ivanov@cern.ch AliTPCkalmanFit: Kalman filter(s) for fitting of the tracks together with calibration/transformation parameters. Correction/Transformation are currently described by set (TObjArray) of primitive correction/transformatio - AliTPCTransformation. Currently we assume that transformation comute (in first order). AliTPCTransformation describe general non linear transformation. Current calibration parameters and covariance stored (fCalibParam, fCalibCovar). Currenly only linear track model implemented. Fits to be implemented: 0. Plane fitting (Laser CE) 1. Primary vertex fitting. 2. Propagation in magnetic field and fit of planes How to use it - see AliTPCkalmanFit::Test function Simple test (see AliTPCkalmanFit::Test) AliTPCTransformation::BuildBasicFormulas(); AliTPCkalmanFit *kalmanFit0 = AliTPCkalmanFit::Test(2000); TFile f("kalmanfitTest.root"); Transformation visualization: Transforamtion can be visualized using TFn (TF1,TF2 ...) and using tree->Draw() e.g: kalmanFit0->SetInstance(kalmanFit0); // kalmanFit0->InitTransformation(); // // TF2 fxRZdz("fxRZdz","sign(y)*1000*(AliTPCkalmanFit::SGetTPCDeltaXYZ(0,-1,0,x,0,y)-AliTPCkalmanFit::SGetTPCDeltaXYZ(0,-1,0,x,0,y-1))",85,245,-250,250); fxRZdz->Draw(""); TF2 fxRZ("fxRZ","sign(y)*10*(AliTPCkalmanFit::SGetTPCDeltaXYZ(0,-1,x,0,y))",85,245,-250,250); fxRZ->Draw(""); */ #include "TRandom.h" #include "TMath.h" #include "TBits.h" #include "TFormula.h" #include "TF1.h" #include "TLinearFitter.h" #include "TFile.h" #include "THnSparse.h" #include "TAxis.h" #include "TTreeStream.h" #include "AliTrackPointArray.h" #include "AliLog.h" #include "AliTPCTransformation.h" #include "AliTPCkalmanFit.h" ClassImp(AliTPCkalmanFit) AliTPCkalmanFit* AliTPCkalmanFit::fgInstance = 0; AliTPCkalmanFit::AliTPCkalmanFit(): TNamed(), fCalibration(0), fCalibParam(0), fCalibCovar(0), fLinearParam(0), fLinearCovar(0), fLastTimeStamp(-1), fCurrentAlpha(0), //! current rotation frame fCA(0), //! cosine of current angle fSA(0) //! sinus of current angle { // // Default constructor // for (Int_t ihis=0; ihis<12; ihis++){ fLinearTrackDelta[ihis]=0; fLinearTrackPull[ihis]=0; } } void AliTPCkalmanFit::InitTransformation(){ // // Initialize pointers to the transforamtion functions // // Int_t ncalibs = fCalibration->GetEntries(); for (Int_t icalib=0;icalibAt(icalib); transform->Init(); } } void AliTPCkalmanFit::Add(const AliTPCkalmanFit * kalman){ // // // Update(kalman); for (Int_t i=0;i<12;i++){ if (fLinearTrackDelta[i] && kalman->fLinearTrackDelta[i]){ fLinearTrackDelta[i]->Add(kalman->fLinearTrackDelta[i]); } if (fLinearTrackPull[i] && kalman->fLinearTrackPull[i]){ fLinearTrackPull[i]->Add(kalman->fLinearTrackPull[i]); } } } void AliTPCkalmanFit::Init(){ // // Initialize parameter vector and covariance matrix // To be called after initialization of all of the transformations // // Int_t ncalibs = fCalibration->GetEntries(); fCalibParam = new TMatrixD(ncalibs,1); fCalibCovar = new TMatrixD(ncalibs,ncalibs); for (Int_t icalib=0;icalibAt(icalib); (*fCalibParam)(icalib,0) = transform->GetParam(); for (Int_t jcalib=0;jcalibGetSigma()*transform->GetSigma(); } } // // Build QA histograms // Double_t mpi = TMath::Pi(); // // delta alpha y0 z0 ky kz Int_t binsQA[6] = {300, 36*4, 30, 25, 20, 20}; Double_t xminQA[6] = {-0.5, -mpi, -120, -250, -1, -1.}; Double_t xmaxQA[6] = { 0.5, mpi, 120, 250, 1, 1.}; TString axisName[6]={"#Delta", "#alpha", "y_{0}", "z_{0}", "tan(#phi)", "tan(theta)"}; // TString deltaName[12]={"#Delta_{y}(cm)", "100*#Delta_{#phi}(cm)", "100^{2}dy0^{2}/dx0^{2}(cm)", "100^{2}dy1^{2}/dx1^{2}(cm)", "#Delta_{z}(cm)", "100*#Delta_{#theta}(cm)", "100^{2}*dz0^{2}/dx0^{2}(cm)", "100^{2}*dz1^{2}/dx1^{2}(cm)", "RMSy_{0} (cm)", "RMSy_{1} (cm)", "RMSz_{0} (cm)", "RMSz_{1} (cm)"}; TString pullName[12]={"#Delta_{y}(unit)", "100*#Delta_{#phi}(unit)", "100^{2}dy0^{2}/dx0^{2}(unit)", "100^{2}dy1^{2}/dx1^{2}(unit)", "#Delta_{z}(unit)", "100*#Delta_{#theta}(unit)", "100^{2}*dz0^{2}/dx0^{2}(unit)", "100^{2}*dz1^{2}/dx1^{2}(unit)" "RMSy_{0} (cm)", "RMSy_{1} (cm)", "RMSz_{0} (cm)", "RMSz_{1} (cm)"}; // // // for (Int_t ihis=0; ihis<12; ihis++){ fLinearTrackDelta[ihis]=0; fLinearTrackPull[ihis]=0; xminQA[0]=-0.5; xmaxQA[0] = 0.5; fLinearTrackDelta[ihis] = new THnSparseS(deltaName[ihis],deltaName[ihis], 6, binsQA,xminQA, xmaxQA); xminQA[0]=-10; xmaxQA[0] = 10; fLinearTrackPull[ihis] = new THnSparseS(pullName[ihis],pullName[ihis], 6, binsQA,xminQA, xmaxQA); for (Int_t iaxis=1; iaxis<6; iaxis++){ fLinearTrackDelta[ihis]->GetAxis(iaxis)->SetName(axisName[iaxis]); fLinearTrackDelta[ihis]->GetAxis(iaxis)->SetTitle(axisName[iaxis]); fLinearTrackPull[ihis]->GetAxis(iaxis)->SetName(axisName[iaxis]); fLinearTrackPull[ihis]->GetAxis(iaxis)->SetTitle(axisName[iaxis]); } fLinearTrackDelta[ihis]->GetAxis(0)->SetName(deltaName[ihis]); fLinearTrackDelta[ihis]->GetAxis(0)->SetTitle(deltaName[ihis]); fLinearTrackPull[ihis]->GetAxis(0)->SetName(deltaName[ihis]); fLinearTrackPull[ihis]->GetAxis(0)->SetTitle(deltaName[ihis]); } } void AliTPCkalmanFit::SetStatus(const char * mask, Bool_t setOn, Bool_t isOr){ // // 0. To activate all transforamtion call SetStatus(0,kTRUE) // 1. To disable everything SetStatus(0,kFALSE) // 2. To activate/desactivate SetStatus("xxx",kTRUE/kFALSE,kFALSE) Int_t ncalibs = fCalibration->GetEntries(); if (mask==0) { for (Int_t i=0; iAt(i); transform->SetActive(setOn); } } else{ for (Int_t i=0; iAt(i); TString strName(transform->GetName()); if (strName.Contains(mask)){ if (!isOr) transform->SetActive( transform->IsActive() && setOn); if (isOr) transform->SetActive( transform->IsActive() || setOn); } } } } void AliTPCkalmanFit::Update(const AliTPCkalmanFit * kalman){ // // Update Kalman filter // Int_t ncalibs = fCalibration->GetEntries(); TMatrixD vecXk=*fCalibParam; // X vector TMatrixD covXk=*fCalibCovar; // X covariance TMatrixD &vecZk = *(kalman->fCalibParam); TMatrixD &measR = *(kalman->fCalibCovar); TMatrixD matHk(ncalibs,ncalibs); // vector to mesurement TMatrixD vecYk(ncalibs,1); // Innovation or measurement residual TMatrixD matHkT(ncalibs,ncalibs); // helper matrix Hk transpose TMatrixD matSk(ncalibs,ncalibs); // Innovation (or residual) covariance TMatrixD matKk(ncalibs,ncalibs); // Optimal Kalman gain TMatrixD covXk2(ncalibs,ncalibs); // helper matrix TMatrixD covXk3(ncalibs,ncalibs); // helper matrix // for (Int_t i=0;iGetEntries(); if (!fLinearParam) { fLinearParam = new TMatrixD(ncalibs+4,1); fLinearCovar = new TMatrixD(ncalibs+4,ncalibs+4); } // for (Int_t i=0; iAt(i); transform->SetParam( (*fLinearParam)(i,0)); (*fCalibParam)(i,0) = (*fLinearParam)(i,0); for (Int_t j=0; jxmean){ fitters[0]->AddPoint(&rxT, ryT,1); fitters[2]->AddPoint(&rxT, rzT,1); fitters[4]->AddPoint(&rx, ry,1); fitters[6]->AddPoint(&rx, rz,1); fitters[8]->AddPoint(&rxT, ryT,1); fitters[10]->AddPoint(&rxT, rzT,1); fitters[12]->AddPoint(&rx, ry,1); fitters[14]->AddPoint(&rx, rz,1); }else{ fitters[1]->AddPoint(&rxT, ryT,1); fitters[3]->AddPoint(&rxT, rzT,1); fitters[5]->AddPoint(&rx, ry,1); fitters[7]->AddPoint(&rx, rz,1); fitters[9]->AddPoint(&rxT, ryT,1); fitters[11]->AddPoint(&rxT, rzT,1); fitters[13]->AddPoint(&rx, ry,1); fitters[15]->AddPoint(&rx, rz,1); } } for (Int_t ifit=0;ifit<16;ifit++){ fitters[ifit]->Eval(); fitters[ifit]->GetParameters(*(params[ifit])); fitters[ifit]->GetErrors(*(errs[ifit])); chi2N[ifit] = TMath::Sqrt(fitters[ifit]->GetChisquare()/(fitters[ifit]->GetNpoints()-1)); (*(errs[ifit]))[0]*=chi2N[ifit]; (*(errs[ifit]))[1]*=chi2N[ifit]; if (ifit>=8) (*(errs[ifit]))[2]*=chi2N[ifit]; // second derivative } if (debug){ (*debug)<<"dumpLinear"<< "alpha="<Fill(x); x[0]/=TMath::Sqrt((*errs[1])[0]*(*errs[1])[0]+(*errs[0])[0]*(*errs[0])[0]); fLinearTrackPull[0]->Fill(x); // //Delta ky // x[0]= 100*((*params[1])[1]-(*params[0])[1]); fLinearTrackDelta[1]->Fill(x); x[0]/=100*TMath::Sqrt((*errs[1])[1]*(*errs[1])[1]+(*errs[0])[1]*(*errs[0])[1]); fLinearTrackPull[1]->Fill(x); // // ky2_0 // x[0]= 100*100*((*params[8])[2]); fLinearTrackDelta[2]->Fill(x); x[0]/=100*100*TMath::Sqrt((*errs[8])[2]*(*errs[8])[2]); fLinearTrackPull[2]->Fill(x); // // ky2_1 // x[0]= 100*100*((*params[9])[2]); fLinearTrackDelta[3]->Fill(x); x[0]/=100*100*TMath::Sqrt((*errs[9])[2]*(*errs[9])[2]); fLinearTrackPull[3]->Fill(x); // // //Delta z // x[0]= (*params[3])[0]-(*params[2])[0]; fLinearTrackDelta[4]->Fill(x); x[0]/=TMath::Sqrt((*errs[3])[0]*(*errs[3])[0]+(*errs[2])[0]*(*errs[2])[0]); fLinearTrackPull[4]->Fill(x); // //Delta kz // x[0]= 100*((*params[3])[1]-(*params[2])[1]); fLinearTrackDelta[5]->Fill(x); x[0]/=100*TMath::Sqrt((*errs[3])[1]*(*errs[3])[1]+(*errs[2])[1]*(*errs[2])[1]); fLinearTrackPull[5]->Fill(x); // // kz2_0 // x[0]= 100*100*((*params[10])[2]); fLinearTrackDelta[6]->Fill(x); x[0]/=100*100*TMath::Sqrt((*errs[10])[2]*(*errs[10])[2]); fLinearTrackPull[6]->Fill(x); // // kz2_1 // x[0]= 100*100*((*params[11])[2]); fLinearTrackDelta[7]->Fill(x); x[0]/=100*100*TMath::Sqrt((*errs[11])[2]*(*errs[11])[2]); fLinearTrackPull[7]->Fill(x); // // rms of track // x[0]= chi2N[0]; fLinearTrackDelta[8]->Fill(x); x[0]= chi2N[1]; fLinearTrackDelta[9]->Fill(x); x[0]= chi2N[2]; fLinearTrackDelta[10]->Fill(x); x[0]= chi2N[3]; fLinearTrackDelta[11]->Fill(x); // for (Int_t ifit=0; ifit<8;ifit++){ delete fitters[ifit]; delete params[ifit]; delete fitters[ifit+8]; delete params[ifit+8]; delete errs[ifit]; delete errs[ifit+8]; } } void AliTPCkalmanFit::Propagate(TTreeSRedirector */*debug*/){ // // Propagate the Kalman // } void AliTPCkalmanFit::AddCovariance(const char * varName, Double_t sigma){ // // // if (fCalibCovar) return; if (!fCalibration) return; if (!fCalibration->FindObject(varName)) return; Int_t ncalibs = fCalibration->GetEntries(); TString strVar(varName); for (Int_t icalib=0;icalibAt(icalib); if (strVar.CompareTo(transform->GetName())==0){ (*fCalibCovar)(icalib,icalib)+=sigma*sigma; } } } void AliTPCkalmanFit::PropagateTime(Int_t time){ // // Propagate the calibration in time // - Increase covariance matrix // if (!fCalibCovar) return; Int_t ncalibs = fCalibration->GetEntries(); Double_t deltaT = 0; if (fLastTimeStamp>0) deltaT = (fLastTimeStamp-time)/(60*60.); // delta T in hours fLastTimeStamp = time; for (Int_t icalib=0;icalibAt(icalib); if ((*fCalibCovar)(icalib,icalib)GetSigmaMax()*transform->GetSigmaMax()) (*fCalibCovar)(icalib,icalib)+= transform->GetSigma2Time()*TMath::Abs(deltaT); } } void AliTPCkalmanFit::UpdateLinear(AliTrackPoint &point, TTreeSRedirector *debug){ // // Update Kalman // // Int_t ncalibs = fCalibration->GetEntries(); Int_t kNmeas = 2; Int_t nelem = ncalibs+4; TMatrixD &vecXk=*fLinearParam; // X vector TMatrixD &covXk=*fLinearCovar; // X covariance // TMatrixD matHk(kNmeas,nelem); // vector to mesurement TMatrixD vecYk(kNmeas,1); // Innovation or measurement residual TMatrixD vecZk(kNmeas,1); // Innovation or measurement residual TMatrixD measR(kNmeas,kNmeas); TMatrixD matHkT(nelem,kNmeas); // helper matrix Hk transpose TMatrixD matSk(kNmeas,kNmeas); // Innovation (or residual) covariance TMatrixD matKk(nelem,kNmeas); // Optimal Kalman gain TMatrixD covXk2(nelem,nelem); // helper matrix TMatrixD covXk3(nelem,nelem); // helper matrix TMatrixD mat1(nelem,nelem); // // reset matHk for (Int_t iel=0;ielAt(icalib); dxdydz[0] = transform->GetDeltaXYZ(0,volId, 1, gxyz[0], gxyz[1], gxyz[2]); dxdydz[1] = transform->GetDeltaXYZ(1,volId, 1, gxyz[0], gxyz[1], gxyz[2]); dxdydz[2] = transform->GetDeltaXYZ(2,volId, 1, gxyz[0], gxyz[1], gxyz[2]); rdxdydz[0] = fCA*dxdydz[0]+fSA*dxdydz[1]; rdxdydz[1] = -fSA*dxdydz[0]+fCA*dxdydz[1]; rdxdydz[2] = dxdydz[2]; // matHk(0,icalib)= rdxdydz[1]-rdxdydz[0]*(*fLinearParam)(ncalibs+1,0); // shift y + shift x * angleY matHk(1,icalib)= rdxdydz[2]-rdxdydz[0]*(*fLinearParam)(ncalibs+3,0); // shift z + shift x * angleZ } matHk(0,ncalibs+0)=1; matHk(0,ncalibs+1)=rxyz[0]; matHk(1,ncalibs+2)=1; matHk(1,ncalibs+3)=rxyz[0]; // // // vecZk(0,0) = rxyz[1]; vecZk(1,0) = rxyz[2]; measR(0,0) = point.GetCov()[1]; measR(0,1)=0; measR(1,1) = point.GetCov()[2]; measR(1,0)=0; // vecYk = vecZk-matHk*vecXk; // Innovation or measurement residual matHkT=matHk.T(); matHk.T(); matSk = (matHk*(covXk*matHkT))+measR; // Innovation (or residual) covariance matSk.Invert(); matKk = (covXk*matHkT)*matSk; // Optimal Kalman gain // covXk2= (mat1-(matKk*matHk)); covXk3 = covXk2*covXk; // CheckCovariance(covXk3,100); vecXk += matKk*vecYk; // updated vector covXk = covXk3; if (debug){ // dump debug info (*debug)<<"updateLinear"<< // "point.="<<&point<< "vecYk.="<<&vecYk<< "vecZk.="<<&vecZk<< "measR.="<<&measR<< "matHk.="<<&matHk<< "matHkT.="<<&matHkT<< "matSk.="<<&matSk<< "matKk.="<<&matKk<< "covXk2.="<<&covXk2<< "covXk.="<<&covXk<< "vecXk.="<<&vecXk<< "\n"; } } AliTrackPointArray * AliTPCkalmanFit::SortPoints(AliTrackPointArray &points){ // //Creates the array - points sorted according radius - neccessay for kalman fit // // // 0. choose the frame - rotation angle // Int_t npoints = points.GetNPoints(); if (npoints<1) return 0; Double_t currentAlpha = TMath::ATan2(points.GetY()[npoints-1]-points.GetY()[0], points.GetX()[npoints-1]-points.GetX()[0]); Double_t ca = TMath::Cos(currentAlpha); Double_t sa = TMath::Sin(currentAlpha); // // 1. sort the points // Double_t *rxvector = new Double_t[npoints]; Int_t *indexes = new Int_t[npoints]; for (Int_t ipoint=0; ipointAddPoint(ipoint,&point); } delete [] rxvector; delete [] indexes; return pointsSorted; } AliTrackPointArray * AliTPCkalmanFit::MakePointArrayLinear(Double_t alpha, Double_t y0, Double_t z0, Double_t ky, Double_t kz, Double_t err){ // // // AliTrackPointArray array(500); Float_t cov[10]; // dummy covariance Int_t npoints=0; for (Int_t i=0;i<6;i++) cov[i]=0.001; for (Int_t i=0;i<500;i++){ AliTrackPoint point(0, 0, 0, cov, -1,0,0); array.AddPoint(npoints, &point); npoints++; } npoints=0; for (Float_t ir = -245; ir<245; ir++){ // // if (TMath::Abs(ir)<80) continue; Double_t ca = TMath::Cos(alpha); Double_t sa = TMath::Sin(alpha); Double_t lx = ir; Double_t ly = y0+lx*ky+gRandom->Gaus(0,err); Double_t lz = z0+lx*kz+gRandom->Gaus(0,err); Double_t gx = lx*ca-ly*sa; Double_t gy = lx*sa+ly*ca; Double_t gz = lz; Double_t galpha = TMath::ATan2(gy,gx); Int_t isec = TMath::Nint((9*galpha/TMath::Pi()+0.5)); if (isec<0) isec+=18; if (gz<0) isec+=18; if (ir>130) isec+=36; // AliTrackPoint point(gx, gy, gz, cov, isec,0,0); array.AddPoint(npoints, &point); npoints++; } AliTrackPointArray *parray = new AliTrackPointArray(npoints); AliTrackPoint point; for (Int_t i=0;iAddPoint(i,&point); } return parray; } void AliTPCkalmanFit::AddCalibration(AliTPCTransformation * calib){ // // Add calibration // if (!fCalibration) fCalibration = new TObjArray(2000); fCalibration->AddLast(calib); } Int_t AliTPCkalmanFit::GetTransformationIndex(const char * trName){ // // // if (!fCalibration) return -1; if (!fCalibration->FindObject(trName)) return -1; // Int_t ncalibs = fCalibration->GetEntries(); TString strVar(trName); for (Int_t icalib=0;icalibAt(icalib); if (strVar.CompareTo(transform->GetName())==0){ return icalib; } } return -1; } void AliTPCkalmanFit::ApplyCalibration(AliTrackPointArray *array, Double_t csign){ // // // if (!fCalibration) return; Int_t ncalibs = fCalibration->GetEntries(); if (ncalibs==0) return; Int_t npoints = array->GetNPoints(); for (Int_t ipoint=0; ipointGetVolumeID()[ipoint]; Double_t xyz[3]={array->GetX()[ipoint], array->GetY()[ipoint],array->GetZ()[ipoint]}; Double_t dxdydz[3]={0,0,0}; for (Int_t icalib=0; icalibAt(icalib); dxdydz[0] += transform->GetDeltaXYZ(0,volId, transform->GetParam(), xyz[0], xyz[1], xyz[2]); dxdydz[1] += transform->GetDeltaXYZ(1,volId, transform->GetParam(), xyz[0], xyz[1], xyz[2]); dxdydz[2] += transform->GetDeltaXYZ(2,volId, transform->GetParam(), xyz[0], xyz[1], xyz[2]); } ((Float_t*)array->GetX())[ipoint]+=csign*dxdydz[0]; ((Float_t*)array->GetY())[ipoint]+=csign*dxdydz[1]; ((Float_t*)array->GetZ())[ipoint]+=csign*dxdydz[2]; } } Bool_t AliTPCkalmanFit::DumpCorelation(Double_t threshold, const char *mask0, const char *mask1){ // // // TMatrixD &mat = *fCalibCovar; Int_t nrow= mat.GetNrows(); for (Int_t irow=0; irowGetName()); if (mask0){ if (!strName0.Contains(mask0)) continue; } for (Int_t icol=irow+1; icolGetName()); if (mask1){ if (!strName1.Contains(mask1)) continue; } // Double_t diag = TMath::Sqrt(TMath::Abs(mat(irow,irow)*mat(icol,icol))); if (diag<=0){ printf("Negative covariance\t%d\t%d\t%f\n",irow,icol, mat(irow,icol)); continue; } Double_t corr0 = mat(irow,icol)/diag; if (TMath::Abs(corr0)>threshold){ printf("%d\t%d\t%s\t%s\t%f\t%f\t%f\n", irow,icol, trans0->GetName(), trans1->GetName(), TMath::Sqrt(mat(irow,irow)), TMath::Sqrt(mat(icol,icol)), corr0); } } } return (nrow>0); } Bool_t AliTPCkalmanFit::DumpCalib(const char *mask, Float_t correlationCut){ // // Print calibration entries - name, value, error // TMatrixD &mat = *fCalibCovar; Int_t nrow= mat.GetNrows(); TString strMask(mask); TVectorD vecCorrSum(nrow); for (Int_t irow=0; irowGetName()); if (mask){ if (!strName.Contains(mask)) continue; } if (vecCorrSum[irow]GetName(), (*fCalibParam)(irow,0), TMath::Sqrt(mat(irow,irow)), vecCorrSum[irow]); } return (nrow>0); } Bool_t AliTPCkalmanFit::CheckCovariance(TMatrixD &mat, Float_t /*maxEl*/){ // // Check consistency of covariance matrix // + symetrize coavariance matrix Bool_t isOK=kTRUE; Int_t nrow= mat.GetNrows(); for (Int_t irow=0; irowmaxEl){ // printf("Too big covariance\t%d\t%f\n",irow,mat(irow,irow)); // isOK=kFALSE; // } for (Int_t icol=0; icol1 || TMath::Abs(cov1)>1 ){ printf("Covariance Problem %d\t%d\t%f\t%f\n",irow,icol, cov0, cov1); isOK=kFALSE; } if (TMath::Abs(cov0-cov1)>0.0000001){ printf("Asymetry problem %d\t%d\t%f\t%f\n",irow,icol, cov0, cov1); isOK=kFALSE; } // // symetrize the covariance matrix Double_t mean = (mat(irow,icol)+ mat(icol,irow))*0.5; mat(irow,icol)=mean; mat(icol,irow)=mean; } } return isOK; } AliTPCkalmanFit * AliTPCkalmanFit::Test(Int_t ntracks){ // // This is test example // // // 1. Setup transformation // TVectorD fpar(10); AliTPCTransformation * transformation=0; AliTPCkalmanFit * kalmanFit0 = new AliTPCkalmanFit; AliTPCkalmanFit * kalmanFit2 = new AliTPCkalmanFit; // // Radial scaling // for (Int_t iside=0; iside<=1; iside++) for (Int_t ipar0=0; ipar0<3; ipar0++) for (Int_t ipar1=0; ipar1<3; ipar1++){ fpar[0]=ipar0; fpar[1]=ipar1; if (ipar0+ipar1==0) continue; Double_t param = (gRandom->Rndm()-0.5)*0.5; // generate random parameters char tname[100]; sprintf(tname,"tscalingR%d%dSide%d",ipar0,ipar1,iside); transformation = new AliTPCTransformation(tname,AliTPCTransformation::BitsSide(iside),"TPCscalingRPol",0,0,1); transformation->SetParams(0,5*0.25,0,&fpar); kalmanFit0->AddCalibration(transformation); transformation = new AliTPCTransformation(tname,AliTPCTransformation::BitsSide(iside),"TPCscalingRPol",0,0,1); transformation->SetParams(param,0.25,0,&fpar); kalmanFit2->AddCalibration(transformation); } // // 2. Init transformation // kalmanFit2->Init(); kalmanFit0->Init(); // // 3. Run kalman filter // Int_t ncalibs = kalmanFit0->fCalibration->GetEntries(); TVectorD err(ncalibs); TTreeSRedirector *pcstream = new TTreeSRedirector("kalmanfitTest.root"); for (Int_t i=0;iRndm()*TMath::TwoPi(); Double_t y0 = (gRandom->Rndm()-0.5)*180; Double_t z0 = (gRandom->Rndm()-0.5)*250*2; Double_t ky = (gRandom->Rndm()-0.5)*1; Double_t kz = (gRandom->Rndm()-0.5)*1; //generate random TPC track AliTrackPointArray * array = AliTPCkalmanFit::MakePointArrayLinear(alpha,y0,z0, ky, kz,0.04); AliTrackPointArray * arrayB = new AliTrackPointArray(*array); // backup kalmanFit2->ApplyCalibration(array,1.); // misalign ideal track for (Int_t icalib=0; icalibfCalibCovar)(icalib,icalib)); } // (*pcstream)<<"dump0"<< "alpha="<FitTrackLinear(*array,pcstream); // fit track - dump intermediate results }else{ kalmanFit0->FitTrackLinear(*array,0); // fit track + calibration } kalmanFit0->DumpTrackLinear(*array,pcstream); // dump track residuals to the tree + fill histograms } pcstream->GetFile()->cd(); kalmanFit0->Write("kalmanFit"); delete pcstream; return kalmanFit0; } // Double_t AliTPCkalmanFit::GetTPCDeltaXYZ(Int_t coord, Int_t volID, Double_t x, Double_t y, Double_t z){ // // // // function for visualization purposes // // // if (!fCalibration) return 0; // Int_t ncalibs = fCalibration->GetEntries(); // if (ncalibs==0) return 0; // Double_t dxdydz[3]={0,0,0}; // // // if (volID<0){ // Double_t alpha = TMath::ATan2(y,x); // Double_t r = TMath::Sqrt(y*y+x*x); // volID = TMath::Nint(9*alpha/TMath::Pi()-0.5); // if (volID<0) volID+=18; // if (z<0) volID+=18; // if (r>120) volID+=36; // } // for (Int_t icalib=0; icalibAt(icalib); // Double_t param = (*fCalibParam)(icalib,0); // dxdydz[coord] += transform->GetDeltaXYZ(coord,volID, param, x, y,z); // } // return dxdydz[coord]; // } // Double_t AliTPCkalmanFit::SGetTPCDeltaXYZ(Int_t coord, Int_t volID, Double_t x, Double_t y, Double_t z){ // // // // // // // if (AliTPCkalmanFit::fgInstance==0) return 0; // return AliTPCkalmanFit::fgInstance->GetTPCDeltaXYZ(coord, volID,x,y,z); // } Double_t AliTPCkalmanFit::GetTPCDeltaXYZ(Int_t coord, Int_t volID, Int_t icoordsys, Double_t x, Double_t y, Double_t z){ // // function for visualization purposes // // coord - coordinate for output // - 0 -X // 1 -Y // 2 -Z // 3 -R // 4 -RPhi // 5 -Z // //icoordsys - type of coordinate system for input // - 0 - x,y,z // - 1 - r,phi,z // if (!fCalibration) return 0; Int_t ncalibs = fCalibration->GetEntries(); if (ncalibs==0) return 0; Double_t xyz[3]={0,0,0}; Double_t dxdydz[6]={0,0,0,0,0,0}; Double_t alpha=0; Double_t r=0; if(icoordsys==0){alpha=TMath::ATan2(y,x); r =TMath::Sqrt(y*y+x*x);} if(icoordsys==1){alpha=y; r=x;} Double_t ca = TMath::Cos(alpha); Double_t sa = TMath::Sin(alpha); if(icoordsys==0){xyz[0]=x; xyz[1]=y; xyz[2]=z;} if(icoordsys==1){xyz[0]=x*ca; xyz[1]=x*sa; xyz[2]=z;} // if (volID<0){ // Double_t alpha = TMath::ATan2(y,x); //Double_t r = TMath::Sqrt(y*y+x*x); volID = TMath::Nint(9*alpha/TMath::Pi()-0.5); if (volID<0) volID+=18; if (z<0) volID+=18; if (r>120) volID+=36; } for (Int_t icalib=0; icalibAt(icalib); Double_t param = (*fCalibParam)(icalib,0); for (Int_t icoord=0;icoord<6;icoord++){ dxdydz[icoord] += transform->GetDeltaXYZ(icoord,volID, param, xyz[0],xyz[1],xyz[2]); } } return dxdydz[coord]; } Double_t AliTPCkalmanFit::SGetTPCDeltaXYZ(Int_t coord, Int_t volID, Int_t icoordsys, Double_t x, Double_t y, Double_t z){ // // // if (AliTPCkalmanFit::fgInstance==0) return 0; return AliTPCkalmanFit::fgInstance->GetTPCDeltaXYZ(coord, volID, icoordsys,x,y,z); } Double_t AliTPCkalmanFit::GetTPCtransXYZ(Int_t coord, Int_t volID, Int_t calibID, Int_t icoordsys, Double_t x, Double_t y, Double_t z){ Int_t ncalibs = fCalibration->GetEntries(); if (calibID>=ncalibs) return 0; //Int_t volID=-1; //Double_t xyz[3]={x,y,z}; Double_t r=0; Double_t alpha=0; if(icoordsys==0){r=TMath::Sqrt(x*x+y*y); alpha = TMath::ATan2(y,x);} if(icoordsys==1){r=x; alpha = y;} Double_t ca = TMath::Cos(alpha); Double_t sa = TMath::Sin(alpha); Double_t xyz[3]={0,0,0}; if(icoordsys==0){xyz[0]=x;xyz[1]=y;xyz[2]=z;} if(icoordsys==1){xyz[0]=x*ca; xyz[1]=x*sa; xyz[2]=z;} //xyz[3]=param; xyz[4]=volID; if (volID<0){ //Double_t alpha = TMath::ATan2(xyz[1],xyz[0]); //Double_t r = TMath::Sqrt(xyz[1]*xyz[1]+xyz[0]*xyz[0]); volID = TMath::Nint(9*alpha/TMath::Pi()-0.5); if (volID<0) volID+=18; if (xyz[2]<0) volID+=18; if (r>120) volID+=36; } AliTPCTransformation * transform = (AliTPCTransformation *)fCalibration->At(calibID); //transform->SetInstance(transform); Double_t param = (*fCalibParam)(calibID,0); Double_t delta = (Double_t)transform->GetDeltaXYZ(coord,volID, param, xyz[0],xyz[1],xyz[2]); return delta; } Double_t AliTPCkalmanFit::SGetTPCtransXYZ(Int_t coord, Int_t volID, Int_t calibID, Int_t icoordsys, Double_t x, Double_t y, Double_t z){ // // // if (AliTPCkalmanFit::fgInstance==0) return 0; return AliTPCkalmanFit::fgInstance->GetTPCtransXYZ(coord, volID, calibID,icoordsys,x,y,z); } void AliTPCkalmanFit::MakeTreeTrans(TTreeSRedirector *debug, const char *treeName){ // // Make the Tree before and after current calibration // if (!fCalibParam) { AliError("Kalman Fit not initialized"); return; } // // // const Int_t ncalibs = fCalibration->GetEntries(); TMatrixD dxdydz(ncalibs,5); Double_t * adx = new Double_t[ncalibs]; Double_t * ady = new Double_t[ncalibs]; Double_t * adz = new Double_t[ncalibs]; Double_t * adr = new Double_t[ncalibs]; Double_t * adrphi = new Double_t[ncalibs]; Double_t x[3]; for (x[0]=-250.;x[0]<=250.;x[0]+=10.){ for (x[1]=-250.;x[1]<=250.;x[1]+=10.){ for (x[2]=-250.;x[2]<=250.;x[2]+=20.) { Double_t r=TMath::Sqrt(x[0]*x[0]+x[1]*x[1]); if (r<20) continue; if (r>260) continue; //Double_t z = x[2]; Double_t phi=TMath::ATan2(x[1],x[0]); Double_t ca=TMath::Cos(phi); Double_t sa=TMath::Sin(phi); Double_t dx=0; Double_t dy=0; Double_t dz=0; Double_t dr=0; Double_t rdphi=0; Int_t volID= TMath::Nint(9*phi/TMath::Pi()-0.5); if (volID<0) volID+=18; if (x[2]<0) volID+=18; //C-side if (r>120) volID+=36; //outer Double_t volalpha=(volID+0.5)*TMath::Pi()/9; Double_t cva=TMath::Cos(volalpha); Double_t sva=TMath::Sin(volalpha); Double_t lx=x[0]*cva+x[1]*sva; Double_t ly=-x[0]*sva+x[1]*cva; for(Int_t icalib=0;icalib