]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - FMD/AliFMDRing.cxx
Added calculation of a strip in a FMD ring
[u/mrichter/AliRoot.git] / FMD / AliFMDRing.cxx
... / ...
CommitLineData
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/* $Id$ */
16/** @file AliFMDRing.cxx
17 @author Christian Holm Christensen <cholm@nbi.dk>
18 @date Mon Mar 27 12:47:43 2006
19 @brief FMD ring geometry parameters
20*/
21//__________________________________________________________________
22//
23// Utility class to help implement collection of FMD modules into
24// rings. This is used by AliFMDDetector and AliFMDGeometry.
25// The AliFMDGeometry object owns the AliFMDRing objects, and the
26// AliFMDDetector objects reference these. That is, the AliFMDRing
27// objects are share amoung the AliFMDDetector objects.
28//
29// Latest changes by Christian Holm Christensen
30//
31
32#include <TMath.h> // ROOT_TMath
33#include <TVector2.h> // ROOT_TVector2
34
35// #include <AliLog.h> // ALILOG_H
36#include "AliFMDRing.h" // ALIFMDRING_H
37
38//====================================================================
39ClassImp(AliFMDRing)
40#if 0
41 ; // This is here to keep Emacs for indenting the next line
42#endif
43
44//____________________________________________________________________
45AliFMDRing::AliFMDRing(Char_t id)
46 : TNamed(Form("FMD%c", id), "Forward multiplicity ring"),
47 fId(id),
48 fBondingWidth(0),
49 fWaferRadius(0),
50 fSiThickness(0),
51 fLowR(0),
52 fHighR(0),
53 fMinR(0),
54 fMaxR(0),
55 fTheta(0),
56 fNStrips(0),
57 fRingDepth(0),
58 fLegRadius(0),
59 fLegLength(0),
60 fLegOffset(0),
61 fModuleSpacing(0),
62 fPrintboardThickness(0),
63 fCopperThickness(0),
64 fChipThickness(0),
65 fSpacing(0),
66 fHoneycombThickness(0.),
67 fAlThickness(0.),
68 fVerticies(0),
69 fSensorVerticies(0),
70 fHybridVerticies(0),
71 fFeetPositions(0)
72{
73 // CTOR
74 SetBondingWidth();
75 SetWaferRadius();
76 SetSiThickness();
77 SetLegRadius();
78 SetLegLength();
79 SetLegOffset();
80 SetModuleSpacing();
81 SetPrintboardThickness();
82 SetCopperThickness();
83 SetChipThickness();
84 SetSpacing();
85 SetHoneycombThickness();
86 SetAlThickness();
87
88 if (fId == 'I' || fId == 'i') {
89 SetLowR(4.3);
90 SetHighR(17.2);
91 SetTheta(36/2);
92 SetNStrips(512);
93 Double_t base = 0; // 4.1915;
94 fFeetPositions.Add(new TVector2( 0.0551687, 8.0534-base));
95 fFeetPositions.Add(new TVector2( 2.9993, 12.9457-base));
96 fFeetPositions.Add(new TVector2(-2.9062, 12.9508-base));
97
98 fHybridVerticies.Add(new TVector2(0.0000, 4.1700));
99 fHybridVerticies.Add(new TVector2(1.0574, 4.1700));
100 fHybridVerticies.Add(new TVector2(4.6614, 15.2622));
101 fHybridVerticies.Add(new TVector2(0.9643, 17.4000));
102 fHybridVerticies.Add(new TVector2(0.0000, 17.4000));
103
104 fSensorVerticies.Add(new TVector2(0.0000, 4.1915));
105 fSensorVerticies.Add(new TVector2(1.5793, 4.1915));
106 fSensorVerticies.Add(new TVector2(5.2293, 15.4251));
107 fSensorVerticies.Add(new TVector2(1.9807, 17.3035));
108 fSensorVerticies.Add(new TVector2(0.0000, 17.3035));
109
110 fVerticies.Add(new TVector2(0.0000, 4.3000));
111 fVerticies.Add(new TVector2(1.3972, 4.3000));
112 fVerticies.Add(new TVector2(4.9895, 15.3560));
113 fVerticies.Add(new TVector2(1.8007, 17.2000));
114 fVerticies.Add(new TVector2(0.0000, 17.2000));
115 }
116 else if (fId == 'O' || fId == 'o') {
117 SetLowR(15.6);
118 SetHighR(28.0);
119 SetTheta(18/2);
120 SetNStrips(256);
121 Double_t base = 0; // 14.9104;
122 fFeetPositions.Add(new TVector2(-1.72540000, 20.6267-base));
123 fFeetPositions.Add(new TVector2( 1.72900000, 20.6267-base));
124 fFeetPositions.Add(new TVector2( 0.00177616, 26.6007-base));
125
126 fHybridVerticies.Add(new TVector2(0.0000, 14.9104));
127 fHybridVerticies.Add(new TVector2(2.0783, 14.9104));
128 fHybridVerticies.Add(new TVector2(3.9202, 26.5395));
129 fHybridVerticies.Add(new TVector2(0.6784, 28.2500));
130 fHybridVerticies.Add(new TVector2(0.0000, 28.2500));
131
132 fSensorVerticies.Add(new TVector2(0.0000, 15.0104));
133 fSensorVerticies.Add(new TVector2(2.5799, 15.0104));
134 fSensorVerticies.Add(new TVector2(4.4439, 26.7766));
135 fSensorVerticies.Add(new TVector2(1.8350, 28.1500));
136 fSensorVerticies.Add(new TVector2(0.0000, 28.1500));
137
138 fVerticies.Add(new TVector2(0.0000, 15.2104));
139 fVerticies.Add(new TVector2(2.4091, 15.2104));
140 fVerticies.Add(new TVector2(4.2231, 26.6638));
141 fVerticies.Add(new TVector2(1.8357, 27.9500));
142 fVerticies.Add(new TVector2(0.0000, 27.9500));
143 }
144}
145
146//____________________________________________________________________
147void
148AliFMDRing::Init()
149{
150 // Initialize
151#if 0
152 Double_t tanTheta = TMath::Tan(fTheta * TMath::Pi() / 180.);
153 Double_t tanTheta2 = TMath::Power(tanTheta,2);
154 Double_t r2 = TMath::Power(fWaferRadius,2);
155 Double_t yA = tanTheta * fLowR;
156 Double_t lr2 = TMath::Power(fLowR, 2);
157 Double_t hr2 = TMath::Power(fHighR,2);
158 Double_t xD = fLowR + TMath::Sqrt(r2 - tanTheta2 * lr2);
159 Double_t xD2 = TMath::Power(xD,2);
160 Double_t yB = TMath::Sqrt(r2 - hr2 + 2 * fHighR * xD - xD2);
161 Double_t xC = ((xD + TMath::Sqrt(-tanTheta2 * xD2 + r2
162 + r2 * tanTheta2))
163 / (1 + tanTheta2));
164 Double_t yC = tanTheta * xC;
165
166 fVerticies.Expand(6);
167 fVerticies.AddAt(new TVector2(fLowR, -yA), 0);
168 fVerticies.AddAt(new TVector2(xC, -yC), 1);
169 fVerticies.AddAt(new TVector2(fHighR, -yB), 2);
170 fVerticies.AddAt(new TVector2(fHighR, yB), 3);
171 fVerticies.AddAt(new TVector2(xC, yC), 4);
172 fVerticies.AddAt(new TVector2(fLowR, yA), 5);
173#endif
174
175 // A's length. Corresponds to distance from nominal beam line to the
176 // cornor of the active silicon element.
177 fMinR = GetVertex(1)->Mod(); // GetVertex(5)->Mod();
178 // A's length. Corresponds to distance from nominal beam line to the
179 // cornor of the active silicon element.
180 fMaxR = fHighR;
181
182 fRingDepth = (fSiThickness + fPrintboardThickness
183 + fCopperThickness + fChipThickness
184 + fLegLength + fModuleSpacing + fSpacing);
185}
186
187//____________________________________________________________________
188TVector2*
189AliFMDRing::GetVertex(Int_t i) const
190{
191 // Get the i'th vertex of polygon shape
192 return static_cast<TVector2*>(fVerticies.At(i));
193}
194
195//____________________________________________________________________
196TVector2*
197AliFMDRing::GetSensorVertex(Int_t i) const
198{
199 // Get the i'th vertex of polygon shape
200 return static_cast<TVector2*>(fSensorVerticies.At(i));
201}
202
203//____________________________________________________________________
204TVector2*
205AliFMDRing::GetHybridVertex(Int_t i) const
206{
207 // Get the i'th vertex of polygon shape
208 return static_cast<TVector2*>(fHybridVerticies.At(i));
209}
210
211//____________________________________________________________________
212TVector2*
213AliFMDRing::GetFootPosition(Int_t i) const
214{
215 // Get the i'th vertex of polygon shape
216 return static_cast<TVector2*>(fFeetPositions.At(i));
217}
218
219//____________________________________________________________________
220Double_t
221AliFMDRing::GetStripRadius(UShort_t strip) const
222{
223 // Return the nominal strip radius
224 Double_t rmax = GetMaxR();
225 Double_t stripoff = GetMinR();
226 Double_t dstrip = (rmax - stripoff) / GetNStrips();
227 return (strip + .5) * dstrip + stripoff; // fLowR
228}
229
230//____________________________________________________________________
231Double_t
232AliFMDRing::GetModuleDepth() const
233{
234 return (GetSiThickness()
235 + GetSpacing()
236 + GetPrintboardThickness()
237 + GetCopperThickness()
238 + GetChipThickness()
239 + GetLegLength());
240
241}
242
243//____________________________________________________________________
244Double_t
245AliFMDRing::GetFullDepth() const
246{
247 return (GetModuleDepth()
248 + GetModuleSpacing()
249 + GetHoneycombThickness()
250 + GetFMDDPrintboardThickness()
251 + GetFMDDCopperThickness()
252 + GetFMDDChipThickness()
253 + 0.5);
254}
255
256//____________________________________________________________________
257void
258AliFMDRing::Detector2XYZ(UShort_t sector,
259 UShort_t strip,
260 Double_t& x,
261 Double_t& y,
262 Double_t& z) const
263{
264 // Translate detector coordinates (this,sector,strip) to global
265 // coordinates (x,y,z)
266 if (sector >= GetNSectors()) {
267 Error("Detector2XYZ", "Invalid sector number %d (>=%d) in ring %c",
268 sector, GetNSectors(), fId);
269 return;
270 }
271 if (strip >= GetNStrips()) {
272 Error("Detector2XYZ", "Invalid strip number %d (>=%d)",
273 strip, GetNStrips(), fId);
274 return;
275 }
276 Double_t phi = Float_t(sector + .5) / GetNSectors() * 2 * TMath::Pi();
277 Double_t r = Float_t(strip + .5) / GetNStrips() * (fHighR - fLowR) + fLowR;
278 x = r * TMath::Cos(phi);
279 y = r * TMath::Sin(phi);
280 if (((sector / 2) % 2) == 1)
281 z += TMath::Sign(fModuleSpacing, z);
282}
283
284//____________________________________________________________________
285Bool_t
286AliFMDRing::XYZ2Detector(Double_t x,
287 Double_t y,
288 Double_t z,
289 UShort_t& sector,
290 UShort_t& strip) const
291{
292 // Translate global coordinates (x,y,z) to detector coordinates
293 // (this,sector,strip)
294 sector = strip = 0;
295 Double_t r = TMath::Sqrt(x * x + y * y);
296 Int_t str = Int_t((r - fMinR) / GetPitch());
297 if (str < 0 || str >= GetNStrips()) return kFALSE;
298
299 Double_t phi = TMath::ATan2(y, x) * 180. / TMath::Pi();
300 if (phi < 0) phi = 360. + phi;
301 Int_t sec = Int_t(phi / fTheta);
302 if (sec < 0 || sec >= GetNSectors()) return kFALSE;
303 if ((sec / 2) % 2 == 1) {
304 if (TMath::Abs(z - TMath::Sign(fModuleSpacing, z)) >= 0.01)
305 return kFALSE;
306 }
307 else if (TMath::Abs(z) >= 0.01) return kFALSE;
308
309 strip = str;
310 sector = sec;
311 return kTRUE;
312}
313//____________________________________________________________________
314Float_t
315AliFMDRing::GetStripLength(UShort_t strip) const
316{
317 if(strip >= GetNStrips())
318 Error("GetStripLength", "Invalid strip number %d (>=%d)",
319 strip, GetNStrips(), fId);
320
321 Float_t rad = GetMaxR()-GetMinR();
322
323 Float_t segment = rad / GetNStrips();
324
325 TVector2* corner1 = GetVertex(2);
326 TVector2* corner2 = GetVertex(3);
327
328 Float_t slope = (corner1->Y() - corner2->Y()) / (corner1->X() - corner2->X());
329 Float_t constant = (corner2->Y()*corner1->X()-(corner2->X()*corner1->Y())) / (corner1->X() - corner2->X());
330 Float_t radius = GetMinR() + strip*segment;
331
332 Float_t d = TMath::Power(TMath::Abs(radius*slope),2) + TMath::Power(radius,2) - TMath::Power(constant,2);
333
334 Float_t arclength = GetBaseStripLength(strip);
335 if(d>0) {
336
337 Float_t x = (-1*TMath::Sqrt(d) -slope*constant) / (1+TMath::Power(slope,2));
338 Float_t y = slope*x + constant;
339 Float_t theta = TMath::ATan2(x,y);
340
341 if(x < corner1->X() && y > corner1->Y()) {
342 arclength = radius*theta; //One sector since theta is by definition half-hybrid
343
344 }
345
346 }
347
348 return arclength;
349
350
351}
352//____________________________________________________________________
353Float_t
354AliFMDRing::GetBaseStripLength(UShort_t strip) const
355{
356 Float_t rad = GetMaxR()-GetMinR();
357 Float_t segment = rad / GetNStrips();
358 Float_t basearc = 2*TMath::Pi() / (0.5*GetNSectors()); // One hybrid: 36 degrees inner, 18 outer
359 Float_t radius = GetMinR() + strip*segment;
360 Float_t basearclength = 0.5*basearc * radius; // One sector
361
362 return basearclength;
363}
364//
365// EOF
366//