]> git.uio.no Git - u/mrichter/AliRoot.git/blob - FMD/AliFMDGeometryBuilder.cxx
Obsolete.
[u/mrichter/AliRoot.git] / FMD / AliFMDGeometryBuilder.cxx
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  **************************************************************************/
15 /* $Id$ */
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 */
21 //____________________________________________________________________
22 //                                                                          
23 // Builder of FMD geometry. 
24 //
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. 
32 //                                                       
33 // 
34
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>
46 #include <TMath.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
53
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
63 #include <iostream>
64
65 //====================================================================
66 ClassImp(AliFMDGeometryBuilder)
67 #if 0
68   ; // This is here to keep Emacs for indenting the next line
69 #endif
70
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";
97
98 //____________________________________________________________________
99 AliFMDGeometryBuilder::AliFMDGeometryBuilder() 
100   : TTask("FMD", "Geomtry builder"),
101     fActiveId(0),
102     fDetailed(kTRUE),
103     fUseAssembly(kTRUE),
104     fSectorOff(0),
105     fModuleOff(0),
106     fRingOff(0),
107     fDetectorOff(0),
108     fSi(0),
109     fC(0),
110     fAl(0),
111     fPCB(0),
112     fChip(0),
113     fAir(0),
114     fPlastic(0),
115     fCopper(0),
116     fSteel(0)
117 {
118   // Default constructor
119   fActiveId.Set(2);
120 }
121
122 //____________________________________________________________________
123 AliFMDGeometryBuilder::AliFMDGeometryBuilder(Bool_t detailed) 
124   : TTask("FMD", "Geometry builder"),
125     fActiveId(0),
126     fDetailed(detailed),
127     fUseAssembly(kTRUE),
128     fSectorOff(0),
129     fModuleOff(0),
130     fRingOff(0),
131     fDetectorOff(0),
132     fSi(0),
133     fC(0),
134     fAl(0),
135     fPCB(0),
136     fChip(0),
137     fAir(0),
138     fPlastic(0),
139     fCopper(0),
140     fSteel(0)
141 {
142   // Normal constructor
143   // 
144   // Parameters: 
145   // 
146   //      fmd           Pointer to AliFMD object 
147   //      detailed      Whether to make a detailed simulation or not 
148   // 
149   fActiveId.Set(2);
150 }
151
152 //____________________________________________________________________
153 TGeoShape*
154 AliFMDGeometryBuilder::MakeXTRU(const TObjArray& verticies, 
155                                 Double_t thick) const
156 {
157   TArrayD xs(6);
158   TArrayD ys(6);
159   for (Int_t i = 0; i < 3; i++) { 
160     TVector2* v = static_cast<TVector2*>(verticies.At(i+1));
161     xs[i]     =  v->Y();
162     ys[i]     = -v->X();
163     xs[6-1-i] =  v->Y();
164     ys[6-1-i] =  v->X();
165   }
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);
170   
171   return shape;
172 }
173
174 //____________________________________________________________________
175 TGeoVolume*
176 AliFMDGeometryBuilder::RingGeometry(AliFMDRing* r) 
177 {
178   // Setup the geometry of a ring.    The defined TGeoVolume is
179   // returned, and should be used when setting up the rest of the
180   // volumes. 
181   // 
182   // 
183   // Parameters:
184   //
185   //     r              Pointer to ring geometry object 
186   // 
187   // Returns:
188   //    pointer to ring volume 
189   //
190   if (!r) { 
191     AliError("Didn't get a ring object");
192     return 0;
193   }
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();
203   
204   //------------------------------------------------------------------
205   // Sensor
206   // Physical sensor
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), 
211                                             sensorShape, fSi);
212   sensorVolume->SetTitle(Form("FMD %s Sensor", lName));
213   sensorVolume->VisibleDaughters(kFALSE);
214   Int_t sid = sensorVolume->GetNumber();
215
216   fSectorOff   = -1;
217   fModuleOff   = 1;
218   fRingOff     = 2;
219   fDetectorOff = 3;
220   if (fDetailed) {
221     fSectorOff   = 1;
222     fModuleOff   = 4;
223     fRingOff     = 5;
224     fDetectorOff = 6;
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(),
228                                                r->GetHighR(), 
229                                                siThick / 2, 
230                                                - theta, 
231                                                + theta);
232     activeShape->SetName(Form(fgkActiveName, id));
233     activeShape->SetTitle(Form("FMD %s active area", lName));
234     TGeoVolume* activeVolume = new TGeoVolume(Form(fgkActiveName, id),
235                                               activeShape,fSi);
236     activeVolume->SetTitle(Form("FMD %s active area", lName));
237     TGeoVolume* sectorVolume = activeVolume->Divide(Form(fgkSectorName,id), 
238                                                       2, 2, -theta,
239                                                     0,0,"N");
240
241     Int_t    ns       = r->GetNStrips();
242     Double_t stripoff = r->GetLowR(); // 0; // a->Mod();
243     Double_t dstrip   = (r->GetHighR() - stripoff) / ns;
244
245     sectorVolume->SetTitle(Form("FMD %s sector", lName));
246     TGeoVolume* stripVolume  = sectorVolume->Divide(Form(fgkStripName, id), 
247                                                     1, ns, stripoff, dstrip, 
248                                                     0, "SX");
249     stripVolume->SetTitle(Form("FMD %s strip", lName));
250     sid = stripVolume->GetNumber();
251     sensorVolume->AddNodeOverlap(activeVolume, 0);
252   }
253   
254   switch (rng) {
255   case 'I': fActiveId[0] = sid; break;
256   case 'O': fActiveId[1] = sid; break;
257   }
258
259   //------------------------------------------------------------------
260   // Hybrid
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));
267
268   // Copper layer
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));
274
275   // Chip layer
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));
281
282   //------------------------------------------------------------------
283   // Legs
284   Double_t      legr     = r->GetLegRadius();
285   Double_t      legl     = r->GetLegLength();
286   Double_t      lege     = .05;
287
288   // Short leg shape 
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));
295   // Long leg shape
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));
303   
304
305
306   //------------------------------------------------------------------
307   // Placement of module volumes in assemblies 
308   TArrayD xfs(3);
309   TArrayD yfs(3);
310   for (Int_t i = 0; i < 3; i++) { 
311     TVector2* vv = r->GetFootPosition(i);
312     // TVector2  uu = vv->Rotate(TMath::Pi()/2);
313     xfs[i]       = vv->Y();
314     yfs[i]       = vv->X();
315   }
316
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));
322
323   Double_t space    = r->GetSpacing();
324   Double_t x        = 0;
325   Double_t y        = 0;
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;
346     y          =  yfs[i]; // 0;
347     backVolume->AddNode(shortLegVolume, i, new TGeoTranslation(x,y,zb));
348     frontVolume->AddNode(longLegVolume, i, new TGeoTranslation(x,y,zf));
349   }
350
351   //------------------------------------------------------------------
352   // FMDD 
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;
359   
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);
366   
367   Double_t clipWX = 0;
368   Double_t clipWY = 0;
369   Double_t clipY  = 1;
370   
371   if (rng == 'I') { 
372     clipWX = ddhr;
373     clipWY = ddhr/2;
374   }
375   else { 
376     clipWX = ddlr+3;
377     clipWY = ddhr/2;
378   }
379   
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",
384                                                     pcbName.Data()), 
385                                                0, clipWY+clipY, 0);
386   trans->RegisterYourself();
387   TGeoShape* fmddPcbShape = 
388     new TGeoCompositeShape(pcbName.Data(), 
389                            Form("%s_inner*%s_clip:%s_trans",
390                                 pcbName.Data(), 
391                                 pcbName.Data(), 
392                                 pcbName.Data())); 
393   TGeoShape* fmddCuShape = 
394     new TGeoCompositeShape(cuName.Data(), 
395                            Form("%s_inner*%s_clip:%s_trans",
396                                 cuName.Data(), 
397                                 cuName.Data(), 
398                                 pcbName.Data()));
399   TGeoShape* fmddChipShape = 
400     new TGeoCompositeShape(chipName.Data(), 
401                            Form("%s_inner*%s_clip:%s_trans",
402                                 chipName.Data(), 
403                                 chipName.Data(), 
404                                 pcbName.Data()));
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));
408
409   TGeoVolume*  fmddPcbVolume = new TGeoVolume(Form(fgkFMDDPCBName, id),
410                                               fmddPcbShape, fPCB);
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));
418
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));
426   
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); 
440     mat1->RotateZ(th);
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);
444   }
445
446   //------------------------------------------------------------------
447   // Add the FMDD 
448   Double_t zi = r->GetFullDepth() - ddt;
449   Int_t    n  = 2;
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));
454     rot->RotateZ(phi);
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));
462   }
463   
464
465   return 0;
466 }
467
468
469 //____________________________________________________________________
470 TGeoShape*
471 AliFMDGeometryBuilder::HoneycombShape(Int_t id, Char_t ring,
472                                       double r1, double r2, 
473                                       double w, double t, double c)
474 {
475   // Make a honey comb shape from passed parameters.
476   // Parameters: 
477   //   id       Detector identifier (1,2, or 3)
478   //   ring     Ring identifier ('I' or 'O')
479   //   r1       Inner radius
480   //   r2       Outer radius
481   //   w        width 
482   //   t        Thickness of material 
483   //   c        Clearing from horizontal. 
484   // Return 
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();
488
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');
495   double       y     = c;
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);
503     
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();
514   
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(),
518                     in.Data(),on.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));
525   return shape;
526 }
527
528 //____________________________________________________________________
529 TGeoVolume* 
530 AliFMDGeometryBuilder::TensionBox()
531 {
532   static TGeoVolumeAssembly* tensionBox = 0;
533   if (tensionBox) return tensionBox;
534   
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));
546   return tensionBox;
547 }
548
549
550 //____________________________________________________________________
551 TGeoVolume*
552 AliFMDGeometryBuilder::DetectorGeometry(AliFMDDetector* d, 
553                                         TGeoVolume* topMother, 
554                                         TGeoVolume* botMother, 
555                                         Double_t    zMother, 
556                                         TGeoVolume* innerTop, 
557                                         TGeoVolume* innerBot, 
558                                         TGeoVolume* outerTop, 
559                                         TGeoVolume* outerBot) 
560 {
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.   
564   // 
565   // Parameeters:
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
571   //
572   // Returns:
573   //    Pointer to mother (detector volume) 
574   // 
575   if (!d) return 0;
576   // Loop over the defined rings 
577   for (int i = 0; i < 2; i++) {
578     AliFMDRing* r     = 0;
579     Double_t    lowr  = 0;
580     Double_t    highr = 0;
581     Double_t    rz    = 0;
582     TGeoVolume* tvol  = 0;
583     TGeoVolume* bvol  = 0;
584     switch (i) {
585     case 0: 
586       r      = d->GetInner();
587       lowr   = d->GetInnerHoneyLowR();
588       highr  = d->GetInnerHoneyHighR();
589       rz     = d->GetInnerZ();
590       tvol   = innerTop;
591       bvol   = innerBot;
592       break;
593     case 1: 
594       r      = d->GetOuter();
595       lowr   = d->GetOuterHoneyLowR();
596       highr  = d->GetOuterHoneyHighR();
597       rz     = d->GetOuterZ();
598       tvol   = outerTop;
599       bvol   = outerBot;
600       break;
601     }
602     if (!r) continue;
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);
608
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));
616
617     // Honeycomp 
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));
621     
622     z += (r->GetModuleDepth() 
623           + r->GetModuleSpacing() / 2
624           + r->GetHoneycombThickness() / 2);
625
626     AliFMDDebug(15, ("Placing a copy of %s in %s and %s at z=%f", 
627                       hcVol->GetName(), topMother->GetName(), 
628                       botMother->GetName(), z));
629     // Add to top 
630     topMother->AddNode(hcVol, 0, new TGeoTranslation(0, 0, z));
631
632     // Add to bottom
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);
638   }
639   return 0;
640 }
641
642 //____________________________________________________________________
643 TGeoVolume*
644 AliFMDGeometryBuilder::FMD1Geometry(AliFMD1* fmd1, 
645                                     TGeoVolume* innerTop, 
646                                     TGeoVolume* innerBot) 
647 {
648   // Setup the FMD1 geometry.  The FMD1 only has one ring, and no
649   // special support as it is at the momement. 
650   // 
651   // See also AliFMDGeometryBuilder::DetectorGeometry 
652   // 
653   if (!fmd1 || !innerTop || !innerBot) return 0;
654   AliFMDRing* r             = fmd1->GetInner();
655   Double_t    z             = fmd1->GetInnerZ();  
656   
657   TGeoVolume* fmd1TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
658                                                           fmd1->GetId(), 'T'));
659   fmd1TopVolume->SetTitle("FMD1 top half");
660   TGeoVolume* fmd1BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
661                                                           fmd1->GetId(), 'B'));
662   fmd1BotVolume->SetTitle("FMD1 bottom half");
663   
664   // Basic detector geometry 
665   DetectorGeometry(fmd1, fmd1TopVolume, fmd1BotVolume, z, 
666                    innerTop, innerBot, 0, 0);
667
668   Double_t lidP[][3] = { {  0.00,  4.20, 20.95 }, 
669                          {  0.15,  4.20, 20.95 }, 
670                          {  0.15, 20.80, 20.95 }, 
671                          {  3.00, 20.80, 20.95 }, 
672                          {  3.00, 20.80, 22.30 }, 
673                          {  3.15, 20.80, 22.30 }, 
674                          {  3.15, 20.95, 24.65 },
675                          {  3.30, 20.95, 24.65 }, 
676                          {  3.30, 24.50, 24.65 }, 
677                          {  6.80, 24.50, 24.65 },
678                          {  6.80, 24.50, 26.00 },
679                          {  6.95, 24.50, 26.00 } };
680   TGeoPcon* lidBaseS = new TGeoPcon("FMD1_lid_base", 0, 180, 12);
681   for (size_t i = 0; i < 12; i++) 
682     lidBaseS->DefineSection(i, lidP[i][0], lidP[i][1], lidP[i][2]);
683   
684   
685   Double_t lidH[][2] = { {  7.84903, 24.15680  }, 
686                          { 20.54900, 14.92970  },
687                          { 21.99700, 12.70000  },
688                          { 25.26090,  2.65502  } };
689   Double_t lidHR = .53 / 2;
690   Double_t lidHL = 0.16;
691   
692   new TGeoTube("FMD1_lid_hole", 0, lidHR, lidHL/2);
693   TString lidComp("FMD1_lid_base-(");
694   TGeoTranslation* trans = 0;
695   for (size_t i = 0; i < 4; i++) { 
696     trans = new TGeoTranslation(-lidH[i][0], lidH[i][1], 6.95-lidHL/2);
697     trans->SetName(Form("FMD1_lid_hole_mat%d", 2*i+0));
698     trans->RegisterYourself();
699     trans = new TGeoTranslation(+lidH[i][0], lidH[i][1], 6.95-lidHL/2);
700     trans->SetName(Form("FMD1_lid_hole_mat%d", 2*i+1));
701     trans->RegisterYourself();
702     lidComp.Append(Form("FMD1_lid_hole:FMD1_lid_hole_mat%d+" 
703                         "FMD1_lid_hole:FMD1_lid_hole_mat%d%c", 
704                         2 * i, 2 * i + 1, i == 3 ? ')' : '+'));
705   }
706   TGeoCompositeShape* lidS = new TGeoCompositeShape(lidComp.Data());
707   lidS->SetName("FMD1_lid");
708   TGeoVolume* lidV = new TGeoVolume("FMD1_lid", lidS, fC);
709   lidV->SetTransparency(63);
710   
711   // Place top cover
712   Double_t lidZ = -(3.3 - r->GetModuleDepth() - r->GetModuleSpacing() / 2);
713   AliFMDDebug(1, ("FMD1 lid offset in Z=%f", lidZ));
714
715   for (Int_t i = 0; i  < 2; i++) {
716     TGeoVolume*   mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
717     Double_t      phi    = 360. / 2 * i;
718     TGeoRotation* rot    = new TGeoRotation(Form("FMD1_lid_rot%d",i));
719     rot->RotateZ(phi);
720     TGeoMatrix* matrix   = new TGeoCombiTrans(Form("FMD1_lid_mat%d", i),
721                                               0, 0, lidZ, rot);
722     mother->AddNode(lidV, i, matrix);    
723   }
724
725   // Must add this after filling the assembly.
726   TGeoVolume* top    = gGeoManager->GetVolume("ALIC");
727   // TGeoMatrix* matrix = new TGeoTranslation("FMD1 trans", 0, 0, z);
728   TGeoRotation* rot = new TGeoRotation("FMD1 rotatation");
729   rot->RotateZ(90);
730   TGeoMatrix* matrix = new TGeoCombiTrans("FMD1 trans", 0, 0, z, rot);
731   AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f", 
732                    fmd1TopVolume->GetName(), fmd1BotVolume->GetName(), z));
733   top->AddNode(fmd1TopVolume, fmd1->GetId(), matrix);
734   top->AddNode(fmd1BotVolume, fmd1->GetId(), matrix);
735   
736   return 0;
737 }
738
739 //____________________________________________________________________
740 TGeoVolume*
741 AliFMDGeometryBuilder::FMD2Geometry(AliFMD2* fmd2, 
742                                     TGeoVolume* innerTop, 
743                                     TGeoVolume* innerBot, 
744                                     TGeoVolume* outerTop,
745                                     TGeoVolume* outerBot) 
746 {
747   // Setup the FMD2 geometry.  The FMD2 has no
748   // special support as it is at the momement. 
749   // 
750   // See also AliFMDGeometryBuilder::DetectorGeometry 
751   // 
752   if (!fmd2 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
753   AliFMDRing* r          = fmd2->GetOuter();
754   Double_t    z             = fmd2->GetOuterZ();  
755   Double_t    framelr       = 32.01;  // fmd2->GetOuterHoneyHighR()+0.5;
756   Double_t    framehr       = 33.611; // fmd2->GetOuterHoneyHighR()+1.8;
757   Double_t    framel        = 14.8; // framehz - framelz;
758   Double_t    backth        = 0.3;
759   Double_t    framelz       = -(2.38 
760                                 - r->GetModuleDepth() 
761                                 - r->GetModuleSpacing() / 2);
762   // Double_t    framelz       = -0.8;
763   // Double_t    framehz       = framelz + backth + framel;
764   Double_t    coverlr       = 4.3; // fmd2->GetInner()->GetLowR()+1;
765   Double_t    coverhr       = framehr; //  - 1;
766   
767   TGeoVolume* fmd2TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
768                                                           fmd2->GetId(), 'T'));
769   TGeoVolume* fmd2BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
770                                                           fmd2->GetId(), 'B'));
771   fmd2TopVolume->SetTitle("FMD2 top half");
772   fmd2BotVolume->SetTitle("FMD2 bottom half");
773   
774   DetectorGeometry(fmd2, fmd2TopVolume, fmd2BotVolume, z, 
775                    innerTop, innerBot, outerTop, outerBot);
776
777   TGeoVolumeAssembly* support = new TGeoVolumeAssembly("FMD2_support");
778   TGeoShape*  cylinderShape   = new TGeoTubeSeg(framelr,framehr,framel/2,0,180);
779   TGeoVolume* cylinderVolume  = new TGeoVolume(Form(fgkBackName, fmd2->GetId()),
780                                                cylinderShape, fC);
781   TGeoShape*  coverShape      = new TGeoTubeSeg(coverlr,coverhr,backth/2,0,180);
782   TGeoVolume* coverVolume     = new TGeoVolume(Form(fgkTopName, fmd2->GetId()), 
783                                                coverShape, fC);
784   cylinderShape->SetName(Form(fgkBackName, fmd2->GetId()));
785   cylinderShape->SetTitle("FMD2 cylinder");
786   cylinderVolume->SetTitle("FMD2 cylinder");
787   cylinderVolume->SetTransparency(63);
788   coverShape->SetName(Form(fgkTopName, fmd2->GetId()));
789   coverShape->SetTitle("FMD2 cover");
790   coverVolume->SetTitle("FMD2 cover");
791   coverVolume->SetTransparency(63);
792   
793   TGeoTranslation* trans = 0;
794   support->AddNode(coverVolume,1, new TGeoTranslation(0,0,backth/2));
795   support->AddNode(cylinderVolume, 1, new TGeoTranslation(0,0,backth+framel/2));
796   
797
798   Double_t    f1l            = 15.6085;
799   Double_t    f1w            = 6;
800   Double_t    f1d            = 1;
801   Int_t       nFiducialHoles = 4;
802   Double_t    precHoles[][2] = { { 32.4948, 29.6663 },
803                                  { 33.9104, 31.0819 },
804                                  { 34.8177, 33.4035 }, 
805                                  { 35.5028, 32.6744 } };
806   Double_t    precRadius     = .25;
807   Double_t    flangeA        = TMath::Pi()/4;
808   
809   new TGeoBBox("FMD2_flange_base", f1l/2, f1w/2, f1d/2);
810   new TGeoTube("FMD2_fiducial_hole", 0, precRadius, f1d/2+.1);
811   Double_t         flangeX        = framehr + f1l/2;
812   TVector2         flangeC(flangeX * TMath::Cos(flangeA), 
813                            flangeX * TMath::Sin(flangeA));
814   TString          flangeComb("FMD2_flange_base-(");  
815   new TGeoBBox("FMD2_flange_slit", 7./2, 1.5/2, f1d/2+.1);
816   trans = new TGeoTranslation(-f1l/2+1+7./2, +.5+1.5/2, 0);
817   trans->SetName("FMD2_flange_slit_mat1");
818   trans->RegisterYourself();
819   trans = new TGeoTranslation(-f1l/2+1+7./2, -.5-1.5/2, 0);
820   trans->SetName("FMD2_flange_slit_mat2");
821   trans->RegisterYourself();
822   flangeComb.Append("FMD2_flange_slit:FMD2_flange_slit_mat1+"
823                     "FMD2_flange_slit:FMD2_flange_slit_mat2+");
824   for (Int_t i = 0; i < nFiducialHoles; i++) { 
825     TVector2         v(precHoles[i][0], precHoles[i][1]);
826     v                   -= flangeC;
827     TVector2         r  =  v.Rotate(-flangeA);
828     TGeoTranslation* t1 =  new TGeoTranslation(r.X(),  r.Y(), 0);
829     TGeoTranslation* t2 =  new TGeoTranslation(r.X(), -r.Y(), 0);
830     t1->SetName(Form("FMD2_fiducial_hole_rot%d", 2*i+0));
831     t2->SetName(Form("FMD2_fiducial_hole_rot%d", 2*i+1));
832     t1->RegisterYourself();
833     t2->RegisterYourself();
834     flangeComb.Append(Form("FMD2_fiducial_hole:FMD2_fiducial_hole_rot%d+"
835                            "FMD2_fiducial_hole:FMD2_fiducial_hole_rot%d%c",
836                            2*i+0, 2*i+1, (i == nFiducialHoles-1 ? ')' : '+')));
837   }
838   // Final flange shape, and at to full shape 
839   TGeoCompositeShape* flangeS = new TGeoCompositeShape(flangeComb.Data());
840   flangeS->SetName("FMD2_flange");
841   TGeoVolume* flangeV = new TGeoVolume("FMD2_flange", flangeS, fAl);
842   
843   Double_t f2l = 7;
844   Double_t f2d = 12.5;
845   Double_t f2w = 1;
846
847   new TGeoBBox("FMD2_flange_spacer_base", f2l/2, f2w/2, f2d/2);
848   new TGeoTube("FMD2_flange_spacer_hole", 0, 2.5, f2w/2+.1);
849   TGeoRotation* holeRot = new TGeoRotation();
850   holeRot->RotateY(90);
851   holeRot->RotateZ(90);
852   TGeoCombiTrans* combo = 0;
853   combo = new TGeoCombiTrans(0, 0, f2d/2-.5-2.5, holeRot);
854   combo->SetName("FMD2_flange_spacer_hole_mat1");
855   combo->RegisterYourself();
856   combo = new TGeoCombiTrans(0, 0, -f2d/2+.5+2.5, holeRot);
857   combo->SetName("FMD2_flange_spacer_hole_mat2");
858   combo->RegisterYourself();
859   TString spacerComp("FMD2_flange_spacer_base-("
860                      "FMD2_flange_spacer_hole:FMD2_flange_spacer_hole_mat1+"
861                      "FMD2_flange_spacer_hole:FMD2_flange_spacer_hole_mat2)");
862   TGeoCompositeShape* spacerS = new TGeoCompositeShape(spacerComp.Data());
863   TGeoVolume*         spacerV = new TGeoVolume("FMD2_flange_spacer",
864                                                spacerS, fAl);
865
866   Double_t            extraL  = framehr-framelr;
867   TGeoBBox*           extraS  = new TGeoBBox("FMD2_flange_extra", 
868                                              extraL/2, f1w/2, f1d/2);
869   TGeoVolume*         extraV  = new TGeoVolume("FMD2_flange_extra", extraS,fAl);
870   TGeoVolumeAssembly* wingV   = new TGeoVolumeAssembly("FMD2_wing");
871   TGeoVolume*         tension = TensionBox();
872   TGeoTube*           wireS   = new TGeoTube(0, .05, (framehr-coverlr)/2);
873   TGeoVolume*         wireV   = new TGeoVolume("FMD2_tension_wire", 
874                                                wireS, fSteel);
875   wingV->AddNode(flangeV, 1, new TGeoTranslation(f1l/2,    0, f1d/2));
876   wingV->AddNode(flangeV, 2, new TGeoTranslation(f1l/2,    0, -f2d-f1d/2));
877   wingV->AddNode(extraV, 1, new TGeoCombiTrans(-extraL/2, 0, f1d/2, 0));
878   wingV->AddNode(spacerV, 1, new TGeoTranslation(1+f2l/2,-f2w/2+f1w/2,
879                                                  -f2d/2));
880   wingV->AddNode(spacerV, 2, new TGeoTranslation(1+f2l/2,+f2w/2-f1w/2,
881                                                  -f2d/2));
882   TGeoRotation* tensionR = new TGeoRotation;
883   tensionR->RotateY(90);
884   wingV->AddNode(tension, 1, new TGeoCombiTrans(4, 0, f1d+1.2, tensionR));
885   TGeoRotation* wireR = new TGeoRotation;
886   wireR->RotateY(90);
887   wingV->AddNode(wireV, 1, new TGeoCombiTrans(-(framehr-coverlr)/2, 0, f1d+1,
888                                               wireR));
889   
890   TGeoCombiTrans* extraM1 = new TGeoCombiTrans(coverhr-extraL/2,0,0,0);
891   extraM1->RotateZ(45);
892   extraM1->RegisterYourself();
893   extraM1->SetName("FMD2_back_cover_slit1");
894   TGeoCombiTrans* extraM2 = new TGeoCombiTrans(coverhr-extraL/2,0,0,0);
895   extraM2->RotateZ(135);
896   extraM2->RegisterYourself();
897   extraM2->SetName("FMD2_back_cover_slit2");
898   TString coverComp(Form(fgkTopName, fmd2->GetId()));
899   coverComp.Append("-(FMD2_flange_extra:FMD2_back_cover_slit1"
900                    "+FMD2_flange_extra:FMD2_back_cover_slit2)");
901   TGeoCompositeShape* cover2Shape = new TGeoCompositeShape(coverComp.Data());
902   cover2Shape->SetName("FMD2_back_cover");
903   TGeoVolume* cover2Volume = new TGeoVolume("FMD2_back_cover", cover2Shape,fC);
904   support->AddNode(cover2Volume,2, 
905                    new TGeoTranslation(0,0,backth+framel+backth/2));
906
907   TGeoCombiTrans* trans1 = new TGeoCombiTrans(framehr, 0, backth+framel, 0);
908   TGeoCombiTrans* trans2 = new TGeoCombiTrans(framehr, 0, backth+framel, 0);
909   trans1->RotateZ(45);
910   trans2->RotateZ(135);
911   support->AddNode(wingV, 1, trans1);
912   support->AddNode(wingV, 2, trans2);
913   AliFMDDebug(1, ("FMD2 support offset is %f", framelz));
914   
915   for (Int_t i = 0; i  < 2; i++) {
916     TGeoVolume*   mother = (i < 1 ? fmd2TopVolume : fmd2BotVolume);
917     
918     Double_t      phi    = 360. / 2 * i;
919     TGeoRotation* rot    = new TGeoRotation(Form("FMD2 support rot %d",i)); 
920     rot->RotateZ(phi);
921     TGeoMatrix*   matrix = new TGeoCombiTrans(0, 0, framelz, rot);
922     mother->AddNode(support, i, matrix);    
923   }
924   
925   // Must be done after filling the assemblies 
926   TGeoVolume* top = gGeoManager->GetVolume("ALIC");
927   TGeoMatrix* matrix = new TGeoTranslation("FMD2 trans", 0, 0, z);
928   AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f", 
929                    fmd2TopVolume->GetName(), fmd2BotVolume->GetName(), z));
930   top->AddNode(fmd2TopVolume, fmd2->GetId(), matrix);
931   top->AddNode(fmd2BotVolume, fmd2->GetId(), matrix);
932
933
934   return 0;
935 }
936   
937 //____________________________________________________________________
938 TGeoVolume*
939 AliFMDGeometryBuilder::FMD3Geometry(AliFMD3* fmd3, 
940                                     TGeoVolume* innerTop, 
941                                     TGeoVolume* innerBot, 
942                                     TGeoVolume* outerTop,
943                                     TGeoVolume* outerBot) 
944 {
945   // Setup the FMD3 geometry.  The FMD2 has a rather elaborate support
946   // structure, as the support will also support the vacuum
947   // beam-pipe. 
948   // 
949   // See also AliFMDGeometryBuilder::DetectorGeometry 
950   // 
951   if (!fmd3 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
952
953   //__________________________________________________________________
954   // Basic detector set-up.
955   TGeoVolume* fmd3TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
956                                                           fmd3->GetId(), 'T'));
957   TGeoVolume* fmd3BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
958                                                           fmd3->GetId(), 'B'));
959   fmd3TopVolume->SetTitle("FMD3 top half");
960   fmd3BotVolume->SetTitle("FMD3 bottom half");
961   DetectorGeometry(fmd3, fmd3TopVolume, fmd3BotVolume, fmd3->GetInnerZ(), 
962                    innerTop, innerBot, outerTop, outerBot);
963
964   //__________________________________________________________________
965   // Mother for all support material
966   TGeoVolumeAssembly* support = new TGeoVolumeAssembly("F3SU");
967   support->SetTitle("FMD3 support");
968
969   //__________________________________________________________________
970   // Base of cone
971   const TObjArray& radii    = fmd3->ConeRadii();
972   Int_t            nRadii   = radii.GetEntriesFast();
973   TGeoPcon*        coneBase = new TGeoPcon("FMD3_cone_base", 0., 180., nRadii);
974   TVector3*        r5       = 0;
975   TVector3*        r4       = 0;
976   for (Int_t i = 0; i < nRadii; i++) { 
977     TVector3* v = static_cast<TVector3*>(radii.At(i));
978     coneBase->DefineSection(i, v->X(), v->Y(), v->Z());
979     if      (i == 5) r5 = v;
980     else if (i == 4) r4 = v;
981   }
982   TString          coneComb("(FMD3_cone_base");
983
984   //__________________________________________________________________
985   // Flanges 
986   double    flangeDepth    = fmd3->GetFlangeDepth() / 2;
987   double    flangeLength   = fmd3->GetFlangeLength() / 2;
988   double    flangeWidth    = fmd3->GetFlangeWidth() / 2;
989   new TGeoBBox("FMD3_flange_base", flangeLength, flangeWidth, flangeDepth);
990
991   // Fiducial holes 
992   const TObjArray& fiducialHoles  = fmd3->FiducialHoles();
993   double           fiducialRadius = fmd3->GetFiducialRadius();
994 #if 0
995   TGeoTube*        fiducialShape  = 
996 #endif
997     new TGeoTube("FMD3_fiducial_hole", 0, fiducialRadius, flangeDepth+.1);
998   Int_t            nFiducialHoles = fiducialHoles.GetEntriesFast();
999   double           flangeAngle    = TMath::Pi() / 4;
1000   double           flangeX        = r5->Y()+flangeLength;
1001   TVector2         flangeC(flangeX * TMath::Cos(flangeAngle), 
1002                            flangeX * TMath::Sin(flangeAngle));
1003   TString          flangeComb("FMD3_flange_base-(");
1004 #if 0// For debugging geometry 
1005   TGeoVolume* fiducialVolume = new TGeoVolume("FMD3_fiducial", fiducialShape);
1006   fiducialVolume->SetLineColor(kGreen);
1007 #endif
1008   for (Int_t i = 0; i < nFiducialHoles; i++) { 
1009     TVector2&        v  =  *(static_cast<TVector2*>(fiducialHoles.At(i)));
1010     v                   -= flangeC;
1011     TVector2         r  =  v.Rotate(-flangeAngle);
1012     TGeoTranslation* t1 =  new TGeoTranslation(r.X(),  r.Y(), 0);
1013     TGeoTranslation* t2 =  new TGeoTranslation(r.X(), -r.Y(), 0);
1014     t1->SetName(Form("FMD3_fiducial_hole_rot%d", 2*i+0));
1015     t2->SetName(Form("FMD3_fiducial_hole_rot%d", 2*i+1));
1016     t1->RegisterYourself();
1017     t2->RegisterYourself();
1018     flangeComb.Append(Form("FMD3_fiducial_hole:FMD3_fiducial_hole_rot%d+"
1019                            "FMD3_fiducial_hole:FMD3_fiducial_hole_rot%d%c",
1020                            2*i+0, 2*i+1, (i == nFiducialHoles-1 ? ')' : '+')));
1021 #if 0 // For debugging geometry 
1022     support->AddNode(fiducialVolume, 2*i+0, t1);
1023     support->AddNode(fiducialVolume, 2*i+1, t2);
1024 #endif
1025   }
1026   
1027   // Final flange shape, and at to full shape 
1028   TGeoCompositeShape* flangeShape = new TGeoCompositeShape(flangeComb.Data());
1029   flangeShape->SetName("FMD3_flange");
1030   for (Int_t i = 0; i < 2; i++) { 
1031     TGeoRotation* rot = new TGeoRotation();
1032     rot->RotateZ((i+.5)*90);
1033     TVector2 v(flangeX, 0);
1034     TVector2 w = v.Rotate((i+.5) * 2 * flangeAngle);
1035     TGeoCombiTrans* trans = new TGeoCombiTrans(w.X(),w.Y(),
1036                                                r4->X()+flangeDepth, rot);
1037     trans->SetName(Form("FMD3_flange_matrix%d", i));
1038     trans->RegisterYourself();
1039     coneComb.Append(Form("+FMD3_flange:FMD3_flange_matrix%d", i));
1040   }
1041   coneComb.Append(")-(");
1042   
1043   //__________________________________________________________________
1044   // Holes 
1045   Double_t holeL  = fmd3->GetHoleLength()/2;
1046   Double_t holeD  = fmd3->GetHoleDepth()/2;
1047   Double_t holeLW = fmd3->GetHoleLowWidth()/2;
1048   Double_t holeHW = fmd3->GetHoleHighWidth()/2;
1049   Double_t holeA  = fmd3->GetConeOuterAngle();
1050   Double_t holeA2 = TMath::Pi() - fmd3->GetConeOuterAngle();
1051   Double_t holeO  = fmd3->GetHoleOffset();
1052   Double_t holeZ  = (holeO
1053                      + holeL * TMath::Cos(holeA)
1054                      - holeD * TMath::Sin(holeA2));
1055   Double_t holeX  = (fmd3->ConeR(-holeZ + fmd3->GetInnerZ() + fmd3->GetNoseZ())
1056                      - holeD * TMath::Sin(holeA2));
1057   new TGeoTrd1("FMD3_cone_hole", holeLW, holeHW, holeD, holeL);
1058   TGeoTrd1* plateShape = new TGeoTrd1("FMD3_cooling_plate", 
1059                                       holeLW, holeHW, .033, holeL);
1060   TGeoRotation* holeRot = new TGeoRotation();
1061   holeRot->SetName("FMD3_cone_hole_rotation");
1062   holeRot->RotateZ(90);
1063   holeRot->RotateY(holeA*180/TMath::Pi());
1064   TGeoCombiTrans* holeBaseTrans = new TGeoCombiTrans(holeX, 0, holeZ, holeRot);
1065   holeBaseTrans->SetName("FMD3_cone_hole_base_matrix");
1066   // TGeoRotation* plateRot = new TGeoRotation();
1067   // plateRot->SetName("FMD3_cone_plate_rotation");
1068   // plateRot->RotateZ(90);
1069   // plateRot->RotateY(plateA*180/TMath::Pi());
1070   // TGeoCombiTrans* plateBaseTrans = new 
1071   //                  TGeoCombiTrans(plateX,0,plateZ,plateRot);
1072   TGeoVolume* plateVolume = new TGeoVolume("FMD3_cooling_plate", 
1073                                            plateShape, fAl);
1074   plateShape->SetTitle("FMD3 cooling plate");
1075   plateVolume->SetTitle("FMD3 cooling plate");
1076   for (Int_t i = 0; i < 4; i++) { 
1077     Double_t        ang   = 360. / 8 * (i + .5);
1078     TGeoCombiTrans* trans = new TGeoCombiTrans(*holeBaseTrans);
1079     trans->RotateZ(ang);
1080     trans->SetName(Form("FMD3_cone_hole_matrix%d", i));
1081     trans->RegisterYourself();
1082     trans = new TGeoCombiTrans(*holeBaseTrans);
1083     trans->RotateZ(ang);
1084     trans->SetName(Form("FMD3_cooling_plate_matrix%d", i));
1085     coneComb.Append(Form("FMD3_cone_hole:FMD3_cone_hole_matrix%d+", i));
1086     support->AddNode(plateVolume, i, trans);
1087   }
1088   
1089   //__________________________________________________________________
1090   // Bolts
1091   Double_t boltRadius = fmd3->GetBoltRadius();
1092   Double_t boltLength = fmd3->GetBoltLength() / 2;
1093   Double_t boltZ1     = fmd3->GetInnerZ()+fmd3->GetNoseZ()-10;
1094   Double_t boltZ2     = fmd3->GetInnerZ()+fmd3->GetNoseZ()-20;
1095   Double_t boltXE     = 2*boltLength*TMath::Cos(fmd3->GetConeOuterAngle());
1096   Double_t boltX1     = (fmd3->ConeR(boltZ1) - boltXE);
1097   Double_t boltX2     = (fmd3->ConeR(boltZ2) - boltXE);
1098   
1099   new TGeoTube("FMD3_bolt_hole", 0, boltRadius, boltLength+.2);
1100   TGeoTube* boltShape = new TGeoTube("FMD3_bolt", 0, boltRadius, boltLength);
1101   TGeoRotation* boltRot = new TGeoRotation();
1102   boltRot->RotateY(-fmd3->GetConeOuterAngle()*180/TMath::Pi());
1103   TGeoCombiTrans* boltTrans1 = new TGeoCombiTrans(boltX1, 0, 10, boltRot);
1104   TGeoCombiTrans* boltTrans2 = new TGeoCombiTrans(boltX2, 0, 20, boltRot);
1105   TGeoCombiTrans* boltTrans3 = new TGeoCombiTrans(*boltTrans1);
1106   TGeoCombiTrans* boltTrans4 = new TGeoCombiTrans(*boltTrans2);
1107   boltTrans3->RotateZ(180);
1108   boltTrans4->RotateZ(180);
1109   boltTrans1->SetName("FMD3_bolt_matrix1");
1110   boltTrans2->SetName("FMD3_bolt_matrix2");
1111   boltTrans3->SetName("FMD3_bolt_matrix3");
1112   boltTrans4->SetName("FMD3_bolt_matrix4");
1113   boltTrans1->RegisterYourself();
1114   boltTrans2->RegisterYourself();
1115   boltTrans3->RegisterYourself();
1116   boltTrans4->RegisterYourself();
1117   coneComb.Append("FMD3_bolt_hole:FMD3_bolt_matrix1"
1118                   "+FMD3_bolt_hole:FMD3_bolt_matrix2"
1119                   "+FMD3_bolt_hole:FMD3_bolt_matrix3"
1120                   "+FMD3_bolt_hole:FMD3_bolt_matrix4");
1121   TGeoVolume*     boltVolume = new TGeoVolume("FMD3_bolt", boltShape, fSteel);
1122   support->AddNode(boltVolume, 1, boltTrans1);
1123   support->AddNode(boltVolume, 2, boltTrans2);
1124   boltShape->SetTitle("FMD3 steering bolt");
1125   boltVolume->SetTitle("FMD3 steering bolt");
1126   
1127   //__________________________________________________________________
1128   // Cut-outs for tension wheel sheeve 
1129   new TGeoBBox("FMD3_sheeve_hole", .55, .75, 1.16);
1130   Double_t        sheeveHoleZ = fmd3->GetInnerZ() + fmd3->GetNoseZ() - .75;
1131   Double_t        sheeveHoleR = fmd3->ConeR(sheeveHoleZ) - .55 + .2572222;
1132   TGeoCombiTrans* sheeveMat1  = new TGeoCombiTrans(sheeveHoleR,0,1.15,0);
1133   TGeoCombiTrans* sheeveMat2  = new TGeoCombiTrans(sheeveHoleR,0,1.15,0);
1134   sheeveMat1->RotateZ(45);
1135   sheeveMat2->RotateZ(135);
1136   sheeveMat1->SetName("FMD3_sheeve_hole_matrix1");
1137   sheeveMat2->SetName("FMD3_sheeve_hole_matrix2");
1138   sheeveMat1->RegisterYourself();
1139   sheeveMat2->RegisterYourself();
1140   coneComb.Append("+FMD3_sheeve_hole:FMD3_sheeve_hole_matrix1"
1141                   "+FMD3_sheeve_hole:FMD3_sheeve_hole_matrix2)");
1142   
1143   //__________________________________________________________________
1144   // Sheeve boxes 
1145   Double_t       sheeveL     = 1.15;
1146   TGeoBBox*      sheeveSideS = new TGeoBBox("FMD3_sheeve_side",
1147                                            .55, .25, 1.15);
1148   TGeoBBox*      sheeveBackS = new TGeoBBox("FMD3_sheeve_back", 
1149                                             .55, .25, .15);
1150   TGeoBBox*      sheeveWingS = new TGeoBBox("FMD3_sheeve_wing", 
1151                                             .15, .15, 1.15);
1152   TGeoPcon*      sheeveWheelS = new TGeoPcon("FMD3_sheeve_wheel", 0, 360, 9);
1153   Double_t       sheeveInnerR = 0; // .2;
1154   Double_t       sheeveR      = .875;
1155   Double_t       sheeveWheelZ = .95;
1156   sheeveWheelS->DefineSection(0, -.25,   sheeveInnerR, 1);
1157   sheeveWheelS->DefineSection(1, -.125,  sheeveInnerR, 1);
1158   sheeveWheelS->DefineSection(2, -.125,  sheeveInnerR, sheeveWheelZ);
1159   sheeveWheelS->DefineSection(3, -.0625, sheeveInnerR, sheeveR+.02);
1160   sheeveWheelS->DefineSection(4, 0.000,  sheeveInnerR, sheeveR);
1161   sheeveWheelS->DefineSection(5, +.0625, sheeveInnerR, sheeveR+.02);
1162   sheeveWheelS->DefineSection(6, +.125,  sheeveInnerR, sheeveWheelZ);
1163   sheeveWheelS->DefineSection(7, +.125,  sheeveInnerR, 1);
1164   sheeveWheelS->DefineSection(8, +.25,   sheeveInnerR, 1);
1165   TGeoVolume*    sheeveSideV = new TGeoVolume("FMD3_sheeve_side", 
1166                                               sheeveSideS, fPlastic);
1167   TGeoVolume*    sheeveBackV = new TGeoVolume("FMD3_sheeve_back", 
1168                                               sheeveBackS, fPlastic);
1169   TGeoVolume*    sheeveWingV = new TGeoVolume("FMD3_sheeve_wing", 
1170                                               sheeveWingS, fPlastic);
1171   TGeoVolume*    sheeveWheelV= new TGeoVolume("FMD3_sheeve_wheel", 
1172                                               sheeveWheelS, fPlastic);
1173   TGeoVolumeAssembly* sheeveBox = new TGeoVolumeAssembly("FMD3_sheeve_box");
1174   sheeveBox->AddNode(sheeveSideV, 1, new TGeoTranslation(0, -.5, 0));
1175   sheeveBox->AddNode(sheeveSideV, 2, new TGeoTranslation(0, +.5, 0));
1176   sheeveBox->AddNode(sheeveBackV, 1, new TGeoTranslation(0, 0, 2.0+.15-1.15));
1177   sheeveBox->AddNode(sheeveWingV, 1, new TGeoTranslation(.55-.15, -.90, 0));
1178   sheeveBox->AddNode(sheeveWingV, 2, new TGeoTranslation(.55-.15, +.90, 0));
1179   TGeoRotation*   sheeveWheelR = new TGeoRotation;
1180   sheeveWheelR->RotateX(90);
1181   TGeoCombiTrans* sheeveWheelM = new TGeoCombiTrans(0, 0, sheeveWheelZ-sheeveL,
1182                                                     sheeveWheelR);
1183   sheeveBox->AddNode(sheeveWheelV, 1, sheeveWheelM);
1184   support->AddNode(sheeveBox, 1, sheeveMat1);
1185   support->AddNode(sheeveBox, 2, sheeveMat2);
1186   
1187   
1188
1189   //__________________________________________________________________
1190   // Final cone
1191   TGeoCompositeShape* coneShape = new TGeoCompositeShape(coneComb.Data());
1192   coneShape->SetName("FMD3_cone");
1193   coneShape->SetTitle("FMD3 cone");
1194   TGeoVolume*  coneVolume = new TGeoVolume("FMD3_Cone", coneShape, fC);
1195   coneVolume->SetLineColor(kRed);
1196   support->AddNode(coneVolume, 0, new TGeoTranslation(0, 0, 0));
1197
1198   //__________________________________________________________________
1199   // Tension boxes. 
1200   TGeoVolume*     tensionBox = TensionBox();
1201   Double_t        tensionH  = .6;
1202   Double_t        tensionL  = 4;
1203   Double_t        tensionZ  = 23.654;
1204   Double_t        tensionR  = fmd3->ConeR(fmd3->GetInnerZ() + fmd3->GetNoseZ() 
1205                                           -  tensionZ);
1206   Double_t        tensionAr = fmd3->GetConeOuterAngle();
1207   Double_t        tensionA  = tensionAr * 180 / TMath::Pi();
1208   TGeoRotation*   tensionQ  = new TGeoRotation;
1209   tensionQ->RotateY(tensionA);
1210   TGeoCombiTrans* tensionM1 = new TGeoCombiTrans(tensionR,0,tensionZ, tensionQ);
1211   TGeoCombiTrans* tensionM2 = new TGeoCombiTrans(tensionR,0,tensionZ, tensionQ);
1212   tensionM1->RotateZ(45);
1213   tensionM2->RotateZ(135);
1214   support->AddNode(tensionBox, 1, tensionM1);
1215   support->AddNode(tensionBox, 2, tensionM2);
1216   
1217   // Double_t         tensionHR    = 0.15;
1218   Double_t         wireT        = .1/2;
1219   Double_t         wireZ1       = (tensionZ
1220                                    - tensionL * TMath::Cos(tensionAr) 
1221                                    - tensionH * TMath::Sin(tensionAr));
1222   Double_t         wireR1       = (tensionR 
1223                                    - tensionL * TMath::Sin(tensionAr) 
1224                                    + tensionH * TMath::Cos(tensionAr));
1225   AliFMDDebug(10, ("Wire Z1: %f=%f-%f*cos(%f)-%f*sin(%f)", 
1226                   wireZ1, tensionZ, tensionL, tensionAr, tensionH, tensionAr));
1227   AliFMDDebug(10, ("Wire R1: %f=%f-%f*sin(%f)-%f*cos(%f)", 
1228                   wireR1, tensionR, tensionL, tensionAr, tensionH, tensionAr));
1229   
1230   Double_t         wireStartA   = 42.3 * TMath::Pi() / 180;
1231   Double_t         wireZ2       = (sheeveWheelZ * (1 - TMath::Sin(wireStartA))
1232                                    // - sheeveL - 
1233                                    - wireT * TMath::Sin(wireStartA));
1234   /* (sheeveWheelZ * (1 - TMath::Sin(wireStartA))
1235                                    - wireT * TMath::Sin(wireStartA) 
1236                                    - sheeveL); */
1237   AliFMDDebug(10, ("wireZ2=%f=%f*(1-%f)", wireZ2, sheeveWheelZ, 
1238                   TMath::Sin(wireStartA)));
1239   Double_t         wireR2       = (sheeveHoleR + 
1240                                    sheeveWheelZ * TMath::Cos(wireStartA) + 
1241                                    wireT * TMath::Cos(wireStartA));
1242   Double_t         wireDR       = wireR1-wireR2;
1243   Double_t         wireDZ       = wireZ1-wireZ2;
1244   Double_t         wireL        = TMath::Sqrt(wireDR*wireDR+wireDZ*wireDZ)-.01;
1245   Double_t         wireAngle    = TMath::ATan2(wireDR,wireDZ);
1246   TGeoTube*        wireShape    = new TGeoTube("FMD3_wire", 0, wireT, wireL/2);
1247   TGeoVolume*      wireVolume   = new TGeoVolume("FMD3_wire", wireShape,fSteel);
1248   TGeoRotation*    wireRot      = new TGeoRotation();
1249   wireRot->RotateY(180/TMath::Pi()*wireAngle);
1250   Double_t         wireR        = wireR2 + wireDR / 2;
1251   Double_t         wireZ        = wireZ2 + wireDZ / 2;
1252   TGeoCombiTrans*  wireM1       = new TGeoCombiTrans(wireR, 0,wireZ, wireRot);
1253   TGeoCombiTrans*  wireM2       = new TGeoCombiTrans(wireR, 0,wireZ, wireRot);
1254   wireM1->RotateZ(45);
1255   wireM2->RotateZ(135);
1256   support->AddNode(wireVolume, 1, wireM1);
1257   support->AddNode(wireVolume, 2, wireM2);
1258
1259
1260   TGeoTorus*       wireTS  = new TGeoTorus(sheeveWheelZ+wireT, 0, wireT, 0, 
1261                                            90-wireStartA*180/TMath::Pi());
1262   TGeoVolume*      wireTV  = new TGeoVolume("FMD3_bend_wire",wireTS,fSteel);
1263   TGeoRotation*    wireTR  = new TGeoRotation;
1264   wireTR->RotateY(90);
1265   wireTR->RotateZ(-90);
1266   Double_t         wireTZ  = sheeveWheelZ;
1267   TGeoCombiTrans*  wireTM1 = new TGeoCombiTrans(sheeveHoleR,0,wireTZ,wireTR);
1268   TGeoCombiTrans*  wireTM2 = new TGeoCombiTrans(sheeveHoleR,0,wireTZ,wireTR);
1269   wireTM1->RotateZ(45);
1270   wireTM2->RotateZ(135);
1271   support->AddNode(wireTV, 1, wireTM1);
1272   support->AddNode(wireTV, 2, wireTM2);
1273
1274   Double_t         colarR = 4.05;
1275   Double_t         wireEL = sheeveHoleR - colarR;
1276   TGeoTube*        wireES = new TGeoTube("FMD3_end_wire", 0, wireT, wireEL/2);
1277   TGeoVolume*      wireEV = new TGeoVolume("FMD3_end_wire", wireES, fSteel);
1278   TGeoRotation*    wireER = new TGeoRotation;
1279   wireER->RotateY(90);
1280   TGeoCombiTrans*  wireEM1 = new TGeoCombiTrans(colarR+wireEL/2,0,
1281                                                 -wireT,wireER);
1282   TGeoCombiTrans*  wireEM2 = new TGeoCombiTrans(colarR+wireEL/2,0,
1283                                                 -wireT,wireER);
1284   wireEM1->RotateZ(45);
1285   wireEM2->RotateZ(135);
1286   support->AddNode(wireEV, 1, wireEM1);
1287   support->AddNode(wireEV, 2, wireEM2);
1288   
1289   
1290
1291   
1292   //__________________________________________________________________
1293   // Place support volumes in half-detector volumes 
1294   Double_t         z  = fmd3->GetInnerZ();
1295   AliFMDDebug(1, ("FMD3 support at z=%f", -fmd3->GetNoseZ()));
1296   TGeoTranslation* t1 = new TGeoTranslation(0, 0, -fmd3->GetNoseZ());
1297   fmd3TopVolume->AddNode(support, 1, t1);
1298   TGeoCombiTrans*  t2 = new TGeoCombiTrans(*t1);
1299   t2->RotateZ(180);
1300   fmd3BotVolume->AddNode(support, 2, t2);
1301
1302   TGeoRotation*   rot        = new TGeoRotation("FMD3 rotatation");
1303   rot->RotateY(180);
1304   TGeoVolume*     top        = gGeoManager->GetVolume("ALIC");
1305   TGeoMatrix* mmatrix        = new TGeoCombiTrans("FMD3 trans", 0, 0, z, rot);
1306   AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f", 
1307                    fmd3TopVolume->GetName(), fmd3BotVolume->GetName(), z));
1308   top->AddNode(fmd3TopVolume, fmd3->GetId(), mmatrix);
1309   top->AddNode(fmd3BotVolume, fmd3->GetId(), mmatrix);
1310
1311   return 0;
1312 }
1313
1314
1315 //____________________________________________________________________
1316 void
1317 AliFMDGeometryBuilder::Exec(Option_t*) 
1318 {
1319   // Setup up the FMD geometry. 
1320   AliFMDDebug(1, ("\tGeometry options: %s",
1321                     (fDetailed  ? "divided into strips" : "one volume")));
1322   if (!gGeoManager) {
1323     AliFatal("No TGeoManager defined");
1324     return;
1325   }
1326
1327   fSi      = gGeoManager->GetMedium("FMD_Si$");
1328   fC       = gGeoManager->GetMedium("FMD_Carbon$");
1329   fAl      = gGeoManager->GetMedium("FMD_Aluminum$");
1330   fChip    = gGeoManager->GetMedium("FMD_Si Chip$");
1331   fAir     = gGeoManager->GetMedium("FMD_Air$");
1332   fPCB     = gGeoManager->GetMedium("FMD_PCB$");
1333   fPlastic = gGeoManager->GetMedium("FMD_Plastic$");
1334   fCopper  = gGeoManager->GetMedium("FMD_Copper$");
1335   fSteel   = gGeoManager->GetMedium("FMD_Steel$");
1336
1337   if (!fSi||!fC||!fAl||!fChip||!fAir||!fPCB||!fPlastic||!fCopper||!fSteel) {
1338     AliError("Failed to get some or all tracking mediums");
1339     return;
1340   }    
1341   AliFMDGeometry* fmd = AliFMDGeometry::Instance();
1342   AliFMDRing* inner = fmd->GetInner();
1343   AliFMDRing* outer = fmd->GetOuter();
1344   RingGeometry(inner);
1345   RingGeometry(outer);
1346   TGeoVolume* innerTop = gGeoManager->GetVolume(Form(fgkRingTopName, 
1347                                                      inner->GetId()));
1348   TGeoVolume* innerBot = gGeoManager->GetVolume(Form(fgkRingBotName, 
1349                                                      inner->GetId()));
1350   TGeoVolume* outerTop = gGeoManager->GetVolume(Form(fgkRingTopName, 
1351                                                      outer->GetId()));
1352   TGeoVolume* outerBot = gGeoManager->GetVolume(Form(fgkRingBotName, 
1353                                                      outer->GetId()));
1354   
1355   FMD1Geometry(fmd->GetFMD1(), innerTop, innerBot);
1356   FMD2Geometry(fmd->GetFMD2(), innerTop, innerBot, outerTop, outerBot);
1357   FMD3Geometry(fmd->GetFMD3(), innerTop, innerBot, outerTop, outerBot);
1358 #ifndef USE_PRE_MOVE
1359   fmd->SetSectorOff(fSectorOff);
1360   fmd->SetModuleOff(fModuleOff);
1361   fmd->SetRingOff(fRingOff);
1362   fmd->SetDetectorOff(fDetectorOff);
1363   fmd->SetActive(fActiveId.fArray, fActiveId.fN);
1364 #endif
1365   // fmd->ExtractGeomInfo();
1366   
1367 }
1368
1369
1370 //____________________________________________________________________
1371 //
1372 // EOF
1373 //