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