0f4a7374 |
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 | $Log$ |
18 | Revision 0.01 2003/12/04 S.Arcelli |
19 | Revision 0.02 2003/12/10 S.Arcelli: |
20 | Implement Global methods GetPos & GetDetID |
21 | Revision 0.03 2003/12/14 S.Arcelli |
22 | Set Phi range [-180,180]->[0,360] |
23 | */ |
24 | |
25 | #include <stdlib.h> |
26 | #include <Riostream.h> |
27 | /////////////////////////////////////////////////////////////////////////////// |
28 | // // |
29 | // TOF Geometry class // |
30 | // // |
31 | /////////////////////////////////////////////////////////////////////////////// |
32 | |
33 | #include "AliConst.h" |
34 | #include "AliTOFGeometry.h" |
35 | |
36 | ClassImp(AliTOFGeometry) |
37 | |
38 | //_____________________________________________________________________________ |
39 | AliTOFGeometry::AliTOFGeometry() |
40 | { |
41 | // |
42 | // AliTOFGeometry default constructor |
43 | // |
44 | Init(); |
45 | |
46 | } |
47 | |
48 | //_____________________________________________________________________________ |
49 | AliTOFGeometry::~AliTOFGeometry() |
50 | { |
51 | // |
52 | // AliTOFGeometry destructor |
53 | // |
54 | |
55 | } |
56 | //_____________________________________________________________________________ |
57 | void AliTOFGeometry::Init() |
58 | { |
59 | // |
60 | // Initialize strip Tilt Angles and Heights |
61 | // |
62 | // Strips Tilt Angles |
63 | |
64 | const Float_t angles[fgkNPlates][fgkMaxNstrip] ={ |
65 | |
66 | {44.494, 43.725, 42.946, 42.156, 41.357, 40.548, 39.729, 38.899, |
67 | 38.060, 37.211, 36.353, 35.484, 34.606, 33.719, 32.822, 31.916, |
68 | 31.001, 30.077, 29.144, 28.202 }, |
69 | |
70 | {26.884, 25.922, 24.952, 23.975, 22.989, 22.320, 21.016, 20.309, |
71 | 19.015, 18.270, 16.989, 16.205, 14.941, 14.117, 12.871, 12.008, |
72 | 10.784, 9.8807, 8.681, 0.0 }, |
73 | |
74 | { 7.5835, 6.4124, 5.4058, 4.2809, 3.2448, 2.1424, 1.078, -0., -1.078, |
75 | -2.1424, -3.2448, -4.2809, -5.4058, -6.4124, -7.5835, 0.0, 0.0, 0.0, |
76 | 0.0, 0.0 }, |
77 | |
78 | {-8.681, -9.8807, -10.784, -12.008, -12.871, -14.117, -14.941, -16.205, |
79 | -16.989, -18.27, -19.015, -20.309, -21.016, -22.32, -22.989, |
80 | -23.975, -24.952, -25.922, -26.884, 0. }, |
81 | |
82 | {-28.202, -29.144, -30.077, -31.001, -31.916, -32.822, -33.719, -34.606, |
83 | -35.484, -36.353, -37.211, -38.06, -38.899, -39.729, -40.548, |
84 | -41.357, -42.156, -42.946, -43.725, -44.494 }}; |
85 | |
86 | |
87 | //Strips Heights |
88 | |
89 | const Float_t heights[fgkNPlates][fgkMaxNstrip]= { |
90 | |
91 | {-5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, |
92 | -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5 }, |
93 | |
94 | {-6.3, -7.1, -7.9, -8.7, -9.5, -3, -9.5, -3, -9.5, -3, |
95 | -9.5, -3.0, -9.5, -3.0, -9.5, -3, -9.5, -3, -9 , 0.}, |
96 | |
97 | { -3, -9, -4.5, -9, -4.5, -9, -4.5, -9, -4.5, -9, |
98 | -4.5, -9, -4.5, -9, -3, 0.0, 0.0, 0.0, 0.0, 0.0 }, |
99 | |
100 | { -9, -3, -9.5, -3, -9.5, -3, -9.5, -3, -9.5, -3, -9.5, |
101 | -3, -9.5, -3, -9.5, -8.7, -7.9, -7.1, -6.3, 0. }, |
102 | |
103 | {-5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, |
104 | -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5, -5.5 }}; |
105 | |
106 | |
107 | // Deposit in fAngles, fHeights |
108 | |
109 | for (Int_t iplate = 0; iplate < fgkNPlates; iplate++) { |
110 | for (Int_t istrip = 0; istrip < fgkMaxNstrip; istrip++) { |
111 | fAngles[iplate][istrip] = angles[iplate][istrip]; |
112 | fHeights[iplate][istrip] = heights[iplate][istrip]; |
113 | } |
114 | } |
115 | |
116 | fPhiSec = 360./fgkNSectors; |
117 | } |
118 | |
119 | //_____________________________________________________________________________ |
120 | void AliTOFGeometry::GetPos(Int_t *det, Float_t *pos) |
121 | { |
122 | // |
123 | // Returns space point coor (x,y,z) (cm) for Detector |
124 | // Indices (iSect,iPlate,iStrip,iPadX,iPadZ) |
125 | // |
126 | |
127 | pos[0]=GetX(det); |
128 | pos[1]=GetY(det); |
129 | pos[2]=GetZ(det); |
130 | |
131 | } |
132 | //_____________________________________________________________________________ |
133 | void AliTOFGeometry::GetDetID( Float_t *pos, Int_t *det) |
134 | { |
135 | // |
136 | // Returns Detector Indices (iSect,iPlate,iStrip,iPadX,iPadZ) |
137 | // space point coor (x,y,z) (cm) |
138 | |
139 | |
140 | det[0]=GetSector(pos); |
141 | det[1]=GetPlate(pos); |
142 | det[2]=GetStrip(pos); |
143 | det[3]=GetPadZ(pos); |
144 | det[4]=GetPadX(pos); |
145 | |
146 | } |
147 | //_____________________________________________________________________________ |
148 | Float_t AliTOFGeometry::GetX(Int_t *det) |
149 | { |
150 | // |
151 | // Returns X coordinate (cm) |
152 | // |
153 | |
154 | Int_t isector = det[0]; |
155 | Int_t iplate = det[1]; |
156 | Int_t istrip = det[2]; |
157 | Int_t ipadz = det[3]; |
158 | Int_t ipadx = det[4]; |
159 | |
160 | // Find out distance d on the plane wrt median phi: |
161 | Float_t d = (ipadx+0.5)*fgkXPad-(fgkNpadX*fgkXPad)*0.5; |
162 | |
163 | // The radius r in xy plane: |
164 | Float_t r = (fgkRmin+fgkRmax)/2.+fHeights[iplate][istrip]+ |
165 | (ipadz-0.5)*fgkZPad*TMath::Sin(fAngles[iplate][istrip]/kRaddeg)-0.25; |
166 | |
167 | // local azimuthal angle in the sector philoc |
168 | Float_t philoc = TMath:: ATan(d/r); |
169 | |
170 | // azimuthal angle in the global frame phi |
171 | Float_t phi = philoc*kRaddeg+(isector+0.5 )*fPhiSec; |
172 | |
173 | Float_t xCoor = r/TMath::Cos(philoc)*TMath::Cos(phi/kRaddeg); |
174 | return xCoor; |
175 | |
176 | } |
177 | //_____________________________________________________________________________ |
178 | Float_t AliTOFGeometry::GetY(Int_t *det) |
179 | { |
180 | // |
181 | // Returns Y coordinate (cm) |
182 | // |
183 | |
184 | Int_t isector = det[0]; |
185 | Int_t iplate = det[1]; |
186 | Int_t istrip = det[2]; |
187 | Int_t ipadz = det[3]; |
188 | Int_t ipadx = det[4]; |
189 | |
190 | // Find out distance d on the plane wrt median phi: |
191 | Float_t d = (ipadx+0.5)*fgkXPad-(fgkNpadX*fgkXPad)*0.5; |
192 | |
193 | // The radius r in xy plane: |
194 | Float_t r = (fgkRmin+fgkRmax)/2.+fHeights[iplate][istrip]+ |
195 | (ipadz-0.5)*fgkZPad*TMath::Sin(fAngles[iplate][istrip]/kRaddeg)-0.25; |
196 | |
197 | // local azimuthal angle in the sector philoc |
198 | Float_t philoc = TMath:: ATan(d/r); |
199 | |
200 | // azimuthal angle in the global frame phi |
201 | Float_t phi = philoc*kRaddeg+(isector+0.5 )*fPhiSec; |
202 | |
203 | Float_t yCoor = r/TMath::Cos(philoc)*TMath::Sin(phi/kRaddeg); |
204 | return yCoor; |
205 | |
206 | } |
207 | |
208 | //_____________________________________________________________________________ |
209 | Float_t AliTOFGeometry::GetZ(Int_t *det) |
210 | { |
211 | // |
212 | // Returns Z coordinate (cm) |
213 | // |
214 | |
215 | Int_t iplate = det[1]; |
216 | Int_t istrip = det[2]; |
217 | Int_t ipadz = det[3]; |
218 | |
219 | |
220 | // The radius r in xy plane: |
221 | Float_t r = (fgkRmin+fgkRmax)/2.+fHeights[iplate][istrip]; |
222 | |
223 | Float_t zCoor = r*TMath::Tan(0.5*TMath::Pi()-GetStripTheta(iplate, istrip))- |
224 | (ipadz-0.5)*fgkZPad*TMath::Cos(fAngles[iplate][istrip]/kRaddeg); |
225 | return zCoor; |
226 | |
227 | } |
228 | //_____________________________________________________________________________ |
229 | Int_t AliTOFGeometry::GetSector(Float_t *pos) |
230 | { |
231 | // |
232 | // Returns the Sector index |
233 | // |
234 | |
235 | Int_t iSect = -1; |
236 | |
237 | Float_t x = pos[0]; |
238 | Float_t y = pos[1]; |
239 | |
240 | Float_t phi = TMath::ATan2(y,x); |
241 | if(phi<0.) phi=2.*TMath::Pi()+phi; |
242 | iSect = (Int_t) (phi*kRaddeg/fPhiSec); |
243 | |
244 | return iSect; |
245 | |
246 | } |
247 | //_____________________________________________________________________________ |
248 | Int_t AliTOFGeometry::GetPadX(Float_t *pos) |
249 | { |
250 | // |
251 | // Returns the Pad index along X |
252 | // |
253 | |
254 | Int_t iPadX = -1; |
255 | |
256 | Float_t x = pos[0]; |
257 | Float_t y = pos[1]; |
258 | Float_t z = pos[2]; |
259 | |
260 | Int_t isector = GetSector(pos); |
261 | if(isector == -1){ |
262 | cout << "Detector Index could not be determined" << endl; |
263 | return iPadX;} |
264 | Int_t iplate = GetPlate(pos); |
265 | if(iplate == -1){ |
266 | cout << "Detector Index could not be determined" << endl; |
267 | return iPadX;} |
268 | Int_t istrip = GetStrip(pos); |
269 | if(istrip == -1){ |
270 | cout << "Detector Index could not be determined" << endl; |
271 | return iPadX;} |
272 | |
273 | |
274 | Float_t rho=TMath::Sqrt(x*x+y*y); |
275 | Float_t phi = TMath::ATan2(y,x); |
276 | if(phi<0.) phi=2.*TMath::Pi()+phi; |
277 | |
278 | // Get the local angle in the sector philoc |
279 | Float_t philoc = phi*kRaddeg-(isector+0.5)*fPhiSec; |
280 | philoc*=TMath::Pi()/180.; |
281 | // theta projected on the median of the sector |
282 | Float_t theta = TMath::ATan2(rho*TMath::Cos(philoc),z); |
283 | // The radius r in xy plane: |
284 | Float_t r = (fgkRmin+fgkRmax)/2.+fHeights[iplate][istrip]+ |
285 | (theta-GetStripTheta(iplate, istrip))/ |
286 | (GetMaxStripTheta(iplate, istrip)-GetMinStripTheta(iplate, istrip)) |
287 | * 2.*fgkZPad*TMath::Sin(fAngles[iplate][istrip]/kRaddeg)-0.25; |
288 | |
289 | // Find out distance projected onto the strip plane |
290 | Float_t d = (r*TMath::Tan(philoc)+(fgkNpadX*fgkXPad)*0.5); |
291 | |
292 | iPadX = (Int_t) ( d/fgkXPad); |
293 | return iPadX; |
294 | |
295 | } |
296 | //_____________________________________________________________________________ |
297 | Int_t AliTOFGeometry::GetPlate(Float_t *pos) |
298 | { |
299 | // |
300 | // Returns the Plate index |
301 | // |
302 | Int_t iPlate=-1; |
303 | |
304 | Int_t isector = GetSector(pos); |
305 | if(isector == -1){ |
306 | cout << "Detector Index could not be determined" << endl; |
307 | return iPlate;} |
308 | |
309 | Float_t x = pos[0]; |
310 | Float_t y = pos[1]; |
311 | Float_t z = pos[2]; |
312 | |
313 | Float_t rho=TMath::Sqrt(x*x+y*y); |
314 | Float_t phi=TMath::ATan2(y,x); |
315 | if(phi<0) phi=2.*TMath::Pi()+phi; |
316 | // Get the local angle in the sector philoc |
317 | Float_t philoc = phi*kRaddeg-(isector+0.5)*fPhiSec; |
318 | philoc*=TMath::Pi()/180.; |
319 | // theta projected on the median of the sector |
320 | Float_t theta=TMath::ATan2(rho*TMath::Cos(philoc),z); |
321 | |
322 | for (Int_t i=0; i<fgkNPlates; i++){ |
323 | if ( GetMaxPlateTheta(i) >= theta && |
324 | GetMinPlateTheta(i) <= theta)iPlate=i; |
325 | } |
326 | |
327 | return iPlate; |
328 | |
329 | } |
330 | //_____________________________________________________________________________ |
331 | Int_t AliTOFGeometry::GetStrip(Float_t *pos) |
332 | { |
333 | // |
334 | // Returns the Strip index |
335 | // |
336 | |
337 | Int_t iStrip=-1; |
338 | |
339 | |
340 | Int_t isector = GetSector(pos); |
341 | if(isector == -1){ |
342 | cout << "Detector Index could not be determined" << endl; |
343 | return iStrip;} |
344 | Int_t iplate = GetPlate(pos); |
345 | if(iplate == -1){ |
346 | cout << "Detector Index could not be determined" << endl; |
347 | return iStrip;} |
348 | |
349 | |
350 | Float_t x = pos[0]; |
351 | Float_t y = pos[1]; |
352 | Float_t z = pos[2]; |
353 | |
354 | Int_t nstrips=0; |
355 | if(iplate==0 || iplate == 4)nstrips=fgkNStripC; |
356 | if(iplate==1 || iplate == 3)nstrips=fgkNStripB; |
357 | if(iplate==2) nstrips=fgkNStripA; |
358 | |
359 | Float_t rho=TMath::Sqrt(x*x+y*y); |
360 | Float_t phi=TMath::ATan2(y,x); |
361 | if(phi<0) phi=2.*TMath::Pi()+phi; |
362 | // Get the local angle in the sector philoc |
363 | Float_t philoc = phi*kRaddeg-(isector+0.5)*fPhiSec; |
364 | philoc*=TMath::Pi()/180.; |
365 | // theta projected on the median of the sector |
366 | Float_t theta=TMath::ATan2(rho*TMath::Cos(philoc),z); |
367 | |
368 | for (Int_t istrip=0; istrip<nstrips; istrip++){ |
369 | |
370 | if( |
371 | GetMaxStripTheta(iplate,istrip) >= theta |
372 | && |
373 | GetMinStripTheta(iplate,istrip) <= theta ) iStrip = istrip; |
374 | |
375 | } |
376 | |
377 | return iStrip; |
378 | } |
379 | //_____________________________________________________________________________ |
380 | Int_t AliTOFGeometry::GetPadZ(Float_t *pos) |
381 | { |
382 | // |
383 | // Returns the Pad index along Z |
384 | // |
385 | Int_t iPadZ = -1; |
386 | |
387 | Int_t isector = GetSector(pos); |
388 | if(isector == -1){ |
389 | cout << "Detector Index could not be determined" << endl; |
390 | return iPadZ;} |
391 | Int_t iplate = GetPlate(pos); |
392 | if(iplate == -1){ |
393 | cout << "Detector Index could not be determined" << endl; |
394 | return iPadZ;} |
395 | Int_t istrip = GetStrip(pos); |
396 | if(istrip == -1){ |
397 | cout << "Detector Index could not be determined" << endl; |
398 | return iPadZ;} |
399 | |
400 | |
401 | Float_t x = pos[0]; |
402 | Float_t y = pos[1]; |
403 | Float_t z = pos[2]; |
404 | |
405 | Float_t rho=TMath::Sqrt(x*x+y*y); |
406 | Float_t phi=TMath::ATan2(y,x); |
407 | if(phi<0) phi=2.*TMath::Pi()+phi; |
408 | Float_t philoc = phi*kRaddeg-(isector+0.5)*fPhiSec; |
409 | philoc*=TMath::Pi()/180.; |
410 | Float_t theta=TMath::ATan2(rho*TMath::Cos(philoc),z); |
411 | |
412 | if (theta >= GetStripTheta(iplate, istrip))iPadZ=1; |
413 | else iPadZ=0; |
414 | |
415 | return iPadZ; |
416 | } |
417 | //_____________________________________________________________________________ |
418 | Float_t AliTOFGeometry::GetMinPlateTheta(Int_t iPlate) |
419 | { |
420 | // |
421 | // Returns the minimum theta angle of a given plate iPlate (rad) |
422 | // |
423 | |
424 | |
425 | Int_t index=0; |
426 | |
427 | Float_t delta =0.; |
428 | if(iPlate==0)delta = -1. ; |
429 | if(iPlate==1)delta = -0.5; |
430 | if(iPlate==3)delta = +0.5; |
431 | if(iPlate==4)delta = +1. ; |
432 | |
433 | Float_t z=(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][index]/kRaddeg)+delta; |
434 | Float_t r=(fgkRmin+fgkRmax)/2.+fHeights[iPlate][index]; |
435 | z =z+fgkZPad*TMath::Cos(fAngles[iPlate][index]/kRaddeg); |
436 | r =r-fgkZPad*TMath::Sin(fAngles[iPlate][index]/kRaddeg); |
437 | |
438 | Float_t thmin = 0.5*TMath::Pi()-TMath::ATan(z/r)-fgkDprecMin; |
439 | return thmin; |
440 | |
441 | } |
442 | //_____________________________________________________________________________ |
443 | Float_t AliTOFGeometry::GetMaxPlateTheta(Int_t iPlate) |
444 | { |
445 | // |
446 | // Returns the maximum theta angle of a given plate iPlate (rad) |
447 | |
448 | Int_t index=0; |
449 | if(iPlate==0 ||iPlate == 4)index=fgkNStripC-1; |
450 | if(iPlate==1 ||iPlate == 3)index=fgkNStripB-1; |
451 | if(iPlate==2) index=fgkNStripA-1; |
452 | |
453 | Float_t delta =0.; |
454 | if(iPlate==0)delta = -1. ; |
455 | if(iPlate==1)delta = -0.5; |
456 | if(iPlate==3)delta = +0.5; |
457 | if(iPlate==4)delta = +1. ; |
458 | |
459 | Float_t z=(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][index]/kRaddeg)+delta; |
460 | Float_t r=(fgkRmin+fgkRmax)/2.+fHeights[iPlate][index]; |
461 | z =z-fgkZPad*TMath::Cos(fAngles[iPlate][index]/kRaddeg); |
462 | r= r+fgkZPad*TMath::Sin(fAngles[iPlate][index]/kRaddeg); |
463 | |
464 | Float_t thmax = 0.5*TMath::Pi()-TMath::ATan(z/r)+fgkDprecMax; |
465 | return thmax; |
466 | |
467 | } |
468 | //_____________________________________________________________________________ |
469 | Float_t AliTOFGeometry::GetMaxStripTheta(Int_t iPlate, Int_t iStrip) |
470 | { |
471 | // |
472 | // Returns the maximum theta angle of a given strip iStrip (rad) |
473 | // |
474 | |
475 | |
476 | Float_t delta =0.; |
477 | if(iPlate==0)delta = -1. ; |
478 | if(iPlate==1)delta = -0.5; |
479 | if(iPlate==3)delta = +0.5; |
480 | if(iPlate==4)delta = +1. ; |
481 | |
482 | Float_t r =(fgkRmin+fgkRmax)/2.+fHeights[iPlate][iStrip]; |
483 | Float_t z =(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][iStrip]/kRaddeg)+delta; |
484 | z = z-fgkZPad*TMath::Cos(fAngles[iPlate][iStrip]/kRaddeg); |
485 | r = r+fgkZPad*TMath::Sin(fAngles[iPlate][iStrip]/kRaddeg); |
486 | Float_t thmax =0.5*TMath::Pi()-TMath::ATan(z/r)+fgkDprecMax; |
487 | return thmax; |
488 | |
489 | } |
490 | |
491 | //_____________________________________________________________________________ |
492 | Float_t AliTOFGeometry::GetMinStripTheta(Int_t iPlate, Int_t iStrip) |
493 | { |
494 | // |
495 | // Returns the minimum theta angle of a given Strip iStrip (rad) |
496 | // |
497 | |
498 | |
499 | Float_t delta =0.; |
500 | if(iPlate==0)delta = -1. ; |
501 | if(iPlate==1)delta = -0.5; |
502 | if(iPlate==3)delta = +0.5; |
503 | if(iPlate==4)delta = +1. ; |
504 | |
505 | |
506 | Float_t r =(fgkRmin+fgkRmax)/2.+fHeights[iPlate][iStrip]; |
507 | Float_t z =(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][iStrip]/kRaddeg)+delta; |
508 | z =z+fgkZPad*TMath::Cos(fAngles[iPlate][iStrip]/kRaddeg); |
509 | r =r-fgkZPad*TMath::Sin(fAngles[iPlate][iStrip]/kRaddeg); |
510 | Float_t thmin =0.5*TMath::Pi()-TMath::ATan(z/r)-fgkDprecMin; |
511 | |
512 | return thmin; |
513 | |
514 | } |
515 | |
516 | |
517 | //_____________________________________________________________________________ |
518 | Float_t AliTOFGeometry::GetStripTheta(Int_t iPlate, Int_t iStrip) |
519 | { |
520 | // |
521 | // returns the median theta angle of a given strip iStrip (rad) |
522 | // |
523 | |
524 | |
525 | Float_t delta =0.; |
526 | if(iPlate==0)delta = -1. ; |
527 | if(iPlate==1)delta = -0.5; |
528 | if(iPlate==3)delta = +0.5; |
529 | if(iPlate==4)delta = +1. ; |
530 | |
531 | Float_t r =(fgkRmin+fgkRmax)/2.+fHeights[iPlate][iStrip]; |
532 | Float_t z =(fgkRmin+2.)*TMath::Tan(fAngles[iPlate][iStrip]/kRaddeg)+delta; |
533 | Float_t theta =0.5*TMath::Pi()-TMath::ATan(z/r); |
534 | if(iPlate != 2){ |
535 | if(theta > 0.5*TMath::Pi() )theta+=fgkDprecCen; |
536 | if(theta < 0.5*TMath::Pi() )theta-=fgkDprecCen; |
537 | } |
538 | return theta; |
539 | } |
540 | |
541 | |
542 | |