undo previous changes
[u/mrichter/AliRoot.git] / FMD / AliFMDRing.cxx
CommitLineData
4347b38f 1/**************************************************************************
c4bcfd14 2 * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
4347b38f 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 **************************************************************************/
4347b38f 15/* $Id$ */
c2fc1258 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*/
c4bcfd14 21//__________________________________________________________________
4347b38f 22//
23// Utility class to help implement collection of FMD modules into
6169f936 24// rings. This is used by AliFMDDetector and AliFMDGeometry.
1a1fdef7 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.
4347b38f 28//
29// Latest changes by Christian Holm Christensen
30//
5edc364e 31
9edefa04 32#include <TMath.h> // ROOT_TMath
33#include <TVector2.h> // ROOT_TVector2
34
02a27b50 35// #include <AliLog.h> // ALILOG_H
e802be3e 36#include "AliFMDRing.h" // ALIFMDRING_H
4347b38f 37
1a1fdef7 38//====================================================================
e6a0eb08 39ClassImp(AliFMDRing)
1a1fdef7 40#if 0
41 ; // This is here to keep Emacs for indenting the next line
42#endif
4347b38f 43
44//____________________________________________________________________
1a1fdef7 45AliFMDRing::AliFMDRing(Char_t id)
46 : TNamed(Form("FMD%c", id), "Forward multiplicity ring"),
47 fId(id),
b5ee4425 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),
d98fbfa5 66 fHoneycombThickness(0.),
67 fAlThickness(0.),
f70f588a 68 fVerticies(0),
69 fSensorVerticies(0),
70 fHybridVerticies(0),
71 fFeetPositions(0)
4347b38f 72{
40fa2e58 73 // Constructor
74 //
75 // Parameters:
76 // id Type of ring (either 'I' or 'O')
77 //
1a1fdef7 78 SetBondingWidth();
79 SetWaferRadius();
80 SetSiThickness();
81 SetLegRadius();
82 SetLegLength();
83 SetLegOffset();
84 SetModuleSpacing();
85 SetPrintboardThickness();
4ac75127 86 SetCopperThickness();
87 SetChipThickness();
a1f80595 88 SetSpacing();
d98fbfa5 89 SetHoneycombThickness();
90 SetAlThickness();
4347b38f 91
1a1fdef7 92 if (fId == 'I' || fId == 'i') {
93 SetLowR(4.3);
94 SetHighR(17.2);
95 SetTheta(36/2);
96 SetNStrips(512);
f70f588a 97 Double_t base = 0; // 4.1915;
98 fFeetPositions.Add(new TVector2( 0.0551687, 8.0534-base));
99 fFeetPositions.Add(new TVector2( 2.9993, 12.9457-base));
100 fFeetPositions.Add(new TVector2(-2.9062, 12.9508-base));
101
102 fHybridVerticies.Add(new TVector2(0.0000, 4.1700));
103 fHybridVerticies.Add(new TVector2(1.0574, 4.1700));
104 fHybridVerticies.Add(new TVector2(4.6614, 15.2622));
105 fHybridVerticies.Add(new TVector2(0.9643, 17.4000));
106 fHybridVerticies.Add(new TVector2(0.0000, 17.4000));
107
108 fSensorVerticies.Add(new TVector2(0.0000, 4.1915));
109 fSensorVerticies.Add(new TVector2(1.5793, 4.1915));
110 fSensorVerticies.Add(new TVector2(5.2293, 15.4251));
111 fSensorVerticies.Add(new TVector2(1.9807, 17.3035));
112 fSensorVerticies.Add(new TVector2(0.0000, 17.3035));
113
114 fVerticies.Add(new TVector2(0.0000, 4.3000));
115 fVerticies.Add(new TVector2(1.3972, 4.3000));
116 fVerticies.Add(new TVector2(4.9895, 15.3560));
117 fVerticies.Add(new TVector2(1.8007, 17.2000));
118 fVerticies.Add(new TVector2(0.0000, 17.2000));
1a1fdef7 119 }
120 else if (fId == 'O' || fId == 'o') {
121 SetLowR(15.6);
122 SetHighR(28.0);
123 SetTheta(18/2);
124 SetNStrips(256);
f70f588a 125 Double_t base = 0; // 14.9104;
126 fFeetPositions.Add(new TVector2(-1.72540000, 20.6267-base));
127 fFeetPositions.Add(new TVector2( 1.72900000, 20.6267-base));
128 fFeetPositions.Add(new TVector2( 0.00177616, 26.6007-base));
129
130 fHybridVerticies.Add(new TVector2(0.0000, 14.9104));
131 fHybridVerticies.Add(new TVector2(2.0783, 14.9104));
132 fHybridVerticies.Add(new TVector2(3.9202, 26.5395));
133 fHybridVerticies.Add(new TVector2(0.6784, 28.2500));
134 fHybridVerticies.Add(new TVector2(0.0000, 28.2500));
135
136 fSensorVerticies.Add(new TVector2(0.0000, 15.0104));
137 fSensorVerticies.Add(new TVector2(2.5799, 15.0104));
138 fSensorVerticies.Add(new TVector2(4.4439, 26.7766));
139 fSensorVerticies.Add(new TVector2(1.8350, 28.1500));
140 fSensorVerticies.Add(new TVector2(0.0000, 28.1500));
141
142 fVerticies.Add(new TVector2(0.0000, 15.2104));
143 fVerticies.Add(new TVector2(2.4091, 15.2104));
144 fVerticies.Add(new TVector2(4.2231, 26.6638));
145 fVerticies.Add(new TVector2(1.8357, 27.9500));
146 fVerticies.Add(new TVector2(0.0000, 27.9500));
4347b38f 147 }
4347b38f 148}
149
4347b38f 150//____________________________________________________________________
151void
1a1fdef7 152AliFMDRing::Init()
4347b38f 153{
088f8e79 154 // Initialize
40fa2e58 155 //
156 // All derived quantities are calculated here.
157 //
f70f588a 158#if 0
1a1fdef7 159 Double_t tanTheta = TMath::Tan(fTheta * TMath::Pi() / 180.);
160 Double_t tanTheta2 = TMath::Power(tanTheta,2);
161 Double_t r2 = TMath::Power(fWaferRadius,2);
162 Double_t yA = tanTheta * fLowR;
163 Double_t lr2 = TMath::Power(fLowR, 2);
164 Double_t hr2 = TMath::Power(fHighR,2);
165 Double_t xD = fLowR + TMath::Sqrt(r2 - tanTheta2 * lr2);
166 Double_t xD2 = TMath::Power(xD,2);
167 Double_t yB = TMath::Sqrt(r2 - hr2 + 2 * fHighR * xD - xD2);
168 Double_t xC = ((xD + TMath::Sqrt(-tanTheta2 * xD2 + r2
169 + r2 * tanTheta2))
170 / (1 + tanTheta2));
171 Double_t yC = tanTheta * xC;
4347b38f 172
1a1fdef7 173 fVerticies.Expand(6);
174 fVerticies.AddAt(new TVector2(fLowR, -yA), 0);
175 fVerticies.AddAt(new TVector2(xC, -yC), 1);
176 fVerticies.AddAt(new TVector2(fHighR, -yB), 2);
177 fVerticies.AddAt(new TVector2(fHighR, yB), 3);
178 fVerticies.AddAt(new TVector2(xC, yC), 4);
179 fVerticies.AddAt(new TVector2(fLowR, yA), 5);
f70f588a 180#endif
1a1fdef7 181
54e415a8 182 // A's length. Corresponds to distance from nominal beam line to the
183 // cornor of the active silicon element.
f70f588a 184 fMinR = GetVertex(1)->Mod(); // GetVertex(5)->Mod();
54e415a8 185 // A's length. Corresponds to distance from nominal beam line to the
186 // cornor of the active silicon element.
187 fMaxR = fHighR;
188
1a1fdef7 189 fRingDepth = (fSiThickness + fPrintboardThickness
4ac75127 190 + fCopperThickness + fChipThickness
191 + fLegLength + fModuleSpacing + fSpacing);
4347b38f 192}
193
194//____________________________________________________________________
1a1fdef7 195TVector2*
196AliFMDRing::GetVertex(Int_t i) const
4347b38f 197{
088f8e79 198 // Get the i'th vertex of polygon shape
40fa2e58 199 //
200 // the polygon shape describes the shape of the rings' sensors
201 //
202 // Parameters:
203 // i The vertex number to get (from 0 to 5)
1a1fdef7 204 return static_cast<TVector2*>(fVerticies.At(i));
4347b38f 205}
206
207//____________________________________________________________________
f70f588a 208TVector2*
209AliFMDRing::GetSensorVertex(Int_t i) const
210{
211 // Get the i'th vertex of polygon shape
40fa2e58 212 //
213 // the polygon shape describes the shape of the rings' sensors
214 //
215 // Parameters:
216 // i The vertex number to get (from 0 to 5)
f70f588a 217 return static_cast<TVector2*>(fSensorVerticies.At(i));
218}
219
220//____________________________________________________________________
221TVector2*
222AliFMDRing::GetHybridVertex(Int_t i) const
223{
224 // Get the i'th vertex of polygon shape
40fa2e58 225 //
226 // the polygon shape describes the shape of the rings' hybrid cards
227 //
228 // Parameters:
229 // i The vertex number to get (from 0 to 5)
f70f588a 230 return static_cast<TVector2*>(fHybridVerticies.At(i));
231}
232
233//____________________________________________________________________
234TVector2*
235AliFMDRing::GetFootPosition(Int_t i) const
236{
237 // Get the i'th vertex of polygon shape
40fa2e58 238 //
239 // The feet are attached to the hybrid cards
240 //
241 // Parameters:
242 // i The foot number to get (from 0 to 2)
f70f588a 243 return static_cast<TVector2*>(fFeetPositions.At(i));
244}
245
246//____________________________________________________________________
bf000c32 247Double_t
248AliFMDRing::GetStripRadius(UShort_t strip) const
249{
250 // Return the nominal strip radius
40fa2e58 251 //
252 // Parameter
253 // strip Strip number (0-511 for inners, 0-255 for outers)
bf000c32 254 Double_t rmax = GetMaxR();
255 Double_t stripoff = GetMinR();
256 Double_t dstrip = (rmax - stripoff) / GetNStrips();
257 return (strip + .5) * dstrip + stripoff; // fLowR
258}
259
260//____________________________________________________________________
d98fbfa5 261Double_t
f70f588a 262AliFMDRing::GetModuleDepth() const
263{
40fa2e58 264 // Get the total depth of a module (sensor + hybrid card)
265 //
266 // The depth is the sum of
267 //
268 // The silicon thickness
269 // The thickness of spacers between the silicon and hybrid
270 // The thickness of the hybrid PCB
271 // The thickness of the copper layer in the PCB
272 // The thickness of the chip layer in the PCB
273 // The height of the legs
f70f588a 274 return (GetSiThickness()
275 + GetSpacing()
276 + GetPrintboardThickness()
277 + GetCopperThickness()
278 + GetChipThickness()
279 + GetLegLength());
280
281}
282
283//____________________________________________________________________
284Double_t
d98fbfa5 285AliFMDRing::GetFullDepth() const
286{
40fa2e58 287 // Get the full depth of this ring, including the honeycomb,
288 // digitizer and card.
f70f588a 289 return (GetModuleDepth()
290 + GetModuleSpacing()
291 + GetHoneycombThickness()
292 + GetFMDDPrintboardThickness()
293 + GetFMDDCopperThickness()
294 + GetFMDDChipThickness()
d98fbfa5 295 + 0.5);
296}
297
298//____________________________________________________________________
1a1fdef7 299void
300AliFMDRing::Detector2XYZ(UShort_t sector,
301 UShort_t strip,
302 Double_t& x,
303 Double_t& y,
304 Double_t& z) const
4347b38f 305{
088f8e79 306 // Translate detector coordinates (this,sector,strip) to global
307 // coordinates (x,y,z)
40fa2e58 308 //
309 // Parameters
310 // sector Sector number in this ring
311 // strip Strip number in this ring
312 // x On return, the global X coordinate
313 // y On return, the global Y coordinate
314 // z On return, the z coordinate in the ring plane
315 //
316 // The ring plane is the plane half way between the two sensor
317 // layers.
1a1fdef7 318 if (sector >= GetNSectors()) {
319 Error("Detector2XYZ", "Invalid sector number %d (>=%d) in ring %c",
320 sector, GetNSectors(), fId);
321 return;
4347b38f 322 }
1a1fdef7 323 if (strip >= GetNStrips()) {
324 Error("Detector2XYZ", "Invalid strip number %d (>=%d)",
325 strip, GetNStrips(), fId);
326 return;
4347b38f 327 }
1a1fdef7 328 Double_t phi = Float_t(sector + .5) / GetNSectors() * 2 * TMath::Pi();
329 Double_t r = Float_t(strip + .5) / GetNStrips() * (fHighR - fLowR) + fLowR;
330 x = r * TMath::Cos(phi);
331 y = r * TMath::Sin(phi);
332 if (((sector / 2) % 2) == 1)
333 z += TMath::Sign(fModuleSpacing, z);
4347b38f 334}
335
54e415a8 336//____________________________________________________________________
337Bool_t
338AliFMDRing::XYZ2Detector(Double_t x,
339 Double_t y,
340 Double_t z,
341 UShort_t& sector,
342 UShort_t& strip) const
343{
088f8e79 344 // Translate global coordinates (x,y,z) to detector coordinates
345 // (this,sector,strip)
40fa2e58 346 //
347 // Parameters:
348 // x Global x coordinate
349 // y Global y coordinate
350 // z Global y coordinate
351 // sector On return, the sector number in this ring
352 // strip On return, the strip number in this ring
353 //
54e415a8 354 sector = strip = 0;
355 Double_t r = TMath::Sqrt(x * x + y * y);
356 Int_t str = Int_t((r - fMinR) / GetPitch());
357 if (str < 0 || str >= GetNStrips()) return kFALSE;
358
359 Double_t phi = TMath::ATan2(y, x) * 180. / TMath::Pi();
360 if (phi < 0) phi = 360. + phi;
361 Int_t sec = Int_t(phi / fTheta);
362 if (sec < 0 || sec >= GetNSectors()) return kFALSE;
363 if ((sec / 2) % 2 == 1) {
364 if (TMath::Abs(z - TMath::Sign(fModuleSpacing, z)) >= 0.01)
365 return kFALSE;
366 }
367 else if (TMath::Abs(z) >= 0.01) return kFALSE;
368
369 strip = str;
370 sector = sec;
371 return kTRUE;
372}
fb848ec4 373//____________________________________________________________________
374Float_t
375AliFMDRing::GetStripLength(UShort_t strip) const
376{
40fa2e58 377 // Get the length of a strip
378 //
379 // Parameters:
380 // strip Strip number (0-511 for inners, 0-255 for outers)
381 //
fb848ec4 382 if(strip >= GetNStrips())
383 Error("GetStripLength", "Invalid strip number %d (>=%d)",
384 strip, GetNStrips(), fId);
385
386 Float_t rad = GetMaxR()-GetMinR();
387
388 Float_t segment = rad / GetNStrips();
389
390 TVector2* corner1 = GetVertex(2);
391 TVector2* corner2 = GetVertex(3);
392
40fa2e58 393 Float_t slope = ((corner1->Y() - corner2->Y()) /
394 (corner1->X() - corner2->X()));
395 Float_t constant = ((corner2->Y() * corner1->X() -
396 (corner2->X()*corner1->Y())) /
397 (corner1->X() - corner2->X()));
fb848ec4 398 Float_t radius = GetMinR() + strip*segment;
399
40fa2e58 400 Float_t d = (TMath::Power(TMath::Abs(radius*slope),2) +
401 TMath::Power(radius,2) - TMath::Power(constant,2));
fb848ec4 402
403 Float_t arclength = GetBaseStripLength(strip);
404 if(d>0) {
40fa2e58 405 Float_t x = ((-1 * TMath::Sqrt(d) -slope*constant) /
406 (1 + TMath::Power(slope,2)));
fb848ec4 407 Float_t y = slope*x + constant;
408 Float_t theta = TMath::ATan2(x,y);
409
410 if(x < corner1->X() && y > corner1->Y()) {
40fa2e58 411 //One sector since theta is by definition half-hybrid
412 arclength = radius*theta;
fb848ec4 413 }
fb848ec4 414 }
415
416 return arclength;
417
418
419}
420//____________________________________________________________________
421Float_t
422AliFMDRing::GetBaseStripLength(UShort_t strip) const
423{
40fa2e58 424 // Get the basic strip length
425 //
426 // Parameters:
427 // strip Strip number
fb848ec4 428 Float_t rad = GetMaxR()-GetMinR();
429 Float_t segment = rad / GetNStrips();
40fa2e58 430 Float_t basearc = 2*TMath::Pi() / (0.5*GetNSectors());
fb848ec4 431 Float_t radius = GetMinR() + strip*segment;
40fa2e58 432 Float_t basearclength = 0.5*basearc * radius;
fb848ec4 433
434 return basearclength;
435}
4347b38f 436//
437// EOF
438//