]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDGeometryBuilder.cxx
Additiona TOF data members (S.Arcelli)
[u/mrichter/AliRoot.git] / FMD / AliFMDGeometryBuilder.cxx
CommitLineData
54e415a8 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
16/* $Id$ */
17
18//____________________________________________________________________
19//
20// Forward Multiplicity Detector based on Silicon wafers. This class
21// contains the base procedures for the Forward Multiplicity detector
22// Detector consists of 3 sub-detectors FMD1, FMD2, and FMD3, each of
23// which has 1 or 2 rings of silicon sensors.
24//
54e415a8 25//
26#include "AliFMDGeometryBuilder.h" // ALIFMDGEOSIMULATOR_H
27#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
28#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
29#include "AliFMDRing.h" // ALIFMDRING_H
30#include "AliFMD1.h" // ALIFMD1_H
31#include "AliFMD2.h" // ALIFMD2_H
32#include "AliFMD3.h" // ALIFMD3_H
33#include "AliFMD.h" // ALIFMD_H
34#include "AliLog.h" // ALILOG_H
35#include <TGeoVolume.h> // ROOT_TGeoVolume
36#include <TGeoTube.h> // ROOT_TGeoTube
37#include <TGeoPcon.h> // ROOT_TGeoPcon
38#include <TGeoMaterial.h> // ROOT_TGeoMaterial
39#include <TGeoMedium.h> // ROOT_TGeoMedium
40#include <TGeoXtru.h> // ROOT_TGeoXtru
41#include <TGeoPolygon.h> // ROOT_TGeoPolygon
42#include <TGeoTube.h> // ROOT_TGeoTube
43#include <TGeoManager.h> // ROOT_TGeoManager
44#include <TVector2.h> // ROOT_TVector2
45#include <TArrayD.h> // ROOT_TArrayD
46
47//====================================================================
48ClassImp(AliFMDGeometryBuilder)
49#if 0
50 ; // This is here to keep Emacs for indenting the next line
51#endif
52
53//____________________________________________________________________
54const Char_t* AliFMDGeometryBuilder::fgkActiveName = "F%cAC";
bf000c32 55const Char_t* AliFMDGeometryBuilder::fgkSectorName = "F%cSC";
54e415a8 56const Char_t* AliFMDGeometryBuilder::fgkStripName = "F%cST";
bf000c32 57const Char_t* AliFMDGeometryBuilder::fgkSensorName = "F%cSE";
58const Char_t* AliFMDGeometryBuilder::fgkPCBName = "F%cPB";
59const Char_t* AliFMDGeometryBuilder::fgkCuName = "F%cCU";
60const Char_t* AliFMDGeometryBuilder::fgkChipName = "F%cCH";
54e415a8 61const Char_t* AliFMDGeometryBuilder::fgkLongLegName = "F%cLL";
62const Char_t* AliFMDGeometryBuilder::fgkShortLegName = "F%cSL";
bf000c32 63const Char_t* AliFMDGeometryBuilder::fgkFrontVName = "F%cFH";
64const Char_t* AliFMDGeometryBuilder::fgkBackVName = "F%cBH";
65const Char_t* AliFMDGeometryBuilder::fgkRingTopName = "F%cTV";
66const Char_t* AliFMDGeometryBuilder::fgkRingBotName = "F%cBV";
67const Char_t* AliFMDGeometryBuilder::fgkHCName = "F%dH%c";
68const Char_t* AliFMDGeometryBuilder::fgkIHCName = "F%dI%c";
54e415a8 69const Char_t* AliFMDGeometryBuilder::fgkNoseName = "F3SN";
70const Char_t* AliFMDGeometryBuilder::fgkBackName = "F3SB";
71const Char_t* AliFMDGeometryBuilder::fgkBeamName = "F3SL";
72const Char_t* AliFMDGeometryBuilder::fgkFlangeName = "F3SF";
bf000c32 73const Char_t* AliFMDGeometryBuilder::fgkFMDName = "F%dM%c";
54e415a8 74
75//____________________________________________________________________
76AliFMDGeometryBuilder::AliFMDGeometryBuilder()
77 : fDetailed(kTRUE),
78 fUseAssembly(kTRUE),
79 fSi(0),
80 fC(0),
81 fAl(0),
82 fPCB(0),
83 fChip(0),
84 fPlastic(0)
85{
86 // Default constructor
088f8e79 87 fActiveId.Set(2);
54e415a8 88}
89
90//____________________________________________________________________
91AliFMDGeometryBuilder::AliFMDGeometryBuilder(Bool_t detailed)
92 : TTask("FMD", "Geometry builder"),
93 fDetailed(detailed),
94 fUseAssembly(kTRUE),
95 fSi(0),
96 fC(0),
97 fAl(0),
98 fPCB(0),
99 fChip(0),
100 fPlastic(0)
101{
102 // Normal constructor
103 //
104 // Parameters:
105 //
106 // fmd Pointer to AliFMD object
107 // detailed Whether to make a detailed simulation or not
108 //
088f8e79 109 fActiveId.Set(2);
54e415a8 110}
111
112
113//____________________________________________________________________
114TGeoVolume*
115AliFMDGeometryBuilder::RingGeometry(AliFMDRing* r)
116{
117 // Setup the geometry of a ring. The defined TGeoVolume is
118 // returned, and should be used when setting up the rest of the
119 // volumes.
120 //
121 //
122 // Parameters:
123 //
124 // r Pointer to ring geometry object
125 //
126 // Returns:
127 // pointer to ring volume
128 //
129 if (!r) {
130 AliError("Didn't get a ring object");
131 return 0;
132 }
133 Char_t id = r->GetId();
134 Double_t siThick = r->GetSiThickness();
135 const Int_t nv = r->GetNVerticies();
136 TVector2* a = r->GetVertex(5);
137 TVector2* b = r->GetVertex(3);
138 TVector2* c = r->GetVertex(4);
139 Double_t theta = r->GetTheta();
140 Double_t off = (TMath::Tan(TMath::Pi() * theta / 180)
141 * r->GetBondingWidth());
142 Double_t rmax = b->Mod();
143 Double_t rmin = r->GetLowR();
144 Double_t pcbThick = r->GetPrintboardThickness();
bf000c32 145 Double_t cuThick = r->GetCopperThickness();
146 Double_t chipThick= r->GetChipThickness();
54e415a8 147 Double_t modSpace = r->GetModuleSpacing();
148 Double_t legr = r->GetLegRadius();
149 Double_t legl = r->GetLegLength();
150 Double_t legoff = r->GetLegOffset();
151 Int_t ns = r->GetNStrips();
152 Double_t stripoff = a->Mod();
153 Double_t dstrip = (rmax - stripoff) / ns;
154 Double_t space = r->GetSpacing();
155 TArrayD xs(nv);
156 TArrayD ys(nv);
157 for (Int_t i = 0; i < nv; i++) {
158 // Reverse the order
159 TVector2* vv = r->GetVertex(nv - 1 - i);
160 if (!vv) {
161 AliError(Form("Failed to get vertex # %d", nv - 1 - i));
162 continue;
163 }
164 xs[i] = vv->X();
165 ys[i] = vv->Y();
166 }
167
168 // Shape of actual sensor
bf000c32 169 TGeoXtru* sensorShape = new TGeoXtru(2);
170 sensorShape->DefinePolygon(nv, xs.fArray, ys.fArray);
171 sensorShape->DefineSection(0, - siThick/2);
172 sensorShape->DefineSection(1, siThick/2);
173 TGeoVolume* sensorVolume = new TGeoVolume(Form(fgkSensorName, id),
174 sensorShape, fSi);
175 sensorVolume->VisibleDaughters(kFALSE);
176 Int_t sid = sensorVolume->GetNumber();
54e415a8 177 fSectorOff = -1;
178 fModuleOff = 1;
179 fRingOff = 2;
180 fDetectorOff = 3;
181 if (fDetailed) {
182 fSectorOff = 1;
bf000c32 183 fModuleOff = 3;
184 fRingOff = 4;
185 fDetectorOff = 5;
54e415a8 186 // Virtual volume shape to divide - This volume is only defined if
187 // the geometry is set to be detailed.
bf000c32 188 TGeoTubeSeg* activeShape = new TGeoTubeSeg(rmin, rmax, siThick/2,
189 - theta, theta);
54e415a8 190 TGeoVolume* activeVolume = new TGeoVolume(Form(fgkActiveName, id),
191 activeShape,fSi);
192 TGeoVolume* sectorVolume = activeVolume->Divide(Form(fgkSectorName,id),
193 2, 2, -theta,0,0,"N");
194 TGeoVolume* stripVolume = sectorVolume->Divide(Form(fgkStripName, id),
195 1, ns, stripoff, dstrip,
196 0, "SX");
197 sid = stripVolume->GetNumber();
bf000c32 198 sensorVolume->AddNodeOverlap(activeVolume, 0);
54e415a8 199 }
200
201 switch (id) {
bf000c32 202 case 'i': case 'I': fActiveId[0] = sid; break;
203 case 'o': case 'O': fActiveId[1] = sid; break;
54e415a8 204 }
205
206 // Shape of Printed circuit Board
54e415a8 207 for (Int_t i = 0; i < nv / 2; i++) ys[i] -= off;
208 for (Int_t i = nv / 2; i < nv; i++) ys[i] += off;
bf000c32 209 TGeoXtru* pcbShape = new TGeoXtru(2);
54e415a8 210 pcbShape->DefinePolygon(nv, xs.fArray, ys.fArray);
211 pcbShape->DefineSection(0, - pcbThick/2);
212 pcbShape->DefineSection(1, pcbThick/2);
bf000c32 213 TGeoVolume* pcbVolume = new TGeoVolume(Form(fgkPCBName, id),
214 pcbShape, fPCB);
215
216 // Copper layer
217 TGeoXtru* cuShape = new TGeoXtru(2);
218 cuShape->DefinePolygon(6, xs.fArray, ys.fArray);
219 cuShape->DefineSection(0, - cuThick/2);
220 cuShape->DefineSection(1, cuThick/2);
221 TGeoVolume* cuVolume = new TGeoVolume(Form(fgkCuName,id),cuShape,fCopper);
222
223 // Chip layer
224 TGeoXtru* chipShape = new TGeoXtru(2);
225 chipShape->DefinePolygon(6, xs.fArray, ys.fArray);
226 chipShape->DefineSection(0, - chipThick/2);
227 chipShape->DefineSection(1, chipThick/2);
228 TGeoVolume* chipVolume = new TGeoVolume(Form(fgkChipName,id),
229 chipShape,fChip);
54e415a8 230
231 // Short leg shape
232 TGeoTube* shortLegShape = new TGeoTube(0, legr, legl / 2);
233 TGeoVolume* shortLegVolume = new TGeoVolume(Form(fgkShortLegName, id),
234 shortLegShape, fPlastic);
235
236 // Long leg shape
237 TGeoTube* longLegShape = new TGeoTube(0, legr, (legl + modSpace) / 2);
238 TGeoVolume* longLegVolume = new TGeoVolume(Form(fgkLongLegName, id),
239 longLegShape, fPlastic);
240
bf000c32 241
54e415a8 242 // Back container volume
bf000c32 243 TGeoVolume* backVolume = new TGeoVolumeAssembly(Form(fgkBackVName, id));
54e415a8 244 Double_t x = 0;
245 Double_t y = 0;
bf000c32 246 Double_t z = pcbThick / 2;
247 backVolume->AddNode(pcbVolume, 0, new TGeoTranslation(x,y,z));
248 z += (pcbThick + cuThick) / 2;
249 backVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, z));
250 z += (cuThick + chipThick) / 2;
251 backVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, z));
54e415a8 252 x = a->X() + legoff + legr;
253 y = 0;
254 z += pcbThick / 2 + legl / 2;
bf000c32 255 backVolume->AddNode(shortLegVolume, 0, new TGeoTranslation(x,y,z));
54e415a8 256 x = c->X();
257 y = c->Y() - legoff - legr - off;
bf000c32 258 backVolume->AddNode(shortLegVolume, 1, new TGeoTranslation(x,y,z));
54e415a8 259 y = -y;
bf000c32 260 backVolume->AddNode(shortLegVolume, 2, new TGeoTranslation(x,y,z));
54e415a8 261
262 // Front container volume
bf000c32 263 TGeoVolume* frontVolume = new TGeoVolumeAssembly(Form(fgkFrontVName, id));
54e415a8 264 x = 0;
265 y = 0;
bf000c32 266 z = pcbThick / 2;
267 frontVolume->AddNode(pcbVolume, 1, new TGeoTranslation(x,y,z));
268 z += (pcbThick + cuThick) / 2;
269 frontVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, z));
270 z += (cuThick + chipThick) / 2;
271 frontVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, z));
54e415a8 272 x = a->X() + legoff + legr;
273 y = 0;
274 z += pcbThick / 2 + (legl + modSpace)/ 2;
bf000c32 275 frontVolume->AddNode(longLegVolume, 0, new TGeoTranslation(x,y,z));
54e415a8 276 x = c->X();
277 y = c->Y() - legoff - legr - off;
bf000c32 278 frontVolume->AddNode(longLegVolume, 1, new TGeoTranslation(x,y,z));
54e415a8 279 y = -y;
bf000c32 280 frontVolume->AddNode(longLegVolume, 2, new TGeoTranslation(x,y,z));
54e415a8 281
bf000c32 282 // Half ring mother volumes.
283 TGeoVolume* ringTopVolume = new TGeoVolumeAssembly(Form(fgkRingTopName,id));
284 TGeoVolume* ringBotVolume = new TGeoVolumeAssembly(Form(fgkRingBotName,id));
285 TGeoVolume* halfRing = ringTopVolume;
54e415a8 286
bf000c32 287 // Adding modules to half-rings
288 Int_t nmod = r->GetNModules();
54e415a8 289 AliDebug(10, Form("making %d modules in ring %c", nmod, id));
290 for (Int_t i = 0; i < nmod; i++) {
bf000c32 291 if (i == nmod / 2) halfRing = ringBotVolume;
292 Bool_t front = (i % 2 == 0);
293 Double_t z1 = siThick / 2 + (i % 2) * modSpace;
294 Double_t z2 = z1 + siThick / 2 + space;
295 Double_t th = (2 * i + 1) * theta;
296 TGeoVolume* vol = (front ? frontVolume : backVolume);
297 AliDebug(20, Form("Placing copy %d of %s and %s in %s at z=%f and %f, "
298 "and theta=%f", i, sensorVolume->GetName(),
299 vol->GetName(), halfRing->GetName(), z1, z2, th));
300 TGeoMatrix* mat1 = new TGeoCombiTrans(0,0,z1,0);
301 mat1->RotateZ(th);
302 halfRing->AddNode(sensorVolume, i, mat1);
303 TGeoMatrix* mat2 = new TGeoCombiTrans(0,0,z2,0);
304 mat2->RotateZ(th);
305 halfRing->AddNode(vol, i, mat2);
54e415a8 306 }
307
bf000c32 308 return 0;
54e415a8 309}
310
311//____________________________________________________________________
312TGeoVolume*
313AliFMDGeometryBuilder::DetectorGeometry(AliFMDDetector* d,
bf000c32 314 TGeoVolume* topMother,
315 TGeoVolume* botMother,
316 Double_t zMother,
317 TGeoVolume* innerTop,
318 TGeoVolume* innerBot,
319 TGeoVolume* outerTop,
320 TGeoVolume* outerBot)
54e415a8 321{
322 // Common stuff for setting up the FMD1, FMD2, and FMD3 geometries.
323 // This includes putting the Honeycomb support plates and the rings
324 // into the mother volumes.
325 //
326 // Parameeters:
327 // d The detector geometry to use
328 // mother The mother volume of the detector
329 // zmother The midpoint in global coordinates of detector vol.
330 // inner Pointer to inner ring volume
331 // outer Pointer to outer ring volume
332 //
333 // Returns:
334 // Pointer to mother (detector volume)
335 //
336 if (!d) return 0;
337 // Loop over the defined rings
338 for (int i = 0; i < 2; i++) {
339 AliFMDRing* r = 0;
340 Double_t lowr = 0;
341 Double_t highr = 0;
342 Double_t rz = 0;
bf000c32 343 TGeoVolume* tvol = 0;
344 TGeoVolume* bvol = 0;
54e415a8 345 switch (i) {
346 case 0:
347 r = d->GetInner();
348 lowr = d->GetInnerHoneyLowR();
349 highr = d->GetInnerHoneyHighR();
350 rz = d->GetInnerZ();
bf000c32 351 tvol = innerTop;
352 bvol = innerBot;
54e415a8 353 break;
354 case 1:
355 r = d->GetOuter();
356 lowr = d->GetOuterHoneyLowR();
357 highr = d->GetOuterHoneyHighR();
358 rz = d->GetOuterZ();
bf000c32 359 tvol = outerTop;
360 bvol = outerBot;
54e415a8 361 break;
362 }
363 if (!r) continue;
364 Char_t c = r->GetId();
365 Int_t id = d->GetId();
366 Double_t hcThick = d->GetHoneycombThickness();
367 Double_t alThick = d->GetAlThickness();
bf000c32 368 Double_t z = TMath::Abs(rz - zMother);
369
54e415a8 370 // Place ring in mother volume
bf000c32 371 // TGeoMatrix*matrix=new TGeoTranslation(Form("FMD%d%c trans",id,c),0,0,0);
372 AliDebug(5, Form("Placing volumes %s and %s in %s and %s at z=%f",
373 tvol->GetName(), bvol->GetName(),
374 topMother->GetName(), botMother->GetName(), z));
375 topMother->AddNode(tvol, Int_t(c), new TGeoTranslation(0,0,z));
376 botMother->AddNode(bvol, Int_t(c), new TGeoTranslation(0,0,z));
54e415a8 377
54e415a8 378 // Top of Honeycomb
bf000c32 379 TGeoTubeSeg* hcSha = new TGeoTubeSeg(lowr, highr, hcThick/2, 0, 180);
380 TGeoVolume* hcVol = new TGeoVolume(Form(fgkHCName,id,c),hcSha,fAl);
54e415a8 381 // Air in top of honeycomb
bf000c32 382 TGeoTubeSeg* ihcSha = new TGeoTubeSeg(lowr+alThick, highr - alThick,
383 (hcThick-alThick)/2, 0, 180);
384 TGeoVolume* ihcVol = new TGeoVolume(Form(fgkIHCName,id,c),ihcSha,fAir);
385 hcVol->AddNode(ihcVol, 0);
386 hcVol->VisibleDaughters(kFALSE);
387 hcVol->SetVisibility(kTRUE);
388
389 z += (r->GetSiThickness() +
390 r->GetSpacing() +
391 r->GetPrintboardThickness() +
392 r->GetCopperThickness() +
393 r->GetChipThickness() +
394 r->GetModuleSpacing() +
395 r->GetLegLength() +
396 hcThick / 2);
397
398 AliDebug(15, Form("Placing a copy of %s in %s and %s at z=%f",
399 hcVol->GetName(), topMother->GetName(),
400 botMother->GetName(), z));
401 // Add to top
402 topMother->AddNode(hcVol, 0, new TGeoTranslation(0, 0, z));
403
404 // Add to bottom
405 TGeoMatrix* bhcMatrix = new TGeoCombiTrans(0,0,z,0);
406 bhcMatrix->RotateZ(180);
407 botMother->AddNode(hcVol, 1, bhcMatrix);
54e415a8 408 }
bf000c32 409 return 0;
54e415a8 410}
411
412//____________________________________________________________________
413TGeoVolume*
bf000c32 414AliFMDGeometryBuilder::FMD1Geometry(AliFMD1* fmd1,
415 TGeoVolume* innerTop,
416 TGeoVolume* innerBot)
54e415a8 417{
418 // Setup the FMD1 geometry. The FMD1 only has one ring, and no
419 // special support as it is at the momement.
420 //
421 // See also AliFMDGeometryBuilder::DetectorGeometry
422 //
bf000c32 423 if (!fmd1 || !innerTop || !innerBot) return 0;
424 Double_t z = fmd1->GetInnerZ();
425 TGeoVolume* fmd1TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
426 fmd1->GetId(), 'T'));
427 TGeoVolume* fmd1BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
428 fmd1->GetId(), 'B'));
54e415a8 429
bf000c32 430 // Basic detector geometry
431 DetectorGeometry(fmd1, fmd1TopVolume, fmd1BotVolume, z,
432 innerTop, innerBot, 0, 0);
433
434 // Must add this after filling the assembly.
435 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
436 TGeoMatrix* matrix = new TGeoTranslation("FMD1 trans", 0, 0, z);
437 AliDebug(5, Form("Placing volumes %s and %s in ALIC at z=%f",
438 fmd1TopVolume->GetName(), fmd1BotVolume->GetName(), z));
439 top->AddNode(fmd1TopVolume, fmd1->GetId(), matrix);
440 top->AddNode(fmd1BotVolume, fmd1->GetId(), matrix);
441
442 return 0;
54e415a8 443}
444
445//____________________________________________________________________
446TGeoVolume*
447AliFMDGeometryBuilder::FMD2Geometry(AliFMD2* fmd2,
bf000c32 448 TGeoVolume* innerTop,
449 TGeoVolume* innerBot,
450 TGeoVolume* outerTop,
451 TGeoVolume* outerBot)
54e415a8 452{
453 // Setup the FMD2 geometry. The FMD2 has no
454 // special support as it is at the momement.
455 //
456 // See also AliFMDGeometryBuilder::DetectorGeometry
457 //
bf000c32 458 if (!fmd2 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
459 Double_t z = fmd2->GetOuterZ();
460 TGeoVolume* fmd2TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
461 fmd2->GetId(), 'T'));
462 TGeoVolume* fmd2BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
463 fmd2->GetId(), 'B'));
54e415a8 464
bf000c32 465 DetectorGeometry(fmd2, fmd2TopVolume, fmd2BotVolume, z,
466 innerTop, innerBot, outerTop, outerBot);
467
468 // Must be done after filling the assemblies
54e415a8 469 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
bf000c32 470 TGeoMatrix* matrix = new TGeoTranslation("FMD2 trans", 0, 0, z);
471 AliDebug(5, Form("Placing volumes %s and %s in ALIC at z=%f",
472 fmd2TopVolume->GetName(), fmd2BotVolume->GetName(), z));
473 top->AddNode(fmd2TopVolume, fmd2->GetId(), matrix);
474 top->AddNode(fmd2BotVolume, fmd2->GetId(), matrix);
54e415a8 475
bf000c32 476 return 0;
54e415a8 477}
478
479//____________________________________________________________________
480TGeoVolume*
481AliFMDGeometryBuilder::FMD3Geometry(AliFMD3* fmd3,
bf000c32 482 TGeoVolume* innerTop,
483 TGeoVolume* innerBot,
484 TGeoVolume* outerTop,
485 TGeoVolume* outerBot)
54e415a8 486{
487 // Setup the FMD3 geometry. The FMD2 has a rather elaborate support
488 // structure, as the support will also support the vacuum
489 // beam-pipe.
490 //
491 // See also AliFMDGeometryBuilder::DetectorGeometry
492 //
bf000c32 493 if (!fmd3 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
54e415a8 494 Double_t nlen = fmd3->GetNoseLength();
495 Double_t nz = fmd3->GetNoseZ();
496 Double_t noser1 = fmd3->GetNoseLowR();
497 Double_t noser2 = fmd3->GetNoseHighR();
498 Double_t conel = fmd3->GetConeLength();
499 Double_t backl = fmd3->GetBackLength();
500 Double_t backr1 = fmd3->GetBackLowR();
501 Double_t backr2 = fmd3->GetBackHighR();
502 Double_t zdist = conel - backl - nlen;
503 Double_t tdist = backr2 - noser2;
504 Double_t beaml = TMath::Sqrt(zdist * zdist + tdist * tdist);
505 Double_t theta = -180. * TMath::ATan2(tdist, zdist) / TMath::Pi();
54e415a8 506 Double_t flanger = fmd3->GetFlangeR();
bf000c32 507 Double_t z = fmd3->GetInnerZ(); // fmd3->GetZ();
54e415a8 508 Double_t zi;
509
bf000c32 510 TGeoVolume* fmd3TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
511 fmd3->GetId(), 'T'));
512 TGeoVolume* fmd3BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
513 fmd3->GetId(), 'B'));
514
54e415a8 515
bf000c32 516 DetectorGeometry(fmd3, fmd3TopVolume, fmd3BotVolume, z,
517 innerTop, innerBot, outerTop, outerBot);
518
519
54e415a8 520 // Nose volume
bf000c32 521 TGeoTubeSeg* noseShape = new TGeoTubeSeg(noser1, noser2, nlen / 2, 0, 180);
54e415a8 522 TGeoVolume* noseVolume = new TGeoVolume(fgkNoseName, noseShape, fC);
bf000c32 523 zi = -nz + nlen / 2 + z;
524
525 fmd3TopVolume->AddNode(noseVolume, 0, new TGeoTranslation(0, 0, zi));
526 TGeoMatrix* nmatrix = new TGeoCombiTrans(0, 0, zi, 0);
527 nmatrix->RotateZ(180);
528 fmd3BotVolume->AddNode(noseVolume, 1, nmatrix);
54e415a8 529
530 // Back
bf000c32 531 TGeoTubeSeg* backShape = new TGeoTubeSeg(backr1, backr2, backl / 2, 0, 180);
54e415a8 532 TGeoVolume* backVolume = new TGeoVolume(fgkBackName, backShape, fC);
bf000c32 533 zi = -nz + conel - backl / 2 + z;
534 fmd3TopVolume->AddNode(backVolume, 0, new TGeoTranslation(0, 0, zi));
535 TGeoMatrix* bmatrix = new TGeoCombiTrans(0, 0, zi, 0);
536 bmatrix->RotateZ(180);
537 fmd3BotVolume->AddNode(backVolume, 1, bmatrix);
538
54e415a8 539
540 Int_t n;
541 Double_t r;
542 // The flanges
543 TGeoBBox* flangeShape = new TGeoBBox((flanger - backr2) / 2,
544 fmd3->GetBeamWidth() / 2,
545 backl / 2);
546 TGeoVolume* flangeVolume = new TGeoVolume(fgkFlangeName, flangeShape, fC);
bf000c32 547 n = fmd3->GetNFlange();
548 r = backr2 + (flanger - backr2) / 2;
549 TGeoVolume* mother = fmd3TopVolume;
54e415a8 550 for (Int_t i = 0; i < n; i++) {
bf000c32 551 if (i >= n / 2) mother = fmd3BotVolume;
552 Double_t phi = 360. / n * i + 180. / n;
553 Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
554 Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
555 AliDebug(15, Form("Placing flange %d in %s at (%f,%f,%f) r=%f, phi=%f",
556 i, mother->GetName(), x, y, zi, r, phi));
557 TGeoRotation* rot = new TGeoRotation;
54e415a8 558 rot->RotateZ(phi);
bf000c32 559 TGeoMatrix* matrix = new TGeoCombiTrans(x, y, zi, rot);
560 mother->AddNode(flangeVolume, i, matrix);
54e415a8 561 }
562
563 // The Beams
564 TGeoBBox* beamShape = new TGeoBBox(fmd3->GetBeamThickness() / 2,
565 fmd3->GetBeamWidth() / 2 - .1,
566 beaml / 2);
567 TGeoVolume* beamVolume = new TGeoVolume(fgkBeamName, beamShape, fC);
bf000c32 568 n = fmd3->GetNBeam();
569 r = noser2 + tdist / 2;
570 zi = - nz + nlen + zdist / 2 + z;
571 mother = fmd3TopVolume;
54e415a8 572 for (Int_t i = 0; i < n; i++) {
bf000c32 573 if (i >= n / 2) mother = fmd3BotVolume;
574 Double_t phi = 360. / n * i;
575 Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
576 Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
54e415a8 577 TGeoRotation* rot = new TGeoRotation(Form("FMD3 beam rotation %d", i));
578 // Order is important
579 rot->RotateY(-theta);
580 rot->RotateZ(phi);
bf000c32 581 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD3 beam trans %d", i),
54e415a8 582 x, y, zi, rot);
bf000c32 583 mother->AddNode(beamVolume, i, matrix);
54e415a8 584 }
585
bf000c32 586 z = fmd3->GetInnerZ();
587 TGeoRotation* rot = new TGeoRotation("FMD3 rotatation");
588 rot->RotateY(180);
589 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
590 TGeoMatrix* mmatrix = new TGeoCombiTrans("FMD3 trans", 0, 0, z, rot);
591 AliDebug(5, Form("Placing volumes %s and %s in ALIC at z=%f",
592 fmd3TopVolume->GetName(), fmd3BotVolume->GetName(), z));
593 top->AddNode(fmd3TopVolume, fmd3->GetId(), mmatrix);
594 top->AddNode(fmd3BotVolume, fmd3->GetId(), mmatrix);
595
596 return 0;
54e415a8 597}
598
599//____________________________________________________________________
600void
601AliFMDGeometryBuilder::Exec(Option_t*)
602{
603 // Setup up the FMD geometry.
bf000c32 604 AliDebug(1, Form("\tGeometry options: %s",
605 (fDetailed ? "divided into strips" : "one volume")));
54e415a8 606 if (!gGeoManager) {
607 AliFatal("No TGeoManager defined");
608 return;
609 }
610
611 fSi = gGeoManager->GetMedium("FMD_Si$");
612 fC = gGeoManager->GetMedium("FMD_Carbon$");
613 fAl = gGeoManager->GetMedium("FMD_Aluminum$");
614 fChip = gGeoManager->GetMedium("FMD_Si Chip$");
615 fAir = gGeoManager->GetMedium("FMD_Air$");
616 fPCB = gGeoManager->GetMedium("FMD_PCB$");
617 fPlastic = gGeoManager->GetMedium("FMD_Plastic$");
618 fCopper = gGeoManager->GetMedium("FMD_Copper$");
619
620 if (!fSi||!fC||!fAl||!fChip||!fAir||!fPCB||!fPlastic||!fCopper) {
621 AliError("Failed to get some or all tracking mediums");
622 return;
623 }
624 AliFMDGeometry* fmd = AliFMDGeometry::Instance();
bf000c32 625 AliFMDRing* inner = fmd->GetInner();
626 AliFMDRing* outer = fmd->GetOuter();
627 RingGeometry(inner);
628 RingGeometry(outer);
629 TGeoVolume* innerTop = gGeoManager->GetVolume(Form(fgkRingTopName,
630 inner->GetId()));
631 TGeoVolume* innerBot = gGeoManager->GetVolume(Form(fgkRingBotName,
632 inner->GetId()));
633 TGeoVolume* outerTop = gGeoManager->GetVolume(Form(fgkRingTopName,
634 outer->GetId()));
635 TGeoVolume* outerBot = gGeoManager->GetVolume(Form(fgkRingBotName,
636 outer->GetId()));
637
638 FMD1Geometry(fmd->GetFMD1(), innerTop, innerBot);
639 FMD2Geometry(fmd->GetFMD2(), innerTop, innerBot, outerTop, outerBot);
640 FMD3Geometry(fmd->GetFMD3(), innerTop, innerBot, outerTop, outerBot);
54e415a8 641#ifndef USE_PRE_MOVE
642 fmd->SetSectorOff(fSectorOff);
643 fmd->SetModuleOff(fModuleOff);
644 fmd->SetRingOff(fRingOff);
645 fmd->SetDetectorOff(fDetectorOff);
646 fmd->SetActive(fActiveId.fArray, fActiveId.fN);
647#endif
648 // fmd->ExtractGeomInfo();
649
650}
651
652
653//____________________________________________________________________
654//
655// EOF
656//