Cuts configuarable from outside.
[u/mrichter/AliRoot.git] / TPC / Base / 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:
829455ad 36// AliTPCclusterer::AddCluster
37// AliTPCtracker::Transform
022ee144 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"
0b736a46 67#include "AliMagF.h"
68#include "TGeoGlobalMagField.h"
69#include "AliTracker.h"
1e6337b1 70#include <AliCTPTimeParams.h>
022ee144 71
66954e3f 72ClassImp(AliTPCTransform)
022ee144 73
74
9430b11a 75AliTPCTransform::AliTPCTransform():
76 AliTransform(),
77 fCurrentRecoParam(0), //! current reconstruction parameters
78 fCurrentRun(0), //! current run
79 fCurrentTimeStamp(0) //! current time stamp
80{
81 //
82 // Speed it up a bit!
83 //
84 for (Int_t i=0;i<18;++i) {
85 Double_t alpha=TMath::DegToRad()*(10.+20.*(i%18));
86 fSins[i]=TMath::Sin(alpha);
87 fCoss[i]=TMath::Cos(alpha);
88 }
89 fPrimVtx[0]=0;
90 fPrimVtx[1]=0;
91 fPrimVtx[2]=0;
92}
93AliTPCTransform::AliTPCTransform(const AliTPCTransform& transform):
94 AliTransform(transform),
95 fCurrentRecoParam(transform.fCurrentRecoParam), //! current reconstruction parameters
96 fCurrentRun(transform.fCurrentRun), //! current run
97 fCurrentTimeStamp(transform.fCurrentTimeStamp) //! current time stamp
003b43ed 98{
24db6af7 99 //
c1bdda91 100 // Speed it up a bit!
24db6af7 101 //
c1bdda91 102 for (Int_t i=0;i<18;++i) {
103 Double_t alpha=TMath::DegToRad()*(10.+20.*(i%18));
104 fSins[i]=TMath::Sin(alpha);
105 fCoss[i]=TMath::Cos(alpha);
106 }
003b43ed 107 fPrimVtx[0]=0;
108 fPrimVtx[1]=0;
109 fPrimVtx[2]=0;
c1bdda91 110}
111
112AliTPCTransform::~AliTPCTransform() {
24db6af7 113 //
114 // Destructor
115 //
c1bdda91 116}
117
003b43ed 118void AliTPCTransform::SetPrimVertex(Double_t *vtx){
119 //
120 //
121 //
122 fPrimVtx[0]=vtx[0];
123 fPrimVtx[1]=vtx[1];
124 fPrimVtx[2]=vtx[2];
125}
126
127
24db6af7 128void AliTPCTransform::Transform(Double_t *x,Int_t *i,UInt_t /*time*/,
003b43ed 129 Int_t /*coordinateType*/) {
24db6af7 130 // input: x[0] - pad row
131 // x[1] - pad
c1bdda91 132 // x[2] - time in us
133 // i[0] - sector
134 // output: x[0] - x (all in the rotated global coordinate frame)
135 // x[1] - y
136 // x[2] - z
ecc5dd8f 137 //
138 // primvtx - position of the primary vertex
139 // used for the TOF correction
140 // TOF of particle calculated assuming the speed-of-light and
141 // line approximation
142 //
768e46f1 143 if (!fCurrentRecoParam) {
144 return;
145 }
24db6af7 146 Int_t row=TMath::Nint(x[0]);
147 Int_t pad=TMath::Nint(x[1]);
c1bdda91 148 Int_t sector=i[0];
9430b11a 149 AliTPCcalibDB* calib=AliTPCcalibDB::Instance();
24db6af7 150 //
151 AliTPCCalPad * time0TPC = calib->GetPadTime0();
2293155b 152 AliTPCCalPad * distortionMapY = calib->GetDistortionMap(0);
153 AliTPCCalPad * distortionMapZ = calib->GetDistortionMap(1);
4486a91f 154 AliTPCCalPad * distortionMapR = calib->GetDistortionMap(2);
24db6af7 155 AliTPCParam * param = calib->GetParameters();
0b736a46 156 AliTPCCorrection * correction = calib->GetTPCComposedCorrection(); // first user defined correction // if does not exist try to get it from calibDB array
157 if (!correction) correction = calib->GetTPCComposedCorrection(AliTracker::GetBz());
24db6af7 158 if (!time0TPC){
159 AliFatal("Time unisochronity missing");
768e46f1 160 return ; // make coverity happy
24db6af7 161 }
3f3549a3 162 AliTPCCorrection * correctionDelta = calib->GetTPCComposedCorrectionDelta();
c1bdda91 163
24db6af7 164 if (!param){
165 AliFatal("Parameters missing");
768e46f1 166 return; // make coverity happy
24db6af7 167 }
c1bdda91 168
24db6af7 169 Double_t xx[3];
170 // Apply Time0 correction - Pad by pad fluctuation
3f3549a3 171 //
172 if (!calib->HasAlignmentOCDB()) x[2]-=time0TPC->GetCalROC(sector)->GetValue(row,pad);
24db6af7 173 //
174 // Tranform from pad - time coordinate system to the rotated global (tracking) system
175 //
176 Local2RotatedGlobal(sector,x);
177 //
178 //
179 //
c1bdda91 180 // Alignment
181 //TODO: calib->GetParameters()->GetClusterMatrix(sector)->LocalToMaster(x,xx);
c1bdda91 182 RotatedGlobal2Global(sector,x);
cf5b0aa0 183
24db6af7 184 //
cf5b0aa0 185 // old ExB correction
24db6af7 186 //
768e46f1 187 if(fCurrentRecoParam->GetUseExBCorrection()) {
3ce45991 188
189 calib->GetExB()->Correct(x,xx);
190
191 } else {
192
193 xx[0] = x[0];
194 xx[1] = x[1];
195 xx[2] = x[2];
196 }
197
ecc5dd8f 198 //
cf5b0aa0 199 // new composed correction - will replace soon ExB correction
200 //
768e46f1 201 if(fCurrentRecoParam->GetUseComposedCorrection()&&correction) {
cf5b0aa0 202 Float_t distPoint[3]={xx[0],xx[1],xx[2]};
203 correction->CorrectPoint(distPoint, sector);
204 xx[0]=distPoint[0];
205 xx[1]=distPoint[1];
206 xx[2]=distPoint[2];
3f3549a3 207 if (correctionDelta&&fCurrentRecoParam->GetUseAlignmentTime()){ // appply time dependent correction if available and enabled
208 Float_t distPointDelta[3]={xx[0],xx[1],xx[2]};
5c8d0ec4 209 correctionDelta->CorrectPoint(distPointDelta, sector);
3f3549a3 210 xx[0]=distPointDelta[0];
211 xx[1]=distPointDelta[1];
212 xx[2]=distPointDelta[2];
213 }
cf5b0aa0 214 }
215
216
217 //
ecc5dd8f 218 // Time of flight correction
003b43ed 219 //
768e46f1 220 if (fCurrentRecoParam->GetUseTOFCorrection()){
9430b11a 221 const Int_t kNIS=param->GetNInnerSector(), kNOS=param->GetNOuterSector();
222 Float_t sign=1;
223 if (sector < kNIS) {
224 sign = (sector < kNIS/2) ? 1 : -1;
225 } else {
226 sign = ((sector-kNIS) < kNOS/2) ? 1 : -1;
227 }
228 Float_t deltaDr =0;
229 Float_t dist=0;
230 dist+=(fPrimVtx[0]-x[0])*(fPrimVtx[0]-x[0]);
231 dist+=(fPrimVtx[1]-x[1])*(fPrimVtx[1]-x[1]);
232 dist+=(fPrimVtx[2]-x[2])*(fPrimVtx[2]-x[2]);
233 dist = TMath::Sqrt(dist);
234 // drift length correction because of TOF
235 // the drift velocity is in cm/s therefore multiplication by 0.01
236 deltaDr = (dist*(0.01*param->GetDriftV()))/TMath::C();
237 xx[2]+=sign*deltaDr;
ecc5dd8f 238 }
9430b11a 239 //
240 //
241 //
242
ecc5dd8f 243 //
c1bdda91 244 Global2RotatedGlobal(sector,xx);
2293155b 245
246 //
247 // Apply non linear distortion correction
248 //
249 if (distortionMapY ){
0b736a46 250 // wt - to get it form the OCDB
251 // ignore T1 and T2
252 AliMagF* magF= (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
253 Double_t bzField = magF->SolenoidField()/10.; //field in T
254 Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us] // From dataBase: to be updated: per second (ideally)
255 Double_t ezField = 400; // [V/cm] // to be updated: never (hopefully)
256 if (sector%36<18) ezField*=-1;
257 Double_t wt = -10.0 * (bzField*10) * vdrift / ezField ;
258 Double_t c0=1./(1.+wt*wt);
259 Double_t c1=wt/c0;
260
2293155b 261 //can be switch on for each dimension separatelly
4486a91f 262 if (fCurrentRecoParam->GetUseFieldCorrection()&0x2)
0b736a46 263 if (distortionMapY){
264 xx[1]-= c0*distortionMapY->GetCalROC(sector)->GetValue(row,pad);
265 xx[0]-= c1*distortionMapY->GetCalROC(sector)->GetValue(row,pad);
266 }
2293155b 267 if (fCurrentRecoParam->GetUseFieldCorrection()&0x4)
4486a91f 268 if (distortionMapZ)
269 xx[2]-=distortionMapZ->GetCalROC(sector)->GetValue(row,pad);
270 if (fCurrentRecoParam->GetUseFieldCorrection()&0x8)
0b736a46 271 if (distortionMapR){
272 xx[0]-= c0*distortionMapR->GetCalROC(sector)->GetValue(row,pad);
273 xx[1]-=-c1*distortionMapR->GetCalROC(sector)->GetValue(row,pad)*wt;
274 }
275
2293155b 276 }
4486a91f 277 //
2293155b 278
003b43ed 279 //
c1bdda91 280 x[0]=xx[0];x[1]=xx[1];x[2]=xx[2];
281}
282
24db6af7 283void AliTPCTransform::Local2RotatedGlobal(Int_t sector, Double_t *x) const {
284 //
285 //
022ee144 286 // Tranform coordinate from
287 // row, pad, time to x,y,z
24db6af7 288 //
022ee144 289 // Drift Velocity
290 // Current implementation - common drift velocity - for full chamber
24db6af7 291 // TODO: use a map or parametrisation!
292 //
293 //
294 //
768e46f1 295 if (!fCurrentRecoParam) return;
9430b11a 296 const Int_t kMax =60; // cache for 60 seconds
297 static Int_t lastStamp=-1; //cached values
298 static Double_t lastCorr = 1;
299 //
66954e3f 300 AliTPCcalibDB* calib=AliTPCcalibDB::Instance();
24db6af7 301 AliTPCParam * param = calib->GetParameters();
9430b11a 302 AliTPCCalibVdrift *driftCalib = AliTPCcalibDB::Instance()->GetVdrift(fCurrentRun);
303 Double_t driftCorr = 1.;
304 if (driftCalib){
305 //
306 // caching drift correction - temp. fix
307 // Extremally slow procedure
308 if ( TMath::Abs((lastStamp)-Int_t(fCurrentTimeStamp))<kMax){
309 driftCorr = lastCorr;
310 }else{
311 driftCorr = 1.+(driftCalib->GetPTRelative(fCurrentTimeStamp,0)+ driftCalib->GetPTRelative(fCurrentTimeStamp,1))*0.5;
312 lastCorr=driftCorr;
313 lastStamp=fCurrentTimeStamp;
314
315 }
316 }
43a74775 317 //
a8f8b6a1 318 // simple caching non thread save
319 static Double_t vdcorrectionTime=1;
5647625c 320 static Double_t vdcorrectionTimeGY=0;
a8f8b6a1 321 static Double_t time0corrTime=0;
322 static Int_t lastStampT=-1;
323 //
817766d5 324 if (lastStampT!=(Int_t)fCurrentTimeStamp){
a8f8b6a1 325 lastStampT=fCurrentTimeStamp;
768e46f1 326 if(fCurrentRecoParam->GetUseDriftCorrectionTime()>0) {
a8f8b6a1 327 vdcorrectionTime = (1+AliTPCcalibDB::Instance()->
328 GetVDriftCorrectionTime(fCurrentTimeStamp,
fefec90f 329 fCurrentRun,
a8f8b6a1 330 sector%36>=18,
331 fCurrentRecoParam->GetUseDriftCorrectionTime()));
332 time0corrTime= AliTPCcalibDB::Instance()->
333 GetTime0CorrectionTime(fCurrentTimeStamp,
fefec90f 334 fCurrentRun,
a8f8b6a1 335 sector%36>=18,
336 fCurrentRecoParam->GetUseDriftCorrectionTime());
337 }
338 //
768e46f1 339 if(fCurrentRecoParam->GetUseDriftCorrectionGY()>0) {
a8f8b6a1 340
5647625c 341 Double_t corrGy= AliTPCcalibDB::Instance()->
a8f8b6a1 342 GetVDriftCorrectionGy(fCurrentTimeStamp,
343 AliTPCcalibDB::Instance()->GetRun(),
344 sector%36>=18,
5647625c 345 fCurrentRecoParam->GetUseDriftCorrectionGY());
346 vdcorrectionTimeGY = corrGy;
a8f8b6a1 347 }
43a74775 348 }
9430b11a 349
350
24db6af7 351 if (!param){
352 AliFatal("Parameters missing");
768e46f1 353 return; // make coverity happy
24db6af7 354 }
355 Int_t row=TMath::Nint(x[0]);
9389f9a4 356 // Int_t pad=TMath::Nint(x[1]);
24db6af7 357 //
358 const Int_t kNIS=param->GetNInnerSector(), kNOS=param->GetNOuterSector();
359 Double_t sign = 1.;
502d13b5 360 Double_t zwidth = param->GetZWidth()*driftCorr;
5647625c 361 Float_t xyzPad[3];
362 AliTPCROC::Instance()->GetPositionGlobal(sector, TMath::Nint(x[0]) ,TMath::Nint(x[1]), xyzPad);
363 if (AliTPCRecoParam:: GetUseTimeCalibration()) zwidth*=vdcorrectionTime*(1+xyzPad[1]*vdcorrectionTimeGY);
24db6af7 364 Double_t padWidth = 0;
365 Double_t padLength = 0;
366 Double_t maxPad = 0;
367 //
368 if (sector < kNIS) {
369 maxPad = param->GetNPadsLow(row);
370 sign = (sector < kNIS/2) ? 1 : -1;
371 padLength = param->GetPadPitchLength(sector,row);
372 padWidth = param->GetPadPitchWidth(sector);
373 } else {
374 maxPad = param->GetNPadsUp(row);
375 sign = ((sector-kNIS) < kNOS/2) ? 1 : -1;
376 padLength = param->GetPadPitchLength(sector,row);
377 padWidth = param->GetPadPitchWidth(sector);
378 }
379 //
380 // X coordinate
022ee144 381 x[0] = param->GetPadRowRadii(sector,row); // padrow X position - ideal
24db6af7 382 //
383 // Y coordinate
384 //
385 x[1]=(x[1]-0.5*maxPad)*padWidth;
afbaa016 386 // pads are mirrorred on C-side
387 if (sector%36>17){
388 x[1]*=-1;
389 }
390
391 //
392
24db6af7 393 //
394 // Z coordinate
395 //
1e6337b1 396 if (AliTPCcalibDB::Instance()->IsTrgL0()){
397 // by defualt we assume L1 trigger is used - make a correction in case of L0
398 AliCTPTimeParams* ctp = AliTPCcalibDB::Instance()->GetCTPTimeParams();
3d1b41c1 399 if (ctp){
400 //for TPC standalone runs no ctp info
401 Double_t delay = ctp->GetDelayL1L0()*0.000000025;
402 x[2]-=delay/param->GetTSample();
403 }
1e6337b1 404 }
405 x[2]-= param->GetNTBinsL1();
24db6af7 406 x[2]*= zwidth; // tranform time bin to the distance to the ROC
1e6337b1 407 x[2]-= 3.*param->GetZSigma() + time0corrTime;
24db6af7 408 // subtract the time offsets
409 x[2] = sign*( param->GetZLength(sector) - x[2]);
c1bdda91 410}
411
c2da420d 412void AliTPCTransform::RotatedGlobal2Global(Int_t sector,Double_t *x) const {
24db6af7 413 //
414 // transform possition rotated global to the global
415 //
c1bdda91 416 Double_t cos,sin;
417 GetCosAndSin(sector,cos,sin);
418 Double_t tmp=x[0];
e81544f7 419 x[0]= cos*tmp-sin*x[1];
420 x[1]=+sin*tmp+cos*x[1];
c1bdda91 421}
422
c2da420d 423void AliTPCTransform::Global2RotatedGlobal(Int_t sector,Double_t *x) const {
24db6af7 424 //
425 // tranform possition Global2RotatedGlobal
426 //
c1bdda91 427 Double_t cos,sin;
428 GetCosAndSin(sector,cos,sin);
429 Double_t tmp=x[0];
e81544f7 430 x[0]= cos*tmp+sin*x[1];
431 x[1]= -sin*tmp+cos*x[1];
c1bdda91 432}
433
c2da420d 434void AliTPCTransform::GetCosAndSin(Int_t sector,Double_t &cos,
c1bdda91 435 Double_t &sin) const {
436 cos=fCoss[sector%18];
437 sin=fSins[sector%18];
438}
439
c1bdda91 440
43a74775 441void AliTPCTransform::ApplyTransformations(Double_t */*xyz*/, Int_t /*volID*/){
442 //
443 // Modify global position
444 // xyz - global xyz position
445 // volID - volID of detector (sector number)
446 //
447 //
448
449}