]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - FMD/AliFMDGeometryBuilder.cxx
fixed bugs in the container management
[u/mrichter/AliRoot.git] / FMD / AliFMDGeometryBuilder.cxx
... / ...
CommitLineData
1/**************************************************************************
2 * Copyright(c) 1998-1999, 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 AliFMDGeometryBuilder.cxx
17 @author Christian Holm Christensen <cholm@nbi.dk>
18 @date Mon Mar 27 12:41:17 2006
19 @brief Class to build the FMD geometry
20*/
21//____________________________________________________________________
22//
23// Builder of FMD geometry.
24//
25// This class takes care of actually building the geometry using the
26// TGeo classes. Various parameters are fecthed from the
27// AliFMDGeometry manager.
28// Forward Multiplicity Detector based on Silicon wafers. This class
29// contains the base procedures for the Forward Multiplicity detector
30// Detector consists of 3 sub-detectors FMD1, FMD2, and FMD3, each of
31// which has 1 or 2 rings of silicon sensors.
32//
33//
34
35#include <TArrayD.h> // ROOT_TArrayD
36#include <TGeoManager.h> // ROOT_TGeoManager
37#include <TGeoMatrix.h> // ROOT_TGeoMatrix
38#include <TGeoTube.h> // ROOT_TGeoTube
39#include <TGeoTrd1.h> // ROOT_TGeoTrd1
40#include <TGeoCone.h> // ROOT_TGeoTrd1
41#include <TGeoVolume.h> // ROOT_TGeoVolume
42#include <TGeoXtru.h> // ROOT_TGeoXtru
43#include <TGeoCompositeShape.h>
44#include <TMath.h>
45#include <TVector2.h> // ROOT_TVector2
46//#include <TGeoMaterial.h> // ROOT_TGeoMaterial
47//#include <TGeoMedium.h> // ROOT_TGeoMedium
48//#include <TGeoPcon.h> // ROOT_TGeoPcon
49//#include <TGeoPolygon.h> // ROOT_TGeoPolygon
50
51#include "AliFMDGeometryBuilder.h" // ALIFMDGEOSIMULATOR_H
52#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
53#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
54#include "AliFMDRing.h" // ALIFMDRING_H
55#include "AliFMD1.h" // ALIFMD1_H
56#include "AliFMD2.h" // ALIFMD2_H
57#include "AliFMD3.h" // ALIFMD3_H
58// #include "AliFMD.h" // ALIFMD_H
59#include "AliFMDDebug.h" // ALILOG_H
60
61//====================================================================
62ClassImp(AliFMDGeometryBuilder)
63#if 0
64 ; // This is here to keep Emacs for indenting the next line
65#endif
66
67//____________________________________________________________________
68const Char_t* AliFMDGeometryBuilder::fgkActiveName = "F%cAC";
69const Char_t* AliFMDGeometryBuilder::fgkSectorName = "F%cSC";
70const Char_t* AliFMDGeometryBuilder::fgkStripName = "F%cST";
71const Char_t* AliFMDGeometryBuilder::fgkSensorName = "F%cSE";
72const Char_t* AliFMDGeometryBuilder::fgkPCBName = "F%cPB";
73const Char_t* AliFMDGeometryBuilder::fgkCuName = "F%cCU";
74const Char_t* AliFMDGeometryBuilder::fgkChipName = "F%cCH";
75const Char_t* AliFMDGeometryBuilder::fgkLongLegName = "F%cLL";
76const Char_t* AliFMDGeometryBuilder::fgkShortLegName = "F%cSL";
77const Char_t* AliFMDGeometryBuilder::fgkFrontVName = "F%cFH";
78const Char_t* AliFMDGeometryBuilder::fgkBackVName = "F%cBH";
79const Char_t* AliFMDGeometryBuilder::fgkRingTopName = "F%cTV";
80const Char_t* AliFMDGeometryBuilder::fgkRingBotName = "F%cBV";
81const Char_t* AliFMDGeometryBuilder::fgkHCName = "F%dH%c";
82const Char_t* AliFMDGeometryBuilder::fgkIHCName = "F%dI%c";
83const Char_t* AliFMDGeometryBuilder::fgkNoseName = "F3SN";
84const Char_t* AliFMDGeometryBuilder::fgkBackName = "F%dSB";
85const Char_t* AliFMDGeometryBuilder::fgkTopName = "F%dSU";
86const Char_t* AliFMDGeometryBuilder::fgkBeamName = "F%dSL";
87const Char_t* AliFMDGeometryBuilder::fgkFlangeName = "F%dSF";
88const Char_t* AliFMDGeometryBuilder::fgkFMDDCuName = "F%cDC";
89const Char_t* AliFMDGeometryBuilder::fgkFMDDPCBName = "F%cDP";
90const Char_t* AliFMDGeometryBuilder::fgkFMDDChipName = "F%cDI";
91const Char_t* AliFMDGeometryBuilder::fgkFMDDName = "F%cDD";
92const Char_t* AliFMDGeometryBuilder::fgkFMDName = "F%dM%c";
93
94//____________________________________________________________________
95AliFMDGeometryBuilder::AliFMDGeometryBuilder()
96 : TTask("FMD", "Geomtry builder"),
97 fActiveId(0),
98 fDetailed(kTRUE),
99 fUseAssembly(kTRUE),
100 fSectorOff(0),
101 fModuleOff(0),
102 fRingOff(0),
103 fDetectorOff(0),
104 fSi(0),
105 fC(0),
106 fAl(0),
107 fPCB(0),
108 fChip(0),
109 fAir(0),
110 fPlastic(0),
111 fCopper(0),
112 fSteel(0)
113{
114 // Default constructor
115 fActiveId.Set(2);
116}
117
118//____________________________________________________________________
119AliFMDGeometryBuilder::AliFMDGeometryBuilder(Bool_t detailed)
120 : TTask("FMD", "Geometry builder"),
121 fActiveId(0),
122 fDetailed(detailed),
123 fUseAssembly(kTRUE),
124 fSectorOff(0),
125 fModuleOff(0),
126 fRingOff(0),
127 fDetectorOff(0),
128 fSi(0),
129 fC(0),
130 fAl(0),
131 fPCB(0),
132 fChip(0),
133 fAir(0),
134 fPlastic(0),
135 fCopper(0),
136 fSteel(0)
137{
138 // Normal constructor
139 //
140 // Parameters:
141 //
142 // fmd Pointer to AliFMD object
143 // detailed Whether to make a detailed simulation or not
144 //
145 fActiveId.Set(2);
146}
147
148
149//____________________________________________________________________
150TGeoVolume*
151AliFMDGeometryBuilder::RingGeometry(AliFMDRing* r)
152{
153 // Setup the geometry of a ring. The defined TGeoVolume is
154 // returned, and should be used when setting up the rest of the
155 // volumes.
156 //
157 //
158 // Parameters:
159 //
160 // r Pointer to ring geometry object
161 //
162 // Returns:
163 // pointer to ring volume
164 //
165 if (!r) {
166 AliError("Didn't get a ring object");
167 return 0;
168 }
169 Char_t id = r->GetId();
170 const Char_t* lName = (id == 'i' || id == 'I' ? "inner" : "outer");
171 Double_t siThick = r->GetSiThickness();
172 const Int_t knv = r->GetNVerticies();
173 TVector2* a = r->GetVertex(5);
174 TVector2* b = r->GetVertex(3);
175 TVector2* c = r->GetVertex(4);
176 Double_t theta = r->GetTheta();
177 Double_t off = (TMath::Tan(TMath::Pi() * theta / 180)
178 * r->GetBondingWidth());
179 Double_t rmax = b->Mod();
180 Double_t rmin = r->GetLowR();
181 Double_t pcbThick = r->GetPrintboardThickness();
182 Double_t cuThick = r->GetCopperThickness();
183 Double_t chipThick= r->GetChipThickness();
184 Double_t modSpace = r->GetModuleSpacing();
185 Double_t legr = r->GetLegRadius();
186 Double_t legl = r->GetLegLength();
187 Double_t legoff = r->GetLegOffset();
188 Int_t ns = r->GetNStrips();
189 Double_t stripoff = a->Mod();
190 Double_t dstrip = (rmax - stripoff) / ns;
191 Double_t space = r->GetSpacing();
192 TArrayD xs(knv);
193 TArrayD ys(knv);
194 for (Int_t i = 0; i < knv; i++) {
195 // Reverse the order
196 TVector2* vv = r->GetVertex(knv - 1 - i);
197 if (!vv) {
198 AliError(Form("Failed to get vertex # %d", knv - 1 - i));
199 continue;
200 }
201 xs[i] = vv->X();
202 ys[i] = vv->Y();
203 }
204
205 // Shape of actual sensor
206 TGeoXtru* sensorShape = new TGeoXtru(2);
207 sensorShape->DefinePolygon(knv, xs.fArray, ys.fArray);
208 sensorShape->DefineSection(0, - siThick/2);
209 sensorShape->DefineSection(1, siThick/2);
210 sensorShape->SetName(Form(fgkSensorName, id));
211 sensorShape->SetTitle(Form("FMD %s Sensor", lName));
212 TGeoVolume* sensorVolume = new TGeoVolume(Form(fgkSensorName, id),
213 sensorShape, fSi);
214 sensorVolume->SetTitle(Form("FMD %s Sensor", lName));
215 sensorVolume->VisibleDaughters(kFALSE);
216 Int_t sid = sensorVolume->GetNumber();
217 fSectorOff = -1;
218 fModuleOff = 1;
219 fRingOff = 2;
220 fDetectorOff = 3;
221 if (fDetailed) {
222 fSectorOff = 1;
223 fModuleOff = 4;
224 fRingOff = 5;
225 fDetectorOff = 6;
226 // Virtual volume shape to divide - This volume is only defined if
227 // the geometry is set to be detailed.
228 TGeoTubeSeg* activeShape = new TGeoTubeSeg(rmin, rmax, siThick/2,
229 - theta, theta);
230 activeShape->SetName(Form(fgkActiveName, id));
231 activeShape->SetTitle(Form("FMD %s active area", lName));
232 TGeoVolume* activeVolume = new TGeoVolume(Form(fgkActiveName, id),
233 activeShape,fSi);
234 activeVolume->SetTitle(Form("FMD %s active area", lName));
235 TGeoVolume* sectorVolume = activeVolume->Divide(Form(fgkSectorName,id),
236 2, 2, -theta,0,0,"N");
237 sectorVolume->SetTitle(Form("FMD %s sector", lName));
238 TGeoVolume* stripVolume = sectorVolume->Divide(Form(fgkStripName, id),
239 1, ns, stripoff, dstrip,
240 0, "SX");
241 stripVolume->SetTitle(Form("FMD %s strip", lName));
242 sid = stripVolume->GetNumber();
243 sensorVolume->AddNodeOverlap(activeVolume, 0);
244 }
245
246 switch (id) {
247 case 'i': case 'I': fActiveId[0] = sid; break;
248 case 'o': case 'O': fActiveId[1] = sid; break;
249 }
250
251 // Shape of Printed circuit Board
252 for (Int_t i = 0; i < knv / 2; i++) ys[i] -= off;
253 for (Int_t i = knv / 2; i < knv; i++) ys[i] += off;
254 TGeoXtru* pcbShape = new TGeoXtru(2);
255 pcbShape->DefinePolygon(knv, xs.fArray, ys.fArray);
256 pcbShape->DefineSection(0, - pcbThick/2);
257 pcbShape->DefineSection(1, pcbThick/2);
258 pcbShape->SetName(Form(fgkPCBName, id));
259 pcbShape->SetTitle(Form("FMD %s hybrid PCB", lName));
260 TGeoVolume* pcbVolume = new TGeoVolume(Form(fgkPCBName, id),
261 pcbShape, fPCB);
262 pcbVolume->SetTitle(Form("FMD %s hybrid PCB", lName));
263
264 // Copper layer
265 TGeoXtru* cuShape = new TGeoXtru(2);
266 cuShape->DefinePolygon(6, xs.fArray, ys.fArray);
267 cuShape->DefineSection(0, - cuThick/2);
268 cuShape->DefineSection(1, cuThick/2);
269 cuShape->SetTitle(Form("FMD %s hybrid copper", lName));
270 TGeoVolume* cuVolume = new TGeoVolume(Form(fgkCuName,id),cuShape,fCopper);
271 cuVolume->SetTitle(Form("FMD %s hybrid copper", lName));
272
273 // Chip layer
274 TGeoXtru* chipShape = new TGeoXtru(2);
275 chipShape->DefinePolygon(6, xs.fArray, ys.fArray);
276 chipShape->DefineSection(0, - chipThick/2);
277 chipShape->DefineSection(1, chipThick/2);
278 chipShape->SetTitle(Form("FMD %s hybrid chip", lName));
279 TGeoVolume* chipVolume = new TGeoVolume(Form(fgkChipName,id),
280 chipShape,fChip);
281 chipVolume->SetTitle(Form("FMD %s hybrid chip", lName));
282
283 // Short leg shape
284 TGeoTube* shortLegShape = new TGeoTube(0, legr, legl / 2);
285 shortLegShape->SetName(Form(fgkShortLegName, id));
286 shortLegShape->SetTitle(Form("FMD %s short support foot", lName));
287 TGeoVolume* shortLegVolume = new TGeoVolume(Form(fgkShortLegName, id),
288 shortLegShape, fCopper);
289 shortLegVolume->SetTitle(Form("FMD %s short support foot", lName));
290 // Long leg shape
291 TGeoTube* longLegShape = new TGeoTube(0, legr, (legl + modSpace) / 2);
292 longLegShape->SetName(Form(fgkLongLegName, id));
293 longLegShape->SetTitle(Form("FMD %s long support foot", lName));
294 TGeoVolume* longLegVolume = new TGeoVolume(Form(fgkLongLegName, id),
295 longLegShape, fCopper);
296 longLegVolume->SetTitle(Form("FMD %s long support foot", lName));
297
298
299 // Back container volume
300 TGeoVolume* backVolume = new TGeoVolumeAssembly(Form(fgkBackVName, id));
301 backVolume->SetTitle(Form("FMD %s back module", lName));
302 Double_t x = 0;
303 Double_t y = 0;
304 Double_t z = siThick / 2;
305 backVolume->AddNode(sensorVolume, 0, new TGeoTranslation(x, y, z));
306 z += siThick / 2 + space + pcbThick / 2;
307 backVolume->AddNode(pcbVolume, 0, new TGeoTranslation(x,y,z));
308 z += (pcbThick + cuThick) / 2;
309 backVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, z));
310 z += (cuThick + chipThick) / 2;
311 backVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, z));
312 x = a->X() + legoff + legr;
313 y = 0;
314 z += pcbThick / 2 + legl / 2;
315 backVolume->AddNode(shortLegVolume, 0, new TGeoTranslation(x,y,z));
316 x = c->X();
317 y = c->Y() - legoff - legr - off;
318 backVolume->AddNode(shortLegVolume, 1, new TGeoTranslation(x,y,z));
319 y = -y;
320 backVolume->AddNode(shortLegVolume, 2, new TGeoTranslation(x,y,z));
321
322 // Front container volume
323 TGeoVolume* frontVolume = new TGeoVolumeAssembly(Form(fgkFrontVName, id));
324 frontVolume->SetTitle(Form("FMD %s front module", lName));
325 x = 0;
326 y = 0;
327 z = siThick / 2;
328 frontVolume->AddNode(sensorVolume, 0, new TGeoTranslation(x, y, z));
329 z += siThick / 2 + space + pcbThick / 2;
330 frontVolume->AddNode(pcbVolume, 0, new TGeoTranslation(x,y,z));
331 z += (pcbThick + cuThick) / 2;
332 frontVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, z));
333 z += (cuThick + chipThick) / 2;
334 frontVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, z));
335 x = a->X() + legoff + legr;
336 y = 0;
337 z += pcbThick / 2 + (legl + modSpace)/ 2;
338 frontVolume->AddNode(longLegVolume, 0, new TGeoTranslation(x,y,z));
339 x = c->X();
340 y = c->Y() - legoff - legr - off;
341 frontVolume->AddNode(longLegVolume, 1, new TGeoTranslation(x,y,z));
342 y = -y;
343 frontVolume->AddNode(longLegVolume, 2, new TGeoTranslation(x,y,z));
344
345
346 // FMDD
347 Double_t ddlr = r->GetFMDDLowR();
348 Double_t ddhr = r->GetFMDDHighR();
349 Double_t ddpt = r->GetFMDDPrintboardThickness();
350 Double_t ddct = r->GetFMDDCopperThickness();
351 Double_t ddit = r->GetFMDDChipThickness();
352 Double_t ddt = ddpt + ddct + ddit;
353
354 TGeoShape* fmddPcbShape = new TGeoTubeSeg(ddlr, ddhr, ddpt/2,0,180);
355 TGeoShape* fmddCuShape = new TGeoTubeSeg(ddlr, ddhr, ddct/2,0,180);
356 TGeoShape* fmddChipShape = new TGeoTubeSeg(ddlr, ddhr, ddit/2,0,180);
357 fmddPcbShape->SetName(Form(fgkFMDDPCBName, id));
358 fmddCuShape->SetName(Form(fgkFMDDCuName, id));
359 fmddChipShape->SetName(Form(fgkFMDDChipName, id));
360 if (id == 'O' || id == 'o') {
361 TString pcbName(fmddPcbShape->GetName());
362 TString cuName(fmddCuShape->GetName());
363 TString chipName(fmddChipShape->GetName());
364
365 fmddPcbShape->SetName(Form("%s_inner", pcbName.Data()));
366 fmddCuShape->SetName(Form("%s_inner", cuName.Data()));
367 fmddChipShape->SetName(Form("%s_inner", chipName.Data()));
368 new TGeoBBox(Form("%s_clip", pcbName.Data()), ddlr+3, ddhr/2, ddpt);
369 new TGeoBBox(Form("%s_clip", cuName.Data()), ddlr+3, ddhr/2, ddpt);
370 new TGeoBBox(Form("%s_clip", chipName.Data()),ddlr+3, ddhr/2, ddpt);
371 TGeoTranslation* trans = new TGeoTranslation(Form("%s_trans",
372 pcbName.Data()),
373 0, ddhr/2, 0);
374 trans->RegisterYourself();
375 fmddPcbShape = new TGeoCompositeShape(pcbName.Data(),
376 Form("%s_inner*%s_clip:%s_trans",
377 pcbName.Data(),
378 pcbName.Data(),
379 pcbName.Data()));
380 fmddCuShape = new TGeoCompositeShape(cuName.Data(),
381 Form("%s_inner*%s_clip:%s_trans",
382 cuName.Data(),
383 cuName.Data(),
384 pcbName.Data()));
385 fmddChipShape = new TGeoCompositeShape(chipName.Data(),
386 Form("%s_inner*%s_clip:%s_trans",
387 chipName.Data(),
388 chipName.Data(),
389 pcbName.Data()));
390 }
391 fmddPcbShape->SetTitle(Form("FMD %s digitiser PCB", lName));
392 fmddCuShape->SetTitle(Form("FMD %s digitiser copper", lName));
393 fmddChipShape->SetTitle(Form("FMD %s digitiser chip", lName));
394
395 TGeoVolume* fmddPcbVolume = new TGeoVolume(Form(fgkFMDDPCBName, id),
396 fmddPcbShape, fPCB);
397 TGeoVolume* fmddCuVolume = new TGeoVolume(Form(fgkFMDDCuName, id),
398 fmddCuShape, fCopper);
399 TGeoVolume* fmddChipVolume= new TGeoVolume(Form(fgkFMDDChipName, id),
400 fmddChipShape, fChip);
401 fmddPcbVolume->SetTitle(Form("FMD %s digitiser PCB", lName));
402 fmddCuVolume->SetTitle(Form("FMD %s digitiser copper", lName));
403 fmddChipVolume->SetTitle(Form("FMD %s digitiser chip", lName));
404
405 // Half ring mother volumes.
406 TGeoVolume* ringTopVolume = new TGeoVolumeAssembly(Form(fgkRingTopName,id));
407 TGeoVolume* ringBotVolume = new TGeoVolumeAssembly(Form(fgkRingBotName,id));
408 TGeoVolume* halfRing = ringTopVolume;
409 ringTopVolume->SetTitle(Form("FMD %s top half-ring", lName));
410 ringBotVolume->SetTitle(Form("FMD %s bottom half-ring", lName));
411
412 // Adding modules to half-rings
413 Int_t nmod = r->GetNModules();
414 AliFMDDebug(10, ("making %d modules in ring %c", nmod, id));
415 for (Int_t i = 0; i < nmod; i++) {
416 if (i == nmod / 2) halfRing = ringBotVolume;
417 Bool_t front = (i % 2 == 0);
418 TGeoVolume* vol = (front ? frontVolume : backVolume);
419 // vol->AddNode(sensorVolume, i, new TGeoTranslation(0,0,siThick/2));
420 Double_t z1 = (i % 2) * modSpace;
421 Double_t th = (2 * i + 1) * theta;
422 TGeoMatrix* mat1 = new TGeoCombiTrans(0,0,z1,0);
423 mat1->RotateZ(th);
424 mat1->SetName(Form("FMD%c_module_%02d", id, i));
425 mat1->SetTitle(Form("FMD %s module %2d matrix", lName, i));
426 halfRing->AddNode(vol, i, mat1);
427#if 0
428 Double_t z2 = z1 + siThick / 2 + space;
429 Double_t th = (2 * i + 1) * theta;
430 AliFMDDebug(20, ("Placing copy %d of %s and %s in %s at z=%f and %f, "
431 "and theta=%f", i, sensorVolume->GetName(),
432 vol->GetName(), halfRing->GetName(), z1, z2, th));
433 TGeoMatrix* mat1 = new TGeoCombiTrans(0,0,z1,0);
434 mat1->RotateZ(th);
435 halfRing->AddNode(sensorVolume, i, mat1);
436 TGeoMatrix* mat2 = new TGeoCombiTrans(0,0,z2,0);
437 mat2->RotateZ(th);
438 halfRing->AddNode(vol, i, mat2);
439#endif
440 }
441
442 // Add the FMDD
443 Double_t zi = r->GetFullDepth() - ddt;
444 Int_t n = 2;
445 for (Int_t i = 0; i < n; i++) {
446 halfRing = (i == 0 ? ringTopVolume : ringBotVolume);
447 Double_t phi = 360. / n * i;
448 TGeoRotation* rot = new TGeoRotation(Form("FMDD%c rotation %d", id, i));
449 rot->RotateZ(phi);
450 rot->SetTitle(Form("FMD %s digitiser rotation %2d", lName, i));
451 z = zi + ddpt / 2;
452 halfRing->AddNode(fmddPcbVolume, i, new TGeoCombiTrans(0,0,z,rot));
453 z += (ddpt + ddct) / 2;
454 halfRing->AddNode(fmddCuVolume, i, new TGeoCombiTrans(0,0,z,rot));
455 z += (ddct + ddit) / 2;
456 halfRing->AddNode(fmddChipVolume, i, new TGeoCombiTrans(0,0,z,rot));
457 }
458
459
460 return 0;
461}
462
463//____________________________________________________________________
464TGeoVolume*
465AliFMDGeometryBuilder::DetectorGeometry(AliFMDDetector* d,
466 TGeoVolume* topMother,
467 TGeoVolume* botMother,
468 Double_t zMother,
469 TGeoVolume* innerTop,
470 TGeoVolume* innerBot,
471 TGeoVolume* outerTop,
472 TGeoVolume* outerBot)
473{
474 // Common stuff for setting up the FMD1, FMD2, and FMD3 geometries.
475 // This includes putting the Honeycomb support plates and the rings
476 // into the mother volumes.
477 //
478 // Parameeters:
479 // d The detector geometry to use
480 // mother The mother volume of the detector
481 // zmother The midpoint in global coordinates of detector vol.
482 // inner Pointer to inner ring volume
483 // outer Pointer to outer ring volume
484 //
485 // Returns:
486 // Pointer to mother (detector volume)
487 //
488 if (!d) return 0;
489 // Loop over the defined rings
490 for (int i = 0; i < 2; i++) {
491 AliFMDRing* r = 0;
492 Double_t lowr = 0;
493 Double_t highr = 0;
494 Double_t rz = 0;
495 TGeoVolume* tvol = 0;
496 TGeoVolume* bvol = 0;
497 switch (i) {
498 case 0:
499 r = d->GetInner();
500 lowr = d->GetInnerHoneyLowR();
501 highr = d->GetInnerHoneyHighR();
502 rz = d->GetInnerZ();
503 tvol = innerTop;
504 bvol = innerBot;
505 break;
506 case 1:
507 r = d->GetOuter();
508 lowr = d->GetOuterHoneyLowR();
509 highr = d->GetOuterHoneyHighR();
510 rz = d->GetOuterZ();
511 tvol = outerTop;
512 bvol = outerBot;
513 break;
514 }
515 if (!r) continue;
516 Char_t c = r->GetId();
517 Int_t id = d->GetId();
518 Double_t hcThick = r->GetHoneycombThickness();
519 Double_t alThick = r->GetAlThickness();
520 Double_t z = TMath::Abs(rz - zMother);
521
522 // Place ring in mother volume
523 // TGeoMatrix*matrix=new TGeoTranslation(Form("FMD%d%c trans",id,c),0,0,0);
524 AliFMDDebug(1, ("Placing volumes %s and %s in %s and %s at z=%f",
525 tvol->GetName(), bvol->GetName(),
526 topMother->GetName(), botMother->GetName(), z));
527 topMother->AddNode(tvol, Int_t(c), new TGeoTranslation(0,0,z));
528 botMother->AddNode(bvol, Int_t(c), new TGeoTranslation(0,0,z));
529
530 // Top of Honeycomb
531 TGeoTubeSeg* hcSha = new TGeoTubeSeg(lowr, highr, hcThick/2, 0, 180);
532 hcSha->SetName(Form(fgkHCName,id,c));
533 hcSha->SetTitle(Form("FMD%d%c honeycomb shell", id, c));
534 TGeoVolume* hcVol = new TGeoVolume(Form(fgkHCName,id,c),hcSha,fAl);
535 hcVol->SetTitle(Form("FMD%d%c honeycomb shell", id, c));
536 // Air in top of honeycomb
537 TGeoTubeSeg* ihcSha = new TGeoTubeSeg(lowr+alThick, highr - alThick,
538 (hcThick-alThick)/2, 0, 180);
539 ihcSha->SetName(Form(fgkIHCName,id,c));
540 ihcSha->SetTitle(Form("FMD%d%c honeycomb internal", id, c));
541 TGeoVolume* ihcVol = new TGeoVolume(Form(fgkIHCName,id,c),ihcSha,fAir);
542 ihcVol->SetTitle(Form("FMD%d%c honeycomb internal", id, c));
543 hcVol->AddNode(ihcVol, 0);
544 hcVol->VisibleDaughters(kFALSE);
545 hcVol->SetVisibility(kTRUE);
546
547 z += (r->GetSiThickness() +
548 r->GetSpacing() +
549 r->GetPrintboardThickness() +
550 r->GetCopperThickness() +
551 r->GetChipThickness() +
552 r->GetModuleSpacing() +
553 r->GetLegLength() +
554 r->GetHoneycombThickness() +
555 r->GetFMDDPrintboardThickness() -
556 hcThick / 2);
557
558 AliFMDDebug(15, ("Placing a copy of %s in %s and %s at z=%f",
559 hcVol->GetName(), topMother->GetName(),
560 botMother->GetName(), z));
561 // Add to top
562 topMother->AddNode(hcVol, 0, new TGeoTranslation(0, 0, z));
563
564 // Add to bottom
565 TGeoMatrix* bhcMatrix = new TGeoCombiTrans(0,0,z,0);
566 bhcMatrix->SetName(Form("FMD%d%c_honeycomp", id, c));
567 bhcMatrix->SetTitle(Form("FMD%d%c honeycomp", id, c));
568 bhcMatrix->RotateZ(180);
569 botMother->AddNode(hcVol, 1, bhcMatrix);
570 }
571 return 0;
572}
573
574//____________________________________________________________________
575TGeoVolume*
576AliFMDGeometryBuilder::FMD1Geometry(AliFMD1* fmd1,
577 TGeoVolume* innerTop,
578 TGeoVolume* innerBot)
579{
580 // Setup the FMD1 geometry. The FMD1 only has one ring, and no
581 // special support as it is at the momement.
582 //
583 // See also AliFMDGeometryBuilder::DetectorGeometry
584 //
585 if (!fmd1 || !innerTop || !innerBot) return 0;
586 AliFMDRing* r = fmd1->GetInner();
587 Double_t z = fmd1->GetInnerZ();
588 Double_t disce = 2;
589 Double_t backlr = fmd1->GetInnerHoneyHighR();
590 Double_t backhr = fmd1->GetInnerHoneyHighR()+5;
591 Double_t backth = 0.2;
592 Double_t toplr = r->GetLowR();
593 Double_t tophr = fmd1->GetInnerHoneyHighR()+disce;
594 Double_t wallbh = (r->GetFullDepth() + disce);
595 Double_t wallth = wallbh+0.1;
596
597 TGeoVolume* fmd1TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
598 fmd1->GetId(), 'T'));
599 fmd1TopVolume->SetTitle("FMD1 top half");
600 TGeoVolume* fmd1BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
601 fmd1->GetId(), 'B'));
602 fmd1BotVolume->SetTitle("FMD1 bottom half");
603
604 // Basic detector geometry
605 DetectorGeometry(fmd1, fmd1TopVolume, fmd1BotVolume, z,
606 innerTop, innerBot, 0, 0);
607
608
609 // Back
610 TGeoTubeSeg* backShape = new TGeoTubeSeg(backlr, backhr, backth / 2, 0, 180);
611 TGeoTubeSeg* wallbShape = new TGeoTubeSeg(backlr, backlr + backth,
612 wallbh/2, 0, 180);
613 TGeoTubeSeg* topShape = new TGeoTubeSeg(toplr, tophr, backth / 2, 0, 180);
614 TGeoTubeSeg* walltShape = new TGeoTubeSeg(tophr, tophr + backth,
615 wallth/2, 0, 180);
616 TGeoVolume* backVolume = new TGeoVolume(Form(fgkBackName, fmd1->GetId()),
617 backShape, fC);
618 TGeoVolume* wallbVolume= new TGeoVolume(Form(fgkFlangeName, fmd1->GetId()),
619 wallbShape, fC);
620 TGeoVolume* topVolume = new TGeoVolume(Form(fgkTopName, fmd1->GetId()),
621 topShape, fC);
622 TGeoVolume* walltVolume= new TGeoVolume(Form(fgkBeamName, fmd1->GetId()),
623 walltShape, fC);
624 backShape->SetName(Form(fgkBackName, fmd1->GetId()));
625 wallbShape->SetName(Form(fgkFlangeName, fmd1->GetId()));
626 topShape->SetName(Form(fgkTopName, fmd1->GetId()));
627 walltShape->SetName(Form(fgkBeamName, fmd1->GetId()));
628 backShape->SetTitle("FMD1 back saucer rim");
629 wallbShape->SetTitle("FMD1 back saucer wall");
630 topShape->SetTitle("FMD1 top lid");
631 walltShape->SetTitle("FMD1 top lid wall");
632 backVolume->SetFillColor(kGray);
633 topVolume->SetFillColor(kGray);
634 wallbVolume->SetFillColor(kGray);
635 walltVolume->SetFillColor(kGray);
636 backVolume->SetTitle("FMD1 back saucer rim");
637 wallbVolume->SetTitle("FMD1 back saucer wall");
638 topVolume->SetTitle("FMD1 top lid");
639 walltVolume->SetTitle("FMD1 top lid wall");
640
641 // Place volumes
642 Double_t zb = TMath::Abs(fmd1->GetInnerZ() - z);
643 Double_t zi = zb;
644 Int_t n = 2;
645
646 // Place top cover
647 zi -= disce / 2 + backth / 2;
648 zb = zi;
649 for (Int_t i = 0; i < 2; i++) {
650 TGeoVolume* mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
651 Double_t phi = 360. / n * i;
652 TGeoRotation* rot = new TGeoRotation(Form("FMD1 top rotation %d",i));
653 rot->RotateZ(phi);
654 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD1 top wall trans %d", i),
655 0, 0, zi, rot);
656 mother->AddNode(topVolume, i, matrix);
657 }
658 // Place outer wall
659 zi += wallth / 2 + backth / 2;
660 for (Int_t i = 0; i < 2; i++) {
661 TGeoVolume* mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
662 Double_t phi = 360. / n * i;
663 TGeoRotation* rot = new TGeoRotation(Form("FMD1 outer wall rotation %d",
664 i));
665 rot->RotateZ(phi);
666 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD1 outer wall trans %d",
667 i), 0, 0, zi, rot);
668 mother->AddNode(walltVolume, i, matrix);
669 }
670 // Place back
671 zi += wallth / 2 + backth / 2; // + disce / 2;
672 for (Int_t i = 0; i < 2; i++) {
673 TGeoVolume* mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
674 Double_t phi = 360. / n * i;
675 TGeoRotation* rot = new TGeoRotation(Form("FMD1 back rotation %d", i));
676 rot->RotateZ(phi);
677 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD1 back trans %d", i),
678 0, 0, zi, rot);
679 mother->AddNode(backVolume, i, matrix);
680 }
681 // Place inner wall
682 zi -= wallbh / 2 + backth / 2; // + disce / 2;
683 for (Int_t i = 0; i < 2; i++) {
684 TGeoVolume* mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
685 Double_t phi = 360. / n * i;
686 TGeoRotation* rot = new TGeoRotation(Form("FMD1 inner wall rotation %d",
687 i));
688 rot->RotateZ(phi);
689 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD1 inner wall trans %d",
690 i), 0, 0, zi, rot);
691 mother->AddNode(wallbVolume, i, matrix);
692 }
693
694
695 // Must add this after filling the assembly.
696 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
697 // TGeoMatrix* matrix = new TGeoTranslation("FMD1 trans", 0, 0, z);
698 TGeoRotation* rot = new TGeoRotation("FMD1 rotatation");
699 rot->RotateZ(-90);
700 TGeoMatrix* matrix = new TGeoCombiTrans("FMD1 trans", 0, 0, z, rot);
701 AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
702 fmd1TopVolume->GetName(), fmd1BotVolume->GetName(), z));
703 top->AddNode(fmd1TopVolume, fmd1->GetId(), matrix);
704 top->AddNode(fmd1BotVolume, fmd1->GetId(), matrix);
705
706 return 0;
707}
708
709//____________________________________________________________________
710TGeoVolume*
711AliFMDGeometryBuilder::FMD2Geometry(AliFMD2* fmd2,
712 TGeoVolume* innerTop,
713 TGeoVolume* innerBot,
714 TGeoVolume* outerTop,
715 TGeoVolume* outerBot)
716{
717 // Setup the FMD2 geometry. The FMD2 has no
718 // special support as it is at the momement.
719 //
720 // See also AliFMDGeometryBuilder::DetectorGeometry
721 //
722 if (!fmd2 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
723 AliFMDRing* r = fmd2->GetOuter();
724 Double_t z = fmd2->GetOuterZ();
725 Double_t framelr = fmd2->GetOuterHoneyHighR()+0.5;
726 Double_t framehr = fmd2->GetOuterHoneyHighR()+1.8;
727 Double_t framelz = -1;
728 Double_t framehz = (fmd2->GetInnerZ()-z) + r->GetFullDepth() + 1;
729 Double_t framel = framehz - framelz;
730 Double_t coverlr = fmd2->GetInner()->GetLowR()+1;
731 Double_t backth = 0.05;
732
733 TGeoVolume* fmd2TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
734 fmd2->GetId(), 'T'));
735 TGeoVolume* fmd2BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
736 fmd2->GetId(), 'B'));
737 fmd2TopVolume->SetTitle("FMD2 top half");
738 fmd2BotVolume->SetTitle("FMD2 bottom half");
739
740 DetectorGeometry(fmd2, fmd2TopVolume, fmd2BotVolume, z,
741 innerTop, innerBot, outerTop, outerBot);
742
743 TGeoShape* cylinderShape = new TGeoTubeSeg(framelr,framehr,framel/2,0,180);
744 TGeoVolume* cylinderVolume = new TGeoVolume(Form(fgkBackName, fmd2->GetId()),
745 cylinderShape, fC);
746 TGeoShape* coverShape = new TGeoTubeSeg(coverlr,framehr,backth/2,0,180);
747 TGeoVolume* coverVolume = new TGeoVolume(Form(fgkTopName, fmd2->GetId()),
748 coverShape, fC);
749 cylinderShape->SetName(Form(fgkBackName, fmd2->GetId()));
750 cylinderShape->SetTitle("FMD2 cylinder");
751 cylinderVolume->SetTitle("FMD2 cylinder");
752 cylinderVolume->SetTransparency(63);
753 coverShape->SetName(Form(fgkTopName, fmd2->GetId()));
754 coverShape->SetTitle("FMD2 cover");
755 coverVolume->SetTitle("FMD2 cover");
756 coverVolume->SetTransparency(63);
757
758 for (Int_t i = 0; i < 2; i++) {
759 TGeoVolume* mother = (i == 0 ? fmd2TopVolume : fmd2BotVolume);
760
761 Double_t phi = 360. / 2 * i;
762 TGeoRotation* rot = new TGeoRotation(Form("FMD2 support rot %d",i));
763 rot->RotateZ(phi);
764 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD2 cyl trans %d", i),
765 0, 0, framelz+framel/2, rot);
766 mother->AddNode(cylinderVolume, i, matrix);
767 matrix = new TGeoCombiTrans(Form("FMD2 fcov trans %d", i),
768 0, 0, framelz-backth/2, rot);
769 mother->AddNode(coverVolume, 2*i+0, matrix);
770 matrix = new TGeoCombiTrans(Form("FMD2 bcov trans %d", i),
771 0, 0, framelz+framel+backth/2,
772 rot);
773 mother->AddNode(coverVolume, 2*i+1, matrix);
774 }
775
776
777 Double_t f1l = 10;
778 Double_t f1w = 6;
779 Double_t f1d = 1.2;
780
781 TGeoBBox* flange1Shape = new TGeoBBox(f1l/2, f1w/2, f1d/2);
782 TGeoVolume* flange1Volume = new TGeoVolume(Form(fgkFlangeName, fmd2->GetId()),
783 flange1Shape, fAl);
784 TGeoBBox* flange2Shape = new TGeoBBox(f1w/2, f1d/2, (framel+backth)/2);
785 TGeoVolume* flange2Volume = new TGeoVolume(Form("F%dSG", fmd2->GetId()),
786 flange2Shape, fAl);
787 flange1Shape->SetName(Form(fgkFlangeName, fmd2->GetId()));
788 flange1Shape->SetTitle("FMD2 vertical flange");
789 flange1Volume->SetTitle("FMD2 vertical flange");
790 flange2Shape->SetName(Form("F%dSG", fmd2->GetId()));
791 flange2Shape->SetTitle("FMD2 horizontal flange");
792 flange2Volume->SetTitle("FMD2 horizontal flange ");
793
794 flange1Volume->SetTransparency(42);
795 for (Int_t i = 0; i < 4; i++) {
796 TGeoVolume* mother = (i < 2 ? fmd2TopVolume : fmd2BotVolume);
797
798 Double_t phi = 360. / 4 * i - 45;
799 Double_t rphi = TMath::Pi()*phi/180;
800 Double_t x = (framelr + f1l/2) * TMath::Sin(rphi);
801 Double_t y = (framelr + f1l/2) * TMath::Cos(rphi);
802 TGeoRotation* rot = new TGeoRotation(Form("FMD2 support rot %d",i));
803 rot->RotateZ(phi);
804 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD2 flange 1 trans %d", i),
805 x,y, framelz-backth-f1d/2, rot);
806 mother->AddNode(flange1Volume, 2*i+0, matrix);
807 matrix = new TGeoCombiTrans(Form("FMD2 flange 2 trans %d", i),
808 x,y,framelz+framel+backth+f1d/2,
809 rot);
810 mother->AddNode(flange1Volume, 2*i+1, matrix);
811 Double_t x1 = x - (f1w-f1d) / 2 * TMath::Cos(rphi);
812 Double_t y1 = y + (f1w-f1d) / 2 * TMath::Sin(rphi);
813 matrix = new TGeoCombiTrans(Form("FMD2 flange 3 trans %d", i),
814 x1,y1,framelz+framel/2, rot);
815 mother->AddNode(flange2Volume, 2*i+0, matrix);
816 Double_t x2 = x + (f1w-f1d) / 2 * TMath::Cos(rphi);
817 Double_t y2 = y - (f1w-f1d) / 2 * TMath::Sin(rphi);
818 matrix = new TGeoCombiTrans(Form("FMD2 flange 4 trans %d", i),
819 x2,y2,framelz+framel/2, rot);
820 mother->AddNode(flange2Volume, 2*i+1, matrix);
821 }
822
823 // Must be done after filling the assemblies
824 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
825 TGeoMatrix* matrix = new TGeoTranslation("FMD2 trans", 0, 0, z);
826 AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
827 fmd2TopVolume->GetName(), fmd2BotVolume->GetName(), z));
828 top->AddNode(fmd2TopVolume, fmd2->GetId(), matrix);
829 top->AddNode(fmd2BotVolume, fmd2->GetId(), matrix);
830
831
832 return 0;
833}
834
835//____________________________________________________________________
836TGeoVolume*
837AliFMDGeometryBuilder::FMD3Geometry(AliFMD3* fmd3,
838 TGeoVolume* innerTop,
839 TGeoVolume* innerBot,
840 TGeoVolume* outerTop,
841 TGeoVolume* outerBot)
842{
843 // Setup the FMD3 geometry. The FMD2 has a rather elaborate support
844 // structure, as the support will also support the vacuum
845 // beam-pipe.
846 //
847 // See also AliFMDGeometryBuilder::DetectorGeometry
848 //
849 if (!fmd3 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
850 Double_t nlen = fmd3->GetNoseLength();
851 Double_t nz = fmd3->GetNoseZ();
852 Double_t noser1 = fmd3->GetNoseLowR();
853 Double_t noser2 = fmd3->GetNoseHighR();
854 Double_t conet = fmd3->GetBeamThickness();
855 Double_t conel = fmd3->GetConeLength();
856 Double_t backl = fmd3->GetBackLength();
857 // Double_t backr1 = fmd3->GetBackLowR();
858 Double_t backr2 = fmd3->GetBackHighR();
859 Double_t zdist = conel - backl - nlen;
860 Double_t tdist = backr2 - noser2;
861 // Double_t beaml = TMath::Sqrt(zdist * zdist + tdist * tdist);
862 Double_t theta = -180. * TMath::ATan2(tdist, zdist) / TMath::Pi();
863 Double_t flanger = fmd3->GetFlangeR();
864 Double_t z = fmd3->GetInnerZ(); // fmd3->GetZ();
865
866 TGeoVolume* fmd3TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
867 fmd3->GetId(), 'T'));
868 TGeoVolume* fmd3BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
869 fmd3->GetId(), 'B'));
870 fmd3TopVolume->SetTitle("FMD3 top half");
871 fmd3BotVolume->SetTitle("FMD3 bottom half");
872
873
874 DetectorGeometry(fmd3, fmd3TopVolume, fmd3BotVolume, z,
875 innerTop, innerBot, outerTop, outerBot);
876
877
878 TGeoVolumeAssembly* support = new TGeoVolumeAssembly("F3SU");
879 support->SetTitle("FMD3 support");
880
881 // Nose volume
882 TGeoTubeSeg* noseShape = new TGeoTubeSeg(noser1, noser2, nlen / 2, 0, 180);
883 TGeoVolume* noseVolume = new TGeoVolume(fgkNoseName, noseShape, fC);
884 support->AddNode(noseVolume, 0, new TGeoTranslation(0, 0, nlen/2));
885 noseShape->SetName(fgkNoseName);
886 noseShape->SetTitle("FMD3 nose");
887 noseVolume->SetTitle("FMD3 nose");
888
889 // Steel bolts
890 TGeoTube* boltShape = new TGeoTube("F3SB", 0, 0.3, conet / 2);
891 TGeoVolume* boltVolume = new TGeoVolume("F3SB", boltShape, fSteel);
892 Double_t z1 = -10;
893 Double_t x1 = (fmd3->ConeR(nz+z1));
894 TGeoRotation* r1 = new TGeoRotation();
895 r1->RotateY(theta);
896 TGeoCombiTrans* t = new TGeoCombiTrans("F3SB1",x1,0,-z1,r1);
897 support->AddNode(boltVolume, 1, t);
898 z1 = -20;
899 x1 = (fmd3->ConeR(nz+z1));
900 t = new TGeoCombiTrans("F3SB2",x1,0,-z1,r1);
901 support->AddNode(boltVolume, 2, t);
902 boltShape->SetTitle("FMD3 steering bolt");
903 boltVolume->SetTitle("FMD3 steering bolt");
904
905 // Cooling plates
906 TGeoTrd1* plateShape = new TGeoTrd1(2, 8, 0.1, (conel-2-2)/2-.1);
907 TGeoVolume* plateVolume = new TGeoVolume("F3CO", plateShape, fAl);
908 plateShape->SetName("F3C0");
909 plateShape->SetTitle("FMD3 cooling plate");
910 plateVolume->SetTitle("FMD3 cooling plate");
911
912 // Shape for carbon half-cone
913 TGeoConeSeg* innerCone = new TGeoConeSeg("F3SC_inner", conel/2,
914 noser2-conet, noser2,
915 backr2-conet, backr2, 0., 180.);
916 innerCone->SetTitle("FMD3 cone inner");
917 TGeoTrd1* coneHole = new TGeoTrd1("F3SC_hole",2,8,conet*3,
918 (conel-2-2)/2);
919 coneHole->SetTitle("FMD3 cone hole");
920 Double_t holeAng = TMath::ATan2(backr2 - noser2, conel);
921 Double_t holeX = ((conel-2) / 2 * TMath::Sin(holeAng) +
922 conet * TMath::Cos(holeAng) +
923 noser2);
924 TGeoRotation* holeRot = new TGeoRotation();
925 holeRot->SetName("FMD3 cone hole rotation");
926 holeRot->RotateZ(90);
927 holeRot->RotateY(holeAng*180./TMath::Pi());
928 TGeoCombiTrans* holeTrans = new TGeoCombiTrans(holeX, 0, -2, holeRot);
929 holeRot->SetName("FMD3 cone hole");
930
931 // Build-up the composite shape for the cone, and add cooling plates
932 // at the same time.
933 TString coneExp("F3SC_inner-(");
934 for (int i = 0; i < 4; i++) {
935 Double_t thisAng = 360. / 8 * (i + .5);
936 TGeoCombiTrans* thisTrans = new TGeoCombiTrans(*holeTrans);
937 thisTrans->RotateZ(thisAng);
938 thisTrans->SetName(Form("F3SC_rot%d", i));
939 thisTrans->RegisterYourself();
940 coneExp.Append(Form("F3SC_hole:F3SC_rot%d+", i));
941
942 const Double_t* tt = thisTrans->GetTranslation();
943 Double_t x = tt[0]+1*TMath::Cos(thisAng*TMath::Pi()/180);
944 Double_t y = tt[1]+1*TMath::Sin(thisAng*TMath::Pi()/180);
945 TGeoCombiTrans* plateTrans = new TGeoCombiTrans(x,y,tt[2]-1+nlen+conel/2,
946 thisTrans->GetRotation());
947 support->AddNode(plateVolume, i, plateTrans);
948 }
949 // Remove bolt holes
950 coneExp.Append("F3SB:F3SB1+F3SB:F3SB2)");
951
952 // Finalize the half-cone shape and add volume
953 TGeoCompositeShape* coneShape = new TGeoCompositeShape(coneExp.Data());
954 TGeoVolume* coneVolume = new TGeoVolume("F3SC", coneShape, fC);
955 coneShape->SetName("F3SC");
956 coneShape->SetTitle("FMD3 cone");
957 coneVolume->SetTitle("FMD3 cone");
958 support->AddNode(coneVolume,1,new TGeoTranslation(0,0,nlen+conel/2));
959
960 // The flanges
961 TGeoBBox* flangeShape = new TGeoBBox((flanger - backr2) / 2,
962 fmd3->GetBeamWidth() / 2,
963 backl / 2);
964 TGeoVolume* flangeVolume = new TGeoVolume(Form(fgkFlangeName, fmd3->GetId()),
965 flangeShape, fC);
966 flangeShape->SetName(Form(fgkFlangeName, fmd3->GetId()));
967 flangeShape->SetTitle("FMD3 flange");
968 flangeVolume->SetTitle("FMD3 flange");
969
970 Int_t n = fmd3->GetNFlange();
971 Double_t r = backr2 + (flanger - backr2) / 2;
972 for (Int_t i = 0; i < n/2; i++) {
973 Double_t phi = 360. / n * i + 180. / n;
974 Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
975 Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
976 TGeoRotation* rot = new TGeoRotation;
977 rot->RotateZ(phi);
978 TGeoMatrix* matrix = new TGeoCombiTrans(x, y, nlen+conel-backl/2, rot);
979 matrix->SetName(Form("FMD3_flange_%02d", i));
980 matrix->SetTitle(Form("FMD3_flange_%2d", i));
981 support->AddNode(flangeVolume, i, matrix);
982 }
983
984 // Place support volumes in half-detector volumes
985 z = fmd3->GetInnerZ();
986 z1 = z-nz;
987 fmd3TopVolume->AddNode(support, 1, new TGeoTranslation(0,0,z1));
988 r1 = new TGeoRotation();
989 r1->RotateZ(180);
990 t = new TGeoCombiTrans(0,0,z1,r1);
991 fmd3BotVolume->AddNode(support, 2, t);
992
993 TGeoRotation* rot = new TGeoRotation("FMD3 rotatation");
994 rot->RotateY(180);
995 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
996 TGeoMatrix* mmatrix = new TGeoCombiTrans("FMD3 trans", 0, 0, z, rot);
997 AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
998 fmd3TopVolume->GetName(), fmd3BotVolume->GetName(), z));
999 top->AddNode(fmd3TopVolume, fmd3->GetId(), mmatrix);
1000 top->AddNode(fmd3BotVolume, fmd3->GetId(), mmatrix);
1001
1002 return 0;
1003}
1004
1005//____________________________________________________________________
1006void
1007AliFMDGeometryBuilder::Exec(Option_t*)
1008{
1009 // Setup up the FMD geometry.
1010 AliFMDDebug(1, ("\tGeometry options: %s",
1011 (fDetailed ? "divided into strips" : "one volume")));
1012 if (!gGeoManager) {
1013 AliFatal("No TGeoManager defined");
1014 return;
1015 }
1016
1017 fSi = gGeoManager->GetMedium("FMD_Si$");
1018 fC = gGeoManager->GetMedium("FMD_Carbon$");
1019 fAl = gGeoManager->GetMedium("FMD_Aluminum$");
1020 fChip = gGeoManager->GetMedium("FMD_Si Chip$");
1021 fAir = gGeoManager->GetMedium("FMD_Air$");
1022 fPCB = gGeoManager->GetMedium("FMD_PCB$");
1023 fPlastic = gGeoManager->GetMedium("FMD_Plastic$");
1024 fCopper = gGeoManager->GetMedium("FMD_Copper$");
1025 fSteel = gGeoManager->GetMedium("FMD_Steel$");
1026
1027 if (!fSi||!fC||!fAl||!fChip||!fAir||!fPCB||!fPlastic||!fCopper||!fSteel) {
1028 AliError("Failed to get some or all tracking mediums");
1029 return;
1030 }
1031 AliFMDGeometry* fmd = AliFMDGeometry::Instance();
1032 AliFMDRing* inner = fmd->GetInner();
1033 AliFMDRing* outer = fmd->GetOuter();
1034 RingGeometry(inner);
1035 RingGeometry(outer);
1036 TGeoVolume* innerTop = gGeoManager->GetVolume(Form(fgkRingTopName,
1037 inner->GetId()));
1038 TGeoVolume* innerBot = gGeoManager->GetVolume(Form(fgkRingBotName,
1039 inner->GetId()));
1040 TGeoVolume* outerTop = gGeoManager->GetVolume(Form(fgkRingTopName,
1041 outer->GetId()));
1042 TGeoVolume* outerBot = gGeoManager->GetVolume(Form(fgkRingBotName,
1043 outer->GetId()));
1044
1045 FMD1Geometry(fmd->GetFMD1(), innerTop, innerBot);
1046 FMD2Geometry(fmd->GetFMD2(), innerTop, innerBot, outerTop, outerBot);
1047 FMD3Geometry(fmd->GetFMD3(), innerTop, innerBot, outerTop, outerBot);
1048#ifndef USE_PRE_MOVE
1049 fmd->SetSectorOff(fSectorOff);
1050 fmd->SetModuleOff(fModuleOff);
1051 fmd->SetRingOff(fRingOff);
1052 fmd->SetDetectorOff(fDetectorOff);
1053 fmd->SetActive(fActiveId.fArray, fActiveId.fN);
1054#endif
1055 // fmd->ExtractGeomInfo();
1056
1057}
1058
1059
1060//____________________________________________________________________
1061//
1062// EOF
1063//