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