Bastian's Task for Jet Fragmentation, to be merged with other FF tasks
[u/mrichter/AliRoot.git] / TPC / AliTPCTransform.cxx
CommitLineData
022ee144 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
66954e3f 23// Transformation
022ee144 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//
003b43ed 31// Time of flight correction -
32// - Depends on the vertex position
33// - by default
34//
022ee144 35// Usage:
36// AliTPCclustererMI::AddCluster
37// AliTPCtrackerMI::Transform
38//
39//-------------------------------------------------------
c1bdda91 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
022ee144 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"
cf5b0aa0 62#include "AliTPCCorrection.h"
66954e3f 63#include "TGeoMatrix.h"
9430b11a 64#include "AliTPCRecoParam.h"
65#include "AliTPCCalibVdrift.h"
022ee144 66#include "AliTPCTransform.h"
1e6337b1 67#include <AliCTPTimeParams.h>
022ee144 68
66954e3f 69ClassImp(AliTPCTransform)
022ee144 70
71
9430b11a 72AliTPCTransform::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}
90AliTPCTransform::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
003b43ed 95{
24db6af7 96 //
c1bdda91 97 // Speed it up a bit!
24db6af7 98 //
c1bdda91 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 }
003b43ed 104 fPrimVtx[0]=0;
105 fPrimVtx[1]=0;
106 fPrimVtx[2]=0;
c1bdda91 107}
108
109AliTPCTransform::~AliTPCTransform() {
24db6af7 110 //
111 // Destructor
112 //
c1bdda91 113}
114
003b43ed 115void 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
24db6af7 125void AliTPCTransform::Transform(Double_t *x,Int_t *i,UInt_t /*time*/,
003b43ed 126 Int_t /*coordinateType*/) {
24db6af7 127 // input: x[0] - pad row
128 // x[1] - pad
c1bdda91 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
ecc5dd8f 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
24db6af7 141 Int_t row=TMath::Nint(x[0]);
142 Int_t pad=TMath::Nint(x[1]);
c1bdda91 143 Int_t sector=i[0];
9430b11a 144 AliTPCcalibDB* calib=AliTPCcalibDB::Instance();
24db6af7 145 //
146 AliTPCCalPad * time0TPC = calib->GetPadTime0();
2293155b 147 AliTPCCalPad * distortionMapY = calib->GetDistortionMap(0);
148 AliTPCCalPad * distortionMapZ = calib->GetDistortionMap(1);
4486a91f 149 AliTPCCalPad * distortionMapR = calib->GetDistortionMap(2);
24db6af7 150 AliTPCParam * param = calib->GetParameters();
cf5b0aa0 151 AliTPCCorrection * correction = calib->GetTPCComposedCorrection();
24db6af7 152 if (!time0TPC){
153 AliFatal("Time unisochronity missing");
154 }
c1bdda91 155
24db6af7 156 if (!param){
157 AliFatal("Parameters missing");
158 }
c1bdda91 159
24db6af7 160 Double_t xx[3];
161 // Apply Time0 correction - Pad by pad fluctuation
162 //
163 x[2]-=time0TPC->GetCalROC(sector)->GetValue(row,pad);
164 //
165 // Tranform from pad - time coordinate system to the rotated global (tracking) system
166 //
167 Local2RotatedGlobal(sector,x);
168 //
169 //
170 //
c1bdda91 171 // Alignment
172 //TODO: calib->GetParameters()->GetClusterMatrix(sector)->LocalToMaster(x,xx);
c1bdda91 173 RotatedGlobal2Global(sector,x);
cf5b0aa0 174
24db6af7 175 //
cf5b0aa0 176 // old ExB correction
24db6af7 177 //
3ce45991 178 if(fCurrentRecoParam&&fCurrentRecoParam->GetUseExBCorrection()) {
179
180 calib->GetExB()->Correct(x,xx);
181
182 } else {
183
184 xx[0] = x[0];
185 xx[1] = x[1];
186 xx[2] = x[2];
187 }
188
ecc5dd8f 189 //
cf5b0aa0 190 // new composed correction - will replace soon ExB correction
191 //
192 if(fCurrentRecoParam&&fCurrentRecoParam->GetUseComposedCorrection()&&correction) {
193 Float_t distPoint[3]={xx[0],xx[1],xx[2]};
194 correction->CorrectPoint(distPoint, sector);
195 xx[0]=distPoint[0];
196 xx[1]=distPoint[1];
197 xx[2]=distPoint[2];
198 }
199
200
201 //
ecc5dd8f 202 // Time of flight correction
003b43ed 203 //
9430b11a 204 if (fCurrentRecoParam&&fCurrentRecoParam->GetUseTOFCorrection()){
205 const Int_t kNIS=param->GetNInnerSector(), kNOS=param->GetNOuterSector();
206 Float_t sign=1;
207 if (sector < kNIS) {
208 sign = (sector < kNIS/2) ? 1 : -1;
209 } else {
210 sign = ((sector-kNIS) < kNOS/2) ? 1 : -1;
211 }
212 Float_t deltaDr =0;
213 Float_t dist=0;
214 dist+=(fPrimVtx[0]-x[0])*(fPrimVtx[0]-x[0]);
215 dist+=(fPrimVtx[1]-x[1])*(fPrimVtx[1]-x[1]);
216 dist+=(fPrimVtx[2]-x[2])*(fPrimVtx[2]-x[2]);
217 dist = TMath::Sqrt(dist);
218 // drift length correction because of TOF
219 // the drift velocity is in cm/s therefore multiplication by 0.01
220 deltaDr = (dist*(0.01*param->GetDriftV()))/TMath::C();
221 xx[2]+=sign*deltaDr;
ecc5dd8f 222 }
9430b11a 223 //
224 //
225 //
226
ecc5dd8f 227 //
c1bdda91 228 Global2RotatedGlobal(sector,xx);
2293155b 229
230 //
231 // Apply non linear distortion correction
232 //
233 if (distortionMapY ){
234 //can be switch on for each dimension separatelly
4486a91f 235 if (fCurrentRecoParam->GetUseFieldCorrection()&0x2)
236 if (distortionMapY)
237 xx[1]-=distortionMapY->GetCalROC(sector)->GetValue(row,pad);
2293155b 238 if (fCurrentRecoParam->GetUseFieldCorrection()&0x4)
4486a91f 239 if (distortionMapZ)
240 xx[2]-=distortionMapZ->GetCalROC(sector)->GetValue(row,pad);
241 if (fCurrentRecoParam->GetUseFieldCorrection()&0x8)
242 if (distortionMapR)
243 xx[0]-=distortionMapR->GetCalROC(sector)->GetValue(row,pad);
2293155b 244 }
4486a91f 245 //
2293155b 246
003b43ed 247 //
c1bdda91 248 x[0]=xx[0];x[1]=xx[1];x[2]=xx[2];
249}
250
24db6af7 251void AliTPCTransform::Local2RotatedGlobal(Int_t sector, Double_t *x) const {
252 //
253 //
022ee144 254 // Tranform coordinate from
255 // row, pad, time to x,y,z
24db6af7 256 //
022ee144 257 // Drift Velocity
258 // Current implementation - common drift velocity - for full chamber
24db6af7 259 // TODO: use a map or parametrisation!
260 //
261 //
262 //
9430b11a 263 const Int_t kMax =60; // cache for 60 seconds
264 static Int_t lastStamp=-1; //cached values
265 static Double_t lastCorr = 1;
266 //
66954e3f 267 AliTPCcalibDB* calib=AliTPCcalibDB::Instance();
24db6af7 268 AliTPCParam * param = calib->GetParameters();
9430b11a 269 AliTPCCalibVdrift *driftCalib = AliTPCcalibDB::Instance()->GetVdrift(fCurrentRun);
270 Double_t driftCorr = 1.;
271 if (driftCalib){
272 //
273 // caching drift correction - temp. fix
274 // Extremally slow procedure
275 if ( TMath::Abs((lastStamp)-Int_t(fCurrentTimeStamp))<kMax){
276 driftCorr = lastCorr;
277 }else{
278 driftCorr = 1.+(driftCalib->GetPTRelative(fCurrentTimeStamp,0)+ driftCalib->GetPTRelative(fCurrentTimeStamp,1))*0.5;
279 lastCorr=driftCorr;
280 lastStamp=fCurrentTimeStamp;
281
282 }
283 }
43a74775 284 //
a8f8b6a1 285 // simple caching non thread save
286 static Double_t vdcorrectionTime=1;
287 static Double_t time0corrTime=0;
288 static Int_t lastStampT=-1;
289 //
817766d5 290 if (lastStampT!=(Int_t)fCurrentTimeStamp){
a8f8b6a1 291 lastStampT=fCurrentTimeStamp;
292 if(fCurrentRecoParam&&fCurrentRecoParam->GetUseDriftCorrectionTime()>0) {
293 vdcorrectionTime = (1+AliTPCcalibDB::Instance()->
294 GetVDriftCorrectionTime(fCurrentTimeStamp,
fefec90f 295 fCurrentRun,
a8f8b6a1 296 sector%36>=18,
297 fCurrentRecoParam->GetUseDriftCorrectionTime()));
298 time0corrTime= AliTPCcalibDB::Instance()->
299 GetTime0CorrectionTime(fCurrentTimeStamp,
fefec90f 300 fCurrentRun,
a8f8b6a1 301 sector%36>=18,
302 fCurrentRecoParam->GetUseDriftCorrectionTime());
303 }
304 //
305 if(fCurrentRecoParam&&fCurrentRecoParam->GetUseDriftCorrectionGY()>0) {
306 Float_t xyzPad[3];
307 AliTPCROC::Instance()->GetPositionGlobal(sector, TMath::Nint(x[0]) ,TMath::Nint(x[1]), xyzPad);
308
309 Double_t corrGy= (1+(xyzPad[1])*AliTPCcalibDB::Instance()->
310 GetVDriftCorrectionGy(fCurrentTimeStamp,
311 AliTPCcalibDB::Instance()->GetRun(),
312 sector%36>=18,
313 fCurrentRecoParam->GetUseDriftCorrectionGY()));
314 vdcorrectionTime *=corrGy;
315 }
43a74775 316 }
9430b11a 317
318
24db6af7 319 if (!param){
320 AliFatal("Parameters missing");
321 }
322 Int_t row=TMath::Nint(x[0]);
9389f9a4 323 // Int_t pad=TMath::Nint(x[1]);
24db6af7 324 //
325 const Int_t kNIS=param->GetNInnerSector(), kNOS=param->GetNOuterSector();
326 Double_t sign = 1.;
502d13b5 327 Double_t zwidth = param->GetZWidth()*driftCorr;
328 if (AliTPCRecoParam:: GetUseTimeCalibration()) zwidth*=vdcorrectionTime;
24db6af7 329 Double_t padWidth = 0;
330 Double_t padLength = 0;
331 Double_t maxPad = 0;
332 //
333 if (sector < kNIS) {
334 maxPad = param->GetNPadsLow(row);
335 sign = (sector < kNIS/2) ? 1 : -1;
336 padLength = param->GetPadPitchLength(sector,row);
337 padWidth = param->GetPadPitchWidth(sector);
338 } else {
339 maxPad = param->GetNPadsUp(row);
340 sign = ((sector-kNIS) < kNOS/2) ? 1 : -1;
341 padLength = param->GetPadPitchLength(sector,row);
342 padWidth = param->GetPadPitchWidth(sector);
343 }
344 //
345 // X coordinate
022ee144 346 x[0] = param->GetPadRowRadii(sector,row); // padrow X position - ideal
24db6af7 347 //
348 // Y coordinate
349 //
350 x[1]=(x[1]-0.5*maxPad)*padWidth;
afbaa016 351 // pads are mirrorred on C-side
352 if (sector%36>17){
353 x[1]*=-1;
354 }
355
356 //
357
24db6af7 358 //
359 // Z coordinate
360 //
1e6337b1 361 if (AliTPCcalibDB::Instance()->IsTrgL0()){
362 // by defualt we assume L1 trigger is used - make a correction in case of L0
363 AliCTPTimeParams* ctp = AliTPCcalibDB::Instance()->GetCTPTimeParams();
3d1b41c1 364 if (ctp){
365 //for TPC standalone runs no ctp info
366 Double_t delay = ctp->GetDelayL1L0()*0.000000025;
367 x[2]-=delay/param->GetTSample();
368 }
1e6337b1 369 }
370 x[2]-= param->GetNTBinsL1();
24db6af7 371 x[2]*= zwidth; // tranform time bin to the distance to the ROC
1e6337b1 372 x[2]-= 3.*param->GetZSigma() + time0corrTime;
24db6af7 373 // subtract the time offsets
374 x[2] = sign*( param->GetZLength(sector) - x[2]);
c1bdda91 375}
376
c2da420d 377void AliTPCTransform::RotatedGlobal2Global(Int_t sector,Double_t *x) const {
24db6af7 378 //
379 // transform possition rotated global to the global
380 //
c1bdda91 381 Double_t cos,sin;
382 GetCosAndSin(sector,cos,sin);
383 Double_t tmp=x[0];
e81544f7 384 x[0]= cos*tmp-sin*x[1];
385 x[1]=+sin*tmp+cos*x[1];
c1bdda91 386}
387
c2da420d 388void AliTPCTransform::Global2RotatedGlobal(Int_t sector,Double_t *x) const {
24db6af7 389 //
390 // tranform possition Global2RotatedGlobal
391 //
c1bdda91 392 Double_t cos,sin;
393 GetCosAndSin(sector,cos,sin);
394 Double_t tmp=x[0];
e81544f7 395 x[0]= cos*tmp+sin*x[1];
396 x[1]= -sin*tmp+cos*x[1];
c1bdda91 397}
398
c2da420d 399void AliTPCTransform::GetCosAndSin(Int_t sector,Double_t &cos,
c1bdda91 400 Double_t &sin) const {
401 cos=fCoss[sector%18];
402 sin=fSins[sector%18];
403}
404
c1bdda91 405
43a74775 406void AliTPCTransform::ApplyTransformations(Double_t */*xyz*/, Int_t /*volID*/){
407 //
408 // Modify global position
409 // xyz - global xyz position
410 // volID - volID of detector (sector number)
411 //
412 //
413
414}