]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDGeometryBuilder.cxx
This is the base class for the FMD Detector Algorithms. All FMD DAs will derive from...
[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");
463 TGeoMatrix* matrix = new TGeoTranslation("FMD1 trans", 0, 0, z);
f95a63c4 464 AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
bf000c32 465 fmd1TopVolume->GetName(), fmd1BotVolume->GetName(), z));
466 top->AddNode(fmd1TopVolume, fmd1->GetId(), matrix);
467 top->AddNode(fmd1BotVolume, fmd1->GetId(), matrix);
468
469 return 0;
54e415a8 470}
471
472//____________________________________________________________________
473TGeoVolume*
474AliFMDGeometryBuilder::FMD2Geometry(AliFMD2* fmd2,
bf000c32 475 TGeoVolume* innerTop,
476 TGeoVolume* innerBot,
477 TGeoVolume* outerTop,
478 TGeoVolume* outerBot)
54e415a8 479{
480 // Setup the FMD2 geometry. The FMD2 has no
481 // special support as it is at the momement.
482 //
483 // See also AliFMDGeometryBuilder::DetectorGeometry
484 //
bf000c32 485 if (!fmd2 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
486 Double_t z = fmd2->GetOuterZ();
487 TGeoVolume* fmd2TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
488 fmd2->GetId(), 'T'));
489 TGeoVolume* fmd2BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
490 fmd2->GetId(), 'B'));
54e415a8 491
bf000c32 492 DetectorGeometry(fmd2, fmd2TopVolume, fmd2BotVolume, z,
493 innerTop, innerBot, outerTop, outerBot);
494
495 // Must be done after filling the assemblies
54e415a8 496 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
bf000c32 497 TGeoMatrix* matrix = new TGeoTranslation("FMD2 trans", 0, 0, z);
f95a63c4 498 AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
bf000c32 499 fmd2TopVolume->GetName(), fmd2BotVolume->GetName(), z));
500 top->AddNode(fmd2TopVolume, fmd2->GetId(), matrix);
501 top->AddNode(fmd2BotVolume, fmd2->GetId(), matrix);
54e415a8 502
bf000c32 503 return 0;
54e415a8 504}
505
506//____________________________________________________________________
507TGeoVolume*
508AliFMDGeometryBuilder::FMD3Geometry(AliFMD3* fmd3,
bf000c32 509 TGeoVolume* innerTop,
510 TGeoVolume* innerBot,
511 TGeoVolume* outerTop,
512 TGeoVolume* outerBot)
54e415a8 513{
514 // Setup the FMD3 geometry. The FMD2 has a rather elaborate support
515 // structure, as the support will also support the vacuum
516 // beam-pipe.
517 //
518 // See also AliFMDGeometryBuilder::DetectorGeometry
519 //
bf000c32 520 if (!fmd3 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
54e415a8 521 Double_t nlen = fmd3->GetNoseLength();
522 Double_t nz = fmd3->GetNoseZ();
523 Double_t noser1 = fmd3->GetNoseLowR();
524 Double_t noser2 = fmd3->GetNoseHighR();
525 Double_t conel = fmd3->GetConeLength();
526 Double_t backl = fmd3->GetBackLength();
527 Double_t backr1 = fmd3->GetBackLowR();
528 Double_t backr2 = fmd3->GetBackHighR();
529 Double_t zdist = conel - backl - nlen;
530 Double_t tdist = backr2 - noser2;
531 Double_t beaml = TMath::Sqrt(zdist * zdist + tdist * tdist);
532 Double_t theta = -180. * TMath::ATan2(tdist, zdist) / TMath::Pi();
54e415a8 533 Double_t flanger = fmd3->GetFlangeR();
bf000c32 534 Double_t z = fmd3->GetInnerZ(); // fmd3->GetZ();
54e415a8 535 Double_t zi;
536
bf000c32 537 TGeoVolume* fmd3TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
538 fmd3->GetId(), 'T'));
539 TGeoVolume* fmd3BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
540 fmd3->GetId(), 'B'));
541
54e415a8 542
bf000c32 543 DetectorGeometry(fmd3, fmd3TopVolume, fmd3BotVolume, z,
544 innerTop, innerBot, outerTop, outerBot);
545
546
54e415a8 547 // Nose volume
bf000c32 548 TGeoTubeSeg* noseShape = new TGeoTubeSeg(noser1, noser2, nlen / 2, 0, 180);
54e415a8 549 TGeoVolume* noseVolume = new TGeoVolume(fgkNoseName, noseShape, fC);
bf000c32 550 zi = -nz + nlen / 2 + z;
551
552 fmd3TopVolume->AddNode(noseVolume, 0, new TGeoTranslation(0, 0, zi));
553 TGeoMatrix* nmatrix = new TGeoCombiTrans(0, 0, zi, 0);
554 nmatrix->RotateZ(180);
555 fmd3BotVolume->AddNode(noseVolume, 1, nmatrix);
54e415a8 556
557 // Back
bf000c32 558 TGeoTubeSeg* backShape = new TGeoTubeSeg(backr1, backr2, backl / 2, 0, 180);
54e415a8 559 TGeoVolume* backVolume = new TGeoVolume(fgkBackName, backShape, fC);
bf000c32 560 zi = -nz + conel - backl / 2 + z;
561 fmd3TopVolume->AddNode(backVolume, 0, new TGeoTranslation(0, 0, zi));
562 TGeoMatrix* bmatrix = new TGeoCombiTrans(0, 0, zi, 0);
563 bmatrix->RotateZ(180);
564 fmd3BotVolume->AddNode(backVolume, 1, bmatrix);
565
54e415a8 566
567 Int_t n;
568 Double_t r;
569 // The flanges
570 TGeoBBox* flangeShape = new TGeoBBox((flanger - backr2) / 2,
571 fmd3->GetBeamWidth() / 2,
572 backl / 2);
573 TGeoVolume* flangeVolume = new TGeoVolume(fgkFlangeName, flangeShape, fC);
bf000c32 574 n = fmd3->GetNFlange();
575 r = backr2 + (flanger - backr2) / 2;
576 TGeoVolume* mother = fmd3TopVolume;
54e415a8 577 for (Int_t i = 0; i < n; i++) {
bf000c32 578 if (i >= n / 2) mother = fmd3BotVolume;
579 Double_t phi = 360. / n * i + 180. / n;
580 Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
581 Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
f95a63c4 582 AliFMDDebug(15, ("Placing flange %d in %s at (%f,%f,%f) r=%f, phi=%f",
bf000c32 583 i, mother->GetName(), x, y, zi, r, phi));
584 TGeoRotation* rot = new TGeoRotation;
54e415a8 585 rot->RotateZ(phi);
bf000c32 586 TGeoMatrix* matrix = new TGeoCombiTrans(x, y, zi, rot);
587 mother->AddNode(flangeVolume, i, matrix);
54e415a8 588 }
589
590 // The Beams
591 TGeoBBox* beamShape = new TGeoBBox(fmd3->GetBeamThickness() / 2,
592 fmd3->GetBeamWidth() / 2 - .1,
593 beaml / 2);
594 TGeoVolume* beamVolume = new TGeoVolume(fgkBeamName, beamShape, fC);
bf000c32 595 n = fmd3->GetNBeam();
596 r = noser2 + tdist / 2;
597 zi = - nz + nlen + zdist / 2 + z;
598 mother = fmd3TopVolume;
54e415a8 599 for (Int_t i = 0; i < n; i++) {
bf000c32 600 if (i >= n / 2) mother = fmd3BotVolume;
601 Double_t phi = 360. / n * i;
602 Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
603 Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
54e415a8 604 TGeoRotation* rot = new TGeoRotation(Form("FMD3 beam rotation %d", i));
605 // Order is important
606 rot->RotateY(-theta);
607 rot->RotateZ(phi);
bf000c32 608 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD3 beam trans %d", i),
54e415a8 609 x, y, zi, rot);
bf000c32 610 mother->AddNode(beamVolume, i, matrix);
54e415a8 611 }
612
bf000c32 613 z = fmd3->GetInnerZ();
614 TGeoRotation* rot = new TGeoRotation("FMD3 rotatation");
615 rot->RotateY(180);
616 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
617 TGeoMatrix* mmatrix = new TGeoCombiTrans("FMD3 trans", 0, 0, z, rot);
f95a63c4 618 AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
bf000c32 619 fmd3TopVolume->GetName(), fmd3BotVolume->GetName(), z));
620 top->AddNode(fmd3TopVolume, fmd3->GetId(), mmatrix);
621 top->AddNode(fmd3BotVolume, fmd3->GetId(), mmatrix);
622
623 return 0;
54e415a8 624}
625
626//____________________________________________________________________
627void
628AliFMDGeometryBuilder::Exec(Option_t*)
629{
630 // Setup up the FMD geometry.
f95a63c4 631 AliFMDDebug(1, ("\tGeometry options: %s",
bf000c32 632 (fDetailed ? "divided into strips" : "one volume")));
54e415a8 633 if (!gGeoManager) {
634 AliFatal("No TGeoManager defined");
635 return;
636 }
637
638 fSi = gGeoManager->GetMedium("FMD_Si$");
639 fC = gGeoManager->GetMedium("FMD_Carbon$");
640 fAl = gGeoManager->GetMedium("FMD_Aluminum$");
641 fChip = gGeoManager->GetMedium("FMD_Si Chip$");
642 fAir = gGeoManager->GetMedium("FMD_Air$");
643 fPCB = gGeoManager->GetMedium("FMD_PCB$");
644 fPlastic = gGeoManager->GetMedium("FMD_Plastic$");
645 fCopper = gGeoManager->GetMedium("FMD_Copper$");
646
647 if (!fSi||!fC||!fAl||!fChip||!fAir||!fPCB||!fPlastic||!fCopper) {
648 AliError("Failed to get some or all tracking mediums");
649 return;
650 }
651 AliFMDGeometry* fmd = AliFMDGeometry::Instance();
bf000c32 652 AliFMDRing* inner = fmd->GetInner();
653 AliFMDRing* outer = fmd->GetOuter();
654 RingGeometry(inner);
655 RingGeometry(outer);
656 TGeoVolume* innerTop = gGeoManager->GetVolume(Form(fgkRingTopName,
657 inner->GetId()));
658 TGeoVolume* innerBot = gGeoManager->GetVolume(Form(fgkRingBotName,
659 inner->GetId()));
660 TGeoVolume* outerTop = gGeoManager->GetVolume(Form(fgkRingTopName,
661 outer->GetId()));
662 TGeoVolume* outerBot = gGeoManager->GetVolume(Form(fgkRingBotName,
663 outer->GetId()));
664
665 FMD1Geometry(fmd->GetFMD1(), innerTop, innerBot);
666 FMD2Geometry(fmd->GetFMD2(), innerTop, innerBot, outerTop, outerBot);
667 FMD3Geometry(fmd->GetFMD3(), innerTop, innerBot, outerTop, outerBot);
54e415a8 668#ifndef USE_PRE_MOVE
669 fmd->SetSectorOff(fSectorOff);
670 fmd->SetModuleOff(fModuleOff);
671 fmd->SetRingOff(fRingOff);
672 fmd->SetDetectorOff(fDetectorOff);
673 fmd->SetActive(fActiveId.fArray, fActiveId.fN);
674#endif
675 // fmd->ExtractGeomInfo();
676
677}
678
679
680//____________________________________________________________________
681//
682// EOF
683//