Fixed some coding convention issues. I have no idea why the
[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 **************************************************************************/
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 75const Char_t* AliFMDRing::fgkRingFormat = "FRG%c";
76const Char_t* AliFMDRing::fgkVirtualFormat = "FV%c%c";
77const Char_t* AliFMDRing::fgkActiveFormat = "FAC%c";
78const Char_t* AliFMDRing::fgkSectorFormat = "FSE%c";
79const Char_t* AliFMDRing::fgkStripFormat = "FST%c";
80const Char_t* AliFMDRing::fgkPrintboardFormat = "FP%c%c";
42403906 81
82
83//____________________________________________________________________
4347b38f 84ClassImp(AliFMDRing);
85
86//____________________________________________________________________
4347b38f 87AliFMDRing::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//____________________________________________________________________
122AliFMDRing::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//____________________________________________________________________
155AliFMDRing&
156AliFMDRing::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//____________________________________________________________________
204void
205AliFMDRing::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//____________________________________________________________________
215AliFMDRing::~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//____________________________________________________________________
224void
225AliFMDRing::Browse(TBrowser* /* b */)
226{
227 // DebugGuard guard("AliFMDRing::Browse");
228 AliDebug(10, "AliFMDRing::Browse");
229}
230
231
232//____________________________________________________________________
233void
234AliFMDRing::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//____________________________________________________________________
267bool
268AliFMDRing::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//____________________________________________________________________
295void
296AliFMDRing::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//____________________________________________________________________
350void
351AliFMDRing::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//____________________________________________________________________
525void
526AliFMDRing::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//____________________________________________________________________
551void
552AliFMDRing::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//____________________________________________________________________
632void
633AliFMDRing::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//