e30e4bcc25b80546d976dee069757289abc3aff8
[u/mrichter/AliRoot.git] / FMD / scripts / GeoGeometry.C
1 //____________________________________________________________________
2 //
3 //
4 // $Id$
5 //
6 // Script I used for rapid prototyping of the FMD3 geometry - in
7 // particular the support cone 
8 //
9 /** @defgroup geo_geom Simple geometry
10     @ingroup FMD_script
11 */
12 #ifndef __CINT___
13 # ifndef ROOT_TGeoVolume
14 #  include <TGeoVolume.h>
15 # endif
16 # ifndef ROOT_TGeoMaterial
17 #  include <TGeoMaterial.h>
18 # endif
19 # ifndef ROOT_TGeoMedium
20 #  include <TGeoMedium.h>
21 # endif
22 # ifndef ROOT_TGeoMatrix
23 #  include <TGeoMatrix.h>
24 # endif
25 # ifndef ROOT_TGeoXtru
26 #  include <TGeoXtru.h>
27 # endif
28 # ifndef ROOT_TGeoPcon
29 #  include <TGeoPcon.h>
30 # endif
31 # ifndef ROOT_TGeoTube
32 #  include <TGeoTube.h>
33 # endif
34 # ifndef ROOT_TGeoManager
35 #  include <TGeoManager.h>
36 # endif
37 # ifndef ROOT_TGeoPhysicalNode
38 #  include <TGeoPhysicalNode.h>
39 # endif
40 # ifndef ROOT_TVector3
41 #  include <TVector3.h>
42 # endif
43 # ifndef ROOT_TString
44 #  include <TString.h>
45 # endif
46 # ifndef ROOT_TRandom
47 #  include <TRandom.h>
48 # endif
49 # ifndef ROOT_TBrowser
50 #  include <TBrowser.h>
51 # endif
52 # ifndef ROOT_TCanvas
53 #  include <TCanvas.h>
54 # endif
55 # ifndef __CSTDARG__
56 #  include <cstdarg>
57 # endif
58 # ifndef __IOSTREAM__
59 #  include <iostream>
60 # endif
61 #endif
62
63 //____________________________________________________________________
64 /** @brief Simple geometry 
65     @ingroup geo_geom
66     @code 
67     gSystem->Load("libPhysics.so");
68     gSystem->Load("libGeom.so");
69     gROOT->LoadMacro("GeoGeometry.C+");
70     Geometry g;
71     g.Exec();
72     @endcode 
73  */
74 class Geometry 
75 {
76 public:
77   /** Constructor */
78   Geometry();
79   /** Destructor */
80   virtual ~Geometry() {}
81   /** Initialize  */
82   virtual void Initialize();
83   /** Register  */
84   virtual void Register();
85   /** @e Do-It member function  */
86   virtual void Exec();
87   /** Try to align */
88   virtual void Align();
89   /** Convert detector coordinates to spatial coordinates 
90       @param sector Sector number 
91       @param strip  Strip number
92       @param xyz    Spatial coordinates
93   */
94   virtual void Detector2XYZ(UInt_t sector, UInt_t strip, TVector3& xyz);
95   /** Debug level */
96   static Int_t fgDebug;
97   /** Print debugging messages 
98       @param lvl Acceptance level 
99       @param where Where it happened
100       @param format Message format. */
101   static void Debug(Int_t lvl, const char* where, const char* format, ...) 
102   {
103     if (lvl > fgDebug) return;
104     static char buf[2048];
105     va_list ap;
106     va_start(ap, format);
107     vsnprintf(buf, 2048, format, ap);
108     std::cout << "D: " << where << ": " << buf << std::endl;
109     va_end(ap);
110   }
111 protected:
112   /** List of translations */
113   TObjArray*    fMatricies;
114   /** Shape parameter */
115   TVector2      fA;
116   /** Shape parameter */
117   TVector2      fB;
118   /** Shape parameter */
119   TVector2      fC;
120   /** Spacing between sensor and hybrid */
121   Double_t      fSpacer;
122   /** Thickness of aluminum plates in honey comb */
123   Double_t      fAlThickness;
124   /** Width of bonding pads */
125   Double_t      fBondingWidth;
126   /** chip layer thickenss */
127   Double_t      fChipThickness;
128   /** Copper layer thickness */
129   Double_t      fCopperThickness;
130   /** Upper radious */
131   Double_t      fHighR;
132   /** Thickness of honey comb */
133   Double_t      fHoneycombThickness;
134   /** Inner honey comb inner radius  */
135   Double_t      fInnerHoneyHighR;
136   /** Inner honey comb outer radius  */
137   Double_t      fInnerHoneyLowR;
138   /** Z coordinate of inner ring  */
139   Double_t      fInnerZ;
140   /** Length of support legs */
141   Double_t      fLegLength;
142   /** Offset from edge of legs */
143   Double_t      fLegOffset;
144   /** Radius of support legs */
145   Double_t      fLegRadius;
146   /** Inner radius */
147   Double_t      fLowR;
148   /** Spacing between modules */
149   Double_t      fModuleSpacing;
150   /** Number of strps */
151   Int_t         fNStrips;
152   /** Outer honey comb inner radius */
153   Double_t      fOuterHoneyHighR;
154   /** Outer honey comb outer radius */
155   Double_t      fOuterHoneyLowR;
156   /** Z coordinate of outer */
157   Double_t      fOuterZ;
158   /** Thickness of print board */
159   Double_t      fPrintboardThickness;
160   /** Cache of ring depth */
161   Double_t      fRingDepth;
162   /** Thickness of silicon sensor */
163   Double_t      fSiThickness;
164   /** ??? */
165   Double_t      fSpacerHeight;
166   /** Opening angle of sensor */
167   Double_t      fTheta;
168   /** Radius of wafer the sensor is cut out of */
169   Double_t      fWaferRadius;
170   /** Air tracking medium */
171   TGeoMedium*   fAir;
172   /** Aluminum tracking medium */
173   TGeoMedium*   fAl;
174   /** Carbon tracking medium */
175   TGeoMedium*   fCarbon;
176   /** Chip tracking medium */
177   TGeoMedium*   fChip;
178   /** Copper tracking medium */
179   TGeoMedium*   fCopper;
180   /** Kapton tracking medium */
181   TGeoMedium*   fKapton;
182   /** PCB tracking medium */
183   TGeoMedium*   fPCB;
184   /** Plastic tracking medium */
185   TGeoMedium*   fPlastic;
186   /** Active silicon tracking medium */
187   TGeoMedium*   fSi;
188   /** Vacuum  tracking medium */
189   TGeoMedium*   fVacuum;
190   /** Use assemblies */
191   Bool_t        fDoubleAssembly;
192   /** Make a detailed geometry */
193   void MakeDetailed(TGeoVolume* mother);
194 };
195
196 //____________________________________________________________________
197 Int_t Geometry::fgDebug = 10;
198
199 //____________________________________________________________________
200 Geometry::Geometry()
201   : fMatricies(0),
202     fA( 4.3000,   1.3972),
203     fB(17.2000,   2.1452),
204     fC(15.3327,   4.9819)
205 {
206   fBondingWidth           =   0.5000;
207   fWaferRadius            =   6.7000;
208   fSiThickness            =   0.0300;
209   fLowR                   =   4.3000;
210   fHighR                  =  17.2000;
211   fTheta                  =  18.0000;
212   fNStrips                =      512;
213   fRingDepth              =   2.1600;
214   fLegRadius              =   0.5000;
215   fLegLength              =   1.0000;
216   fLegOffset              =   2.0000;
217   fModuleSpacing          =   1.0000;
218   fPrintboardThickness    =   0.1000;
219   fSpacerHeight           =   0.0300;
220
221   fInnerZ                 =  83.4000;
222   fOuterZ                 =  75.2000;
223   fHoneycombThickness     =   1.0000;
224   fAlThickness            =   0.1000;
225   fInnerHoneyLowR         =   5.3000;
226   fInnerHoneyHighR        =  18.2000;
227   fOuterHoneyLowR         =  16.6000;
228   fOuterHoneyHighR        =  29.0000;
229
230   fCopperThickness        =   0.01;
231   fChipThickness          =   0.01;
232   fAlThickness            =   0.10;
233   fHoneycombThickness     =   1.00;
234   fSpacer                 =   0.10;
235   fLegLength              =   1.00;
236 }
237
238 //____________________________________________________________________
239 void 
240 Geometry::Exec()
241 {
242   Initialize();
243   Register();
244   // gGeoManager->DefaultColors();
245   gGeoManager->ViewLeaves(kFALSE);
246   TCanvas* c = new TCanvas;
247   c->SetFillColor(0);
248   gGeoManager->GetTopVolume()->Draw();
249   new TBrowser("b", "Browser");
250 }
251
252 //____________________________________________________________________
253 void 
254 Geometry::Initialize()
255 {
256   Double_t mMax  = 10;
257   Double_t mType = 2;
258   
259   // Air 
260   Double_t pAir[]     = { 0., mType, mMax, 1.,  .001, 1., .001, .001 };
261   TGeoMixture* fmdAir = new TGeoMixture("FMD air", 4, .00120479);
262   fmdAir->DefineElement(0, 12.0107,  6., 0.000124);
263   fmdAir->DefineElement(1, 14.0067,  7., 0.755267);
264   fmdAir->DefineElement(2, 15.9994,  8., 0.231781);
265   fmdAir->DefineElement(3, 39.948,  18., 0.012827);
266   fmdAir->SetTransparency('0');
267   fAir = new TGeoMedium("FMD Air", 1, fmdAir,  pAir);
268
269   // Silicon 
270   Double_t pSi[]      = { 1., mType, mMax, 1.,  .001, 1., .001, .001 };
271   TGeoMaterial* fmdSi = new TGeoMaterial("FMD Si", 28.0855, 14, 2.33);
272   fmdSi->SetFillColor(2);
273   fSi = new TGeoMedium("FMD Si", 1, fmdSi,  pSi);
274
275   // Vacumm 
276   Double_t pVacuum[]  = { 0., mType, mMax, 10,  .01, .1, .003, .003 };
277   TGeoMaterial* fmdVacuum = new TGeoMaterial("FMD Vacuum",1e-16,1e-16,1e-16);
278   fmdVacuum->SetTransparency('0');
279   fVacuum = new TGeoMedium("FMD Vacuum", 1, fmdVacuum,pVacuum);
280
281
282   // PCB 
283   Double_t pPCB[]     = { 0., mType, mMax, 1.,  .001, 1., .001, .001 };
284   TGeoMixture* fmdPCB = new TGeoMixture("FMD PCB", 14, 1.8);
285   fmdPCB->DefineElement(0,  28.0855,   14, 0.15144894);
286   fmdPCB->DefineElement(1,  40.078,    20, 0.08147477);
287   fmdPCB->DefineElement(2,  26.981538, 13, 0.04128158);
288   fmdPCB->DefineElement(3,  24.305,    12, 0.00904554);
289   fmdPCB->DefineElement(4,  10.811,     5, 0.01397570);
290   fmdPCB->DefineElement(5,  47.867,    22, 0.00287685);
291   fmdPCB->DefineElement(6,  22.98977,  11, 0.00445114);
292   fmdPCB->DefineElement(7,  39.0983,   19, 0.00498089);
293   fmdPCB->DefineElement(8,  55.845,    26, 0.00209828);
294   fmdPCB->DefineElement(9,  18.9984,    9, 0.00420000);
295   fmdPCB->DefineElement(10, 15.9994,    8, 0.36043788);
296   fmdPCB->DefineElement(11, 12.0107,    6, 0.27529425);
297   fmdPCB->DefineElement(12, 14.0067,    7, 0.01415852);
298   fmdPCB->DefineElement(13,  1.00794,   1, 0.03427566);
299   fmdPCB->SetFillColor(7);
300   fPCB = new TGeoMedium("FMD PCB", 1, fmdPCB,  pPCB);
301
302   // Chip 
303   Double_t pChip[]  = { 0., mType, mMax, 10., .01,  1., .003, .003 };
304   TGeoMixture* fmdChip = new TGeoMixture("FMD Chip", 6, 2.36436);
305   fmdChip->DefineElement(0,  12.0107,   6, 0.039730642);
306   fmdChip->DefineElement(1,  14.0067,   7, 0.001396798);
307   fmdChip->DefineElement(2,  15.9994,   8, 0.01169634);
308   fmdChip->DefineElement(3,   1.00794,  1, 0.004367771);
309   fmdChip->DefineElement(4,  28.0855,  14, 0.844665);
310   fmdChip->DefineElement(5, 107.8682,  47, 0.0981434490);
311   fmdChip->SetFillColor(4);
312   fChip = new TGeoMedium("FMD Chip", 1, fmdChip, pChip);
313
314   // Carbon 
315   Double_t pC[]       = { 0., mType, mMax, 10., .01,  1., .003, .003 };
316   TGeoMaterial* fmdC = new TGeoMaterial("FMD C", 12.011, 6, 2.265);
317   fmdC->SetFillColor(6);
318   fCarbon = new TGeoMedium("FMD C", 1, fmdC, pC);
319   
320   // Kapton (inside of Honeycombs)
321   Double_t pKapton[]  = { 0., mType, mMax, 1.,  .001, 1., .001, .001 };
322   TGeoMaterial* fmdKapton = new TGeoMaterial("FMD Kapton", 12.011,   6.,0.01);
323   fmdKapton->SetFillColor(3);
324   fKapton                 = new TGeoMedium("FMD Kapton",1,fmdKapton,pKapton);
325
326   // Plastic 
327   Double_t pPlastic[] = { 0., mType, mMax, 10., .01,  1., .003, .003 };
328   TGeoMixture* fmdPlastic = new TGeoMixture("FMD Plastic", 2, 1.03);
329   fmdPlastic->DefineElement(0,  1.01,   1, .5);
330   fmdPlastic->DefineElement(1,  12.01,  6, .5);
331   fmdPlastic->SetFillColor(4);
332   fPlastic = new TGeoMedium("FMD Plastic", 1, fmdPlastic,  pPlastic);
333
334   // Aluminium 
335   Double_t pAl[]  = { 0., mType, mMax, 10., .001,  -1., .003, .003 };
336   TGeoMaterial* fmdAl = new TGeoMaterial("FMD Al", 26.981539, 13, 2.7);
337   fmdAl->SetFillColor(3);
338   fAl = new TGeoMedium("FMD Al", 1, fmdAl, pAl);
339
340   // Copper 
341   Double_t pCopper[]  = { 0., mType, mMax, 10., .01,  1., .003, .003 };
342   TGeoMaterial* fmdCopper = new TGeoMaterial("FMD Copper", 63.546,  29.,8.96);
343   fmdCopper->SetFillColor(3);
344   fCopper = new TGeoMedium("FMD Copper",  1, fmdCopper, pCopper);
345 }
346
347 #define DEGRAD TMath::Pi()/180.
348 //____________________________________________________________________
349 void 
350 Geometry::Detector2XYZ(UInt_t sector, UInt_t strip, TVector3& xyz)
351 {
352   UInt_t   mod      = sector / 2;
353   if (!fMatricies) {
354     Warning("Detector2XYZ", "No matricies");
355     return;
356   }
357   TGeoMatrix* m = static_cast<TGeoMatrix*>(fMatricies->At(mod));
358   if (!m) {
359     Warning("Detector2XYZ", "No matrix found for module %d", mod);
360     return;
361   }
362   Debug(10, "Detector2XYZ", "Transforming (%2d,%3d)", sector, strip);
363   Double_t rmax     = fB.Mod();
364   Double_t stripoff = fA.Mod();
365   Double_t dstrip   = (rmax - stripoff) / fNStrips;
366   Double_t r        = (strip + .5) * dstrip + stripoff; // fLowR
367   Double_t theta    = ((sector % 2) - .5) * fTheta;
368   Double_t modThick = (fSiThickness 
369                        + fPrintboardThickness 
370                        + fCopperThickness
371                        + fChipThickness 
372                        + fSpacer);
373   Debug(10,"Detector2XYZ", "Radius %7.3f, angle %7.3f (%f, %f)", r, theta, 
374        fLowR, stripoff);
375   Double_t local[] = {
376     r * TMath::Cos(theta * DEGRAD), 
377     r * TMath::Sin(theta * DEGRAD), 
378     -modThick + fSiThickness / 2
379   };
380   Double_t master[3];
381   Debug(10, "Detector2XYZ", "Local (%7.3f,%7.3f,%7.3f)", 
382        local[0], local[1], local[2]);
383   m->LocalToMaster(local, master);
384   Debug(10, "Detector2XYZ", "Master (%7.3f,%7.3f,%7.3f)", 
385        master[0], master[1], master[2]);
386   xyz.SetXYZ(master[0], master[1], master[2]);
387 }
388 //____________________________________________________________________
389 void
390 Geometry::MakeDetailed(TGeoVolume* caveVolume)
391 {
392   Info("MakeSimple", "Using a detailed geometry");
393   Double_t xv[6] = { fA.X(), fC.X(), fB.X(),  fB.X(),  fC.X(),  fA.X() };
394   Double_t yv[6] = { fA.Y(), fC.Y(), fB.Y(), -fB.Y(), -fC.Y(), -fA.Y() };
395   Double_t rmax     = fB.Mod();
396   Double_t stripoff = fA.Mod();
397   Double_t dstrip   = (rmax - stripoff) / fNStrips;
398
399   // Double_t hybridThick = (fPrintboardThickness + fCopperThickness 
400   //                         + fChipThickness);
401   // Double_t modThick    = fSiThickness + fSpacer + hybridThick;
402   // Double_t fmdWidth    = (modThick + fHoneycombThickness + fModuleSpacing
403   //                         + fLegLength + fSpacer);
404   
405   // Top
406   // TGeoTube*   fmdShape     = new TGeoTube(fLowR-.1,fHighR+.1,fmdWidth/2+.1);
407   // TGeoPcon*   fmdShape     = new TGeoPcon(0, 360, 2);
408   // fmdShape->DefineSection(0, -fmdWidth / 2 - .1, fLowR-.1, fHighR+.1);
409   // fmdShape->DefineSection(1,  fmdWidth / 2 + .1, fLowR-.1, fHighR+.1);
410   // TGeoVolume* fmdVolume    = new TGeoVolume("FMD1", fmdShape, fVacuum);
411   
412   
413   // Sensor 
414   TGeoXtru* sensorShape = new TGeoXtru(2);
415   sensorShape->DefinePolygon(6, xv, yv);
416   sensorShape->DefineSection(0, - fSiThickness/2);
417   sensorShape->DefineSection(1, fSiThickness/2);
418   TGeoVolume* sensorVolume= new TGeoVolume("FISE",sensorShape,fSi);
419   sensorVolume->SetLineColor(2);
420   // sensorVolume->VisibleDaughters(kFALSE);
421   // sensorVolume->SetVisibility(kTRUE);
422
423   // Virtual volume shape to divide 
424   TGeoTubeSeg* activeShape   = new TGeoTubeSeg(fLowR, rmax, fSiThickness/2, 
425                                                - fTheta, fTheta);
426   TGeoVolume*  activeVolume  = new TGeoVolume("FIAC", activeShape,fSi);
427   activeVolume->SetLineColor(3);
428   sensorVolume->AddNodeOverlap(activeVolume, 0);
429   // activeVolume->SetTransparency(0x3f);
430   TGeoVolume* sectorVolume   = activeVolume->Divide("FISC",2,2,-fTheta,
431                                                     0,0,"N");
432   TGeoVolume* stripVolume    = sectorVolume->Divide("FIST",1,fNStrips,
433                                                     stripoff,dstrip,0,"SX");
434   (void)stripVolume;
435   
436   // Position
437   Double_t x, y, z;
438   
439   // Make PCB volume 
440   for (Int_t i = 0; i < 3; i++) yv[i] -= fBondingWidth;
441   for (Int_t i = 3; i < 6; i++) yv[i] += fBondingWidth;
442   Double_t off = (TMath::Tan(TMath::Pi() * fTheta / 180) * fBondingWidth);
443
444   // PCB layer 
445   TGeoXtru* pcbShape      = new TGeoXtru(2);
446   pcbShape->DefinePolygon(6, xv, yv);
447   pcbShape->DefineSection(0, - fPrintboardThickness/2);
448   pcbShape->DefineSection(1, fPrintboardThickness/2);
449   TGeoVolume* pcbVolume   = new TGeoVolume("FPCB",pcbShape,fPCB);
450   pcbVolume->SetLineColor(4);
451
452   // Copper layer
453   TGeoXtru* cuShape       = new TGeoXtru(2);
454   cuShape->DefinePolygon(6, xv, yv);
455   cuShape->DefineSection(0, - fCopperThickness/2);
456   cuShape->DefineSection(1, fCopperThickness/2);
457   TGeoVolume* cuVolume    = new TGeoVolume("FCOP",cuShape,fCopper);
458   cuVolume->SetLineColor(4);
459
460   // Chip layer
461   TGeoXtru*   chipShape   = new TGeoXtru(2);
462   chipShape->DefinePolygon(6, xv, yv);
463   chipShape->DefineSection(0, - fChipThickness/2);
464   chipShape->DefineSection(1, fChipThickness/2);
465   TGeoVolume* chipVolume = new TGeoVolume("FCHI",chipShape,fChip);
466   chipVolume->SetLineColor(4);
467
468   // Short leg shape 
469   TGeoTube*   shortLegShape  = new TGeoTube(0, fLegRadius, fLegLength / 2);
470   TGeoVolume* shortLegVolume = new TGeoVolume("FISL", shortLegShape, fPlastic);
471   shortLegVolume->SetLineColor(2);
472   // Long leg shape
473   TGeoTube*   longLegShape   = new TGeoTube(0, fLegRadius, 
474                                             (fLegLength + fModuleSpacing) / 2);
475   TGeoVolume* longLegVolume  = new TGeoVolume("FILL", longLegShape, fPlastic);
476   longLegVolume->SetLineColor(2);
477   
478   // Make a front volume 
479   TGeoVolume* frontVolume    =  new TGeoVolumeAssembly("FIFV");
480   z                          =  fPrintboardThickness / 2;
481   frontVolume->AddNode(pcbVolume, 0, new TGeoTranslation(0, 0, z));
482   z                          += (fPrintboardThickness + fCopperThickness) / 2;
483   frontVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, z));
484   z                          += (fCopperThickness + fChipThickness) / 2;
485   frontVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, z));
486   z                          += (fChipThickness + fModuleSpacing 
487                                  + fLegLength) / 2;
488   x                          =  fA.X() + fLegOffset + fLegRadius;
489   y                          =  0;
490   frontVolume->AddNode(longLegVolume, 0, new TGeoTranslation(x, y, z));
491   x                          =  fC.X();
492   y                          =  fC.Y() - fLegOffset - fLegRadius - off;
493   frontVolume->AddNode(longLegVolume, 1, new TGeoTranslation(x,y,z));
494   y                          =  -y;
495   frontVolume->AddNode(longLegVolume, 2, new TGeoTranslation(x,y,z));
496
497   // Make a back volume 
498   TGeoVolume* backVolume     =  new TGeoVolumeAssembly("FIBV");
499   z                          =  fPrintboardThickness / 2;
500   backVolume->AddNode(pcbVolume, 0, new TGeoTranslation(0, 0, z));
501   z                          += (fPrintboardThickness + fCopperThickness) / 2;
502   backVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, z));
503   z                          += (fCopperThickness + fChipThickness) / 2;
504   backVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, z));
505   z                          += (fChipThickness + fLegLength) / 2;
506   x                          =  fA.X() + fLegOffset + fLegRadius;
507   y                          =  0;
508   backVolume->AddNode(shortLegVolume, 0, new TGeoTranslation(x, y, z));
509   x                          =  fC.X();
510   y                          =  fC.Y() - fLegOffset - fLegRadius - off;
511   backVolume->AddNode(shortLegVolume, 1, new TGeoTranslation(x,y,z));
512   y                          =  -y;
513   backVolume->AddNode(shortLegVolume, 2, new TGeoTranslation(x,y,z));
514
515 #if 1
516   TGeoVolume* ringTopVolume  = new TGeoVolumeAssembly("FITV");
517   TGeoVolume* ringBotVolume  = new TGeoVolumeAssembly("FIBV");
518   Double_t dz = 0;
519 #else
520   Double_t dz = (fSiThickness + fSpacer + fModuleSpacing + 
521                  fPrintboardThickness + fCopperThickness + 
522                  fChipThickness + fLegLength);
523   TGeoTubeSeg* topRingShape = new TGeoTubeSeg(fA.X(), rmax, dz/2, 0, 180);
524   TGeoTubeSeg* botRingShape = new TGeoTubeSeg(fA.X(), rmax, dz/2, 180, 360);
525   TGeoVolume* ringTopVolume = new TGeoVolume("FITV", topRingShape, fAir);
526   TGeoVolume* ringBotVolume = new TGeoVolume("FIBV", botRingShape, fAir);
527 #endif
528
529   TGeoVolume* half = ringTopVolume;
530   // Place in mother 
531   for (Int_t i = 0; i < 10; i++) {
532     if (i > 4)  half  = ringBotVolume;
533     Bool_t      front = ((i % 2) == 0);
534     z                 =  -dz/2 + fSiThickness / 2 + (i % 2) * fModuleSpacing;
535     TGeoMatrix* m1    = new TGeoCombiTrans(0,0,z,0);
536     m1->RotateZ((2 * i + 1) * fTheta);
537     half->AddNode(sensorVolume, i, m1);
538     TGeoVolume* vol   = (front ? frontVolume : backVolume);
539     z                 += fSpacer + fSiThickness / 2;
540     TGeoMatrix* m2    = new TGeoCombiTrans(0,0,z,0);
541     m2->RotateZ((2 * i + 1) * fTheta);
542     half->AddNode(vol, i, m2);    
543   }
544
545   TGeoVolume* fmdTopVolume  = new TGeoVolumeAssembly("FMT1");
546   TGeoVolume* fmdBotVolume  = new TGeoVolumeAssembly("FMB1");
547   fmdTopVolume->AddNode(ringTopVolume, 0, new TGeoTranslation(0,0,dz/2));
548   fmdBotVolume->AddNode(ringBotVolume, 0, new TGeoTranslation(0,0,dz/2));
549   
550   // Top of Honeycomb
551   TGeoTubeSeg* hcShape       = new TGeoTubeSeg(fLowR, fHighR,
552                                                fHoneycombThickness / 2,
553                                                0, 180);
554   TGeoVolume*  hcVolume      = new TGeoVolume("F1II", hcShape, fAl);
555   hcVolume->VisibleDaughters(kFALSE);
556   hcVolume->SetLineColor(5);
557   // Air in top of honeycomb
558   TGeoTubeSeg* ihcShape      = new TGeoTubeSeg(fLowR + fAlThickness, 
559                                                fHighR - fAlThickness, 
560                                                (fHoneycombThickness 
561                                                 - fAlThickness) / 2,
562                                                0, 180);
563   TGeoVolume*  ihcVolume     = new TGeoVolume("F1IK", ihcShape, fKapton);
564   hcVolume->AddNode(ihcVolume, 0);
565
566   // Add honey comb to mothers. 
567   z = (fSiThickness + fSpacer + fPrintboardThickness + fCopperThickness
568        + fChipThickness + fModuleSpacing + fLegLength + fHoneycombThickness/2);
569   fmdTopVolume->AddNode(hcVolume, 0, new TGeoTranslation(0,0,z));
570   TGeoMatrix* r = new TGeoCombiTrans(0,0,z, 0); r->RotateZ(180);
571   fmdBotVolume->AddNode(hcVolume, 1, r);
572
573   z = 0;
574   caveVolume->AddNode(fmdTopVolume, 1, new TGeoTranslation(0,0,z));
575   caveVolume->AddNode(fmdBotVolume, 1, new TGeoTranslation(0,0,z));
576 }
577
578 //____________________________________________________________________
579 void
580 Geometry::Register()
581 {
582   // Framework::Task::Register(option);
583   TGeoShape* caveShape = new TGeoBBox(fHighR+10, fHighR+10, fHighR+10);
584   TGeoVolume* caveVolume = new TGeoVolume("Cave", caveShape, fVacuum);
585   gGeoManager->SetTopVolume(caveVolume);
586
587   if (!gGeoManager->GetVolume("FM1T")) MakeDetailed(caveVolume);
588   gGeoManager->CloseGeometry();
589 }
590
591 //____________________________________________________________________
592 void
593 Geometry::Align()
594 {
595   if (!gGeoManager)                 return;
596   if (!gGeoManager->GetTopVolume()) return;
597   if (!gGeoManager->IsClosed())     return;
598   
599   if (!fMatricies) fMatricies = new TObjArray;
600   TGeoIterator next(gGeoManager->GetTopVolume());
601   TGeoNode* node = 0;
602
603   while ((node = static_cast<TGeoNode*>(next()))) {
604     // node->Print();
605     if (node->GetName()[0] == 'F' && node->GetName()[2] == 'S' && 
606         node->GetName()[3] == 'E') {
607       // We go an FMD module 
608       TString path("/");
609       path.Append(gGeoManager->GetNode(0)->GetName());
610       Int_t nlevel = next.GetLevel();
611       Debug(10, "Exec", "Level is %d", nlevel);
612       for (int lvl = 0; lvl <= nlevel; lvl++) {
613         TGeoNode* p = next.GetNode(lvl);
614         if (!p) continue;
615         Debug(10, "Exec", "Adding '%s' to path '%s'",
616               p->GetName(), path.Data());
617         if (!path.IsNull()) path.Append("/");
618         path.Append(p->GetName());
619       }
620       TGeoPhysicalNode* pnode = gGeoManager->MakePhysicalNode(path.Data());
621       TGeoHMatrix* matrix = new TGeoHMatrix(*node->GetMatrix());
622       TGeoRotation pertub;
623       Double_t angles[] = { gRandom->Uniform(0, 3), 
624                             gRandom->Uniform(0, 3), 
625                             gRandom->Uniform(0, 3) };
626       pertub.RotateX(angles[0]);
627       pertub.RotateY(angles[1]);
628       pertub.RotateZ(angles[1]);
629       *matrix *= pertub;
630       Debug(5, "Exec", "Aliging %s (%f,%f,%f)",
631             pnode->GetName(), angles[0], angles[1], angles[2]);
632       pnode->Align(matrix);
633     }
634   }
635 }
636
637 //____________________________________________________________________
638 //
639 // EOF
640 //
641
642