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