1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
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
21 //____________________________________________________________________
23 // Builder of FMD geometry.
25 // This class takes care of actually building the geometry using the
26 // TGeo classes. Various parameters are fecthed from the
27 // AliFMDGeometry manager.
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.
35 #include <TArrayD.h> // ROOT_TArrayD
36 #include <TGeoManager.h> // ROOT_TGeoManager
37 #include <TGeoMatrix.h> // ROOT_TGeoMatrix
38 #include <TGeoTube.h> // ROOT_TGeoTube
39 #include <TGeoTrd1.h> // ROOT_TGeoTrd1
40 #include <TGeoCone.h> // ROOT_TGeoTrd1
41 #include <TGeoVolume.h> // ROOT_TGeoVolume
42 #include <TGeoXtru.h> // ROOT_TGeoXtru
43 #include <TGeoPcon.h> // ROOT_TGeoPcon
44 #include <TGeoTorus.h> // ROOT_TGeoTorus
45 #include <TGeoCompositeShape.h>
47 #include <TVector2.h> // ROOT_TVector2
48 #include <TVector3.h> // ROOT_TVector3
49 //#include <TGeoMaterial.h> // ROOT_TGeoMaterial
50 //#include <TGeoMedium.h> // ROOT_TGeoMedium
51 //#include <TGeoPcon.h> // ROOT_TGeoPcon
52 //#include <TGeoPolygon.h> // ROOT_TGeoPolygon
54 #include "AliFMDGeometryBuilder.h" // ALIFMDGEOSIMULATOR_H
55 #include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
56 #include "AliFMDDetector.h" // ALIFMDDETECTOR_H
57 #include "AliFMDRing.h" // ALIFMDRING_H
58 #include "AliFMD1.h" // ALIFMD1_H
59 #include "AliFMD2.h" // ALIFMD2_H
60 #include "AliFMD3.h" // ALIFMD3_H
61 // #include "AliFMD.h" // ALIFMD_H
62 #include "AliFMDDebug.h" // ALILOG_H
65 //====================================================================
66 ClassImp(AliFMDGeometryBuilder)
68 ; // This is here to keep Emacs for indenting the next line
71 //____________________________________________________________________
72 const Char_t* AliFMDGeometryBuilder::fgkActiveName = "F%cAC";
73 const Char_t* AliFMDGeometryBuilder::fgkSectorName = "F%cSC";
74 const Char_t* AliFMDGeometryBuilder::fgkStripName = "F%cST";
75 const Char_t* AliFMDGeometryBuilder::fgkSensorName = "F%cSE";
76 const Char_t* AliFMDGeometryBuilder::fgkPCBName = "F%cPB";
77 const Char_t* AliFMDGeometryBuilder::fgkCuName = "F%cCU";
78 const Char_t* AliFMDGeometryBuilder::fgkChipName = "F%cCH";
79 const Char_t* AliFMDGeometryBuilder::fgkLongLegName = "F%cLL";
80 const Char_t* AliFMDGeometryBuilder::fgkShortLegName = "F%cSL";
81 const Char_t* AliFMDGeometryBuilder::fgkFrontVName = "F%cFH";
82 const Char_t* AliFMDGeometryBuilder::fgkBackVName = "F%cBH";
83 const Char_t* AliFMDGeometryBuilder::fgkRingTopName = "F%cTV";
84 const Char_t* AliFMDGeometryBuilder::fgkRingBotName = "F%cBV";
85 const Char_t* AliFMDGeometryBuilder::fgkHCName = "F%dH%c";
86 const Char_t* AliFMDGeometryBuilder::fgkIHCName = "F%dI%c";
87 const Char_t* AliFMDGeometryBuilder::fgkNoseName = "F3SN";
88 const Char_t* AliFMDGeometryBuilder::fgkBackName = "F%dSB";
89 const Char_t* AliFMDGeometryBuilder::fgkTopName = "F%dSU";
90 const Char_t* AliFMDGeometryBuilder::fgkBeamName = "F%dSL";
91 const Char_t* AliFMDGeometryBuilder::fgkFlangeName = "F%dSF";
92 const Char_t* AliFMDGeometryBuilder::fgkFMDDCuName = "F%cDC";
93 const Char_t* AliFMDGeometryBuilder::fgkFMDDPCBName = "F%cDP";
94 const Char_t* AliFMDGeometryBuilder::fgkFMDDChipName = "F%cDI";
95 const Char_t* AliFMDGeometryBuilder::fgkFMDDName = "F%cDD";
96 const Char_t* AliFMDGeometryBuilder::fgkFMDName = "F%dM%c";
98 //____________________________________________________________________
99 AliFMDGeometryBuilder::AliFMDGeometryBuilder()
100 : TTask("FMD", "Geomtry builder"),
118 // Default constructor
122 //____________________________________________________________________
123 AliFMDGeometryBuilder::AliFMDGeometryBuilder(Bool_t detailed)
124 : TTask("FMD", "Geometry builder"),
142 // Normal constructor
146 // fmd Pointer to AliFMD object
147 // detailed Whether to make a detailed simulation or not
152 //____________________________________________________________________
154 AliFMDGeometryBuilder::MakeXTRU(const TObjArray& verticies,
155 Double_t thick) const
159 for (Int_t i = 0; i < 3; i++) {
160 TVector2* v = static_cast<TVector2*>(verticies.At(i+1));
166 TGeoXtru* shape = new TGeoXtru(2);
167 shape->DefinePolygon(xs.fN, xs.fArray, ys.fArray);
168 shape->DefineSection(0, -thick/2);
169 shape->DefineSection(1, +thick/2);
174 //____________________________________________________________________
176 AliFMDGeometryBuilder::RingGeometry(AliFMDRing* r)
178 // Setup the geometry of a ring. The defined TGeoVolume is
179 // returned, and should be used when setting up the rest of the
185 // r Pointer to ring geometry object
188 // pointer to ring volume
191 AliError("Didn't get a ring object");
194 Char_t id = r->GetId();
195 Char_t rng = toupper(id);
196 const Char_t* lName = (rng == 'I' ? "inner" : "outer");
197 Double_t siThick = r->GetSiThickness();
198 Double_t pcbThick = r->GetPrintboardThickness();
199 Double_t cuThick = r->GetCopperThickness();
200 Double_t chipThick= r->GetChipThickness();
201 Double_t modSpace = r->GetModuleSpacing();
202 Double_t theta = r->GetTheta();
204 //------------------------------------------------------------------
207 TGeoShape* sensorShape = MakeXTRU(r->GetSensorVerticies(), siThick);
208 sensorShape->SetName(Form("FMD%c_physical_sensor", id));
209 sensorShape->SetTitle(Form("FMD %s physical sensor", lName));
210 TGeoVolume* sensorVolume = new TGeoVolume(Form(fgkSensorName, id),
212 sensorVolume->SetTitle(Form("FMD %s Sensor", lName));
213 sensorVolume->VisibleDaughters(kFALSE);
214 Int_t sid = sensorVolume->GetNumber();
225 // Virtual volume shape to divide - This volume is only defined if
226 // the geometry is set to be detailed.
227 TGeoTubeSeg* activeShape = new TGeoTubeSeg(r->GetLowR(),
232 activeShape->SetName(Form(fgkActiveName, id));
233 activeShape->SetTitle(Form("FMD %s active area", lName));
234 TGeoVolume* activeVolume = new TGeoVolume(Form(fgkActiveName, id),
236 activeVolume->SetTitle(Form("FMD %s active area", lName));
237 TGeoVolume* sectorVolume = activeVolume->Divide(Form(fgkSectorName,id),
241 Int_t ns = r->GetNStrips();
242 Double_t stripoff = r->GetLowR(); // 0; // a->Mod();
243 Double_t dstrip = (r->GetHighR() - stripoff) / ns;
245 sectorVolume->SetTitle(Form("FMD %s sector", lName));
246 TGeoVolume* stripVolume = sectorVolume->Divide(Form(fgkStripName, id),
247 1, ns, stripoff, dstrip,
249 stripVolume->SetTitle(Form("FMD %s strip", lName));
250 sid = stripVolume->GetNumber();
251 sensorVolume->AddNodeOverlap(activeVolume, 0);
255 case 'I': fActiveId[0] = sid; break;
256 case 'O': fActiveId[1] = sid; break;
259 //------------------------------------------------------------------
261 // PCB layer of hybrid
262 TGeoShape* pcbShape = MakeXTRU(r->GetHybridVerticies(), pcbThick);
263 pcbShape->SetName(Form("FMD%c_hybrid_pcb", id));
264 pcbShape->SetTitle(Form("FMD %s hybrid PCB", lName));
265 TGeoVolume* pcbVolume = new TGeoVolume(Form(fgkPCBName, id), pcbShape, fPCB);
266 pcbVolume->SetTitle(Form("FMD %s hybrid PCB", lName));
269 TGeoShape* cuShape = MakeXTRU(r->GetHybridVerticies(), cuThick);
270 cuShape->SetName(Form("FMD%c_hybrid_copper", id));
271 cuShape->SetTitle(Form("FMD %s hybrid copper", lName));
272 TGeoVolume* cuVolume = new TGeoVolume(Form(fgkCuName,id),cuShape,fCopper);
273 cuVolume->SetTitle(Form("FMD %s hybrid copper", lName));
276 TGeoShape* chipShape = MakeXTRU(r->GetHybridVerticies(), chipThick);
277 chipShape->SetName(Form("FMD%c_hybrid_chip", id));
278 chipShape->SetTitle(Form("FMD %s hybrid chip", lName));
279 TGeoVolume* chipVolume = new TGeoVolume(Form(fgkChipName,id),chipShape,fChip);
280 chipVolume->SetTitle(Form("FMD %s hybrid chip", lName));
282 //------------------------------------------------------------------
284 Double_t legr = r->GetLegRadius();
285 Double_t legl = r->GetLegLength();
289 TGeoTube* shortLegShape = new TGeoTube(0, legr, (legl-lege) / 2);
290 shortLegShape->SetName(Form(fgkShortLegName, id));
291 shortLegShape->SetTitle(Form("FMD %s short support foot", lName));
292 TGeoVolume* shortLegVolume = new TGeoVolume(Form(fgkShortLegName, id),
293 shortLegShape, fCopper);
294 shortLegVolume->SetTitle(Form("FMD %s short support foot", lName));
296 TGeoTube* longLegShape = new TGeoTube(0, legr,
297 (legl - lege + modSpace) / 2);
298 longLegShape->SetName(Form(fgkLongLegName, id));
299 longLegShape->SetTitle(Form("FMD %s long support foot", lName));
300 TGeoVolume* longLegVolume = new TGeoVolume(Form(fgkLongLegName, id),
301 longLegShape, fCopper);
302 longLegVolume->SetTitle(Form("FMD %s long support foot", lName));
306 //------------------------------------------------------------------
307 // Placement of module volumes in assemblies
310 for (Int_t i = 0; i < 3; i++) {
311 TVector2* vv = r->GetFootPosition(i);
312 // TVector2 uu = vv->Rotate(TMath::Pi()/2);
317 // Back container volume
318 TGeoVolume* backVolume = new TGeoVolumeAssembly(Form(fgkBackVName, id));
319 backVolume->SetTitle(Form("FMD %s back module", lName));
320 TGeoVolume* frontVolume = new TGeoVolumeAssembly(Form(fgkFrontVName, id));
321 frontVolume->SetTitle(Form("FMD %s front module", lName));
323 Double_t space = r->GetSpacing();
326 Double_t zb = siThick / 2;
327 Double_t zf = siThick / 2;
328 backVolume->AddNode(sensorVolume, 0, new TGeoTranslation(x, y, zb));
329 frontVolume->AddNode(sensorVolume, 0, new TGeoTranslation(x, y, zf));
330 zb += siThick / 2 + space + pcbThick / 2;
331 zf += siThick / 2 + space + pcbThick / 2;
332 backVolume->AddNode(pcbVolume, 0, new TGeoTranslation(x, y, zb));
333 frontVolume->AddNode(pcbVolume, 0, new TGeoTranslation(x, y, zf));
334 zb += (pcbThick + cuThick) / 2;
335 zf += (pcbThick + cuThick) / 2;
336 backVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, zf));
337 frontVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, zb));
338 zb += (cuThick + chipThick) / 2;
339 zf += (cuThick + chipThick) / 2;
340 backVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, zb));
341 frontVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, zf));
342 zb += pcbThick / 2 + (legl)/ 2 - lege;
343 zf += pcbThick / 2 + (legl + modSpace)/ 2 - lege;
344 for (Int_t i = 0; i < 3; i++) {
345 x = xfs[i]; // a->X() + legoff + legr;
347 backVolume->AddNode(shortLegVolume, i, new TGeoTranslation(x,y,zb));
348 frontVolume->AddNode(longLegVolume, i, new TGeoTranslation(x,y,zf));
351 //------------------------------------------------------------------
353 Double_t ddlr = r->GetFMDDLowR();
354 Double_t ddhr = r->GetFMDDHighR();
355 Double_t ddpt = r->GetFMDDPrintboardThickness();
356 Double_t ddct = r->GetFMDDCopperThickness();
357 Double_t ddit = r->GetFMDDChipThickness();
358 Double_t ddt = ddpt + ddct + ddit;
360 TString pcbName(Form(fgkFMDDPCBName, id));
361 TString cuName(Form(fgkFMDDCuName, id));
362 TString chipName(Form(fgkFMDDChipName, id));
363 new TGeoTubeSeg(Form("%s_inner", pcbName.Data()), ddlr, ddhr, ddpt/2,0,180);
364 new TGeoTubeSeg(Form("%s_inner", cuName.Data()), ddlr, ddhr, ddct/2,0,180);
365 new TGeoTubeSeg(Form("%s_inner", chipName.Data()), ddlr, ddhr, ddit/2,0,180);
380 new TGeoBBox(Form("%s_clip", pcbName.Data()), clipWX, clipWY, ddpt);
381 new TGeoBBox(Form("%s_clip", cuName.Data()), clipWX, clipWY, ddct);
382 new TGeoBBox(Form("%s_clip", chipName.Data()),clipWX, clipWY, ddit);
383 TGeoTranslation* trans = new TGeoTranslation(Form("%s_trans",
386 trans->RegisterYourself();
387 TGeoShape* fmddPcbShape =
388 new TGeoCompositeShape(pcbName.Data(),
389 Form("%s_inner*%s_clip:%s_trans",
393 TGeoShape* fmddCuShape =
394 new TGeoCompositeShape(cuName.Data(),
395 Form("%s_inner*%s_clip:%s_trans",
399 TGeoShape* fmddChipShape =
400 new TGeoCompositeShape(chipName.Data(),
401 Form("%s_inner*%s_clip:%s_trans",
405 fmddPcbShape->SetTitle(Form("FMD %s digitiser PCB", lName));
406 fmddCuShape->SetTitle(Form("FMD %s digitiser copper", lName));
407 fmddChipShape->SetTitle(Form("FMD %s digitiser chip", lName));
409 TGeoVolume* fmddPcbVolume = new TGeoVolume(Form(fgkFMDDPCBName, id),
411 TGeoVolume* fmddCuVolume = new TGeoVolume(Form(fgkFMDDCuName, id),
412 fmddCuShape, fCopper);
413 TGeoVolume* fmddChipVolume= new TGeoVolume(Form(fgkFMDDChipName, id),
414 fmddChipShape, fChip);
415 fmddPcbVolume->SetTitle(Form("FMD %s digitiser PCB", lName));
416 fmddCuVolume->SetTitle(Form("FMD %s digitiser copper", lName));
417 fmddChipVolume->SetTitle(Form("FMD %s digitiser chip", lName));
419 //------------------------------------------------------------------
420 // Half ring mother volumes.
421 TGeoVolume* ringTopVolume = new TGeoVolumeAssembly(Form(fgkRingTopName,id));
422 TGeoVolume* ringBotVolume = new TGeoVolumeAssembly(Form(fgkRingBotName,id));
423 TGeoVolume* halfRing = ringTopVolume;
424 ringTopVolume->SetTitle(Form("FMD %s top half-ring", lName));
425 ringBotVolume->SetTitle(Form("FMD %s bottom half-ring", lName));
427 //------------------------------------------------------------------
428 // Adding modules to half-rings
429 Int_t nmod = r->GetNModules();
430 AliFMDDebug(10, ("making %d modules in ring %c", nmod, id));
431 for (Int_t i = 0; i < nmod; i++) {
432 if (i == nmod / 2) halfRing = ringBotVolume;
433 Bool_t front = (i % 2 == (rng == 'I' ? 1 : 0));
434 TGeoVolume* vol = (front ? frontVolume : backVolume);
435 // vol->AddNode(sensorVolume, i, new TGeoTranslation(0,0,siThick/2));
436 Double_t z1 = (front ? -1 : 1) * modSpace / 2;
437 // Double_t z1 = (front ? 0 : modSpace);
438 Double_t th = (2 * i + 1) * theta;
439 TGeoMatrix* mat1 = new TGeoCombiTrans(0,0,z1,0);
441 mat1->SetName(Form("FMD%c_module_%02d", id, i));
442 mat1->SetTitle(Form("FMD %s module %2d matrix", lName, i));
443 halfRing->AddNode(vol, i, mat1);
446 //------------------------------------------------------------------
448 Double_t zi = r->GetFullDepth() - ddt;
450 for (Int_t i = 0; i < n; i++) {
451 halfRing = (i == 0 ? ringTopVolume : ringBotVolume);
452 Double_t phi = 360. / n * i;
453 TGeoRotation* rot = new TGeoRotation(Form("FMDD%c rotation %d", id, i));
455 rot->SetTitle(Form("FMD %s digitiser rotation %2d", lName, i));
456 Double_t z = zi + ddpt / 2;
457 halfRing->AddNode(fmddPcbVolume, i, new TGeoCombiTrans(0,0,z,rot));
458 z += (ddpt + ddct) / 2;
459 halfRing->AddNode(fmddCuVolume, i, new TGeoCombiTrans(0,0,z,rot));
460 z += (ddct + ddit) / 2;
461 halfRing->AddNode(fmddChipVolume, i, new TGeoCombiTrans(0,0,z,rot));
469 //____________________________________________________________________
471 AliFMDGeometryBuilder::HoneycombShape(Int_t id, Char_t ring,
472 double r1, double r2,
473 double w, double t, double c)
475 // Make a honey comb shape from passed parameters.
477 // id Detector identifier (1,2, or 3)
478 // ring Ring identifier ('I' or 'O')
482 // t Thickness of material
483 // c Clearing from horizontal.
485 // Pointer to newly allocated composite shape.
486 TString form = Form("FMD%d%c_%%c_%%c", id, ring);
487 double a1 = TMath::ATan2(c, r1) * 180 / TMath::Pi();
489 TString fn = Form(form.Data(),'F','1');
490 TString bn = Form(form.Data(),'B','1');
491 TString cn = Form(form.Data(),'C','O');
492 TString in = Form(form.Data(),'R','I');
493 TString on = Form(form.Data(),'R','O');
494 TString en = Form(form.Data(),'E','X');
496 double x = r1 * TMath::Cos(TMath::Pi()*a1/180);
497 new TGeoTubeSeg(fn.Data(),r1,r2,t/2,0,180);
498 new TGeoTubeSeg(bn.Data(),r1,r2,t/2,0,180);
499 new TGeoBBox(cn.Data(),(r2-r1)/2,t/2,w/2);
500 new TGeoTubeSeg(in.Data(),r1,r1+t,w/2,0,180);
501 new TGeoTubeSeg(on.Data(),r2-t,r2,w/2,0,180);
502 new TGeoBBox(en.Data(),r2+.005,c/2+.005,w/2+.005);
504 TString ftn = Form(form.Data(),'F','T');
505 TString btn = Form(form.Data(),'F','B');
506 TString ltn = Form(form.Data(),'C','L');
507 TString rtn = Form(form.Data(),'C','R');
508 TString etn = Form(form.Data(),'E','X');
509 (new TGeoTranslation(ftn.Data(),0,0,+w/2-t/2))->RegisterYourself();
510 (new TGeoTranslation(btn.Data(),0,0,-w/2+t/2))->RegisterYourself();
511 (new TGeoTranslation(ltn.Data(),-(x+(r2-r1)/2), y+t/2,0))->RegisterYourself();
512 (new TGeoTranslation(rtn.Data(),(x+(r2-r1)/2), y+t/2,0))->RegisterYourself();
513 (new TGeoTranslation(etn.Data(),0, c/2,0))->RegisterYourself();
515 TString comp(Form("(%s:%s+%s:%s+%s+%s+%s:%s+%s:%s)-%s:%s",
516 fn.Data(),ftn.Data(),
517 bn.Data(),btn.Data(),
519 cn.Data(),ltn.Data(),
520 cn.Data(),rtn.Data(),
521 en.Data(),etn.Data()));
522 TGeoCompositeShape* shape = new TGeoCompositeShape(comp.Data());
523 shape->SetName(Form(fgkHCName,id,ring));
524 shape->SetTitle(Form("FMD%d%c Honeycomb shape", id, ring));
528 //____________________________________________________________________
530 AliFMDGeometryBuilder::TensionBox()
532 static TGeoVolumeAssembly* tensionBox = 0;
533 if (tensionBox) return tensionBox;
535 TGeoBBox* tensionEndS = new TGeoBBox("FMD_tension_end", .6, 3, .25);
536 TGeoBBox* tensionTopS = new TGeoBBox("FMD_tension_top", .1, .5, 3.5);
537 TGeoVolume* tensionEndV = new TGeoVolume("FMD_tension_end", tensionEndS,fAl);
538 TGeoVolume* tensionTopV = new TGeoVolume("FMD_tension_top", tensionTopS,fAl);
539 tensionBox = new TGeoVolumeAssembly("FMD_tension_box");
540 tensionBox->AddNode(tensionEndV, 1, new TGeoTranslation(.6, 0, -3.75));
541 tensionBox->AddNode(tensionEndV, 2, new TGeoTranslation(.6, 0, +3.75));
542 tensionBox->AddNode(tensionTopV, 1, new TGeoTranslation(0.1, +2.5, 0));
543 tensionBox->AddNode(tensionTopV, 2, new TGeoTranslation(0.1, -2.5, 0));
544 tensionBox->AddNode(tensionTopV, 3, new TGeoTranslation(1.1, +2.5, 0));
545 tensionBox->AddNode(tensionTopV, 4, new TGeoTranslation(1.1, -2.5, 0));
550 //____________________________________________________________________
552 AliFMDGeometryBuilder::DetectorGeometry(AliFMDDetector* d,
553 TGeoVolume* topMother,
554 TGeoVolume* botMother,
556 TGeoVolume* innerTop,
557 TGeoVolume* innerBot,
558 TGeoVolume* outerTop,
559 TGeoVolume* outerBot)
561 // Common stuff for setting up the FMD1, FMD2, and FMD3 geometries.
562 // This includes putting the Honeycomb support plates and the rings
563 // into the mother volumes.
566 // d The detector geometry to use
567 // mother The mother volume of the detector
568 // zmother The midpoint in global coordinates of detector vol.
569 // inner Pointer to inner ring volume
570 // outer Pointer to outer ring volume
573 // Pointer to mother (detector volume)
576 // Loop over the defined rings
577 for (int i = 0; i < 2; i++) {
582 TGeoVolume* tvol = 0;
583 TGeoVolume* bvol = 0;
587 lowr = d->GetInnerHoneyLowR();
588 highr = d->GetInnerHoneyHighR();
595 lowr = d->GetOuterHoneyLowR();
596 highr = d->GetOuterHoneyHighR();
603 Char_t c = r->GetId();
604 Int_t id = d->GetId();
605 Double_t hcThick = r->GetHoneycombThickness();
606 Double_t alThick = r->GetAlThickness();
607 Double_t z = TMath::Abs(rz - zMother);
609 // Place ring in mother volume
610 // TGeoMatrix*matrix=new TGeoTranslation(Form("FMD%d%c trans",id,c),0,0,0);
611 AliFMDDebug(2, ("Placing volumes %s and %s in %s and %s at z=%f",
612 tvol->GetName(), bvol->GetName(),
613 topMother->GetName(), botMother->GetName(), z));
614 topMother->AddNode(tvol, Int_t(c), new TGeoTranslation(0,0,z));
615 botMother->AddNode(bvol, Int_t(c), new TGeoTranslation(0,0,z));
618 TGeoShape* hcSha = HoneycombShape(id, c, lowr, highr, hcThick, alThick);
619 TGeoVolume* hcVol = new TGeoVolume(Form(fgkHCName,id,c),hcSha,fAl);
620 hcVol->SetTitle(Form("FMD%d%c honeycomb shell", id, c));
622 z += (r->GetModuleDepth()
623 + r->GetModuleSpacing() / 2
624 + r->GetHoneycombThickness() / 2);
626 AliFMDDebug(15, ("Placing a copy of %s in %s and %s at z=%f",
627 hcVol->GetName(), topMother->GetName(),
628 botMother->GetName(), z));
630 topMother->AddNode(hcVol, 0, new TGeoTranslation(0, 0, z));
633 TGeoMatrix* bhcMatrix = new TGeoCombiTrans(0,0,z,0);
634 bhcMatrix->SetName(Form("FMD%d%c_honeycomp", id, c));
635 bhcMatrix->SetTitle(Form("FMD%d%c honeycomp", id, c));
636 bhcMatrix->RotateZ(180);
637 botMother->AddNode(hcVol, 1, bhcMatrix);
642 //____________________________________________________________________
644 AliFMDGeometryBuilder::FMD1Geometry(AliFMD1* fmd1,
645 TGeoVolume* innerTop,
646 TGeoVolume* innerBot)
648 // Setup the FMD1 geometry. The FMD1 only has one ring, and no
649 // special support as it is at the momement.
651 // See also AliFMDGeometryBuilder::DetectorGeometry
653 if (!fmd1 || !innerTop || !innerBot) return 0;
654 AliFMDRing* r = fmd1->GetInner();
655 Double_t z = fmd1->GetInnerZ();
657 // `Top' or `Outside' master volume
658 TGeoVolume* fmd1TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
659 fmd1->GetId(), 'T'));
660 fmd1TopVolume->SetTitle("FMD1 top half");
662 // `Bottom' or `Inside' master volume
663 TGeoVolume* fmd1BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
664 fmd1->GetId(), 'B'));
665 fmd1BotVolume->SetTitle("FMD1 bottom half");
667 // Basic detector geometry
668 DetectorGeometry(fmd1, fmd1TopVolume, fmd1BotVolume, z,
669 innerTop, innerBot, 0, 0);
671 Double_t lidP[][3] = { { 0.00, 4.20, 20.95 },
672 { 0.15, 4.20, 20.95 },
673 { 0.15, 20.80, 20.95 },
674 { 3.00, 20.80, 20.95 },
675 { 3.00, 20.80, 22.30 },
676 { 3.15, 20.80, 22.30 },
677 { 3.15, 20.95, 24.65 },
678 { 3.30, 20.95, 24.65 },
679 { 3.30, 24.50, 24.65 },
680 { 6.80, 24.50, 24.65 },
681 { 6.80, 24.50, 26.00 },
682 { 6.95, 24.50, 26.00 } };
683 Double_t lidZStart = lidP[11][0];
684 TGeoPcon* lidBaseS = new TGeoPcon("FMD1_lid_base", 0, 180, 12);
685 for (size_t i = 0; i < 12; i++)
686 lidBaseS->DefineSection(i, lidP[i][0] - lidZStart, lidP[i][1], lidP[i][2]);
689 Double_t lidH[][2] = { { 7.84903, 24.15680 },
690 { 20.54900, 14.92970 },
691 { 21.99700, 12.70000 },
692 { 25.26090, 2.65502 } };
693 Double_t lidHR = .53 / 2;
694 Double_t lidHL = 0.16;
696 new TGeoTube("FMD1_lid_hole", 0, lidHR, lidHL/2);
697 TString lidComp("FMD1_lid_base-(");
698 TGeoTranslation* trans = 0;
699 for (size_t i = 0; i < 4; i++) {
700 trans = new TGeoTranslation(-lidH[i][0], lidH[i][1], /*6.95*/-lidHL/2);
701 trans->SetName(Form("FMD1_lid_hole_mat%d", 2*i+0));
702 trans->RegisterYourself();
703 trans = new TGeoTranslation(+lidH[i][0], lidH[i][1], /*6.95*/-lidHL/2);
704 trans->SetName(Form("FMD1_lid_hole_mat%d", 2*i+1));
705 trans->RegisterYourself();
706 lidComp.Append(Form("FMD1_lid_hole:FMD1_lid_hole_mat%d+"
707 "FMD1_lid_hole:FMD1_lid_hole_mat%d%c",
708 2 * i, 2 * i + 1, i == 3 ? ')' : '+'));
710 TGeoCompositeShape* lidS = new TGeoCompositeShape(lidComp.Data());
711 lidS->SetName("FMD1_lid");
712 TGeoVolume* lidV = new TGeoVolume("FMD1_lid", lidS, fC);
713 lidV->SetTransparency(63);
716 Double_t lidZ = (lidZStart -
717 (3.3 - r->GetModuleDepth() - r->GetModuleSpacing() / 2));
718 AliFMDDebug(1, ("FMD1 lid offset in Z=%f", lidZ));
720 for (Int_t i = 0; i < 2; i++) {
721 TGeoVolume* mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
722 Double_t phi = 360. / 2 * i;
723 TGeoRotation* rot = new TGeoRotation(Form("FMD1_lid_rot%d",i));
725 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD1_lid_mat%d", i),
727 mother->AddNode(lidV, i, matrix);
730 // Must add this after filling the assembly.
731 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
732 // TGeoMatrix* matrix = new TGeoTranslation("FMD1 trans", 0, 0, z);
733 TGeoRotation* rot = new TGeoRotation("FMD1 rotatation");
735 TGeoMatrix* matrix = new TGeoCombiTrans("FMD1 trans", 0, 0, z, rot);
737 AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
738 fmd1TopVolume->GetName(), fmd1BotVolume->GetName(), z));
739 top->AddNode(fmd1TopVolume, fmd1->GetId(), matrix);
740 top->AddNode(fmd1BotVolume, fmd1->GetId(), matrix);
743 // Survey points on V0A (screw holes for the FMD)
744 const Double_t icb[] = { +12.700, -21.997, 324.670 };
745 const Double_t ict[] = { +12.700, +21.997, 324.670 };
746 const Double_t ocb[] = { -12.700, -21.997, 324.670 };
747 const Double_t oct[] = { -12.700, +21.997, 324.670 };
749 TGeoTube* surveyShape = new TGeoTube("FMD1_survey_marker",
752 TGeoMatrix* outMat = matrix;
754 if (gGeoManager->cd("/ALIC_1/F1MT_1"))
755 outMat = gGeoManager->GetCurrentMatrix();
757 AliWarning("Couldn't cd to /ALIC_1/F1MT_1");
760 Double_t loct[3], locb[3];
761 outMat->MasterToLocal(oct, loct);
762 outMat->MasterToLocal(ocb, locb);
763 TGeoVolume* vOct = new TGeoVolume("V0L_OCT", surveyShape, fPlastic);
764 TGeoVolume* vOcb = new TGeoVolume("V0L_OCB", surveyShape, fPlastic);
766 fmd1TopVolume->AddNode(vOct, 1, new TGeoTranslation(loct[0],loct[1],loct[2]));
767 fmd1TopVolume->AddNode(vOcb, 1, new TGeoTranslation(locb[0],locb[1],locb[2]));
770 TGeoMatrix* inMat = matrix;
772 if (gGeoManager->cd("/ALIC_1/F1MT_1"))
773 inMat = gGeoManager->GetCurrentMatrix();
775 AliWarning("Couldn't cd to /ALIC_1/F1MT_1");
778 Double_t lict[3], licb[3];
779 inMat->MasterToLocal(ict, lict);
780 inMat->MasterToLocal(icb, licb);
781 TGeoVolume* vIct = new TGeoVolume("V0L_ICT", surveyShape, fPlastic);
782 TGeoVolume* vIcb = new TGeoVolume("V0L_ICB", surveyShape, fPlastic);
784 fmd1BotVolume->AddNode(vIct, 1, new TGeoTranslation(lict[0],lict[1],lict[2]));
785 fmd1BotVolume->AddNode(vIcb, 1, new TGeoTranslation(licb[0],licb[1],licb[2]));
790 //____________________________________________________________________
792 AliFMDGeometryBuilder::FMD2Geometry(AliFMD2* fmd2,
793 TGeoVolume* innerTop,
794 TGeoVolume* innerBot,
795 TGeoVolume* outerTop,
796 TGeoVolume* outerBot)
798 // Setup the FMD2 geometry. The FMD2 has no
799 // special support as it is at the momement.
801 // See also AliFMDGeometryBuilder::DetectorGeometry
803 if (!fmd2 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
804 AliFMDRing* ring = fmd2->GetOuter();
805 Double_t z = fmd2->GetOuterZ();
806 Double_t framelr = 32.01; // fmd2->GetOuterHoneyHighR()+0.5;
807 Double_t framehr = 33.611; // fmd2->GetOuterHoneyHighR()+1.8;
808 Double_t framel = 14.8; // framehz - framelz;
809 // Double_t backth = 0.3;
810 Double_t backth = 0.03;
811 Double_t framelz = -(2.38
812 - ring->GetModuleDepth()
813 - ring->GetModuleSpacing() / 2);
814 // Double_t framelz = -0.8;
815 // Double_t framehz = framelz + backth + framel;
816 Double_t coverlr = 4.3; // fmd2->GetInner()->GetLowR()+1;
817 Double_t coverhr = framehr; // - 1;
819 TGeoVolume* fmd2TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
820 fmd2->GetId(), 'T'));
821 TGeoVolume* fmd2BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
822 fmd2->GetId(), 'B'));
823 fmd2TopVolume->SetTitle("FMD2 top half");
824 fmd2BotVolume->SetTitle("FMD2 bottom half");
826 DetectorGeometry(fmd2, fmd2TopVolume, fmd2BotVolume, z,
827 innerTop, innerBot, outerTop, outerBot);
829 TGeoVolumeAssembly* support = new TGeoVolumeAssembly("FMD2_support");
830 TGeoShape* cylinderShape = new TGeoTubeSeg(framelr,framehr,framel/2,0,180);
831 TGeoVolume* cylinderVolume = new TGeoVolume(Form(fgkBackName, fmd2->GetId()),
833 TGeoShape* coverShape = new TGeoTubeSeg(coverlr,coverhr,backth/2,0,180);
834 TGeoVolume* coverVolume = new TGeoVolume(Form(fgkTopName, fmd2->GetId()),
836 cylinderShape->SetName(Form(fgkBackName, fmd2->GetId()));
837 cylinderShape->SetTitle("FMD2 cylinder");
838 cylinderVolume->SetTitle("FMD2 cylinder");
839 cylinderVolume->SetTransparency(63);
840 coverShape->SetName(Form(fgkTopName, fmd2->GetId()));
841 coverShape->SetTitle("FMD2 cover");
842 coverVolume->SetTitle("FMD2 cover");
843 coverVolume->SetTransparency(63);
845 TGeoTranslation* trans = 0;
846 support->AddNode(coverVolume,1, new TGeoTranslation(0,0,backth/2));
847 support->AddNode(cylinderVolume, 1, new TGeoTranslation(0,0,backth+framel/2));
850 Double_t f1l = 15.6085;
853 Int_t nFiducialHoles = 4;
854 Double_t precHoles[][2] = { { 32.4948, 29.6663 },
855 { 33.9104, 31.0819 },
856 { 34.8177, 33.4035 },
857 { 35.5028, 32.6744 } };
858 Double_t precRadius = .25;
859 Double_t flangeA = TMath::Pi()/4;
861 new TGeoBBox("FMD2_flange_base", f1l/2, f1w/2, f1d/2);
862 new TGeoTube("FMD2_fiducial_hole", 0, precRadius, f1d/2+.1);
863 Double_t flangeX = framehr + f1l/2;
864 TVector2 flangeC(flangeX * TMath::Cos(flangeA),
865 flangeX * TMath::Sin(flangeA));
866 TString flangeComb("FMD2_flange_base-(");
867 new TGeoBBox("FMD2_flange_slit", 7./2, 1.5/2, f1d/2+.1);
868 trans = new TGeoTranslation(-f1l/2+1+7./2, +.5+1.5/2, 0);
869 trans->SetName("FMD2_flange_slit_mat1");
870 trans->RegisterYourself();
871 trans = new TGeoTranslation(-f1l/2+1+7./2, -.5-1.5/2, 0);
872 trans->SetName("FMD2_flange_slit_mat2");
873 trans->RegisterYourself();
874 flangeComb.Append("FMD2_flange_slit:FMD2_flange_slit_mat1+"
875 "FMD2_flange_slit:FMD2_flange_slit_mat2+");
876 for (Int_t i = 0; i < nFiducialHoles; i++) {
877 TVector2 v(precHoles[i][0], precHoles[i][1]);
879 TVector2 r = v.Rotate(-flangeA);
880 TGeoTranslation* t1 = new TGeoTranslation(r.X(), r.Y(), 0);
881 TGeoTranslation* t2 = new TGeoTranslation(r.X(), -r.Y(), 0);
882 t1->SetName(Form("FMD2_fiducial_hole_rot%d", 2*i+0));
883 t2->SetName(Form("FMD2_fiducial_hole_rot%d", 2*i+1));
884 t1->RegisterYourself();
885 t2->RegisterYourself();
886 flangeComb.Append(Form("FMD2_fiducial_hole:FMD2_fiducial_hole_rot%d+"
887 "FMD2_fiducial_hole:FMD2_fiducial_hole_rot%d%c",
888 2*i+0, 2*i+1, (i == nFiducialHoles-1 ? ')' : '+')));
890 // Final flange shape, and at to full shape
891 TGeoCompositeShape* flangeS = new TGeoCompositeShape(flangeComb.Data());
892 flangeS->SetName("FMD2_flange");
893 TGeoVolume* flangeV = new TGeoVolume("FMD2_flange", flangeS, fAl);
899 new TGeoBBox("FMD2_flange_spacer_base", f2l/2, f2w/2, f2d/2);
900 new TGeoTube("FMD2_flange_spacer_hole", 0, 2.5, f2w/2+.1);
901 TGeoRotation* holeRot = new TGeoRotation();
902 holeRot->RotateY(90);
903 holeRot->RotateZ(90);
904 TGeoCombiTrans* combo = 0;
905 combo = new TGeoCombiTrans(0, 0, f2d/2-.5-2.5, holeRot);
906 combo->SetName("FMD2_flange_spacer_hole_mat1");
907 combo->RegisterYourself();
908 combo = new TGeoCombiTrans(0, 0, -f2d/2+.5+2.5, holeRot);
909 combo->SetName("FMD2_flange_spacer_hole_mat2");
910 combo->RegisterYourself();
911 TString spacerComp("FMD2_flange_spacer_base-("
912 "FMD2_flange_spacer_hole:FMD2_flange_spacer_hole_mat1+"
913 "FMD2_flange_spacer_hole:FMD2_flange_spacer_hole_mat2)");
914 TGeoCompositeShape* spacerS = new TGeoCompositeShape(spacerComp.Data());
915 TGeoVolume* spacerV = new TGeoVolume("FMD2_flange_spacer",
918 Double_t extraL = framehr-framelr;
919 TGeoBBox* extraS = new TGeoBBox("FMD2_flange_extra",
920 extraL/2, f1w/2, f1d/2);
921 TGeoVolume* extraV = new TGeoVolume("FMD2_flange_extra", extraS,fAl);
922 TGeoVolumeAssembly* wingV = new TGeoVolumeAssembly("FMD2_wing");
923 TGeoVolume* tension = TensionBox();
924 TGeoTube* wireS = new TGeoTube(0, .05, (framehr-coverlr)/2);
925 TGeoVolume* wireV = new TGeoVolume("FMD2_tension_wire",
927 wingV->AddNode(flangeV, 1, new TGeoTranslation(f1l/2, 0, f1d/2));
928 wingV->AddNode(flangeV, 2, new TGeoTranslation(f1l/2, 0, -f2d-f1d/2));
929 wingV->AddNode(extraV, 1, new TGeoCombiTrans(-extraL/2, 0, f1d/2, 0));
930 wingV->AddNode(spacerV, 1, new TGeoTranslation(1+f2l/2,-f2w/2+f1w/2,
932 wingV->AddNode(spacerV, 2, new TGeoTranslation(1+f2l/2,+f2w/2-f1w/2,
934 TGeoRotation* tensionR = new TGeoRotation;
935 tensionR->RotateY(90);
936 wingV->AddNode(tension, 1, new TGeoCombiTrans(4, 0, f1d+1.2, tensionR));
937 TGeoRotation* wireR = new TGeoRotation;
939 wingV->AddNode(wireV, 1, new TGeoCombiTrans(-(framehr-coverlr)/2, 0, f1d+1,
942 TGeoCombiTrans* extraM1 = new TGeoCombiTrans(coverhr-extraL/2,0,0,0);
943 extraM1->RotateZ(45);
944 extraM1->RegisterYourself();
945 extraM1->SetName("FMD2_back_cover_slit1");
946 TGeoCombiTrans* extraM2 = new TGeoCombiTrans(coverhr-extraL/2,0,0,0);
947 extraM2->RotateZ(135);
948 extraM2->RegisterYourself();
949 extraM2->SetName("FMD2_back_cover_slit2");
950 TString coverComp(Form(fgkTopName, fmd2->GetId()));
951 coverComp.Append("-(FMD2_flange_extra:FMD2_back_cover_slit1"
952 "+FMD2_flange_extra:FMD2_back_cover_slit2)");
953 TGeoCompositeShape* cover2Shape = new TGeoCompositeShape(coverComp.Data());
954 cover2Shape->SetName("FMD2_back_cover");
955 TGeoVolume* cover2Volume = new TGeoVolume("FMD2_back_cover", cover2Shape,fC);
956 support->AddNode(cover2Volume,2,
957 new TGeoTranslation(0,0,backth+framel+backth/2));
959 TGeoCombiTrans* trans1 = new TGeoCombiTrans(framehr, 0, backth+framel, 0);
960 TGeoCombiTrans* trans2 = new TGeoCombiTrans(framehr, 0, backth+framel, 0);
962 trans2->RotateZ(135);
963 support->AddNode(wingV, 1, trans1);
964 support->AddNode(wingV, 2, trans2);
965 AliFMDDebug(1, ("FMD2 support offset is %f", framelz));
967 for (Int_t i = 0; i < 2; i++) {
968 TGeoVolume* mother = (i < 1 ? fmd2TopVolume : fmd2BotVolume);
970 Double_t phi = 360. / 2 * i;
971 TGeoRotation* rot = new TGeoRotation(Form("FMD2 support rot %d",i));
973 TGeoMatrix* matrix = new TGeoCombiTrans(0, 0, framelz, rot);
974 mother->AddNode(support, i, matrix);
977 // Must be done after filling the assemblies
978 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
979 TGeoMatrix* matrix = new TGeoTranslation("FMD2 trans", 0, 0, z);
980 AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
981 fmd2TopVolume->GetName(), fmd2BotVolume->GetName(), z));
982 top->AddNode(fmd2TopVolume, fmd2->GetId(), matrix);
983 top->AddNode(fmd2BotVolume, fmd2->GetId(), matrix);
989 //____________________________________________________________________
991 AliFMDGeometryBuilder::FMD3Geometry(AliFMD3* fmd3,
992 TGeoVolume* innerTop,
993 TGeoVolume* innerBot,
994 TGeoVolume* outerTop,
995 TGeoVolume* outerBot)
997 // Setup the FMD3 geometry. The FMD2 has a rather elaborate support
998 // structure, as the support will also support the vacuum
1001 // See also AliFMDGeometryBuilder::DetectorGeometry
1003 if (!fmd3 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
1005 //__________________________________________________________________
1006 // Basic detector set-up.
1007 TGeoVolume* fmd3TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
1008 fmd3->GetId(), 'T'));
1009 TGeoVolume* fmd3BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
1010 fmd3->GetId(), 'B'));
1011 fmd3TopVolume->SetTitle("FMD3 top half");
1012 fmd3BotVolume->SetTitle("FMD3 bottom half");
1013 DetectorGeometry(fmd3, fmd3TopVolume, fmd3BotVolume, fmd3->GetInnerZ(),
1014 innerTop, innerBot, outerTop, outerBot);
1016 //__________________________________________________________________
1017 // Mother for all support material
1018 TGeoVolumeAssembly* support = new TGeoVolumeAssembly("F3SU");
1019 support->SetTitle("FMD3 support");
1021 //__________________________________________________________________
1023 const TObjArray& radii = fmd3->ConeRadii();
1024 Int_t nRadii = radii.GetEntriesFast();
1025 TGeoPcon* coneBase = new TGeoPcon("FMD3_cone_base", 0., 180., nRadii);
1028 for (Int_t i = 0; i < nRadii; i++) {
1029 TVector3* v = static_cast<TVector3*>(radii.At(i));
1030 coneBase->DefineSection(i, v->X(), v->Y(), v->Z());
1032 else if (i == 4) r4 = v;
1034 TString coneComb("(FMD3_cone_base");
1036 //__________________________________________________________________
1038 double flangeDepth = fmd3->GetFlangeDepth() / 2;
1039 double flangeLength = fmd3->GetFlangeLength() / 2;
1040 double flangeWidth = fmd3->GetFlangeWidth() / 2;
1041 new TGeoBBox("FMD3_flange_base", flangeLength, flangeWidth, flangeDepth);
1044 const TObjArray& fiducialHoles = fmd3->FiducialHoles();
1045 double fiducialRadius = fmd3->GetFiducialRadius();
1047 TGeoTube* fiducialShape =
1049 new TGeoTube("FMD3_fiducial_hole", 0, fiducialRadius, flangeDepth+.1);
1050 Int_t nFiducialHoles = fiducialHoles.GetEntriesFast();
1051 double flangeAngle = TMath::Pi() / 4;
1052 double flangeX = r5->Y()+flangeLength;
1053 TVector2 flangeC(flangeX * TMath::Cos(flangeAngle),
1054 flangeX * TMath::Sin(flangeAngle));
1055 TString flangeComb("FMD3_flange_base-(");
1056 #if 0// For debugging geometry
1057 TGeoVolume* fiducialVolume = new TGeoVolume("FMD3_fiducial", fiducialShape);
1058 fiducialVolume->SetLineColor(kGreen);
1060 for (Int_t i = 0; i < nFiducialHoles; i++) {
1061 TVector2& v = *(static_cast<TVector2*>(fiducialHoles.At(i)));
1063 TVector2 r = v.Rotate(-flangeAngle);
1064 TGeoTranslation* t1 = new TGeoTranslation(r.X(), r.Y(), 0);
1065 TGeoTranslation* t2 = new TGeoTranslation(r.X(), -r.Y(), 0);
1066 t1->SetName(Form("FMD3_fiducial_hole_rot%d", 2*i+0));
1067 t2->SetName(Form("FMD3_fiducial_hole_rot%d", 2*i+1));
1068 t1->RegisterYourself();
1069 t2->RegisterYourself();
1070 flangeComb.Append(Form("FMD3_fiducial_hole:FMD3_fiducial_hole_rot%d+"
1071 "FMD3_fiducial_hole:FMD3_fiducial_hole_rot%d%c",
1072 2*i+0, 2*i+1, (i == nFiducialHoles-1 ? ')' : '+')));
1073 #if 0 // For debugging geometry
1074 support->AddNode(fiducialVolume, 2*i+0, t1);
1075 support->AddNode(fiducialVolume, 2*i+1, t2);
1079 // Final flange shape, and at to full shape
1080 TGeoCompositeShape* flangeShape = new TGeoCompositeShape(flangeComb.Data());
1081 flangeShape->SetName("FMD3_flange");
1082 for (Int_t i = 0; i < 2; i++) {
1083 TGeoRotation* rot = new TGeoRotation();
1084 rot->RotateZ((i+.5)*90);
1085 TVector2 v(flangeX, 0);
1086 TVector2 w = v.Rotate((i+.5) * 2 * flangeAngle);
1087 TGeoCombiTrans* trans = new TGeoCombiTrans(w.X(),w.Y(),
1088 r4->X()+flangeDepth, rot);
1089 trans->SetName(Form("FMD3_flange_matrix%d", i));
1090 trans->RegisterYourself();
1091 coneComb.Append(Form("+FMD3_flange:FMD3_flange_matrix%d", i));
1093 coneComb.Append(")-(");
1095 //__________________________________________________________________
1097 Double_t holeL = fmd3->GetHoleLength()/2;
1098 Double_t holeD = fmd3->GetHoleDepth()/2;
1099 Double_t holeLW = fmd3->GetHoleLowWidth()/2;
1100 Double_t holeHW = fmd3->GetHoleHighWidth()/2;
1101 Double_t holeA = fmd3->GetConeOuterAngle();
1102 Double_t holeA2 = TMath::Pi() - fmd3->GetConeOuterAngle();
1103 Double_t holeO = fmd3->GetHoleOffset();
1104 Double_t holeZ = (holeO
1105 + holeL * TMath::Cos(holeA)
1106 - holeD * TMath::Sin(holeA2));
1107 Double_t holeX = (fmd3->ConeR(-holeZ + fmd3->GetInnerZ() + fmd3->GetNoseZ())
1108 - holeD * TMath::Sin(holeA2));
1109 new TGeoTrd1("FMD3_cone_hole", holeLW, holeHW, holeD, holeL);
1110 TGeoTrd1* plateShape = new TGeoTrd1("FMD3_cooling_plate",
1111 holeLW, holeHW, .033, holeL);
1112 TGeoRotation* holeRot = new TGeoRotation();
1113 holeRot->SetName("FMD3_cone_hole_rotation");
1114 holeRot->RotateZ(90);
1115 holeRot->RotateY(holeA*180/TMath::Pi());
1116 TGeoCombiTrans* holeBaseTrans = new TGeoCombiTrans(holeX, 0, holeZ, holeRot);
1117 holeBaseTrans->SetName("FMD3_cone_hole_base_matrix");
1118 // TGeoRotation* plateRot = new TGeoRotation();
1119 // plateRot->SetName("FMD3_cone_plate_rotation");
1120 // plateRot->RotateZ(90);
1121 // plateRot->RotateY(plateA*180/TMath::Pi());
1122 // TGeoCombiTrans* plateBaseTrans = new
1123 // TGeoCombiTrans(plateX,0,plateZ,plateRot);
1124 TGeoVolume* plateVolume = new TGeoVolume("FMD3_cooling_plate",
1126 plateShape->SetTitle("FMD3 cooling plate");
1127 plateVolume->SetTitle("FMD3 cooling plate");
1128 for (Int_t i = 0; i < 4; i++) {
1129 Double_t ang = 360. / 8 * (i + .5);
1130 TGeoCombiTrans* trans = new TGeoCombiTrans(*holeBaseTrans);
1131 trans->RotateZ(ang);
1132 trans->SetName(Form("FMD3_cone_hole_matrix%d", i));
1133 trans->RegisterYourself();
1134 trans = new TGeoCombiTrans(*holeBaseTrans);
1135 trans->RotateZ(ang);
1136 trans->SetName(Form("FMD3_cooling_plate_matrix%d", i));
1137 coneComb.Append(Form("FMD3_cone_hole:FMD3_cone_hole_matrix%d+", i));
1138 support->AddNode(plateVolume, i, trans);
1141 //__________________________________________________________________
1143 Double_t boltRadius = fmd3->GetBoltRadius();
1144 Double_t boltLength = fmd3->GetBoltLength() / 2;
1145 Double_t boltZ1 = fmd3->GetInnerZ()+fmd3->GetNoseZ()-10;
1146 Double_t boltZ2 = fmd3->GetInnerZ()+fmd3->GetNoseZ()-20;
1147 Double_t boltXE = 2*boltLength*TMath::Cos(fmd3->GetConeOuterAngle());
1148 Double_t boltX1 = (fmd3->ConeR(boltZ1) - boltXE);
1149 Double_t boltX2 = (fmd3->ConeR(boltZ2) - boltXE);
1151 new TGeoTube("FMD3_bolt_hole", 0, boltRadius, boltLength+.2);
1152 TGeoTube* boltShape = new TGeoTube("FMD3_bolt", 0, boltRadius, boltLength);
1153 TGeoRotation* boltRot = new TGeoRotation();
1154 boltRot->RotateY(-fmd3->GetConeOuterAngle()*180/TMath::Pi());
1155 TGeoCombiTrans* boltTrans1 = new TGeoCombiTrans(boltX1, 0, 10, boltRot);
1156 TGeoCombiTrans* boltTrans2 = new TGeoCombiTrans(boltX2, 0, 20, boltRot);
1157 TGeoCombiTrans* boltTrans3 = new TGeoCombiTrans(*boltTrans1);
1158 TGeoCombiTrans* boltTrans4 = new TGeoCombiTrans(*boltTrans2);
1159 boltTrans3->RotateZ(180);
1160 boltTrans4->RotateZ(180);
1161 boltTrans1->SetName("FMD3_bolt_matrix1");
1162 boltTrans2->SetName("FMD3_bolt_matrix2");
1163 boltTrans3->SetName("FMD3_bolt_matrix3");
1164 boltTrans4->SetName("FMD3_bolt_matrix4");
1165 boltTrans1->RegisterYourself();
1166 boltTrans2->RegisterYourself();
1167 boltTrans3->RegisterYourself();
1168 boltTrans4->RegisterYourself();
1169 coneComb.Append("FMD3_bolt_hole:FMD3_bolt_matrix1"
1170 "+FMD3_bolt_hole:FMD3_bolt_matrix2"
1171 "+FMD3_bolt_hole:FMD3_bolt_matrix3"
1172 "+FMD3_bolt_hole:FMD3_bolt_matrix4");
1173 TGeoVolume* boltVolume = new TGeoVolume("FMD3_bolt", boltShape, fSteel);
1174 support->AddNode(boltVolume, 1, boltTrans1);
1175 support->AddNode(boltVolume, 2, boltTrans2);
1176 boltShape->SetTitle("FMD3 steering bolt");
1177 boltVolume->SetTitle("FMD3 steering bolt");
1179 //__________________________________________________________________
1180 // Cut-outs for tension wheel sheeve
1181 new TGeoBBox("FMD3_sheeve_hole", .55, .75, 1.16);
1182 Double_t sheeveHoleZ = fmd3->GetInnerZ() + fmd3->GetNoseZ() - .75;
1183 Double_t sheeveHoleR = fmd3->ConeR(sheeveHoleZ) - .55 + .2572222;
1184 TGeoCombiTrans* sheeveMat1 = new TGeoCombiTrans(sheeveHoleR,0,1.15,0);
1185 TGeoCombiTrans* sheeveMat2 = new TGeoCombiTrans(sheeveHoleR,0,1.15,0);
1186 sheeveMat1->RotateZ(45);
1187 sheeveMat2->RotateZ(135);
1188 sheeveMat1->SetName("FMD3_sheeve_hole_matrix1");
1189 sheeveMat2->SetName("FMD3_sheeve_hole_matrix2");
1190 sheeveMat1->RegisterYourself();
1191 sheeveMat2->RegisterYourself();
1192 coneComb.Append("+FMD3_sheeve_hole:FMD3_sheeve_hole_matrix1"
1193 "+FMD3_sheeve_hole:FMD3_sheeve_hole_matrix2)");
1195 //__________________________________________________________________
1197 Double_t sheeveL = 1.15;
1198 TGeoBBox* sheeveSideS = new TGeoBBox("FMD3_sheeve_side",
1200 TGeoBBox* sheeveBackS = new TGeoBBox("FMD3_sheeve_back",
1202 TGeoBBox* sheeveWingS = new TGeoBBox("FMD3_sheeve_wing",
1204 TGeoPcon* sheeveWheelS = new TGeoPcon("FMD3_sheeve_wheel", 0, 360, 9);
1205 Double_t sheeveInnerR = 0; // .2;
1206 Double_t sheeveR = .875;
1207 Double_t sheeveWheelZ = .95;
1208 sheeveWheelS->DefineSection(0, -.25, sheeveInnerR, 1);
1209 sheeveWheelS->DefineSection(1, -.125, sheeveInnerR, 1);
1210 sheeveWheelS->DefineSection(2, -.125, sheeveInnerR, sheeveWheelZ);
1211 sheeveWheelS->DefineSection(3, -.0625, sheeveInnerR, sheeveR+.02);
1212 sheeveWheelS->DefineSection(4, 0.000, sheeveInnerR, sheeveR);
1213 sheeveWheelS->DefineSection(5, +.0625, sheeveInnerR, sheeveR+.02);
1214 sheeveWheelS->DefineSection(6, +.125, sheeveInnerR, sheeveWheelZ);
1215 sheeveWheelS->DefineSection(7, +.125, sheeveInnerR, 1);
1216 sheeveWheelS->DefineSection(8, +.25, sheeveInnerR, 1);
1217 TGeoVolume* sheeveSideV = new TGeoVolume("FMD3_sheeve_side",
1218 sheeveSideS, fPlastic);
1219 TGeoVolume* sheeveBackV = new TGeoVolume("FMD3_sheeve_back",
1220 sheeveBackS, fPlastic);
1221 TGeoVolume* sheeveWingV = new TGeoVolume("FMD3_sheeve_wing",
1222 sheeveWingS, fPlastic);
1223 TGeoVolume* sheeveWheelV= new TGeoVolume("FMD3_sheeve_wheel",
1224 sheeveWheelS, fPlastic);
1225 TGeoVolumeAssembly* sheeveBox = new TGeoVolumeAssembly("FMD3_sheeve_box");
1226 sheeveBox->AddNode(sheeveSideV, 1, new TGeoTranslation(0, -.5, 0));
1227 sheeveBox->AddNode(sheeveSideV, 2, new TGeoTranslation(0, +.5, 0));
1228 sheeveBox->AddNode(sheeveBackV, 1, new TGeoTranslation(0, 0, 2.0+.15-1.15));
1229 sheeveBox->AddNode(sheeveWingV, 1, new TGeoTranslation(.55-.15, -.90, 0));
1230 sheeveBox->AddNode(sheeveWingV, 2, new TGeoTranslation(.55-.15, +.90, 0));
1231 TGeoRotation* sheeveWheelR = new TGeoRotation;
1232 sheeveWheelR->RotateX(90);
1233 TGeoCombiTrans* sheeveWheelM = new TGeoCombiTrans(0, 0, sheeveWheelZ-sheeveL,
1235 sheeveBox->AddNode(sheeveWheelV, 1, sheeveWheelM);
1236 support->AddNode(sheeveBox, 1, sheeveMat1);
1237 support->AddNode(sheeveBox, 2, sheeveMat2);
1241 //__________________________________________________________________
1243 TGeoCompositeShape* coneShape = new TGeoCompositeShape(coneComb.Data());
1244 coneShape->SetName("FMD3_cone");
1245 coneShape->SetTitle("FMD3 cone");
1246 TGeoVolume* coneVolume = new TGeoVolume("FMD3_Cone", coneShape, fC);
1247 coneVolume->SetLineColor(kRed);
1248 support->AddNode(coneVolume, 0, new TGeoTranslation(0, 0, 0));
1250 //__________________________________________________________________
1252 TGeoVolume* tensionBox = TensionBox();
1253 Double_t tensionH = .6;
1254 Double_t tensionL = 4;
1255 Double_t tensionZ = 23.654;
1256 Double_t tensionR = fmd3->ConeR(fmd3->GetInnerZ() + fmd3->GetNoseZ()
1258 Double_t tensionAr = fmd3->GetConeOuterAngle();
1259 Double_t tensionA = tensionAr * 180 / TMath::Pi();
1260 TGeoRotation* tensionQ = new TGeoRotation;
1261 tensionQ->RotateY(tensionA);
1262 TGeoCombiTrans* tensionM1 = new TGeoCombiTrans(tensionR,0,tensionZ, tensionQ);
1263 TGeoCombiTrans* tensionM2 = new TGeoCombiTrans(tensionR,0,tensionZ, tensionQ);
1264 tensionM1->RotateZ(45);
1265 tensionM2->RotateZ(135);
1266 support->AddNode(tensionBox, 1, tensionM1);
1267 support->AddNode(tensionBox, 2, tensionM2);
1269 // Double_t tensionHR = 0.15;
1270 Double_t wireT = .1/2;
1271 Double_t wireZ1 = (tensionZ
1272 - tensionL * TMath::Cos(tensionAr)
1273 - tensionH * TMath::Sin(tensionAr));
1274 Double_t wireR1 = (tensionR
1275 - tensionL * TMath::Sin(tensionAr)
1276 + tensionH * TMath::Cos(tensionAr));
1277 AliFMDDebug(10, ("Wire Z1: %f=%f-%f*cos(%f)-%f*sin(%f)",
1278 wireZ1, tensionZ, tensionL, tensionAr, tensionH, tensionAr));
1279 AliFMDDebug(10, ("Wire R1: %f=%f-%f*sin(%f)-%f*cos(%f)",
1280 wireR1, tensionR, tensionL, tensionAr, tensionH, tensionAr));
1282 Double_t wireStartA = 42.3 * TMath::Pi() / 180;
1283 Double_t wireZ2 = (sheeveWheelZ * (1 - TMath::Sin(wireStartA))
1285 - wireT * TMath::Sin(wireStartA));
1286 /* (sheeveWheelZ * (1 - TMath::Sin(wireStartA))
1287 - wireT * TMath::Sin(wireStartA)
1289 AliFMDDebug(10, ("wireZ2=%f=%f*(1-%f)", wireZ2, sheeveWheelZ,
1290 TMath::Sin(wireStartA)));
1291 Double_t wireR2 = (sheeveHoleR +
1292 sheeveWheelZ * TMath::Cos(wireStartA) +
1293 wireT * TMath::Cos(wireStartA));
1294 Double_t wireDR = wireR1-wireR2;
1295 Double_t wireDZ = wireZ1-wireZ2;
1296 Double_t wireL = TMath::Sqrt(wireDR*wireDR+wireDZ*wireDZ)-.01;
1297 Double_t wireAngle = TMath::ATan2(wireDR,wireDZ);
1298 TGeoTube* wireShape = new TGeoTube("FMD3_wire", 0, wireT, wireL/2);
1299 TGeoVolume* wireVolume = new TGeoVolume("FMD3_wire", wireShape,fSteel);
1300 TGeoRotation* wireRot = new TGeoRotation();
1301 wireRot->RotateY(180/TMath::Pi()*wireAngle);
1302 Double_t wireR = wireR2 + wireDR / 2;
1303 Double_t wireZ = wireZ2 + wireDZ / 2;
1304 TGeoCombiTrans* wireM1 = new TGeoCombiTrans(wireR, 0,wireZ, wireRot);
1305 TGeoCombiTrans* wireM2 = new TGeoCombiTrans(wireR, 0,wireZ, wireRot);
1306 wireM1->RotateZ(45);
1307 wireM2->RotateZ(135);
1308 support->AddNode(wireVolume, 1, wireM1);
1309 support->AddNode(wireVolume, 2, wireM2);
1312 TGeoTorus* wireTS = new TGeoTorus(sheeveWheelZ+wireT, 0, wireT, 0,
1313 90-wireStartA*180/TMath::Pi());
1314 TGeoVolume* wireTV = new TGeoVolume("FMD3_bend_wire",wireTS,fSteel);
1315 TGeoRotation* wireTR = new TGeoRotation;
1316 wireTR->RotateY(90);
1317 wireTR->RotateZ(-90);
1318 Double_t wireTZ = sheeveWheelZ;
1319 TGeoCombiTrans* wireTM1 = new TGeoCombiTrans(sheeveHoleR,0,wireTZ,wireTR);
1320 TGeoCombiTrans* wireTM2 = new TGeoCombiTrans(sheeveHoleR,0,wireTZ,wireTR);
1321 wireTM1->RotateZ(45);
1322 wireTM2->RotateZ(135);
1323 support->AddNode(wireTV, 1, wireTM1);
1324 support->AddNode(wireTV, 2, wireTM2);
1326 Double_t colarR = 4.05;
1327 Double_t wireEL = sheeveHoleR - colarR;
1328 TGeoTube* wireES = new TGeoTube("FMD3_end_wire", 0, wireT, wireEL/2);
1329 TGeoVolume* wireEV = new TGeoVolume("FMD3_end_wire", wireES, fSteel);
1330 TGeoRotation* wireER = new TGeoRotation;
1331 wireER->RotateY(90);
1332 TGeoCombiTrans* wireEM1 = new TGeoCombiTrans(colarR+wireEL/2,0,
1334 TGeoCombiTrans* wireEM2 = new TGeoCombiTrans(colarR+wireEL/2,0,
1336 wireEM1->RotateZ(45);
1337 wireEM2->RotateZ(135);
1338 support->AddNode(wireEV, 1, wireEM1);
1339 support->AddNode(wireEV, 2, wireEM2);
1344 //__________________________________________________________________
1345 // Place support volumes in half-detector volumes
1346 Double_t z = fmd3->GetInnerZ();
1347 AliFMDDebug(1, ("FMD3 support at z=%f", -fmd3->GetNoseZ()));
1348 TGeoTranslation* t1 = new TGeoTranslation(0, 0, -fmd3->GetNoseZ());
1349 fmd3TopVolume->AddNode(support, 1, t1);
1350 TGeoCombiTrans* t2 = new TGeoCombiTrans(*t1);
1352 fmd3BotVolume->AddNode(support, 2, t2);
1354 TGeoRotation* rot = new TGeoRotation("FMD3 rotatation");
1356 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
1357 TGeoMatrix* mmatrix = new TGeoCombiTrans("FMD3 trans", 0, 0, z, rot);
1358 AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
1359 fmd3TopVolume->GetName(), fmd3BotVolume->GetName(), z));
1360 top->AddNode(fmd3TopVolume, fmd3->GetId(), mmatrix);
1361 top->AddNode(fmd3BotVolume, fmd3->GetId(), mmatrix);
1367 //____________________________________________________________________
1369 AliFMDGeometryBuilder::Exec(Option_t*)
1371 // Setup up the FMD geometry.
1372 AliFMDDebug(1, ("\tGeometry options: %s",
1373 (fDetailed ? "divided into strips" : "one volume")));
1375 AliFatal("No TGeoManager defined");
1379 fSi = gGeoManager->GetMedium("FMD_Si$");
1380 fC = gGeoManager->GetMedium("FMD_Carbon$");
1381 fAl = gGeoManager->GetMedium("FMD_Aluminum$");
1382 fChip = gGeoManager->GetMedium("FMD_Si Chip$");
1383 fAir = gGeoManager->GetMedium("FMD_Air$");
1384 fPCB = gGeoManager->GetMedium("FMD_PCB$");
1385 fPlastic = gGeoManager->GetMedium("FMD_Plastic$");
1386 fCopper = gGeoManager->GetMedium("FMD_Copper$");
1387 fSteel = gGeoManager->GetMedium("FMD_Steel$");
1389 if (!fSi||!fC||!fAl||!fChip||!fAir||!fPCB||!fPlastic||!fCopper||!fSteel) {
1390 AliError("Failed to get some or all tracking mediums");
1393 AliFMDGeometry* fmd = AliFMDGeometry::Instance();
1394 AliFMDRing* inner = fmd->GetInner();
1395 AliFMDRing* outer = fmd->GetOuter();
1396 RingGeometry(inner);
1397 RingGeometry(outer);
1398 TGeoVolume* innerTop = gGeoManager->GetVolume(Form(fgkRingTopName,
1400 TGeoVolume* innerBot = gGeoManager->GetVolume(Form(fgkRingBotName,
1402 TGeoVolume* outerTop = gGeoManager->GetVolume(Form(fgkRingTopName,
1404 TGeoVolume* outerBot = gGeoManager->GetVolume(Form(fgkRingBotName,
1407 FMD1Geometry(fmd->GetFMD1(), innerTop, innerBot);
1408 FMD2Geometry(fmd->GetFMD2(), innerTop, innerBot, outerTop, outerBot);
1409 FMD3Geometry(fmd->GetFMD3(), innerTop, innerBot, outerTop, outerBot);
1410 #ifndef USE_PRE_MOVE
1411 fmd->SetSectorOff(fSectorOff);
1412 fmd->SetModuleOff(fModuleOff);
1413 fmd->SetRingOff(fRingOff);
1414 fmd->SetDetectorOff(fDetectorOff);
1415 fmd->SetActive(fActiveId.fArray, fActiveId.fN);
1417 // fmd->ExtractGeomInfo();
1422 //____________________________________________________________________