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 | **************************************************************************/ |
15 | |
16 | /* $Id$ */ |
17 | |
c4bcfd14 |
18 | //__________________________________________________________________ |
4347b38f |
19 | // |
20 | // Utility class to help implement collection of FMD modules into |
21 | // rings. This is used by AliFMDSubDetector and AliFMD. |
22 | // |
23 | // The AliFMD object owns the AliFMDRing objects, and the |
24 | // AliFMDSubDetector objects reference these. That is, the AliFMDRing |
25 | // objects are share amoung the AliFMDSubDetector objects. |
26 | // |
27 | // Latest changes by Christian Holm Christensen |
28 | // |
4347b38f |
29 | #ifndef ALIFMDRING_H |
30 | # include "AliFMDRing.h" |
31 | #endif |
32 | #ifndef ALILOG_H |
33 | # include "AliLog.h" |
34 | #endif |
35 | #ifndef ROOT_TMath |
36 | # include <TMath.h> |
37 | #endif |
38 | #ifndef ROOT_TH2 |
39 | # include <TH2.h> |
40 | #endif |
41 | #ifndef ROOT_TVirtualMC |
42 | # include <TVirtualMC.h> |
43 | #endif |
44 | #ifndef ROOT_TVector2 |
45 | # include <TVector2.h> |
46 | #endif |
47 | #ifndef ROOT_TBrowser |
48 | # include <TBrowser.h> |
49 | #endif |
50 | #ifndef ROOT_TString |
51 | # include <TString.h> |
52 | #endif |
53 | #ifndef ROOT_TArc |
54 | # include <TArc.h> |
55 | #endif |
56 | #ifndef ROOT_TObjArray |
57 | # include <TObjArray.h> |
58 | #endif |
59 | #ifndef ROOT_TXTRU |
60 | # include <TXTRU.h> |
61 | #endif |
62 | #ifndef ROOT_TNode |
63 | # include <TNode.h> |
64 | #endif |
65 | #ifndef ROOT_TRotMatrix |
66 | # include <TRotMatrix.h> |
67 | #endif |
68 | #ifndef ROOT_TList |
69 | # include <TList.h> |
70 | #endif |
71 | #ifndef __IOSTREAM__ |
72 | # include <iostream> |
73 | #endif |
74 | |
c4bcfd14 |
75 | const Char_t* AliFMDRing::fgkRingFormat = "FRG%c"; |
76 | const Char_t* AliFMDRing::fgkVirtualFormat = "FV%c%c"; |
77 | const Char_t* AliFMDRing::fgkActiveFormat = "FAC%c"; |
78 | const Char_t* AliFMDRing::fgkSectorFormat = "FSE%c"; |
79 | const Char_t* AliFMDRing::fgkStripFormat = "FST%c"; |
80 | const Char_t* AliFMDRing::fgkPrintboardFormat = "FP%c%c"; |
42403906 |
81 | |
82 | |
83 | //____________________________________________________________________ |
4347b38f |
84 | ClassImp(AliFMDRing); |
85 | |
86 | //____________________________________________________________________ |
4347b38f |
87 | AliFMDRing::AliFMDRing(Char_t id, Bool_t detailed) |
88 | : fId(id), |
89 | fDetailed(detailed), |
c4bcfd14 |
90 | fActiveId(0), |
91 | fPrintboardBottomId(0), |
92 | fPrintboardTopId(0), |
93 | fRingId(0), |
94 | fSectionId(0), |
95 | fStripId(0), |
96 | fVirtualBackId(0), |
97 | fVirtualFrontId(0), |
98 | fBondingWidth(0), |
4347b38f |
99 | fWaferRadius(0), |
100 | fSiThickness(0), |
101 | fLowR(0), |
102 | fHighR(0), |
103 | fTheta(0), |
104 | fNStrips(0), |
c4bcfd14 |
105 | fRingDepth(0), |
106 | fLegRadius(0), |
107 | fLegLength(0), |
108 | fLegOffset(0), |
109 | fModuleSpacing(0), |
110 | fPrintboardThickness(0), |
4347b38f |
111 | fShape(0), |
112 | fRotMatricies(0) |
42403906 |
113 | { |
114 | // Construct a alifmdring. |
115 | // |
116 | // id Id of the ring (either 'i' or 'o'). |
c4bcfd14 |
117 | // detailed Whether the strips are made or not. |
118 | // |
119 | } |
120 | |
121 | //____________________________________________________________________ |
122 | AliFMDRing::AliFMDRing(const AliFMDRing& other) |
123 | : TObject(other), |
124 | fId(other.fId), |
125 | fDetailed(other.fDetailed), |
126 | fActiveId(other.fActiveId), |
127 | fPrintboardBottomId(other.fPrintboardBottomId), |
128 | fPrintboardTopId(other.fPrintboardTopId), |
129 | fRingId(other.fRingId), |
130 | fSectionId(other.fSectionId), |
131 | fStripId(other.fStripId), |
132 | fVirtualBackId(other.fVirtualBackId), |
133 | fVirtualFrontId(other.fVirtualFrontId), |
134 | fBondingWidth(other.fBondingWidth), |
135 | fWaferRadius(other.fWaferRadius), |
136 | fSiThickness(other.fSiThickness), |
137 | fLowR(other.fLowR), |
138 | fHighR(other.fHighR), |
139 | fTheta(other.fTheta), |
140 | fNStrips(other.fNStrips), |
141 | fRingDepth(other.fRingDepth), |
142 | fLegRadius(other.fLegRadius), |
143 | fLegLength(other.fLegLength), |
144 | fLegOffset(other.fLegOffset), |
145 | fModuleSpacing(other.fModuleSpacing), |
146 | fPrintboardThickness(other.fPrintboardThickness), |
147 | fRotations(other.fRotations), |
148 | fShape(other.fShape), |
149 | fRotMatricies(other.fRotMatricies) |
150 | { |
151 | // Copy constructor of a AliFMDRing. |
152 | } |
153 | |
154 | //____________________________________________________________________ |
155 | AliFMDRing& |
156 | AliFMDRing::operator=(const AliFMDRing& other) |
157 | { |
158 | // Assignment operator |
159 | // |
160 | fId = other.fId; |
161 | fDetailed = other.fDetailed; |
162 | fActiveId = other.fActiveId; |
163 | fPrintboardBottomId = other.fPrintboardBottomId; |
164 | fPrintboardTopId = other.fPrintboardTopId; |
165 | fRingId = other.fRingId; |
166 | fSectionId = other.fSectionId; |
167 | fStripId = other.fStripId; |
168 | fVirtualBackId = other.fVirtualBackId; |
169 | fVirtualFrontId = other.fVirtualFrontId; |
170 | fBondingWidth = other.fBondingWidth; |
171 | fWaferRadius = other.fWaferRadius; |
172 | fSiThickness = other.fSiThickness; |
173 | fLowR = other.fLowR; |
174 | fHighR = other.fHighR; |
175 | fTheta = other.fTheta; |
176 | fNStrips = other.fNStrips; |
177 | fRingDepth = other.fRingDepth; |
178 | fLegRadius = other.fLegRadius; |
179 | fLegLength = other.fLegLength; |
180 | fLegOffset = other.fLegOffset; |
181 | fModuleSpacing = other.fModuleSpacing; |
182 | fPrintboardThickness = other.fPrintboardThickness; |
183 | fRotations = other.fRotations; |
184 | if (other.fShape) { |
185 | if (other.fShape->IsA() == TXTRU::Class()) |
186 | ((TXTRU*)other.fShape)->Copy(*fShape); |
187 | else |
188 | fShape = 0; |
189 | } |
190 | if (other.fRotMatricies) { |
191 | Int_t n = other.fRotMatricies->GetEntries(); |
192 | if (!fRotMatricies) fRotMatricies = new TObjArray(n); |
193 | else fRotMatricies->Expand(n); |
194 | TIter next(other.fRotMatricies); |
195 | TObject* o = 0; |
196 | while ((o = next())) fRotMatricies->Add(o); |
197 | } |
198 | return *this; |
42403906 |
199 | } |
200 | |
c4bcfd14 |
201 | |
4347b38f |
202 | |
203 | //____________________________________________________________________ |
204 | void |
205 | AliFMDRing::Init() |
206 | { |
207 | // Initialize the ring object. |
208 | // DebugGuard guard("AliFMDRing::Init"); |
209 | AliDebug(10, "AliFMDRing::Init"); |
210 | fPolygon.Clear(); |
211 | SetupCoordinates(); |
212 | } |
213 | |
214 | //____________________________________________________________________ |
215 | AliFMDRing::~AliFMDRing() |
216 | { |
42403906 |
217 | // Destructor - deletes shape and rotation matricies |
4347b38f |
218 | if (fShape) delete fShape; |
219 | if (fRotMatricies) delete fRotMatricies; |
220 | } |
221 | |
222 | |
223 | //____________________________________________________________________ |
224 | void |
225 | AliFMDRing::Browse(TBrowser* /* b */) |
226 | { |
227 | // DebugGuard guard("AliFMDRing::Browse"); |
228 | AliDebug(10, "AliFMDRing::Browse"); |
229 | } |
230 | |
231 | |
232 | //____________________________________________________________________ |
233 | void |
234 | AliFMDRing::SetupCoordinates() |
235 | { |
236 | // Calculates the parameters of the polygon shape. |
237 | // |
238 | // DebugGuard guard("AliFMDRing::SetupCoordinates"); |
239 | AliDebug(10, "AliFMDRing::SetupCoordinates"); |
240 | // Get out immediately if we have already done all this |
241 | if (fPolygon.GetNVerticies() > 1) return; |
242 | |
c4bcfd14 |
243 | double tanTheta = TMath::Tan(fTheta * TMath::Pi() / 180.); |
244 | double tanTheta2 = TMath::Power(tanTheta,2); |
4347b38f |
245 | double r2 = TMath::Power(fWaferRadius,2); |
c4bcfd14 |
246 | double yA = tanTheta * fLowR; |
4347b38f |
247 | double lr2 = TMath::Power(fLowR, 2); |
248 | double hr2 = TMath::Power(fHighR,2); |
c4bcfd14 |
249 | double xD = fLowR + TMath::Sqrt(r2 - tanTheta2 * lr2); |
250 | double xD2 = TMath::Power(xD,2); |
251 | //double xD_2 = fLowR - TMath::Sqrt(r2 - tanTheta2 * lr2); |
252 | double yB = sqrt(r2 - hr2 + 2 * fHighR * xD - xD2); |
253 | double xC = ((xD + TMath::Sqrt(-tanTheta2 * xD2 + r2 |
254 | + r2 * tanTheta2)) |
255 | / (1 + tanTheta2)); |
256 | double yC = tanTheta * xC; |
257 | |
258 | fPolygon.AddVertex(fLowR, -yA); |
259 | fPolygon.AddVertex(xC, -yC); |
260 | fPolygon.AddVertex(fHighR, -yB); |
261 | fPolygon.AddVertex(fHighR, yB); |
262 | fPolygon.AddVertex(xC, yC); |
263 | fPolygon.AddVertex(fLowR, yA); |
4347b38f |
264 | } |
265 | |
266 | //____________________________________________________________________ |
267 | bool |
268 | AliFMDRing::IsWithin(size_t moduleNo, double x, double y) const |
269 | { |
270 | // Checks if a point (x,y) is inside the module with number moduleNo |
271 | // |
272 | // DebugGuard guard("AliFMDRing::IsWithin"); |
273 | AliDebug(10, "AliFMDRing::IsWithin"); |
274 | bool ret = false; |
275 | double r2 = x * x + y * y; |
276 | if (r2 < fHighR * fHighR && r2 > fLowR * fLowR) { |
277 | // double point_angle = TMath::ATan2(y, x); |
278 | // int n_modules = 360 / Int_t(fTheta * 2); |
279 | double m_angle = (.5 + moduleNo) * 2 * fTheta; |
280 | double m_radians = TMath::Pi() * m_angle / 180.; |
281 | |
282 | // Rotate the point. |
283 | double xr = x * TMath::Cos(-m_radians) - y * TMath::Sin(-m_radians); |
284 | double yr = x * TMath::Sin(-m_radians) + y * TMath::Cos(-m_radians); |
285 | |
286 | ret = fPolygon.Contains(xr,yr); |
287 | } |
288 | return ret; |
289 | } |
290 | |
291 | |
292 | |
293 | |
294 | //____________________________________________________________________ |
295 | void |
296 | AliFMDRing::Draw(Option_t* option) const |
297 | { |
298 | // Draw a the shape of the ring into a 2D histogram. Useful for |
299 | // superimposing the actual shape of the ring onto a scatter plot of |
300 | // hits in the detector. |
301 | // |
302 | // DebugGuard guard("AliFMDRing::Draw"); |
303 | AliDebug(10, "AliFMDRing::Draw"); |
304 | // The unrotated coordinates of the polygon verticies |
305 | if (fPolygon.GetNVerticies() < 1) return; |
306 | |
307 | TVector2 v[6]; |
308 | for (size_t i = 0; i < fPolygon.GetNVerticies(); i++) |
309 | v[i] = fPolygon.GetVertex(i); |
310 | |
311 | Int_t nModules = 360 / Int_t(fTheta * 2); |
312 | Double_t dTheta = fTheta * 2; |
313 | |
314 | TString opt(option); |
315 | if (opt.Contains("B", TString::kIgnoreCase)) { |
316 | opt.Remove(opt.Index("B", 1, TString::kIgnoreCase),1); |
317 | TH1* null = new TH2F("null", "Null", |
318 | 100, -fHighR * 1.1, fHighR * 1.1, |
319 | 100, -fHighR * 1.1, fHighR * 1.1); |
320 | null->SetStats(0); |
321 | null->Draw(opt.Data()); |
322 | } |
323 | |
324 | for (int i = 0; i < nModules; i++) { |
325 | Double_t theta = (i + .5) * dTheta; |
326 | AliFMDPolygon p; |
327 | for (int j = 0; j < 6; j++) { |
328 | TVector2 vr(v[j].Rotate(TMath::Pi() * theta / 180.)); |
329 | if (!p.AddVertex(vr.X(),vr.Y())) { |
330 | // std::cerr << "Draw of polygon " << i << " failed" << std::endl; |
331 | break; |
332 | } |
333 | } |
334 | p.Draw(opt.Data(), Form("MOD%c_%d", fId, i)); |
335 | } |
336 | if (opt.Contains("0", TString::kIgnoreCase)) { |
337 | TArc* arcH = new TArc(0,0, fHighR); |
338 | arcH->SetLineStyle(2); |
339 | arcH->SetLineColor(4); |
340 | arcH->Draw(); |
341 | |
342 | TArc* arcL = new TArc(0,0, fLowR); |
343 | arcL->SetLineStyle(2); |
344 | arcL->SetLineColor(4); |
345 | arcL->Draw(); |
346 | } |
347 | } |
348 | |
349 | //____________________________________________________________________ |
350 | void |
351 | AliFMDRing::SetupGeometry(Int_t vacuumId, Int_t siId, Int_t pcbId, |
352 | Int_t pbRotId, Int_t idRotId) |
353 | { |
354 | // Setup the geometry of the ring. It defines the volumes |
355 | // RNGI or RNGO which can later be positioned in a sub-detector |
356 | // volume. |
357 | // |
358 | // The hieracy of the RNGx volume is |
359 | // |
42403906 |
360 | // FRGx // Ring volume |
361 | // FVFx // Container of hybrid + legs |
362 | // FACx // Active volume (si sensor approx) |
363 | // FSEx // Section division |
364 | // FSTx // Strip division |
365 | // FPTx // Print board (bottom) |
366 | // FPBx // Print board (top) |
367 | // FLL // Support leg (long version) |
368 | // FVBx // Container of hybrid + legs |
369 | // FACx // Active volume (si sensor approx) |
370 | // FSEx // Section division |
371 | // FSTx // Strip division |
372 | // FPTx // Print board (bottom) |
373 | // FPBx // Print board (top) |
374 | // FSL // Support leg (long version) |
4347b38f |
375 | // |
376 | // Parameters: |
377 | // |
378 | // vacuumId Medium of inactive virtual volumes |
379 | // siId Medium of Silicon sensor (active) |
380 | // pcbId Medium of print boards |
381 | // pbRotId Print board rotation matrix |
382 | // idRotId Identity rotation matrix |
383 | // |
384 | // DebugGuard guard("AliFMDRing::SetupGeometry"); |
385 | AliDebug(10, "AliFMDRing::SetupGeometry"); |
386 | |
387 | const TVector2& bCorner = fPolygon.GetVertex(3); // Third corner |
388 | const TVector2& aCorner = fPolygon.GetVertex(5); // First corner |
389 | const TVector2& cCorner = fPolygon.GetVertex(4); // Second corner |
390 | TString name; |
391 | TString name2; |
392 | Double_t dStrip = (bCorner.Mod() - aCorner.Mod()) / fNStrips; |
393 | Double_t stripOff = aCorner.Mod(); |
394 | Double_t rmin = fLowR; |
395 | Double_t rmax = bCorner.Mod(); |
396 | Double_t pars[10]; |
397 | fRingDepth = (fSiThickness |
398 | + fPrintboardThickness |
399 | + fLegLength |
400 | + fModuleSpacing); |
401 | |
402 | // Ring virtual volume |
403 | pars[0] = rmin; |
c4bcfd14 |
404 | pars[1] = rmax; |
4347b38f |
405 | pars[2] = fRingDepth / 2; |
c4bcfd14 |
406 | name = Form(fgkRingFormat, fId); |
4347b38f |
407 | fRingId = gMC->Gsvolu(name.Data(), "TUBE", vacuumId, pars, 3); |
408 | |
409 | // Virtual volume for modules with long legs |
410 | pars[1] = rmax; |
411 | pars[3] = -fTheta; |
412 | pars[4] = fTheta; |
c4bcfd14 |
413 | name = Form(fgkVirtualFormat, 'F', fId); |
4347b38f |
414 | fVirtualFrontId = gMC->Gsvolu(name.Data(), "TUBS", vacuumId, pars, 5); |
415 | |
416 | // Virtual volume for modules with long legs |
417 | pars[2] = (fRingDepth - fModuleSpacing) / 2; |
c4bcfd14 |
418 | name = Form(fgkVirtualFormat, 'B', fId); |
4347b38f |
419 | fVirtualBackId = gMC->Gsvolu(name.Data(), "TUBS", vacuumId, pars, 5); |
420 | |
421 | // Virtual mother volume for silicon |
422 | pars[2] = fSiThickness/2; |
423 | name2 = name; |
c4bcfd14 |
424 | name = Form(fgkActiveFormat, fId); |
4347b38f |
425 | fActiveId = gMC->Gsvolu(name.Data(), "TUBS", vacuumId , pars, 5); |
426 | |
427 | if (fDetailed) { |
428 | // Virtual sector volumes |
429 | name2 = name; |
c4bcfd14 |
430 | name = Form(fgkSectorFormat, fId); |
4347b38f |
431 | gMC->Gsdvn2(name.Data(), name2.Data(), 2, 2, -fTheta, vacuumId); |
432 | fSectionId = gMC->VolId(name.Data()); |
433 | |
434 | // Active strip volumes |
435 | name2 = name; |
c4bcfd14 |
436 | name = Form(fgkStripFormat, fId); |
42403906 |
437 | gMC->Gsdvt2(name.Data(), name2.Data(), dStrip, 1,stripOff, siId, fNStrips); |
4347b38f |
438 | fStripId = gMC->VolId(name.Data()); |
439 | } |
440 | |
441 | // Print-board on back of module |
442 | pars[4] = TMath::Tan(TMath::Pi() * fTheta / 180) * fBondingWidth; |
443 | // Top of the print board |
444 | pars[0] = cCorner.Y() - pars[4]; |
445 | pars[1] = bCorner.Y() - pars[4]; |
446 | pars[2] = fPrintboardThickness / 2; // PCB half thickness |
447 | pars[3] = (bCorner.X() - cCorner.X()) / 2; |
c4bcfd14 |
448 | name = Form(fgkPrintboardFormat, 'T', fId); |
4347b38f |
449 | fPrintboardTopId = gMC->Gsvolu(name.Data(), "TRD1", pcbId, pars, 4); |
450 | |
451 | // Bottom of the print board |
452 | pars[0] = aCorner.Y() - pars[4]; |
453 | pars[1] = cCorner.Y() - pars[4]; |
454 | pars[3] = (cCorner.X() - aCorner.X()) / 2; |
c4bcfd14 |
455 | name = Form(fgkPrintboardFormat, 'B', fId); |
4347b38f |
456 | fPrintboardBottomId = gMC->Gsvolu(name.Data(), "TRD1", pcbId, pars, 4); |
457 | |
458 | // Define rotation matricies |
459 | Int_t nModules = 360 / Int_t(fTheta * 2); |
460 | Double_t dTheta = fTheta * 2; |
461 | fRotations.Set(nModules); |
462 | for (int i = 0; i < nModules; i++) { |
463 | Double_t theta = (i + .5) * dTheta; |
464 | Int_t idrot = 0; |
465 | // Rotation matrix for virtual module volumes |
466 | gMC->Matrix(idrot, 90, theta, 90, fmod(90 + theta, 360), 0, 0); |
467 | fRotations[i] = idrot; |
468 | } |
469 | |
470 | |
471 | // Int_t nModules = 360 / Int_t(fTheta * 2); |
472 | // Double_t dTheta = fTheta * 2; |
473 | Double_t pbTopL = (bCorner.X() - cCorner.X()); |
474 | Double_t pbBotL = (cCorner.X() - aCorner.X()); |
475 | Double_t yoffset = ((TMath::Tan(TMath::Pi() * fTheta / 180) |
476 | * fBondingWidth)); |
477 | |
478 | for (int i = 0; i < nModules; i++) { |
c4bcfd14 |
479 | TString name2 = Form(fgkRingFormat, fId); |
4347b38f |
480 | |
481 | Int_t id = i; |
482 | // Double_t theta = (i + .5) * dTheta; |
483 | Bool_t isFront = (i % 2 == 1); |
484 | Double_t dz = 0; |
485 | Double_t w = fRingDepth - (isFront ? 0 : fModuleSpacing); |
486 | |
487 | // Place virtual module volume |
c4bcfd14 |
488 | name = Form(fgkVirtualFormat, (isFront ? 'F' : 'B'), fId); |
4347b38f |
489 | dz = (w - fRingDepth) / 2; |
490 | gMC->Gspos(name.Data(), id, name2.Data(), 0., 0., dz,fRotations[i]); |
491 | |
492 | // We only need to place the children once, they are copied when |
493 | // we place the other virtual volumes. |
494 | if (i > 1) continue; |
495 | name2 = name; |
496 | |
497 | // Place active silicon wafer - this is put so that the front of |
498 | // the silicon is on the edge of the virtual volume. |
c4bcfd14 |
499 | name = Form(fgkActiveFormat, fId); |
4347b38f |
500 | dz = (w - fSiThickness) / 2; |
501 | gMC->Gspos(name.Data(), id, name2.Data(),0.,0.,dz,idRotId); |
502 | |
503 | // Place print board. This is put immediately behind the silicon |
c4bcfd14 |
504 | name = Form(fgkPrintboardFormat, 'T', fId); |
4347b38f |
505 | dz = w / 2 - fSiThickness - fPrintboardThickness / 2; |
506 | gMC->Gspos(name.Data(), id, name2.Data(), |
507 | fLowR + pbBotL + pbTopL / 2, 0, dz, pbRotId, "ONLY"); |
c4bcfd14 |
508 | name = Form(fgkPrintboardFormat, 'B', fId); |
4347b38f |
509 | gMC->Gspos(name.Data(), id, name2.Data(), |
510 | fLowR + pbBotL / 2, 0, dz, pbRotId, "ONLY"); |
511 | |
512 | // Support legs |
513 | // This is put immediately behind the pringboard. |
514 | dz = (w / 2 - fSiThickness - fPrintboardThickness |
515 | - (fLegLength + (isFront ? fModuleSpacing : 0)) /2); |
42403906 |
516 | name = (isFront ? "FLL" : "FSL"); |
4347b38f |
517 | gMC->Gspos(name.Data(), id*10 + 1, name2.Data(), |
518 | aCorner.X() + fLegOffset + fLegRadius, 0., dz, idRotId, ""); |
519 | Double_t y = cCorner.Y() - yoffset - fLegOffset - fLegRadius; |
520 | gMC->Gspos(name.Data(),id*10+2,name2.Data(),cCorner.X(), y,dz,idRotId,""); |
c4bcfd14 |
521 | gMC->Gspos(name.Data(),id*10+3,name2.Data(),cCorner.X(), -y,dz,idRotId,""); |
4347b38f |
522 | } |
523 | } |
524 | //____________________________________________________________________ |
525 | void |
526 | AliFMDRing::Geometry(const char* mother, Int_t baseId, Double_t z, |
527 | Int_t /* pbRotId */, Int_t idRotId) |
528 | { |
529 | // Positions a RNGx volume inside a mother. |
530 | // |
531 | // Parameters |
532 | // |
533 | // mother Mother volume to position the RNGx volume in |
534 | // baseId Base copy number |
535 | // z Z coordinate where the front of the active silicon |
536 | // should be in the mother volume, so we need to |
537 | // subtract half the ring width. |
538 | // idRotId Identity rotation matrix |
539 | // |
540 | // DebugGuard guard("AliFMDRing::Geometry"); |
541 | AliDebug(10, "AliFMDRing::Geometry"); |
542 | TString name; |
543 | Double_t offsetZ = (fSiThickness |
544 | + fPrintboardThickness |
545 | + fLegLength + fModuleSpacing) / 2; |
c4bcfd14 |
546 | name = Form(fgkRingFormat, fId); |
4347b38f |
547 | gMC->Gspos(name.Data(), baseId, mother, 0., 0., z - offsetZ, idRotId, ""); |
548 | } |
549 | |
550 | //____________________________________________________________________ |
551 | void |
552 | AliFMDRing::SimpleGeometry(TList* nodes, |
553 | TNode* mother, |
554 | Int_t colour, |
555 | Double_t z, |
556 | Int_t n) |
557 | { |
558 | // Make a simple geometry of the ring for event display. |
559 | // |
560 | // The simple geometry is made from ROOT TNode and TShape objects. |
561 | // Note, that we cache the TShape and TRotMatrix objects used for |
562 | // this. |
563 | // |
564 | // Parameters |
565 | // |
566 | // nodes List of nodes to register all create nodes in |
567 | // mother Mother node to put the ring in. |
568 | // colour Colour of the nodes |
569 | // z Z position of the node in the mother volume |
570 | // n Detector number |
571 | // |
572 | // DebugGuard guard("AliFMDRing::SimpleGeometry"); |
573 | AliDebug(10, "AliFMDRing::SimpleGeometry"); |
574 | SetupCoordinates(); |
575 | |
576 | // If the shape hasn't been defined yet, we define it here. |
577 | if (!fShape) { |
c4bcfd14 |
578 | TString name(Form(fgkActiveFormat, fId)); |
4347b38f |
579 | TString title(Form("Shape of modules in %c Rings", fId)); |
580 | Int_t n = fPolygon.GetNVerticies(); |
581 | TXTRU* shape = new TXTRU(name.Data(), title.Data(), "void", n, 2); |
582 | for (Int_t i = 0; i < n; i++) { |
583 | const TVector2& v = fPolygon.GetVertex(i); |
584 | shape->DefineVertex(i, v.X(), v.Y()); |
585 | } |
586 | shape->DefineSection(0, - fSiThickness / 2, 1, 0, 0); |
587 | shape->DefineSection(1, + fSiThickness / 2, 1, 0, 0); |
588 | fShape = shape; |
589 | fShape->SetLineColor(colour); |
590 | } |
591 | |
592 | Int_t nModules = 360 / Int_t(fTheta * 2); |
593 | Double_t dTheta = fTheta * 2; |
594 | |
595 | // If the roation matricies hasn't been defined yet, we do so here |
596 | if (!fRotMatricies) { |
597 | fRotMatricies = new TObjArray(nModules); |
598 | for (int i = 0; i < nModules; i++) { |
599 | Double_t theta = (i + .5) * dTheta; |
600 | TString name(Form("FMD_ring_%c_rot", fId)); |
601 | TString title(Form("FMD Ring %c Rotation", fId)); |
602 | TRotMatrix* rot = |
603 | new TRotMatrix(name.Data(), title.Data(), |
604 | 90, theta, 90, fmod(90 + theta, 360), 0, 0); |
605 | fRotMatricies->AddAt(rot, i); |
606 | } |
607 | } |
608 | |
609 | Double_t offsetZ = (fSiThickness |
610 | + fPrintboardThickness |
611 | + fLegLength + fModuleSpacing) / 2; |
612 | |
613 | // Make all the nodes |
614 | for (int i = 0; i < nModules; i++) { |
615 | Bool_t isFront = (i % 2 == 1); |
616 | mother->cd(); |
617 | TRotMatrix* rot = static_cast<TRotMatrix*>(fRotMatricies->At(i)); |
42403906 |
618 | TString name(Form("FAC%c_%d_%d", fId, n, i)); |
4347b38f |
619 | TString title(Form("Active FMD%d volume in %c Ring", n, fId)); |
620 | TNode* node = new TNode(name.Data(), title.Data(), fShape, |
621 | 0, 0, |
622 | z - offsetZ + (isFront ? fModuleSpacing : 0), |
623 | rot); |
624 | node->SetLineColor(colour); |
625 | nodes->Add(node); |
626 | } |
627 | } |
628 | |
629 | |
630 | |
631 | //____________________________________________________________________ |
632 | void |
633 | AliFMDRing::Gsatt() |
634 | { |
635 | // Set drawing attributes for the RING |
636 | // |
637 | // DebugGuard guard("AliFMDRing::Gsatt"); |
638 | AliDebug(10, "AliFMDRing::Gsatt"); |
639 | TString name; |
c4bcfd14 |
640 | name = Form(fgkRingFormat,fId); |
4347b38f |
641 | gMC->Gsatt(name.Data(), "SEEN", 0); |
642 | |
c4bcfd14 |
643 | name = Form(fgkVirtualFormat, 'T', fId); |
4347b38f |
644 | gMC->Gsatt(name.Data(), "SEEN", 0); |
645 | |
c4bcfd14 |
646 | name = Form(fgkVirtualFormat, 'B', fId); |
4347b38f |
647 | gMC->Gsatt(name.Data(), "SEEN", 0); |
648 | |
c4bcfd14 |
649 | name = Form(fgkActiveFormat,fId); |
4347b38f |
650 | gMC->Gsatt(name.Data(), "SEEN", 1); |
651 | |
c4bcfd14 |
652 | name = Form(fgkPrintboardFormat, 'T', fId); |
4347b38f |
653 | gMC->Gsatt(name.Data(), "SEEN", 1); |
654 | |
c4bcfd14 |
655 | name = Form(fgkPrintboardFormat, 'B',fId); |
4347b38f |
656 | gMC->Gsatt(name.Data(), "SEEN", 1); |
657 | } |
658 | |
659 | // |
660 | // EOF |
661 | // |