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 **************************************************************************/
19 Responsible: marian.ivanov@cern.ch
20 Tools for fitting of the space point distortion parameters.
24 1. Creation of the distortion maps from the residual histograms
26 3. Parameters to calculate- dO/dp
28 Some functions, for the moment function present in the AliTPCPreprocesorOffline, some will be
29 extracted from the old macros
34 #include "Riostream.h"
37 #include "TGraphErrors.h"
38 #include "AliExternalTrackParam.h"
41 #include "TMultiGraph.h"
43 #include "THnSparse.h"
51 #include "AliTPCROC.h"
52 #include "AliTPCCalROC.h"
53 #include "AliESDfriend.h"
54 #include "AliTPCcalibTime.h"
55 #include "AliSplineFit.h"
56 #include "AliCDBMetaData.h"
58 #include "AliCDBManager.h"
59 #include "AliCDBStorage.h"
60 #include "AliTPCcalibBase.h"
61 #include "AliTPCcalibDB.h"
62 #include "AliTPCcalibDButil.h"
63 #include "AliRelAlignerKalman.h"
64 #include "AliTPCParamSR.h"
65 #include "AliTPCcalibTimeGain.h"
66 #include "AliTPCcalibGainMult.h"
67 #include "AliSplineFit.h"
68 #include "AliTPCComposedCorrection.h"
69 #include "AliTPCExBTwist.h"
70 #include "AliTPCCalibGlobalMisalignment.h"
71 #include "TStatToolkit.h"
74 #include "AliTrackerBase.h"
75 #include "AliTPCCorrectionFit.h"
76 #include "AliTPCLaserTrack.h"
77 #include "TDatabasePDG.h"
78 #include "AliTPCcalibAlign.h"
80 ClassImp(AliTPCCorrectionFit)
82 AliTPCCorrectionFit::AliTPCCorrectionFit():
83 TNamed("TPCCorrectionFit","TPCCorrectionFit")
86 // default constructor
90 AliTPCCorrectionFit::~AliTPCCorrectionFit() {
97 Double_t AliTPCCorrectionFit::EvalAt(Double_t phi, Double_t refX, Double_t theta, Int_t corr, Int_t ptype){
101 Double_t sector = 9*phi/TMath::Pi();
102 if (sector<0) sector+=18;
103 Double_t y85=AliTPCCorrection::GetCorrSector(sector,85,theta,1,corr);
104 Double_t y245=AliTPCCorrection::GetCorrSector(sector,245,theta,1,corr);
105 if (ptype==0) return y85+(y245-y85)*(refX-85.)/(245.-85.);
106 if (ptype==2) return (y245-y85)/(245.-85.);
113 Double_t AliTPCCorrectionFit::EvalAtPar(Double_t phi0, Double_t snp, Double_t refX, Double_t theta, Int_t corr, Int_t ptype, Int_t nsteps){
115 // Fit the distortion along the line with the parabolic model
117 // phi0 - phi at the entrance of the TPC
118 // snp - local inclination angle at the entrance of the TPC
119 // refX - ref X where the distortion is evanluated
122 static TLinearFitter fitter(3,"pol2");
123 fitter.ClearPoints();
124 if (nsteps<3) nsteps=3;
125 Double_t deltaX=(245-85)/(nsteps);
126 for (Int_t istep=0; istep<(nsteps+1); istep++){
128 Double_t localX =85.+deltaX*istep;
129 Double_t localPhi=phi0+deltaX*snp*istep;
130 Double_t sector = 9*localPhi/TMath::Pi();
131 if (sector<0) sector+=18;
132 Double_t y=AliTPCCorrection::GetCorrSector(sector,localX,theta,1,corr);
133 Double_t dlocalX=AliTPCCorrection::GetCorrSector(sector,localX,theta,0,corr);
134 Double_t x[1]={localX-dlocalX};
135 fitter.AddPoint(x,y);
139 par[0]=fitter.GetParameter(0);
140 par[1]=fitter.GetParameter(1);
141 par[2]=fitter.GetParameter(2);
143 if (ptype==0) return par[0]+par[1]*refX+par[2]*refX*refX;
144 if (ptype==2) return par[1]+2*par[2]*refX;
145 if (ptype==4) return par[2];
152 void AliTPCCorrectionFit::CreateAlignMaps(Double_t bz, Int_t run){
154 // Create cluster distortion map
156 TFile *falign = TFile::Open("CalibObjects.root");
157 TObjArray * arrayAlign = (TObjArray *)falign->Get("TPCAlign");
159 AliWarning("Alignment was not included in the calibration task");
162 AliTPCcalibAlign * align = (AliTPCcalibAlign *)arrayAlign->FindObject("alignTPC");
164 AliWarning("Alignment was not included in the calibration task");
167 TTreeSRedirector * pcstream = new TTreeSRedirector("TPCAlign.root");
169 THnBase * hdY = (THnBase*)align->GetClusterDelta(0);
170 //THnBase * hdZ = (THnBase*)align->GetClusterDelta(1);
171 AliTPCCorrectionFit::MakeClusterDistortionMap(hdY,pcstream,0, bz);
172 // AliTPCCorrectionFit::MakeClusterDistortionMap(hdZ,pcstream,1, bz);
174 const char * hname[5]={"dy","dz","dsnp","dtheta","d1pt"};
175 for (Int_t ihis=0; ihis<4; ihis++){
176 THnSparse * hisAlign =align->GetTrackletDelta(ihis);
177 AliTPCCorrectionFit::MakeDistortionMapSector(hisAlign, pcstream, hname[ihis], run, ihis,bz);
187 void AliTPCCorrectionFit::MakeClusterDistortionMap(THnBase * hisInput,TTreeSRedirector *pcstream , Int_t ptype, Int_t dtype){
189 // Make cluster residual map from the n-dimensional histogram
190 // hisInput supposed to have given format:
196 // Vertex position assumed to be at (0,0,0)
198 //TTreeSRedirector *pcstream=new TTreeSRedirector(sname);
200 Int_t nbins1=hisInput->GetAxis(1)->GetNbins();
201 Int_t nbins2=hisInput->GetAxis(2)->GetNbins();
202 Int_t nbins3=hisInput->GetAxis(3)->GetNbins();
205 new TH3F("his3D","his3D",
206 nbins1,hisInput->GetAxis(1)->GetXmin(), hisInput->GetAxis(1)->GetXmax(),
207 nbins2,hisInput->GetAxis(2)->GetXmin(), hisInput->GetAxis(2)->GetXmax(),
208 nbins3,hisInput->GetAxis(3)->GetXmin(), hisInput->GetAxis(3)->GetXmax());
209 hisResMap3D->GetXaxis()->SetTitle("sector");
210 hisResMap3D->GetYaxis()->SetTitle("localX");
211 hisResMap3D->GetZaxis()->SetTitle("kZ");
213 TH2F * hisResMap2D[4] ={0,0,0,0};
214 for (Int_t i=0; i<4; i++){
216 new TH2F(Form("his2D_0%d",i),Form("his2D_0%d",i),
217 nbins1,hisInput->GetAxis(1)->GetXmin(), hisInput->GetAxis(1)->GetXmax(),
218 nbins2,hisInput->GetAxis(2)->GetXmin(), hisInput->GetAxis(2)->GetXmax());
219 hisResMap2D[i]->GetXaxis()->SetTitle("sector");
220 hisResMap2D[i]->GetYaxis()->SetTitle("localX");
226 Int_t axis0[4]={0,1,2,3};
227 Int_t axis1[4]={0,1,2,3};
229 for (Int_t ibin1=1; ibin1<nbins1; ibin1+=1){
231 hisInput->GetAxis(1)->SetRange(ibin1-1,ibin1+1);
232 THnBase *his1=(THnBase *)hisInput->ProjectionND(4,axis0);
233 Double_t sector=hisInput->GetAxis(1)->GetBinCenter(ibin1);
235 for (Int_t ibin2=1; ibin2<nbins2; ibin2+=1){
238 his1->GetAxis(2)->SetRange(ibin2-1,ibin2+1);
239 THnBase *his2=(THnBase *)his1->ProjectionND(4,axis1);
240 Double_t localX=hisInput->GetAxis(2)->GetBinCenter(ibin2);
243 his2->GetAxis(3)->SetRangeUser(0.01,0.3);
244 TH1 * hisA = his2->Projection(0);
245 Double_t meanA= hisA->GetMean();
246 Double_t rmsA= hisA->GetRMS();
247 Double_t entriesA= hisA->GetEntries();
250 his2->GetAxis(3)->SetRangeUser(0.01,0.3);
251 TH1 * hisC = his2->Projection(0);
252 Double_t meanC= hisC->GetMean();
253 Double_t rmsC= hisC->GetRMS();
254 Double_t entriesC= hisC->GetEntries();
256 his2->GetAxis(3)->SetRangeUser(-1.2,1.2);
257 TH2 * hisAC = his2->Projection(0,3);
258 TProfile *profAC = hisAC->ProfileX();
260 profAC->Fit("pol1","QNR","QNR",0.05,1);
261 if (!f1) f1=(TF1*)gROOT->FindObject("pol1");
262 Double_t offsetA=f1->GetParameter(0);
263 Double_t slopeA=f1->GetParameter(1);
264 Double_t offsetAE=f1->GetParError(0);
265 Double_t slopeAE=f1->GetParError(1);
266 Double_t chi2A=f1->GetChisquare()/f1->GetNumberFreeParameters();
267 profAC->Fit("pol1","QNR","QNR",-1.1,-0.1);
268 f1=(TF1*)gROOT->FindObject("pol1");
269 Double_t offsetC=f1->GetParameter(0);
270 Double_t slopeC=f1->GetParameter(1);
271 Double_t offsetCE=f1->GetParError(0);
272 Double_t slopeCE=f1->GetParError(1);
273 Double_t chi2C=f1->GetChisquare()/f1->GetNumberFreeParameters();
274 if (counter%50==0) printf("%f\t%f\t%f\t%f\t%f\t%f\t%f\n", sector,localX, entriesA+entriesC, slopeA,slopeC, chi2A, chi2C);
276 (*pcstream)<<"deltaFit"<<
281 "entriesA="<<entriesA<<
284 "entriesC="<<entriesC<<
285 "offsetA="<<offsetA<<
287 "offsetAE="<<offsetAE<<
288 "slopeAE="<<slopeAE<<
290 "offsetC="<<offsetC<<
292 "offsetCE="<<offsetCE<<
293 "slopeCE="<<slopeCE<<
297 hisResMap2D[0]->SetBinContent(ibin1,ibin2, offsetA);
298 hisResMap2D[1]->SetBinContent(ibin1,ibin2, slopeA);
299 hisResMap2D[2]->SetBinContent(ibin1,ibin2, offsetC);
300 hisResMap2D[3]->SetBinContent(ibin1,ibin2, slopeC);
302 for (Int_t ibin3=1; ibin3<nbins3; ibin3++){
303 Double_t kZ=hisInput->GetAxis(3)->GetBinCenter(ibin3);
304 if (TMath::Abs(kZ)<0.05) continue; // crossing
305 his2->GetAxis(3)->SetRange(ibin3,ibin3);
306 if (TMath::Abs(kZ)>0.15){
307 his2->GetAxis(3)->SetRange(ibin3,ibin3);
309 TH1 * his = his2->Projection(0);
310 Double_t mean= his->GetMean();
311 Double_t rms= his->GetRMS();
312 Double_t entries= his->GetEntries();
313 //printf("%f\t%f\t%f\t%f\t%f\t%f\n", sector,localX,kZ, entries, mean,rms);
314 hisResMap3D->SetBinContent(ibin1,ibin2,ibin3, mean);
315 Double_t phi=TMath::Pi()*sector/9;
316 if (phi>TMath::Pi()) phi+=TMath::Pi();
321 his->Fit("gaus","Q","goff");
322 fgaus= (TF1*)((his->GetListOfFunctions()->FindObject("gaus"))->Clone());
325 his->Fit(fgaus,"Q","goff");
326 meanG=fgaus->GetParameter(1);
327 rmsG=fgaus->GetParameter(2);
330 Double_t dsec=sector-Int_t(sector)-0.5;
331 Double_t snp=dsec*TMath::Pi()/9.;
332 (*pcstream)<<"delta"<<
346 "entries="<<entries<<
349 "entriesA="<<entriesA<<
352 "entriesC="<<entriesC<<
353 "offsetA="<<offsetA<<
356 "offsetC="<<offsetC<<
366 hisResMap3D->Write();
367 hisResMap2D[0]->Write();
368 hisResMap2D[1]->Write();
369 hisResMap2D[2]->Write();
370 hisResMap2D[3]->Write();
376 void AliTPCCorrectionFit::MakeDistortionMap(THnSparse * his0, TTreeSRedirector * const pcstream, const char* hname, Int_t run, Float_t refX, Int_t type, Int_t integ, Double_t bz){
378 // make a distortion map out ou fthe residual histogram
379 // Results are written to the debug streamer - pcstream
381 // his0 - input (4D) residual histogram
382 // pcstream - file to write the tree
384 // refX - track matching reference X
385 // type - 0- y 1-z,2 -snp, 3-theta, 4=1/pt
387 // OBJ: TAxis #Delta #Delta
388 // OBJ: TAxis tanTheta tan(#Theta)
389 // OBJ: TAxis phi #phi
390 // OBJ: TAxis snp snp
392 // marian.ivanov@cern.ch
393 const Int_t kMinEntries=10;
394 Int_t idim[4]={0,1,2,3};
398 Int_t nbins3=his0->GetAxis(3)->GetNbins();
399 Int_t first3=his0->GetAxis(3)->GetFirst();
400 Int_t last3 =his0->GetAxis(3)->GetLast();
402 for (Int_t ibin3=first3; ibin3<last3; ibin3+=1){ // axis 3 - local angle
403 his0->GetAxis(3)->SetRange(TMath::Max(ibin3-integ,1),TMath::Min(ibin3+integ,nbins3));
404 Double_t x3= his0->GetAxis(3)->GetBinCenter(ibin3);
405 THnSparse * his3= his0->Projection(3,idim); //projected histogram according selection 3
407 Int_t nbins2 = his3->GetAxis(2)->GetNbins();
408 Int_t first2 = his3->GetAxis(2)->GetFirst();
409 Int_t last2 = his3->GetAxis(2)->GetLast();
411 for (Int_t ibin2=first2; ibin2<last2; ibin2+=1){ // axis 2 - phi
412 his3->GetAxis(2)->SetRange(TMath::Max(ibin2-integ,1),TMath::Min(ibin2+integ,nbins2));
413 Double_t x2= his3->GetAxis(2)->GetBinCenter(ibin2);
414 THnSparse * his2= his3->Projection(2,idim); //projected histogram according selection 2
415 Int_t nbins1 = his2->GetAxis(1)->GetNbins();
416 Int_t first1 = his2->GetAxis(1)->GetFirst();
417 Int_t last1 = his2->GetAxis(1)->GetLast();
418 for (Int_t ibin1=first1; ibin1<last1; ibin1++){ //axis 1 - theta
420 Double_t x1= his2->GetAxis(1)->GetBinCenter(ibin1);
421 his2->GetAxis(1)->SetRange(TMath::Max(ibin1-1,1),TMath::Min(ibin1+1,nbins1));
422 if (TMath::Abs(x1)<0.1){
423 if (x1<0) his2->GetAxis(1)->SetRange(TMath::Max(ibin1-1,1),TMath::Min(ibin1,nbins1));
424 if (x1>0) his2->GetAxis(1)->SetRange(TMath::Max(ibin1,1),TMath::Min(ibin1+1,nbins1));
426 if (TMath::Abs(x1)<0.06){
427 his2->GetAxis(1)->SetRange(TMath::Max(ibin1,1),TMath::Min(ibin1,nbins1));
429 TH1 * hisDelta = his2->Projection(0);
431 Double_t entries = hisDelta->GetEntries();
432 Double_t mean=0, rms=0;
433 if (entries>kMinEntries){
434 mean = hisDelta->GetMean();
435 rms = hisDelta->GetRMS();
437 Double_t sector = 9.*x2/TMath::Pi();
438 if (sector<0) sector+=18;
439 Double_t dsec = sector-Int_t(sector)-0.5;
448 "entries="<<entries<<
451 "refX="<<refX<< // track matching refernce plane
457 //printf("%f\t%f\t%f\t%f\t%f\n",x3,x2,x1, entries,mean);
467 void AliTPCCorrectionFit::MakeDistortionMapCosmic(THnSparse * hisInput, TTreeSRedirector * const pcstream, const char* hname, Int_t run, Float_t refX, Int_t type){
469 // make a distortion map out ou fthe residual histogram
470 // Results are written to the debug streamer - pcstream
472 // his0 - input (4D) residual histogram
473 // pcstream - file to write the tree
475 // refX - track matching reference X
476 // type - 0- y 1-z,2 -snp, 3-theta, 4=1/pt
477 // marian.ivanov@cern.ch
480 // Collection name='TObjArray', class='TObjArray', size=16
481 // 0. OBJ: TAxis #Delta #Delta
482 // 1. OBJ: TAxis N_{cl} N_{cl}
483 // 2. OBJ: TAxis dca_{r} (cm) dca_{r} (cm)
484 // 3. OBJ: TAxis z (cm) z (cm)
485 // 4. OBJ: TAxis sin(#phi) sin(#phi)
486 // 5. OBJ: TAxis tan(#theta) tan(#theta)
487 // 6. OBJ: TAxis 1/pt (1/GeV) 1/pt (1/GeV)
488 // 7. OBJ: TAxis pt (GeV) pt (GeV)
489 // 8. OBJ: TAxis alpha alpha
490 const Int_t kMinEntries=10;
492 // 1. make default selections
495 Int_t idim0[4]={0 , 5, 8, 3}; // delta, theta, alpha, z
496 hisInput->GetAxis(1)->SetRangeUser(110,190); //long tracks
497 hisInput->GetAxis(2)->SetRangeUser(-10,35); //tracks close to beam pipe
498 hisInput->GetAxis(4)->SetRangeUser(-0.3,0.3); //small snp at TPC entrance
499 hisInput->GetAxis(7)->SetRangeUser(3,100); //"high pt tracks"
500 hisDelta= hisInput->Projection(0);
501 hisInput->GetAxis(0)->SetRangeUser(-6.*hisDelta->GetRMS(), +6.*hisDelta->GetRMS());
503 THnSparse *his0= hisInput->Projection(4,idim0);
505 // 2. Get mean in diferent bins
507 Int_t nbins1=his0->GetAxis(1)->GetNbins();
508 Int_t first1=his0->GetAxis(1)->GetFirst();
509 Int_t last1 =his0->GetAxis(1)->GetLast();
511 Double_t bz=AliTrackerBase::GetBz();
512 Int_t idim[4]={0,1, 2, 3}; // delta, theta,alpha,z
514 for (Int_t ibin1=first1; ibin1<=last1; ibin1++){ //axis 1 - theta
516 Double_t x1= his0->GetAxis(1)->GetBinCenter(ibin1);
517 his0->GetAxis(1)->SetRange(TMath::Max(ibin1-1,1),TMath::Min(ibin1+1,nbins1));
519 THnSparse * his1 = his0->Projection(4,idim); // projected histogram according range1
520 Int_t nbins3 = his1->GetAxis(3)->GetNbins();
521 Int_t first3 = his1->GetAxis(3)->GetFirst();
522 Int_t last3 = his1->GetAxis(3)->GetLast();
524 for (Int_t ibin3=first3-1; ibin3<=last3; ibin3+=1){ // axis 3 - z at "vertex"
525 his1->GetAxis(3)->SetRange(TMath::Max(ibin3-1,1),TMath::Min(ibin3+1,nbins3));
526 Double_t x3= his1->GetAxis(3)->GetBinCenter(ibin3);
528 his1->GetAxis(3)->SetRangeUser(-1,1);
531 THnSparse * his3= his1->Projection(4,idim); //projected histogram according selection 3
532 Int_t nbins2 = his3->GetAxis(2)->GetNbins();
533 Int_t first2 = his3->GetAxis(2)->GetFirst();
534 Int_t last2 = his3->GetAxis(2)->GetLast();
536 for (Int_t ibin2=first2; ibin2<=last2; ibin2+=1){
537 his3->GetAxis(2)->SetRange(TMath::Max(ibin2-1,1),TMath::Min(ibin2+1,nbins2));
538 Double_t x2= his3->GetAxis(2)->GetBinCenter(ibin2);
539 hisDelta = his3->Projection(0);
541 Double_t entries = hisDelta->GetEntries();
542 Double_t mean=0, rms=0;
543 if (entries>kMinEntries){
544 mean = hisDelta->GetMean();
545 rms = hisDelta->GetRMS();
547 Double_t sector = 9.*x2/TMath::Pi();
548 if (sector<0) sector+=18;
549 Double_t dsec = sector-Int_t(sector)-0.5;
550 Double_t snp=0; // dummy snp - equal 0
553 "bz="<<bz<< // magnetic field
554 "theta="<<x1<< // theta
555 "phi="<<x2<< // phi (alpha)
556 "z="<<x3<< // z at "vertex"
557 "snp="<<snp<< // dummy snp
558 "entries="<<entries<< // entries in bin
559 "mean="<<mean<< // mean
561 "refX="<<refX<< // track matching refernce plane
562 "type="<<type<< // parameter type
563 "sector="<<sector<< // sector
564 "dsec="<<dsec<< // dummy delta sector
567 printf("%f\t%f\t%f\t%f\t%f\n",x1,x3,x2, entries,mean);
578 void AliTPCCorrectionFit::MakeDistortionMapSector(THnSparse * hisInput, TTreeSRedirector * const pcstream, const char* hname, Int_t run, Int_t type, Double_t bz){
580 // make a distortion map out of the residual histogram
581 // Results are written to the debug streamer - pcstream
583 // his0 - input (4D) residual histogram
584 // pcstream - file to write the tree
586 // type - 0- y 1-z,2 -snp, 3-theta
587 // bz - magnetic field
588 // marian.ivanov@cern.ch
590 //Collection name='TObjArray', class='TObjArray', size=16
591 //0 OBJ: TAxis delta delta
592 //1 OBJ: TAxis phi phi
593 //2 OBJ: TAxis localX localX
596 //5 OBJ: TAxis is1 is1
597 //6 OBJ: TAxis is0 is0
599 //8. OBJ: TAxis IsPrimary IsPrimary
601 const Int_t kMinEntries=10;
602 THnSparse * hisSector0=0;
603 TH1 * htemp=0; // histogram to calculate mean value of parameter
604 // Double_t bz=AliTrackerBase::GetBz();
607 // Loop over pair of sector:
618 for (Int_t isec0=0; isec0<72; isec0++){
619 Int_t index0[9]={0, 4, 3, 7, 1, 2, 5, 6,8}; //regroup indeces
621 //hisInput->GetAxis(8)->SetRangeUser(-0.1,0.4); // select secondaries only ? - get out later ?
622 hisInput->GetAxis(6)->SetRangeUser(isec0-0.1,isec0+0.1);
623 hisSector0=hisInput->Projection(7,index0);
626 for (Int_t isec1=isec0+1; isec1<72; isec1++){
627 //if (isec1!=isec0+36) continue;
628 if ( TMath::Abs((isec0%18)-(isec1%18))>1.5 && TMath::Abs((isec0%18)-(isec1%18))<16.5) continue;
629 printf("Sectors %d\t%d\n",isec1,isec0);
630 hisSector0->GetAxis(6)->SetRangeUser(isec1-0.1,isec1+0.1);
631 TH1 * hisX=hisSector0->Projection(5);
632 Double_t refX= hisX->GetMean();
634 TH1 *hisDelta=hisSector0->Projection(0);
635 Double_t dmean = hisDelta->GetMean();
636 Double_t drms = hisDelta->GetRMS();
637 hisSector0->GetAxis(0)->SetRangeUser(dmean-5.*drms, dmean+5.*drms);
640 // 1. make default selections
642 Int_t idim0[5]={0 , 1, 2, 3, 4}; // {delta, theta, snp, z, phi }
643 THnBase *hisSector1= hisSector0->ProjectionND(5,idim0);
645 // 2. Get mean in diferent bins
647 Int_t idim[5]={0, 1, 2, 3, 4}; // {delta, theta-1,snp-2 ,z-3, phi-4}
649 // Int_t nbinsPhi=hisSector1->GetAxis(4)->GetNbins();
650 Int_t firstPhi=hisSector1->GetAxis(4)->GetFirst();
651 Int_t lastPhi =hisSector1->GetAxis(4)->GetLast();
653 for (Int_t ibinPhi=firstPhi; ibinPhi<=lastPhi; ibinPhi+=2){ //axis 4 - phi
657 Double_t xPhi= hisSector1->GetAxis(4)->GetBinCenter(ibinPhi);
658 Double_t psec = (9*xPhi/TMath::Pi());
659 if (psec<0) psec+=18;
662 if (TMath::Abs(psec-isec0%18-0.5)<1. || TMath::Abs(psec-isec0%18-17.5)<1.) isOK0=kTRUE;
663 if (TMath::Abs(psec-isec1%18-0.5)<1. || TMath::Abs(psec-isec1%18-17.5)<1.) isOK1=kTRUE;
664 if (!isOK0) continue;
665 if (!isOK1) continue;
667 hisSector1->GetAxis(4)->SetRange(TMath::Max(ibinPhi-2,firstPhi),TMath::Min(ibinPhi+2,lastPhi));
668 if (isec1!=isec0+36) {
669 hisSector1->GetAxis(4)->SetRange(TMath::Max(ibinPhi-3,firstPhi),TMath::Min(ibinPhi+3,lastPhi));
672 htemp = hisSector1->Projection(4);
673 xPhi=htemp->GetMean();
675 THnBase * hisPhi = hisSector1->ProjectionND(4,idim);
676 //Int_t nbinsZ = hisPhi->GetAxis(3)->GetNbins();
677 Int_t firstZ = hisPhi->GetAxis(3)->GetFirst();
678 Int_t lastZ = hisPhi->GetAxis(3)->GetLast();
680 for (Int_t ibinZ=firstZ; ibinZ<=lastZ; ibinZ+=2){ // axis 3 - z
684 hisPhi->GetAxis(3)->SetRange(TMath::Max(ibinZ,firstZ),TMath::Min(ibinZ,lastZ));
685 if (isec1!=isec0+36) {
686 hisPhi->GetAxis(3)->SetRange(TMath::Max(ibinZ-1,firstZ),TMath::Min(ibinZ-1,lastZ));
688 htemp = hisPhi->Projection(3);
689 Double_t xZ= htemp->GetMean();
691 THnBase * hisZ= hisPhi->ProjectionND(3,idim);
692 //projected histogram according selection 3 -z
695 //Int_t nbinsSnp = hisZ->GetAxis(2)->GetNbins();
696 Int_t firstSnp = hisZ->GetAxis(2)->GetFirst();
697 Int_t lastSnp = hisZ->GetAxis(2)->GetLast();
698 for (Int_t ibinSnp=firstSnp; ibinSnp<=lastSnp; ibinSnp+=2){ // axis 2 - snp
702 hisZ->GetAxis(2)->SetRange(TMath::Max(ibinSnp-1,firstSnp),TMath::Min(ibinSnp+1,lastSnp));
703 if (isec1!=isec0+36) {
704 hisZ->GetAxis(2)->SetRange(TMath::Max(ibinSnp-2,firstSnp),TMath::Min(ibinSnp+2,lastSnp));
706 htemp = hisZ->Projection(2);
707 Double_t xSnp= htemp->GetMean();
709 THnBase * hisSnp= hisZ->ProjectionND(2,idim);
710 //projected histogram according selection 2 - snp
712 //Int_t nbinsTheta = hisSnp->GetAxis(1)->GetNbins();
713 Int_t firstTheta = hisSnp->GetAxis(1)->GetFirst();
714 Int_t lastTheta = hisSnp->GetAxis(1)->GetLast();
716 for (Int_t ibinTheta=firstTheta; ibinTheta<=lastTheta; ibinTheta+=2){ // axis1 theta
719 hisSnp->GetAxis(1)->SetRange(TMath::Max(ibinTheta-2,firstTheta),TMath::Min(ibinTheta+2,lastTheta));
720 if (isec1!=isec0+36) {
721 hisSnp->GetAxis(1)->SetRange(TMath::Max(ibinTheta-3,firstTheta),TMath::Min(ibinTheta+3,lastTheta));
723 htemp = hisSnp->Projection(1);
724 Double_t xTheta=htemp->GetMean();
726 hisDelta = hisSnp->Projection(0);
728 Double_t entries = hisDelta->GetEntries();
729 Double_t mean=0, rms=0;
730 if (entries>kMinEntries){
731 mean = hisDelta->GetMean();
732 rms = hisDelta->GetRMS();
734 Double_t sector = 9.*xPhi/TMath::Pi();
735 if (sector<0) sector+=18;
736 Double_t dsec = sector-Int_t(sector)-0.5;
737 Int_t dtype=1; // TPC alignment type
740 "bz="<<bz<< // magnetic field
741 "ptype="<<type<< // parameter type
742 "dtype="<<dtype<< // parameter type
743 "isec0="<<isec0<< // sector 0
744 "isec1="<<isec1<< // sector 1
745 "sector="<<sector<< // sector as float
746 "dsec="<<dsec<< // delta sector
748 "theta="<<xTheta<< // theta
749 "phi="<<xPhi<< // phi (alpha)
751 "snp="<<xSnp<< // snp
754 "entries="<<entries<< // entries in bin
755 "mean="<<mean<< // mean
757 "refX="<<refX<< // track matching reference plane
760 //printf("%d\t%d\t%f\t%f\t%f\t%f\t%f\t%f\n",isec0, isec1, xPhi,xZ,xSnp, xTheta, entries,mean);
779 // void AliTPCCorrectionFit::MakeLaserDistortionTree(TTree* tree, TObjArray */*corrArray*/, Int_t /*itype*/){
781 // // Make a laser fit tree for global minimization
783 // AliTPCcalibDB* calib=AliTPCcalibDB::Instance();
784 // AliTPCCorrection * correction = calib->GetTPCComposedCorrection();
785 // if (!correction) correction = calib->GetTPCComposedCorrection(AliTrackerBase::GetBz());
786 // correction->AddVisualCorrection(correction,0); //register correction
788 // // AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
789 // //AliTPCParam *param = AliTPCcalibDB::Instance()->GetParameters();
791 // const Double_t cutErrY=0.05;
792 // const Double_t kSigmaCut=4;
793 // // const Double_t cutErrZ=0.03;
794 // const Double_t kEpsilon=0.00000001;
795 // // const Double_t kMaxDist=1.; // max distance - space correction
796 // TVectorD *vecdY=0;
797 // TVectorD *vecdZ=0;
798 // TVectorD *veceY=0;
799 // TVectorD *veceZ=0;
800 // AliTPCLaserTrack *ltr=0;
801 // AliTPCLaserTrack::LoadTracks();
802 // tree->SetBranchAddress("dY.",&vecdY);
803 // tree->SetBranchAddress("dZ.",&vecdZ);
804 // tree->SetBranchAddress("eY.",&veceY);
805 // tree->SetBranchAddress("eZ.",&veceZ);
806 // tree->SetBranchAddress("LTr.",<r);
807 // Int_t entries= tree->GetEntries();
808 // TTreeSRedirector *pcstream= new TTreeSRedirector("distortionLaser_0.root");
809 // Double_t bz=AliTrackerBase::GetBz();
811 // // Double_t globalXYZ[3];
812 // //Double_t globalXYZCorr[3];
813 // for (Int_t ientry=0; ientry<entries; ientry++){
814 // tree->GetEntry(ientry);
815 // if (!ltr->GetVecGX()){
816 // ltr->UpdatePoints();
819 // TVectorD fit10(5);
821 // printf("Entry\t%d\n",ientry);
822 // for (Int_t irow0=0; irow0<158; irow0+=1){
824 // TLinearFitter fitter10(4,"hyp3");
825 // TLinearFitter fitter5(2,"hyp1");
826 // Int_t sector= (Int_t)(*ltr->GetVecSec())[irow0];
827 // if (sector<0) continue;
828 // //if (TMath::Abs(vecdY->GetMatrixArray()[irow0])<kEpsilon) continue;
830 // Double_t refX= (*ltr->GetVecLX())[irow0];
831 // Int_t firstRow1 = TMath::Max(irow0-10,0);
832 // Int_t lastRow1 = TMath::Min(irow0+10,158);
833 // Double_t padWidth=(irow0<64)?0.4:0.6;
834 // // make long range fit
835 // for (Int_t irow1=firstRow1; irow1<=lastRow1; irow1++){
836 // if (TMath::Abs((*ltr->GetVecSec())[irow1]-sector)>kEpsilon) continue;
837 // if (veceY->GetMatrixArray()[irow1]>cutErrY) continue;
838 // if (TMath::Abs(vecdY->GetMatrixArray()[irow1])<kEpsilon) continue;
839 // Double_t idealX= (*ltr->GetVecLX())[irow1];
840 // Double_t idealY= (*ltr->GetVecLY())[irow1];
841 // // Double_t idealZ= (*ltr->GetVecLZ())[irow1];
842 // Double_t gx= (*ltr->GetVecGX())[irow1];
843 // Double_t gy= (*ltr->GetVecGY())[irow1];
844 // Double_t gz= (*ltr->GetVecGZ())[irow1];
845 // Double_t measY=(*vecdY)[irow1]+idealY;
846 // Double_t deltaR = GetCorrXYZ(gx, gy, gz, 0,0);
847 // // deltaR = R distorted -R ideal
848 // Double_t xxx[4]={idealX+deltaR-refX,TMath::Cos(idealY/padWidth), TMath::Sin(idealY/padWidth)};
849 // fitter10.AddPoint(xxx,measY,1);
851 // Bool_t isOK=kTRUE;
852 // Double_t rms10=0;//TMath::Sqrt(fitter10.GetChisquare()/(fitter10.GetNpoints()-4));
853 // Double_t mean10 =0;// fitter10.GetParameter(0);
854 // Double_t slope10 =0;// fitter10.GetParameter(0);
855 // Double_t cosPart10 = 0;// fitter10.GetParameter(2);
856 // Double_t sinPart10 =0;// fitter10.GetParameter(3);
858 // if (fitter10.GetNpoints()>10){
860 // rms10=TMath::Sqrt(fitter10.GetChisquare()/(fitter10.GetNpoints()-4));
861 // mean10 = fitter10.GetParameter(0);
862 // slope10 = fitter10.GetParameter(1);
863 // cosPart10 = fitter10.GetParameter(2);
864 // sinPart10 = fitter10.GetParameter(3);
866 // // make short range fit
868 // for (Int_t irow1=firstRow1+5; irow1<=lastRow1-5; irow1++){
869 // if (TMath::Abs((*ltr->GetVecSec())[irow1]-sector)>kEpsilon) continue;
870 // if (veceY->GetMatrixArray()[irow1]>cutErrY) continue;
871 // if (TMath::Abs(vecdY->GetMatrixArray()[irow1])<kEpsilon) continue;
872 // Double_t idealX= (*ltr->GetVecLX())[irow1];
873 // Double_t idealY= (*ltr->GetVecLY())[irow1];
874 // // Double_t idealZ= (*ltr->GetVecLZ())[irow1];
875 // Double_t gx= (*ltr->GetVecGX())[irow1];
876 // Double_t gy= (*ltr->GetVecGY())[irow1];
877 // Double_t gz= (*ltr->GetVecGZ())[irow1];
878 // Double_t measY=(*vecdY)[irow1]+idealY;
879 // Double_t deltaR = GetCorrXYZ(gx, gy, gz, 0,0);
880 // // deltaR = R distorted -R ideal
881 // Double_t expY= mean10+slope10*(idealX+deltaR-refX);
882 // if (TMath::Abs(measY-expY)>kSigmaCut*rms10) continue;
884 // Double_t corr=cosPart10*TMath::Cos(idealY/padWidth)+sinPart10*TMath::Sin(idealY/padWidth);
885 // Double_t xxx[4]={idealX+deltaR-refX,TMath::Cos(idealY/padWidth), TMath::Sin(idealY/padWidth)};
886 // fitter5.AddPoint(xxx,measY-corr,1);
891 // if (fitter5.GetNpoints()<8) isOK=kFALSE;
893 // Double_t rms5=0;//TMath::Sqrt(fitter5.GetChisquare()/(fitter5.GetNpoints()-4));
894 // Double_t offset5 =0;// fitter5.GetParameter(0);
895 // Double_t slope5 =0;// fitter5.GetParameter(0);
898 // rms5=TMath::Sqrt(fitter5.GetChisquare()/(fitter5.GetNpoints()-4));
899 // offset5 = fitter5.GetParameter(0);
900 // slope5 = fitter5.GetParameter(0);
905 // Double_t phi =(*ltr->GetVecPhi())[irow0];
906 // Double_t theta =ltr->GetTgl();
907 // Double_t mean=(vecdY)->GetMatrixArray()[irow0];
908 // Double_t gx=0,gy=0,gz=0;
909 // Double_t snp = (*ltr->GetVecP2())[irow0];
910 // Int_t bundle= ltr->GetBundle();
911 // Int_t id= ltr->GetId();
912 // // Double_t rms = err->GetMatrixArray()[irow];
914 // gx = (*ltr->GetVecGX())[irow0];
915 // gy = (*ltr->GetVecGY())[irow0];
916 // gz = (*ltr->GetVecGZ())[irow0];
917 // Double_t dRrec = GetCorrXYZ(gx, gy, gz, 0,0);
918 // fitter10.GetParameters(fit10);
919 // fitter5.GetParameters(fit5);
920 // Double_t idealY= (*ltr->GetVecLY())[irow0];
921 // Double_t measY=(*vecdY)[irow0]+idealY;
922 // Double_t corr=cosPart10*TMath::Cos(idealY/padWidth)+sinPart10*TMath::Sin(idealY/padWidth);
923 // if (TMath::Max(rms5,rms10)>0.06) isOK=kFALSE;
925 // (*pcstream)<<"fitFull"<< // dumpe also intermediate results
926 // "bz="<<bz<< // magnetic filed used
927 // "dtype="<<dtype<< // detector match type
928 // "ptype="<<ptype<< // parameter type
929 // "theta="<<theta<< // theta
930 // "phi="<<phi<< // phi
931 // "snp="<<snp<< // snp
932 // "sector="<<sector<<
933 // "bundle="<<bundle<<
934 // // // "dsec="<<dsec<<
935 // "refX="<<refX<< // reference radius
936 // "gx="<<gx<< // global position
937 // "gy="<<gy<< // global position
938 // "gz="<<gz<< // global position
939 // "dRrec="<<dRrec<< // delta Radius in reconstruction
940 // "id="<<id<< //bundle
943 // "fit10.="<<&fit10<<
947 // "idealY="<<idealY<<
957 void AliTPCCorrectionFit::MakeTrackDistortionTree(TTree *tinput, Int_t dtype, Int_t ptype, const TObjArray * corrArray, Int_t step, Int_t offset, Bool_t debug ){
960 // For each partial correction (specified in array) and given track topology (phi, theta, snp, refX)
961 // calculates partial distortions
962 // Partial distortion is stored in the resulting tree
963 // Output is storred in the file distortion_<dettype>_<partype>.root
964 // Partial distortion is stored with the name given by correction name
967 // Parameters of function:
968 // input - input tree
969 // dtype - distortion type 0 - ITSTPC, 1 -TPCTRD, 2 - TPCvertex , 3 - TPC-TOF, 4 - TPCTPC track crossing
970 // ppype - parameter type
971 // corrArray - array with partial corrections
972 // step - skipe entries - if 1 all entries processed - it is slow
973 // debug 0 if debug on also space points dumped - it is slow
975 const Double_t kMaxSnp = 0.85;
976 const Double_t kcutSnp=0.25;
977 const Double_t kcutTheta=1.;
978 const Double_t kRadiusTPC=85;
979 // AliTPCROC *tpcRoc =AliTPCROC::Instance();
981 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
982 // const Double_t kB2C=-0.299792458e-3;
983 const Int_t kMinEntries=20;
984 Double_t phi,theta, snp, mean,rms, entries,sector,dsec;
987 tinput->SetBranchAddress("run",&run);
988 tinput->SetBranchAddress("theta",&theta);
989 tinput->SetBranchAddress("phi", &phi);
990 tinput->SetBranchAddress("snp",&snp);
991 tinput->SetBranchAddress("mean",&mean);
992 tinput->SetBranchAddress("rms",&rms);
993 tinput->SetBranchAddress("entries",&entries);
994 tinput->SetBranchAddress("sector",§or);
995 tinput->SetBranchAddress("dsec",&dsec);
996 tinput->SetBranchAddress("refX",&refX);
997 TTreeSRedirector *pcstream = new TTreeSRedirector(Form("distortion%d_%d_%d.root",dtype,ptype,offset));
999 Int_t nentries=tinput->GetEntries();
1000 Int_t ncorr=corrArray->GetEntries();
1001 Double_t corrections[100]={0}; //
1003 Double_t cov[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1005 if (dtype==5 || dtype==6) dtype=4;
1006 if (dtype==0) { dir=-1;}
1007 if (dtype==1) { dir=1;}
1008 if (dtype==2) { dir=-1;}
1009 if (dtype==3) { dir=1;}
1010 if (dtype==4) { dir=-1;}
1012 for (Int_t ientry=offset; ientry<nentries; ientry+=step){
1013 tinput->GetEntry(ientry);
1014 if (TMath::Abs(snp)>kMaxSnp) continue;
1017 if (dtype==2) tPar[1]=theta*kRadiusTPC;
1020 tPar[4]=(gRandom->Rndm()-0.5)*0.02; // should be calculated - non equal to 0
1022 // tracks crossing CE
1023 tPar[1]=0; // track at the CE
1024 //if (TMath::Abs(theta) <0.05) continue; // deep cross
1027 if (TMath::Abs(snp) >kcutSnp) continue;
1028 if (TMath::Abs(theta) >kcutTheta) continue;
1029 printf("%f\t%f\t%f\t%f\t%f\t%f\n",entries, sector,theta,snp, mean,rms);
1030 Double_t bz=AliTrackerBase::GetBz();
1031 if (dtype !=4) { //exclude TPC - for TPC mainly non primary tracks
1032 if (dtype!=2 && TMath::Abs(bz)>0.1 ) tPar[4]=snp/(refX*bz*kB2C*2);
1034 if (dtype==2 && TMath::Abs(bz)>0.1 ) {
1035 tPar[4]=snp/(kRadiusTPC*bz*kB2C*2);//
1036 // snp at the TPC inner radius in case the vertex match used
1040 tPar[4]+=(gRandom->Rndm()-0.5)*0.02;
1041 AliExternalTrackParam track(refX,phi,tPar,cov);
1045 Double_t pt=1./tPar[4];
1046 Double_t dRrec=0; // dummy value - needed for points - e.g for laser
1047 //if (ptype==4 &&bz<0) mean*=-1; // interpret as curvature -- COMMENTED out - in lookup signed 1/pt used
1048 Double_t refXD=refX;
1049 (*pcstream)<<"fit"<<
1050 "run="<<run<< // run number
1051 "bz="<<bz<< // magnetic filed used
1052 "dtype="<<dtype<< // detector match type
1053 "ptype="<<ptype<< // parameter type
1054 "theta="<<theta<< // theta
1055 "phi="<<phi<< // phi
1056 "snp="<<snp<< // snp
1057 "mean="<<mean<< // mean dist value
1058 "rms="<<rms<< // rms
1061 "refX="<<refXD<< // referece X as double
1062 "gx="<<xyz[0]<< // global position at reference
1063 "gy="<<xyz[1]<< // global position at reference
1064 "gz="<<xyz[2]<< // global position at reference
1065 "dRrec="<<dRrec<< // delta Radius in reconstruction
1067 "id="<<id<< // track id
1068 "entries="<<entries;// number of entries in bin
1071 if (entries<kMinEntries) isOK=kFALSE;
1073 if (dtype!=4) for (Int_t icorr=0; icorr<ncorr; icorr++) {
1074 AliTPCCorrection *corr = (AliTPCCorrection*)corrArray->At(icorr);
1075 corrections[icorr]=0;
1076 if (entries>kMinEntries){
1077 AliExternalTrackParam trackIn(refX,phi,tPar,cov);
1078 AliExternalTrackParam *trackOut = 0;
1079 if (debug) trackOut=corr->FitDistortedTrack(trackIn, refX, dir,pcstream);
1080 if (!debug) trackOut=corr->FitDistortedTrack(trackIn, refX, dir,0);
1081 if (dtype==0) {dir= -1;}
1082 if (dtype==1) {dir= 1;}
1083 if (dtype==2) {dir= -1;}
1084 if (dtype==3) {dir= 1;}
1087 if (!AliTrackerBase::PropagateTrackTo(&trackIn,refX,kMass,5,kTRUE,kMaxSnp)) isOK=kFALSE;
1088 if (!trackOut->Rotate(trackIn.GetAlpha())) isOK=kFALSE;
1089 if (!AliTrackerBase::PropagateTrackTo(trackOut,trackIn.GetX(),kMass,5,kFALSE,kMaxSnp)) isOK=kFALSE;
1090 // trackOut->PropagateTo(trackIn.GetX(),AliTrackerBase::GetBz());
1092 corrections[icorr]= trackOut->GetParameter()[ptype]-trackIn.GetParameter()[ptype];
1095 corrections[icorr]=0;
1098 //if (ptype==4 &&bz<0) corrections[icorr]*=-1; // interpret as curvature - commented out
1100 (*pcstream)<<"fit"<<
1101 Form("%s=",corr->GetName())<<corrections[icorr]; // dump correction value
1104 if (dtype==4) for (Int_t icorr=0; icorr<ncorr; icorr++) {
1106 // special case of the TPC tracks crossing the CE
1108 AliTPCCorrection *corr = (AliTPCCorrection*)corrArray->At(icorr);
1109 corrections[icorr]=0;
1110 if (entries>kMinEntries){
1111 AliExternalTrackParam trackIn0(refX,phi,tPar,cov); //Outer - direction to vertex
1112 AliExternalTrackParam trackIn1(refX,phi,tPar,cov); //Inner - direction magnet
1113 AliExternalTrackParam *trackOut0 = 0;
1114 AliExternalTrackParam *trackOut1 = 0;
1116 if (debug) trackOut0=corr->FitDistortedTrack(trackIn0, refX, dir,pcstream);
1117 if (!debug) trackOut0=corr->FitDistortedTrack(trackIn0, refX, dir,0);
1118 if (debug) trackOut1=corr->FitDistortedTrack(trackIn1, refX, -dir,pcstream);
1119 if (!debug) trackOut1=corr->FitDistortedTrack(trackIn1, refX, -dir,0);
1121 if (trackOut0 && trackOut1){
1122 if (!AliTrackerBase::PropagateTrackTo(&trackIn0,refX,kMass,5,kTRUE,kMaxSnp)) isOK=kFALSE;
1123 if (!AliTrackerBase::PropagateTrackTo(&trackIn0,refX,kMass,1,kFALSE,kMaxSnp)) isOK=kFALSE;
1124 if (!trackOut0->Rotate(trackIn0.GetAlpha())) isOK=kFALSE;
1125 if (!AliTrackerBase::PropagateTrackTo(trackOut0,trackIn0.GetX(),kMass,5,kFALSE,kMaxSnp)) isOK=kFALSE;
1127 if (!AliTrackerBase::PropagateTrackTo(&trackIn1,refX,kMass,5,kTRUE,kMaxSnp)) isOK=kFALSE;
1128 if (!trackIn1.Rotate(trackIn0.GetAlpha())) isOK=kFALSE;
1129 if (!AliTrackerBase::PropagateTrackTo(&trackIn1,trackIn0.GetX(),kMass,1,kFALSE,kMaxSnp)) isOK=kFALSE;
1130 if (!trackOut1->Rotate(trackIn1.GetAlpha())) isOK=kFALSE;
1131 if (!AliTrackerBase::PropagateTrackTo(trackOut1,trackIn1.GetX(),kMass,5,kFALSE,kMaxSnp)) isOK=kFALSE;
1133 corrections[icorr] = (trackOut0->GetParameter()[ptype]-trackIn0.GetParameter()[ptype]);
1134 corrections[icorr]-= (trackOut1->GetParameter()[ptype]-trackIn1.GetParameter()[ptype]);
1136 if ((TMath::Abs(trackOut0->GetX()-trackOut1->GetX())>0.1)||
1137 (TMath::Abs(trackOut0->GetX()-trackIn1.GetX())>0.1)||
1138 (TMath::Abs(trackOut0->GetAlpha()-trackOut1->GetAlpha())>0.00001)||
1139 (TMath::Abs(trackOut0->GetAlpha()-trackIn1.GetAlpha())>0.00001)||
1140 (TMath::Abs(trackIn0.GetTgl()-trackIn1.GetTgl())>0.0001)||
1141 (TMath::Abs(trackIn0.GetSnp()-trackIn1.GetSnp())>0.0001)
1148 corrections[icorr]=0;
1152 //if (ptype==4 &&bz<0) corrections[icorr]*=-1; // interpret as curvature - commented out no in lookup
1154 (*pcstream)<<"fit"<<
1155 Form("%s=",corr->GetName())<<corrections[icorr]; // dump correction value
1158 (*pcstream)<<"fit"<<"isOK="<<isOK<<"\n";
1167 void AliTPCCorrectionFit::MakeSectorDistortionTree(TTree *tinput, Int_t dtype, Int_t ptype, const TObjArray * corrArray, Int_t step, Int_t offset, Bool_t debug ){
1170 // For each partial correction (specified in array) and given track topology (phi, theta, snp, refX)
1171 // calculates partial distortions
1172 // Partial distortion is stored in the resulting tree
1173 // Output is storred in the file distortion_<dettype>_<partype>.root
1174 // Partial distortion is stored with the name given by correction name
1177 // Parameters of function:
1178 // input - input tree
1179 // dtype - distortion type 10 - IROC-OROC
1180 // ppype - parameter type
1181 // corrArray - array with partial corrections
1182 // step - skipe entries - if 1 all entries processed - it is slow
1183 // debug 0 if debug on also space points dumped - it is slow
1185 const Double_t kMaxSnp = 0.8;
1186 const Int_t kMinEntries=200;
1187 // AliTPCROC *tpcRoc =AliTPCROC::Instance();
1189 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
1190 // const Double_t kB2C=-0.299792458e-3;
1191 Double_t phi,theta, snp, mean,rms, entries,sector,dsec,globalZ;
1196 tinput->SetBranchAddress("run",&run);
1197 tinput->SetBranchAddress("theta",&theta);
1198 tinput->SetBranchAddress("phi", &phi);
1199 tinput->SetBranchAddress("snp",&snp);
1200 tinput->SetBranchAddress("mean",&mean);
1201 tinput->SetBranchAddress("rms",&rms);
1202 tinput->SetBranchAddress("entries",&entries);
1203 tinput->SetBranchAddress("sector",§or);
1204 tinput->SetBranchAddress("dsec",&dsec);
1205 tinput->SetBranchAddress("refX",&refXD);
1206 tinput->SetBranchAddress("z",&globalZ);
1207 tinput->SetBranchAddress("isec0",&isec0);
1208 tinput->SetBranchAddress("isec1",&isec1);
1209 TTreeSRedirector *pcstream = new TTreeSRedirector(Form("distortionSector%d_%d_%d.root",dtype,ptype,offset));
1211 Int_t nentries=tinput->GetEntries();
1212 Int_t ncorr=corrArray->GetEntries();
1213 Double_t corrections[100]={0}; //
1215 Double_t cov[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1218 for (Int_t ientry=offset; ientry<nentries; ientry+=step){
1219 tinput->GetEntry(ientry);
1222 if (TMath::Abs(TMath::Abs(isec0%18)-TMath::Abs(isec1%18))==0) id=1; // IROC-OROC - opposite side
1223 if (TMath::Abs(TMath::Abs(isec0%36)-TMath::Abs(isec1%36))==0) id=2; // IROC-OROC - same side
1224 if (dtype==10 && id==-1) continue;
1231 tPar[4]=(gRandom->Rndm()-0.1)*0.2; //
1232 Double_t pt=1./tPar[4];
1234 printf("%f\t%f\t%f\t%f\t%f\t%f\n",entries, sector,theta,snp, mean,rms);
1235 Double_t bz=AliTrackerBase::GetBz();
1236 AliExternalTrackParam track(refX,phi,tPar,cov);
1237 Double_t xyz[3],xyzIn[3],xyzOut[3];
1239 track.GetXYZAt(85,bz,xyzIn);
1240 track.GetXYZAt(245,bz,xyzOut);
1241 Double_t phiIn = TMath::ATan2(xyzIn[1],xyzIn[0]);
1242 Double_t phiOut = TMath::ATan2(xyzOut[1],xyzOut[0]);
1243 Double_t phiRef = TMath::ATan2(xyz[1],xyz[0]);
1244 Int_t sectorRef = TMath::Nint(9.*phiRef/TMath::Pi()-0.5);
1245 Int_t sectorIn = TMath::Nint(9.*phiIn/TMath::Pi()-0.5);
1246 Int_t sectorOut = TMath::Nint(9.*phiOut/TMath::Pi()-0.5);
1249 if (sectorIn!=sectorOut) isOK=kFALSE; // requironment - cluster in the same sector
1250 if (sectorIn!=sectorRef) isOK=kFALSE; // requironment - cluster in the same sector
1251 if (entries<kMinEntries/(1+TMath::Abs(globalZ/100.))) isOK=kFALSE; // requironment - minimal amount of tracks in bin
1253 if (TMath::Abs(theta)>1) isOK=kFALSE;
1255 Double_t dRrec=0; // dummy value - needed for points - e.g for laser
1257 (*pcstream)<<"fit"<<
1259 "bz="<<bz<< // magnetic filed used
1260 "dtype="<<dtype<< // detector match type
1261 "ptype="<<ptype<< // parameter type
1262 "theta="<<theta<< // theta
1263 "phi="<<phi<< // phi
1264 "snp="<<snp<< // snp
1265 "mean="<<mean<< // mean dist value
1266 "rms="<<rms<< // rms
1269 "refX="<<refXD<< // referece X
1270 "gx="<<xyz[0]<< // global position at reference
1271 "gy="<<xyz[1]<< // global position at reference
1272 "gz="<<xyz[2]<< // global position at reference
1273 "dRrec="<<dRrec<< // delta Radius in reconstruction
1275 "id="<<id<< // track id
1276 "entries="<<entries;// number of entries in bin
1278 AliExternalTrackParam *trackOut0 = 0;
1279 AliExternalTrackParam *trackOut1 = 0;
1280 AliExternalTrackParam *ptrackIn0 = 0;
1281 AliExternalTrackParam *ptrackIn1 = 0;
1283 for (Int_t icorr=0; icorr<ncorr; icorr++) {
1285 // special case of the TPC tracks crossing the CE
1287 AliTPCCorrection *corr = (AliTPCCorrection*)corrArray->At(icorr);
1288 corrections[icorr]=0;
1289 if (entries>kMinEntries &&isOK){
1290 AliExternalTrackParam trackIn0(refX,phi,tPar,cov);
1291 AliExternalTrackParam trackIn1(refX,phi,tPar,cov);
1292 ptrackIn1=&trackIn0;
1293 ptrackIn0=&trackIn1;
1295 if (debug) trackOut0=corr->FitDistortedTrack(trackIn0, refX, dir,pcstream);
1296 if (!debug) trackOut0=corr->FitDistortedTrack(trackIn0, refX, dir,0);
1297 if (debug) trackOut1=corr->FitDistortedTrack(trackIn1, refX, -dir,pcstream);
1298 if (!debug) trackOut1=corr->FitDistortedTrack(trackIn1, refX, -dir,0);
1300 if (trackOut0 && trackOut1){
1302 if (!AliTrackerBase::PropagateTrackTo(&trackIn0,refX,kMass,1,kTRUE,kMaxSnp)) isOK=kFALSE;
1303 if (!AliTrackerBase::PropagateTrackTo(&trackIn0,refX,kMass,1,kFALSE,kMaxSnp)) isOK=kFALSE;
1304 // rotate all tracks to the same frame
1305 if (!trackOut0->Rotate(trackIn0.GetAlpha())) isOK=kFALSE;
1306 if (!trackIn1.Rotate(trackIn0.GetAlpha())) isOK=kFALSE;
1307 if (!trackOut1->Rotate(trackIn0.GetAlpha())) isOK=kFALSE;
1309 if (!AliTrackerBase::PropagateTrackTo(trackOut0,refX,kMass,1,kFALSE,kMaxSnp)) isOK=kFALSE;
1310 if (!AliTrackerBase::PropagateTrackTo(&trackIn1,refX,kMass,1,kFALSE,kMaxSnp)) isOK=kFALSE;
1311 if (!AliTrackerBase::PropagateTrackTo(trackOut1,refX,kMass,1,kFALSE,kMaxSnp)) isOK=kFALSE;
1313 corrections[icorr] = (trackOut0->GetParameter()[ptype]-trackIn0.GetParameter()[ptype]);
1314 corrections[icorr]-= (trackOut1->GetParameter()[ptype]-trackIn1.GetParameter()[ptype]);
1315 (*pcstream)<<"fitDebug"<< // just to debug the correction
1317 "pIn0.="<<ptrackIn0<<
1318 "pIn1.="<<ptrackIn1<<
1319 "pOut0.="<<trackOut0<<
1320 "pOut1.="<<trackOut1<<
1326 corrections[icorr]=0;
1330 (*pcstream)<<"fit"<<
1331 Form("%s=",corr->GetName())<<corrections[icorr]; // dump correction value
1334 (*pcstream)<<"fit"<<"isOK="<<isOK<<"\n";