]> git.uio.no Git - u/mrichter/AliRoot.git/blob - FMD/AliFMDGeometryBuilder.cxx
Fix some warnings.
[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 <TGeoCompositeShape.h>
45 #include <TMath.h>
46 #include <TVector2.h>           // ROOT_TVector2
47 #include <TVector3.h>           // ROOT_TVector3
48 //#include <TGeoMaterial.h>     // ROOT_TGeoMaterial
49 //#include <TGeoMedium.h>               // ROOT_TGeoMedium
50 //#include <TGeoPcon.h>         // ROOT_TGeoPcon
51 //#include <TGeoPolygon.h>      // ROOT_TGeoPolygon
52
53 #include "AliFMDGeometryBuilder.h"      // ALIFMDGEOSIMULATOR_H
54 #include "AliFMDGeometry.h"     // ALIFMDGEOMETRY_H
55 #include "AliFMDDetector.h"     // ALIFMDDETECTOR_H
56 #include "AliFMDRing.h"         // ALIFMDRING_H
57 #include "AliFMD1.h"            // ALIFMD1_H
58 #include "AliFMD2.h"            // ALIFMD2_H
59 #include "AliFMD3.h"            // ALIFMD3_H
60 // #include "AliFMD.h"          // ALIFMD_H
61 #include "AliFMDDebug.h"                // ALILOG_H
62 #include <iostream>
63
64 //====================================================================
65 ClassImp(AliFMDGeometryBuilder)
66 #if 0
67   ; // This is here to keep Emacs for indenting the next line
68 #endif
69
70 //____________________________________________________________________
71 const Char_t* AliFMDGeometryBuilder::fgkActiveName      = "F%cAC";
72 const Char_t* AliFMDGeometryBuilder::fgkSectorName      = "F%cSC";
73 const Char_t* AliFMDGeometryBuilder::fgkStripName       = "F%cST";
74 const Char_t* AliFMDGeometryBuilder::fgkSensorName      = "F%cSE";
75 const Char_t* AliFMDGeometryBuilder::fgkPCBName         = "F%cPB";
76 const Char_t* AliFMDGeometryBuilder::fgkCuName          = "F%cCU";
77 const Char_t* AliFMDGeometryBuilder::fgkChipName        = "F%cCH";
78 const Char_t* AliFMDGeometryBuilder::fgkLongLegName     = "F%cLL";
79 const Char_t* AliFMDGeometryBuilder::fgkShortLegName    = "F%cSL";
80 const Char_t* AliFMDGeometryBuilder::fgkFrontVName      = "F%cFH";
81 const Char_t* AliFMDGeometryBuilder::fgkBackVName       = "F%cBH";
82 const Char_t* AliFMDGeometryBuilder::fgkRingTopName     = "F%cTV";
83 const Char_t* AliFMDGeometryBuilder::fgkRingBotName     = "F%cBV";
84 const Char_t* AliFMDGeometryBuilder::fgkHCName          = "F%dH%c";
85 const Char_t* AliFMDGeometryBuilder::fgkIHCName         = "F%dI%c";
86 const Char_t* AliFMDGeometryBuilder::fgkNoseName        = "F3SN";
87 const Char_t* AliFMDGeometryBuilder::fgkBackName        = "F%dSB";
88 const Char_t* AliFMDGeometryBuilder::fgkTopName         = "F%dSU";
89 const Char_t* AliFMDGeometryBuilder::fgkBeamName        = "F%dSL";
90 const Char_t* AliFMDGeometryBuilder::fgkFlangeName      = "F%dSF";
91 const Char_t* AliFMDGeometryBuilder::fgkFMDDCuName      = "F%cDC";
92 const Char_t* AliFMDGeometryBuilder::fgkFMDDPCBName     = "F%cDP";
93 const Char_t* AliFMDGeometryBuilder::fgkFMDDChipName    = "F%cDI";
94 const Char_t* AliFMDGeometryBuilder::fgkFMDDName        = "F%cDD";
95 const Char_t* AliFMDGeometryBuilder::fgkFMDName         = "F%dM%c";
96
97 //____________________________________________________________________
98 AliFMDGeometryBuilder::AliFMDGeometryBuilder() 
99   : TTask("FMD", "Geomtry builder"),
100     fActiveId(0),
101     fDetailed(kTRUE),
102     fUseAssembly(kTRUE),
103     fSectorOff(0),
104     fModuleOff(0),
105     fRingOff(0),
106     fDetectorOff(0),
107     fSi(0),
108     fC(0),
109     fAl(0),
110     fPCB(0),
111     fChip(0),
112     fAir(0),
113     fPlastic(0),
114     fCopper(0),
115     fSteel(0)
116 {
117   // Default constructor
118   fActiveId.Set(2);
119 }
120
121 //____________________________________________________________________
122 AliFMDGeometryBuilder::AliFMDGeometryBuilder(Bool_t detailed) 
123   : TTask("FMD", "Geometry builder"),
124     fActiveId(0),
125     fDetailed(detailed),
126     fUseAssembly(kTRUE),
127     fSectorOff(0),
128     fModuleOff(0),
129     fRingOff(0),
130     fDetectorOff(0),
131     fSi(0),
132     fC(0),
133     fAl(0),
134     fPCB(0),
135     fChip(0),
136     fAir(0),
137     fPlastic(0),
138     fCopper(0),
139     fSteel(0)
140 {
141   // Normal constructor
142   // 
143   // Parameters: 
144   // 
145   //      fmd           Pointer to AliFMD object 
146   //      detailed      Whether to make a detailed simulation or not 
147   // 
148   fActiveId.Set(2);
149 }
150
151
152 //____________________________________________________________________
153 TGeoVolume*
154 AliFMDGeometryBuilder::RingGeometry(AliFMDRing* r) 
155 {
156   // Setup the geometry of a ring.    The defined TGeoVolume is
157   // returned, and should be used when setting up the rest of the
158   // volumes. 
159   // 
160   // 
161   // Parameters:
162   //
163   //     r              Pointer to ring geometry object 
164   // 
165   // Returns:
166   //    pointer to ring volume 
167   //
168   if (!r) { 
169     AliError("Didn't get a ring object");
170     return 0;
171   }
172   Char_t        id       = r->GetId();
173   const Char_t* lName    = (id == 'i' || id == 'I' ? "inner" : "outer");
174   Double_t      siThick  = r->GetSiThickness();
175   const Int_t   knv      = r->GetNVerticies();
176   TVector2*     a        = r->GetVertex(5);
177   TVector2*     b        = r->GetVertex(3);
178   TVector2*     c        = r->GetVertex(4);
179   Double_t      theta    = r->GetTheta();
180   Double_t      off      = (TMath::Tan(TMath::Pi() * theta / 180) 
181                             * r->GetBondingWidth());
182   Double_t      rmax     = b->Mod();
183   Double_t      rmin     = r->GetLowR();
184   Double_t      pcbThick = r->GetPrintboardThickness();
185   Double_t      cuThick  = r->GetCopperThickness();
186   Double_t      chipThick= r->GetChipThickness();
187   Double_t      modSpace = r->GetModuleSpacing();
188   Double_t      legr     = r->GetLegRadius();
189   Double_t      legl     = r->GetLegLength();
190   Double_t      legoff   = r->GetLegOffset();
191   Int_t         ns       = r->GetNStrips();
192   Double_t      stripoff = a->Mod();
193   Double_t      dstrip   = (rmax - stripoff) / ns;
194   Double_t      space    = r->GetSpacing();
195   TArrayD       xs(knv);
196   TArrayD       ys(knv);
197   for (Int_t i = 0; i < knv; i++) {
198     // Reverse the order 
199     TVector2* vv = r->GetVertex(knv - 1 - i);
200     if (!vv) {
201       AliError(Form("Failed to get vertex # %d", knv - 1 - i));
202       continue;
203     }
204     xs[i] = vv->X();
205     ys[i] = vv->Y();
206   }
207   
208   // Shape of actual sensor 
209   TGeoXtru* sensorShape = new TGeoXtru(2);
210   sensorShape->DefinePolygon(knv, xs.fArray, ys.fArray);
211   sensorShape->DefineSection(0, - siThick/2);
212   sensorShape->DefineSection(1, siThick/2);
213   sensorShape->SetName(Form(fgkSensorName, id));
214   sensorShape->SetTitle(Form("FMD %s Sensor", lName));
215   TGeoVolume* sensorVolume = new TGeoVolume(Form(fgkSensorName, id), 
216                                             sensorShape, fSi);
217   sensorVolume->SetTitle(Form("FMD %s Sensor", lName));
218   sensorVolume->VisibleDaughters(kFALSE);
219   Int_t sid = sensorVolume->GetNumber();
220   fSectorOff   = -1;
221   fModuleOff   = 1;
222   fRingOff     = 2;
223   fDetectorOff = 3;
224   if (fDetailed) {
225     fSectorOff   = 1;
226     fModuleOff   = 4;
227     fRingOff     = 5;
228     fDetectorOff = 6;
229     // Virtual volume shape to divide - This volume is only defined if
230     // the geometry is set to be detailed. 
231     TGeoTubeSeg* activeShape = new TGeoTubeSeg(rmin, rmax, siThick/2, 
232                                                - theta, theta);
233     activeShape->SetName(Form(fgkActiveName, id));
234     activeShape->SetTitle(Form("FMD %s active area", lName));
235     TGeoVolume* activeVolume = new TGeoVolume(Form(fgkActiveName, id),
236                                               activeShape,fSi);
237     activeVolume->SetTitle(Form("FMD %s active area", lName));
238     TGeoVolume* sectorVolume = activeVolume->Divide(Form(fgkSectorName,id), 
239                                                       2, 2, -theta,0,0,"N");
240     sectorVolume->SetTitle(Form("FMD %s sector", lName));
241     TGeoVolume* stripVolume  = sectorVolume->Divide(Form(fgkStripName, id), 
242                                                     1, ns, stripoff, dstrip, 
243                                                     0, "SX");
244     stripVolume->SetTitle(Form("FMD %s strip", lName));
245     sid = stripVolume->GetNumber();
246     sensorVolume->AddNodeOverlap(activeVolume, 0);
247   }
248   
249   switch (id) {
250   case 'i': case 'I': fActiveId[0] = sid; break;
251   case 'o': case 'O': fActiveId[1] = sid; break;
252   }
253
254   // Shape of Printed circuit Board 
255   for (Int_t i = 0;       i < knv / 2; i++) ys[i] -= off;
256   for (Int_t i = knv / 2; i < knv;     i++) ys[i] += off;
257   TGeoXtru* pcbShape         = new TGeoXtru(2);
258   pcbShape->DefinePolygon(knv, xs.fArray, ys.fArray);
259   pcbShape->DefineSection(0, - pcbThick/2);
260   pcbShape->DefineSection(1, pcbThick/2);
261   pcbShape->SetName(Form(fgkPCBName, id));
262   pcbShape->SetTitle(Form("FMD %s hybrid PCB", lName));
263   TGeoVolume* pcbVolume      = new TGeoVolume(Form(fgkPCBName, id), 
264                                               pcbShape, fPCB);
265   pcbVolume->SetTitle(Form("FMD %s hybrid PCB", lName));
266
267   // Copper layer
268   TGeoXtru* cuShape       = new TGeoXtru(2);
269   cuShape->DefinePolygon(6, xs.fArray, ys.fArray);
270   cuShape->DefineSection(0, - cuThick/2);
271   cuShape->DefineSection(1, cuThick/2);
272   cuShape->SetTitle(Form("FMD %s hybrid copper", lName));
273   TGeoVolume* cuVolume    = new TGeoVolume(Form(fgkCuName,id),cuShape,fCopper);
274   cuVolume->SetTitle(Form("FMD %s hybrid copper", lName));
275
276   // Chip layer
277   TGeoXtru*   chipShape   = new TGeoXtru(2);
278   chipShape->DefinePolygon(6, xs.fArray, ys.fArray);
279   chipShape->DefineSection(0, - chipThick/2);
280   chipShape->DefineSection(1, chipThick/2);
281   chipShape->SetTitle(Form("FMD %s hybrid chip", lName));
282   TGeoVolume* chipVolume = new TGeoVolume(Form(fgkChipName,id),
283                                           chipShape,fChip);
284   chipVolume->SetTitle(Form("FMD %s hybrid chip", lName));
285
286   // Short leg shape 
287   TGeoTube*   shortLegShape  = new TGeoTube(0, legr, legl / 2);
288   shortLegShape->SetName(Form(fgkShortLegName, id));
289   shortLegShape->SetTitle(Form("FMD %s short support foot", lName));
290   TGeoVolume* shortLegVolume = new TGeoVolume(Form(fgkShortLegName, id), 
291                                               shortLegShape, fCopper);
292   shortLegVolume->SetTitle(Form("FMD %s short support foot", lName));
293   // Long leg shape
294   TGeoTube*   longLegShape   = new TGeoTube(0, legr, (legl + modSpace) / 2);
295   longLegShape->SetName(Form(fgkLongLegName, id));
296   longLegShape->SetTitle(Form("FMD %s long support foot", lName));
297   TGeoVolume* longLegVolume  = new TGeoVolume(Form(fgkLongLegName, id), 
298                                               longLegShape, fCopper);
299   longLegVolume->SetTitle(Form("FMD %s long support foot", lName));
300   
301   
302   // Back container volume 
303   TGeoVolume* backVolume     = new TGeoVolumeAssembly(Form(fgkBackVName, id));
304   backVolume->SetTitle(Form("FMD %s back module", lName));
305   Double_t x = 0;
306   Double_t y = 0;
307   Double_t z = siThick / 2;
308   backVolume->AddNode(sensorVolume, 0, new TGeoTranslation(x, y, z));
309   z          += siThick / 2 + space + pcbThick / 2;
310   backVolume->AddNode(pcbVolume, 0, new TGeoTranslation(x,y,z));
311   z          += (pcbThick + cuThick) / 2;
312   backVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, z));
313   z          += (cuThick + chipThick) / 2;
314   backVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, z));
315   x          =  a->X() + legoff + legr;
316   y          =  0;
317   z          += pcbThick / 2 + legl / 2;
318   backVolume->AddNode(shortLegVolume, 0, new TGeoTranslation(x,y,z));
319   x          =  c->X();
320   y          =  c->Y() - legoff - legr - off;
321   backVolume->AddNode(shortLegVolume, 1, new TGeoTranslation(x,y,z));
322   y          =  -y;
323   backVolume->AddNode(shortLegVolume, 2, new TGeoTranslation(x,y,z));
324
325   // Front container volume 
326   TGeoVolume* frontVolume    = new TGeoVolumeAssembly(Form(fgkFrontVName, id));
327   frontVolume->SetTitle(Form("FMD %s front module", lName));
328   x         =  0;
329   y         =  0;
330   z         = siThick / 2;
331   frontVolume->AddNode(sensorVolume, 0, new TGeoTranslation(x, y, z));
332   z          += siThick / 2 + space + pcbThick / 2;
333   frontVolume->AddNode(pcbVolume, 0, new TGeoTranslation(x,y,z));
334   z          += (pcbThick + cuThick) / 2;
335   frontVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, z));
336   z          += (cuThick + chipThick) / 2;
337   frontVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, z));
338   x         =  a->X() + legoff + legr;
339   y         =  0;
340   z         += pcbThick / 2 + (legl + modSpace)/ 2;
341   frontVolume->AddNode(longLegVolume, 0, new TGeoTranslation(x,y,z));
342   x         =  c->X();
343   y         =  c->Y() - legoff - legr - off;
344   frontVolume->AddNode(longLegVolume, 1, new TGeoTranslation(x,y,z));
345   y         =  -y;
346   frontVolume->AddNode(longLegVolume, 2, new TGeoTranslation(x,y,z));
347
348
349   // FMDD 
350   Double_t ddlr = r->GetFMDDLowR();
351   Double_t ddhr = r->GetFMDDHighR();
352   Double_t ddpt = r->GetFMDDPrintboardThickness();
353   Double_t ddct = r->GetFMDDCopperThickness();
354   Double_t ddit = r->GetFMDDChipThickness();
355   Double_t ddt  = ddpt + ddct + ddit;
356   
357   TString    pcbName(Form(fgkFMDDPCBName, id));
358   TString    cuName(Form(fgkFMDDCuName, id));
359   TString    chipName(Form(fgkFMDDChipName, id));
360   new TGeoTubeSeg(Form("%s_inner", pcbName.Data()),  ddlr, ddhr, ddpt/2,0,180);
361   new TGeoTubeSeg(Form("%s_inner", cuName.Data()),   ddlr, ddhr, ddct/2,0,180);
362   new TGeoTubeSeg(Form("%s_inner", chipName.Data()), ddlr, ddhr, ddit/2,0,180);
363   
364   Double_t clipWX = 0;
365   Double_t clipWY = 0;
366   Double_t clipY  = 1;
367   
368   if (id == 'I' || id == 'i') { 
369     clipWX = ddhr;
370     clipWY = ddhr/2;
371   }
372   else { 
373     clipWX = ddlr+3;
374     clipWY = ddhr/2;
375   }
376   
377   new TGeoBBox(Form("%s_clip",  pcbName.Data()), clipWX, clipWY, ddpt);
378   new TGeoBBox(Form("%s_clip",  cuName.Data()),  clipWX, clipWY, ddct);
379   new TGeoBBox(Form("%s_clip",  chipName.Data()),clipWX, clipWY, ddit);
380   TGeoTranslation* trans = new TGeoTranslation(Form("%s_trans",
381                                                     pcbName.Data()), 
382                                                0, clipWY+clipY, 0);
383   trans->RegisterYourself();
384   TGeoShape* fmddPcbShape = 
385     new TGeoCompositeShape(pcbName.Data(), 
386                            Form("%s_inner*%s_clip:%s_trans",
387                                 pcbName.Data(), 
388                                 pcbName.Data(), 
389                                 pcbName.Data())); 
390   TGeoShape* fmddCuShape = 
391     new TGeoCompositeShape(cuName.Data(), 
392                            Form("%s_inner*%s_clip:%s_trans",
393                                 cuName.Data(), 
394                                 cuName.Data(), 
395                                 pcbName.Data()));
396   TGeoShape* fmddChipShape = 
397     new TGeoCompositeShape(chipName.Data(), 
398                            Form("%s_inner*%s_clip:%s_trans",
399                                 chipName.Data(), 
400                                 chipName.Data(), 
401                                 pcbName.Data()));
402   fmddPcbShape->SetTitle(Form("FMD %s digitiser PCB", lName));
403   fmddCuShape->SetTitle(Form("FMD %s digitiser copper", lName));
404   fmddChipShape->SetTitle(Form("FMD %s digitiser chip", lName));
405
406   TGeoVolume*  fmddPcbVolume = new TGeoVolume(Form(fgkFMDDPCBName, id),
407                                               fmddPcbShape, fPCB);
408   TGeoVolume*  fmddCuVolume  = new TGeoVolume(Form(fgkFMDDCuName, id),
409                                               fmddCuShape, fCopper);
410   TGeoVolume*  fmddChipVolume= new TGeoVolume(Form(fgkFMDDChipName, id),
411                                               fmddChipShape, fChip);
412   fmddPcbVolume->SetTitle(Form("FMD %s digitiser PCB", lName));
413   fmddCuVolume->SetTitle(Form("FMD %s digitiser copper", lName));
414   fmddChipVolume->SetTitle(Form("FMD %s digitiser chip", lName));
415
416   // Half ring mother volumes. 
417   TGeoVolume* ringTopVolume = new TGeoVolumeAssembly(Form(fgkRingTopName,id));
418   TGeoVolume* ringBotVolume = new TGeoVolumeAssembly(Form(fgkRingBotName,id));
419   TGeoVolume* halfRing      = ringTopVolume;
420   ringTopVolume->SetTitle(Form("FMD %s top half-ring", lName));
421   ringBotVolume->SetTitle(Form("FMD %s bottom half-ring", lName));
422   
423   // Adding modules to half-rings
424   Int_t    nmod =  r->GetNModules();
425   AliFMDDebug(10, ("making %d modules in ring %c", nmod, id));
426   for (Int_t i = 0; i < nmod; i++) {
427     if (i == nmod / 2) halfRing = ringBotVolume;
428     Bool_t      front =  (i % 2 == 0);
429     TGeoVolume* vol   =  (front ? frontVolume : backVolume);
430     // vol->AddNode(sensorVolume, i, new TGeoTranslation(0,0,siThick/2));
431     Double_t    z1    =  (i % 2) * modSpace;
432     Double_t    th    =  (2 * i + 1) * theta;
433     TGeoMatrix* mat1  =  new TGeoCombiTrans(0,0,z1,0); 
434     mat1->RotateZ(th);
435     mat1->SetName(Form("FMD%c_module_%02d", id, i));
436     mat1->SetTitle(Form("FMD %s module %2d matrix", lName, i));
437     halfRing->AddNode(vol, i, mat1);
438 #if 0
439     Double_t    z2    =  z1 + siThick / 2 + space;
440     Double_t    th    =  (2 * i + 1) * theta;
441     AliFMDDebug(20, ("Placing copy %d of %s and %s in %s at z=%f and %f, "
442                       "and theta=%f", i, sensorVolume->GetName(), 
443                       vol->GetName(), halfRing->GetName(), z1, z2, th));
444     TGeoMatrix* mat1  =  new TGeoCombiTrans(0,0,z1,0); 
445     mat1->RotateZ(th);
446     halfRing->AddNode(sensorVolume, i, mat1);
447     TGeoMatrix* mat2  =  new TGeoCombiTrans(0,0,z2,0); 
448     mat2->RotateZ(th);
449     halfRing->AddNode(vol, i, mat2);
450 #endif
451   }
452
453   // Add the FMDD 
454   Double_t zi = r->GetFullDepth() - ddt;
455   Int_t    n  = 2;
456   for (Int_t i = 0; i  < n; i++) {
457     halfRing             = (i == 0 ? ringTopVolume : ringBotVolume);
458     Double_t      phi    = 360. / n * i;
459     TGeoRotation* rot    = new TGeoRotation(Form("FMDD%c rotation %d", id, i));
460     rot->RotateZ(phi);
461     rot->SetTitle(Form("FMD %s digitiser rotation %2d", lName, i));
462     z         =  zi + ddpt / 2;
463     halfRing->AddNode(fmddPcbVolume, i, new TGeoCombiTrans(0,0,z,rot));
464     z          += (ddpt + ddct) / 2;
465     halfRing->AddNode(fmddCuVolume, i, new TGeoCombiTrans(0,0,z,rot));
466     z          += (ddct + ddit) / 2;
467     halfRing->AddNode(fmddChipVolume, i, new TGeoCombiTrans(0,0,z,rot));
468   }
469   
470
471   return 0;
472 }
473
474 //____________________________________________________________________
475 TGeoShape*
476 AliFMDGeometryBuilder::HoneycombShape(Int_t id, Char_t ring,
477                                       double r1, double r2, 
478                                       double w, double t, double c)
479 {
480   // Make a honey comb shape from passed parameters.
481   // Parameters: 
482   //   id       Detector identifier (1,2, or 3)
483   //   ring     Ring identifier ('I' or 'O')
484   //   r1       Inner radius
485   //   r2       Outer radius
486   //   w        width 
487   //   t        Thickness of material 
488   //   c        Clearing from horizontal. 
489   // Return 
490   //   Pointer to newly allocated composite shape. 
491   TString      form  = Form("FMD%d%c_%%c_%%c", id, ring);
492   double       a1    = TMath::ATan2(c, r1) * 180  / TMath::Pi();
493
494   TString      fn    = Form(form.Data(),'F','1');
495   TString      bn    = Form(form.Data(),'B','1');
496   TString      cn    = Form(form.Data(),'C','O');
497   TString      in    = Form(form.Data(),'R','I');
498   TString      on    = Form(form.Data(),'R','O');
499   TString      en    = Form(form.Data(),'E','X');
500   double       y     = c;
501   double       x     = r1 * TMath::Cos(TMath::Pi()*a1/180);
502   new TGeoTubeSeg(fn.Data(),r1,r2,t/2,0,180);
503   new TGeoTubeSeg(bn.Data(),r1,r2,t/2,0,180);
504   new TGeoBBox(cn.Data(),(r2-r1)/2,t/2,w/2);
505   new TGeoTubeSeg(in.Data(),r1,r1+t,w/2,0,180);
506   new TGeoTubeSeg(on.Data(),r2-t,r2,w/2,0,180);
507   new TGeoBBox(en.Data(),r2+.005,c/2+.005,w/2+.005);
508     
509   TString          ftn = Form(form.Data(),'F','T');
510   TString          btn = Form(form.Data(),'F','B');
511   TString          ltn = Form(form.Data(),'C','L');
512   TString          rtn = Form(form.Data(),'C','R');
513   TString          etn = Form(form.Data(),'E','X');
514   (new TGeoTranslation(ftn.Data(),0,0,+w/2-t/2))->RegisterYourself();
515   (new TGeoTranslation(btn.Data(),0,0,-w/2+t/2))->RegisterYourself();
516   (new TGeoTranslation(ltn.Data(),-(x+(r2-r1)/2), y+t/2,0))->RegisterYourself();
517   (new TGeoTranslation(rtn.Data(),(x+(r2-r1)/2), y+t/2,0))->RegisterYourself();
518   (new TGeoTranslation(etn.Data(),0, c/2,0))->RegisterYourself();
519   
520   TString comp(Form("(%s:%s+%s:%s+%s+%s+%s:%s+%s:%s)-%s:%s", 
521                     fn.Data(),ftn.Data(),
522                     bn.Data(),btn.Data(),
523                     in.Data(),on.Data(),
524                     cn.Data(),ltn.Data(),
525                     cn.Data(),rtn.Data(),
526                     en.Data(),etn.Data()));
527   TGeoCompositeShape* shape = new TGeoCompositeShape(comp.Data());
528   shape->SetName(Form(fgkHCName,id,ring));
529   shape->SetTitle(Form("FMD%d%c Honeycomb shape", id, ring));
530   return shape;
531 }
532
533
534 //____________________________________________________________________
535 TGeoVolume*
536 AliFMDGeometryBuilder::DetectorGeometry(AliFMDDetector* d, 
537                                         TGeoVolume* topMother, 
538                                         TGeoVolume* botMother, 
539                                         Double_t    zMother, 
540                                         TGeoVolume* innerTop, 
541                                         TGeoVolume* innerBot, 
542                                         TGeoVolume* outerTop, 
543                                         TGeoVolume* outerBot) 
544 {
545   // Common stuff for setting up the FMD1, FMD2, and FMD3 geometries.
546   // This includes putting the Honeycomb support plates and the rings
547   // into the mother volumes.   
548   // 
549   // Parameeters:
550   //    d         The detector geometry to use 
551   //    mother    The mother volume of the detector 
552   //    zmother   The midpoint in global coordinates of detector vol.
553   //    inner     Pointer to inner ring volume 
554   //    outer     Pointer to outer ring volume
555   //
556   // Returns:
557   //    Pointer to mother (detector volume) 
558   // 
559   if (!d) return 0;
560   // Loop over the defined rings 
561   for (int i = 0; i < 2; i++) {
562     AliFMDRing* r     = 0;
563     Double_t    lowr  = 0;
564     Double_t    highr = 0;
565     Double_t    rz    = 0;
566     TGeoVolume* tvol  = 0;
567     TGeoVolume* bvol  = 0;
568     switch (i) {
569     case 0: 
570       r      = d->GetInner();
571       lowr   = d->GetInnerHoneyLowR();
572       highr  = d->GetInnerHoneyHighR();
573       rz     = d->GetInnerZ();
574       tvol   = innerTop;
575       bvol   = innerBot;
576       break;
577     case 1: 
578       r      = d->GetOuter();
579       lowr   = d->GetOuterHoneyLowR();
580       highr  = d->GetOuterHoneyHighR();
581       rz     = d->GetOuterZ();
582       tvol   = outerTop;
583       bvol   = outerBot;
584       break;
585     }
586     if (!r) continue;
587     Char_t   c       = r->GetId();
588     Int_t    id      = d->GetId();
589     Double_t hcThick = r->GetHoneycombThickness();
590     Double_t alThick = r->GetAlThickness();
591     Double_t z       = TMath::Abs(rz - zMother);
592
593     // Place ring in mother volume
594     // TGeoMatrix*matrix=new TGeoTranslation(Form("FMD%d%c trans",id,c),0,0,0);
595     AliFMDDebug(1, ("Placing volumes %s and %s in %s and %s at z=%f", 
596                      tvol->GetName(), bvol->GetName(), 
597                      topMother->GetName(), botMother->GetName(), z));
598     topMother->AddNode(tvol, Int_t(c), new TGeoTranslation(0,0,z));
599     botMother->AddNode(bvol, Int_t(c), new TGeoTranslation(0,0,z));
600
601     // Honeycomp 
602     TGeoShape*   hcSha = HoneycombShape(id, c, lowr, highr, hcThick, alThick);
603     TGeoVolume*  hcVol = new TGeoVolume(Form(fgkHCName,id,c),hcSha,fAl);
604     hcVol->SetTitle(Form("FMD%d%c honeycomb shell", id, c));
605     
606     z += (r->GetSiThickness() + 
607           r->GetSpacing() + 
608           r->GetPrintboardThickness() + 
609           r->GetCopperThickness() + 
610           r->GetChipThickness() + 
611           r->GetModuleSpacing() +
612           r->GetLegLength() + 
613           r->GetHoneycombThickness() + 
614           r->GetFMDDPrintboardThickness() - 
615           hcThick / 2); 
616
617     AliFMDDebug(15, ("Placing a copy of %s in %s and %s at z=%f", 
618                       hcVol->GetName(), topMother->GetName(), 
619                       botMother->GetName(), z));
620     // Add to top 
621     topMother->AddNode(hcVol, 0, new TGeoTranslation(0, 0, z));
622
623     // Add to bottom
624     TGeoMatrix*   bhcMatrix = new TGeoCombiTrans(0,0,z,0);
625     bhcMatrix->SetName(Form("FMD%d%c_honeycomp", id, c));
626     bhcMatrix->SetTitle(Form("FMD%d%c honeycomp", id, c));
627     bhcMatrix->RotateZ(180);
628     botMother->AddNode(hcVol, 1, bhcMatrix);
629   }
630   return 0;
631 }
632
633 //____________________________________________________________________
634 TGeoVolume*
635 AliFMDGeometryBuilder::FMD1Geometry(AliFMD1* fmd1, 
636                                     TGeoVolume* innerTop, 
637                                     TGeoVolume* innerBot) 
638 {
639   // Setup the FMD1 geometry.  The FMD1 only has one ring, and no
640   // special support as it is at the momement. 
641   // 
642   // See also AliFMDGeometryBuilder::DetectorGeometry 
643   // 
644   if (!fmd1 || !innerTop || !innerBot) return 0;
645   AliFMDRing* r             = fmd1->GetInner();
646   Double_t    z             = fmd1->GetInnerZ();  
647   Double_t    disce         = 2;
648   Double_t    backlr        = fmd1->GetInnerHoneyHighR();
649   Double_t    backhr        = fmd1->GetInnerHoneyHighR()+5;
650   Double_t    backth        = 0.2;
651   Double_t    toplr         = r->GetLowR();
652   Double_t    tophr         = fmd1->GetInnerHoneyHighR()+disce;
653   Double_t    wallbh        = (r->GetFullDepth() + disce);
654   Double_t    wallth        = wallbh+0.1;
655   
656   TGeoVolume* fmd1TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
657                                                           fmd1->GetId(), 'T'));
658   fmd1TopVolume->SetTitle("FMD1 top half");
659   TGeoVolume* fmd1BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
660                                                           fmd1->GetId(), 'B'));
661   fmd1BotVolume->SetTitle("FMD1 bottom half");
662   
663   // Basic detector geometry 
664   DetectorGeometry(fmd1, fmd1TopVolume, fmd1BotVolume, z, 
665                    innerTop, innerBot, 0, 0);
666
667
668   // Back
669   TGeoTubeSeg* backShape  = new TGeoTubeSeg(backlr, backhr, backth / 2, 0, 180);
670   TGeoTubeSeg* wallbShape = new TGeoTubeSeg(backlr, backlr + backth, 
671                                             wallbh/2, 0, 180);
672   TGeoTubeSeg* topShape   = new TGeoTubeSeg(toplr, tophr, backth / 2, 0, 180);
673   TGeoTubeSeg* walltShape = new TGeoTubeSeg(tophr, tophr + backth, 
674                                             wallth/2, 0, 180);
675   TGeoVolume*  backVolume = new TGeoVolume(Form(fgkBackName, fmd1->GetId()), 
676                                            backShape, fC);
677   TGeoVolume*  wallbVolume= new TGeoVolume(Form(fgkFlangeName, fmd1->GetId()), 
678                                            wallbShape, fC);
679   TGeoVolume*  topVolume  = new TGeoVolume(Form(fgkTopName, fmd1->GetId()), 
680                                            topShape, fC);
681   TGeoVolume*  walltVolume= new TGeoVolume(Form(fgkBeamName, fmd1->GetId()), 
682                                            walltShape, fC);
683   backShape->SetName(Form(fgkBackName, fmd1->GetId()));
684   wallbShape->SetName(Form(fgkFlangeName, fmd1->GetId()));
685   topShape->SetName(Form(fgkTopName, fmd1->GetId()));
686   walltShape->SetName(Form(fgkBeamName, fmd1->GetId()));
687   backShape->SetTitle("FMD1 back saucer rim");
688   wallbShape->SetTitle("FMD1 back saucer wall");
689   topShape->SetTitle("FMD1 top lid");
690   walltShape->SetTitle("FMD1 top lid wall");
691   backVolume->SetFillColor(kGray);
692   topVolume->SetFillColor(kGray);
693   wallbVolume->SetFillColor(kGray);
694   walltVolume->SetFillColor(kGray);
695   backVolume->SetTitle("FMD1 back saucer rim");
696   wallbVolume->SetTitle("FMD1 back saucer wall");
697   topVolume->SetTitle("FMD1 top lid");
698   walltVolume->SetTitle("FMD1 top lid wall");
699   
700   // Place volumes
701   Double_t zb = TMath::Abs(fmd1->GetInnerZ() - z);
702   Double_t zi = zb;
703   Int_t    n  = 2;
704   
705   // Place top cover
706   zi -= disce / 2 + backth / 2;
707   zb =  zi;
708   for (Int_t i = 0; i  < 2; i++) {
709     TGeoVolume*   mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
710     Double_t      phi    = 360. / n * i;
711     TGeoRotation* rot    = new TGeoRotation(Form("FMD1 top rotation %d",i));
712     rot->RotateZ(phi);
713     TGeoMatrix* matrix   = new TGeoCombiTrans(Form("FMD1 top wall trans %d", i),
714                                               0, 0, zi, rot);
715     mother->AddNode(topVolume, i, matrix);    
716   }
717   // Place outer wall
718   zi += wallth / 2 + backth / 2;
719   for (Int_t i = 0; i  < 2; i++) {
720     TGeoVolume*   mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
721     Double_t      phi    = 360. / n * i;
722     TGeoRotation* rot    = new TGeoRotation(Form("FMD1 outer wall rotation %d",
723                                                  i));
724     rot->RotateZ(phi);
725     TGeoMatrix* matrix   = new TGeoCombiTrans(Form("FMD1 outer wall trans %d",
726                                                    i), 0, 0, zi, rot);
727     mother->AddNode(walltVolume, i, matrix);    
728   }
729   // Place back
730   zi += wallth / 2 + backth / 2; // + disce / 2;
731   for (Int_t i = 0; i  < 2; i++) {
732     TGeoVolume*   mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
733     Double_t      phi    = 360. / n * i;
734     TGeoRotation* rot    = new TGeoRotation(Form("FMD1 back rotation %d", i));
735     rot->RotateZ(phi);
736     TGeoMatrix* matrix   = new TGeoCombiTrans(Form("FMD1 back trans %d", i),
737                                              0, 0, zi, rot);
738     mother->AddNode(backVolume, i, matrix);    
739   }
740   // Place inner wall
741   zi -= wallbh / 2 + backth / 2; // + disce / 2;
742   for (Int_t i = 0; i  < 2; i++) {
743     TGeoVolume*   mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
744     Double_t      phi    = 360. / n * i;
745     TGeoRotation* rot    = new TGeoRotation(Form("FMD1 inner wall rotation %d",
746                                                  i)); 
747     rot->RotateZ(phi);
748     TGeoMatrix*   matrix = new TGeoCombiTrans(Form("FMD1 inner wall trans %d", 
749                                                    i), 0, 0, zi, rot);
750     mother->AddNode(wallbVolume, i, matrix);    
751   }
752
753
754   // Must add this after filling the assembly.
755   TGeoVolume* top    = gGeoManager->GetVolume("ALIC");
756   // TGeoMatrix* matrix = new TGeoTranslation("FMD1 trans", 0, 0, z);
757   TGeoRotation* rot = new TGeoRotation("FMD1 rotatation");
758   rot->RotateZ(90);
759   TGeoMatrix* matrix = new TGeoCombiTrans("FMD1 trans", 0, 0, z, rot);
760   AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f", 
761                    fmd1TopVolume->GetName(), fmd1BotVolume->GetName(), z));
762   top->AddNode(fmd1TopVolume, fmd1->GetId(), matrix);
763   top->AddNode(fmd1BotVolume, fmd1->GetId(), matrix);
764
765   return 0;
766 }
767
768 //____________________________________________________________________
769 TGeoVolume*
770 AliFMDGeometryBuilder::FMD2Geometry(AliFMD2* fmd2, 
771                                     TGeoVolume* innerTop, 
772                                     TGeoVolume* innerBot, 
773                                     TGeoVolume* outerTop,
774                                     TGeoVolume* outerBot) 
775 {
776   // Setup the FMD2 geometry.  The FMD2 has no
777   // special support as it is at the momement. 
778   // 
779   // See also AliFMDGeometryBuilder::DetectorGeometry 
780   // 
781   if (!fmd2 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
782   AliFMDRing* r             = fmd2->GetOuter();
783   Double_t    z             = fmd2->GetOuterZ();  
784   Double_t    framelr       = fmd2->GetOuterHoneyHighR()+0.5;
785   Double_t    framehr       = fmd2->GetOuterHoneyHighR()+1.8;
786   Double_t    framelz       = -.5;
787   Double_t    framehz       = (fmd2->GetInnerZ()-z) + r->GetFullDepth() + .5;
788   Double_t    framel        = framehz - framelz;
789   Double_t    coverlr       = fmd2->GetInner()->GetLowR()+1;
790   Double_t    backth        = 0.05;
791
792   TGeoVolume* fmd2TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
793                                                           fmd2->GetId(), 'T'));
794   TGeoVolume* fmd2BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
795                                                           fmd2->GetId(), 'B'));
796   fmd2TopVolume->SetTitle("FMD2 top half");
797   fmd2BotVolume->SetTitle("FMD2 bottom half");
798   
799   DetectorGeometry(fmd2, fmd2TopVolume, fmd2BotVolume, z, 
800                    innerTop, innerBot, outerTop, outerBot);
801
802   TGeoShape*  cylinderShape   = new TGeoTubeSeg(framelr,framehr,framel/2,0,180);
803   TGeoVolume* cylinderVolume  = new TGeoVolume(Form(fgkBackName, fmd2->GetId()),
804                                                cylinderShape, fC);
805   TGeoShape*  coverShape      = new TGeoTubeSeg(coverlr,framehr,backth/2,0,180);
806   TGeoVolume* coverVolume     = new TGeoVolume(Form(fgkTopName, fmd2->GetId()), 
807                                                coverShape, fC);
808   cylinderShape->SetName(Form(fgkBackName, fmd2->GetId()));
809   cylinderShape->SetTitle("FMD2 cylinder");
810   cylinderVolume->SetTitle("FMD2 cylinder");
811   cylinderVolume->SetTransparency(63);
812   coverShape->SetName(Form(fgkTopName, fmd2->GetId()));
813   coverShape->SetTitle("FMD2 cover");
814   coverVolume->SetTitle("FMD2 cover");
815   coverVolume->SetTransparency(63);
816   
817   for (Int_t i = 0; i  < 2; i++) {
818     TGeoVolume*   mother = (i == 0 ? fmd2TopVolume : fmd2BotVolume);
819     
820     Double_t      phi    = 360. / 2 * i;
821     TGeoRotation* rot    = new TGeoRotation(Form("FMD2 support rot %d",i)); 
822     rot->RotateZ(phi);
823     TGeoMatrix*   matrix = new TGeoCombiTrans(Form("FMD2 cyl trans %d", i),
824                                               0, 0, framelz+framel/2, rot);
825     mother->AddNode(cylinderVolume, i, matrix);    
826     matrix               = new TGeoCombiTrans(Form("FMD2 fcov trans %d", i),
827                                               0, 0, framelz-backth/2, rot);
828     mother->AddNode(coverVolume, 2*i+0, matrix);    
829     matrix               = new TGeoCombiTrans(Form("FMD2 bcov trans %d", i),
830                                               0, 0, framelz+framel+backth/2, 
831                                               rot);
832     mother->AddNode(coverVolume, 2*i+1, matrix);    
833   }
834
835
836   Double_t    f1l           = 10;
837   Double_t    f1w           = 6;
838   Double_t    f1d           = 1;
839   
840   TGeoBBox*   flange1Shape  = new TGeoBBox(f1l/2, f1w/2, f1d/2);
841   TGeoVolume* flange1Volume = new TGeoVolume(Form(fgkFlangeName, fmd2->GetId()),
842                                              flange1Shape, fAl);
843   TGeoBBox*   flange2Shape  = new TGeoBBox(f1w/2, f1d/2, (framel+backth)/2);
844   TGeoVolume* flange2Volume = new TGeoVolume(Form("F%dSG", fmd2->GetId()),
845                                              flange2Shape, fAl);
846   flange1Shape->SetName(Form(fgkFlangeName, fmd2->GetId()));
847   flange1Shape->SetTitle("FMD2 vertical flange");
848   flange1Volume->SetTitle("FMD2 vertical flange");
849   flange2Shape->SetName(Form("F%dSG", fmd2->GetId()));
850   flange2Shape->SetTitle("FMD2 horizontal flange");
851   flange2Volume->SetTitle("FMD2 horizontal flange ");
852   
853   flange1Volume->SetTransparency(42);
854   for (Int_t i = 0; i  < 4; i++) {
855     TGeoVolume*   mother = (i < 2 ? fmd2TopVolume : fmd2BotVolume);
856     
857     Double_t      phi    = 360. / 4 * i - 45;
858     Double_t      rphi   = TMath::Pi()*phi/180;
859     Double_t      x      = (framelr + f1l/2) * TMath::Sin(rphi);
860     Double_t      y      = (framelr + f1l/2) * TMath::Cos(rphi);
861     TGeoRotation* rot    = new TGeoRotation(Form("FMD2 support rot %d",i)); 
862     rot->RotateZ(phi);
863     TGeoMatrix*   matrix = new TGeoCombiTrans(Form("FMD2 flange 1 trans %d", i),
864                                               x,y, framelz-backth-f1d/2, rot);
865     mother->AddNode(flange1Volume, 2*i+0, matrix);    
866     matrix               = new TGeoCombiTrans(Form("FMD2 flange 2 trans %d", i),
867                                               x,y,framelz+framel+backth+f1d/2, 
868                                               rot);
869     mother->AddNode(flange1Volume, 2*i+1, matrix);    
870     Double_t x1 = x - (f1w-f1d) / 2 * TMath::Cos(rphi); 
871     Double_t y1 = y + (f1w-f1d) / 2 * TMath::Sin(rphi);
872     matrix               = new TGeoCombiTrans(Form("FMD2 flange 3 trans %d", i),
873                                               x1,y1,framelz+framel/2, rot);
874     mother->AddNode(flange2Volume, 2*i+0, matrix);    
875     Double_t x2 = x + (f1w-f1d) / 2 * TMath::Cos(rphi); 
876     Double_t y2 = y - (f1w-f1d) / 2 * TMath::Sin(rphi);
877     matrix               = new TGeoCombiTrans(Form("FMD2 flange 4 trans %d", i),
878                                               x2,y2,framelz+framel/2, rot);
879     mother->AddNode(flange2Volume, 2*i+1, matrix);    
880   }
881   
882   // Must be done after filling the assemblies 
883   TGeoVolume* top = gGeoManager->GetVolume("ALIC");
884   TGeoMatrix* matrix = new TGeoTranslation("FMD2 trans", 0, 0, z);
885   AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f", 
886                    fmd2TopVolume->GetName(), fmd2BotVolume->GetName(), z));
887   top->AddNode(fmd2TopVolume, fmd2->GetId(), matrix);
888   top->AddNode(fmd2BotVolume, fmd2->GetId(), matrix);
889
890
891   return 0;
892 }
893   
894 #if 1
895 //____________________________________________________________________
896 TGeoVolume*
897 AliFMDGeometryBuilder::FMD3Geometry(AliFMD3* fmd3, 
898                                     TGeoVolume* innerTop, 
899                                     TGeoVolume* innerBot, 
900                                     TGeoVolume* outerTop,
901                                     TGeoVolume* outerBot) 
902 {
903   // Setup the FMD3 geometry.  The FMD2 has a rather elaborate support
904   // structure, as the support will also support the vacuum
905   // beam-pipe. 
906   // 
907   // See also AliFMDGeometryBuilder::DetectorGeometry 
908   // 
909   if (!fmd3 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
910
911   //__________________________________________________________________
912   // Basic detector set-up.
913   TGeoVolume* fmd3TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
914                                                           fmd3->GetId(), 'T'));
915   TGeoVolume* fmd3BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
916                                                           fmd3->GetId(), 'B'));
917   fmd3TopVolume->SetTitle("FMD3 top half");
918   fmd3BotVolume->SetTitle("FMD3 bottom half");
919   DetectorGeometry(fmd3, fmd3TopVolume, fmd3BotVolume, fmd3->GetInnerZ(), 
920                    innerTop, innerBot, outerTop, outerBot);
921
922   //__________________________________________________________________
923   // Mother for all support material
924   TGeoVolumeAssembly* support = new TGeoVolumeAssembly("F3SU");
925   support->SetTitle("FMD3 support");
926
927   //__________________________________________________________________
928   // Base of cone
929   const TObjArray& radii    = fmd3->ConeRadii();
930   Int_t            nRadii   = radii.GetEntriesFast();
931   TGeoPcon*        coneBase = new TGeoPcon("FMD3_cone_base", 0., 180., nRadii);
932   TVector3*        r5       = 0;
933   TVector3*        r4       = 0;
934   for (Int_t i = 0; i < nRadii; i++) { 
935     TVector3* v = static_cast<TVector3*>(radii.At(i));
936     coneBase->DefineSection(i, v->X(), v->Y(), v->Z());
937     if      (i == 5) r5 = v;
938     else if (i == 4) r4 = v;
939   }
940   TString          coneComb("(FMD3_cone_base");
941
942   //__________________________________________________________________
943   // Flanges 
944   double    flangeDepth    = fmd3->GetFlangeDepth() / 2;
945   double    flangeLength   = fmd3->GetFlangeLength() / 2;
946   double    flangeWidth    = fmd3->GetFlangeWidth() / 2;
947   new TGeoBBox("FMD3_flange_base", flangeLength, flangeWidth, flangeDepth);
948
949   // Fiducial holes 
950   const TObjArray& fiducialHoles  = fmd3->FiducialHoles();
951   double           fiducialRadius = fmd3->GetFiducialRadius();
952 #if 0
953   TGeoTube*        fiducialShape  = 
954 #endif
955     new TGeoTube("FMD3_fiducial_hole", 0, fiducialRadius, flangeDepth+.1);
956   Int_t            nFiducialHoles = fiducialHoles.GetEntriesFast();
957   double           flangeAngle    = TMath::Pi() / 4;
958   double           flangeX        = r5->Y()+flangeLength;
959   TVector2         flangeC(flangeX * TMath::Cos(flangeAngle), 
960                            flangeX * TMath::Sin(flangeAngle));
961   TString          flangeComb("FMD3_flange_base-(");
962 #if 0// For debugging geometry 
963   TGeoVolume* fiducialVolume = new TGeoVolume("FMD3_fiducial", fiducialShape);
964   fiducialVolume->SetLineColor(kGreen);
965 #endif
966   for (Int_t i = 0; i < nFiducialHoles; i++) { 
967     TVector2&        v  =  *(static_cast<TVector2*>(fiducialHoles.At(i)));
968     v                   -= flangeC;
969     TVector2         r  =  v.Rotate(-flangeAngle);
970     TGeoTranslation* t1 =  new TGeoTranslation(r.X(),  r.Y(), 0);
971     TGeoTranslation* t2 =  new TGeoTranslation(r.X(), -r.Y(), 0);
972     t1->SetName(Form("FMD3_fiducial_hole_rot%d", 2*i+0));
973     t2->SetName(Form("FMD3_fiducial_hole_rot%d", 2*i+1));
974     t1->RegisterYourself();
975     t2->RegisterYourself();
976     flangeComb.Append(Form("FMD3_fiducial_hole:FMD3_fiducial_hole_rot%d+"
977                            "FMD3_fiducial_hole:FMD3_fiducial_hole_rot%d%c",
978                            2*i+0, 2*i+1, (i == nFiducialHoles-1 ? ')' : '+')));
979 #if 1 // For debugging geometry 
980     // support->AddNode(fiducialVolume, 2*i+0, t1);
981     // support->AddNode(fiducialVolume, 2*i+1, t2);
982 #endif
983   }
984   
985   // Final flange shape, and at to full shape 
986   TGeoCompositeShape* flangeShape = new TGeoCompositeShape(flangeComb.Data());
987   flangeShape->SetName("FMD3_flange");
988   for (Int_t i = 0; i < 2; i++) { 
989     TGeoRotation* rot = new TGeoRotation();
990     rot->RotateZ((i+.5)*90);
991     TVector2 v(flangeX, 0);
992     TVector2 w = v.Rotate((i+.5) * 2 * flangeAngle);
993     TGeoCombiTrans* trans = new TGeoCombiTrans(w.X(),w.Y(),
994                                                r4->X()+flangeDepth, rot);
995     trans->SetName(Form("FMD3_flange_matrix%d", i));
996     trans->RegisterYourself();
997     coneComb.Append(Form("+FMD3_flange:FMD3_flange_matrix%d", i));
998   }
999   coneComb.Append(")-(");
1000   
1001   //__________________________________________________________________
1002   // Holes 
1003   Double_t holeL  = (fmd3->GetHoleLength()-1)/2;
1004   Double_t holeD  = fmd3->GetHoleDepth()/2;
1005   Double_t holeLW = fmd3->GetHoleLowWidth()/2;
1006   Double_t holeHW = fmd3->GetHoleHighWidth()/2;
1007   Double_t holeA  = fmd3->GetConeOuterAngle() - 1 * TMath::Pi() / 180;
1008   Double_t holeZ  = (fmd3->GetHoleOffset() 
1009                      + holeL * TMath::Cos(holeA)
1010                      - holeD * TMath::Sin(holeA));
1011   Double_t holeX  = (fmd3->ConeR(-holeZ + fmd3->GetInnerZ() + fmd3->GetNoseZ()) 
1012                      - holeD * TMath::Cos(holeA));
1013   Double_t plateZ  = (fmd3->GetHoleOffset() 
1014                      + holeL * TMath::Cos(holeA)
1015                      - 0.033 * TMath::Sin(holeA));
1016   Double_t plateX = (fmd3->ConeR(-plateZ + fmd3->GetInnerZ()+fmd3->GetNoseZ()) 
1017                      - 0.033 * TMath::Cos(holeA));
1018   new TGeoTrd1("FMD3_cone_hole", holeLW, holeHW, holeD, holeL);
1019   TGeoTrd1* plateShape = new TGeoTrd1("FMD3_cooling_plate", 
1020                                       holeLW, holeHW, .033, holeL);
1021   TGeoRotation* holeRot = new TGeoRotation();
1022   holeRot->SetName("FMD3_cone_hole_rotation");
1023   holeRot->RotateZ(90);
1024   holeRot->RotateY(holeA*180/TMath::Pi());
1025   TGeoCombiTrans* holeBaseTrans = new TGeoCombiTrans(holeX, 0, holeZ, holeRot);
1026   holeBaseTrans->SetName("FMD3_cone_hole_base_matrix");
1027   TGeoCombiTrans* plateBaseTrans = new TGeoCombiTrans(plateX, 0,plateZ,holeRot);
1028   TGeoVolume* plateVolume = new TGeoVolume("FMD3_cooling_plate", 
1029                                            plateShape, fAl);
1030   plateShape->SetTitle("FMD3 cooling plate");
1031   plateVolume->SetTitle("FMD3 cooling plate");
1032   for (Int_t i = 0; i < 4; i++) { 
1033     Double_t        ang   = 360. / 8 * (i + .5);
1034     TGeoCombiTrans* trans = new TGeoCombiTrans(*holeBaseTrans);
1035     trans->RotateZ(ang);
1036     trans->SetName(Form("FMD3_cone_hole_matrix%d", i));
1037     trans->RegisterYourself();
1038     trans = new TGeoCombiTrans(*plateBaseTrans);
1039     trans->RotateZ(ang);
1040     trans->SetName(Form("FMD3_cooling_plate_matrix%d", i));
1041     coneComb.Append(Form("FMD3_cone_hole:FMD3_cone_hole_matrix%d+", i));
1042     support->AddNode(plateVolume, i, trans);
1043   }
1044   
1045   //__________________________________________________________________
1046   // Bolts
1047   Double_t boltRadius = fmd3->GetBoltRadius();
1048   Double_t boltLength = fmd3->GetBoltLength() / 2;
1049   Double_t boltZ1     = fmd3->GetInnerZ()+fmd3->GetNoseZ()-10;
1050   Double_t boltZ2     = fmd3->GetInnerZ()+fmd3->GetNoseZ()-20;
1051   Double_t boltXE     = 2*boltLength*TMath::Cos(fmd3->GetConeOuterAngle());
1052   Double_t boltX1     = (fmd3->ConeR(boltZ1) - boltXE);
1053   Double_t boltX2     = (fmd3->ConeR(boltZ2) - boltXE);
1054   
1055   new TGeoTube("FMD3_bolt_hole", 0, boltRadius, boltLength+.2);
1056   TGeoTube* boltShape = new TGeoTube("FMD3_bolt", 0, boltRadius, boltLength);
1057   TGeoRotation* boltRot = new TGeoRotation();
1058   boltRot->RotateY(-fmd3->GetConeOuterAngle()*180/TMath::Pi());
1059   TGeoCombiTrans* boltTrans1 = new TGeoCombiTrans(boltX1, 0, 10, boltRot);
1060   TGeoCombiTrans* boltTrans2 = new TGeoCombiTrans(boltX2, 0, 20, boltRot);
1061   TGeoCombiTrans* boltTrans3 = new TGeoCombiTrans(*boltTrans1);
1062   TGeoCombiTrans* boltTrans4 = new TGeoCombiTrans(*boltTrans2);
1063   boltTrans3->RotateZ(180);
1064   boltTrans4->RotateZ(180);
1065   boltTrans1->SetName("FMD3_bolt_matrix1");
1066   boltTrans2->SetName("FMD3_bolt_matrix2");
1067   boltTrans3->SetName("FMD3_bolt_matrix3");
1068   boltTrans4->SetName("FMD3_bolt_matrix4");
1069   boltTrans1->RegisterYourself();
1070   boltTrans2->RegisterYourself();
1071   boltTrans3->RegisterYourself();
1072   boltTrans4->RegisterYourself();
1073   coneComb.Append("FMD3_bolt_hole:FMD3_bolt_matrix1"
1074                   "+FMD3_bolt_hole:FMD3_bolt_matrix2"
1075                   "+FMD3_bolt_hole:FMD3_bolt_matrix3"
1076                   "+FMD3_bolt_hole:FMD3_bolt_matrix4)");
1077   TGeoVolume*     boltVolume = new TGeoVolume("FMD3_bolt", boltShape, fSteel);
1078   support->AddNode(boltVolume, 1, boltTrans1);
1079   support->AddNode(boltVolume, 2, boltTrans2);
1080   boltShape->SetTitle("FMD3 steering bolt");
1081   boltVolume->SetTitle("FMD3 steering bolt");
1082   
1083   //__________________________________________________________________
1084   // Final cone
1085   TGeoCompositeShape* coneShape = new TGeoCompositeShape(coneComb.Data());
1086   coneShape->SetName("FMD3_cone");
1087   coneShape->SetTitle("FMD3 cone");
1088   TGeoVolume*  coneVolume = new TGeoVolume("FMD3_Cone", coneShape, fC);
1089   coneVolume->SetLineColor(kRed);
1090   support->AddNode(coneVolume, 0, new TGeoTranslation(0, 0, 0));
1091
1092   //__________________________________________________________________
1093   // Tension boxes. 
1094   TGeoBBox* tensionOuter = new TGeoBBox("FMD3_tension_outer", .5, 3, 5);
1095   new TGeoBBox("FMD3_tension_inner", .51, 2.5, 4.6);
1096   TString tensionExpr("FMD3_tension_outer-FMD3_tension_inner");
1097   TGeoCompositeShape* tensionShape = new TGeoCompositeShape(tensionExpr.Data());
1098   tensionShape->SetName("FMD3_tension_box");
1099   tensionShape->SetTitle("FMD3 tension box");
1100   TGeoVolume*      tensionFrame = new TGeoVolume("FMD3_tension_frame",
1101                                                   tensionShape, fAl);
1102   TGeoTube*        springShape  = new TGeoTube("FMD3_tension_spring", 
1103                                                0, .3, 4.3/2);
1104   TGeoVolume*      springVolume = new TGeoVolume("FMD3_tension_spring", 
1105                                                  springShape, fSteel);
1106   TGeoVolume*      tensionBox   = new TGeoVolume("FMD3_tension_box", 
1107                                                  tensionOuter, fAir);
1108   tensionBox->AddNode(tensionFrame, 0);
1109   tensionBox->AddNode(springVolume, 0, new TGeoTranslation(0,0,4.2/2));
1110   
1111   Double_t         tensionD     = 5*TMath::Cos(fmd3->GetConeOuterAngle());
1112   Double_t         tensionZ     = (r4->Z() - 2 * tensionD - 5 -
1113                                    2*.5*TMath::Cos(fmd3->GetConeOuterAngle()));
1114   Double_t         tensionX     = (fmd3->ConeR(fmd3->GetInnerZ()
1115                                                +fmd3->GetNoseZ() 
1116                                                -tensionZ) + 
1117                                    2*.5*TMath::Cos(fmd3->GetConeOuterAngle())); 
1118   TGeoRotation*    tensionRot   = new TGeoRotation();
1119   tensionRot->RotateY(180/TMath::Pi()*fmd3->GetConeOuterAngle());
1120   TGeoCombiTrans*  tensionBase  = new TGeoCombiTrans(tensionX, 0, tensionZ, 
1121                                                      tensionRot);
1122   
1123   Double_t         wireT        = .1;
1124   Double_t         wireR1       = fmd3->ConeR(fmd3->GetInnerZ()
1125                                               +fmd3->GetNoseZ()) + wireT;
1126   Double_t         wireR2       = fmd3->ConeR(fmd3->GetInnerZ()
1127                                               +fmd3->GetNoseZ()-
1128                                               tensionZ+tensionD) + wireT;
1129   Double_t         wireL        = TMath::Sqrt(TMath::Power(wireR1-wireR2,2)+ 
1130                                               TMath::Power(tensionZ-
1131                                                            tensionD,2));
1132   Double_t         wireAngle    = TMath::ATan2(wireR2-wireR1,tensionZ-tensionD);
1133   TGeoTube*        wireShape    = new TGeoTube("FMD3_wire", 0, wireT, wireL/2);
1134   TGeoVolume*      wireVolume   = new TGeoVolume("FMD3_wire", wireShape,fSteel);
1135   TGeoRotation*    wireRot      = new TGeoRotation();
1136   wireRot->RotateY(180/TMath::Pi()*wireAngle);
1137   TGeoCombiTrans*  wireBase     = new TGeoCombiTrans((wireR2-wireR1)/2+wireR1
1138                                                      +.1*TMath::Cos(wireAngle),
1139                                                      0,(tensionZ-tensionD)/2,
1140                                                      wireRot);
1141   for (Int_t i = 0; i < 2; i++) { 
1142     Double_t        thisAngle = (i+.5) * 90;
1143     TGeoCombiTrans* thisTrans = new TGeoCombiTrans(*tensionBase);
1144     thisTrans->RotateZ(thisAngle);
1145     support->AddNode(tensionBox, i, thisTrans);
1146     thisTrans = new TGeoCombiTrans(*wireBase);
1147     thisTrans->RotateZ(thisAngle);
1148     support->AddNode(wireVolume, i, thisTrans);
1149   }
1150
1151   //__________________________________________________________________
1152   // Place support volumes in half-detector volumes 
1153   Double_t         z  = fmd3->GetInnerZ();
1154   TGeoTranslation* t1 = new TGeoTranslation(0, 0, -fmd3->GetNoseZ());
1155   fmd3TopVolume->AddNode(support, 1, t1);
1156   TGeoCombiTrans*  t2 = new TGeoCombiTrans(*t1);
1157   t2->RotateZ(180);
1158   fmd3BotVolume->AddNode(support, 2, t2);
1159
1160   TGeoRotation*   rot        = new TGeoRotation("FMD3 rotatation");
1161   rot->RotateY(180);
1162   TGeoVolume*     top        = gGeoManager->GetVolume("ALIC");
1163   TGeoMatrix* mmatrix        = new TGeoCombiTrans("FMD3 trans", 0, 0, z, rot);
1164   AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f", 
1165                    fmd3TopVolume->GetName(), fmd3BotVolume->GetName(), z));
1166   top->AddNode(fmd3TopVolume, fmd3->GetId(), mmatrix);
1167   top->AddNode(fmd3BotVolume, fmd3->GetId(), mmatrix);
1168
1169   return 0;
1170 }
1171
1172 #else
1173 //____________________________________________________________________
1174 TGeoVolume*
1175 AliFMDGeometryBuilder::FMD3Geometry(AliFMD3* fmd3, 
1176                                     TGeoVolume* innerTop, 
1177                                     TGeoVolume* innerBot, 
1178                                     TGeoVolume* outerTop,
1179                                     TGeoVolume* outerBot) 
1180 {
1181   // Setup the FMD3 geometry.  The FMD2 has a rather elaborate support
1182   // structure, as the support will also support the vacuum
1183   // beam-pipe. 
1184   // 
1185   // See also AliFMDGeometryBuilder::DetectorGeometry 
1186   // 
1187   if (!fmd3 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
1188   Double_t nlen    = fmd3->GetNoseLength();
1189   Double_t nz      = fmd3->GetNoseZ();
1190   Double_t noser1  = fmd3->GetNoseLowR();
1191   Double_t noser2  = fmd3->GetNoseHighR();
1192   Double_t conet   = fmd3->GetBeamThickness();
1193   Double_t conel   = fmd3->GetConeLength();
1194   Double_t backl   = fmd3->GetBackLength();
1195   // Double_t backr1  = fmd3->GetBackLowR();
1196   Double_t backr2  = fmd3->GetBackHighR();
1197   Double_t zdist   = conel -  backl - nlen;
1198   Double_t tdist   = backr2 - noser2;
1199   // Double_t beaml   = TMath::Sqrt(zdist * zdist + tdist * tdist);
1200   Double_t theta   = -180. * TMath::ATan2(tdist, zdist) / TMath::Pi();
1201   Double_t flanger = fmd3->GetFlangeR();
1202   Double_t z       = fmd3->GetInnerZ(); // fmd3->GetZ();
1203
1204   TGeoVolume* fmd3TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
1205                                                           fmd3->GetId(), 'T'));
1206   TGeoVolume* fmd3BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
1207                                                           fmd3->GetId(), 'B'));
1208   fmd3TopVolume->SetTitle("FMD3 top half");
1209   fmd3BotVolume->SetTitle("FMD3 bottom half");
1210   
1211   
1212   DetectorGeometry(fmd3, fmd3TopVolume, fmd3BotVolume, z, 
1213                    innerTop, innerBot, outerTop, outerBot);
1214
1215   
1216   TGeoVolumeAssembly* support = new TGeoVolumeAssembly("F3SU");
1217   support->SetTitle("FMD3 support");
1218   
1219   // Cone shape 
1220   TGeoPcon*        coneBase = new TGeoPcon("FMD3 cone base", 0, 180, 6);
1221   const TObjArray& radii    = fmd3.ConeRadii();
1222   TVector3*        v1       = 0;
1223   TVector3*        v4       = 0;
1224   for (Int_t i = 0; i < radii.GetEntriesFast(); i++) { 
1225     TVector3* v = static_cast<TVector3*>(radii.At(i));
1226     coneBase->DefineSection(i,  v->X(), v->Y(), v->Z());
1227     if (i == 1) v1 = v;
1228     if (i == 4) v4 = v;
1229     
1230   }
1231   Double_t  holeL = TMath::Sqrt(TMath::Power(v4->Z()-v1->Z(),2) + 
1232                                 TMath::Power(v4->X()-v1->X(),2));
1233   
1234   TGeoTrd1*       coneHole  = new TGeoTrd1("F3SC_hole",2,8,conet*3,
1235                                            (conel-2-2)/2);
1236   
1237
1238
1239   // Nose volume 
1240   TGeoTubeSeg* noseShape  = new TGeoTubeSeg(noser1, noser2, nlen / 2, 0, 180);
1241   TGeoVolume*  noseVolume = new TGeoVolume(fgkNoseName, noseShape, fC);
1242   support->AddNode(noseVolume, 0, new TGeoTranslation(0, 0, nlen/2));
1243   noseShape->SetName(fgkNoseName);
1244   noseShape->SetTitle("FMD3 nose");
1245   noseVolume->SetTitle("FMD3 nose");
1246   
1247   // Steel bolts 
1248   TGeoTube*       boltShape  = new TGeoTube("F3SB", 0, 0.3, conet / 2);
1249   TGeoVolume*     boltVolume = new TGeoVolume("F3SB", boltShape, fSteel);
1250   Double_t        z1         = -10;
1251   Double_t        x1         = (fmd3->ConeR(nz+z1));
1252   TGeoRotation*   r1         = new TGeoRotation();
1253   r1->RotateY(theta);
1254   TGeoCombiTrans* t          = new TGeoCombiTrans("F3SB1",x1,0,-z1,r1);
1255   support->AddNode(boltVolume, 1, t);
1256   z1                         = -20;
1257   x1                         = (fmd3->ConeR(nz+z1));
1258   t                          = new TGeoCombiTrans("F3SB2",x1,0,-z1,r1);
1259   support->AddNode(boltVolume, 2, t);
1260   boltShape->SetTitle("FMD3 steering bolt");
1261   boltVolume->SetTitle("FMD3 steering bolt");
1262
1263   // Cooling plates
1264   TGeoTrd1*   plateShape  = new TGeoTrd1(2, 8, 0.1, (conel-2-2)/2-.1);
1265   TGeoVolume* plateVolume = new TGeoVolume("F3CO", plateShape, fAl);
1266   plateShape->SetName("F3C0");
1267   plateShape->SetTitle("FMD3 cooling plate");
1268   plateVolume->SetTitle("FMD3 cooling plate");
1269
1270   // Shape for carbon half-cone
1271   TGeoConeSeg*    innerCone = new TGeoConeSeg("F3SC_inner", conel/2,
1272                                               noser2-conet, noser2, 
1273                                               backr2-conet, backr2, 0., 180.);
1274   innerCone->SetTitle("FMD3 cone inner");
1275   TGeoTrd1*       coneHole  = new TGeoTrd1("F3SC_hole",2,8,conet*3,
1276                                            (conel-2-2)/2);
1277   coneHole->SetTitle("FMD3 cone hole");
1278   Double_t        holeAng   = TMath::ATan2(backr2 - noser2, conel);
1279   Double_t        holeX     = ((conel-2) / 2 * TMath::Sin(holeAng) +
1280                                conet     * TMath::Cos(holeAng) +
1281                                noser2);
1282   TGeoRotation*   holeRot   = new TGeoRotation();
1283   holeRot->SetName("FMD3 cone hole rotation");
1284   holeRot->RotateZ(90);
1285   holeRot->RotateY(holeAng*180./TMath::Pi());
1286   TGeoCombiTrans* holeTrans = new TGeoCombiTrans(holeX, 0, -2, holeRot);
1287   holeRot->SetName("FMD3 cone hole");
1288
1289   // Build-up the composite shape for the cone, and add cooling plates
1290   // at the same time. 
1291   TString coneExp("F3SC_inner-(");
1292   for (int i = 0; i < 4; i++) { 
1293     Double_t        thisAng   = 360. / 8 * (i + .5);
1294     TGeoCombiTrans* thisTrans = new TGeoCombiTrans(*holeTrans);
1295     thisTrans->RotateZ(thisAng);
1296     thisTrans->SetName(Form("F3SC_rot%d", i));
1297     thisTrans->RegisterYourself();
1298     coneExp.Append(Form("F3SC_hole:F3SC_rot%d+", i));
1299
1300     const Double_t* tt         = thisTrans->GetTranslation();
1301     Double_t        x          = tt[0]+1*TMath::Cos(thisAng*TMath::Pi()/180);
1302     Double_t        y          = tt[1]+1*TMath::Sin(thisAng*TMath::Pi()/180);
1303     TGeoCombiTrans* plateTrans = new TGeoCombiTrans(x,y,tt[2]-1+nlen+conel/2,
1304                                                     thisTrans->GetRotation());
1305     support->AddNode(plateVolume, i, plateTrans);
1306   }
1307   // Remove bolt holes 
1308   coneExp.Append("F3SB:F3SB1+F3SB:F3SB2)");
1309
1310   // Finalize the half-cone shape and add volume
1311   TGeoCompositeShape* coneShape  = new TGeoCompositeShape(coneExp.Data());
1312   TGeoVolume*         coneVolume = new TGeoVolume("F3SC", coneShape, fC);
1313   coneShape->SetName("F3SC");
1314   coneShape->SetTitle("FMD3 cone");
1315   coneVolume->SetTitle("FMD3 cone");
1316   support->AddNode(coneVolume,1,new TGeoTranslation(0,0,nlen+conel/2));
1317   
1318   // The flanges 
1319   TGeoBBox* flangeShape    = new TGeoBBox((flanger - backr2) / 2, 
1320                                           fmd3->GetBeamWidth() / 2,
1321                                           backl / 2);
1322   TGeoVolume* flangeVolume = new TGeoVolume(Form(fgkFlangeName, fmd3->GetId()),
1323                                             flangeShape, fC);
1324   flangeShape->SetName(Form(fgkFlangeName, fmd3->GetId()));
1325   flangeShape->SetTitle("FMD3 flange");
1326   flangeVolume->SetTitle("FMD3 flange");
1327   
1328   Int_t    n               = fmd3->GetNFlange();
1329   Double_t r               = backr2 + (flanger - backr2) / 2;
1330   for (Int_t i = 0; i  < n/2; i++) {
1331     Double_t phi       = 360. / n * i + 180. / n;
1332     Double_t x         = r * TMath::Cos(TMath::Pi() / 180 * phi);
1333     Double_t y         = r * TMath::Sin(TMath::Pi() / 180 * phi);
1334     TGeoRotation* rot  = new TGeoRotation;
1335     rot->RotateZ(phi);
1336     TGeoMatrix* matrix = new TGeoCombiTrans(x, y, nlen+conel-backl/2, rot);
1337     matrix->SetName(Form("FMD3_flange_%02d", i));
1338     matrix->SetTitle(Form("FMD3_flange_%2d", i));
1339     support->AddNode(flangeVolume, i, matrix);
1340   }
1341
1342   // Place support volumes in half-detector volumes 
1343   z                          = fmd3->GetInnerZ();
1344   z1                         = z-nz;
1345   fmd3TopVolume->AddNode(support, 1, new TGeoTranslation(0,0,z1));
1346   r1                         = new TGeoRotation();
1347   r1->RotateZ(180);
1348   t                          = new TGeoCombiTrans(0,0,z1,r1);
1349   fmd3BotVolume->AddNode(support, 2, t);
1350
1351   TGeoRotation*   rot        = new TGeoRotation("FMD3 rotatation");
1352   rot->RotateY(180);
1353   TGeoVolume*     top        = gGeoManager->GetVolume("ALIC");
1354   TGeoMatrix* mmatrix        = new TGeoCombiTrans("FMD3 trans", 0, 0, z, rot);
1355   AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f", 
1356                    fmd3TopVolume->GetName(), fmd3BotVolume->GetName(), z));
1357   top->AddNode(fmd3TopVolume, fmd3->GetId(), mmatrix);
1358   top->AddNode(fmd3BotVolume, fmd3->GetId(), mmatrix);
1359
1360   return 0;
1361 }
1362 #endif
1363
1364 //____________________________________________________________________
1365 void
1366 AliFMDGeometryBuilder::Exec(Option_t*) 
1367 {
1368   // Setup up the FMD geometry. 
1369   AliFMDDebug(1, ("\tGeometry options: %s",
1370                     (fDetailed  ? "divided into strips" : "one volume")));
1371   if (!gGeoManager) {
1372     AliFatal("No TGeoManager defined");
1373     return;
1374   }
1375
1376   fSi      = gGeoManager->GetMedium("FMD_Si$");
1377   fC       = gGeoManager->GetMedium("FMD_Carbon$");
1378   fAl      = gGeoManager->GetMedium("FMD_Aluminum$");
1379   fChip    = gGeoManager->GetMedium("FMD_Si Chip$");
1380   fAir     = gGeoManager->GetMedium("FMD_Air$");
1381   fPCB     = gGeoManager->GetMedium("FMD_PCB$");
1382   fPlastic = gGeoManager->GetMedium("FMD_Plastic$");
1383   fCopper  = gGeoManager->GetMedium("FMD_Copper$");
1384   fSteel   = gGeoManager->GetMedium("FMD_Steel$");
1385
1386   if (!fSi||!fC||!fAl||!fChip||!fAir||!fPCB||!fPlastic||!fCopper||!fSteel) {
1387     AliError("Failed to get some or all tracking mediums");
1388     return;
1389   }    
1390   AliFMDGeometry* fmd = AliFMDGeometry::Instance();
1391   AliFMDRing* inner = fmd->GetInner();
1392   AliFMDRing* outer = fmd->GetOuter();
1393   RingGeometry(inner);
1394   RingGeometry(outer);
1395   TGeoVolume* innerTop = gGeoManager->GetVolume(Form(fgkRingTopName, 
1396                                                      inner->GetId()));
1397   TGeoVolume* innerBot = gGeoManager->GetVolume(Form(fgkRingBotName, 
1398                                                      inner->GetId()));
1399   TGeoVolume* outerTop = gGeoManager->GetVolume(Form(fgkRingTopName, 
1400                                                      outer->GetId()));
1401   TGeoVolume* outerBot = gGeoManager->GetVolume(Form(fgkRingBotName, 
1402                                                      outer->GetId()));
1403   
1404   FMD1Geometry(fmd->GetFMD1(), innerTop, innerBot);
1405   FMD2Geometry(fmd->GetFMD2(), innerTop, innerBot, outerTop, outerBot);
1406   FMD3Geometry(fmd->GetFMD3(), innerTop, innerBot, outerTop, outerBot);
1407 #ifndef USE_PRE_MOVE
1408   fmd->SetSectorOff(fSectorOff);
1409   fmd->SetModuleOff(fModuleOff);
1410   fmd->SetRingOff(fRingOff);
1411   fmd->SetDetectorOff(fDetectorOff);
1412   fmd->SetActive(fActiveId.fArray, fActiveId.fN);
1413 #endif
1414   // fmd->ExtractGeomInfo();
1415   
1416 }
1417
1418
1419 //____________________________________________________________________
1420 //
1421 // EOF
1422 //