]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDRing.cxx
New FMD correction objects. Again.
[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{
088f8e79 73 // CTOR
1a1fdef7 74 SetBondingWidth();
75 SetWaferRadius();
76 SetSiThickness();
77 SetLegRadius();
78 SetLegLength();
79 SetLegOffset();
80 SetModuleSpacing();
81 SetPrintboardThickness();
4ac75127 82 SetCopperThickness();
83 SetChipThickness();
a1f80595 84 SetSpacing();
d98fbfa5 85 SetHoneycombThickness();
86 SetAlThickness();
4347b38f 87
1a1fdef7 88 if (fId == 'I' || fId == 'i') {
89 SetLowR(4.3);
90 SetHighR(17.2);
91 SetTheta(36/2);
92 SetNStrips(512);
f70f588a 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));
1a1fdef7 115 }
116 else if (fId == 'O' || fId == 'o') {
117 SetLowR(15.6);
118 SetHighR(28.0);
119 SetTheta(18/2);
120 SetNStrips(256);
f70f588a 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));
4347b38f 143 }
4347b38f 144}
145
4347b38f 146//____________________________________________________________________
147void
1a1fdef7 148AliFMDRing::Init()
4347b38f 149{
088f8e79 150 // Initialize
f70f588a 151#if 0
1a1fdef7 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;
4347b38f 165
1a1fdef7 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);
f70f588a 173#endif
1a1fdef7 174
54e415a8 175 // A's length. Corresponds to distance from nominal beam line to the
176 // cornor of the active silicon element.
f70f588a 177 fMinR = GetVertex(1)->Mod(); // GetVertex(5)->Mod();
54e415a8 178 // A's length. Corresponds to distance from nominal beam line to the
179 // cornor of the active silicon element.
180 fMaxR = fHighR;
181
1a1fdef7 182 fRingDepth = (fSiThickness + fPrintboardThickness
4ac75127 183 + fCopperThickness + fChipThickness
184 + fLegLength + fModuleSpacing + fSpacing);
4347b38f 185}
186
187//____________________________________________________________________
1a1fdef7 188TVector2*
189AliFMDRing::GetVertex(Int_t i) const
4347b38f 190{
088f8e79 191 // Get the i'th vertex of polygon shape
1a1fdef7 192 return static_cast<TVector2*>(fVerticies.At(i));
4347b38f 193}
194
f70f588a 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
bf000c32 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
f70f588a 230//____________________________________________________________________
231Double_t
232AliFMDRing::GetModuleDepth() const
233{
234 return (GetSiThickness()
235 + GetSpacing()
236 + GetPrintboardThickness()
237 + GetCopperThickness()
238 + GetChipThickness()
239 + GetLegLength());
240
241}
242
d98fbfa5 243//____________________________________________________________________
244Double_t
245AliFMDRing::GetFullDepth() const
246{
f70f588a 247 return (GetModuleDepth()
248 + GetModuleSpacing()
249 + GetHoneycombThickness()
250 + GetFMDDPrintboardThickness()
251 + GetFMDDCopperThickness()
252 + GetFMDDChipThickness()
d98fbfa5 253 + 0.5);
254}
255
4347b38f 256//____________________________________________________________________
1a1fdef7 257void
258AliFMDRing::Detector2XYZ(UShort_t sector,
259 UShort_t strip,
260 Double_t& x,
261 Double_t& y,
262 Double_t& z) const
4347b38f 263{
088f8e79 264 // Translate detector coordinates (this,sector,strip) to global
265 // coordinates (x,y,z)
1a1fdef7 266 if (sector >= GetNSectors()) {
267 Error("Detector2XYZ", "Invalid sector number %d (>=%d) in ring %c",
268 sector, GetNSectors(), fId);
269 return;
4347b38f 270 }
1a1fdef7 271 if (strip >= GetNStrips()) {
272 Error("Detector2XYZ", "Invalid strip number %d (>=%d)",
273 strip, GetNStrips(), fId);
274 return;
4347b38f 275 }
1a1fdef7 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);
4347b38f 282}
283
54e415a8 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{
088f8e79 292 // Translate global coordinates (x,y,z) to detector coordinates
293 // (this,sector,strip)
54e415a8 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}
fb848ec4 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}
4347b38f 364//
365// EOF
366//