]> git.uio.no Git - u/mrichter/AliRoot.git/blob - FMD/AliFMDRing.cxx
Moving required CMake version from 2.8.4 to 2.8.8
[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 /* $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 //====================================================================
39 ClassImp(AliFMDRing)
40 #if 0
41   ; // This is here to keep Emacs for indenting the next line
42 #endif
43
44 //____________________________________________________________________
45 AliFMDRing::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   // Constructor 
74   // 
75   // Parameters: 
76   //    id      Type of ring (either 'I' or 'O') 
77   // 
78   SetBondingWidth();
79   SetWaferRadius();
80   SetSiThickness();
81   SetLegRadius();
82   SetLegLength();
83   SetLegOffset();
84   SetModuleSpacing();
85   SetPrintboardThickness();
86   SetCopperThickness();
87   SetChipThickness();
88   SetSpacing();
89   SetHoneycombThickness();
90   SetAlThickness();
91   
92   if (fId == 'I' || fId == 'i') {
93     SetLowR(4.3);
94     SetHighR(17.2);
95     SetTheta(36/2);
96     SetNStrips(512);
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));
119   }
120   else if (fId == 'O' || fId == 'o') {
121     SetLowR(15.6);
122     SetHighR(28.0);
123     SetTheta(18/2);
124     SetNStrips(256);
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));
147   }
148 }
149
150 //____________________________________________________________________
151 void
152 AliFMDRing::Init()
153 {
154   // Initialize 
155   // 
156   // All derived quantities are calculated here. 
157   // 
158 #if 0
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;
172   
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);  
180 #endif
181
182   // A's length. Corresponds to distance from nominal beam line to the
183   // cornor of the active silicon element. 
184   fMinR = GetVertex(1)->Mod(); // GetVertex(5)->Mod();
185   // A's length. Corresponds to distance from nominal beam line to the
186   // cornor of the active silicon element. 
187   fMaxR = fHighR;
188
189   fRingDepth = (fSiThickness + fPrintboardThickness 
190                 + fCopperThickness + fChipThickness 
191                 + fLegLength + fModuleSpacing + fSpacing);
192 }
193
194 //____________________________________________________________________
195 TVector2*
196 AliFMDRing::GetVertex(Int_t i) const
197 {
198   // Get the i'th vertex of polygon shape
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)
204   return static_cast<TVector2*>(fVerticies.At(i));
205 }
206
207 //____________________________________________________________________
208 TVector2*
209 AliFMDRing::GetSensorVertex(Int_t i) const
210 {
211   // Get the i'th vertex of polygon shape
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)
217   return static_cast<TVector2*>(fSensorVerticies.At(i));
218 }
219
220 //____________________________________________________________________
221 TVector2*
222 AliFMDRing::GetHybridVertex(Int_t i) const
223 {
224   // Get the i'th vertex of polygon shape
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)
230   return static_cast<TVector2*>(fHybridVerticies.At(i));
231 }
232
233 //____________________________________________________________________
234 TVector2*
235 AliFMDRing::GetFootPosition(Int_t i) const
236 {
237   // Get the i'th vertex of polygon shape
238   // 
239   // The feet are attached to the hybrid cards
240   // 
241   // Parameters: 
242   //     i    The foot number to get (from 0 to 2)
243   return static_cast<TVector2*>(fFeetPositions.At(i));
244 }
245
246 //____________________________________________________________________
247 Double_t
248 AliFMDRing::GetStripRadius(UShort_t strip) const
249 {
250   // Return the nominal strip radius 
251   // 
252   // Parameter 
253   //   strip    Strip number (0-511 for inners, 0-255 for outers)
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 //____________________________________________________________________
261 Double_t
262 AliFMDRing::GetModuleDepth() const
263 {
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
274   return (GetSiThickness() 
275           + GetSpacing() 
276           + GetPrintboardThickness()
277           + GetCopperThickness()
278           + GetChipThickness()
279           + GetLegLength());
280   
281 }
282
283 //____________________________________________________________________
284 Double_t
285 AliFMDRing::GetFullDepth() const
286 {
287   // Get the full depth of this ring, including the honeycomb, 
288   // digitizer and card. 
289   return (GetModuleDepth() 
290           + GetModuleSpacing()
291           + GetHoneycombThickness()
292           + GetFMDDPrintboardThickness()
293           + GetFMDDCopperThickness()
294           + GetFMDDChipThickness() 
295           + 0.5);
296 }
297
298 //____________________________________________________________________
299 void
300 AliFMDRing::Detector2XYZ(UShort_t sector,
301                          UShort_t strip, 
302                          Double_t& x, 
303                          Double_t& y, 
304                          Double_t& z) const
305 {
306   // Translate detector coordinates (this,sector,strip) to global
307   // coordinates (x,y,z)
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. 
318   if (sector >= GetNSectors()) {
319     Error("Detector2XYZ", "Invalid sector number %d (>=%d) in ring %c", 
320           sector, GetNSectors(), fId);
321     return;
322   }
323   if (strip >= GetNStrips()) {
324     Error("Detector2XYZ", "Invalid strip number %d (>=%d) for ring type '%c'", 
325           strip, GetNStrips(), fId);
326     return;
327   }
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);
334 }
335
336 //____________________________________________________________________
337 Bool_t
338 AliFMDRing::XYZ2Detector(Double_t  x, 
339                          Double_t  y, 
340                          Double_t  z,
341                          UShort_t& sector,
342                          UShort_t& strip) const
343 {
344   // Translate global coordinates (x,y,z) to detector coordinates
345   // (this,sector,strip)
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   // 
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 }
373 //____________________________________________________________________
374 Float_t 
375 AliFMDRing::GetStripLength(UShort_t strip) const 
376 {
377   // Get the length of a strip 
378   // 
379   // Parameters:
380   //   strip     Strip number (0-511 for inners, 0-255 for outers)
381   // 
382   if(strip >= GetNStrips())
383     Error("GetStripLength", "Invalid strip number %d (>=%d) for ring type %c", 
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   
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()));
398   Float_t radius     = GetMinR() + strip*segment;
399   
400   Float_t d          = (TMath::Power(TMath::Abs(radius*slope),2) + 
401                         TMath::Power(radius,2) - TMath::Power(constant,2));
402   
403   Float_t arclength  = GetBaseStripLength(strip);
404   if(d>0) {
405     Float_t x        = ((-1 * TMath::Sqrt(d) -slope*constant) / 
406                         (1 + TMath::Power(slope,2)));
407     Float_t y        = slope*x + constant;
408     Float_t theta    = TMath::ATan2(x,y);
409     
410     if(x < corner1->X() && y > corner1->Y()) {
411       //One sector since theta is by definition half-hybrid
412       arclength = radius*theta;
413     }
414   }
415   
416   return arclength;
417   
418   
419 }
420 //____________________________________________________________________
421 Float_t 
422 AliFMDRing::GetBaseStripLength(UShort_t strip) const 
423 {  
424   // Get the basic strip length 
425   // 
426   // Parameters:
427   //   strip    Strip number
428   Float_t rad             = GetMaxR()-GetMinR();
429   Float_t segment         = rad / GetNStrips();
430   Float_t basearc         = 2*TMath::Pi() / (0.5*GetNSectors()); 
431   Float_t radius          = GetMinR() + strip*segment;
432   Float_t basearclength   = 0.5*basearc * radius;                
433   
434   return basearclength;
435 }
436 //
437 // EOF
438 //