]> git.uio.no Git - u/mrichter/AliRoot.git/blob - FMD/AliFMDGeometryBuilder.cxx
A lot of changes after detector review:
[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   // `Top' or `Outside' master volume
658   TGeoVolume* fmd1TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
659                                                           fmd1->GetId(), 'T'));
660   fmd1TopVolume->SetTitle("FMD1 top half");
661
662   // `Bottom' or `Inside' master volume
663   TGeoVolume* fmd1BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
664                                                           fmd1->GetId(), 'B'));
665   fmd1BotVolume->SetTitle("FMD1 bottom half");
666   
667   // Basic detector geometry 
668   DetectorGeometry(fmd1, fmd1TopVolume, fmd1BotVolume, z, 
669                    innerTop, innerBot, 0, 0);
670
671   Double_t lidP[][3] = { {  0.00,  4.20, 20.95 }, 
672                          {  0.15,  4.20, 20.95 }, 
673                          {  0.15, 20.80, 20.95 }, 
674                          {  3.00, 20.80, 20.95 }, 
675                          {  3.00, 20.80, 22.30 }, 
676                          {  3.15, 20.80, 22.30 }, 
677                          {  3.15, 20.95, 24.65 },
678                          {  3.30, 20.95, 24.65 }, 
679                          {  3.30, 24.50, 24.65 }, 
680                          {  6.80, 24.50, 24.65 },
681                          {  6.80, 24.50, 26.00 },
682                          {  6.95, 24.50, 26.00 } };
683   TGeoPcon* lidBaseS = new TGeoPcon("FMD1_lid_base", 0, 180, 12);
684   for (size_t i = 0; i < 12; i++) 
685     lidBaseS->DefineSection(i, lidP[i][0], lidP[i][1], lidP[i][2]);
686   
687   
688   Double_t lidH[][2] = { {  7.84903, 24.15680  }, 
689                          { 20.54900, 14.92970  },
690                          { 21.99700, 12.70000  },
691                          { 25.26090,  2.65502  } };
692   Double_t lidHR = .53 / 2;
693   Double_t lidHL = 0.16;
694   
695   new TGeoTube("FMD1_lid_hole", 0, lidHR, lidHL/2);
696   TString lidComp("FMD1_lid_base-(");
697   TGeoTranslation* trans = 0;
698   for (size_t i = 0; i < 4; i++) { 
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+0));
701     trans->RegisterYourself();
702     trans = new TGeoTranslation(+lidH[i][0], lidH[i][1], 6.95-lidHL/2);
703     trans->SetName(Form("FMD1_lid_hole_mat%d", 2*i+1));
704     trans->RegisterYourself();
705     lidComp.Append(Form("FMD1_lid_hole:FMD1_lid_hole_mat%d+" 
706                         "FMD1_lid_hole:FMD1_lid_hole_mat%d%c", 
707                         2 * i, 2 * i + 1, i == 3 ? ')' : '+'));
708   }
709   TGeoCompositeShape* lidS = new TGeoCompositeShape(lidComp.Data());
710   lidS->SetName("FMD1_lid");
711   TGeoVolume* lidV = new TGeoVolume("FMD1_lid", lidS, fC);
712   lidV->SetTransparency(63);
713   
714   // Place top cover
715   Double_t lidZ = -(3.3 - r->GetModuleDepth() - r->GetModuleSpacing() / 2);
716   AliFMDDebug(1, ("FMD1 lid offset in Z=%f", lidZ));
717
718   for (Int_t i = 0; i  < 2; i++) {
719     TGeoVolume*   mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
720     Double_t      phi    = 360. / 2 * i;
721     TGeoRotation* rot    = new TGeoRotation(Form("FMD1_lid_rot%d",i));
722     rot->RotateZ(phi);
723     TGeoMatrix* matrix   = new TGeoCombiTrans(Form("FMD1_lid_mat%d", i),
724                                               0, 0, lidZ, rot);
725     mother->AddNode(lidV, i, matrix);    
726   }
727
728   // Must add this after filling the assembly.
729   TGeoVolume* top    = gGeoManager->GetVolume("ALIC");
730   // TGeoMatrix* matrix = new TGeoTranslation("FMD1 trans", 0, 0, z);
731   TGeoRotation* rot = new TGeoRotation("FMD1 rotatation");
732   rot->RotateZ(90);
733   TGeoMatrix* matrix = new TGeoCombiTrans("FMD1 trans", 0, 0, z, rot);
734
735   AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f", 
736                    fmd1TopVolume->GetName(), fmd1BotVolume->GetName(), z));
737   top->AddNode(fmd1TopVolume, fmd1->GetId(), matrix);
738   top->AddNode(fmd1BotVolume, fmd1->GetId(), matrix);
739
740
741   // Survey points on V0A (screw holes for the FMD) 
742   const Double_t icb[] = { +12.700, -21.997, 324.670 };
743   const Double_t ict[] = { +12.700, +21.997, 324.670 };
744   const Double_t ocb[] = { -12.700, -21.997, 324.670 };
745   const Double_t oct[] = { -12.700, +21.997, 324.670 };
746
747   TGeoTube* surveyShape = new TGeoTube("FMD1_survey_marker", 
748                                         0, .2, .001);
749
750   TGeoMatrix* outMat = matrix;
751 #if 0
752   if (gGeoManager->cd("/ALIC_1/F1MT_1")) 
753     outMat = gGeoManager->GetCurrentMatrix();
754   else 
755     AliWarning("Couldn't cd to /ALIC_1/F1MT_1");
756 #endif
757
758   Double_t loct[3], locb[3];
759   outMat->MasterToLocal(oct, loct);
760   outMat->MasterToLocal(ocb, locb);
761   TGeoVolume* vOct = new TGeoVolume("V0L_OCT", surveyShape, fPlastic);
762   TGeoVolume* vOcb = new TGeoVolume("V0L_OCB", surveyShape, fPlastic);
763   
764   fmd1TopVolume->AddNode(vOct, 1, new TGeoTranslation(loct[0],loct[1],loct[2]));
765   fmd1TopVolume->AddNode(vOcb, 1, new TGeoTranslation(locb[0],locb[1],locb[2]));
766     
767   
768   TGeoMatrix* inMat = matrix;
769 #if 0
770   if (gGeoManager->cd("/ALIC_1/F1MT_1")) 
771     inMat = gGeoManager->GetCurrentMatrix();
772   else 
773     AliWarning("Couldn't cd to /ALIC_1/F1MT_1");
774 #endif
775
776   Double_t lict[3], licb[3];
777   inMat->MasterToLocal(ict, lict);
778   inMat->MasterToLocal(icb, licb);
779   TGeoVolume* vIct = new TGeoVolume("V0L_ICT", surveyShape, fPlastic);
780   TGeoVolume* vIcb = new TGeoVolume("V0L_ICB", surveyShape, fPlastic);
781   
782   fmd1BotVolume->AddNode(vIct, 1, new TGeoTranslation(lict[0],lict[1],lict[2]));
783   fmd1BotVolume->AddNode(vIcb, 1, new TGeoTranslation(licb[0],licb[1],licb[2]));
784
785   return 0;
786 }
787
788 //____________________________________________________________________
789 TGeoVolume*
790 AliFMDGeometryBuilder::FMD2Geometry(AliFMD2* fmd2, 
791                                     TGeoVolume* innerTop, 
792                                     TGeoVolume* innerBot, 
793                                     TGeoVolume* outerTop,
794                                     TGeoVolume* outerBot) 
795 {
796   // Setup the FMD2 geometry.  The FMD2 has no
797   // special support as it is at the momement. 
798   // 
799   // See also AliFMDGeometryBuilder::DetectorGeometry 
800   // 
801   if (!fmd2 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
802   AliFMDRing* r          = fmd2->GetOuter();
803   Double_t    z             = fmd2->GetOuterZ();  
804   Double_t    framelr       = 32.01;  // fmd2->GetOuterHoneyHighR()+0.5;
805   Double_t    framehr       = 33.611; // fmd2->GetOuterHoneyHighR()+1.8;
806   Double_t    framel        = 14.8; // framehz - framelz;
807   // Double_t    backth        = 0.3;
808   Double_t    backth        = 0.03;
809   Double_t    framelz       = -(2.38 
810                                 - r->GetModuleDepth() 
811                                 - r->GetModuleSpacing() / 2);
812   // Double_t    framelz       = -0.8;
813   // Double_t    framehz       = framelz + backth + framel;
814   Double_t    coverlr       = 4.3; // fmd2->GetInner()->GetLowR()+1;
815   Double_t    coverhr       = framehr; //  - 1;
816   
817   TGeoVolume* fmd2TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
818                                                           fmd2->GetId(), 'T'));
819   TGeoVolume* fmd2BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
820                                                           fmd2->GetId(), 'B'));
821   fmd2TopVolume->SetTitle("FMD2 top half");
822   fmd2BotVolume->SetTitle("FMD2 bottom half");
823   
824   DetectorGeometry(fmd2, fmd2TopVolume, fmd2BotVolume, z, 
825                    innerTop, innerBot, outerTop, outerBot);
826
827   TGeoVolumeAssembly* support = new TGeoVolumeAssembly("FMD2_support");
828   TGeoShape*  cylinderShape   = new TGeoTubeSeg(framelr,framehr,framel/2,0,180);
829   TGeoVolume* cylinderVolume  = new TGeoVolume(Form(fgkBackName, fmd2->GetId()),
830                                                cylinderShape, fC);
831   TGeoShape*  coverShape      = new TGeoTubeSeg(coverlr,coverhr,backth/2,0,180);
832   TGeoVolume* coverVolume     = new TGeoVolume(Form(fgkTopName, fmd2->GetId()), 
833                                                coverShape, fC);
834   cylinderShape->SetName(Form(fgkBackName, fmd2->GetId()));
835   cylinderShape->SetTitle("FMD2 cylinder");
836   cylinderVolume->SetTitle("FMD2 cylinder");
837   cylinderVolume->SetTransparency(63);
838   coverShape->SetName(Form(fgkTopName, fmd2->GetId()));
839   coverShape->SetTitle("FMD2 cover");
840   coverVolume->SetTitle("FMD2 cover");
841   coverVolume->SetTransparency(63);
842   
843   TGeoTranslation* trans = 0;
844   support->AddNode(coverVolume,1, new TGeoTranslation(0,0,backth/2));
845   support->AddNode(cylinderVolume, 1, new TGeoTranslation(0,0,backth+framel/2));
846   
847
848   Double_t    f1l            = 15.6085;
849   Double_t    f1w            = 6;
850   Double_t    f1d            = 1;
851   Int_t       nFiducialHoles = 4;
852   Double_t    precHoles[][2] = { { 32.4948, 29.6663 },
853                                  { 33.9104, 31.0819 },
854                                  { 34.8177, 33.4035 }, 
855                                  { 35.5028, 32.6744 } };
856   Double_t    precRadius     = .25;
857   Double_t    flangeA        = TMath::Pi()/4;
858   
859   new TGeoBBox("FMD2_flange_base", f1l/2, f1w/2, f1d/2);
860   new TGeoTube("FMD2_fiducial_hole", 0, precRadius, f1d/2+.1);
861   Double_t         flangeX        = framehr + f1l/2;
862   TVector2         flangeC(flangeX * TMath::Cos(flangeA), 
863                            flangeX * TMath::Sin(flangeA));
864   TString          flangeComb("FMD2_flange_base-(");  
865   new TGeoBBox("FMD2_flange_slit", 7./2, 1.5/2, f1d/2+.1);
866   trans = new TGeoTranslation(-f1l/2+1+7./2, +.5+1.5/2, 0);
867   trans->SetName("FMD2_flange_slit_mat1");
868   trans->RegisterYourself();
869   trans = new TGeoTranslation(-f1l/2+1+7./2, -.5-1.5/2, 0);
870   trans->SetName("FMD2_flange_slit_mat2");
871   trans->RegisterYourself();
872   flangeComb.Append("FMD2_flange_slit:FMD2_flange_slit_mat1+"
873                     "FMD2_flange_slit:FMD2_flange_slit_mat2+");
874   for (Int_t i = 0; i < nFiducialHoles; i++) { 
875     TVector2         v(precHoles[i][0], precHoles[i][1]);
876     v                   -= flangeC;
877     TVector2         r  =  v.Rotate(-flangeA);
878     TGeoTranslation* t1 =  new TGeoTranslation(r.X(),  r.Y(), 0);
879     TGeoTranslation* t2 =  new TGeoTranslation(r.X(), -r.Y(), 0);
880     t1->SetName(Form("FMD2_fiducial_hole_rot%d", 2*i+0));
881     t2->SetName(Form("FMD2_fiducial_hole_rot%d", 2*i+1));
882     t1->RegisterYourself();
883     t2->RegisterYourself();
884     flangeComb.Append(Form("FMD2_fiducial_hole:FMD2_fiducial_hole_rot%d+"
885                            "FMD2_fiducial_hole:FMD2_fiducial_hole_rot%d%c",
886                            2*i+0, 2*i+1, (i == nFiducialHoles-1 ? ')' : '+')));
887   }
888   // Final flange shape, and at to full shape 
889   TGeoCompositeShape* flangeS = new TGeoCompositeShape(flangeComb.Data());
890   flangeS->SetName("FMD2_flange");
891   TGeoVolume* flangeV = new TGeoVolume("FMD2_flange", flangeS, fAl);
892   
893   Double_t f2l = 7;
894   Double_t f2d = 12.5;
895   Double_t f2w = 1;
896
897   new TGeoBBox("FMD2_flange_spacer_base", f2l/2, f2w/2, f2d/2);
898   new TGeoTube("FMD2_flange_spacer_hole", 0, 2.5, f2w/2+.1);
899   TGeoRotation* holeRot = new TGeoRotation();
900   holeRot->RotateY(90);
901   holeRot->RotateZ(90);
902   TGeoCombiTrans* combo = 0;
903   combo = new TGeoCombiTrans(0, 0, f2d/2-.5-2.5, holeRot);
904   combo->SetName("FMD2_flange_spacer_hole_mat1");
905   combo->RegisterYourself();
906   combo = new TGeoCombiTrans(0, 0, -f2d/2+.5+2.5, holeRot);
907   combo->SetName("FMD2_flange_spacer_hole_mat2");
908   combo->RegisterYourself();
909   TString spacerComp("FMD2_flange_spacer_base-("
910                      "FMD2_flange_spacer_hole:FMD2_flange_spacer_hole_mat1+"
911                      "FMD2_flange_spacer_hole:FMD2_flange_spacer_hole_mat2)");
912   TGeoCompositeShape* spacerS = new TGeoCompositeShape(spacerComp.Data());
913   TGeoVolume*         spacerV = new TGeoVolume("FMD2_flange_spacer",
914                                                spacerS, fAl);
915
916   Double_t            extraL  = framehr-framelr;
917   TGeoBBox*           extraS  = new TGeoBBox("FMD2_flange_extra", 
918                                              extraL/2, f1w/2, f1d/2);
919   TGeoVolume*         extraV  = new TGeoVolume("FMD2_flange_extra", extraS,fAl);
920   TGeoVolumeAssembly* wingV   = new TGeoVolumeAssembly("FMD2_wing");
921   TGeoVolume*         tension = TensionBox();
922   TGeoTube*           wireS   = new TGeoTube(0, .05, (framehr-coverlr)/2);
923   TGeoVolume*         wireV   = new TGeoVolume("FMD2_tension_wire", 
924                                                wireS, fSteel);
925   wingV->AddNode(flangeV, 1, new TGeoTranslation(f1l/2,    0, f1d/2));
926   wingV->AddNode(flangeV, 2, new TGeoTranslation(f1l/2,    0, -f2d-f1d/2));
927   wingV->AddNode(extraV, 1, new TGeoCombiTrans(-extraL/2, 0, f1d/2, 0));
928   wingV->AddNode(spacerV, 1, new TGeoTranslation(1+f2l/2,-f2w/2+f1w/2,
929                                                  -f2d/2));
930   wingV->AddNode(spacerV, 2, new TGeoTranslation(1+f2l/2,+f2w/2-f1w/2,
931                                                  -f2d/2));
932   TGeoRotation* tensionR = new TGeoRotation;
933   tensionR->RotateY(90);
934   wingV->AddNode(tension, 1, new TGeoCombiTrans(4, 0, f1d+1.2, tensionR));
935   TGeoRotation* wireR = new TGeoRotation;
936   wireR->RotateY(90);
937   wingV->AddNode(wireV, 1, new TGeoCombiTrans(-(framehr-coverlr)/2, 0, f1d+1,
938                                               wireR));
939   
940   TGeoCombiTrans* extraM1 = new TGeoCombiTrans(coverhr-extraL/2,0,0,0);
941   extraM1->RotateZ(45);
942   extraM1->RegisterYourself();
943   extraM1->SetName("FMD2_back_cover_slit1");
944   TGeoCombiTrans* extraM2 = new TGeoCombiTrans(coverhr-extraL/2,0,0,0);
945   extraM2->RotateZ(135);
946   extraM2->RegisterYourself();
947   extraM2->SetName("FMD2_back_cover_slit2");
948   TString coverComp(Form(fgkTopName, fmd2->GetId()));
949   coverComp.Append("-(FMD2_flange_extra:FMD2_back_cover_slit1"
950                    "+FMD2_flange_extra:FMD2_back_cover_slit2)");
951   TGeoCompositeShape* cover2Shape = new TGeoCompositeShape(coverComp.Data());
952   cover2Shape->SetName("FMD2_back_cover");
953   TGeoVolume* cover2Volume = new TGeoVolume("FMD2_back_cover", cover2Shape,fC);
954   support->AddNode(cover2Volume,2, 
955                    new TGeoTranslation(0,0,backth+framel+backth/2));
956
957   TGeoCombiTrans* trans1 = new TGeoCombiTrans(framehr, 0, backth+framel, 0);
958   TGeoCombiTrans* trans2 = new TGeoCombiTrans(framehr, 0, backth+framel, 0);
959   trans1->RotateZ(45);
960   trans2->RotateZ(135);
961   support->AddNode(wingV, 1, trans1);
962   support->AddNode(wingV, 2, trans2);
963   AliFMDDebug(1, ("FMD2 support offset is %f", framelz));
964   
965   for (Int_t i = 0; i  < 2; i++) {
966     TGeoVolume*   mother = (i < 1 ? fmd2TopVolume : fmd2BotVolume);
967     
968     Double_t      phi    = 360. / 2 * i;
969     TGeoRotation* rot    = new TGeoRotation(Form("FMD2 support rot %d",i)); 
970     rot->RotateZ(phi);
971     TGeoMatrix*   matrix = new TGeoCombiTrans(0, 0, framelz, rot);
972     mother->AddNode(support, i, matrix);    
973   }
974   
975   // Must be done after filling the assemblies 
976   TGeoVolume* top = gGeoManager->GetVolume("ALIC");
977   TGeoMatrix* matrix = new TGeoTranslation("FMD2 trans", 0, 0, z);
978   AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f", 
979                    fmd2TopVolume->GetName(), fmd2BotVolume->GetName(), z));
980   top->AddNode(fmd2TopVolume, fmd2->GetId(), matrix);
981   top->AddNode(fmd2BotVolume, fmd2->GetId(), matrix);
982
983
984   return 0;
985 }
986   
987 //____________________________________________________________________
988 TGeoVolume*
989 AliFMDGeometryBuilder::FMD3Geometry(AliFMD3* fmd3, 
990                                     TGeoVolume* innerTop, 
991                                     TGeoVolume* innerBot, 
992                                     TGeoVolume* outerTop,
993                                     TGeoVolume* outerBot) 
994 {
995   // Setup the FMD3 geometry.  The FMD2 has a rather elaborate support
996   // structure, as the support will also support the vacuum
997   // beam-pipe. 
998   // 
999   // See also AliFMDGeometryBuilder::DetectorGeometry 
1000   // 
1001   if (!fmd3 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
1002
1003   //__________________________________________________________________
1004   // Basic detector set-up.
1005   TGeoVolume* fmd3TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
1006                                                           fmd3->GetId(), 'T'));
1007   TGeoVolume* fmd3BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName, 
1008                                                           fmd3->GetId(), 'B'));
1009   fmd3TopVolume->SetTitle("FMD3 top half");
1010   fmd3BotVolume->SetTitle("FMD3 bottom half");
1011   DetectorGeometry(fmd3, fmd3TopVolume, fmd3BotVolume, fmd3->GetInnerZ(), 
1012                    innerTop, innerBot, outerTop, outerBot);
1013
1014   //__________________________________________________________________
1015   // Mother for all support material
1016   TGeoVolumeAssembly* support = new TGeoVolumeAssembly("F3SU");
1017   support->SetTitle("FMD3 support");
1018
1019   //__________________________________________________________________
1020   // Base of cone
1021   const TObjArray& radii    = fmd3->ConeRadii();
1022   Int_t            nRadii   = radii.GetEntriesFast();
1023   TGeoPcon*        coneBase = new TGeoPcon("FMD3_cone_base", 0., 180., nRadii);
1024   TVector3*        r5       = 0;
1025   TVector3*        r4       = 0;
1026   for (Int_t i = 0; i < nRadii; i++) { 
1027     TVector3* v = static_cast<TVector3*>(radii.At(i));
1028     coneBase->DefineSection(i, v->X(), v->Y(), v->Z());
1029     if      (i == 5) r5 = v;
1030     else if (i == 4) r4 = v;
1031   }
1032   TString          coneComb("(FMD3_cone_base");
1033
1034   //__________________________________________________________________
1035   // Flanges 
1036   double    flangeDepth    = fmd3->GetFlangeDepth() / 2;
1037   double    flangeLength   = fmd3->GetFlangeLength() / 2;
1038   double    flangeWidth    = fmd3->GetFlangeWidth() / 2;
1039   new TGeoBBox("FMD3_flange_base", flangeLength, flangeWidth, flangeDepth);
1040
1041   // Fiducial holes 
1042   const TObjArray& fiducialHoles  = fmd3->FiducialHoles();
1043   double           fiducialRadius = fmd3->GetFiducialRadius();
1044 #if 0
1045   TGeoTube*        fiducialShape  = 
1046 #endif
1047     new TGeoTube("FMD3_fiducial_hole", 0, fiducialRadius, flangeDepth+.1);
1048   Int_t            nFiducialHoles = fiducialHoles.GetEntriesFast();
1049   double           flangeAngle    = TMath::Pi() / 4;
1050   double           flangeX        = r5->Y()+flangeLength;
1051   TVector2         flangeC(flangeX * TMath::Cos(flangeAngle), 
1052                            flangeX * TMath::Sin(flangeAngle));
1053   TString          flangeComb("FMD3_flange_base-(");
1054 #if 0// For debugging geometry 
1055   TGeoVolume* fiducialVolume = new TGeoVolume("FMD3_fiducial", fiducialShape);
1056   fiducialVolume->SetLineColor(kGreen);
1057 #endif
1058   for (Int_t i = 0; i < nFiducialHoles; i++) { 
1059     TVector2&        v  =  *(static_cast<TVector2*>(fiducialHoles.At(i)));
1060     v                   -= flangeC;
1061     TVector2         r  =  v.Rotate(-flangeAngle);
1062     TGeoTranslation* t1 =  new TGeoTranslation(r.X(),  r.Y(), 0);
1063     TGeoTranslation* t2 =  new TGeoTranslation(r.X(), -r.Y(), 0);
1064     t1->SetName(Form("FMD3_fiducial_hole_rot%d", 2*i+0));
1065     t2->SetName(Form("FMD3_fiducial_hole_rot%d", 2*i+1));
1066     t1->RegisterYourself();
1067     t2->RegisterYourself();
1068     flangeComb.Append(Form("FMD3_fiducial_hole:FMD3_fiducial_hole_rot%d+"
1069                            "FMD3_fiducial_hole:FMD3_fiducial_hole_rot%d%c",
1070                            2*i+0, 2*i+1, (i == nFiducialHoles-1 ? ')' : '+')));
1071 #if 0 // For debugging geometry 
1072     support->AddNode(fiducialVolume, 2*i+0, t1);
1073     support->AddNode(fiducialVolume, 2*i+1, t2);
1074 #endif
1075   }
1076   
1077   // Final flange shape, and at to full shape 
1078   TGeoCompositeShape* flangeShape = new TGeoCompositeShape(flangeComb.Data());
1079   flangeShape->SetName("FMD3_flange");
1080   for (Int_t i = 0; i < 2; i++) { 
1081     TGeoRotation* rot = new TGeoRotation();
1082     rot->RotateZ((i+.5)*90);
1083     TVector2 v(flangeX, 0);
1084     TVector2 w = v.Rotate((i+.5) * 2 * flangeAngle);
1085     TGeoCombiTrans* trans = new TGeoCombiTrans(w.X(),w.Y(),
1086                                                r4->X()+flangeDepth, rot);
1087     trans->SetName(Form("FMD3_flange_matrix%d", i));
1088     trans->RegisterYourself();
1089     coneComb.Append(Form("+FMD3_flange:FMD3_flange_matrix%d", i));
1090   }
1091   coneComb.Append(")-(");
1092   
1093   //__________________________________________________________________
1094   // Holes 
1095   Double_t holeL  = fmd3->GetHoleLength()/2;
1096   Double_t holeD  = fmd3->GetHoleDepth()/2;
1097   Double_t holeLW = fmd3->GetHoleLowWidth()/2;
1098   Double_t holeHW = fmd3->GetHoleHighWidth()/2;
1099   Double_t holeA  = fmd3->GetConeOuterAngle();
1100   Double_t holeA2 = TMath::Pi() - fmd3->GetConeOuterAngle();
1101   Double_t holeO  = fmd3->GetHoleOffset();
1102   Double_t holeZ  = (holeO
1103                      + holeL * TMath::Cos(holeA)
1104                      - holeD * TMath::Sin(holeA2));
1105   Double_t holeX  = (fmd3->ConeR(-holeZ + fmd3->GetInnerZ() + fmd3->GetNoseZ())
1106                      - holeD * TMath::Sin(holeA2));
1107   new TGeoTrd1("FMD3_cone_hole", holeLW, holeHW, holeD, holeL);
1108   TGeoTrd1* plateShape = new TGeoTrd1("FMD3_cooling_plate", 
1109                                       holeLW, holeHW, .033, holeL);
1110   TGeoRotation* holeRot = new TGeoRotation();
1111   holeRot->SetName("FMD3_cone_hole_rotation");
1112   holeRot->RotateZ(90);
1113   holeRot->RotateY(holeA*180/TMath::Pi());
1114   TGeoCombiTrans* holeBaseTrans = new TGeoCombiTrans(holeX, 0, holeZ, holeRot);
1115   holeBaseTrans->SetName("FMD3_cone_hole_base_matrix");
1116   // TGeoRotation* plateRot = new TGeoRotation();
1117   // plateRot->SetName("FMD3_cone_plate_rotation");
1118   // plateRot->RotateZ(90);
1119   // plateRot->RotateY(plateA*180/TMath::Pi());
1120   // TGeoCombiTrans* plateBaseTrans = new 
1121   //                  TGeoCombiTrans(plateX,0,plateZ,plateRot);
1122   TGeoVolume* plateVolume = new TGeoVolume("FMD3_cooling_plate", 
1123                                            plateShape, fAl);
1124   plateShape->SetTitle("FMD3 cooling plate");
1125   plateVolume->SetTitle("FMD3 cooling plate");
1126   for (Int_t i = 0; i < 4; i++) { 
1127     Double_t        ang   = 360. / 8 * (i + .5);
1128     TGeoCombiTrans* trans = new TGeoCombiTrans(*holeBaseTrans);
1129     trans->RotateZ(ang);
1130     trans->SetName(Form("FMD3_cone_hole_matrix%d", i));
1131     trans->RegisterYourself();
1132     trans = new TGeoCombiTrans(*holeBaseTrans);
1133     trans->RotateZ(ang);
1134     trans->SetName(Form("FMD3_cooling_plate_matrix%d", i));
1135     coneComb.Append(Form("FMD3_cone_hole:FMD3_cone_hole_matrix%d+", i));
1136     support->AddNode(plateVolume, i, trans);
1137   }
1138   
1139   //__________________________________________________________________
1140   // Bolts
1141   Double_t boltRadius = fmd3->GetBoltRadius();
1142   Double_t boltLength = fmd3->GetBoltLength() / 2;
1143   Double_t boltZ1     = fmd3->GetInnerZ()+fmd3->GetNoseZ()-10;
1144   Double_t boltZ2     = fmd3->GetInnerZ()+fmd3->GetNoseZ()-20;
1145   Double_t boltXE     = 2*boltLength*TMath::Cos(fmd3->GetConeOuterAngle());
1146   Double_t boltX1     = (fmd3->ConeR(boltZ1) - boltXE);
1147   Double_t boltX2     = (fmd3->ConeR(boltZ2) - boltXE);
1148   
1149   new TGeoTube("FMD3_bolt_hole", 0, boltRadius, boltLength+.2);
1150   TGeoTube* boltShape = new TGeoTube("FMD3_bolt", 0, boltRadius, boltLength);
1151   TGeoRotation* boltRot = new TGeoRotation();
1152   boltRot->RotateY(-fmd3->GetConeOuterAngle()*180/TMath::Pi());
1153   TGeoCombiTrans* boltTrans1 = new TGeoCombiTrans(boltX1, 0, 10, boltRot);
1154   TGeoCombiTrans* boltTrans2 = new TGeoCombiTrans(boltX2, 0, 20, boltRot);
1155   TGeoCombiTrans* boltTrans3 = new TGeoCombiTrans(*boltTrans1);
1156   TGeoCombiTrans* boltTrans4 = new TGeoCombiTrans(*boltTrans2);
1157   boltTrans3->RotateZ(180);
1158   boltTrans4->RotateZ(180);
1159   boltTrans1->SetName("FMD3_bolt_matrix1");
1160   boltTrans2->SetName("FMD3_bolt_matrix2");
1161   boltTrans3->SetName("FMD3_bolt_matrix3");
1162   boltTrans4->SetName("FMD3_bolt_matrix4");
1163   boltTrans1->RegisterYourself();
1164   boltTrans2->RegisterYourself();
1165   boltTrans3->RegisterYourself();
1166   boltTrans4->RegisterYourself();
1167   coneComb.Append("FMD3_bolt_hole:FMD3_bolt_matrix1"
1168                   "+FMD3_bolt_hole:FMD3_bolt_matrix2"
1169                   "+FMD3_bolt_hole:FMD3_bolt_matrix3"
1170                   "+FMD3_bolt_hole:FMD3_bolt_matrix4");
1171   TGeoVolume*     boltVolume = new TGeoVolume("FMD3_bolt", boltShape, fSteel);
1172   support->AddNode(boltVolume, 1, boltTrans1);
1173   support->AddNode(boltVolume, 2, boltTrans2);
1174   boltShape->SetTitle("FMD3 steering bolt");
1175   boltVolume->SetTitle("FMD3 steering bolt");
1176   
1177   //__________________________________________________________________
1178   // Cut-outs for tension wheel sheeve 
1179   new TGeoBBox("FMD3_sheeve_hole", .55, .75, 1.16);
1180   Double_t        sheeveHoleZ = fmd3->GetInnerZ() + fmd3->GetNoseZ() - .75;
1181   Double_t        sheeveHoleR = fmd3->ConeR(sheeveHoleZ) - .55 + .2572222;
1182   TGeoCombiTrans* sheeveMat1  = new TGeoCombiTrans(sheeveHoleR,0,1.15,0);
1183   TGeoCombiTrans* sheeveMat2  = new TGeoCombiTrans(sheeveHoleR,0,1.15,0);
1184   sheeveMat1->RotateZ(45);
1185   sheeveMat2->RotateZ(135);
1186   sheeveMat1->SetName("FMD3_sheeve_hole_matrix1");
1187   sheeveMat2->SetName("FMD3_sheeve_hole_matrix2");
1188   sheeveMat1->RegisterYourself();
1189   sheeveMat2->RegisterYourself();
1190   coneComb.Append("+FMD3_sheeve_hole:FMD3_sheeve_hole_matrix1"
1191                   "+FMD3_sheeve_hole:FMD3_sheeve_hole_matrix2)");
1192   
1193   //__________________________________________________________________
1194   // Sheeve boxes 
1195   Double_t       sheeveL     = 1.15;
1196   TGeoBBox*      sheeveSideS = new TGeoBBox("FMD3_sheeve_side",
1197                                            .55, .25, 1.15);
1198   TGeoBBox*      sheeveBackS = new TGeoBBox("FMD3_sheeve_back", 
1199                                             .55, .25, .15);
1200   TGeoBBox*      sheeveWingS = new TGeoBBox("FMD3_sheeve_wing", 
1201                                             .15, .15, 1.15);
1202   TGeoPcon*      sheeveWheelS = new TGeoPcon("FMD3_sheeve_wheel", 0, 360, 9);
1203   Double_t       sheeveInnerR = 0; // .2;
1204   Double_t       sheeveR      = .875;
1205   Double_t       sheeveWheelZ = .95;
1206   sheeveWheelS->DefineSection(0, -.25,   sheeveInnerR, 1);
1207   sheeveWheelS->DefineSection(1, -.125,  sheeveInnerR, 1);
1208   sheeveWheelS->DefineSection(2, -.125,  sheeveInnerR, sheeveWheelZ);
1209   sheeveWheelS->DefineSection(3, -.0625, sheeveInnerR, sheeveR+.02);
1210   sheeveWheelS->DefineSection(4, 0.000,  sheeveInnerR, sheeveR);
1211   sheeveWheelS->DefineSection(5, +.0625, sheeveInnerR, sheeveR+.02);
1212   sheeveWheelS->DefineSection(6, +.125,  sheeveInnerR, sheeveWheelZ);
1213   sheeveWheelS->DefineSection(7, +.125,  sheeveInnerR, 1);
1214   sheeveWheelS->DefineSection(8, +.25,   sheeveInnerR, 1);
1215   TGeoVolume*    sheeveSideV = new TGeoVolume("FMD3_sheeve_side", 
1216                                               sheeveSideS, fPlastic);
1217   TGeoVolume*    sheeveBackV = new TGeoVolume("FMD3_sheeve_back", 
1218                                               sheeveBackS, fPlastic);
1219   TGeoVolume*    sheeveWingV = new TGeoVolume("FMD3_sheeve_wing", 
1220                                               sheeveWingS, fPlastic);
1221   TGeoVolume*    sheeveWheelV= new TGeoVolume("FMD3_sheeve_wheel", 
1222                                               sheeveWheelS, fPlastic);
1223   TGeoVolumeAssembly* sheeveBox = new TGeoVolumeAssembly("FMD3_sheeve_box");
1224   sheeveBox->AddNode(sheeveSideV, 1, new TGeoTranslation(0, -.5, 0));
1225   sheeveBox->AddNode(sheeveSideV, 2, new TGeoTranslation(0, +.5, 0));
1226   sheeveBox->AddNode(sheeveBackV, 1, new TGeoTranslation(0, 0, 2.0+.15-1.15));
1227   sheeveBox->AddNode(sheeveWingV, 1, new TGeoTranslation(.55-.15, -.90, 0));
1228   sheeveBox->AddNode(sheeveWingV, 2, new TGeoTranslation(.55-.15, +.90, 0));
1229   TGeoRotation*   sheeveWheelR = new TGeoRotation;
1230   sheeveWheelR->RotateX(90);
1231   TGeoCombiTrans* sheeveWheelM = new TGeoCombiTrans(0, 0, sheeveWheelZ-sheeveL,
1232                                                     sheeveWheelR);
1233   sheeveBox->AddNode(sheeveWheelV, 1, sheeveWheelM);
1234   support->AddNode(sheeveBox, 1, sheeveMat1);
1235   support->AddNode(sheeveBox, 2, sheeveMat2);
1236   
1237   
1238
1239   //__________________________________________________________________
1240   // Final cone
1241   TGeoCompositeShape* coneShape = new TGeoCompositeShape(coneComb.Data());
1242   coneShape->SetName("FMD3_cone");
1243   coneShape->SetTitle("FMD3 cone");
1244   TGeoVolume*  coneVolume = new TGeoVolume("FMD3_Cone", coneShape, fC);
1245   coneVolume->SetLineColor(kRed);
1246   support->AddNode(coneVolume, 0, new TGeoTranslation(0, 0, 0));
1247
1248   //__________________________________________________________________
1249   // Tension boxes. 
1250   TGeoVolume*     tensionBox = TensionBox();
1251   Double_t        tensionH  = .6;
1252   Double_t        tensionL  = 4;
1253   Double_t        tensionZ  = 23.654;
1254   Double_t        tensionR  = fmd3->ConeR(fmd3->GetInnerZ() + fmd3->GetNoseZ() 
1255                                           -  tensionZ);
1256   Double_t        tensionAr = fmd3->GetConeOuterAngle();
1257   Double_t        tensionA  = tensionAr * 180 / TMath::Pi();
1258   TGeoRotation*   tensionQ  = new TGeoRotation;
1259   tensionQ->RotateY(tensionA);
1260   TGeoCombiTrans* tensionM1 = new TGeoCombiTrans(tensionR,0,tensionZ, tensionQ);
1261   TGeoCombiTrans* tensionM2 = new TGeoCombiTrans(tensionR,0,tensionZ, tensionQ);
1262   tensionM1->RotateZ(45);
1263   tensionM2->RotateZ(135);
1264   support->AddNode(tensionBox, 1, tensionM1);
1265   support->AddNode(tensionBox, 2, tensionM2);
1266   
1267   // Double_t         tensionHR    = 0.15;
1268   Double_t         wireT        = .1/2;
1269   Double_t         wireZ1       = (tensionZ
1270                                    - tensionL * TMath::Cos(tensionAr) 
1271                                    - tensionH * TMath::Sin(tensionAr));
1272   Double_t         wireR1       = (tensionR 
1273                                    - tensionL * TMath::Sin(tensionAr) 
1274                                    + tensionH * TMath::Cos(tensionAr));
1275   AliFMDDebug(10, ("Wire Z1: %f=%f-%f*cos(%f)-%f*sin(%f)", 
1276                   wireZ1, tensionZ, tensionL, tensionAr, tensionH, tensionAr));
1277   AliFMDDebug(10, ("Wire R1: %f=%f-%f*sin(%f)-%f*cos(%f)", 
1278                   wireR1, tensionR, tensionL, tensionAr, tensionH, tensionAr));
1279   
1280   Double_t         wireStartA   = 42.3 * TMath::Pi() / 180;
1281   Double_t         wireZ2       = (sheeveWheelZ * (1 - TMath::Sin(wireStartA))
1282                                    // - sheeveL - 
1283                                    - wireT * TMath::Sin(wireStartA));
1284   /* (sheeveWheelZ * (1 - TMath::Sin(wireStartA))
1285                                    - wireT * TMath::Sin(wireStartA) 
1286                                    - sheeveL); */
1287   AliFMDDebug(10, ("wireZ2=%f=%f*(1-%f)", wireZ2, sheeveWheelZ, 
1288                   TMath::Sin(wireStartA)));
1289   Double_t         wireR2       = (sheeveHoleR + 
1290                                    sheeveWheelZ * TMath::Cos(wireStartA) + 
1291                                    wireT * TMath::Cos(wireStartA));
1292   Double_t         wireDR       = wireR1-wireR2;
1293   Double_t         wireDZ       = wireZ1-wireZ2;
1294   Double_t         wireL        = TMath::Sqrt(wireDR*wireDR+wireDZ*wireDZ)-.01;
1295   Double_t         wireAngle    = TMath::ATan2(wireDR,wireDZ);
1296   TGeoTube*        wireShape    = new TGeoTube("FMD3_wire", 0, wireT, wireL/2);
1297   TGeoVolume*      wireVolume   = new TGeoVolume("FMD3_wire", wireShape,fSteel);
1298   TGeoRotation*    wireRot      = new TGeoRotation();
1299   wireRot->RotateY(180/TMath::Pi()*wireAngle);
1300   Double_t         wireR        = wireR2 + wireDR / 2;
1301   Double_t         wireZ        = wireZ2 + wireDZ / 2;
1302   TGeoCombiTrans*  wireM1       = new TGeoCombiTrans(wireR, 0,wireZ, wireRot);
1303   TGeoCombiTrans*  wireM2       = new TGeoCombiTrans(wireR, 0,wireZ, wireRot);
1304   wireM1->RotateZ(45);
1305   wireM2->RotateZ(135);
1306   support->AddNode(wireVolume, 1, wireM1);
1307   support->AddNode(wireVolume, 2, wireM2);
1308
1309
1310   TGeoTorus*       wireTS  = new TGeoTorus(sheeveWheelZ+wireT, 0, wireT, 0, 
1311                                            90-wireStartA*180/TMath::Pi());
1312   TGeoVolume*      wireTV  = new TGeoVolume("FMD3_bend_wire",wireTS,fSteel);
1313   TGeoRotation*    wireTR  = new TGeoRotation;
1314   wireTR->RotateY(90);
1315   wireTR->RotateZ(-90);
1316   Double_t         wireTZ  = sheeveWheelZ;
1317   TGeoCombiTrans*  wireTM1 = new TGeoCombiTrans(sheeveHoleR,0,wireTZ,wireTR);
1318   TGeoCombiTrans*  wireTM2 = new TGeoCombiTrans(sheeveHoleR,0,wireTZ,wireTR);
1319   wireTM1->RotateZ(45);
1320   wireTM2->RotateZ(135);
1321   support->AddNode(wireTV, 1, wireTM1);
1322   support->AddNode(wireTV, 2, wireTM2);
1323
1324   Double_t         colarR = 4.05;
1325   Double_t         wireEL = sheeveHoleR - colarR;
1326   TGeoTube*        wireES = new TGeoTube("FMD3_end_wire", 0, wireT, wireEL/2);
1327   TGeoVolume*      wireEV = new TGeoVolume("FMD3_end_wire", wireES, fSteel);
1328   TGeoRotation*    wireER = new TGeoRotation;
1329   wireER->RotateY(90);
1330   TGeoCombiTrans*  wireEM1 = new TGeoCombiTrans(colarR+wireEL/2,0,
1331                                                 -wireT,wireER);
1332   TGeoCombiTrans*  wireEM2 = new TGeoCombiTrans(colarR+wireEL/2,0,
1333                                                 -wireT,wireER);
1334   wireEM1->RotateZ(45);
1335   wireEM2->RotateZ(135);
1336   support->AddNode(wireEV, 1, wireEM1);
1337   support->AddNode(wireEV, 2, wireEM2);
1338   
1339   
1340
1341   
1342   //__________________________________________________________________
1343   // Place support volumes in half-detector volumes 
1344   Double_t         z  = fmd3->GetInnerZ();
1345   AliFMDDebug(1, ("FMD3 support at z=%f", -fmd3->GetNoseZ()));
1346   TGeoTranslation* t1 = new TGeoTranslation(0, 0, -fmd3->GetNoseZ());
1347   fmd3TopVolume->AddNode(support, 1, t1);
1348   TGeoCombiTrans*  t2 = new TGeoCombiTrans(*t1);
1349   t2->RotateZ(180);
1350   fmd3BotVolume->AddNode(support, 2, t2);
1351
1352   TGeoRotation*   rot        = new TGeoRotation("FMD3 rotatation");
1353   rot->RotateY(180);
1354   TGeoVolume*     top        = gGeoManager->GetVolume("ALIC");
1355   TGeoMatrix* mmatrix        = new TGeoCombiTrans("FMD3 trans", 0, 0, z, rot);
1356   AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f", 
1357                    fmd3TopVolume->GetName(), fmd3BotVolume->GetName(), z));
1358   top->AddNode(fmd3TopVolume, fmd3->GetId(), mmatrix);
1359   top->AddNode(fmd3BotVolume, fmd3->GetId(), mmatrix);
1360
1361   return 0;
1362 }
1363
1364
1365 //____________________________________________________________________
1366 void
1367 AliFMDGeometryBuilder::Exec(Option_t*) 
1368 {
1369   // Setup up the FMD geometry. 
1370   AliFMDDebug(1, ("\tGeometry options: %s",
1371                     (fDetailed  ? "divided into strips" : "one volume")));
1372   if (!gGeoManager) {
1373     AliFatal("No TGeoManager defined");
1374     return;
1375   }
1376
1377   fSi      = gGeoManager->GetMedium("FMD_Si$");
1378   fC       = gGeoManager->GetMedium("FMD_Carbon$");
1379   fAl      = gGeoManager->GetMedium("FMD_Aluminum$");
1380   fChip    = gGeoManager->GetMedium("FMD_Si Chip$");
1381   fAir     = gGeoManager->GetMedium("FMD_Air$");
1382   fPCB     = gGeoManager->GetMedium("FMD_PCB$");
1383   fPlastic = gGeoManager->GetMedium("FMD_Plastic$");
1384   fCopper  = gGeoManager->GetMedium("FMD_Copper$");
1385   fSteel   = gGeoManager->GetMedium("FMD_Steel$");
1386
1387   if (!fSi||!fC||!fAl||!fChip||!fAir||!fPCB||!fPlastic||!fCopper||!fSteel) {
1388     AliError("Failed to get some or all tracking mediums");
1389     return;
1390   }    
1391   AliFMDGeometry* fmd = AliFMDGeometry::Instance();
1392   AliFMDRing* inner = fmd->GetInner();
1393   AliFMDRing* outer = fmd->GetOuter();
1394   RingGeometry(inner);
1395   RingGeometry(outer);
1396   TGeoVolume* innerTop = gGeoManager->GetVolume(Form(fgkRingTopName, 
1397                                                      inner->GetId()));
1398   TGeoVolume* innerBot = gGeoManager->GetVolume(Form(fgkRingBotName, 
1399                                                      inner->GetId()));
1400   TGeoVolume* outerTop = gGeoManager->GetVolume(Form(fgkRingTopName, 
1401                                                      outer->GetId()));
1402   TGeoVolume* outerBot = gGeoManager->GetVolume(Form(fgkRingBotName, 
1403                                                      outer->GetId()));
1404   
1405   FMD1Geometry(fmd->GetFMD1(), innerTop, innerBot);
1406   FMD2Geometry(fmd->GetFMD2(), innerTop, innerBot, outerTop, outerBot);
1407   FMD3Geometry(fmd->GetFMD3(), innerTop, innerBot, outerTop, outerBot);
1408 #ifndef USE_PRE_MOVE
1409   fmd->SetSectorOff(fSectorOff);
1410   fmd->SetModuleOff(fModuleOff);
1411   fmd->SetRingOff(fRingOff);
1412   fmd->SetDetectorOff(fDetectorOff);
1413   fmd->SetActive(fActiveId.fArray, fActiveId.fN);
1414 #endif
1415   // fmd->ExtractGeomInfo();
1416   
1417 }
1418
1419
1420 //____________________________________________________________________
1421 //
1422 // EOF
1423 //