]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCTransform.cxx
M AliTPCcalibBase.h - make magnetic field persistent
[u/mrichter/AliRoot.git] / TPC / AliTPCTransform.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15
16 //-------------------------------------------------------
17 //          Implementation of the TPC transformation class
18 //
19 //   Origin: Marian Ivanov   Marian.Ivanov@cern.ch
20 //           Magnus Mager
21 //
22 //   Class for tranformation of the coordinate frame
23 //   Transformation  
24 //    local coordinate frame (sector, padrow, pad, timebine) ==>
25 //    rotated global (tracking) cooridnate frame (sector, lx,ly,lz)
26 //
27 //    Unisochronity  - (substract time0 - pad by pad)
28 //    Drift velocity - Currently common drift velocity - functionality of AliTPCParam
29 //    ExB effect     - 
30 //
31 //    Time of flight correction -
32 //                   - Depends on the vertex position
33 //                   - by default 
34 //                           
35 //    Usage:
36 //          AliTPCclustererMI::AddCluster
37 //          AliTPCtrackerMI::Transform
38 //    
39 //-------------------------------------------------------
40
41 /* To test it:
42    cdb=AliCDBManager::Instance()
43    cdb->SetDefaultStorage("local:///u/mmager/mycalib1")
44    c=AliTPCcalibDB::Instance()
45    c->SetRun(0)
46    Double_t x[]={1.0,2.0,3.0}
47    Int_t i[]={4}
48    AliTPCTransform trafo
49    trafo.Transform(x,i,0,1)
50  */
51
52 /* $Id$ */
53
54 #include "AliTPCROC.h"
55 #include "AliTPCCalPad.h"
56 #include "AliTPCCalROC.h"
57 #include "AliTPCcalibDB.h"
58 #include "AliTPCParam.h"
59 #include "TMath.h"
60 #include "AliLog.h"
61 #include "AliTPCExB.h"
62 #include "AliTPCCorrection.h"
63 #include "TGeoMatrix.h"
64 #include "AliTPCRecoParam.h"
65 #include "AliTPCCalibVdrift.h"
66 #include "AliTPCTransform.h"
67 #include <AliCTPTimeParams.h>
68
69 ClassImp(AliTPCTransform)
70
71
72 AliTPCTransform::AliTPCTransform():
73   AliTransform(),
74   fCurrentRecoParam(0),       //! current reconstruction parameters
75   fCurrentRun(0),             //! current run
76   fCurrentTimeStamp(0)        //! current time stamp   
77 {
78   //
79   // Speed it up a bit!
80   //
81   for (Int_t i=0;i<18;++i) {
82     Double_t alpha=TMath::DegToRad()*(10.+20.*(i%18));
83     fSins[i]=TMath::Sin(alpha);
84     fCoss[i]=TMath::Cos(alpha);
85   }
86   fPrimVtx[0]=0;
87   fPrimVtx[1]=0;
88   fPrimVtx[2]=0;
89 }
90 AliTPCTransform::AliTPCTransform(const AliTPCTransform& transform):
91   AliTransform(transform),
92   fCurrentRecoParam(transform.fCurrentRecoParam),       //! current reconstruction parameters
93   fCurrentRun(transform.fCurrentRun),             //! current run
94   fCurrentTimeStamp(transform.fCurrentTimeStamp)        //! current time stamp   
95 {
96   //
97   // Speed it up a bit!
98   //
99   for (Int_t i=0;i<18;++i) {
100     Double_t alpha=TMath::DegToRad()*(10.+20.*(i%18));
101     fSins[i]=TMath::Sin(alpha);
102     fCoss[i]=TMath::Cos(alpha);
103   }
104   fPrimVtx[0]=0;
105   fPrimVtx[1]=0;
106   fPrimVtx[2]=0;
107 }
108
109 AliTPCTransform::~AliTPCTransform() {
110   //
111   // Destructor
112   //
113 }
114
115 void AliTPCTransform::SetPrimVertex(Double_t *vtx){
116   //
117   //
118   //
119   fPrimVtx[0]=vtx[0];
120   fPrimVtx[1]=vtx[1];
121   fPrimVtx[2]=vtx[2];
122 }
123
124
125 void AliTPCTransform::Transform(Double_t *x,Int_t *i,UInt_t /*time*/,
126                                 Int_t /*coordinateType*/) {
127   // input: x[0] - pad row
128   //        x[1] - pad 
129   //        x[2] - time in us
130   //        i[0] - sector
131   // output: x[0] - x (all in the rotated global coordinate frame)
132   //         x[1] - y
133   //         x[2] - z
134   //
135   //  primvtx     - position of the primary vertex
136   //                used for the TOF correction
137   //                TOF of particle calculated assuming the speed-of-light and 
138   //                line approximation  
139   //
140   
141   Int_t row=TMath::Nint(x[0]);
142   Int_t pad=TMath::Nint(x[1]);
143   Int_t sector=i[0];
144   AliTPCcalibDB*  calib=AliTPCcalibDB::Instance();  
145   //
146   AliTPCCalPad * time0TPC = calib->GetPadTime0(); 
147   AliTPCCalPad * distortionMapY = calib->GetDistortionMap(0); 
148   AliTPCCalPad * distortionMapZ = calib->GetDistortionMap(1); 
149   AliTPCParam  * param    = calib->GetParameters(); 
150   AliTPCCorrection * correction = calib->GetTPCComposedCorrection();
151   if (!time0TPC){
152     AliFatal("Time unisochronity missing");
153   }
154
155   if (!param){
156     AliFatal("Parameters missing");
157   }
158
159   Double_t xx[3];
160   //  Apply Time0 correction - Pad by pad fluctuation
161   //
162   x[2]-=time0TPC->GetCalROC(sector)->GetValue(row,pad);
163   //
164   // Tranform from pad - time coordinate system to the rotated global (tracking) system
165   //
166   Local2RotatedGlobal(sector,x);
167   //
168   //
169   //
170   // Alignment
171   //TODO:  calib->GetParameters()->GetClusterMatrix(sector)->LocalToMaster(x,xx);
172   RotatedGlobal2Global(sector,x);
173   
174   //
175   // old ExB correction 
176   //
177   if(fCurrentRecoParam&&fCurrentRecoParam->GetUseExBCorrection()) {
178
179     calib->GetExB()->Correct(x,xx);
180
181   } else {
182
183     xx[0] = x[0];
184     xx[1] = x[1];
185     xx[2] = x[2];
186   }
187
188   //
189   // new composed  correction  - will replace soon ExB correction
190   //
191   if(fCurrentRecoParam&&fCurrentRecoParam->GetUseComposedCorrection()&&correction) {
192     Float_t distPoint[3]={xx[0],xx[1],xx[2]};
193     correction->CorrectPoint(distPoint, sector);
194     xx[0]=distPoint[0];
195     xx[1]=distPoint[1];
196     xx[2]=distPoint[2];
197   } 
198
199
200   //
201   // Time of flight correction
202   // 
203   if (fCurrentRecoParam&&fCurrentRecoParam->GetUseTOFCorrection()){
204     const Int_t kNIS=param->GetNInnerSector(), kNOS=param->GetNOuterSector(); 
205     Float_t sign=1;
206     if (sector < kNIS) {
207       sign = (sector < kNIS/2) ? 1 : -1;
208     } else {
209       sign = ((sector-kNIS) < kNOS/2) ? 1 : -1;
210     }
211     Float_t deltaDr =0;
212     Float_t dist=0;
213     dist+=(fPrimVtx[0]-x[0])*(fPrimVtx[0]-x[0]);
214     dist+=(fPrimVtx[1]-x[1])*(fPrimVtx[1]-x[1]);
215     dist+=(fPrimVtx[2]-x[2])*(fPrimVtx[2]-x[2]);
216     dist = TMath::Sqrt(dist);
217     // drift length correction because of TOF
218     // the drift velocity is in cm/s therefore multiplication by 0.01
219     deltaDr = (dist*(0.01*param->GetDriftV()))/TMath::C(); 
220     xx[2]+=sign*deltaDr;
221   }
222   //
223   //
224   //
225
226   //
227   Global2RotatedGlobal(sector,xx);
228
229   //
230   // Apply non linear distortion correction  
231   //
232   if (distortionMapY ){
233     //can be switch on for each dimension separatelly
234     if (fCurrentRecoParam->GetUseFieldCorrection()&0x2) 
235       xx[1]-=distortionMapY->GetCalROC(sector)->GetValue(row,pad);
236     if (fCurrentRecoParam->GetUseFieldCorrection()&0x4) 
237       xx[2]-=distortionMapZ->GetCalROC(sector)->GetValue(row,pad);
238   }
239
240
241   //
242   x[0]=xx[0];x[1]=xx[1];x[2]=xx[2];
243 }
244
245 void AliTPCTransform::Local2RotatedGlobal(Int_t sector, Double_t *x) const {
246   //
247   //  
248   // Tranform coordinate from  
249   // row, pad, time to x,y,z
250   //
251   // Drift Velocity 
252   // Current implementation - common drift velocity - for full chamber
253   // TODO: use a map or parametrisation!
254   //
255   //  
256   //
257   const  Int_t kMax =60;  // cache for 60 seconds
258   static Int_t lastStamp=-1;  //cached values
259   static Double_t lastCorr = 1;
260   //
261   AliTPCcalibDB*  calib=AliTPCcalibDB::Instance();
262   AliTPCParam  * param    = calib->GetParameters(); 
263   AliTPCCalibVdrift *driftCalib = AliTPCcalibDB::Instance()->GetVdrift(fCurrentRun);
264   Double_t driftCorr = 1.;
265   if (driftCalib){
266     //
267     // caching drift correction - temp. fix
268     // Extremally slow procedure
269     if ( TMath::Abs((lastStamp)-Int_t(fCurrentTimeStamp))<kMax){
270       driftCorr = lastCorr;
271     }else{
272       driftCorr = 1.+(driftCalib->GetPTRelative(fCurrentTimeStamp,0)+ driftCalib->GetPTRelative(fCurrentTimeStamp,1))*0.5;
273       lastCorr=driftCorr;
274       lastStamp=fCurrentTimeStamp;
275       
276     }
277   }
278   //
279   // simple caching non thread save
280   static Double_t vdcorrectionTime=1;
281   static Double_t time0corrTime=0;
282   static Int_t    lastStampT=-1;
283   //
284   if (lastStampT!=(Int_t)fCurrentTimeStamp){
285     lastStampT=fCurrentTimeStamp;
286     if(fCurrentRecoParam&&fCurrentRecoParam->GetUseDriftCorrectionTime()>0) {
287       vdcorrectionTime = (1+AliTPCcalibDB::Instance()->
288                           GetVDriftCorrectionTime(fCurrentTimeStamp, 
289                                                   fCurrentRun,
290                                                   sector%36>=18,
291                                                   fCurrentRecoParam->GetUseDriftCorrectionTime()));                       
292       time0corrTime= AliTPCcalibDB::Instance()->
293         GetTime0CorrectionTime(fCurrentTimeStamp, 
294                                fCurrentRun,
295                                sector%36>=18,
296                                fCurrentRecoParam->GetUseDriftCorrectionTime()); 
297     }
298     //
299     if(fCurrentRecoParam&&fCurrentRecoParam->GetUseDriftCorrectionGY()>0) {
300       Float_t xyzPad[3];
301       AliTPCROC::Instance()->GetPositionGlobal(sector, TMath::Nint(x[0]) ,TMath::Nint(x[1]), xyzPad);
302       
303       Double_t corrGy= (1+(xyzPad[1])*AliTPCcalibDB::Instance()->
304                         GetVDriftCorrectionGy(fCurrentTimeStamp, 
305                                               AliTPCcalibDB::Instance()->GetRun(),
306                                               sector%36>=18,
307                                               fCurrentRecoParam->GetUseDriftCorrectionGY()));
308       vdcorrectionTime *=corrGy;
309     }
310   }
311
312
313   if (!param){
314     AliFatal("Parameters missing");
315   }
316   Int_t row=TMath::Nint(x[0]);
317   //  Int_t pad=TMath::Nint(x[1]);
318   //
319   const Int_t kNIS=param->GetNInnerSector(), kNOS=param->GetNOuterSector();
320   Double_t sign = 1.;
321   Double_t zwidth    = param->GetZWidth()*driftCorr;
322   if (AliTPCRecoParam:: GetUseTimeCalibration()) zwidth*=vdcorrectionTime;
323   Double_t padWidth  = 0;
324   Double_t padLength = 0;
325   Double_t    maxPad    = 0;
326   //
327   if (sector < kNIS) {
328     maxPad = param->GetNPadsLow(row);
329     sign = (sector < kNIS/2) ? 1 : -1;
330     padLength = param->GetPadPitchLength(sector,row);
331     padWidth = param->GetPadPitchWidth(sector);
332   } else {
333     maxPad = param->GetNPadsUp(row);
334     sign = ((sector-kNIS) < kNOS/2) ? 1 : -1;
335     padLength = param->GetPadPitchLength(sector,row);
336     padWidth  = param->GetPadPitchWidth(sector);
337   }
338   //
339   // X coordinate
340   x[0] = param->GetPadRowRadii(sector,row);  // padrow X position - ideal
341   //
342   // Y coordinate
343   //
344   x[1]=(x[1]-0.5*maxPad)*padWidth;
345   // pads are mirrorred on C-side
346   if (sector%36>17){
347     x[1]*=-1;
348   }
349   
350   //
351   
352   //
353   // Z coordinate
354   //
355   if (AliTPCcalibDB::Instance()->IsTrgL0()){
356     // by defualt we assume L1 trigger is used - make a correction in case of  L0
357     AliCTPTimeParams* ctp = AliTPCcalibDB::Instance()->GetCTPTimeParams();
358     if (ctp){
359       //for TPC standalone runs no ctp info
360       Double_t delay = ctp->GetDelayL1L0()*0.000000025;
361       x[2]-=delay/param->GetTSample();
362     }
363   }
364   x[2]-= param->GetNTBinsL1();
365   x[2]*= zwidth;  // tranform time bin to the distance to the ROC
366   x[2]-= 3.*param->GetZSigma() + time0corrTime;
367   // subtract the time offsets
368   x[2] = sign*( param->GetZLength(sector) - x[2]);
369 }
370
371 void AliTPCTransform::RotatedGlobal2Global(Int_t sector,Double_t *x) const {
372   //
373   // transform possition rotated global to the global
374   //
375   Double_t cos,sin;
376   GetCosAndSin(sector,cos,sin);
377   Double_t tmp=x[0];
378   x[0]= cos*tmp-sin*x[1];
379   x[1]=+sin*tmp+cos*x[1];
380 }
381
382 void AliTPCTransform::Global2RotatedGlobal(Int_t sector,Double_t *x) const {
383   //
384   // tranform possition Global2RotatedGlobal
385   //
386   Double_t cos,sin;
387   GetCosAndSin(sector,cos,sin);
388   Double_t tmp=x[0];
389   x[0]= cos*tmp+sin*x[1];
390   x[1]= -sin*tmp+cos*x[1];
391 }
392
393 void AliTPCTransform::GetCosAndSin(Int_t sector,Double_t &cos,
394                                           Double_t &sin) const {
395   cos=fCoss[sector%18];
396   sin=fSins[sector%18];
397 }
398
399
400 void AliTPCTransform::ApplyTransformations(Double_t */*xyz*/, Int_t /*volID*/){
401   //
402   // Modify global position
403   // xyz    - global xyz position
404   // volID  - volID of detector (sector number)
405   //
406   //
407   
408 }