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