1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 ////////////////////////////////////////////////////////////////////////////////
18 // AliTPCCorrection class //
20 // This class provides a general framework to deal with space point //
21 // distortions. An correction class which inherits from here is for example //
22 // AliTPCExBBShape or AliTPCExBTwist //
24 // General functions are (for example): //
25 // CorrectPoint(x,roc) where x is the vector of inital positions in //
26 // cartesian coordinates and roc represents the Read Out chamber number //
27 // according to the offline naming convention. The vector x is overwritten //
28 // with the corrected coordinates. //
30 // An alternative usage would be CorrectPoint(x,roc,dx), which leaves the //
31 // vector x untouched, put returns the distortions via the vector dx //
33 // The class allows "effective Omega Tau" corrections to be shifted to the //
34 // single distortion classes. //
36 // Note: This class is normally used via the class AliTPCComposedCorrection //
38 // date: 27/04/2010 //
39 // Authors: Magnus Mager, Stefan Rossegger, Jim Thomas //
40 ////////////////////////////////////////////////////////////////////////////////
41 #include "Riostream.h"
46 #include <TTreeStream.h>
49 #include <TTimeStamp.h>
50 #include <AliCDBStorage.h>
52 #include <AliCDBMetaData.h>
54 #include "AliExternalTrackParam.h"
55 #include "AliTrackPointArray.h"
56 #include "TDatabasePDG.h"
57 #include "AliTrackerBase.h"
58 #include "AliTPCROC.h"
61 #include "AliTPCCorrection.h"
63 ClassImp(AliTPCCorrection)
65 // FIXME: the following values should come from the database
66 const Double_t AliTPCCorrection::fgkTPC_Z0 =249.7; // nominal gating grid position
67 const Double_t AliTPCCorrection::fgkIFCRadius= 83.06; // Mean Radius of the Inner Field Cage ( 82.43 min, 83.70 max) (cm)
68 const Double_t AliTPCCorrection::fgkOFCRadius=254.5; // Mean Radius of the Outer Field Cage (252.55 min, 256.45 max) (cm)
69 const Double_t AliTPCCorrection::fgkZOffSet = 0.2; // Offset from CE: calculate all distortions closer to CE as if at this point
70 const Double_t AliTPCCorrection::fgkCathodeV =-100000.0; // Cathode Voltage (volts)
71 const Double_t AliTPCCorrection::fgkGG =-70.0; // Gating Grid voltage (volts)
74 // FIXME: List of interpolation points (course grid in the middle, fine grid on the borders)
75 const Double_t AliTPCCorrection::fgkRList[AliTPCCorrection::kNR] = {
76 84.0, 84.5, 85.0, 85.5, 86.0, 87.0, 88.0,
77 90.0, 92.0, 94.0, 96.0, 98.0, 100.0, 102.0, 104.0, 106.0, 108.0,
78 110.0, 112.0, 114.0, 116.0, 118.0, 120.0, 122.0, 124.0, 126.0, 128.0,
79 130.0, 132.0, 134.0, 136.0, 138.0, 140.0, 142.0, 144.0, 146.0, 148.0,
80 150.0, 152.0, 154.0, 156.0, 158.0, 160.0, 162.0, 164.0, 166.0, 168.0,
81 170.0, 172.0, 174.0, 176.0, 178.0, 180.0, 182.0, 184.0, 186.0, 188.0,
82 190.0, 192.0, 194.0, 196.0, 198.0, 200.0, 202.0, 204.0, 206.0, 208.0,
83 210.0, 212.0, 214.0, 216.0, 218.0, 220.0, 222.0, 224.0, 226.0, 228.0,
84 230.0, 232.0, 234.0, 236.0, 238.0, 240.0, 242.0, 244.0, 246.0, 248.0,
85 249.0, 249.5, 250.0, 251.5, 252.0 } ;
87 const Double_t AliTPCCorrection::fgkZList[AliTPCCorrection::kNZ] = {
88 -249.5, -249.0, -248.5, -248.0, -247.0, -246.0, -245.0, -243.0, -242.0, -241.0,
89 -240.0, -238.0, -236.0, -234.0, -232.0, -230.0, -228.0, -226.0, -224.0, -222.0,
90 -220.0, -218.0, -216.0, -214.0, -212.0, -210.0, -208.0, -206.0, -204.0, -202.0,
91 -200.0, -198.0, -196.0, -194.0, -192.0, -190.0, -188.0, -186.0, -184.0, -182.0,
92 -180.0, -178.0, -176.0, -174.0, -172.0, -170.0, -168.0, -166.0, -164.0, -162.0,
93 -160.0, -158.0, -156.0, -154.0, -152.0, -150.0, -148.0, -146.0, -144.0, -142.0,
94 -140.0, -138.0, -136.0, -134.0, -132.0, -130.0, -128.0, -126.0, -124.0, -122.0,
95 -120.0, -118.0, -116.0, -114.0, -112.0, -110.0, -108.0, -106.0, -104.0, -102.0,
96 -100.0, -98.0, -96.0, -94.0, -92.0, -90.0, -88.0, -86.0, -84.0, -82.0,
97 -80.0, -78.0, -76.0, -74.0, -72.0, -70.0, -68.0, -66.0, -64.0, -62.0,
98 -60.0, -58.0, -56.0, -54.0, -52.0, -50.0, -48.0, -46.0, -44.0, -42.0,
99 -40.0, -38.0, -36.0, -34.0, -32.0, -30.0, -28.0, -26.0, -24.0, -22.0,
100 -20.0, -18.0, -16.0, -14.0, -12.0, -10.0, -8.0, -6.0, -4.0, -2.0,
101 -1.0, -0.5, -0.2, -0.1, -0.05, 0.05, 0.1, 0.2, 0.5, 1.0,
102 2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0,
103 22.0, 24.0, 26.0, 28.0, 30.0, 32.0, 34.0, 36.0, 38.0, 40.0,
104 42.0, 44.0, 46.0, 48.0, 50.0, 52.0, 54.0, 56.0, 58.0, 60.0,
105 62.0, 64.0, 66.0, 68.0, 70.0, 72.0, 74.0, 76.0, 78.0, 80.0,
106 82.0, 84.0, 86.0, 88.0, 90.0, 92.0, 94.0, 96.0, 98.0, 100.0,
107 102.0, 104.0, 106.0, 108.0, 110.0, 112.0, 114.0, 116.0, 118.0, 120.0,
108 122.0, 124.0, 126.0, 128.0, 130.0, 132.0, 134.0, 136.0, 138.0, 140.0,
109 142.0, 144.0, 146.0, 148.0, 150.0, 152.0, 154.0, 156.0, 158.0, 160.0,
110 162.0, 164.0, 166.0, 168.0, 170.0, 172.0, 174.0, 176.0, 178.0, 180.0,
111 182.0, 184.0, 186.0, 188.0, 190.0, 192.0, 194.0, 196.0, 198.0, 200.0,
112 202.0, 204.0, 206.0, 208.0, 210.0, 212.0, 214.0, 216.0, 218.0, 220.0,
113 222.0, 224.0, 226.0, 228.0, 230.0, 232.0, 234.0, 236.0, 238.0, 240.0,
114 242.0, 243.0, 244.0, 245.0, 246.0, 247.0, 248.0, 248.5, 249.0, 249.5 } ;
118 AliTPCCorrection::AliTPCCorrection()
119 : TNamed("correction_unity","unity"),fJLow(0),fKLow(0)
122 // default constructor
126 AliTPCCorrection::AliTPCCorrection(const char *name,const char *title)
127 : TNamed(name,title),fJLow(0),fKLow(0)
130 // default constructor, that set the name and title
134 AliTPCCorrection::~AliTPCCorrection() {
136 // virtual destructor
140 void AliTPCCorrection::CorrectPoint(Float_t x[],const Short_t roc) {
142 // Corrects the initial coordinates x (cartesian coordinates)
143 // according to the given effect (inherited classes)
144 // roc represents the TPC read out chamber (offline numbering convention)
147 GetCorrection(x,roc,dx);
148 for (Int_t j=0;j<3;++j) x[j]+=dx[j];
151 void AliTPCCorrection::CorrectPoint(const Float_t x[],const Short_t roc,Float_t xp[]) {
153 // Corrects the initial coordinates x (cartesian coordinates) and stores the new
154 // (distorted) coordinates in xp. The distortion is set according to the given effect (inherited classes)
155 // roc represents the TPC read out chamber (offline numbering convention)
158 GetCorrection(x,roc,dx);
159 for (Int_t j=0;j<3;++j) xp[j]=x[j]+dx[j];
162 void AliTPCCorrection::DistortPoint(Float_t x[],const Short_t roc) {
164 // Distorts the initial coordinates x (cartesian coordinates)
165 // according to the given effect (inherited classes)
166 // roc represents the TPC read out chamber (offline numbering convention)
169 GetDistortion(x,roc,dx);
170 for (Int_t j=0;j<3;++j) x[j]+=dx[j];
173 void AliTPCCorrection::DistortPoint(const Float_t x[],const Short_t roc,Float_t xp[]) {
175 // Distorts the initial coordinates x (cartesian coordinates) and stores the new
176 // (distorted) coordinates in xp. The distortion is set according to the given effect (inherited classes)
177 // roc represents the TPC read out chamber (offline numbering convention)
180 GetDistortion(x,roc,dx);
181 for (Int_t j=0;j<3;++j) xp[j]=x[j]+dx[j];
184 void AliTPCCorrection::GetCorrection(const Float_t /*x*/[],const Short_t /*roc*/,Float_t dx[]) {
186 // This function delivers the correction values dx in respect to the inital coordinates x
187 // roc represents the TPC read out chamber (offline numbering convention)
188 // Note: The dx is overwritten by the inherited effectice class ...
190 for (Int_t j=0;j<3;++j) { dx[j]=0.; }
193 void AliTPCCorrection::GetDistortion(const Float_t x[],const Short_t roc,Float_t dx[]) {
195 // This function delivers the distortion values dx in respect to the inital coordinates x
196 // roc represents the TPC read out chamber (offline numbering convention)
198 GetCorrection(x,roc,dx);
199 for (Int_t j=0;j<3;++j) dx[j]=-dx[j];
202 void AliTPCCorrection::Init() {
204 // Initialization funtion (not used at the moment)
208 void AliTPCCorrection::Update(const TTimeStamp &/*timeStamp*/) {
214 void AliTPCCorrection::Print(Option_t* /*option*/) const {
216 // Print function to check which correction classes are used
217 // option=="d" prints details regarding the setted magnitude
218 // option=="a" prints the C0 and C1 coefficents for calibration purposes
220 printf("TPC spacepoint correction: \"%s\"\n",GetTitle());
223 void AliTPCCorrection:: SetOmegaTauT1T2(Float_t /*omegaTau*/,Float_t /*t1*/,Float_t /*t2*/) {
225 // Virtual funtion to pass the wt values (might become event dependent) to the inherited classes
226 // t1 and t2 represent the "effective omegaTau" corrections and were measured in a dedicated
229 // SetOmegaTauT1T2(omegaTau, t1, t2);
232 TH2F* AliTPCCorrection::CreateHistoDRinXY(Float_t z,Int_t nx,Int_t ny) {
234 // Simple plot functionality.
235 // Returns a 2d hisogram which represents the corrections in radial direction (dr)
236 // in respect to position z within the XY plane.
237 // The histogramm has nx times ny entries.
240 TH2F *h=CreateTH2F("dr_xy",GetTitle(),"x [cm]","y [cm]","dr [cm]",
241 nx,-250.,250.,ny,-250.,250.);
244 Int_t roc=z>0.?0:18; // FIXME
245 for (Int_t iy=1;iy<=ny;++iy) {
246 x[1]=h->GetYaxis()->GetBinCenter(iy);
247 for (Int_t ix=1;ix<=nx;++ix) {
248 x[0]=h->GetXaxis()->GetBinCenter(ix);
249 GetCorrection(x,roc,dx);
250 Float_t r0=TMath::Sqrt((x[0] )*(x[0] )+(x[1] )*(x[1] ));
251 if (90.<=r0 && r0<=250.) {
252 Float_t r1=TMath::Sqrt((x[0]+dx[0])*(x[0]+dx[0])+(x[1]+dx[1])*(x[1]+dx[1]));
253 h->SetBinContent(ix,iy,r1-r0);
256 h->SetBinContent(ix,iy,0.);
262 TH2F* AliTPCCorrection::CreateHistoDRPhiinXY(Float_t z,Int_t nx,Int_t ny) {
264 // Simple plot functionality.
265 // Returns a 2d hisogram which represents the corrections in rphi direction (drphi)
266 // in respect to position z within the XY plane.
267 // The histogramm has nx times ny entries.
270 TH2F *h=CreateTH2F("drphi_xy",GetTitle(),"x [cm]","y [cm]","drphi [cm]",
271 nx,-250.,250.,ny,-250.,250.);
274 Int_t roc=z>0.?0:18; // FIXME
275 for (Int_t iy=1;iy<=ny;++iy) {
276 x[1]=h->GetYaxis()->GetBinCenter(iy);
277 for (Int_t ix=1;ix<=nx;++ix) {
278 x[0]=h->GetXaxis()->GetBinCenter(ix);
279 GetCorrection(x,roc,dx);
280 Float_t r0=TMath::Sqrt((x[0] )*(x[0] )+(x[1] )*(x[1] ));
281 if (90.<=r0 && r0<=250.) {
282 Float_t phi0=TMath::ATan2(x[1] ,x[0] );
283 Float_t phi1=TMath::ATan2(x[1]+dx[1],x[0]+dx[0]);
285 Float_t dphi=phi1-phi0;
286 if (dphi<TMath::Pi()) dphi+=TMath::TwoPi();
287 if (dphi>TMath::Pi()) dphi-=TMath::TwoPi();
289 h->SetBinContent(ix,iy,r0*dphi);
292 h->SetBinContent(ix,iy,0.);
298 TH2F* AliTPCCorrection::CreateHistoDRinZR(Float_t phi,Int_t nz,Int_t nr) {
300 // Simple plot functionality.
301 // Returns a 2d hisogram which represents the corrections in r direction (dr)
302 // in respect to angle phi within the ZR plane.
303 // The histogramm has nx times ny entries.
305 TH2F *h=CreateTH2F("dr_zr",GetTitle(),"z [cm]","r [cm]","dr [cm]",
306 nz,-250.,250.,nr,85.,250.);
308 for (Int_t ir=1;ir<=nr;++ir) {
309 Float_t radius=h->GetYaxis()->GetBinCenter(ir);
310 x[0]=radius*TMath::Cos(phi);
311 x[1]=radius*TMath::Sin(phi);
312 for (Int_t iz=1;iz<=nz;++iz) {
313 x[2]=h->GetXaxis()->GetBinCenter(iz);
314 Int_t roc=x[2]>0.?0:18; // FIXME
315 GetCorrection(x,roc,dx);
316 Float_t r0=TMath::Sqrt((x[0] )*(x[0] )+(x[1] )*(x[1] ));
317 Float_t r1=TMath::Sqrt((x[0]+dx[0])*(x[0]+dx[0])+(x[1]+dx[1])*(x[1]+dx[1]));
318 h->SetBinContent(iz,ir,r1-r0);
326 TH2F* AliTPCCorrection::CreateHistoDRPhiinZR(Float_t phi,Int_t nz,Int_t nr) {
328 // Simple plot functionality.
329 // Returns a 2d hisogram which represents the corrections in rphi direction (drphi)
330 // in respect to angle phi within the ZR plane.
331 // The histogramm has nx times ny entries.
333 TH2F *h=CreateTH2F("drphi_zr",GetTitle(),"z [cm]","r [cm]","drphi [cm]",
334 nz,-250.,250.,nr,85.,250.);
336 for (Int_t iz=1;iz<=nz;++iz) {
337 x[2]=h->GetXaxis()->GetBinCenter(iz);
338 Int_t roc=x[2]>0.?0:18; // FIXME
339 for (Int_t ir=1;ir<=nr;++ir) {
340 Float_t radius=h->GetYaxis()->GetBinCenter(ir);
341 x[0]=radius*TMath::Cos(phi);
342 x[1]=radius*TMath::Sin(phi);
343 GetCorrection(x,roc,dx);
344 Float_t r0=TMath::Sqrt((x[0] )*(x[0] )+(x[1] )*(x[1] ));
345 Float_t phi0=TMath::ATan2(x[1] ,x[0] );
346 Float_t phi1=TMath::ATan2(x[1]+dx[1],x[0]+dx[0]);
348 Float_t dphi=phi1-phi0;
349 if (dphi<TMath::Pi()) dphi+=TMath::TwoPi();
350 if (dphi>TMath::Pi()) dphi-=TMath::TwoPi();
352 h->SetBinContent(iz,ir,r0*dphi);
358 TH2F* AliTPCCorrection::CreateTH2F(const char *name,const char *title,
359 const char *xlabel,const char *ylabel,const char *zlabel,
360 Int_t nbinsx,Double_t xlow,Double_t xup,
361 Int_t nbinsy,Double_t ylow,Double_t yup) {
363 // Helper function to create a 2d histogramm of given size
369 while (gDirectory->FindObject(hname.Data())) {
376 TH2F *h=new TH2F(hname.Data(),title,
379 h->GetXaxis()->SetTitle(xlabel);
380 h->GetYaxis()->SetTitle(ylabel);
381 h->GetZaxis()->SetTitle(zlabel);
387 // Simple Interpolation functions: e.g. with bi(tri)cubic interpolations (not yet in TH2 and TH3)
389 void AliTPCCorrection::Interpolate2DEdistortion( const Int_t order, const Double_t r, const Double_t z,
390 const Double_t er[kNZ][kNR], Double_t &er_value )
393 // Interpolate table - 2D interpolation
395 Double_t save_er[10] ;
397 Search( kNZ, fgkZList, z, fJLow ) ;
398 Search( kNR, fgkRList, r, fKLow ) ;
399 if ( fJLow < 0 ) fJLow = 0 ; // check if out of range
400 if ( fKLow < 0 ) fKLow = 0 ;
401 if ( fJLow + order >= kNZ - 1 ) fJLow = kNZ - 1 - order ;
402 if ( fKLow + order >= kNR - 1 ) fKLow = kNR - 1 - order ;
404 for ( Int_t j = fJLow ; j < fJLow + order + 1 ; j++ ) {
405 save_er[j-fJLow] = Interpolate( &fgkRList[fKLow], &er[j][fKLow], order, r ) ;
407 er_value = Interpolate( &fgkZList[fJLow], save_er, order, z ) ;
412 Double_t AliTPCCorrection::Interpolate( const Double_t xArray[], const Double_t yArray[],
413 const Int_t order, const Double_t x )
416 // Interpolate function Y(x) using linear (order=1) or quadratic (order=2) interpolation.
420 if ( order == 2 ) { // Quadratic Interpolation = 2
421 y = (x-xArray[1]) * (x-xArray[2]) * yArray[0] / ( (xArray[0]-xArray[1]) * (xArray[0]-xArray[2]) ) ;
422 y += (x-xArray[2]) * (x-xArray[0]) * yArray[1] / ( (xArray[1]-xArray[2]) * (xArray[1]-xArray[0]) ) ;
423 y += (x-xArray[0]) * (x-xArray[1]) * yArray[2] / ( (xArray[2]-xArray[0]) * (xArray[2]-xArray[1]) ) ;
424 } else { // Linear Interpolation = 1
425 y = yArray[0] + ( yArray[1]-yArray[0] ) * ( x-xArray[0] ) / ( xArray[1] - xArray[0] ) ;
433 void AliTPCCorrection::Search( const Int_t n, const Double_t xArray[], const Double_t x, Int_t &low )
436 // Search an ordered table by starting at the most recently used point
439 Long_t middle, high ;
440 Int_t ascend = 0, increment = 1 ;
442 if ( xArray[n-1] >= xArray[0] ) ascend = 1 ; // Ascending ordered table if true
444 if ( low < 0 || low > n-1 ) {
445 low = -1 ; high = n ;
446 } else { // Ordered Search phase
447 if ( (Int_t)( x >= xArray[low] ) == ascend ) {
448 if ( low == n-1 ) return ;
450 while ( (Int_t)( x >= xArray[high] ) == ascend ) {
453 high = low + increment ;
454 if ( high > n-1 ) { high = n ; break ; }
457 if ( low == 0 ) { low = -1 ; return ; }
459 while ( (Int_t)( x < xArray[low] ) == ascend ) {
462 if ( increment >= high ) { low = -1 ; break ; }
463 else low = high - increment ;
468 while ( (high-low) != 1 ) { // Binary Search Phase
469 middle = ( high + low ) / 2 ;
470 if ( (Int_t)( x >= xArray[middle] ) == ascend )
476 if ( x == xArray[n-1] ) low = n-2 ;
477 if ( x == xArray[0] ) low = 0 ;
482 AliExternalTrackParam * AliTPCCorrection::FitDistortedTrack(AliExternalTrackParam & trackIn, Double_t refX, Int_t dir,TTreeSRedirector *pcstream){
484 // Fit the track parameters - without and with distortion
485 // 1. Space points in the TPC are simulated along the trajectory
486 // 2. Space points distorted
487 // 3. Fits the non distorted and distroted track to the reference plane at refX
488 // 4. For visualization and debugging purposes the space points and tracks can be stored in the tree - using the TTreeSRedirector functionality
490 // trackIn - input track parameters
491 // refX - reference X to fit the track
492 // dir - direction - out=1 or in=-1
493 // pcstream - debug streamer to check the results
495 // see AliExternalTrackParam.h documentation:
496 // track1.fP[0] - local y (rphi)
498 // track1.fP[2] - sinus of local inclination angle
499 // track1.fP[3] - tangent of deep angle
500 // track1.fP[4] - 1/pt
501 AliTPCROC * roc = AliTPCROC::Instance();
502 const Int_t npoints0=roc->GetNRows(0)+roc->GetNRows(36);
503 const Double_t kRTPC0 =roc->GetPadRowRadii(0,0);
504 const Double_t kRTPC1 =roc->GetPadRowRadii(36,roc->GetNRows(36)-1);
506 const Double_t kMaxSnp = 0.85;
507 const Double_t kSigmaY=0.1;
508 const Double_t kSigmaZ=0.1;
509 const Double_t kMass = TDatabasePDG::Instance()->GetParticle("pi+")->Mass();
511 AliExternalTrackParam track(trackIn); //
513 AliTrackPointArray pointArray0(npoints0);
514 AliTrackPointArray pointArray1(npoints0);
516 AliTrackerBase::PropagateTrackTo(&track,kRTPC0,kMass,3,kTRUE,kMaxSnp);
518 // simulate the track
520 Float_t covPoint[6]={0,0,0, kSigmaY*kSigmaY,0,kSigmaZ*kSigmaZ}; //covariance at the local frame
521 for (Double_t radius=kRTPC0; radius<kRTPC1; radius++){
522 AliTrackerBase::PropagateTrackTo(&track,radius,kMass,3,kTRUE,kMaxSnp);
524 AliTrackPoint pIn0; // space point
526 Int_t sector= (xyz[2]>0)? 0:18;
527 pointArray0.GetPoint(pIn0,npoints);
528 pointArray1.GetPoint(pIn1,npoints);
529 Double_t alpha = TMath::ATan2(xyz[1],xyz[0]);
530 Float_t distPoint[3]={xyz[0],xyz[1],xyz[2]};
531 DistortPoint(distPoint, sector);
532 pIn0.SetXYZ(xyz[0], xyz[1],xyz[2]);
533 pIn1.SetXYZ(distPoint[0], distPoint[1],distPoint[2]);
536 AliTrackPoint prot0 = pIn0.Rotate(alpha); // rotate to the local frame - non distoted point
537 AliTrackPoint prot1 = pIn1.Rotate(alpha); // rotate to the local frame - distorted point
538 prot0.SetXYZ(prot0.GetX(),prot0.GetY(), prot0.GetZ(),covPoint);
539 prot1.SetXYZ(prot1.GetX(),prot1.GetY(), prot1.GetZ(),covPoint);
540 pIn0=prot0.Rotate(-alpha); // rotate back to global frame
541 pIn1=prot1.Rotate(-alpha); // rotate back to global frame
542 pointArray0.AddPoint(npoints, &pIn0);
543 pointArray1.AddPoint(npoints, &pIn1);
545 if (npoints>=npoints0) break;
550 AliExternalTrackParam *track0=0;
551 AliExternalTrackParam *track1=0;
552 AliTrackPoint point1,point2,point3;
553 if (dir==1) { //make seed inner
554 pointArray0.GetPoint(point1,1);
555 pointArray0.GetPoint(point2,10);
556 pointArray0.GetPoint(point3,20);
558 if (dir==-1){ //make seed outer
559 pointArray0.GetPoint(point1,npoints-20);
560 pointArray0.GetPoint(point2,npoints-10);
561 pointArray0.GetPoint(point3,npoints-1);
563 track0 = AliTrackerBase::MakeSeed(point1, point2, point3);
564 track1 = AliTrackerBase::MakeSeed(point1, point2, point3);
567 for (Int_t jpoint=0; jpoint<npoints; jpoint++){
568 Int_t ipoint= (dir>0) ? ipoint: npoints-1-jpoint;
572 pointArray0.GetPoint(pIn0,ipoint);
573 pointArray1.GetPoint(pIn1,ipoint);
574 AliTrackPoint prot0 = pIn0.Rotate(track0->GetAlpha()); // rotate to the local frame - non distoted point
575 AliTrackPoint prot1 = pIn1.Rotate(track1->GetAlpha()); // rotate to the local frame - distorted point
577 AliTrackerBase::PropagateTrackTo(track0,prot0.GetX(),kMass,1,kFALSE,kMaxSnp);
578 AliTrackerBase::PropagateTrackTo(track1,prot1.GetX(),kMass,1,kFALSE,kMaxSnp);
581 Double_t pointPos[2]={0,0};
582 Double_t pointCov[3]={0,0,0};
583 pointPos[0]=prot0.GetY();//local y
584 pointPos[1]=prot0.GetZ();//local z
585 pointCov[0]=prot0.GetCov()[3];//simay^2
586 pointCov[1]=prot0.GetCov()[4];//sigmayz
587 pointCov[2]=prot0.GetCov()[5];//sigmaz^2
588 track0->Update(pointPos,pointCov);
590 pointPos[0]=prot1.GetY();//local y
591 pointPos[1]=prot1.GetZ();//local z
592 pointCov[0]=prot1.GetCov()[3];//simay^2
593 pointCov[1]=prot1.GetCov()[4];//sigmayz
594 pointCov[2]=prot1.GetCov()[5];//sigmaz^2
595 track1->Update(pointPos,pointCov);
598 AliTrackerBase::PropagateTrackTo(track0,refX,kMass,2.,kTRUE,kMaxSnp);
599 track1->Rotate(track0->GetAlpha());
600 track1->PropagateTo(track0->GetX(),AliTrackerBase::GetBz());
602 if (pcstream) (*pcstream)<<Form("fitDistort%s",GetName())<<
603 "point0.="<<&pointArray0<< // points
604 "point1.="<<&pointArray1<< // distorted points
605 "trackIn.="<<&track<< // original track
606 "track0.="<<track0<< // fitted track
607 "track1.="<<track1<< // fitted distorted track
609 new(&trackIn) AliExternalTrackParam(*track0);
618 TTree* AliTPCCorrection::CreateDistortionTree(Double_t step){
620 // create the distortion tree on a mesh with granularity given by step
621 // return the tree with distortions at given position
622 // Map is created on the mesh with given step size
624 TTreeSRedirector *pcstream = new TTreeSRedirector(Form("correction%s.root",GetName()));
626 for (Double_t x= -250; x<250; x+=step){
627 for (Double_t y= -250; y<250; y+=step){
628 Double_t r = TMath::Sqrt(x*x+y*y);
631 for (Double_t z= -250; z<250; z+=step){
632 Int_t roc=(z>0)?0:18;
636 Double_t phi = TMath::ATan2(y,x);
637 DistortPoint(xyz,roc);
638 Double_t r1 = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);
639 Double_t phi1 = TMath::ATan2(xyz[1],xyz[0]);
640 if ((phi1-phi)>TMath::Pi()) phi1-=TMath::Pi();
641 if ((phi1-phi)<-TMath::Pi()) phi1+=TMath::Pi();
642 Double_t dx = xyz[0]-x;
643 Double_t dy = xyz[1]-y;
644 Double_t dz = xyz[2]-z;
646 Double_t drphi=(phi1-phi)*r;
647 (*pcstream)<<"distortion"<<
648 "x="<<x<< // original position
653 "x1="<<xyz[0]<< // distorted position
659 "dx="<<dx<< // delta position
669 TFile f(Form("correction%s.root",GetName()));
670 TTree * tree = (TTree*)f.Get("distortion");
671 TTree * tree2= tree->CopyTree("1");
672 tree2->SetName(Form("dist%s",GetName()));
673 tree2->SetDirectory(0);
681 void AliTPCCorrection::MakeTrackDistortionTree(TTree *tinput, Int_t dtype, Int_t ptype, TObjArray * corrArray, Int_t step, Bool_t debug ){
684 // For each partial correction (specified in array) and given track topology (phi, theta, snp, refX)
685 // calculates partial distortions
686 // Partial distortion is stored in the resulting tree
687 // Output is storred in the file distortion_<dettype>_<partype>.root
688 // Partial distortion is stored with the name given by correction name
691 // Parameters of function:
692 // input - input tree
693 // dtype - distortion type 0 - ITSTPC, 1 -TPCTRD, 2 - TPCvertex
694 // ppype - parameter type
695 // corrArray - array with partial corrections
696 // step - skipe entries - if 1 all entries processed - it is slow
697 // debug 0 if debug on also space points dumped - it is slow
698 const Int_t kMinEntries=50;
699 Double_t phi,theta, snp, mean,rms, entries;
700 tinput->SetBranchAddress("theta",&theta);
701 tinput->SetBranchAddress("phi", &phi);
702 tinput->SetBranchAddress("snp",&snp);
703 tinput->SetBranchAddress("mean",&mean);
704 tinput->SetBranchAddress("rms",&rms);
705 tinput->SetBranchAddress("entries",&entries);
706 TTreeSRedirector *pcstream = new TTreeSRedirector(Form("distortion%d_%d.root",dtype,ptype));
708 Int_t nentries=tinput->GetEntries();
709 Int_t ncorr=corrArray->GetEntries();
710 Double_t corrections[100]; //
712 Double_t cov[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0};
715 if (dtype==0) {refX=85; dir=-1;}
716 if (dtype==1) {refX=245; dir=1;}
717 if (dtype==2) {refX=0; dir=-1;}
719 for (Int_t ientry=0; ientry<nentries; ientry+=step){
720 tinput->GetEntry(ientry);
725 tPar[4]=0.00001; // should be calculated - non equal to 0
727 cout<<"Entry\n\n"<<ientry<<endl;
728 cout<<"dtype="<<dtype<< // detector match type
729 "ptype="<<ptype<< // parameter type
730 "theta="<<theta<< // theta
733 "mean="<<mean<< // mean dist value
735 "entries="<<entries<<endl; // number of entries in bin
737 if (TMath::Abs(snp)>0.251) continue;
739 "dtype="<<dtype<< // detector match type
740 "ptype="<<ptype<< // parameter type
741 "theta="<<theta<< // theta
744 "mean="<<mean<< // mean dist value
746 "entries="<<entries;// number of entries in bin
748 for (Int_t icorr=0; icorr<ncorr; icorr++) {
749 AliTPCCorrection *corr = (AliTPCCorrection*)corrArray->At(icorr);
750 corrections[icorr]=0;
751 if (entries>kMinEntries){
752 AliExternalTrackParam trackIn(refX,phi,tPar,cov);
753 AliExternalTrackParam *trackOut = 0;
754 if (debug) trackOut=corr->FitDistortedTrack(trackIn, refX, dir,pcstream);
755 if (!debug) trackOut=corr->FitDistortedTrack(trackIn, refX, dir,0);
756 corrections[icorr]= trackOut->GetParameter()[ptype]-trackIn.GetParameter()[ptype];
760 Form("%s=",corr->GetName())<<corrections[icorr]; // dump correction value
762 (*pcstream)<<"fit"<<"\n";
770 void AliTPCCorrection::StoreInOCDB(Int_t startRun, Int_t endRun, const char *comment){
772 // Store object in the OCDB
773 // By default the object is stored in the current directory
774 // default comment consit of user name and the date
776 TString ocdbStorage="";
777 ocdbStorage+="local://"+gSystem->GetFromPipe("pwd")+"/OCDB";
778 AliCDBMetaData *metaData= new AliCDBMetaData();
779 metaData->SetObjectClassName("AliTPCCorrection");
780 metaData->SetResponsible("Marian Ivanov");
781 metaData->SetBeamPeriod(1);
782 metaData->SetAliRootVersion("05-25-01"); //root version
783 TString userName=gSystem->GetFromPipe("echo $USER");
784 TString date=gSystem->GetFromPipe("date");
786 if (!comment) metaData->SetComment(Form("Space point distortion calibration\n User: %s\n Data%s",userName.Data(),date.Data()));
787 if (comment) metaData->SetComment(comment);
789 id1=new AliCDBId("TPC/Calib/Correction", startRun, endRun);
790 AliCDBStorage* gStorage = AliCDBManager::Instance()->GetStorage(ocdbStorage);
791 gStorage->Put(this, (*id1), metaData);