]> git.uio.no Git - u/mrichter/AliRoot.git/blob - FMD/AliFMDRing.cxx
Added new library libFMDutil. This library contains utility classes that
[u/mrichter/AliRoot.git] / FMD / AliFMDRing.cxx
1 /**************************************************************************
2  * Copyright(c) 2004, 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 /* $Id$ */
17
18 //__________________________________________________________________
19 //
20 // Utility class to help implement collection of FMD modules into
21 // rings.  This is used by AliFMDDetector and AliFMDGeometry.  
22 //
23 // The AliFMDGeometry object owns the AliFMDRing objects, and the
24 // AliFMDDetector objects reference these.  That is, the AliFMDRing
25 // objects are share amoung the AliFMDDetector objects.
26 //
27 // Latest changes by Christian Holm Christensen
28 //
29
30 #include <AliLog.h>             // ALILOG_H
31 #include "AliFMDRing.h"         // ALIFMDRING_H
32 #include <TMath.h>              // ROOT_TMath
33 #include <TVector2.h>           // ROOT_TVector2
34
35 //====================================================================
36 ClassImp(AliFMDRing)
37 #if 0
38   ; // This is here to keep Emacs for indenting the next line
39 #endif
40
41 //____________________________________________________________________
42 AliFMDRing::AliFMDRing(Char_t id) 
43   : TNamed(Form("FMD%c", id), "Forward multiplicity ring"), 
44     fId(id), 
45     fVerticies(0)
46 {
47   SetBondingWidth();
48   SetWaferRadius();
49   SetSiThickness();
50   SetLegRadius();
51   SetLegLength();
52   SetLegOffset();
53   SetModuleSpacing();
54   SetPrintboardThickness();
55   SetCopperThickness();
56   SetChipThickness();
57   SetSpacing();
58   
59   if (fId == 'I' || fId == 'i') {
60     SetLowR(4.3);
61     SetHighR(17.2);
62     SetTheta(36/2);
63     SetNStrips(512);
64   }
65   else if (fId == 'O' || fId == 'o') {
66     SetLowR(15.6);
67     SetHighR(28.0);
68     SetTheta(18/2);
69     SetNStrips(256);
70   }
71 }
72
73 //____________________________________________________________________
74 void
75 AliFMDRing::Init()
76 {
77   Double_t tanTheta  = TMath::Tan(fTheta * TMath::Pi() / 180.);
78   Double_t tanTheta2 = TMath::Power(tanTheta,2);
79   Double_t r2        = TMath::Power(fWaferRadius,2);
80   Double_t yA        = tanTheta * fLowR;
81   Double_t lr2       = TMath::Power(fLowR, 2);
82   Double_t hr2       = TMath::Power(fHighR,2);
83   Double_t xD        = fLowR + TMath::Sqrt(r2 - tanTheta2 * lr2);
84   Double_t xD2       = TMath::Power(xD,2);
85   Double_t yB        = TMath::Sqrt(r2 - hr2 + 2 * fHighR * xD - xD2);
86   Double_t xC        = ((xD + TMath::Sqrt(-tanTheta2 * xD2 + r2
87                                           + r2 * tanTheta2)) 
88                         / (1 + tanTheta2));
89   Double_t yC        = tanTheta * xC;
90   
91   fVerticies.Expand(6);
92   fVerticies.AddAt(new TVector2(fLowR,  -yA), 0);
93   fVerticies.AddAt(new TVector2(xC,     -yC), 1);
94   fVerticies.AddAt(new TVector2(fHighR, -yB), 2);
95   fVerticies.AddAt(new TVector2(fHighR,  yB), 3);
96   fVerticies.AddAt(new TVector2(xC,      yC), 4);
97   fVerticies.AddAt(new TVector2(fLowR,   yA), 5);  
98
99   // A's length. Corresponds to distance from nominal beam line to the
100   // cornor of the active silicon element. 
101   fMinR = GetVertex(5)->Mod();
102   // A's length. Corresponds to distance from nominal beam line to the
103   // cornor of the active silicon element. 
104   fMaxR = fHighR;
105
106   fRingDepth = (fSiThickness + fPrintboardThickness 
107                 + fCopperThickness + fChipThickness 
108                 + fLegLength + fModuleSpacing + fSpacing);
109 }
110
111 //____________________________________________________________________
112 TVector2*
113 AliFMDRing::GetVertex(Int_t i) const
114 {
115   return static_cast<TVector2*>(fVerticies.At(i));
116 }
117
118 //____________________________________________________________________
119 void
120 AliFMDRing::Detector2XYZ(UShort_t sector,
121                          UShort_t strip, 
122                          Double_t& x, 
123                          Double_t& y, 
124                          Double_t& z) const
125 {
126   if (sector >= GetNSectors()) {
127     Error("Detector2XYZ", "Invalid sector number %d (>=%d) in ring %c", 
128           sector, GetNSectors(), fId);
129     return;
130   }
131   if (strip >= GetNStrips()) {
132     Error("Detector2XYZ", "Invalid strip number %d (>=%d)", 
133           strip, GetNStrips(), fId);
134     return;
135   }
136   Double_t phi = Float_t(sector + .5) / GetNSectors() * 2 * TMath::Pi();
137   Double_t r   = Float_t(strip + .5) / GetNStrips() * (fHighR - fLowR) + fLowR;
138   x = r * TMath::Cos(phi);
139   y = r * TMath::Sin(phi);
140   if (((sector / 2) % 2) == 1) 
141     z += TMath::Sign(fModuleSpacing, z);
142 }
143
144 //____________________________________________________________________
145 Bool_t
146 AliFMDRing::XYZ2Detector(Double_t  x, 
147                          Double_t  y, 
148                          Double_t  z,
149                          UShort_t& sector,
150                          UShort_t& strip) const
151 {
152   sector = strip = 0;
153   Double_t r = TMath::Sqrt(x * x + y * y);
154   Int_t str = Int_t((r - fMinR) / GetPitch());
155   if (str < 0 || str >= GetNStrips()) return kFALSE;
156
157   Double_t phi = TMath::ATan2(y, x) * 180. / TMath::Pi();
158   if (phi < 0) phi = 360. + phi;
159   Int_t sec = Int_t(phi / fTheta);
160   if (sec < 0 || sec >= GetNSectors()) return kFALSE;
161   if ((sec / 2) % 2 == 1) {
162     if (TMath::Abs(z - TMath::Sign(fModuleSpacing, z)) >= 0.01)
163       return kFALSE;
164   }
165   else if (TMath::Abs(z) >= 0.01) return kFALSE;
166
167   strip  = str;
168   sector = sec;
169   return kTRUE;
170 }
171
172
173 //
174 // EOF
175 //