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" |
66954e3f |
62 | #include "TGeoMatrix.h" |
9430b11a |
63 | #include "AliTPCRecoParam.h" |
64 | #include "AliTPCCalibVdrift.h" |
022ee144 |
65 | #include "AliTPCTransform.h" |
1e6337b1 |
66 | #include <AliCTPTimeParams.h> |
022ee144 |
67 | |
66954e3f |
68 | ClassImp(AliTPCTransform) |
022ee144 |
69 | |
70 | |
9430b11a |
71 | AliTPCTransform::AliTPCTransform(): |
72 | AliTransform(), |
73 | fCurrentRecoParam(0), //! current reconstruction parameters |
74 | fCurrentRun(0), //! current run |
75 | fCurrentTimeStamp(0) //! current time stamp |
76 | { |
77 | // |
78 | // Speed it up a bit! |
79 | // |
80 | for (Int_t i=0;i<18;++i) { |
81 | Double_t alpha=TMath::DegToRad()*(10.+20.*(i%18)); |
82 | fSins[i]=TMath::Sin(alpha); |
83 | fCoss[i]=TMath::Cos(alpha); |
84 | } |
85 | fPrimVtx[0]=0; |
86 | fPrimVtx[1]=0; |
87 | fPrimVtx[2]=0; |
88 | } |
89 | AliTPCTransform::AliTPCTransform(const AliTPCTransform& transform): |
90 | AliTransform(transform), |
91 | fCurrentRecoParam(transform.fCurrentRecoParam), //! current reconstruction parameters |
92 | fCurrentRun(transform.fCurrentRun), //! current run |
93 | fCurrentTimeStamp(transform.fCurrentTimeStamp) //! current time stamp |
003b43ed |
94 | { |
24db6af7 |
95 | // |
c1bdda91 |
96 | // Speed it up a bit! |
24db6af7 |
97 | // |
c1bdda91 |
98 | for (Int_t i=0;i<18;++i) { |
99 | Double_t alpha=TMath::DegToRad()*(10.+20.*(i%18)); |
100 | fSins[i]=TMath::Sin(alpha); |
101 | fCoss[i]=TMath::Cos(alpha); |
102 | } |
003b43ed |
103 | fPrimVtx[0]=0; |
104 | fPrimVtx[1]=0; |
105 | fPrimVtx[2]=0; |
c1bdda91 |
106 | } |
107 | |
108 | AliTPCTransform::~AliTPCTransform() { |
24db6af7 |
109 | // |
110 | // Destructor |
111 | // |
c1bdda91 |
112 | } |
113 | |
003b43ed |
114 | void AliTPCTransform::SetPrimVertex(Double_t *vtx){ |
115 | // |
116 | // |
117 | // |
118 | fPrimVtx[0]=vtx[0]; |
119 | fPrimVtx[1]=vtx[1]; |
120 | fPrimVtx[2]=vtx[2]; |
121 | } |
122 | |
123 | |
24db6af7 |
124 | void AliTPCTransform::Transform(Double_t *x,Int_t *i,UInt_t /*time*/, |
003b43ed |
125 | Int_t /*coordinateType*/) { |
24db6af7 |
126 | // input: x[0] - pad row |
127 | // x[1] - pad |
c1bdda91 |
128 | // x[2] - time in us |
129 | // i[0] - sector |
130 | // output: x[0] - x (all in the rotated global coordinate frame) |
131 | // x[1] - y |
132 | // x[2] - z |
ecc5dd8f |
133 | // |
134 | // primvtx - position of the primary vertex |
135 | // used for the TOF correction |
136 | // TOF of particle calculated assuming the speed-of-light and |
137 | // line approximation |
138 | // |
139 | |
24db6af7 |
140 | Int_t row=TMath::Nint(x[0]); |
141 | Int_t pad=TMath::Nint(x[1]); |
c1bdda91 |
142 | Int_t sector=i[0]; |
9430b11a |
143 | AliTPCcalibDB* calib=AliTPCcalibDB::Instance(); |
24db6af7 |
144 | // |
145 | AliTPCCalPad * time0TPC = calib->GetPadTime0(); |
146 | AliTPCParam * param = calib->GetParameters(); |
147 | if (!time0TPC){ |
148 | AliFatal("Time unisochronity missing"); |
149 | } |
c1bdda91 |
150 | |
24db6af7 |
151 | if (!param){ |
152 | AliFatal("Parameters missing"); |
153 | } |
c1bdda91 |
154 | |
24db6af7 |
155 | Double_t xx[3]; |
156 | // Apply Time0 correction - Pad by pad fluctuation |
157 | // |
158 | x[2]-=time0TPC->GetCalROC(sector)->GetValue(row,pad); |
159 | // |
160 | // Tranform from pad - time coordinate system to the rotated global (tracking) system |
161 | // |
162 | Local2RotatedGlobal(sector,x); |
163 | // |
164 | // |
165 | // |
c1bdda91 |
166 | // Alignment |
167 | //TODO: calib->GetParameters()->GetClusterMatrix(sector)->LocalToMaster(x,xx); |
c1bdda91 |
168 | RotatedGlobal2Global(sector,x); |
24db6af7 |
169 | // |
170 | // |
171 | // ExB correction |
172 | // |
3ce45991 |
173 | if(fCurrentRecoParam&&fCurrentRecoParam->GetUseExBCorrection()) { |
174 | |
175 | calib->GetExB()->Correct(x,xx); |
176 | |
177 | } else { |
178 | |
179 | xx[0] = x[0]; |
180 | xx[1] = x[1]; |
181 | xx[2] = x[2]; |
182 | } |
183 | |
ecc5dd8f |
184 | // |
185 | // Time of flight correction |
003b43ed |
186 | // |
9430b11a |
187 | if (fCurrentRecoParam&&fCurrentRecoParam->GetUseTOFCorrection()){ |
188 | const Int_t kNIS=param->GetNInnerSector(), kNOS=param->GetNOuterSector(); |
189 | Float_t sign=1; |
190 | if (sector < kNIS) { |
191 | sign = (sector < kNIS/2) ? 1 : -1; |
192 | } else { |
193 | sign = ((sector-kNIS) < kNOS/2) ? 1 : -1; |
194 | } |
195 | Float_t deltaDr =0; |
196 | Float_t dist=0; |
197 | dist+=(fPrimVtx[0]-x[0])*(fPrimVtx[0]-x[0]); |
198 | dist+=(fPrimVtx[1]-x[1])*(fPrimVtx[1]-x[1]); |
199 | dist+=(fPrimVtx[2]-x[2])*(fPrimVtx[2]-x[2]); |
200 | dist = TMath::Sqrt(dist); |
201 | // drift length correction because of TOF |
202 | // the drift velocity is in cm/s therefore multiplication by 0.01 |
203 | deltaDr = (dist*(0.01*param->GetDriftV()))/TMath::C(); |
204 | xx[2]+=sign*deltaDr; |
ecc5dd8f |
205 | } |
9430b11a |
206 | // |
207 | // |
208 | // |
209 | |
ecc5dd8f |
210 | // |
c1bdda91 |
211 | Global2RotatedGlobal(sector,xx); |
003b43ed |
212 | // |
c1bdda91 |
213 | x[0]=xx[0];x[1]=xx[1];x[2]=xx[2]; |
214 | } |
215 | |
24db6af7 |
216 | void AliTPCTransform::Local2RotatedGlobal(Int_t sector, Double_t *x) const { |
217 | // |
218 | // |
022ee144 |
219 | // Tranform coordinate from |
220 | // row, pad, time to x,y,z |
24db6af7 |
221 | // |
022ee144 |
222 | // Drift Velocity |
223 | // Current implementation - common drift velocity - for full chamber |
24db6af7 |
224 | // TODO: use a map or parametrisation! |
225 | // |
226 | // |
227 | // |
9430b11a |
228 | const Int_t kMax =60; // cache for 60 seconds |
229 | static Int_t lastStamp=-1; //cached values |
230 | static Double_t lastCorr = 1; |
231 | // |
66954e3f |
232 | AliTPCcalibDB* calib=AliTPCcalibDB::Instance(); |
24db6af7 |
233 | AliTPCParam * param = calib->GetParameters(); |
9430b11a |
234 | AliTPCCalibVdrift *driftCalib = AliTPCcalibDB::Instance()->GetVdrift(fCurrentRun); |
235 | Double_t driftCorr = 1.; |
236 | if (driftCalib){ |
237 | // |
238 | // caching drift correction - temp. fix |
239 | // Extremally slow procedure |
240 | if ( TMath::Abs((lastStamp)-Int_t(fCurrentTimeStamp))<kMax){ |
241 | driftCorr = lastCorr; |
242 | }else{ |
243 | driftCorr = 1.+(driftCalib->GetPTRelative(fCurrentTimeStamp,0)+ driftCalib->GetPTRelative(fCurrentTimeStamp,1))*0.5; |
244 | lastCorr=driftCorr; |
245 | lastStamp=fCurrentTimeStamp; |
246 | |
247 | } |
248 | } |
43a74775 |
249 | // |
a8f8b6a1 |
250 | // simple caching non thread save |
251 | static Double_t vdcorrectionTime=1; |
252 | static Double_t time0corrTime=0; |
253 | static Int_t lastStampT=-1; |
254 | // |
817766d5 |
255 | if (lastStampT!=(Int_t)fCurrentTimeStamp){ |
a8f8b6a1 |
256 | lastStampT=fCurrentTimeStamp; |
257 | if(fCurrentRecoParam&&fCurrentRecoParam->GetUseDriftCorrectionTime()>0) { |
258 | vdcorrectionTime = (1+AliTPCcalibDB::Instance()-> |
259 | GetVDriftCorrectionTime(fCurrentTimeStamp, |
fefec90f |
260 | fCurrentRun, |
a8f8b6a1 |
261 | sector%36>=18, |
262 | fCurrentRecoParam->GetUseDriftCorrectionTime())); |
263 | time0corrTime= AliTPCcalibDB::Instance()-> |
264 | GetTime0CorrectionTime(fCurrentTimeStamp, |
fefec90f |
265 | fCurrentRun, |
a8f8b6a1 |
266 | sector%36>=18, |
267 | fCurrentRecoParam->GetUseDriftCorrectionTime()); |
268 | } |
269 | // |
270 | if(fCurrentRecoParam&&fCurrentRecoParam->GetUseDriftCorrectionGY()>0) { |
271 | Float_t xyzPad[3]; |
272 | AliTPCROC::Instance()->GetPositionGlobal(sector, TMath::Nint(x[0]) ,TMath::Nint(x[1]), xyzPad); |
273 | |
274 | Double_t corrGy= (1+(xyzPad[1])*AliTPCcalibDB::Instance()-> |
275 | GetVDriftCorrectionGy(fCurrentTimeStamp, |
276 | AliTPCcalibDB::Instance()->GetRun(), |
277 | sector%36>=18, |
278 | fCurrentRecoParam->GetUseDriftCorrectionGY())); |
279 | vdcorrectionTime *=corrGy; |
280 | } |
43a74775 |
281 | } |
9430b11a |
282 | |
283 | |
24db6af7 |
284 | if (!param){ |
285 | AliFatal("Parameters missing"); |
286 | } |
287 | Int_t row=TMath::Nint(x[0]); |
9389f9a4 |
288 | // Int_t pad=TMath::Nint(x[1]); |
24db6af7 |
289 | // |
290 | const Int_t kNIS=param->GetNInnerSector(), kNOS=param->GetNOuterSector(); |
291 | Double_t sign = 1.; |
43a74775 |
292 | Double_t zwidth = param->GetZWidth()*driftCorr*vdcorrectionTime; |
24db6af7 |
293 | Double_t padWidth = 0; |
294 | Double_t padLength = 0; |
295 | Double_t maxPad = 0; |
296 | // |
297 | if (sector < kNIS) { |
298 | maxPad = param->GetNPadsLow(row); |
299 | sign = (sector < kNIS/2) ? 1 : -1; |
300 | padLength = param->GetPadPitchLength(sector,row); |
301 | padWidth = param->GetPadPitchWidth(sector); |
302 | } else { |
303 | maxPad = param->GetNPadsUp(row); |
304 | sign = ((sector-kNIS) < kNOS/2) ? 1 : -1; |
305 | padLength = param->GetPadPitchLength(sector,row); |
306 | padWidth = param->GetPadPitchWidth(sector); |
307 | } |
308 | // |
309 | // X coordinate |
022ee144 |
310 | x[0] = param->GetPadRowRadii(sector,row); // padrow X position - ideal |
24db6af7 |
311 | // |
312 | // Y coordinate |
313 | // |
314 | x[1]=(x[1]-0.5*maxPad)*padWidth; |
afbaa016 |
315 | // pads are mirrorred on C-side |
316 | if (sector%36>17){ |
317 | x[1]*=-1; |
318 | } |
319 | |
320 | // |
321 | |
24db6af7 |
322 | // |
323 | // Z coordinate |
324 | // |
1e6337b1 |
325 | if (AliTPCcalibDB::Instance()->IsTrgL0()){ |
326 | // by defualt we assume L1 trigger is used - make a correction in case of L0 |
327 | AliCTPTimeParams* ctp = AliTPCcalibDB::Instance()->GetCTPTimeParams(); |
328 | Double_t delay = ctp->GetDelayL1L0()*0.000000025; |
329 | x[2]-=delay/param->GetTSample(); |
330 | } |
331 | x[2]-= param->GetNTBinsL1(); |
24db6af7 |
332 | x[2]*= zwidth; // tranform time bin to the distance to the ROC |
1e6337b1 |
333 | x[2]-= 3.*param->GetZSigma() + time0corrTime; |
24db6af7 |
334 | // subtract the time offsets |
335 | x[2] = sign*( param->GetZLength(sector) - x[2]); |
c1bdda91 |
336 | } |
337 | |
c2da420d |
338 | void AliTPCTransform::RotatedGlobal2Global(Int_t sector,Double_t *x) const { |
24db6af7 |
339 | // |
340 | // transform possition rotated global to the global |
341 | // |
c1bdda91 |
342 | Double_t cos,sin; |
343 | GetCosAndSin(sector,cos,sin); |
344 | Double_t tmp=x[0]; |
e81544f7 |
345 | x[0]= cos*tmp-sin*x[1]; |
346 | x[1]=+sin*tmp+cos*x[1]; |
c1bdda91 |
347 | } |
348 | |
c2da420d |
349 | void AliTPCTransform::Global2RotatedGlobal(Int_t sector,Double_t *x) const { |
24db6af7 |
350 | // |
351 | // tranform possition Global2RotatedGlobal |
352 | // |
c1bdda91 |
353 | Double_t cos,sin; |
354 | GetCosAndSin(sector,cos,sin); |
355 | Double_t tmp=x[0]; |
e81544f7 |
356 | x[0]= cos*tmp+sin*x[1]; |
357 | x[1]= -sin*tmp+cos*x[1]; |
c1bdda91 |
358 | } |
359 | |
c2da420d |
360 | void AliTPCTransform::GetCosAndSin(Int_t sector,Double_t &cos, |
c1bdda91 |
361 | Double_t &sin) const { |
362 | cos=fCoss[sector%18]; |
363 | sin=fSins[sector%18]; |
364 | } |
365 | |
c1bdda91 |
366 | |
43a74775 |
367 | void AliTPCTransform::ApplyTransformations(Double_t */*xyz*/, Int_t /*volID*/){ |
368 | // |
369 | // Modify global position |
370 | // xyz - global xyz position |
371 | // volID - volID of detector (sector number) |
372 | // |
373 | // |
374 | |
375 | } |