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