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
28 3. Space point distortion not directly observable. Instead a derived variables
29 like DCA at vertex, local y distortion in the TPC-*TOF,TRD,ITS) matching
30 in all 5 tracking parameters are obsereved.
31 In the AliTPCcorrection fir code we calculate the derivative of given variables
35 d0 = sum{ki*dO_{i}/dp_{i}} - linear fitting of the amplitudes ki
37 Some functions, for the moment function present in the AliTPCPreprocesorOffline, some will be
38 extracted from the old macros
43 #include "Riostream.h"
46 #include "TGraphErrors.h"
47 #include "AliExternalTrackParam.h"
50 #include "TMultiGraph.h"
52 #include "THnSparse.h"
60 #include "AliTPCROC.h"
61 #include "AliTPCCalROC.h"
62 #include "AliESDfriend.h"
63 #include "AliTPCcalibTime.h"
64 #include "AliSplineFit.h"
65 #include "AliCDBMetaData.h"
67 #include "AliCDBManager.h"
68 #include "AliCDBStorage.h"
69 #include "AliTPCcalibBase.h"
70 #include "AliTPCcalibDB.h"
71 #include "AliTPCcalibDButil.h"
72 #include "AliRelAlignerKalman.h"
73 #include "AliTPCParamSR.h"
74 #include "AliTPCcalibTimeGain.h"
75 #include "AliTPCcalibGainMult.h"
76 #include "AliSplineFit.h"
77 #include "AliTPCComposedCorrection.h"
78 #include "AliTPCExBTwist.h"
79 #include "AliTPCCalibGlobalMisalignment.h"
80 #include "TStatToolkit.h"
83 #include "AliTrackerBase.h"
84 #include "AliTPCCorrectionFit.h"
85 #include "AliTPCLaserTrack.h"
86 #include "TDatabasePDG.h"
87 #include "AliTPCcalibAlign.h"
89 #include "AliRieman.h"
91 ClassImp(AliTPCCorrectionFit)
93 AliTPCCorrectionFit::AliTPCCorrectionFit():
94 TNamed("TPCCorrectionFit","TPCCorrectionFit")
97 // default constructor
101 AliTPCCorrectionFit::~AliTPCCorrectionFit() {
108 Double_t AliTPCCorrectionFit::EvalAt(Double_t phi, Double_t refX, Double_t theta, Int_t corr, Int_t ptype){
110 // Evalution at point using the lienar approximation
112 Double_t sector = 9*phi/TMath::Pi();
113 if (sector<0) sector+=18;
114 Double_t y85=AliTPCCorrection::GetCorrSector(sector,85,theta,1,corr);
115 Double_t y245=AliTPCCorrection::GetCorrSector(sector,245,theta,1,corr);
116 if (ptype==0) return y85+(y245-y85)*(refX-85.)/(245.-85.);
117 if (ptype==2) return (y245-y85)/(245.-85.);
124 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){
126 // Fit the distortion along the line with the parabolic model
127 // We assume that the track are primaries - where the vertex is at (0,0,0)
130 // phi0 - phi at the entrance of the TPC
131 // snp - local inclination angle at the entrance of the TPC
132 // refX - ref X where the distortion is evanluated
133 // theta - inclination angle
134 // corr - internal number of the correction and distortion
135 // ptype - 0 - local y distortion
136 // //1 - local z distortion
137 // 2 - local derivative distortion
139 // 4 - distortion in the curvature
140 // nsteps - number of fit points
142 // return value - distortion at point refX with type ptype
144 static TLinearFitter fitter(3,"pol2");
145 fitter.ClearPoints();
146 if (nsteps<3) nsteps=3;
147 Double_t deltaX=(245-85)/(nsteps);
148 for (Int_t istep=0; istep<(nsteps+1); istep++){
150 Double_t localX =85.+deltaX*istep;
151 Double_t localPhi=phi0+deltaX*snp*istep;
152 Double_t sector = 9*localPhi/TMath::Pi();
153 if (sector<0) sector+=18;
154 Double_t dy=AliTPCCorrection::GetCorrSector(sector,localX,theta,1,corr);
155 Double_t dlocalX=AliTPCCorrection::GetCorrSector(sector,localX,theta,0,corr);
156 Double_t x[1]={localX-dlocalX};
157 fitter.AddPoint(x,dy);
161 par[0]=fitter.GetParameter(0);
162 par[1]=fitter.GetParameter(1);
163 par[2]=fitter.GetParameter(2);
165 if (ptype==0) return par[0]+par[1]*refX+par[2]*refX*refX;
166 if (ptype==2) return par[1]+2*par[2]*refX;
167 if (ptype==4) return par[2];
172 Double_t AliTPCCorrectionFit::EvalAtHelix(Double_t phi0, Double_t snp, Double_t refX, Double_t theta, Int_t corr, Int_t ptype, Int_t nsteps){
174 // Fit the distortion along the line with the helix model
175 // FIXME - original trajectory to be changed - AliHelix to be used
176 // We assume that the track are primaries - where the vertex is at (0,0,0)
179 // phi0 - phi at the entrance of the TPC
180 // snp - local inclination angle at the entrance of the TPC
181 // refX - ref X where the distortion is evanluated
182 // theta - inclination angle
183 // corr - internal number of the correction and distortion
184 // ptype - 0 - local y distortion
185 // //1 - local z distortion
186 // 2 - local derivative distortion
188 // 4 - distortion in the curvature
189 // nsteps - number of fit points
191 // return value - distortion at point refX with type ptype
193 if (nsteps<3) nsteps=3;
194 Double_t deltaX=(245-85)/(nsteps);
195 AliRieman rieman(nsteps);
197 for (Int_t istep=0; istep<(nsteps+1); istep++){
199 Double_t localX =85.+deltaX*istep;
200 Double_t localPhi=phi0+deltaX*snp*istep;
201 Double_t sector = 9*localPhi/TMath::Pi();
202 if (sector<0) sector+=18;
203 Double_t dy=AliTPCCorrection::GetCorrSector(sector,localX,theta,1,corr);
204 Double_t dlocalX=AliTPCCorrection::GetCorrSector(sector,localX,theta,0,corr);
205 Double_t x[1]={localX-dlocalX};
206 Double_t z=theta*x[0];
207 rieman.AddPoint(x[0],dy,z,0.1,0.1);
212 if (ptype==0) return rieman.GetYat(refX);
213 if (ptype==2) return rieman.GetDYat(refX);
214 if (ptype==4) return rieman.GetC();
221 void AliTPCCorrectionFit::CreateAlignMaps(Double_t bz, Int_t run){
223 // Create cluster distortion map
225 TFile *falign = TFile::Open("CalibObjects.root");
226 TObjArray * arrayAlign = (TObjArray *)falign->Get("TPCAlign");
228 AliWarningGeneral("AliTPCCorrectionFit::CreateAlignMaps","Alignment was not included in the calibration task");
231 AliTPCcalibAlign * align = (AliTPCcalibAlign *)arrayAlign->FindObject("alignTPC");
233 AliWarningGeneral("AliTPCCorrectionFit::CreateAlignMaps","Alignment was not included in the calibration task");
236 TTreeSRedirector * pcstream = new TTreeSRedirector("TPCAlign.root");
238 THnBase * hdY = (THnBase*)align->GetClusterDelta(0);
239 //THnBase * hdZ = (THnBase*)align->GetClusterDelta(1);
240 AliTPCCorrectionFit::MakeClusterDistortionMap(hdY,pcstream,0, bz);
241 // AliTPCCorrectionFit::MakeClusterDistortionMap(hdZ,pcstream,1, bz);
243 const char * hname[5]={"dy","dz","dsnp","dtheta","d1pt"};
244 for (Int_t ihis=0; ihis<4; ihis++){
245 THnSparse * hisAlign =align->GetTrackletDelta(ihis);
246 AliTPCCorrectionFit::MakeDistortionMapSector(hisAlign, pcstream, hname[ihis], run, ihis,bz);
256 void AliTPCCorrectionFit::MakeClusterDistortionMap(THnBase * hisInput,TTreeSRedirector *pcstream , Int_t ptype, Int_t dtype){
258 // Make cluster residual map from the n-dimensional histogram
259 // hisInput supposed to have given format:
265 // Vertex position assumed to be at (0,0,0)
267 //TTreeSRedirector *pcstream=new TTreeSRedirector(sname);
269 Int_t nbins1=hisInput->GetAxis(1)->GetNbins();
270 Int_t nbins2=hisInput->GetAxis(2)->GetNbins();
271 Int_t nbins3=hisInput->GetAxis(3)->GetNbins();
274 new TH3F("his3D","his3D",
275 nbins1,hisInput->GetAxis(1)->GetXmin(), hisInput->GetAxis(1)->GetXmax(),
276 nbins2,hisInput->GetAxis(2)->GetXmin(), hisInput->GetAxis(2)->GetXmax(),
277 nbins3,hisInput->GetAxis(3)->GetXmin(), hisInput->GetAxis(3)->GetXmax());
278 hisResMap3D->GetXaxis()->SetTitle("sector");
279 hisResMap3D->GetYaxis()->SetTitle("localX");
280 hisResMap3D->GetZaxis()->SetTitle("kZ");
282 TH2F * hisResMap2D[4] ={0,0,0,0};
283 for (Int_t i=0; i<4; i++){
285 new TH2F(Form("his2D_0%d",i),Form("his2D_0%d",i),
286 nbins1,hisInput->GetAxis(1)->GetXmin(), hisInput->GetAxis(1)->GetXmax(),
287 nbins2,hisInput->GetAxis(2)->GetXmin(), hisInput->GetAxis(2)->GetXmax());
288 hisResMap2D[i]->GetXaxis()->SetTitle("sector");
289 hisResMap2D[i]->GetYaxis()->SetTitle("localX");
295 Int_t axis0[4]={0,1,2,3};
296 Int_t axis1[4]={0,1,2,3};
298 for (Int_t ibin1=1; ibin1<nbins1; ibin1+=1){
300 hisInput->GetAxis(1)->SetRange(ibin1-1,ibin1+1);
301 THnBase *his1=(THnBase *)hisInput->ProjectionND(4,axis0);
302 Double_t sector=hisInput->GetAxis(1)->GetBinCenter(ibin1);
304 for (Int_t ibin2=1; ibin2<nbins2; ibin2+=1){
307 his1->GetAxis(2)->SetRange(ibin2-1,ibin2+1);
308 THnBase *his2=(THnBase *)his1->ProjectionND(4,axis1);
309 Double_t localX=hisInput->GetAxis(2)->GetBinCenter(ibin2);
312 his2->GetAxis(3)->SetRangeUser(0.01,0.3);
313 TH1 * hisA = his2->Projection(0);
314 Double_t meanA= hisA->GetMean();
315 Double_t rmsA= hisA->GetRMS();
316 Double_t entriesA= hisA->GetEntries();
319 his2->GetAxis(3)->SetRangeUser(0.01,0.3);
320 TH1 * hisC = his2->Projection(0);
321 Double_t meanC= hisC->GetMean();
322 Double_t rmsC= hisC->GetRMS();
323 Double_t entriesC= hisC->GetEntries();
325 his2->GetAxis(3)->SetRangeUser(-1.2,1.2);
326 TH2 * hisAC = his2->Projection(0,3);
327 TProfile *profAC = hisAC->ProfileX();
329 profAC->Fit("pol1","QNR","QNR",0.05,1);
330 if (!f1) f1=(TF1*)gROOT->FindObject("pol1");
331 Double_t offsetA=f1->GetParameter(0);
332 Double_t slopeA=f1->GetParameter(1);
333 Double_t offsetAE=f1->GetParError(0);
334 Double_t slopeAE=f1->GetParError(1);
335 Double_t chi2A=f1->GetChisquare()/f1->GetNumberFreeParameters();
336 profAC->Fit("pol1","QNR","QNR",-1.1,-0.1);
337 f1=(TF1*)gROOT->FindObject("pol1");
338 Double_t offsetC=f1->GetParameter(0);
339 Double_t slopeC=f1->GetParameter(1);
340 Double_t offsetCE=f1->GetParError(0);
341 Double_t slopeCE=f1->GetParError(1);
342 Double_t chi2C=f1->GetChisquare()/f1->GetNumberFreeParameters();
343 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);
345 (*pcstream)<<"deltaFit"<<
350 "entriesA="<<entriesA<<
353 "entriesC="<<entriesC<<
354 "offsetA="<<offsetA<<
356 "offsetAE="<<offsetAE<<
357 "slopeAE="<<slopeAE<<
359 "offsetC="<<offsetC<<
361 "offsetCE="<<offsetCE<<
362 "slopeCE="<<slopeCE<<
366 hisResMap2D[0]->SetBinContent(ibin1,ibin2, offsetA);
367 hisResMap2D[1]->SetBinContent(ibin1,ibin2, slopeA);
368 hisResMap2D[2]->SetBinContent(ibin1,ibin2, offsetC);
369 hisResMap2D[3]->SetBinContent(ibin1,ibin2, slopeC);
371 for (Int_t ibin3=1; ibin3<nbins3; ibin3++){
372 Double_t kZ=hisInput->GetAxis(3)->GetBinCenter(ibin3);
373 if (TMath::Abs(kZ)<0.05) continue; // crossing
374 his2->GetAxis(3)->SetRange(ibin3,ibin3);
375 if (TMath::Abs(kZ)>0.15){
376 his2->GetAxis(3)->SetRange(ibin3,ibin3);
378 TH1 * his = his2->Projection(0);
379 Double_t mean= his->GetMean();
380 Double_t rms= his->GetRMS();
381 Double_t entries= his->GetEntries();
382 //printf("%f\t%f\t%f\t%f\t%f\t%f\n", sector,localX,kZ, entries, mean,rms);
383 hisResMap3D->SetBinContent(ibin1,ibin2,ibin3, mean);
384 Double_t phi=TMath::Pi()*sector/9;
385 if (phi>TMath::Pi()) phi+=TMath::Pi();
390 his->Fit("gaus","Q","goff");
391 fgaus= (TF1*)((his->GetListOfFunctions()->FindObject("gaus"))->Clone());
394 his->Fit(fgaus,"Q","goff");
395 meanG=fgaus->GetParameter(1);
396 rmsG=fgaus->GetParameter(2);
399 Double_t dsec=sector-Int_t(sector)-0.5;
400 Double_t snp=dsec*TMath::Pi()/9.;
401 (*pcstream)<<"delta"<<
415 "entries="<<entries<<
418 "entriesA="<<entriesA<<
421 "entriesC="<<entriesC<<
422 "offsetA="<<offsetA<<
425 "offsetC="<<offsetC<<
435 hisResMap3D->Write();
436 hisResMap2D[0]->Write();
437 hisResMap2D[1]->Write();
438 hisResMap2D[2]->Write();
439 hisResMap2D[3]->Write();
445 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){
447 // make a distortion map out ou fthe residual histogram
448 // Results are written to the debug streamer - pcstream
450 // his0 - input (4D) residual histogram
451 // pcstream - file to write the tree
453 // refX - track matching reference X
454 // type - 0- y 1-z,2 -snp, 3-theta, 4=1/pt
456 // OBJ: TAxis #Delta #Delta
457 // OBJ: TAxis tanTheta tan(#Theta)
458 // OBJ: TAxis phi #phi
459 // OBJ: TAxis snp snp
461 // marian.ivanov@cern.ch
462 const Int_t kMinEntries=10;
463 Int_t idim[4]={0,1,2,3};
467 Int_t nbins3=his0->GetAxis(3)->GetNbins();
468 Int_t first3=his0->GetAxis(3)->GetFirst();
469 Int_t last3 =his0->GetAxis(3)->GetLast();
471 for (Int_t ibin3=first3; ibin3<last3; ibin3+=1){ // axis 3 - local angle
472 his0->GetAxis(3)->SetRange(TMath::Max(ibin3-integ,1),TMath::Min(ibin3+integ,nbins3));
473 Double_t x3= his0->GetAxis(3)->GetBinCenter(ibin3);
474 THnSparse * his3= his0->Projection(3,idim); //projected histogram according selection 3
476 Int_t nbins2 = his3->GetAxis(2)->GetNbins();
477 Int_t first2 = his3->GetAxis(2)->GetFirst();
478 Int_t last2 = his3->GetAxis(2)->GetLast();
480 for (Int_t ibin2=first2; ibin2<last2; ibin2+=1){ // axis 2 - phi
481 his3->GetAxis(2)->SetRange(TMath::Max(ibin2-integ,1),TMath::Min(ibin2+integ,nbins2));
482 Double_t x2= his3->GetAxis(2)->GetBinCenter(ibin2);
483 THnSparse * his2= his3->Projection(2,idim); //projected histogram according selection 2
484 Int_t nbins1 = his2->GetAxis(1)->GetNbins();
485 Int_t first1 = his2->GetAxis(1)->GetFirst();
486 Int_t last1 = his2->GetAxis(1)->GetLast();
487 for (Int_t ibin1=first1; ibin1<last1; ibin1++){ //axis 1 - theta
489 Double_t x1= his2->GetAxis(1)->GetBinCenter(ibin1);
490 his2->GetAxis(1)->SetRange(TMath::Max(ibin1-1,1),TMath::Min(ibin1+1,nbins1));
491 if (TMath::Abs(x1)<0.1){
492 if (x1<0) his2->GetAxis(1)->SetRange(TMath::Max(ibin1-1,1),TMath::Min(ibin1,nbins1));
493 if (x1>0) his2->GetAxis(1)->SetRange(TMath::Max(ibin1,1),TMath::Min(ibin1+1,nbins1));
495 if (TMath::Abs(x1)<0.06){
496 his2->GetAxis(1)->SetRange(TMath::Max(ibin1,1),TMath::Min(ibin1,nbins1));
498 TH1 * hisDelta = his2->Projection(0);
500 Double_t entries = hisDelta->GetEntries();
501 Double_t mean=0, rms=0;
502 if (entries>kMinEntries){
503 mean = hisDelta->GetMean();
504 rms = hisDelta->GetRMS();
506 Double_t sector = 9.*x2/TMath::Pi();
507 if (sector<0) sector+=18;
508 Double_t dsec = sector-Int_t(sector)-0.5;
517 "entries="<<entries<<
520 "refX="<<refX<< // track matching refernce plane
526 //printf("%f\t%f\t%f\t%f\t%f\n",x3,x2,x1, entries,mean);
536 void AliTPCCorrectionFit::MakeDistortionMapCosmic(THnSparse * hisInput, TTreeSRedirector * const pcstream, const char* hname, Int_t run, Float_t refX, Int_t type){
538 // make a distortion map out ou fthe residual histogram
539 // Results are written to the debug streamer - pcstream
541 // his0 - input (4D) residual histogram
542 // pcstream - file to write the tree
544 // refX - track matching reference X
545 // type - 0- y 1-z,2 -snp, 3-theta, 4=1/pt
546 // marian.ivanov@cern.ch
549 // Collection name='TObjArray', class='TObjArray', size=16
550 // 0. OBJ: TAxis #Delta #Delta
551 // 1. OBJ: TAxis N_{cl} N_{cl}
552 // 2. OBJ: TAxis dca_{r} (cm) dca_{r} (cm)
553 // 3. OBJ: TAxis z (cm) z (cm)
554 // 4. OBJ: TAxis sin(#phi) sin(#phi)
555 // 5. OBJ: TAxis tan(#theta) tan(#theta)
556 // 6. OBJ: TAxis 1/pt (1/GeV) 1/pt (1/GeV)
557 // 7. OBJ: TAxis pt (GeV) pt (GeV)
558 // 8. OBJ: TAxis alpha alpha
559 const Int_t kMinEntries=10;
561 // 1. make default selections
564 Int_t idim0[4]={0 , 5, 8, 3}; // delta, theta, alpha, z
565 hisInput->GetAxis(1)->SetRangeUser(110,190); //long tracks
566 hisInput->GetAxis(2)->SetRangeUser(-10,35); //tracks close to beam pipe
567 hisInput->GetAxis(4)->SetRangeUser(-0.3,0.3); //small snp at TPC entrance
568 hisInput->GetAxis(7)->SetRangeUser(3,100); //"high pt tracks"
569 hisDelta= hisInput->Projection(0);
570 hisInput->GetAxis(0)->SetRangeUser(-6.*hisDelta->GetRMS(), +6.*hisDelta->GetRMS());
572 THnSparse *his0= hisInput->Projection(4,idim0);
574 // 2. Get mean in diferent bins
576 Int_t nbins1=his0->GetAxis(1)->GetNbins();
577 Int_t first1=his0->GetAxis(1)->GetFirst();
578 Int_t last1 =his0->GetAxis(1)->GetLast();
580 Double_t bz=AliTrackerBase::GetBz();
581 Int_t idim[4]={0,1, 2, 3}; // delta, theta,alpha,z
583 for (Int_t ibin1=first1; ibin1<=last1; ibin1++){ //axis 1 - theta
585 Double_t x1= his0->GetAxis(1)->GetBinCenter(ibin1);
586 his0->GetAxis(1)->SetRange(TMath::Max(ibin1-1,1),TMath::Min(ibin1+1,nbins1));
588 THnSparse * his1 = his0->Projection(4,idim); // projected histogram according range1
589 Int_t nbins3 = his1->GetAxis(3)->GetNbins();
590 Int_t first3 = his1->GetAxis(3)->GetFirst();
591 Int_t last3 = his1->GetAxis(3)->GetLast();
593 for (Int_t ibin3=first3-1; ibin3<=last3; ibin3+=1){ // axis 3 - z at "vertex"
594 his1->GetAxis(3)->SetRange(TMath::Max(ibin3-1,1),TMath::Min(ibin3+1,nbins3));
595 Double_t x3= his1->GetAxis(3)->GetBinCenter(ibin3);
597 his1->GetAxis(3)->SetRangeUser(-1,1);
600 THnSparse * his3= his1->Projection(4,idim); //projected histogram according selection 3
601 Int_t nbins2 = his3->GetAxis(2)->GetNbins();
602 Int_t first2 = his3->GetAxis(2)->GetFirst();
603 Int_t last2 = his3->GetAxis(2)->GetLast();
605 for (Int_t ibin2=first2; ibin2<=last2; ibin2+=1){
606 his3->GetAxis(2)->SetRange(TMath::Max(ibin2-1,1),TMath::Min(ibin2+1,nbins2));
607 Double_t x2= his3->GetAxis(2)->GetBinCenter(ibin2);
608 hisDelta = his3->Projection(0);
610 Double_t entries = hisDelta->GetEntries();
611 Double_t mean=0, rms=0;
612 if (entries>kMinEntries){
613 mean = hisDelta->GetMean();
614 rms = hisDelta->GetRMS();
616 Double_t sector = 9.*x2/TMath::Pi();
617 if (sector<0) sector+=18;
618 Double_t dsec = sector-Int_t(sector)-0.5;
619 Double_t snp=0; // dummy snp - equal 0
622 "bz="<<bz<< // magnetic field
623 "theta="<<x1<< // theta
624 "phi="<<x2<< // phi (alpha)
625 "z="<<x3<< // z at "vertex"
626 "snp="<<snp<< // dummy snp
627 "entries="<<entries<< // entries in bin
628 "mean="<<mean<< // mean
630 "refX="<<refX<< // track matching refernce plane
631 "type="<<type<< // parameter type
632 "sector="<<sector<< // sector
633 "dsec="<<dsec<< // dummy delta sector
636 printf("%f\t%f\t%f\t%f\t%f\n",x1,x3,x2, entries,mean);
647 void AliTPCCorrectionFit::MakeDistortionMapSector(THnSparse * hisInput, TTreeSRedirector * const pcstream, const char* hname, Int_t run, Int_t type, Double_t bz){
649 // make a distortion map out of the residual histogram
650 // Results are written to the debug streamer - pcstream
652 // his0 - input (4D) residual histogram
653 // pcstream - file to write the tree
655 // type - 0- y 1-z,2 -snp, 3-theta
656 // bz - magnetic field
657 // marian.ivanov@cern.ch
659 //Collection name='TObjArray', class='TObjArray', size=16
660 //0 OBJ: TAxis delta delta
661 //1 OBJ: TAxis phi phi
662 //2 OBJ: TAxis localX localX
665 //5 OBJ: TAxis is1 is1
666 //6 OBJ: TAxis is0 is0
668 //8. OBJ: TAxis IsPrimary IsPrimary
670 const Int_t kMinEntries=10;
671 THnSparse * hisSector0=0;
672 TH1 * htemp=0; // histogram to calculate mean value of parameter
673 // Double_t bz=AliTrackerBase::GetBz();
676 // Loop over pair of sector:
687 for (Int_t isec0=0; isec0<72; isec0++){
688 Int_t index0[9]={0, 4, 3, 7, 1, 2, 5, 6,8}; //regroup indeces
690 //hisInput->GetAxis(8)->SetRangeUser(-0.1,0.4); // select secondaries only ? - get out later ?
691 hisInput->GetAxis(6)->SetRangeUser(isec0-0.1,isec0+0.1);
692 hisSector0=hisInput->Projection(7,index0);
695 for (Int_t isec1=isec0+1; isec1<72; isec1++){
696 //if (isec1!=isec0+36) continue;
697 if ( TMath::Abs((isec0%18)-(isec1%18))>1.5 && TMath::Abs((isec0%18)-(isec1%18))<16.5) continue;
698 printf("Sectors %d\t%d\n",isec1,isec0);
699 hisSector0->GetAxis(6)->SetRangeUser(isec1-0.1,isec1+0.1);
700 TH1 * hisX=hisSector0->Projection(5);
701 Double_t refX= hisX->GetMean();
703 TH1 *hisDelta=hisSector0->Projection(0);
704 Double_t dmean = hisDelta->GetMean();
705 Double_t drms = hisDelta->GetRMS();
706 hisSector0->GetAxis(0)->SetRangeUser(dmean-5.*drms, dmean+5.*drms);
709 // 1. make default selections
711 Int_t idim0[5]={0 , 1, 2, 3, 4}; // {delta, theta, snp, z, phi }
712 THnBase *hisSector1= hisSector0->ProjectionND(5,idim0);
714 // 2. Get mean in diferent bins
716 Int_t idim[5]={0, 1, 2, 3, 4}; // {delta, theta-1,snp-2 ,z-3, phi-4}
718 // Int_t nbinsPhi=hisSector1->GetAxis(4)->GetNbins();
719 Int_t firstPhi=hisSector1->GetAxis(4)->GetFirst();
720 Int_t lastPhi =hisSector1->GetAxis(4)->GetLast();
722 for (Int_t ibinPhi=firstPhi; ibinPhi<=lastPhi; ibinPhi+=2){ //axis 4 - phi
726 Double_t xPhi= hisSector1->GetAxis(4)->GetBinCenter(ibinPhi);
727 Double_t psec = (9*xPhi/TMath::Pi());
728 if (psec<0) psec+=18;
731 if (TMath::Abs(psec-isec0%18-0.5)<1. || TMath::Abs(psec-isec0%18-17.5)<1.) isOK0=kTRUE;
732 if (TMath::Abs(psec-isec1%18-0.5)<1. || TMath::Abs(psec-isec1%18-17.5)<1.) isOK1=kTRUE;
733 if (!isOK0) continue;
734 if (!isOK1) continue;
736 hisSector1->GetAxis(4)->SetRange(TMath::Max(ibinPhi-2,firstPhi),TMath::Min(ibinPhi+2,lastPhi));
737 if (isec1!=isec0+36) {
738 hisSector1->GetAxis(4)->SetRange(TMath::Max(ibinPhi-3,firstPhi),TMath::Min(ibinPhi+3,lastPhi));
741 htemp = hisSector1->Projection(4);
742 xPhi=htemp->GetMean();
744 THnBase * hisPhi = hisSector1->ProjectionND(4,idim);
745 //Int_t nbinsZ = hisPhi->GetAxis(3)->GetNbins();
746 Int_t firstZ = hisPhi->GetAxis(3)->GetFirst();
747 Int_t lastZ = hisPhi->GetAxis(3)->GetLast();
749 for (Int_t ibinZ=firstZ; ibinZ<=lastZ; ibinZ+=2){ // axis 3 - z
753 hisPhi->GetAxis(3)->SetRange(TMath::Max(ibinZ,firstZ),TMath::Min(ibinZ,lastZ));
754 if (isec1!=isec0+36) {
755 hisPhi->GetAxis(3)->SetRange(TMath::Max(ibinZ-1,firstZ),TMath::Min(ibinZ-1,lastZ));
757 htemp = hisPhi->Projection(3);
758 Double_t xZ= htemp->GetMean();
760 THnBase * hisZ= hisPhi->ProjectionND(3,idim);
761 //projected histogram according selection 3 -z
764 //Int_t nbinsSnp = hisZ->GetAxis(2)->GetNbins();
765 Int_t firstSnp = hisZ->GetAxis(2)->GetFirst();
766 Int_t lastSnp = hisZ->GetAxis(2)->GetLast();
767 for (Int_t ibinSnp=firstSnp; ibinSnp<=lastSnp; ibinSnp+=2){ // axis 2 - snp
771 hisZ->GetAxis(2)->SetRange(TMath::Max(ibinSnp-1,firstSnp),TMath::Min(ibinSnp+1,lastSnp));
772 if (isec1!=isec0+36) {
773 hisZ->GetAxis(2)->SetRange(TMath::Max(ibinSnp-2,firstSnp),TMath::Min(ibinSnp+2,lastSnp));
775 htemp = hisZ->Projection(2);
776 Double_t xSnp= htemp->GetMean();
778 THnBase * hisSnp= hisZ->ProjectionND(2,idim);
779 //projected histogram according selection 2 - snp
781 //Int_t nbinsTheta = hisSnp->GetAxis(1)->GetNbins();
782 Int_t firstTheta = hisSnp->GetAxis(1)->GetFirst();
783 Int_t lastTheta = hisSnp->GetAxis(1)->GetLast();
785 for (Int_t ibinTheta=firstTheta; ibinTheta<=lastTheta; ibinTheta+=2){ // axis1 theta
788 hisSnp->GetAxis(1)->SetRange(TMath::Max(ibinTheta-2,firstTheta),TMath::Min(ibinTheta+2,lastTheta));
789 if (isec1!=isec0+36) {
790 hisSnp->GetAxis(1)->SetRange(TMath::Max(ibinTheta-3,firstTheta),TMath::Min(ibinTheta+3,lastTheta));
792 htemp = hisSnp->Projection(1);
793 Double_t xTheta=htemp->GetMean();
795 hisDelta = hisSnp->Projection(0);
797 Double_t entries = hisDelta->GetEntries();
798 Double_t mean=0, rms=0;
799 if (entries>kMinEntries){
800 mean = hisDelta->GetMean();
801 rms = hisDelta->GetRMS();
803 Double_t sector = 9.*xPhi/TMath::Pi();
804 if (sector<0) sector+=18;
805 Double_t dsec = sector-Int_t(sector)-0.5;
806 Int_t dtype=1; // TPC alignment type
809 "bz="<<bz<< // magnetic field
810 "ptype="<<type<< // parameter type
811 "dtype="<<dtype<< // parameter type
812 "isec0="<<isec0<< // sector 0
813 "isec1="<<isec1<< // sector 1
814 "sector="<<sector<< // sector as float
815 "dsec="<<dsec<< // delta sector
817 "theta="<<xTheta<< // theta
818 "phi="<<xPhi<< // phi (alpha)
820 "snp="<<xSnp<< // snp
823 "entries="<<entries<< // entries in bin
824 "mean="<<mean<< // mean
826 "refX="<<refX<< // track matching reference plane
829 //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);
848 // void AliTPCCorrectionFit::MakeLaserDistortionTree(TTree* tree, TObjArray */*corrArray*/, Int_t /*itype*/){
850 // // Make a laser fit tree for global minimization
852 // AliTPCcalibDB* calib=AliTPCcalibDB::Instance();
853 // AliTPCCorrection * correction = calib->GetTPCComposedCorrection();
854 // if (!correction) correction = calib->GetTPCComposedCorrection(AliTrackerBase::GetBz());
855 // correction->AddVisualCorrection(correction,0); //register correction
857 // // AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
858 // //AliTPCParam *param = AliTPCcalibDB::Instance()->GetParameters();
860 // const Double_t cutErrY=0.05;
861 // const Double_t kSigmaCut=4;
862 // // const Double_t cutErrZ=0.03;
863 // const Double_t kEpsilon=0.00000001;
864 // // const Double_t kMaxDist=1.; // max distance - space correction
865 // TVectorD *vecdY=0;
866 // TVectorD *vecdZ=0;
867 // TVectorD *veceY=0;
868 // TVectorD *veceZ=0;
869 // AliTPCLaserTrack *ltr=0;
870 // AliTPCLaserTrack::LoadTracks();
871 // tree->SetBranchAddress("dY.",&vecdY);
872 // tree->SetBranchAddress("dZ.",&vecdZ);
873 // tree->SetBranchAddress("eY.",&veceY);
874 // tree->SetBranchAddress("eZ.",&veceZ);
875 // tree->SetBranchAddress("LTr.",<r);
876 // Int_t entries= tree->GetEntries();
877 // TTreeSRedirector *pcstream= new TTreeSRedirector("distortionLaser_0.root");
878 // Double_t bz=AliTrackerBase::GetBz();
880 // // Double_t globalXYZ[3];
881 // //Double_t globalXYZCorr[3];
882 // for (Int_t ientry=0; ientry<entries; ientry++){
883 // tree->GetEntry(ientry);
884 // if (!ltr->GetVecGX()){
885 // ltr->UpdatePoints();
888 // TVectorD fit10(5);
890 // printf("Entry\t%d\n",ientry);
891 // for (Int_t irow0=0; irow0<158; irow0+=1){
893 // TLinearFitter fitter10(4,"hyp3");
894 // TLinearFitter fitter5(2,"hyp1");
895 // Int_t sector= (Int_t)(*ltr->GetVecSec())[irow0];
896 // if (sector<0) continue;
897 // //if (TMath::Abs(vecdY->GetMatrixArray()[irow0])<kEpsilon) continue;
899 // Double_t refX= (*ltr->GetVecLX())[irow0];
900 // Int_t firstRow1 = TMath::Max(irow0-10,0);
901 // Int_t lastRow1 = TMath::Min(irow0+10,158);
902 // Double_t padWidth=(irow0<64)?0.4:0.6;
903 // // make long range fit
904 // for (Int_t irow1=firstRow1; irow1<=lastRow1; irow1++){
905 // if (TMath::Abs((*ltr->GetVecSec())[irow1]-sector)>kEpsilon) continue;
906 // if (veceY->GetMatrixArray()[irow1]>cutErrY) continue;
907 // if (TMath::Abs(vecdY->GetMatrixArray()[irow1])<kEpsilon) continue;
908 // Double_t idealX= (*ltr->GetVecLX())[irow1];
909 // Double_t idealY= (*ltr->GetVecLY())[irow1];
910 // // Double_t idealZ= (*ltr->GetVecLZ())[irow1];
911 // Double_t gx= (*ltr->GetVecGX())[irow1];
912 // Double_t gy= (*ltr->GetVecGY())[irow1];
913 // Double_t gz= (*ltr->GetVecGZ())[irow1];
914 // Double_t measY=(*vecdY)[irow1]+idealY;
915 // Double_t deltaR = GetCorrXYZ(gx, gy, gz, 0,0);
916 // // deltaR = R distorted -R ideal
917 // Double_t xxx[4]={idealX+deltaR-refX,TMath::Cos(idealY/padWidth), TMath::Sin(idealY/padWidth)};
918 // fitter10.AddPoint(xxx,measY,1);
920 // Bool_t isOK=kTRUE;
921 // Double_t rms10=0;//TMath::Sqrt(fitter10.GetChisquare()/(fitter10.GetNpoints()-4));
922 // Double_t mean10 =0;// fitter10.GetParameter(0);
923 // Double_t slope10 =0;// fitter10.GetParameter(0);
924 // Double_t cosPart10 = 0;// fitter10.GetParameter(2);
925 // Double_t sinPart10 =0;// fitter10.GetParameter(3);
927 // if (fitter10.GetNpoints()>10){
929 // rms10=TMath::Sqrt(fitter10.GetChisquare()/(fitter10.GetNpoints()-4));
930 // mean10 = fitter10.GetParameter(0);
931 // slope10 = fitter10.GetParameter(1);
932 // cosPart10 = fitter10.GetParameter(2);
933 // sinPart10 = fitter10.GetParameter(3);
935 // // make short range fit
937 // for (Int_t irow1=firstRow1+5; irow1<=lastRow1-5; irow1++){
938 // if (TMath::Abs((*ltr->GetVecSec())[irow1]-sector)>kEpsilon) continue;
939 // if (veceY->GetMatrixArray()[irow1]>cutErrY) continue;
940 // if (TMath::Abs(vecdY->GetMatrixArray()[irow1])<kEpsilon) continue;
941 // Double_t idealX= (*ltr->GetVecLX())[irow1];
942 // Double_t idealY= (*ltr->GetVecLY())[irow1];
943 // // Double_t idealZ= (*ltr->GetVecLZ())[irow1];
944 // Double_t gx= (*ltr->GetVecGX())[irow1];
945 // Double_t gy= (*ltr->GetVecGY())[irow1];
946 // Double_t gz= (*ltr->GetVecGZ())[irow1];
947 // Double_t measY=(*vecdY)[irow1]+idealY;
948 // Double_t deltaR = GetCorrXYZ(gx, gy, gz, 0,0);
949 // // deltaR = R distorted -R ideal
950 // Double_t expY= mean10+slope10*(idealX+deltaR-refX);
951 // if (TMath::Abs(measY-expY)>kSigmaCut*rms10) continue;
953 // Double_t corr=cosPart10*TMath::Cos(idealY/padWidth)+sinPart10*TMath::Sin(idealY/padWidth);
954 // Double_t xxx[4]={idealX+deltaR-refX,TMath::Cos(idealY/padWidth), TMath::Sin(idealY/padWidth)};
955 // fitter5.AddPoint(xxx,measY-corr,1);
960 // if (fitter5.GetNpoints()<8) isOK=kFALSE;
962 // Double_t rms5=0;//TMath::Sqrt(fitter5.GetChisquare()/(fitter5.GetNpoints()-4));
963 // Double_t offset5 =0;// fitter5.GetParameter(0);
964 // Double_t slope5 =0;// fitter5.GetParameter(0);
967 // rms5=TMath::Sqrt(fitter5.GetChisquare()/(fitter5.GetNpoints()-4));
968 // offset5 = fitter5.GetParameter(0);
969 // slope5 = fitter5.GetParameter(0);
974 // Double_t phi =(*ltr->GetVecPhi())[irow0];
975 // Double_t theta =ltr->GetTgl();
976 // Double_t mean=(vecdY)->GetMatrixArray()[irow0];
977 // Double_t gx=0,gy=0,gz=0;
978 // Double_t snp = (*ltr->GetVecP2())[irow0];
979 // Int_t bundle= ltr->GetBundle();
980 // Int_t id= ltr->GetId();
981 // // Double_t rms = err->GetMatrixArray()[irow];
983 // gx = (*ltr->GetVecGX())[irow0];
984 // gy = (*ltr->GetVecGY())[irow0];
985 // gz = (*ltr->GetVecGZ())[irow0];
986 // Double_t dRrec = GetCorrXYZ(gx, gy, gz, 0,0);
987 // fitter10.GetParameters(fit10);
988 // fitter5.GetParameters(fit5);
989 // Double_t idealY= (*ltr->GetVecLY())[irow0];
990 // Double_t measY=(*vecdY)[irow0]+idealY;
991 // Double_t corr=cosPart10*TMath::Cos(idealY/padWidth)+sinPart10*TMath::Sin(idealY/padWidth);
992 // if (TMath::Max(rms5,rms10)>0.06) isOK=kFALSE;
994 // (*pcstream)<<"fitFull"<< // dumpe also intermediate results
995 // "bz="<<bz<< // magnetic filed used
996 // "dtype="<<dtype<< // detector match type
997 // "ptype="<<ptype<< // parameter type
998 // "theta="<<theta<< // theta
999 // "phi="<<phi<< // phi
1000 // "snp="<<snp<< // snp
1001 // "sector="<<sector<<
1002 // "bundle="<<bundle<<
1003 // // // "dsec="<<dsec<<
1004 // "refX="<<refX<< // reference radius
1005 // "gx="<<gx<< // global position
1006 // "gy="<<gy<< // global position
1007 // "gz="<<gz<< // global position
1008 // "dRrec="<<dRrec<< // delta Radius in reconstruction
1009 // "id="<<id<< //bundle
1010 // "rms10="<<rms10<<
1012 // "fit10.="<<&fit10<<
1013 // "fit5.="<<&fit5<<
1014 // "measY="<<measY<<
1016 // "idealY="<<idealY<<
1026 void AliTPCCorrectionFit::MakeTrackDistortionTree(TTree *tinput, Int_t dtype, Int_t ptype, const TObjArray * corrArray, Int_t step, Int_t offset, Bool_t debug ){
1029 // For each partial correction (specified in array) and given track topology (phi, theta, snp, refX)
1030 // calculates partial distortions
1031 // Partial distortion is stored in the resulting tree
1032 // Output is storred in the file distortion_<dettype>_<partype>.root
1033 // Partial distortion is stored with the name given by correction name
1036 // Parameters of function:
1037 // input - input tree
1038 // dtype - distortion type 0 - ITSTPC, 1 -TPCTRD, 2 - TPCvertex , 3 - TPC-TOF, 4 - TPCTPC track crossing
1039 // ppype - parameter type
1040 // corrArray - array with partial corrections
1041 // step - skipe entries - if 1 all entries processed - it is slow
1042 // debug 0 if debug on also space points dumped - it is slow
1044 const Double_t kMaxSnp = 0.85;
1045 const Double_t kcutSnp=0.25;
1046 const Double_t kcutTheta=1.;
1047 const Double_t kRadiusTPC=85;
1048 // AliTPCROC *tpcRoc =AliTPCROC::Instance();
1050 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
1051 // const Double_t kB2C=-0.299792458e-3;
1052 const Int_t kMinEntries=20;
1053 Double_t phi,theta, snp, mean,rms, entries,sector,dsec;
1056 tinput->SetBranchAddress("run",&run);
1057 tinput->SetBranchAddress("theta",&theta);
1058 tinput->SetBranchAddress("phi", &phi);
1059 tinput->SetBranchAddress("snp",&snp);
1060 tinput->SetBranchAddress("mean",&mean);
1061 tinput->SetBranchAddress("rms",&rms);
1062 tinput->SetBranchAddress("entries",&entries);
1063 tinput->SetBranchAddress("sector",§or);
1064 tinput->SetBranchAddress("dsec",&dsec);
1065 tinput->SetBranchAddress("refX",&refX);
1066 TTreeSRedirector *pcstream = new TTreeSRedirector(Form("distortion%d_%d_%d.root",dtype,ptype,offset));
1068 Int_t nentries=tinput->GetEntries();
1069 Int_t ncorr=corrArray->GetEntries();
1070 Double_t corrections[100]={0}; //
1072 Double_t cov[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1074 if (dtype==5 || dtype==6) dtype=4;
1075 if (dtype==0) { dir=-1;}
1076 if (dtype==1) { dir=1;}
1077 if (dtype==2) { dir=-1;}
1078 if (dtype==3) { dir=1;}
1079 if (dtype==4) { dir=-1;}
1081 for (Int_t ientry=offset; ientry<nentries; ientry+=step){
1082 tinput->GetEntry(ientry);
1083 if (TMath::Abs(snp)>kMaxSnp) continue;
1086 if (dtype==2) tPar[1]=theta*kRadiusTPC;
1089 tPar[4]=(gRandom->Rndm()-0.5)*0.02; // should be calculated - non equal to 0
1091 // tracks crossing CE
1092 tPar[1]=0; // track at the CE
1093 //if (TMath::Abs(theta) <0.05) continue; // deep cross
1096 if (TMath::Abs(snp) >kcutSnp) continue;
1097 if (TMath::Abs(theta) >kcutTheta) continue;
1098 printf("%f\t%f\t%f\t%f\t%f\t%f\n",entries, sector,theta,snp, mean,rms);
1099 Double_t bz=AliTrackerBase::GetBz();
1100 if (dtype !=4) { //exclude TPC - for TPC mainly non primary tracks
1101 if (dtype!=2 && TMath::Abs(bz)>0.1 ) tPar[4]=snp/(refX*bz*kB2C*2);
1103 if (dtype==2 && TMath::Abs(bz)>0.1 ) {
1104 tPar[4]=snp/(kRadiusTPC*bz*kB2C*2);//
1105 // snp at the TPC inner radius in case the vertex match used
1109 tPar[4]+=(gRandom->Rndm()-0.5)*0.02;
1110 AliExternalTrackParam track(refX,phi,tPar,cov);
1114 Double_t pt=1./tPar[4];
1115 Double_t dRrec=0; // dummy value - needed for points - e.g for laser
1116 //if (ptype==4 &&bz<0) mean*=-1; // interpret as curvature -- COMMENTED out - in lookup signed 1/pt used
1117 Double_t refXD=refX;
1118 (*pcstream)<<"fit"<<
1119 "run="<<run<< // run number
1120 "bz="<<bz<< // magnetic filed used
1121 "dtype="<<dtype<< // detector match type
1122 "ptype="<<ptype<< // parameter type
1123 "theta="<<theta<< // theta
1124 "phi="<<phi<< // phi
1125 "snp="<<snp<< // snp
1126 "mean="<<mean<< // mean dist value
1127 "rms="<<rms<< // rms
1130 "refX="<<refXD<< // referece X as double
1131 "gx="<<xyz[0]<< // global position at reference
1132 "gy="<<xyz[1]<< // global position at reference
1133 "gz="<<xyz[2]<< // global position at reference
1134 "dRrec="<<dRrec<< // delta Radius in reconstruction
1136 "id="<<id<< // track id
1137 "entries="<<entries;// number of entries in bin
1140 if (entries<kMinEntries) isOK=kFALSE;
1142 if (dtype!=4) for (Int_t icorr=0; icorr<ncorr; icorr++) {
1143 AliTPCCorrection *corr = (AliTPCCorrection*)corrArray->At(icorr);
1144 corrections[icorr]=0;
1145 if (entries>kMinEntries){
1146 AliExternalTrackParam trackIn(refX,phi,tPar,cov);
1147 AliExternalTrackParam *trackOut = 0;
1148 if (debug) trackOut=corr->FitDistortedTrack(trackIn, refX, dir,pcstream);
1149 if (!debug) trackOut=corr->FitDistortedTrack(trackIn, refX, dir,0);
1150 if (dtype==0) {dir= -1;}
1151 if (dtype==1) {dir= 1;}
1152 if (dtype==2) {dir= -1;}
1153 if (dtype==3) {dir= 1;}
1156 if (!AliTrackerBase::PropagateTrackTo(&trackIn,refX,kMass,5,kTRUE,kMaxSnp)) isOK=kFALSE;
1157 if (!trackOut->Rotate(trackIn.GetAlpha())) isOK=kFALSE;
1158 if (!AliTrackerBase::PropagateTrackTo(trackOut,trackIn.GetX(),kMass,5,kFALSE,kMaxSnp)) isOK=kFALSE;
1159 // trackOut->PropagateTo(trackIn.GetX(),AliTrackerBase::GetBz());
1161 corrections[icorr]= trackOut->GetParameter()[ptype]-trackIn.GetParameter()[ptype];
1164 corrections[icorr]=0;
1167 //if (ptype==4 &&bz<0) corrections[icorr]*=-1; // interpret as curvature - commented out
1169 (*pcstream)<<"fit"<<
1170 Form("%s=",corr->GetName())<<corrections[icorr]; // dump correction value
1173 if (dtype==4) for (Int_t icorr=0; icorr<ncorr; icorr++) {
1175 // special case of the TPC tracks crossing the CE
1177 AliTPCCorrection *corr = (AliTPCCorrection*)corrArray->At(icorr);
1178 corrections[icorr]=0;
1179 if (entries>kMinEntries){
1180 AliExternalTrackParam trackIn0(refX,phi,tPar,cov); //Outer - direction to vertex
1181 AliExternalTrackParam trackIn1(refX,phi,tPar,cov); //Inner - direction magnet
1182 AliExternalTrackParam *trackOut0 = 0;
1183 AliExternalTrackParam *trackOut1 = 0;
1185 if (debug) trackOut0=corr->FitDistortedTrack(trackIn0, refX, dir,pcstream);
1186 if (!debug) trackOut0=corr->FitDistortedTrack(trackIn0, refX, dir,0);
1187 if (debug) trackOut1=corr->FitDistortedTrack(trackIn1, refX, -dir,pcstream);
1188 if (!debug) trackOut1=corr->FitDistortedTrack(trackIn1, refX, -dir,0);
1190 if (trackOut0 && trackOut1){
1191 if (!AliTrackerBase::PropagateTrackTo(&trackIn0,refX,kMass,5,kTRUE,kMaxSnp)) isOK=kFALSE;
1192 if (!AliTrackerBase::PropagateTrackTo(&trackIn0,refX,kMass,1,kFALSE,kMaxSnp)) isOK=kFALSE;
1193 if (!trackOut0->Rotate(trackIn0.GetAlpha())) isOK=kFALSE;
1194 if (!AliTrackerBase::PropagateTrackTo(trackOut0,trackIn0.GetX(),kMass,5,kFALSE,kMaxSnp)) isOK=kFALSE;
1196 if (!AliTrackerBase::PropagateTrackTo(&trackIn1,refX,kMass,5,kTRUE,kMaxSnp)) isOK=kFALSE;
1197 if (!trackIn1.Rotate(trackIn0.GetAlpha())) isOK=kFALSE;
1198 if (!AliTrackerBase::PropagateTrackTo(&trackIn1,trackIn0.GetX(),kMass,1,kFALSE,kMaxSnp)) isOK=kFALSE;
1199 if (!trackOut1->Rotate(trackIn1.GetAlpha())) isOK=kFALSE;
1200 if (!AliTrackerBase::PropagateTrackTo(trackOut1,trackIn1.GetX(),kMass,5,kFALSE,kMaxSnp)) isOK=kFALSE;
1202 corrections[icorr] = (trackOut0->GetParameter()[ptype]-trackIn0.GetParameter()[ptype]);
1203 corrections[icorr]-= (trackOut1->GetParameter()[ptype]-trackIn1.GetParameter()[ptype]);
1205 if ((TMath::Abs(trackOut0->GetX()-trackOut1->GetX())>0.1)||
1206 (TMath::Abs(trackOut0->GetX()-trackIn1.GetX())>0.1)||
1207 (TMath::Abs(trackOut0->GetAlpha()-trackOut1->GetAlpha())>0.00001)||
1208 (TMath::Abs(trackOut0->GetAlpha()-trackIn1.GetAlpha())>0.00001)||
1209 (TMath::Abs(trackIn0.GetTgl()-trackIn1.GetTgl())>0.0001)||
1210 (TMath::Abs(trackIn0.GetSnp()-trackIn1.GetSnp())>0.0001)
1217 corrections[icorr]=0;
1221 //if (ptype==4 &&bz<0) corrections[icorr]*=-1; // interpret as curvature - commented out no in lookup
1223 (*pcstream)<<"fit"<<
1224 Form("%s=",corr->GetName())<<corrections[icorr]; // dump correction value
1227 (*pcstream)<<"fit"<<"isOK="<<isOK<<"\n";
1236 void AliTPCCorrectionFit::MakeSectorDistortionTree(TTree *tinput, Int_t dtype, Int_t ptype, const TObjArray * corrArray, Int_t step, Int_t offset, Bool_t debug ){
1239 // For each partial correction (specified in array) and given track topology (phi, theta, snp, refX)
1240 // calculates partial distortions
1241 // Partial distortion is stored in the resulting tree
1242 // Output is storred in the file distortion_<dettype>_<partype>.root
1243 // Partial distortion is stored with the name given by correction name
1246 // Parameters of function:
1247 // input - input tree
1248 // dtype - distortion type 10 - IROC-OROC
1249 // ppype - parameter type
1250 // corrArray - array with partial corrections
1251 // step - skipe entries - if 1 all entries processed - it is slow
1252 // debug 0 if debug on also space points dumped - it is slow
1254 const Double_t kMaxSnp = 0.8;
1255 const Int_t kMinEntries=200;
1256 // AliTPCROC *tpcRoc =AliTPCROC::Instance();
1258 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
1259 // const Double_t kB2C=-0.299792458e-3;
1260 Double_t phi,theta, snp, mean,rms, entries,sector,dsec,globalZ;
1265 tinput->SetBranchAddress("run",&run);
1266 tinput->SetBranchAddress("theta",&theta);
1267 tinput->SetBranchAddress("phi", &phi);
1268 tinput->SetBranchAddress("snp",&snp);
1269 tinput->SetBranchAddress("mean",&mean);
1270 tinput->SetBranchAddress("rms",&rms);
1271 tinput->SetBranchAddress("entries",&entries);
1272 tinput->SetBranchAddress("sector",§or);
1273 tinput->SetBranchAddress("dsec",&dsec);
1274 tinput->SetBranchAddress("refX",&refXD);
1275 tinput->SetBranchAddress("z",&globalZ);
1276 tinput->SetBranchAddress("isec0",&isec0);
1277 tinput->SetBranchAddress("isec1",&isec1);
1278 TTreeSRedirector *pcstream = new TTreeSRedirector(Form("distortionSector%d_%d_%d.root",dtype,ptype,offset));
1280 Int_t nentries=tinput->GetEntries();
1281 Int_t ncorr=corrArray->GetEntries();
1282 Double_t corrections[100]={0}; //
1284 Double_t cov[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1287 for (Int_t ientry=offset; ientry<nentries; ientry+=step){
1288 tinput->GetEntry(ientry);
1291 if (TMath::Abs(TMath::Abs(isec0%18)-TMath::Abs(isec1%18))==0) id=1; // IROC-OROC - opposite side
1292 if (TMath::Abs(TMath::Abs(isec0%36)-TMath::Abs(isec1%36))==0) id=2; // IROC-OROC - same side
1293 if (dtype==10 && id==-1) continue;
1300 tPar[4]=(gRandom->Rndm()-0.1)*0.2; //
1301 Double_t pt=1./tPar[4];
1303 printf("%f\t%f\t%f\t%f\t%f\t%f\n",entries, sector,theta,snp, mean,rms);
1304 Double_t bz=AliTrackerBase::GetBz();
1305 AliExternalTrackParam track(refX,phi,tPar,cov);
1306 Double_t xyz[3],xyzIn[3],xyzOut[3];
1308 track.GetXYZAt(85,bz,xyzIn);
1309 track.GetXYZAt(245,bz,xyzOut);
1310 Double_t phiIn = TMath::ATan2(xyzIn[1],xyzIn[0]);
1311 Double_t phiOut = TMath::ATan2(xyzOut[1],xyzOut[0]);
1312 Double_t phiRef = TMath::ATan2(xyz[1],xyz[0]);
1313 Int_t sectorRef = TMath::Nint(9.*phiRef/TMath::Pi()-0.5);
1314 Int_t sectorIn = TMath::Nint(9.*phiIn/TMath::Pi()-0.5);
1315 Int_t sectorOut = TMath::Nint(9.*phiOut/TMath::Pi()-0.5);
1318 if (sectorIn!=sectorOut) isOK=kFALSE; // requironment - cluster in the same sector
1319 if (sectorIn!=sectorRef) isOK=kFALSE; // requironment - cluster in the same sector
1320 if (entries<kMinEntries/(1+TMath::Abs(globalZ/100.))) isOK=kFALSE; // requironment - minimal amount of tracks in bin
1322 if (TMath::Abs(theta)>1) isOK=kFALSE;
1324 Double_t dRrec=0; // dummy value - needed for points - e.g for laser
1326 (*pcstream)<<"fit"<<
1328 "bz="<<bz<< // magnetic filed used
1329 "dtype="<<dtype<< // detector match type
1330 "ptype="<<ptype<< // parameter type
1331 "theta="<<theta<< // theta
1332 "phi="<<phi<< // phi
1333 "snp="<<snp<< // snp
1334 "mean="<<mean<< // mean dist value
1335 "rms="<<rms<< // rms
1338 "refX="<<refXD<< // referece X
1339 "gx="<<xyz[0]<< // global position at reference
1340 "gy="<<xyz[1]<< // global position at reference
1341 "gz="<<xyz[2]<< // global position at reference
1342 "dRrec="<<dRrec<< // delta Radius in reconstruction
1344 "id="<<id<< // track id
1345 "entries="<<entries;// number of entries in bin
1347 AliExternalTrackParam *trackOut0 = 0;
1348 AliExternalTrackParam *trackOut1 = 0;
1349 AliExternalTrackParam *ptrackIn0 = 0;
1350 AliExternalTrackParam *ptrackIn1 = 0;
1352 for (Int_t icorr=0; icorr<ncorr; icorr++) {
1354 // special case of the TPC tracks crossing the CE
1356 AliTPCCorrection *corr = (AliTPCCorrection*)corrArray->At(icorr);
1357 corrections[icorr]=0;
1358 if (entries>kMinEntries &&isOK){
1359 AliExternalTrackParam trackIn0(refX,phi,tPar,cov);
1360 AliExternalTrackParam trackIn1(refX,phi,tPar,cov);
1361 ptrackIn1=&trackIn0;
1362 ptrackIn0=&trackIn1;
1364 if (debug) trackOut0=corr->FitDistortedTrack(trackIn0, refX, dir,pcstream);
1365 if (!debug) trackOut0=corr->FitDistortedTrack(trackIn0, refX, dir,0);
1366 if (debug) trackOut1=corr->FitDistortedTrack(trackIn1, refX, -dir,pcstream);
1367 if (!debug) trackOut1=corr->FitDistortedTrack(trackIn1, refX, -dir,0);
1369 if (trackOut0 && trackOut1){
1371 if (!AliTrackerBase::PropagateTrackTo(&trackIn0,refX,kMass,1,kTRUE,kMaxSnp)) isOK=kFALSE;
1372 if (!AliTrackerBase::PropagateTrackTo(&trackIn0,refX,kMass,1,kFALSE,kMaxSnp)) isOK=kFALSE;
1373 // rotate all tracks to the same frame
1374 if (!trackOut0->Rotate(trackIn0.GetAlpha())) isOK=kFALSE;
1375 if (!trackIn1.Rotate(trackIn0.GetAlpha())) isOK=kFALSE;
1376 if (!trackOut1->Rotate(trackIn0.GetAlpha())) isOK=kFALSE;
1378 if (!AliTrackerBase::PropagateTrackTo(trackOut0,refX,kMass,1,kFALSE,kMaxSnp)) isOK=kFALSE;
1379 if (!AliTrackerBase::PropagateTrackTo(&trackIn1,refX,kMass,1,kFALSE,kMaxSnp)) isOK=kFALSE;
1380 if (!AliTrackerBase::PropagateTrackTo(trackOut1,refX,kMass,1,kFALSE,kMaxSnp)) isOK=kFALSE;
1382 corrections[icorr] = (trackOut0->GetParameter()[ptype]-trackIn0.GetParameter()[ptype]);
1383 corrections[icorr]-= (trackOut1->GetParameter()[ptype]-trackIn1.GetParameter()[ptype]);
1384 (*pcstream)<<"fitDebug"<< // just to debug the correction
1386 "pIn0.="<<ptrackIn0<<
1387 "pIn1.="<<ptrackIn1<<
1388 "pOut0.="<<trackOut0<<
1389 "pOut1.="<<trackOut1<<
1395 corrections[icorr]=0;
1399 (*pcstream)<<"fit"<<
1400 Form("%s=",corr->GetName())<<corrections[icorr]; // dump correction value
1403 (*pcstream)<<"fit"<<"isOK="<<isOK<<"\n";