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 **************************************************************************/
15 //-----------------------------------------------------//
18 // Date : August 05 2003 //
20 // Utility code for ALICE-PMD //
22 //-----------------------------------------------------//
24 #include "Riostream.h"
28 #include <TClonesArray.h>
33 #include "AliPMDUtility.h"
34 #include "AliAlignObjMatrix.h"
35 #include "AliCDBManager.h"
36 #include "AliCDBEntry.h"
40 ClassImp(AliPMDUtility)
42 AliPMDUtility::AliPMDUtility():
43 fAlObj(GetAlignObj()),
52 // Default constructor
53 for (Int_t i = 0; i < 4; i++)
55 for (Int_t j = 0; j < 3; j++)
63 AliPMDUtility::AliPMDUtility(Float_t px, Float_t py, Float_t pz):
64 fAlObj(GetAlignObj()),
74 for (Int_t i = 0; i < 4; i++)
76 for (Int_t j = 0; j < 3; j++)
83 AliPMDUtility::AliPMDUtility(const AliPMDUtility &pmdutil):
85 fAlObj(pmdutil.GetAlignObj()),
89 fTheta(pmdutil.fTheta),
92 fWriteModule(pmdutil.fWriteModule)
95 for (Int_t i = 0; i < 4; i++)
97 for (Int_t j = 0; j < 3; j++)
99 fSecTr[i][j] = pmdutil.fSecTr[i][j];
104 AliPMDUtility & AliPMDUtility::operator=(const AliPMDUtility &pmdutil)
106 // assignment operator
112 fTheta = pmdutil.fTheta;
115 fWriteModule = pmdutil.fWriteModule;
116 for (Int_t i = 0; i < 4; i++)
118 for (Int_t j = 0; j < 3; j++)
120 fSecTr[i][j] = pmdutil.fSecTr[i][j];
127 AliPMDUtility::~AliPMDUtility()
129 // Default destructor
132 void AliPMDUtility::RectGeomCellPos(Int_t ism, Int_t xpad, Int_t ypad, Float_t &xpos, Float_t &ypos)
134 // This routine finds the cell eta,phi for the new PMD rectangular
136 // Authors : Bedanga Mohanty and Dipak Mishra - 29.4.2003
137 // modified by B. K. Nandi for change of coordinate sys
139 // SMA ---> Supermodule Type A ( SM - 0)
140 // SMAR ---> Supermodule Type A ROTATED ( SM - 1)
141 // SMB ---> Supermodule Type B ( SM - 2)
142 // SMBR ---> Supermodule Type B ROTATED ( SM - 3)
144 // ism : Serial module number from 0 to 23 for each plane
147 // Corner positions (x,y) of the 24 unit moudles in ALICE PMD
151 74.8833, 53.0045, 31.1255, //Type-A
152 74.8833, 53.0045, 31.1255, //Type-A
153 -74.8833, -53.0044, -31.1255, //Type-AR
154 -74.8833, -53.0044, -31.1255, //Type-AR
155 8.9165, -33.7471, //Type-B
156 8.9165, -33.7471, //Type-B
157 8.9165, -33.7471, //Type-B
158 -8.9165, 33.7471, //Type-BR
159 -8.9165, 33.7471, //Type-BR
160 -8.9165, 33.7471, //Type-BR
166 86.225, 86.225, 86.225, //Type-A
167 37.075, 37.075, 37.075, //Type-A
168 -86.225, -86.225, -86.225, //Type-AR
169 -37.075, -37.075, -37.075, //Type-AR
170 86.225, 86.225, //Type-B
171 61.075, 61.075, //Type-B
172 35.925, 35.925, //Type-B
173 -86.225, -86.225, //Type-BR
174 -61.075, -61.075, //Type-BR
175 -35.925, -35.925 //Type-BR
179 const Float_t kSqroot3 = 1.73205; // sqrt(3.);
180 const Float_t kCellRadius = 0.25;
183 //Every even row of cells is shifted and placed
184 //in geant so this condition
186 Float_t cellRadius = 0.25;
190 shift = -cellRadius/2.0;
200 ypos = ycorner[ism] - (Float_t) xpad*kCellRadius*2.0 + shift;
201 xpos = xcorner[ism] - (Float_t) ypad*kSqroot3*kCellRadius;
203 else if(ism >=6 && ism < 12)
205 ypos = ycorner[ism] + (Float_t) xpad*kCellRadius*2.0 + shift;
206 xpos = xcorner[ism] + (Float_t) ypad*kSqroot3*kCellRadius;
208 else if(ism >= 12 && ism < 18)
210 ypos = ycorner[ism] - (Float_t) xpad*kCellRadius*2.0 + shift;
211 xpos = xcorner[ism] - (Float_t) ypad*kSqroot3*kCellRadius;
213 else if(ism >= 18 && ism < 24)
215 ypos = ycorner[ism] + (Float_t) xpad*kCellRadius*2.0 + shift;
216 xpos = xcorner[ism] + (Float_t) ypad*kSqroot3*kCellRadius;
218 // Apply the alignment here to the x, y values
221 xpos += fSecTr[0][0];
222 ypos += fSecTr[0][1];
224 else if(ism >= 6 && ism < 12)
226 xpos += fSecTr[1][0];
227 ypos += fSecTr[1][1];
229 else if(ism >=12 && ism < 18)
231 xpos += fSecTr[2][0];
232 ypos += fSecTr[2][1];
234 else if(ism >= 18 && ism < 24)
236 xpos += fSecTr[3][0];
237 ypos += fSecTr[3][1];
241 // ----------------------------------------------------------
242 void AliPMDUtility::RectGeomCellPos(Int_t ism, Float_t xpad, Float_t ypad, Float_t &xpos, Float_t &ypos)
244 // If the xpad and ypad inputs are float, then 0.5 is added to it
245 // to find the layer which is shifted.
246 // This routine finds the cell eta,phi for the new PMD rectangular
248 // Authors : Bedanga Mohanty and Dipak Mishra - 29.4.2003
249 // modified by B. K. Nnadi for change of coordinate sys
251 // SMA ---> Supermodule Type A ( SM - 0)
252 // SMAR ---> Supermodule Type A ROTATED ( SM - 1)
253 // SMB ---> Supermodule Type B ( SM - 2)
254 // SMBR ---> Supermodule Type B ROTATED ( SM - 3)
256 // ism : Serial Module number from 0 to 23 for each plane
258 // Corner positions (x,y) of the 24 unit moudles in ALICE PMD
262 74.8833, 53.0045, 31.1255, //Type-A
263 74.8833, 53.0045, 31.1255, //Type-A
264 -74.8833, -53.0044, -31.1255, //Type-AR
265 -74.8833, -53.0044, -31.1255, //Type-AR
266 8.9165, -33.7471, //Type-B
267 8.9165, -33.7471, //Type-B
268 8.9165, -33.7471, //Type-B
269 -8.9165, 33.7471, //Type-BR
270 -8.9165, 33.7471, //Type-BR
271 -8.9165, 33.7471, //Type-BR
278 86.225, 86.225, 86.225, //Type-A
279 37.075, 37.075, 37.075, //Type-A
280 -86.225, -86.225, -86.225, //Type-AR
281 -37.075, -37.075, -37.075, //Type-AR
282 86.225, 86.225, //Type-B
283 61.075, 61.075, //Type-B
284 35.925, 35.925, //Type-B
285 -86.225, -86.225, //Type-BR
286 -61.075, -61.075, //Type-BR
287 -35.925, -35.925 //Type-BR
291 const Float_t kSqroot3 = 1.73205; // sqrt(3.);
292 const Float_t kCellRadius = 0.25;
295 //Every even row of cells is shifted and placed
296 //in geant so this condition
298 Float_t cellRadius = 0.25;
300 Int_t iirow = (Int_t) (xpad+0.5);
303 shift = -cellRadius/2.0;
312 ypos = ycorner[ism] - xpad*kCellRadius*2.0 + shift;
313 xpos = xcorner[ism] - ypad*kSqroot3*kCellRadius;
315 else if(ism >=6 && ism < 12)
317 ypos = ycorner[ism] + xpad*kCellRadius*2.0 + shift;
318 xpos = xcorner[ism] + ypad*kSqroot3*kCellRadius;
320 else if(ism >= 12 && ism < 18)
322 ypos = ycorner[ism] - xpad*kCellRadius*2.0 + shift;
323 xpos = xcorner[ism] - ypad*kSqroot3*kCellRadius;
325 else if(ism >= 18 && ism < 24)
327 ypos = ycorner[ism] + xpad*kCellRadius*2.0 + shift;
328 xpos = xcorner[ism] + ypad*kSqroot3*kCellRadius;
331 // Apply the alignment here to the x, y values
334 xpos += fSecTr[0][0];
335 ypos += fSecTr[0][1];
337 else if(ism >= 6 && ism < 12)
339 xpos += fSecTr[1][0];
340 ypos += fSecTr[1][1];
342 else if(ism >=12 && ism < 18)
344 xpos += fSecTr[2][0];
345 ypos += fSecTr[2][1];
347 else if(ism >= 18 && ism < 24)
349 xpos += fSecTr[3][0];
350 ypos += fSecTr[3][1];
355 // -------------------------------------------------------- //
357 void AliPMDUtility::RectGeomCellPos(Int_t ism, Float_t xpad,
358 Float_t ypad, Float_t &xpos,
359 Float_t &ypos, Float_t & zpos)
361 // If the xpad and ypad inputs are float, then 0.5 is added to it
362 // to find the layer which is shifted.
363 // This routine finds the cell eta,phi for the new PMD rectangular
365 // Authors : Bedanga Mohanty and Dipak Mishra - 29.4.2003
366 // modified by B. K. Nnadi for change of coordinate sys
368 // SMA ---> Supermodule Type A ( SM - 0)
369 // SMAR ---> Supermodule Type A ROTATED ( SM - 1)
370 // SMB ---> Supermodule Type B ( SM - 2)
371 // SMBR ---> Supermodule Type B ROTATED ( SM - 3)
373 // ism : Serial Module number from 0 to 23 for each plane
375 // Corner positions (x,y) of the 24 unit moudles in ALICE PMD
379 74.8833, 53.0045, 31.1255, //Type-A
380 74.8833, 53.0045, 31.1255, //Type-A
381 -74.8833, -53.0044, -31.1255, //Type-AR
382 -74.8833, -53.0044, -31.1255, //Type-AR
383 8.9165, -33.7471, //Type-B
384 8.9165, -33.7471, //Type-B
385 8.9165, -33.7471, //Type-B
386 -8.9165, 33.7471, //Type-BR
387 -8.9165, 33.7471, //Type-BR
388 -8.9165, 33.7471, //Type-BR
395 86.225, 86.225, 86.225, //Type-A
396 37.075, 37.075, 37.075, //Type-A
397 -86.225, -86.225, -86.225, //Type-AR
398 -37.075, -37.075, -37.075, //Type-AR
399 86.225, 86.225, //Type-B
400 61.075, 61.075, //Type-B
401 35.925, 35.925, //Type-B
402 -86.225, -86.225, //Type-BR
403 -61.075, -61.075, //Type-BR
404 -35.925, -35.925 //Type-BR
408 const Float_t kSqroot3 = 1.73205; // sqrt(3.);
409 const Float_t kCellRadius = 0.25;
412 //Every even row of cells is shifted and placed
413 //in geant so this condition
415 Float_t cellRadius = 0.25;
417 Int_t iirow = (Int_t) (xpad+0.5);
420 shift = -cellRadius/2.0;
429 ypos = ycorner[ism] - xpad*kCellRadius*2.0 + shift;
430 xpos = xcorner[ism] - ypad*kSqroot3*kCellRadius;
432 else if(ism >=6 && ism < 12)
434 ypos = ycorner[ism] + xpad*kCellRadius*2.0 + shift;
435 xpos = xcorner[ism] + ypad*kSqroot3*kCellRadius;
437 else if(ism >= 12 && ism < 18)
439 ypos = ycorner[ism] - xpad*kCellRadius*2.0 + shift;
440 xpos = xcorner[ism] - ypad*kSqroot3*kCellRadius;
442 else if(ism >= 18 && ism < 24)
444 ypos = ycorner[ism] + xpad*kCellRadius*2.0 + shift;
445 xpos = xcorner[ism] + ypad*kSqroot3*kCellRadius;
448 // Apply the alignment here to the x, y, and z values
451 xpos += fSecTr[0][0];
452 ypos += fSecTr[0][1];
453 zpos += fSecTr[0][2];
455 else if(ism >= 6 && ism < 12)
457 xpos += fSecTr[1][0];
458 ypos += fSecTr[1][1];
459 zpos += fSecTr[1][2];
461 else if(ism >=12 && ism < 18)
463 xpos += fSecTr[2][0];
464 ypos += fSecTr[2][1];
465 zpos += fSecTr[2][2];
467 else if(ism >= 18 && ism < 24)
469 xpos += fSecTr[3][0];
470 ypos += fSecTr[3][1];
471 zpos += fSecTr[3][2];
477 // -------------------------------------------------------- //
479 void AliPMDUtility::GenerateBoundaryPoints(Int_t ism, Float_t &x1ism,
480 Float_t &y1ism, Float_t &x2ism,
483 // Generate bounding-box.
486 Float_t xism = 0, yism = 0;
487 Float_t dxism = 0., dyism = 0.;
489 const Float_t kRad = 0.25;
490 const Float_t kSqRoot3 = 1.732050808;
491 const Float_t kDia = 0.50;
494 const Double_t kXcorner[24] =
496 74.8833, 53.0045, 31.1255, //Type-A
497 74.8833, 53.0045, 31.1255, //Type-A
498 -74.8833, -53.0044, -31.1255, //Type-AR
499 -74.8833, -53.0044, -31.1255, //Type-AR
500 8.9165, -33.7471, //Type-B
501 8.9165, -33.7471, //Type-B
502 8.9165, -33.7471, //Type-B
503 -8.9165, 33.7471, //Type-BR
504 -8.9165, 33.7471, //Type-BR
505 -8.9165, 33.7471, //Type-BR
509 const Double_t kYcorner[24] =
511 86.225, 86.225, 86.225, //Type-A
512 37.075, 37.075, 37.075, //Type-A
513 -86.225, -86.225, -86.225, //Type-AR
514 -37.075, -37.075, -37.075, //Type-AR
515 86.225, 86.225, //Type-B
516 61.075, 61.075, //Type-B
517 35.925, 35.925, //Type-B
518 -86.225, -86.225, //Type-BR
519 -61.075, -61.075, //Type-BR
520 -35.925, -35.925 //Type-BR
524 if (ism > 23) ism -= 24;
529 xism = kXcorner[ism] + kRad;
530 yism = kYcorner[ism] + kRad;
531 dxism = -kRad*kSqRoot3*48.;
532 dyism = -kDia*96. - kRad;
534 if (ism >= 6 && ism < 12)
536 xism = kXcorner[ism] - kRad;
537 yism = kYcorner[ism] - kRad;
538 dxism = kRad*kSqRoot3*48.;
539 dyism = kDia*96. + kRad;
541 if (ism >= 12 && ism < 18)
543 xism = kXcorner[ism] + kRad;
544 yism = kYcorner[ism] + kRad;
545 dxism = -kRad*kSqRoot3*96.;
546 dyism = -kDia*48. - kRad;
548 if (ism >= 18 && ism < 24)
550 xism = kXcorner[ism] - kRad;
551 yism = kYcorner[ism] - kRad;
552 dxism = kRad*kSqRoot3*96.;
553 dyism = kDia*48. + kRad;
557 x2ism = xism + dxism;
559 y2ism = yism + dyism;
562 // ------------------------------------------------------------------- //
564 void AliPMDUtility::DrawPMDModule(Int_t idet)
567 Float_t x1ism = 0., x2ism = 0., y1ism = 0., y2ism = 0.;
568 Float_t deltaX = 0., deltaY = 0.;
570 //TH2F *h2 = new TH2F("h2","Y vs. X",200,-100.,100.,200,-100.,100.);
581 for(Int_t ism=0; ism < 24; ism++)
583 GenerateBoundaryPoints(ism, x1ism, y1ism, x2ism, y2ism);
584 deltaX = (x2ism - x1ism)/2.;
585 deltaY = (y2ism - y1ism)/2.;
586 if (fWriteModule == 1)
590 sprintf(smnumber,"%d",ism);
594 sprintf(smnumber,"%d",24+ism);
596 tt.DrawText(x1ism+deltaX,y1ism+deltaY,smnumber);
598 t.DrawLine(x1ism, y1ism, x1ism, y2ism);
599 t.DrawLine(x1ism, y1ism, x2ism, y1ism);
600 t.DrawLine(x2ism, y1ism, x2ism, y2ism);
601 t.DrawLine(x1ism, y2ism, x2ism, y2ism);
606 // ------------------------------------------------------------------- //
609 void AliPMDUtility::ApplyVertexCorrection(Float_t vertex[], Float_t xpos,
610 Float_t ypos, Float_t zpos)
613 fPx = xpos - vertex[0];
614 fPy = ypos - vertex[1];
615 fPz = zpos - vertex[2];
617 void AliPMDUtility::ApplyAlignment()
619 // Get the alignment stuff here
621 AliAlignObjMatrix * aam;
623 //Double_t secTr[4][3];
625 for (Int_t isector=0; isector<4; isector++)
627 aam = (AliAlignObjMatrix*)fAlObj->UncheckedAt(isector);
628 aam->GetTranslation(tr);
630 for(Int_t ixyz=0; ixyz < 3; ixyz++)
632 fSecTr[isector][ixyz] = (Float_t) tr[ixyz];
637 void AliPMDUtility::SetPxPyPz(Float_t px, Float_t py, Float_t pz)
644 void AliPMDUtility::SetXYZ(Float_t xpos, Float_t ypos, Float_t zpos)
650 void AliPMDUtility::SetWriteModule(Int_t wrmod)
652 fWriteModule = wrmod;
654 void AliPMDUtility::CalculateEta()
656 Float_t rpxpy = TMath::Sqrt(fPx*fPx + fPy*fPy);
657 Float_t theta = TMath::ATan2(rpxpy,fPz);
658 Float_t eta = -TMath::Log(TMath::Tan(0.5*theta));
662 void AliPMDUtility::CalculatePhi()
664 Float_t pybypx = 0., phi = 0., phi1 = 0.;
669 if(fPy<0) phi = 270.;
674 if(pybypx < 0) pybypx = - pybypx;
675 phi1 = TMath::ATan(pybypx)*180./3.14159;
677 if(fPx > 0 && fPy > 0) phi = phi1; // 1st Quadrant
678 if(fPx < 0 && fPy > 0) phi = 180 - phi1; // 2nd Quadrant
679 if(fPx < 0 && fPy < 0) phi = 180 + phi1; // 3rd Quadrant
680 if(fPx > 0 && fPy < 0) phi = 360 - phi1; // 4th Quadrant
683 phi = phi*3.14159/180.;
688 void AliPMDUtility::CalculateEtaPhi()
690 Float_t pybypx = 0., phi = 0., phi1 = 0.;
692 Float_t rpxpy = TMath::Sqrt(fPx*fPx + fPy*fPy);
693 Float_t theta = TMath::ATan2(rpxpy,fPz);
694 Float_t eta = -TMath::Log(TMath::Tan(0.5*theta));
699 if(fPy<0) phi = 270.;
704 if(pybypx < 0) pybypx = - pybypx;
705 phi1 = TMath::ATan(pybypx)*180./3.14159;
706 if(fPx > 0 && fPy > 0) phi = phi1; // 1st Quadrant
707 if(fPx < 0 && fPy > 0) phi = 180 - phi1; // 2nd Quadrant
708 if(fPx < 0 && fPy < 0) phi = 180 + phi1; // 3rd Quadrant
709 if(fPx > 0 && fPy < 0) phi = 360 - phi1; // 4th Quadrant
712 phi = phi*3.14159/180.;
718 void AliPMDUtility::CalculateXY(Float_t eta, Float_t phi, Float_t zpos)
722 // eta = -TMath::Log(TMath::Tan(0.5*theta));
724 Float_t xpos = 0., ypos = 0.;
726 // Float_t theta = 2.0*TMath::ATan(TMath::Log(-eta));
734 Float_t AliPMDUtility::GetTheta() const
738 Float_t AliPMDUtility::GetEta() const
742 Float_t AliPMDUtility::GetPhi() const
746 Float_t AliPMDUtility::GetX() const
750 Float_t AliPMDUtility::GetY() const
754 Float_t AliPMDUtility::GetZ() const
758 //--------------------------------------------------------------------//
759 TClonesArray* AliPMDUtility::GetAlignObj() const
761 // The run number will be centralized in AliCDBManager,
762 // you don't need to set it here!
763 AliCDBEntry *entry = AliCDBManager::Instance()->Get("PMD/Align/Data");
765 if(!entry) AliFatal("Alignment object retrieval failed!");
767 TClonesArray *alobj = 0;
768 if (entry) alobj = (TClonesArray*) entry->GetObject();
770 if (!alobj) AliFatal("No alignment data from database !");