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 //-------------------------------------------------------
17 // Implementation of the TPC transformation class
19 // Origin: Marian Ivanov Marian.Ivanov@cern.ch
22 // Class for tranformation of the coordinate frame
24 // local coordinate frame (sector, padrow, pad, timebine) ==>
25 // rotated global (tracking) cooridnate frame (sector, lx,ly,lz)
27 // Unisochronity - (substract time0 - pad by pad)
28 // Drift velocity - Currently common drift velocity - functionality of AliTPCParam
31 // Time of flight correction -
32 // - Depends on the vertex position
36 // AliTPCclustererMI::AddCluster
37 // AliTPCtrackerMI::Transform
39 //-------------------------------------------------------
42 cdb=AliCDBManager::Instance()
43 cdb->SetDefaultStorage("local:///u/mmager/mycalib1")
44 c=AliTPCcalibDB::Instance()
46 Double_t x[]={1.0,2.0,3.0}
49 trafo.Transform(x,i,0,1)
54 #include "AliTPCROC.h"
55 #include "AliTPCCalPad.h"
56 #include "AliTPCCalROC.h"
57 #include "AliTPCcalibDB.h"
58 #include "AliTPCParam.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>
69 ClassImp(AliTPCTransform)
72 AliTPCTransform::AliTPCTransform():
74 fCurrentRecoParam(0), //! current reconstruction parameters
75 fCurrentRun(0), //! current run
76 fCurrentTimeStamp(0) //! current time stamp
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);
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
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);
109 AliTPCTransform::~AliTPCTransform() {
115 void AliTPCTransform::SetPrimVertex(Double_t *vtx){
125 void AliTPCTransform::Transform(Double_t *x,Int_t *i,UInt_t /*time*/,
126 Int_t /*coordinateType*/) {
127 // input: x[0] - pad row
131 // output: x[0] - x (all in the rotated global coordinate frame)
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
141 Int_t row=TMath::Nint(x[0]);
142 Int_t pad=TMath::Nint(x[1]);
144 AliTPCcalibDB* calib=AliTPCcalibDB::Instance();
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();
152 AliFatal("Time unisochronity missing");
156 AliFatal("Parameters missing");
160 // Apply Time0 correction - Pad by pad fluctuation
162 x[2]-=time0TPC->GetCalROC(sector)->GetValue(row,pad);
164 // Tranform from pad - time coordinate system to the rotated global (tracking) system
166 Local2RotatedGlobal(sector,x);
171 //TODO: calib->GetParameters()->GetClusterMatrix(sector)->LocalToMaster(x,xx);
172 RotatedGlobal2Global(sector,x);
175 // old ExB correction
177 if(fCurrentRecoParam&&fCurrentRecoParam->GetUseExBCorrection()) {
179 calib->GetExB()->Correct(x,xx);
189 // new composed correction - will replace soon ExB correction
191 if(fCurrentRecoParam&&fCurrentRecoParam->GetUseComposedCorrection()&&correction) {
192 Float_t distPoint[3]={xx[0],xx[1],xx[2]};
193 correction->CorrectPoint(distPoint, sector);
201 // Time of flight correction
203 if (fCurrentRecoParam&&fCurrentRecoParam->GetUseTOFCorrection()){
204 const Int_t kNIS=param->GetNInnerSector(), kNOS=param->GetNOuterSector();
207 sign = (sector < kNIS/2) ? 1 : -1;
209 sign = ((sector-kNIS) < kNOS/2) ? 1 : -1;
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();
227 Global2RotatedGlobal(sector,xx);
230 // Apply non linear distortion correction
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);
242 x[0]=xx[0];x[1]=xx[1];x[2]=xx[2];
245 void AliTPCTransform::Local2RotatedGlobal(Int_t sector, Double_t *x) const {
248 // Tranform coordinate from
249 // row, pad, time to x,y,z
252 // Current implementation - common drift velocity - for full chamber
253 // TODO: use a map or parametrisation!
257 const Int_t kMax =60; // cache for 60 seconds
258 static Int_t lastStamp=-1; //cached values
259 static Double_t lastCorr = 1;
261 AliTPCcalibDB* calib=AliTPCcalibDB::Instance();
262 AliTPCParam * param = calib->GetParameters();
263 AliTPCCalibVdrift *driftCalib = AliTPCcalibDB::Instance()->GetVdrift(fCurrentRun);
264 Double_t driftCorr = 1.;
267 // caching drift correction - temp. fix
268 // Extremally slow procedure
269 if ( TMath::Abs((lastStamp)-Int_t(fCurrentTimeStamp))<kMax){
270 driftCorr = lastCorr;
272 driftCorr = 1.+(driftCalib->GetPTRelative(fCurrentTimeStamp,0)+ driftCalib->GetPTRelative(fCurrentTimeStamp,1))*0.5;
274 lastStamp=fCurrentTimeStamp;
279 // simple caching non thread save
280 static Double_t vdcorrectionTime=1;
281 static Double_t time0corrTime=0;
282 static Int_t lastStampT=-1;
284 if (lastStampT!=(Int_t)fCurrentTimeStamp){
285 lastStampT=fCurrentTimeStamp;
286 if(fCurrentRecoParam&&fCurrentRecoParam->GetUseDriftCorrectionTime()>0) {
287 vdcorrectionTime = (1+AliTPCcalibDB::Instance()->
288 GetVDriftCorrectionTime(fCurrentTimeStamp,
291 fCurrentRecoParam->GetUseDriftCorrectionTime()));
292 time0corrTime= AliTPCcalibDB::Instance()->
293 GetTime0CorrectionTime(fCurrentTimeStamp,
296 fCurrentRecoParam->GetUseDriftCorrectionTime());
299 if(fCurrentRecoParam&&fCurrentRecoParam->GetUseDriftCorrectionGY()>0) {
301 AliTPCROC::Instance()->GetPositionGlobal(sector, TMath::Nint(x[0]) ,TMath::Nint(x[1]), xyzPad);
303 Double_t corrGy= (1+(xyzPad[1])*AliTPCcalibDB::Instance()->
304 GetVDriftCorrectionGy(fCurrentTimeStamp,
305 AliTPCcalibDB::Instance()->GetRun(),
307 fCurrentRecoParam->GetUseDriftCorrectionGY()));
308 vdcorrectionTime *=corrGy;
314 AliFatal("Parameters missing");
316 Int_t row=TMath::Nint(x[0]);
317 // Int_t pad=TMath::Nint(x[1]);
319 const Int_t kNIS=param->GetNInnerSector(), kNOS=param->GetNOuterSector();
321 Double_t zwidth = param->GetZWidth()*driftCorr;
322 if (AliTPCRecoParam:: GetUseTimeCalibration()) zwidth*=vdcorrectionTime;
323 Double_t padWidth = 0;
324 Double_t padLength = 0;
328 maxPad = param->GetNPadsLow(row);
329 sign = (sector < kNIS/2) ? 1 : -1;
330 padLength = param->GetPadPitchLength(sector,row);
331 padWidth = param->GetPadPitchWidth(sector);
333 maxPad = param->GetNPadsUp(row);
334 sign = ((sector-kNIS) < kNOS/2) ? 1 : -1;
335 padLength = param->GetPadPitchLength(sector,row);
336 padWidth = param->GetPadPitchWidth(sector);
340 x[0] = param->GetPadRowRadii(sector,row); // padrow X position - ideal
344 x[1]=(x[1]-0.5*maxPad)*padWidth;
345 // pads are mirrorred on C-side
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();
359 //for TPC standalone runs no ctp info
360 Double_t delay = ctp->GetDelayL1L0()*0.000000025;
361 x[2]-=delay/param->GetTSample();
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]);
371 void AliTPCTransform::RotatedGlobal2Global(Int_t sector,Double_t *x) const {
373 // transform possition rotated global to the global
376 GetCosAndSin(sector,cos,sin);
378 x[0]= cos*tmp-sin*x[1];
379 x[1]=+sin*tmp+cos*x[1];
382 void AliTPCTransform::Global2RotatedGlobal(Int_t sector,Double_t *x) const {
384 // tranform possition Global2RotatedGlobal
387 GetCosAndSin(sector,cos,sin);
389 x[0]= cos*tmp+sin*x[1];
390 x[1]= -sin*tmp+cos*x[1];
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];
400 void AliTPCTransform::ApplyTransformations(Double_t */*xyz*/, Int_t /*volID*/){
402 // Modify global position
403 // xyz - global xyz position
404 // volID - volID of detector (sector number)