AliRoot Core  3dc7879 (3dc7879)
AliFMDGeometryBuilder.cxx
Go to the documentation of this file.
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$ */
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 //____________________________________________________________________
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 //____________________________________________________________________
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*
155  Double_t thick) const
156 {
157  //
158  // Make a polygonic extrusion shape based on verticies passed in @a
159  // verticies
160  //
161  // Parameters:
162  // verticies List of verticies
163  // thick Thickness
164  //
165  // Return:
166  // newly allocated polygonic extrusion shape
167  //
168  TArrayD xs(6);
169  TArrayD ys(6);
170  for (Int_t i = 0; i < 3; i++) {
171  TVector2* v = static_cast<TVector2*>(verticies.At(i+1));
172  xs[i] = v->Y();
173  ys[i] = -v->X();
174  xs[6-1-i] = v->Y();
175  ys[6-1-i] = v->X();
176  }
177  TGeoXtru* shape = new TGeoXtru(2);
178  shape->DefinePolygon(xs.fN, xs.fArray, ys.fArray);
179  shape->DefineSection(0, -thick/2);
180  shape->DefineSection(1, +thick/2);
181 
182  return shape;
183 }
184 
185 //____________________________________________________________________
186 TGeoVolume*
188 {
189  // Setup the geometry of a ring. The defined TGeoVolume is
190  // returned, and should be used when setting up the rest of the
191  // volumes.
192  //
193  //
194  // Parameters:
195  //
196  // r Pointer to ring geometry object
197  //
198  // Returns:
199  // pointer to ring volume
200  //
201  if (!r) {
202  AliError("Didn't get a ring object");
203  return 0;
204  }
205  Char_t id = r->GetId();
206  Char_t rng = toupper(id);
207  const Char_t* lName = (rng == 'I' ? "inner" : "outer");
208  Double_t siThick = r->GetSiThickness();
209  Double_t pcbThick = r->GetPrintboardThickness();
210  Double_t cuThick = r->GetCopperThickness();
211  Double_t chipThick= r->GetChipThickness();
212  Double_t modSpace = r->GetModuleSpacing();
213  Double_t theta = r->GetTheta();
214 
215  //------------------------------------------------------------------
216  // Sensor
217  // Physical sensor
218  TGeoShape* sensorShape = MakeXTRU(r->GetSensorVerticies(), siThick);
219  sensorShape->SetName(Form("FMD%c_physical_sensor", id));
220  sensorShape->SetTitle(Form("FMD %s physical sensor", lName));
221  TString sensorName = TString::Format(fgkSensorName, id);
222  TGeoVolume* sensorVolume = new TGeoVolume(sensorName, sensorShape, fSi);
223  sensorVolume->SetTitle(Form("FMD %s Sensor", lName));
224  sensorVolume->VisibleDaughters(kFALSE);
225  Int_t sid = sensorVolume->GetNumber();
226 
227  fSectorOff = -1;
228  fModuleOff = 1;
229  fRingOff = 2;
230  fDetectorOff = 3;
231  if (fDetailed) {
232  fSectorOff = 1;
233  fModuleOff = 4;
234  fRingOff = 5;
235  fDetectorOff = 6;
236  // Virtual volume shape to divide - This volume is only defined if
237  // the geometry is set to be detailed.
238  TGeoTubeSeg* activeShape = new TGeoTubeSeg(r->GetLowR(),
239  r->GetHighR(),
240  siThick / 2,
241  - theta,
242  + theta);
243  activeShape->SetName(Form(fgkActiveName, id));
244  activeShape->SetTitle(Form("FMD %s active area", lName));
245  TString activeName = TString::Format(fgkActiveName, id);
246  TGeoVolume* activeVolume = new TGeoVolume(activeName,activeShape,fSi);
247  activeVolume->SetTitle(Form("FMD %s active area", lName));
248  TString sectorName = TString::Format(fgkSectorName,id);
249  TGeoVolume* sectorVolume = activeVolume->Divide(sectorName, 2, 2, -theta,
250  0,0,"N");
251 
252  Int_t ns = r->GetNStrips();
253  Double_t stripoff = r->GetLowR(); // 0; // a->Mod();
254  Double_t dstrip = (r->GetHighR() - stripoff) / ns;
255 
256  sectorVolume->SetTitle(Form("FMD %s sector", lName));
257  TString stripName = TString::Format(fgkStripName, id);
258  TGeoVolume* stripVolume = sectorVolume->Divide(stripName,
259  1, ns, stripoff, dstrip,
260  0, "SX");
261  stripVolume->SetTitle(Form("FMD %s strip", lName));
262  sid = stripVolume->GetNumber();
263  sensorVolume->AddNodeOverlap(activeVolume, 0);
264  }
265 
266  switch (rng) {
267  case 'I': fActiveId[0] = sid; break;
268  case 'O': fActiveId[1] = sid; break;
269  }
270 
271  //------------------------------------------------------------------
272  // Hybrid
273  // PCB layer of hybrid
274  TGeoShape* pcbShape = MakeXTRU(r->GetHybridVerticies(), pcbThick);
275  pcbShape->SetName(Form("FMD%c_hybrid_pcb", id));
276  pcbShape->SetTitle(Form("FMD %s hybrid PCB", lName));
277  TString pcbName = TString::Format(fgkPCBName, id);
278  TGeoVolume* pcbVolume = new TGeoVolume(pcbName, pcbShape, fPCB);
279  pcbVolume->SetTitle(Form("FMD %s hybrid PCB", lName));
280 
281  // Copper layer
282  TGeoShape* cuShape = MakeXTRU(r->GetHybridVerticies(), cuThick);
283  cuShape->SetName(Form("FMD%c_hybrid_copper", id));
284  cuShape->SetTitle(Form("FMD %s hybrid copper", lName));
285  TString cuName = TString::Format(fgkCuName,id);
286  TGeoVolume* cuVolume = new TGeoVolume(cuName,cuShape,fCopper);
287  cuVolume->SetTitle(Form("FMD %s hybrid copper", lName));
288 
289  // Chip layer
290  TGeoShape* chipShape = MakeXTRU(r->GetHybridVerticies(), chipThick);
291  chipShape->SetName(Form("FMD%c_hybrid_chip", id));
292  chipShape->SetTitle(Form("FMD %s hybrid chip", lName));
293  TString chipName = TString::Format(fgkChipName,id);
294  TGeoVolume* chipVolume = new TGeoVolume(chipName,chipShape,fChip);
295  chipVolume->SetTitle(Form("FMD %s hybrid chip", lName));
296 
297  //------------------------------------------------------------------
298  // Legs
299  Double_t legr = r->GetLegRadius();
300  Double_t legl = r->GetLegLength();
301  Double_t lege = .05;
302 
303  // Short leg shape
304  TGeoTube* shortLegShape = new TGeoTube(0, legr, (legl-lege) / 2);
305  shortLegShape->SetName(Form(fgkShortLegName, id));
306  shortLegShape->SetTitle(Form("FMD %s short support foot", lName));
307  TString shortLegName = TString::Format(fgkShortLegName, id);
308  TGeoVolume* shortLegVolume = new TGeoVolume(shortLegName,
309  shortLegShape, fCopper);
310  shortLegVolume->SetTitle(Form("FMD %s short support foot", lName));
311  // Long leg shape
312  TGeoTube* longLegShape = new TGeoTube(0, legr,
313  (legl - lege + modSpace) / 2);
314  longLegShape->SetName(Form(fgkLongLegName, id));
315  longLegShape->SetTitle(Form("FMD %s long support foot", lName));
316  TString longLegName = TString::Format(fgkLongLegName, id);
317  TGeoVolume* longLegVolume = new TGeoVolume(longLegName,
318  longLegShape, fCopper);
319  longLegVolume->SetTitle(Form("FMD %s long support foot", lName));
320 
321 
322 
323  //------------------------------------------------------------------
324  // Placement of module volumes in assemblies
325  TArrayD xfs(3);
326  TArrayD yfs(3);
327  for (Int_t i = 0; i < 3; i++) {
328  TVector2* vv = r->GetFootPosition(i);
329  // TVector2 uu = vv->Rotate(TMath::Pi()/2);
330  xfs[i] = vv->Y();
331  yfs[i] = vv->X();
332  }
333 
334  // Back container volume
335  TGeoVolume* backVolume = new TGeoVolumeAssembly(Form(fgkBackVName, id));
336  backVolume->SetTitle(Form("FMD %s back module", lName));
337  TGeoVolume* frontVolume = new TGeoVolumeAssembly(Form(fgkFrontVName, id));
338  frontVolume->SetTitle(Form("FMD %s front module", lName));
339 
340  Double_t space = r->GetSpacing();
341  Double_t x = 0;
342  Double_t y = 0;
343  Double_t zb = siThick / 2;
344  Double_t zf = siThick / 2;
345  backVolume->AddNode(sensorVolume, 0, new TGeoTranslation(x, y, zb));
346  frontVolume->AddNode(sensorVolume, 0, new TGeoTranslation(x, y, zf));
347  zb += siThick / 2 + space + pcbThick / 2;
348  zf += siThick / 2 + space + pcbThick / 2;
349  backVolume->AddNode(pcbVolume, 0, new TGeoTranslation(x, y, zb));
350  frontVolume->AddNode(pcbVolume, 0, new TGeoTranslation(x, y, zf));
351  zb += (pcbThick + cuThick) / 2;
352  zf += (pcbThick + cuThick) / 2;
353  backVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, zf));
354  frontVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, zb));
355  zb += (cuThick + chipThick) / 2;
356  zf += (cuThick + chipThick) / 2;
357  backVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, zb));
358  frontVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, zf));
359  zb += pcbThick / 2 + (legl)/ 2 - lege;
360  zf += pcbThick / 2 + (legl + modSpace)/ 2 - lege;
361  for (Int_t i = 0; i < 3; i++) {
362  x = xfs[i]; // a->X() + legoff + legr;
363  y = yfs[i]; // 0;
364  backVolume->AddNode(shortLegVolume, i, new TGeoTranslation(x,y,zb));
365  frontVolume->AddNode(longLegVolume, i, new TGeoTranslation(x,y,zf));
366  }
367 
368  //------------------------------------------------------------------
369  // FMDD
370  Double_t ddlr = r->GetFMDDLowR();
371  Double_t ddhr = r->GetFMDDHighR();
372  Double_t ddpt = r->GetFMDDPrintboardThickness();
373  Double_t ddct = r->GetFMDDCopperThickness();
374  Double_t ddit = r->GetFMDDChipThickness();
375  Double_t ddt = ddpt + ddct + ddit;
376 
377  TString pcbdName(Form(fgkFMDDPCBName, id));
378  TString cudName(Form(fgkFMDDCuName, id));
379  TString chipdName(Form(fgkFMDDChipName, id));
380  new TGeoTubeSeg(Form("%s_inner", pcbdName.Data()), ddlr, ddhr, ddpt/2,0,180);
381  new TGeoTubeSeg(Form("%s_inner", cudName.Data()), ddlr, ddhr, ddct/2,0,180);
382  new TGeoTubeSeg(Form("%s_inner", chipdName.Data()), ddlr, ddhr, ddit/2,0,180);
383 
384  Double_t clipWX = 0;
385  Double_t clipWY = 0;
386  Double_t clipY = 1;
387 
388  if (rng == 'I') {
389  clipWX = ddhr;
390  clipWY = ddhr/2;
391  }
392  else {
393  clipWX = ddlr+3;
394  clipWY = ddhr/2;
395  }
396 
397  new TGeoBBox(Form("%s_clip", pcbdName.Data()), clipWX, clipWY, ddpt);
398  new TGeoBBox(Form("%s_clip", cudName.Data()), clipWX, clipWY, ddct);
399  new TGeoBBox(Form("%s_clip", chipdName.Data()),clipWX, clipWY, ddit);
400  TGeoTranslation* trans = new TGeoTranslation(Form("%s_trans",
401  pcbdName.Data()),
402  0, clipWY+clipY, 0);
403  trans->RegisterYourself();
404  TGeoShape* fmddPcbShape =
405  new TGeoCompositeShape(pcbdName.Data(),
406  Form("%s_inner*%s_clip:%s_trans",
407  pcbdName.Data(),
408  pcbdName.Data(),
409  pcbdName.Data()));
410  TGeoShape* fmddCuShape =
411  new TGeoCompositeShape(cudName.Data(),
412  Form("%s_inner*%s_clip:%s_trans",
413  cudName.Data(),
414  cudName.Data(),
415  pcbdName.Data()));
416  TGeoShape* fmddChipShape =
417  new TGeoCompositeShape(chipdName.Data(),
418  Form("%s_inner*%s_clip:%s_trans",
419  chipdName.Data(),
420  chipdName.Data(),
421  pcbdName.Data()));
422  fmddPcbShape->SetTitle(Form("FMD %s digitiser PCB", lName));
423  fmddCuShape->SetTitle(Form("FMD %s digitiser copper", lName));
424  fmddChipShape->SetTitle(Form("FMD %s digitiser chip", lName));
425 
426  TString fmddPcbName = TString::Format(fgkFMDDPCBName, id);
427  TGeoVolume* fmddPcbVolume = new TGeoVolume(fmddPcbName,
428  fmddPcbShape, fPCB);
429  TString fmddCuName = TString::Format(fgkFMDDCuName, id);
430  TGeoVolume* fmddCuVolume = new TGeoVolume(fmddCuName,
431  fmddCuShape, fCopper);
432  TString fmddChipName = TString::Format(fgkFMDDChipName, id);
433  TGeoVolume* fmddChipVolume = new TGeoVolume(fmddChipName,
434  fmddChipShape, fChip);
435  fmddPcbVolume->SetTitle(Form("FMD %s digitiser PCB", lName));
436  fmddCuVolume->SetTitle(Form("FMD %s digitiser copper", lName));
437  fmddChipVolume->SetTitle(Form("FMD %s digitiser chip", lName));
438 
439  //------------------------------------------------------------------
440  // Half ring mother volumes.
441  TGeoVolume* ringTopVolume = new TGeoVolumeAssembly(Form(fgkRingTopName,id));
442  TGeoVolume* ringBotVolume = new TGeoVolumeAssembly(Form(fgkRingBotName,id));
443  TGeoVolume* halfRing = ringTopVolume;
444  ringTopVolume->SetTitle(Form("FMD %s top half-ring", lName));
445  ringBotVolume->SetTitle(Form("FMD %s bottom half-ring", lName));
446 
447  //------------------------------------------------------------------
448  // Adding modules to half-rings
449  Int_t nmod = r->GetNModules();
450  AliFMDDebug(10, ("making %d modules in ring %c", nmod, id));
451  for (Int_t i = 0; i < nmod; i++) {
452  if (i == nmod / 2) halfRing = ringBotVolume;
453  Bool_t front = (i % 2 == (rng == 'I' ? 1 : 0));
454  TGeoVolume* vol = (front ? frontVolume : backVolume);
455  // vol->AddNode(sensorVolume, i, new TGeoTranslation(0,0,siThick/2));
456  Double_t z1 = (front ? -1 : 1) * modSpace / 2;
457  // Double_t z1 = (front ? 0 : modSpace);
458  Double_t th = (2 * i + 1) * theta;
459  TGeoMatrix* mat1 = new TGeoCombiTrans(0,0,z1,0);
460  mat1->RotateZ(th);
461  mat1->SetName(Form("FMD%c_module_%02d", id, i));
462  mat1->SetTitle(Form("FMD %s module %2d matrix", lName, i));
463  halfRing->AddNode(vol, i, mat1);
464  }
465 
466  //------------------------------------------------------------------
467  // Add the FMDD
468  Double_t zi = r->GetFullDepth() - ddt;
469  Int_t n = 2;
470  for (Int_t i = 0; i < n; i++) {
471  halfRing = (i == 0 ? ringTopVolume : ringBotVolume);
472  Double_t phi = 360. / n * i;
473  TGeoRotation* rot = new TGeoRotation(Form("FMDD%c rotation %d", id, i));
474  rot->RotateZ(phi);
475  rot->SetTitle(Form("FMD %s digitiser rotation %2d", lName, i));
476  Double_t z = zi + ddpt / 2;
477  halfRing->AddNode(fmddPcbVolume, i, new TGeoCombiTrans(0,0,z,rot));
478  z += (ddpt + ddct) / 2;
479  halfRing->AddNode(fmddCuVolume, i, new TGeoCombiTrans(0,0,z,rot));
480  z += (ddct + ddit) / 2;
481  halfRing->AddNode(fmddChipVolume, i, new TGeoCombiTrans(0,0,z,rot));
482  }
483 
484 
485  return 0;
486 }
487 
488 
489 //____________________________________________________________________
490 TGeoShape*
492  double r1, double r2,
493  double w, double t, double c)
494 {
495  // Make a honey comb shape from passed parameters.
496  // Parameters:
497  // id Detector identifier (1,2, or 3)
498  // ring Ring identifier ('I' or 'O')
499  // r1 Inner radius
500  // r2 Outer radius
501  // w width
502  // t Thickness of material
503  // c Clearing from horizontal.
504  // Return
505  // Pointer to newly allocated composite shape.
506  TString form = Form("FMD%d%c_%%c_%%c", id, ring);
507  double a1 = TMath::ATan2(c, r1) * 180 / TMath::Pi();
508 
509  TString fn = Form(form.Data(),'F','1');
510  TString bn = Form(form.Data(),'B','1');
511  TString cn = Form(form.Data(),'C','O');
512  TString in = Form(form.Data(),'R','I');
513  TString on = Form(form.Data(),'R','O');
514  TString en = Form(form.Data(),'E','X');
515  double y = c;
516  double x = r1 * TMath::Cos(TMath::Pi()*a1/180);
517  new TGeoTubeSeg(fn.Data(),r1,r2,t/2,0,180);
518  new TGeoTubeSeg(bn.Data(),r1,r2,t/2,0,180);
519  new TGeoBBox(cn.Data(),(r2-r1)/2,t/2,w/2);
520  new TGeoTubeSeg(in.Data(),r1,r1+t,w/2,0,180);
521  new TGeoTubeSeg(on.Data(),r2-t,r2,w/2,0,180);
522  new TGeoBBox(en.Data(),r2+.005,c/2+.005,w/2+.005);
523 
524  TString ftn = Form(form.Data(),'F','T');
525  TString btn = Form(form.Data(),'F','B');
526  TString ltn = Form(form.Data(),'C','L');
527  TString rtn = Form(form.Data(),'C','R');
528  TString etn = Form(form.Data(),'E','X');
529  (new TGeoTranslation(ftn.Data(),0,0,+w/2-t/2))->RegisterYourself();
530  (new TGeoTranslation(btn.Data(),0,0,-w/2+t/2))->RegisterYourself();
531  (new TGeoTranslation(ltn.Data(),-(x+(r2-r1)/2), y+t/2,0))->RegisterYourself();
532  (new TGeoTranslation(rtn.Data(),(x+(r2-r1)/2), y+t/2,0))->RegisterYourself();
533  (new TGeoTranslation(etn.Data(),0, c/2,0))->RegisterYourself();
534 
535  TString comp(Form("(%s:%s+%s:%s+%s+%s+%s:%s+%s:%s)-%s:%s",
536  fn.Data(),ftn.Data(),
537  bn.Data(),btn.Data(),
538  in.Data(),on.Data(),
539  cn.Data(),ltn.Data(),
540  cn.Data(),rtn.Data(),
541  en.Data(),etn.Data()));
542  TGeoCompositeShape* shape = new TGeoCompositeShape(comp.Data());
543  shape->SetName(Form(fgkHCName,id,ring));
544  shape->SetTitle(Form("FMD%d%c Honeycomb shape", id, ring));
545  return shape;
546 }
547 
548 //____________________________________________________________________
549 TGeoVolume*
551 {
552  //
553  // Get the tension box volume
554  //
555  //
556  // Return:
557  //
558  //
559  static TGeoVolumeAssembly* tensionBox = 0;
560  if (tensionBox) return tensionBox;
561 
562  TGeoBBox* tensionEndS = new TGeoBBox("FMD_tension_end", .6, 3, .25);
563  TGeoBBox* tensionTopS = new TGeoBBox("FMD_tension_top", .1, .5, 3.5);
564  TGeoVolume* tensionEndV = new TGeoVolume("FMD_tension_end", tensionEndS,fAl);
565  TGeoVolume* tensionTopV = new TGeoVolume("FMD_tension_top", tensionTopS,fAl);
566  tensionBox = new TGeoVolumeAssembly("FMD_tension_box");
567  tensionBox->AddNode(tensionEndV, 1, new TGeoTranslation(.6, 0, -3.75));
568  tensionBox->AddNode(tensionEndV, 2, new TGeoTranslation(.6, 0, +3.75));
569  tensionBox->AddNode(tensionTopV, 1, new TGeoTranslation(0.1, +2.5, 0));
570  tensionBox->AddNode(tensionTopV, 2, new TGeoTranslation(0.1, -2.5, 0));
571  tensionBox->AddNode(tensionTopV, 3, new TGeoTranslation(1.1, +2.5, 0));
572  tensionBox->AddNode(tensionTopV, 4, new TGeoTranslation(1.1, -2.5, 0));
573  return tensionBox;
574 }
575 
576 
577 //____________________________________________________________________
578 TGeoVolume*
580  TGeoVolume* topMother,
581  TGeoVolume* botMother,
582  Double_t zMother,
583  TGeoVolume* innerTop,
584  TGeoVolume* innerBot,
585  TGeoVolume* outerTop,
586  TGeoVolume* outerBot)
587 {
588  // Common stuff for setting up the FMD1, FMD2, and FMD3 geometries.
589  // This includes putting the Honeycomb support plates and the rings
590  // into the mother volumes.
591  //
592  // Parameeters:
593  // d The detector geometry to use
594  // mother The mother volume of the detector
595  // zmother The midpoint in global coordinates of detector vol.
596  // inner Pointer to inner ring volume
597  // outer Pointer to outer ring volume
598  //
599  // Returns:
600  // Pointer to mother (detector volume)
601  //
602  if (!d) return 0;
603  // Loop over the defined rings
604  for (int i = 0; i < 2; i++) {
605  AliFMDRing* r = 0;
606  Double_t lowr = 0;
607  Double_t highr = 0;
608  Double_t rz = 0;
609  TGeoVolume* tvol = 0;
610  TGeoVolume* bvol = 0;
611  switch (i) {
612  case 0:
613  r = d->GetInner();
614  lowr = d->GetInnerHoneyLowR();
615  highr = d->GetInnerHoneyHighR();
616  rz = d->GetInnerZ();
617  tvol = innerTop;
618  bvol = innerBot;
619  break;
620  case 1:
621  r = d->GetOuter();
622  lowr = d->GetOuterHoneyLowR();
623  highr = d->GetOuterHoneyHighR();
624  rz = d->GetOuterZ();
625  tvol = outerTop;
626  bvol = outerBot;
627  break;
628  }
629  if (!r) continue;
630  Char_t c = r->GetId();
631  Int_t id = d->GetId();
632  Double_t hcThick = r->GetHoneycombThickness();
633  Double_t alThick = r->GetAlThickness();
634  Double_t z = TMath::Abs(rz - zMother);
635 
636  // Place ring in mother volume
637  // TGeoMatrix*matrix=new TGeoTranslation(Form("FMD%d%c trans",id,c),0,0,0);
638  AliFMDDebug(2, ("Placing volumes %s and %s in %s and %s at z=%f",
639  tvol->GetName(), bvol->GetName(),
640  topMother->GetName(), botMother->GetName(), z));
641  topMother->AddNode(tvol, Int_t(c), new TGeoTranslation(0,0,z));
642  botMother->AddNode(bvol, Int_t(c), new TGeoTranslation(0,0,z));
643 
644  // Honeycomp
645  TGeoShape* hcSha = HoneycombShape(id, c, lowr, highr, hcThick, alThick);
646  TGeoVolume* hcVol = new TGeoVolume(Form(fgkHCName,id,c),hcSha,fAl);
647  hcVol->SetTitle(Form("FMD%d%c honeycomb shell", id, c));
648 
649  z += (r->GetModuleDepth()
650  + r->GetModuleSpacing() / 2
651  + r->GetHoneycombThickness() / 2);
652 
653  AliFMDDebug(15, ("Placing a copy of %s in %s and %s at z=%f",
654  hcVol->GetName(), topMother->GetName(),
655  botMother->GetName(), z));
656  // Add to top
657  topMother->AddNode(hcVol, 0, new TGeoTranslation(0, 0, z));
658 
659  // Add to bottom
660  TGeoMatrix* bhcMatrix = new TGeoCombiTrans(0,0,z,0);
661  bhcMatrix->SetName(Form("FMD%d%c_honeycomp", id, c));
662  bhcMatrix->SetTitle(Form("FMD%d%c honeycomp", id, c));
663  bhcMatrix->RotateZ(180);
664  botMother->AddNode(hcVol, 1, bhcMatrix);
665  }
666  return 0;
667 }
668 
669 //____________________________________________________________________
670 TGeoVolume*
672  TGeoVolume* innerTop,
673  TGeoVolume* innerBot)
674 {
675  // Setup the FMD1 geometry. The FMD1 only has one ring, and no
676  // special support as it is at the momement.
677  //
678  // See also AliFMDGeometryBuilder::DetectorGeometry
679  //
680  if (!fmd1 || !innerTop || !innerBot) return 0;
681  AliFMDRing* r = fmd1->GetInner();
682  Double_t z = fmd1->GetInnerZ();
683 
684  // `Top' or `Outside' master volume
685  TString fmd1TopName = TString::Format(fgkFMDName, fmd1->GetId(), 'T');
686  TGeoVolume* fmd1TopVolume = new TGeoVolumeAssembly(fmd1TopName);
687  fmd1TopVolume->SetTitle("FMD1 top half");
688 
689  // `Bottom' or `Inside' master volume
690  TString fmd1BotName = TString::Format(fgkFMDName, fmd1->GetId(), 'B');
691  TGeoVolume* fmd1BotVolume = new TGeoVolumeAssembly(fmd1BotName);
692  fmd1BotVolume->SetTitle("FMD1 bottom half");
693 
694  // Basic detector geometry
695  DetectorGeometry(fmd1, fmd1TopVolume, fmd1BotVolume, z,
696  innerTop, innerBot, 0, 0);
697 
698  Double_t lidP[][3] = { { 0.00, 4.20, 20.95 },
699  { 0.15, 4.20, 20.95 },
700  { 0.15, 20.80, 20.95 },
701  { 3.00, 20.80, 20.95 },
702  { 3.00, 20.80, 22.30 },
703  { 3.15, 20.80, 22.30 },
704  { 3.15, 20.95, 24.65 },
705  { 3.30, 20.95, 24.65 },
706  { 3.30, 24.50, 24.65 },
707  { 6.80, 24.50, 24.65 },
708  { 6.80, 24.50, 26.00 },
709  { 6.95, 24.50, 26.00 } };
710  Double_t lidZStart = lidP[11][0];
711  TGeoPcon* lidBaseS = new TGeoPcon("FMD1_lid_base", 0, 180, 12);
712  for (size_t i = 0; i < 12; i++)
713  lidBaseS->DefineSection(i, lidP[i][0] - lidZStart, lidP[i][1], lidP[i][2]);
714 
715 
716  Double_t lidH[][2] = { { 7.84903, 24.15680 },
717  { 20.54900, 14.92970 },
718  { 21.99700, 12.70000 },
719  { 25.26090, 2.65502 } };
720  Double_t lidHR = .53 / 2;
721  Double_t lidHL = 0.16;
722 
723  new TGeoTube("FMD1_lid_hole", 0, lidHR, lidHL/2);
724  TString lidComp("FMD1_lid_base-(");
725  TGeoTranslation* trans = 0;
726  for (size_t i = 0; i < 4; i++) {
727  trans = new TGeoTranslation(-lidH[i][0], lidH[i][1], /*6.95*/-lidHL/2);
728  trans->SetName(Form("FMD1_lid_hole_mat%d", int(2*i+0)));
729  trans->RegisterYourself();
730  trans = new TGeoTranslation(+lidH[i][0], lidH[i][1], /*6.95*/-lidHL/2);
731  trans->SetName(Form("FMD1_lid_hole_mat%d", int(2*i+1)));
732  trans->RegisterYourself();
733  lidComp.Append(Form("FMD1_lid_hole:FMD1_lid_hole_mat%d+"
734  "FMD1_lid_hole:FMD1_lid_hole_mat%d%c",
735  int(2 * i), int(2 * i + 1), int(i == 3 ? ')' : '+')));
736  }
737  TGeoCompositeShape* lidS = new TGeoCompositeShape(lidComp.Data());
738  lidS->SetName("FMD1_lid");
739  TGeoVolume* lidV = new TGeoVolume("FMD1_lid", lidS, fC);
740  lidV->SetTransparency(63);
741 
742  // Place top cover
743  Double_t lidZ = (lidZStart -
744  (3.3 - r->GetModuleDepth() - r->GetModuleSpacing() / 2));
745  AliFMDDebug(1, ("FMD1 lid offset in Z=%f", lidZ));
746 
747  for (Int_t i = 0; i < 2; i++) {
748  TGeoVolume* mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
749  Double_t phi = 360. / 2 * i;
750  TGeoRotation* rot = new TGeoRotation(Form("FMD1_lid_rot%d",i));
751  rot->RotateZ(phi);
752  TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD1_lid_mat%d", i),
753  0, 0, lidZ, rot);
754  mother->AddNode(lidV, i, matrix);
755  }
756 
757  // Must add this after filling the assembly.
758  TGeoVolume* top = gGeoManager->GetVolume("ALIC");
759  // TGeoMatrix* matrix = new TGeoTranslation("FMD1 trans", 0, 0, z);
760  TGeoRotation* rot = new TGeoRotation("FMD1 rotatation");
761  rot->RotateZ(90);
762  TGeoMatrix* matrix = new TGeoCombiTrans("FMD1 trans", 0, 0, z, rot);
763 
764  AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
765  fmd1TopVolume->GetName(), fmd1BotVolume->GetName(), z));
766  top->AddNode(fmd1TopVolume, fmd1->GetId(), matrix);
767  top->AddNode(fmd1BotVolume, fmd1->GetId(), matrix);
768 
769 
770  // Survey points on V0A (screw holes for the FMD)
771  const Double_t icb[] = { +12.700, -21.997, 324.670 };
772  const Double_t ict[] = { +12.700, +21.997, 324.670 };
773  const Double_t ocb[] = { -12.700, -21.997, 324.670 };
774  const Double_t oct[] = { -12.700, +21.997, 324.670 };
775 
776  TGeoTube* surveyShape = new TGeoTube("FMD1_survey_marker",
777  0, .2, .001);
778 
779  TGeoMatrix* outMat = matrix;
780 #if 0
781  if (gGeoManager->cd("/ALIC_1/F1MT_1"))
782  outMat = gGeoManager->GetCurrentMatrix();
783  else
784  AliWarning("Couldn't cd to /ALIC_1/F1MT_1");
785 #endif
786 
787  Double_t loct[3], locb[3];
788  outMat->MasterToLocal(oct, loct);
789  outMat->MasterToLocal(ocb, locb);
790  TGeoVolume* vOct = new TGeoVolume("V0L_OCT", surveyShape, fPlastic);
791  TGeoVolume* vOcb = new TGeoVolume("V0L_OCB", surveyShape, fPlastic);
792 
793  fmd1TopVolume->AddNode(vOct, 1, new TGeoTranslation(loct[0],loct[1],loct[2]));
794  fmd1TopVolume->AddNode(vOcb, 1, new TGeoTranslation(locb[0],locb[1],locb[2]));
795 
796 
797  TGeoMatrix* inMat = matrix;
798 #if 0
799  if (gGeoManager->cd("/ALIC_1/F1MT_1"))
800  inMat = gGeoManager->GetCurrentMatrix();
801  else
802  AliWarning("Couldn't cd to /ALIC_1/F1MT_1");
803 #endif
804 
805  Double_t lict[3], licb[3];
806  inMat->MasterToLocal(ict, lict);
807  inMat->MasterToLocal(icb, licb);
808  TGeoVolume* vIct = new TGeoVolume("V0L_ICT", surveyShape, fPlastic);
809  TGeoVolume* vIcb = new TGeoVolume("V0L_ICB", surveyShape, fPlastic);
810 
811  fmd1BotVolume->AddNode(vIct, 1, new TGeoTranslation(lict[0],lict[1],lict[2]));
812  fmd1BotVolume->AddNode(vIcb, 1, new TGeoTranslation(licb[0],licb[1],licb[2]));
813 
814  return 0;
815 }
816 
817 //____________________________________________________________________
818 TGeoVolume*
820  TGeoVolume* innerTop,
821  TGeoVolume* innerBot,
822  TGeoVolume* outerTop,
823  TGeoVolume* outerBot)
824 {
825  // Setup the FMD2 geometry. The FMD2 has no
826  // special support as it is at the momement.
827  //
828  // See also AliFMDGeometryBuilder::DetectorGeometry
829  //
830  if (!fmd2 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
831  AliFMDRing* ring = fmd2->GetOuter();
832  Double_t z = fmd2->GetOuterZ();
833  Double_t framelr = 32.01; // fmd2->GetOuterHoneyHighR()+0.5;
834  Double_t framehr = 33.611; // fmd2->GetOuterHoneyHighR()+1.8;
835  Double_t framel = 14.8; // framehz - framelz;
836  // Double_t backth = 0.3;
837  Double_t backth = 0.03;
838  Double_t framelz = -(2.38
839  - ring->GetModuleDepth()
840  - ring->GetModuleSpacing() / 2);
841  // Double_t framelz = -0.8;
842  // Double_t framehz = framelz + backth + framel;
843  Double_t coverlr = 4.3; // fmd2->GetInner()->GetLowR()+1;
844  Double_t coverhr = framehr; // - 1;
845 
846  TString fmd2TopName = TString::Format(fgkFMDName, fmd2->GetId(), 'T');
847  TGeoVolume* fmd2TopVolume = new TGeoVolumeAssembly(fmd2TopName);
848  TString fmd2BotName = TString::Format(fgkFMDName, fmd2->GetId(), 'B');
849  TGeoVolume* fmd2BotVolume = new TGeoVolumeAssembly(fmd2BotName);
850  fmd2TopVolume->SetTitle("FMD2 top half");
851  fmd2BotVolume->SetTitle("FMD2 bottom half");
852 
853  DetectorGeometry(fmd2, fmd2TopVolume, fmd2BotVolume, z,
854  innerTop, innerBot, outerTop, outerBot);
855 
856  TGeoVolumeAssembly* support = new TGeoVolumeAssembly("FMD2_support");
857  TGeoShape* cylinderShape = new TGeoTubeSeg(framelr,framehr,framel/2,0,180);
858  TGeoVolume* cylinderVolume = new TGeoVolume(Form(fgkBackName, fmd2->GetId()),
859  cylinderShape, fC);
860  TGeoShape* coverShape = new TGeoTubeSeg(coverlr,coverhr,backth/2,0,180);
861  TGeoVolume* coverVolume = new TGeoVolume(Form(fgkTopName, fmd2->GetId()),
862  coverShape, fC);
863  cylinderShape->SetName(Form(fgkBackName, fmd2->GetId()));
864  cylinderShape->SetTitle("FMD2 cylinder");
865  cylinderVolume->SetTitle("FMD2 cylinder");
866  cylinderVolume->SetTransparency(63);
867  coverShape->SetName(Form(fgkTopName, fmd2->GetId()));
868  coverShape->SetTitle("FMD2 cover");
869  coverVolume->SetTitle("FMD2 cover");
870  coverVolume->SetTransparency(63);
871 
872  TGeoTranslation* trans = 0;
873  support->AddNode(coverVolume,1, new TGeoTranslation(0,0,backth/2));
874  support->AddNode(cylinderVolume, 1, new TGeoTranslation(0,0,backth+framel/2));
875 
876 
877  Double_t f1l = 15.6085;
878  Double_t f1w = 6;
879  Double_t f1d = 1;
880  Int_t nFiducialHoles = 4;
881  Double_t precHoles[][2] = { { 32.4948, 29.6663 },
882  { 33.9104, 31.0819 },
883  { 34.8177, 33.4035 },
884  { 35.5028, 32.6744 } };
885  Double_t precRadius = .25;
886  Double_t flangeA = TMath::Pi()/4;
887 
888  new TGeoBBox("FMD2_flange_base", f1l/2, f1w/2, f1d/2);
889  new TGeoTube("FMD2_fiducial_hole", 0, precRadius, f1d/2+.1);
890  Double_t flangeX = framehr + f1l/2;
891  TVector2 flangeC(flangeX * TMath::Cos(flangeA),
892  flangeX * TMath::Sin(flangeA));
893  TString flangeComb("FMD2_flange_base-(");
894  new TGeoBBox("FMD2_flange_slit", 7./2, 1.5/2, f1d/2+.1);
895  trans = new TGeoTranslation(-f1l/2+1+7./2, +.5+1.5/2, 0);
896  trans->SetName("FMD2_flange_slit_mat1");
897  trans->RegisterYourself();
898  trans = new TGeoTranslation(-f1l/2+1+7./2, -.5-1.5/2, 0);
899  trans->SetName("FMD2_flange_slit_mat2");
900  trans->RegisterYourself();
901  flangeComb.Append("FMD2_flange_slit:FMD2_flange_slit_mat1+"
902  "FMD2_flange_slit:FMD2_flange_slit_mat2+");
903  for (Int_t i = 0; i < nFiducialHoles; i++) {
904  TVector2 v(precHoles[i][0], precHoles[i][1]);
905  v -= flangeC;
906  TVector2 r = v.Rotate(-flangeA);
907  TGeoTranslation* t1 = new TGeoTranslation(r.X(), r.Y(), 0);
908  TGeoTranslation* t2 = new TGeoTranslation(r.X(), -r.Y(), 0);
909  t1->SetName(Form("FMD2_fiducial_hole_rot%d", 2*i+0));
910  t2->SetName(Form("FMD2_fiducial_hole_rot%d", 2*i+1));
911  t1->RegisterYourself();
912  t2->RegisterYourself();
913  flangeComb.Append(Form("FMD2_fiducial_hole:FMD2_fiducial_hole_rot%d+"
914  "FMD2_fiducial_hole:FMD2_fiducial_hole_rot%d%c",
915  2*i+0, 2*i+1, (i == nFiducialHoles-1 ? ')' : '+')));
916  }
917  // Final flange shape, and at to full shape
918  TGeoCompositeShape* flangeS = new TGeoCompositeShape(flangeComb.Data());
919  flangeS->SetName("FMD2_flange");
920  TGeoVolume* flangeV = new TGeoVolume("FMD2_flange", flangeS, fAl);
921 
922  Double_t f2l = 7;
923  Double_t f2d = 12.5;
924  Double_t f2w = 1;
925 
926  new TGeoBBox("FMD2_flange_spacer_base", f2l/2, f2w/2, f2d/2);
927  new TGeoTube("FMD2_flange_spacer_hole", 0, 2.5, f2w/2+.1);
928  TGeoRotation* holeRot = new TGeoRotation();
929  holeRot->RotateY(90);
930  holeRot->RotateZ(90);
931  TGeoCombiTrans* combo = 0;
932  combo = new TGeoCombiTrans(0, 0, f2d/2-.5-2.5, holeRot);
933  combo->SetName("FMD2_flange_spacer_hole_mat1");
934  combo->RegisterYourself();
935  combo = new TGeoCombiTrans(0, 0, -f2d/2+.5+2.5, holeRot);
936  combo->SetName("FMD2_flange_spacer_hole_mat2");
937  combo->RegisterYourself();
938  TString spacerComp("FMD2_flange_spacer_base-("
939  "FMD2_flange_spacer_hole:FMD2_flange_spacer_hole_mat1+"
940  "FMD2_flange_spacer_hole:FMD2_flange_spacer_hole_mat2)");
941  TGeoCompositeShape* spacerS = new TGeoCompositeShape(spacerComp.Data());
942  TGeoVolume* spacerV = new TGeoVolume("FMD2_flange_spacer",
943  spacerS, fAl);
944 
945  Double_t extraL = framehr-framelr;
946  TGeoBBox* extraS = new TGeoBBox("FMD2_flange_extra",
947  extraL/2, f1w/2, f1d/2);
948  TGeoVolume* extraV = new TGeoVolume("FMD2_flange_extra", extraS,fAl);
949  TGeoVolumeAssembly* wingV = new TGeoVolumeAssembly("FMD2_wing");
950  TGeoVolume* tension = TensionBox();
951  TGeoTube* wireS = new TGeoTube(0, .05, (framehr-coverlr)/2);
952  TGeoVolume* wireV = new TGeoVolume("FMD2_tension_wire",
953  wireS, fSteel);
954  wingV->AddNode(flangeV, 1, new TGeoTranslation(f1l/2, 0, f1d/2));
955  wingV->AddNode(flangeV, 2, new TGeoTranslation(f1l/2, 0, -f2d-f1d/2));
956  wingV->AddNode(extraV, 1, new TGeoCombiTrans(-extraL/2, 0, f1d/2, 0));
957  wingV->AddNode(spacerV, 1, new TGeoTranslation(1+f2l/2,-f2w/2+f1w/2,
958  -f2d/2));
959  wingV->AddNode(spacerV, 2, new TGeoTranslation(1+f2l/2,+f2w/2-f1w/2,
960  -f2d/2));
961  TGeoRotation* tensionR = new TGeoRotation;
962  tensionR->RotateY(90);
963  wingV->AddNode(tension, 1, new TGeoCombiTrans(4, 0, f1d+1.2, tensionR));
964  TGeoRotation* wireR = new TGeoRotation;
965  wireR->RotateY(90);
966  wingV->AddNode(wireV, 1, new TGeoCombiTrans(-(framehr-coverlr)/2, 0, f1d+1,
967  wireR));
968 
969  TGeoCombiTrans* extraM1 = new TGeoCombiTrans(coverhr-extraL/2,0,0,0);
970  extraM1->RotateZ(45);
971  extraM1->RegisterYourself();
972  extraM1->SetName("FMD2_back_cover_slit1");
973  TGeoCombiTrans* extraM2 = new TGeoCombiTrans(coverhr-extraL/2,0,0,0);
974  extraM2->RotateZ(135);
975  extraM2->RegisterYourself();
976  extraM2->SetName("FMD2_back_cover_slit2");
977  TString coverComp(Form(fgkTopName, fmd2->GetId()));
978  coverComp.Append("-(FMD2_flange_extra:FMD2_back_cover_slit1"
979  "+FMD2_flange_extra:FMD2_back_cover_slit2)");
980  TGeoCompositeShape* cover2Shape = new TGeoCompositeShape(coverComp.Data());
981  cover2Shape->SetName("FMD2_back_cover");
982  TGeoVolume* cover2Volume = new TGeoVolume("FMD2_back_cover", cover2Shape,fC);
983  support->AddNode(cover2Volume,2,
984  new TGeoTranslation(0,0,backth+framel+backth/2));
985 
986  TGeoCombiTrans* trans1 = new TGeoCombiTrans(framehr, 0, backth+framel, 0);
987  TGeoCombiTrans* trans2 = new TGeoCombiTrans(framehr, 0, backth+framel, 0);
988  trans1->RotateZ(45);
989  trans2->RotateZ(135);
990  support->AddNode(wingV, 1, trans1);
991  support->AddNode(wingV, 2, trans2);
992  AliFMDDebug(1, ("FMD2 support offset is %f", framelz));
993 
994  for (Int_t i = 0; i < 2; i++) {
995  TGeoVolume* mother = (i < 1 ? fmd2TopVolume : fmd2BotVolume);
996 
997  Double_t phi = 360. / 2 * i;
998  TGeoRotation* rot = new TGeoRotation(Form("FMD2 support rot %d",i));
999  rot->RotateZ(phi);
1000  TGeoMatrix* matrix = new TGeoCombiTrans(0, 0, framelz, rot);
1001  mother->AddNode(support, i, matrix);
1002  }
1003 
1004  // Must be done after filling the assemblies
1005  TGeoVolume* top = gGeoManager->GetVolume("ALIC");
1006  TGeoMatrix* matrix = new TGeoTranslation("FMD2 trans", 0, 0, z);
1007  AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
1008  fmd2TopVolume->GetName(), fmd2BotVolume->GetName(), z));
1009  top->AddNode(fmd2TopVolume, fmd2->GetId(), matrix);
1010  top->AddNode(fmd2BotVolume, fmd2->GetId(), matrix);
1011 
1012 
1013  return 0;
1014 }
1015 
1016 //____________________________________________________________________
1017 TGeoVolume*
1019  TGeoVolume* innerTop,
1020  TGeoVolume* innerBot,
1021  TGeoVolume* outerTop,
1022  TGeoVolume* outerBot)
1023 {
1024  // Setup the FMD3 geometry. The FMD2 has a rather elaborate support
1025  // structure, as the support will also support the vacuum
1026  // beam-pipe.
1027  //
1028  // See also AliFMDGeometryBuilder::DetectorGeometry
1029  //
1030  if (!fmd3 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
1031 
1032  //__________________________________________________________________
1033  // Basic detector set-up.
1034  TString fmd3TopName = TString::Format(fgkFMDName, fmd3->GetId(), 'T');
1035  TGeoVolume* fmd3TopVolume = new TGeoVolumeAssembly(fmd3TopName);
1036  TString fmd3BotName = TString::Format(fgkFMDName, fmd3->GetId(), 'B');
1037  TGeoVolume* fmd3BotVolume = new TGeoVolumeAssembly(fmd3BotName);
1038  fmd3TopVolume->SetTitle("FMD3 top half");
1039  fmd3BotVolume->SetTitle("FMD3 bottom half");
1040  DetectorGeometry(fmd3, fmd3TopVolume, fmd3BotVolume, fmd3->GetInnerZ(),
1041  innerTop, innerBot, outerTop, outerBot);
1042 
1043  //__________________________________________________________________
1044  // Mother for all support material
1045  TGeoVolumeAssembly* support = new TGeoVolumeAssembly("F3SU");
1046  support->SetTitle("FMD3 support");
1047 
1048  //__________________________________________________________________
1049  // Base of cone
1050  const TObjArray& radii = fmd3->ConeRadii();
1051  Int_t nRadii = radii.GetEntriesFast();
1052  TGeoPcon* coneBase = new TGeoPcon("FMD3_cone_base", 0., 180., nRadii);
1053  TVector3* r5 = 0;
1054  TVector3* r4 = 0;
1055  for (Int_t i = 0; i < nRadii; i++) {
1056  TVector3* v = static_cast<TVector3*>(radii.At(i));
1057  coneBase->DefineSection(i, v->X(), v->Y(), v->Z());
1058  if (i == 5) r5 = v;
1059  else if (i == 4) r4 = v;
1060  }
1061  TString coneComb("(FMD3_cone_base");
1062 
1063  //__________________________________________________________________
1064  // Flanges
1065  double flangeDepth = fmd3->GetFlangeDepth() / 2;
1066  double flangeLength = fmd3->GetFlangeLength() / 2;
1067  double flangeWidth = fmd3->GetFlangeWidth() / 2;
1068  new TGeoBBox("FMD3_flange_base", flangeLength, flangeWidth, flangeDepth);
1069 
1070  // Fiducial holes
1071  const TObjArray& fiducialHoles = fmd3->FiducialHoles();
1072  double fiducialRadius = fmd3->GetFiducialRadius();
1073 #if 0
1074  TGeoTube* fiducialShape =
1075 #endif
1076  new TGeoTube("FMD3_fiducial_hole", 0, fiducialRadius, flangeDepth+.1);
1077  Int_t nFiducialHoles = fiducialHoles.GetEntriesFast();
1078  double flangeAngle = TMath::Pi() / 4;
1079  double flangeX = r5->Y()+flangeLength;
1080  TVector2 flangeC(flangeX * TMath::Cos(flangeAngle),
1081  flangeX * TMath::Sin(flangeAngle));
1082  TString flangeComb("FMD3_flange_base-(");
1083 #if 0// For debugging geometry
1084  TGeoVolume* fiducialVolume = new TGeoVolume("FMD3_fiducial", fiducialShape);
1085  fiducialVolume->SetLineColor(kGreen);
1086 #endif
1087  for (Int_t i = 0; i < nFiducialHoles; i++) {
1088  TVector2& v = *(static_cast<TVector2*>(fiducialHoles.At(i)));
1089  v -= flangeC;
1090  TVector2 r = v.Rotate(-flangeAngle);
1091  TGeoTranslation* t1 = new TGeoTranslation(r.X(), r.Y(), 0);
1092  TGeoTranslation* t2 = new TGeoTranslation(r.X(), -r.Y(), 0);
1093  t1->SetName(Form("FMD3_fiducial_hole_rot%d", 2*i+0));
1094  t2->SetName(Form("FMD3_fiducial_hole_rot%d", 2*i+1));
1095  t1->RegisterYourself();
1096  t2->RegisterYourself();
1097  flangeComb.Append(Form("FMD3_fiducial_hole:FMD3_fiducial_hole_rot%d+"
1098  "FMD3_fiducial_hole:FMD3_fiducial_hole_rot%d%c",
1099  2*i+0, 2*i+1, (i == nFiducialHoles-1 ? ')' : '+')));
1100 #if 0 // For debugging geometry
1101  support->AddNode(fiducialVolume, 2*i+0, t1);
1102  support->AddNode(fiducialVolume, 2*i+1, t2);
1103 #endif
1104  }
1105 
1106  // Final flange shape, and at to full shape
1107  TGeoCompositeShape* flangeShape = new TGeoCompositeShape(flangeComb.Data());
1108  flangeShape->SetName("FMD3_flange");
1109  for (Int_t i = 0; i < 2; i++) {
1110  TGeoRotation* rot = new TGeoRotation();
1111  rot->RotateZ((i+.5)*90);
1112  TVector2 v(flangeX, 0);
1113  TVector2 w = v.Rotate((i+.5) * 2 * flangeAngle);
1114  TGeoCombiTrans* trans = new TGeoCombiTrans(w.X(),w.Y(),
1115  r4->X()+flangeDepth, rot);
1116  trans->SetName(Form("FMD3_flange_matrix%d", i));
1117  trans->RegisterYourself();
1118  coneComb.Append(Form("+FMD3_flange:FMD3_flange_matrix%d", i));
1119  }
1120  coneComb.Append(")-(");
1121 
1122  //__________________________________________________________________
1123  // Holes
1124  Double_t holeL = fmd3->GetHoleLength()/2;
1125  Double_t holeD = fmd3->GetHoleDepth()/2;
1126  Double_t holeLW = fmd3->GetHoleLowWidth()/2;
1127  Double_t holeHW = fmd3->GetHoleHighWidth()/2;
1128  Double_t holeA = fmd3->GetConeOuterAngle();
1129  Double_t holeA2 = TMath::Pi() - fmd3->GetConeOuterAngle();
1130  Double_t holeO = fmd3->GetHoleOffset();
1131  Double_t holeZ = (holeO
1132  + holeL * TMath::Cos(holeA)
1133  - holeD * TMath::Sin(holeA2));
1134  Double_t holeX = (fmd3->ConeR(-holeZ + fmd3->GetInnerZ() + fmd3->GetNoseZ())
1135  - holeD * TMath::Sin(holeA2));
1136  new TGeoTrd1("FMD3_cone_hole", holeLW, holeHW, holeD, holeL);
1137  TGeoTrd1* plateShape = new TGeoTrd1("FMD3_cooling_plate",
1138  holeLW, holeHW, .033, holeL);
1139  TGeoRotation* holeRot = new TGeoRotation();
1140  holeRot->SetName("FMD3_cone_hole_rotation");
1141  holeRot->RotateZ(90);
1142  holeRot->RotateY(holeA*180/TMath::Pi());
1143  TGeoCombiTrans* holeBaseTrans = new TGeoCombiTrans(holeX, 0, holeZ, holeRot);
1144  holeBaseTrans->SetName("FMD3_cone_hole_base_matrix");
1145  // TGeoRotation* plateRot = new TGeoRotation();
1146  // plateRot->SetName("FMD3_cone_plate_rotation");
1147  // plateRot->RotateZ(90);
1148  // plateRot->RotateY(plateA*180/TMath::Pi());
1149  // TGeoCombiTrans* plateBaseTrans = new
1150  // TGeoCombiTrans(plateX,0,plateZ,plateRot);
1151  TGeoVolume* plateVolume = new TGeoVolume("FMD3_cooling_plate",
1152  plateShape, fAl);
1153  plateShape->SetTitle("FMD3 cooling plate");
1154  plateVolume->SetTitle("FMD3 cooling plate");
1155  for (Int_t i = 0; i < 4; i++) {
1156  Double_t ang = 360. / 8 * (i + .5);
1157  TGeoCombiTrans* trans = new TGeoCombiTrans(*holeBaseTrans);
1158  trans->RotateZ(ang);
1159  trans->SetName(Form("FMD3_cone_hole_matrix%d", i));
1160  trans->RegisterYourself();
1161  trans = new TGeoCombiTrans(*holeBaseTrans);
1162  trans->RotateZ(ang);
1163  trans->SetName(Form("FMD3_cooling_plate_matrix%d", i));
1164  coneComb.Append(Form("FMD3_cone_hole:FMD3_cone_hole_matrix%d+", i));
1165  support->AddNode(plateVolume, i, trans);
1166  }
1167 
1168  //__________________________________________________________________
1169  // Bolts
1170  Double_t boltRadius = fmd3->GetBoltRadius();
1171  Double_t boltLength = fmd3->GetBoltLength() / 2;
1172  Double_t boltZ1 = fmd3->GetInnerZ()+fmd3->GetNoseZ()-10;
1173  Double_t boltZ2 = fmd3->GetInnerZ()+fmd3->GetNoseZ()-20;
1174  Double_t boltXE = 2*boltLength*TMath::Cos(fmd3->GetConeOuterAngle());
1175  Double_t boltX1 = (fmd3->ConeR(boltZ1) - boltXE);
1176  Double_t boltX2 = (fmd3->ConeR(boltZ2) - boltXE);
1177 
1178  new TGeoTube("FMD3_bolt_hole", 0, boltRadius, boltLength+.2);
1179  TGeoTube* boltShape = new TGeoTube("FMD3_bolt", 0, boltRadius, boltLength);
1180  TGeoRotation* boltRot = new TGeoRotation();
1181  boltRot->RotateY(-fmd3->GetConeOuterAngle()*180/TMath::Pi());
1182  TGeoCombiTrans* boltTrans1 = new TGeoCombiTrans(boltX1, 0, 10, boltRot);
1183  TGeoCombiTrans* boltTrans2 = new TGeoCombiTrans(boltX2, 0, 20, boltRot);
1184  TGeoCombiTrans* boltTrans3 = new TGeoCombiTrans(*boltTrans1);
1185  TGeoCombiTrans* boltTrans4 = new TGeoCombiTrans(*boltTrans2);
1186  boltTrans3->RotateZ(180);
1187  boltTrans4->RotateZ(180);
1188  boltTrans1->SetName("FMD3_bolt_matrix1");
1189  boltTrans2->SetName("FMD3_bolt_matrix2");
1190  boltTrans3->SetName("FMD3_bolt_matrix3");
1191  boltTrans4->SetName("FMD3_bolt_matrix4");
1192  boltTrans1->RegisterYourself();
1193  boltTrans2->RegisterYourself();
1194  boltTrans3->RegisterYourself();
1195  boltTrans4->RegisterYourself();
1196  coneComb.Append("FMD3_bolt_hole:FMD3_bolt_matrix1"
1197  "+FMD3_bolt_hole:FMD3_bolt_matrix2"
1198  "+FMD3_bolt_hole:FMD3_bolt_matrix3"
1199  "+FMD3_bolt_hole:FMD3_bolt_matrix4");
1200  TGeoVolume* boltVolume = new TGeoVolume("FMD3_bolt", boltShape, fSteel);
1201  support->AddNode(boltVolume, 1, boltTrans1);
1202  support->AddNode(boltVolume, 2, boltTrans2);
1203  boltShape->SetTitle("FMD3 steering bolt");
1204  boltVolume->SetTitle("FMD3 steering bolt");
1205 
1206  //__________________________________________________________________
1207  // Cut-outs for tension wheel sheeve
1208  new TGeoBBox("FMD3_sheeve_hole", .55, .75, 1.16);
1209  Double_t sheeveHoleZ = fmd3->GetInnerZ() + fmd3->GetNoseZ() - .75;
1210  Double_t sheeveHoleR = fmd3->ConeR(sheeveHoleZ) - .55 + .2572222;
1211  TGeoCombiTrans* sheeveMat1 = new TGeoCombiTrans(sheeveHoleR,0,1.15,0);
1212  TGeoCombiTrans* sheeveMat2 = new TGeoCombiTrans(sheeveHoleR,0,1.15,0);
1213  sheeveMat1->RotateZ(45);
1214  sheeveMat2->RotateZ(135);
1215  sheeveMat1->SetName("FMD3_sheeve_hole_matrix1");
1216  sheeveMat2->SetName("FMD3_sheeve_hole_matrix2");
1217  sheeveMat1->RegisterYourself();
1218  sheeveMat2->RegisterYourself();
1219  coneComb.Append("+FMD3_sheeve_hole:FMD3_sheeve_hole_matrix1"
1220  "+FMD3_sheeve_hole:FMD3_sheeve_hole_matrix2)");
1221 
1222  //__________________________________________________________________
1223  // Sheeve boxes
1224  Double_t sheeveL = 1.15;
1225  TGeoBBox* sheeveSideS = new TGeoBBox("FMD3_sheeve_side",
1226  .55, .25, 1.15);
1227  TGeoBBox* sheeveBackS = new TGeoBBox("FMD3_sheeve_back",
1228  .55, .25, .15);
1229  TGeoBBox* sheeveWingS = new TGeoBBox("FMD3_sheeve_wing",
1230  .15, .15, 1.15);
1231  TGeoPcon* sheeveWheelS = new TGeoPcon("FMD3_sheeve_wheel", 0, 360, 9);
1232  Double_t sheeveInnerR = 0; // .2;
1233  Double_t sheeveR = .875;
1234  Double_t sheeveWheelZ = .95;
1235  sheeveWheelS->DefineSection(0, -.25, sheeveInnerR, 1);
1236  sheeveWheelS->DefineSection(1, -.125, sheeveInnerR, 1);
1237  sheeveWheelS->DefineSection(2, -.125, sheeveInnerR, sheeveWheelZ);
1238  sheeveWheelS->DefineSection(3, -.0625, sheeveInnerR, sheeveR+.02);
1239  sheeveWheelS->DefineSection(4, 0.000, sheeveInnerR, sheeveR);
1240  sheeveWheelS->DefineSection(5, +.0625, sheeveInnerR, sheeveR+.02);
1241  sheeveWheelS->DefineSection(6, +.125, sheeveInnerR, sheeveWheelZ);
1242  sheeveWheelS->DefineSection(7, +.125, sheeveInnerR, 1);
1243  sheeveWheelS->DefineSection(8, +.25, sheeveInnerR, 1);
1244  TGeoVolume* sheeveSideV = new TGeoVolume("FMD3_sheeve_side",
1245  sheeveSideS, fPlastic);
1246  TGeoVolume* sheeveBackV = new TGeoVolume("FMD3_sheeve_back",
1247  sheeveBackS, fPlastic);
1248  TGeoVolume* sheeveWingV = new TGeoVolume("FMD3_sheeve_wing",
1249  sheeveWingS, fPlastic);
1250  TGeoVolume* sheeveWheelV= new TGeoVolume("FMD3_sheeve_wheel",
1251  sheeveWheelS, fPlastic);
1252  TGeoVolumeAssembly* sheeveBox = new TGeoVolumeAssembly("FMD3_sheeve_box");
1253  sheeveBox->AddNode(sheeveSideV, 1, new TGeoTranslation(0, -.5, 0));
1254  sheeveBox->AddNode(sheeveSideV, 2, new TGeoTranslation(0, +.5, 0));
1255  sheeveBox->AddNode(sheeveBackV, 1, new TGeoTranslation(0, 0, 2.0+.15-1.15));
1256  sheeveBox->AddNode(sheeveWingV, 1, new TGeoTranslation(.55-.15, -.90, 0));
1257  sheeveBox->AddNode(sheeveWingV, 2, new TGeoTranslation(.55-.15, +.90, 0));
1258  TGeoRotation* sheeveWheelR = new TGeoRotation;
1259  sheeveWheelR->RotateX(90);
1260  TGeoCombiTrans* sheeveWheelM = new TGeoCombiTrans(0, 0, sheeveWheelZ-sheeveL,
1261  sheeveWheelR);
1262  sheeveBox->AddNode(sheeveWheelV, 1, sheeveWheelM);
1263  support->AddNode(sheeveBox, 1, sheeveMat1);
1264  support->AddNode(sheeveBox, 2, sheeveMat2);
1265 
1266 
1267 
1268  //__________________________________________________________________
1269  // Final cone
1270  TGeoCompositeShape* coneShape = new TGeoCompositeShape(coneComb.Data());
1271  coneShape->SetName("FMD3_cone");
1272  coneShape->SetTitle("FMD3 cone");
1273  TGeoVolume* coneVolume = new TGeoVolume("FMD3_Cone", coneShape, fC);
1274  coneVolume->SetLineColor(kRed);
1275  support->AddNode(coneVolume, 0, new TGeoTranslation(0, 0, 0));
1276 
1277  //__________________________________________________________________
1278  // Tension boxes.
1279  TGeoVolume* tensionBox = TensionBox();
1280  Double_t tensionH = .6;
1281  Double_t tensionL = 4;
1282  Double_t tensionZ = 23.654;
1283  Double_t tensionR = fmd3->ConeR(fmd3->GetInnerZ() + fmd3->GetNoseZ()
1284  - tensionZ);
1285  Double_t tensionAr = fmd3->GetConeOuterAngle();
1286  Double_t tensionA = tensionAr * 180 / TMath::Pi();
1287  TGeoRotation* tensionQ = new TGeoRotation;
1288  tensionQ->RotateY(tensionA);
1289  TGeoCombiTrans* tensionM1 = new TGeoCombiTrans(tensionR,0,tensionZ, tensionQ);
1290  TGeoCombiTrans* tensionM2 = new TGeoCombiTrans(tensionR,0,tensionZ, tensionQ);
1291  tensionM1->RotateZ(45);
1292  tensionM2->RotateZ(135);
1293  support->AddNode(tensionBox, 1, tensionM1);
1294  support->AddNode(tensionBox, 2, tensionM2);
1295 
1296  // Double_t tensionHR = 0.15;
1297  Double_t wireT = .1/2;
1298  Double_t wireZ1 = (tensionZ
1299  - tensionL * TMath::Cos(tensionAr)
1300  - tensionH * TMath::Sin(tensionAr));
1301  Double_t wireR1 = (tensionR
1302  - tensionL * TMath::Sin(tensionAr)
1303  + tensionH * TMath::Cos(tensionAr));
1304  AliFMDDebug(10, ("Wire Z1: %f=%f-%f*cos(%f)-%f*sin(%f)",
1305  wireZ1, tensionZ, tensionL, tensionAr, tensionH, tensionAr));
1306  AliFMDDebug(10, ("Wire R1: %f=%f-%f*sin(%f)-%f*cos(%f)",
1307  wireR1, tensionR, tensionL, tensionAr, tensionH, tensionAr));
1308 
1309  Double_t wireStartA = 42.3 * TMath::Pi() / 180;
1310  Double_t wireZ2 = (sheeveWheelZ * (1 - TMath::Sin(wireStartA))
1311  // - sheeveL -
1312  - wireT * TMath::Sin(wireStartA));
1313  /* (sheeveWheelZ * (1 - TMath::Sin(wireStartA))
1314  - wireT * TMath::Sin(wireStartA)
1315  - sheeveL); */
1316  AliFMDDebug(10, ("wireZ2=%f=%f*(1-%f)", wireZ2, sheeveWheelZ,
1317  TMath::Sin(wireStartA)));
1318  Double_t wireR2 = (sheeveHoleR +
1319  sheeveWheelZ * TMath::Cos(wireStartA) +
1320  wireT * TMath::Cos(wireStartA));
1321  Double_t wireDR = wireR1-wireR2;
1322  Double_t wireDZ = wireZ1-wireZ2;
1323  Double_t wireL = TMath::Sqrt(wireDR*wireDR+wireDZ*wireDZ)-.01;
1324  Double_t wireAngle = TMath::ATan2(wireDR,wireDZ);
1325  TGeoTube* wireShape = new TGeoTube("FMD3_wire", 0, wireT, wireL/2);
1326  TGeoVolume* wireVolume = new TGeoVolume("FMD3_wire", wireShape,fSteel);
1327  TGeoRotation* wireRot = new TGeoRotation();
1328  wireRot->RotateY(180/TMath::Pi()*wireAngle);
1329  Double_t wireR = wireR2 + wireDR / 2;
1330  Double_t wireZ = wireZ2 + wireDZ / 2;
1331  TGeoCombiTrans* wireM1 = new TGeoCombiTrans(wireR, 0,wireZ, wireRot);
1332  TGeoCombiTrans* wireM2 = new TGeoCombiTrans(wireR, 0,wireZ, wireRot);
1333  wireM1->RotateZ(45);
1334  wireM2->RotateZ(135);
1335  support->AddNode(wireVolume, 1, wireM1);
1336  support->AddNode(wireVolume, 2, wireM2);
1337 
1338 
1339  TGeoTorus* wireTS = new TGeoTorus(sheeveWheelZ+wireT, 0, wireT, 0,
1340  90-wireStartA*180/TMath::Pi());
1341  TGeoVolume* wireTV = new TGeoVolume("FMD3_bend_wire",wireTS,fSteel);
1342  TGeoRotation* wireTR = new TGeoRotation;
1343  wireTR->RotateY(90);
1344  wireTR->RotateZ(-90);
1345  Double_t wireTZ = sheeveWheelZ;
1346  TGeoCombiTrans* wireTM1 = new TGeoCombiTrans(sheeveHoleR,0,wireTZ,wireTR);
1347  TGeoCombiTrans* wireTM2 = new TGeoCombiTrans(sheeveHoleR,0,wireTZ,wireTR);
1348  wireTM1->RotateZ(45);
1349  wireTM2->RotateZ(135);
1350  support->AddNode(wireTV, 1, wireTM1);
1351  support->AddNode(wireTV, 2, wireTM2);
1352 
1353  Double_t colarR = 4.05;
1354  Double_t wireEL = sheeveHoleR - colarR;
1355  TGeoTube* wireES = new TGeoTube("FMD3_end_wire", 0, wireT, wireEL/2);
1356  TGeoVolume* wireEV = new TGeoVolume("FMD3_end_wire", wireES, fSteel);
1357  TGeoRotation* wireER = new TGeoRotation;
1358  wireER->RotateY(90);
1359  TGeoCombiTrans* wireEM1 = new TGeoCombiTrans(colarR+wireEL/2,0,
1360  -wireT,wireER);
1361  TGeoCombiTrans* wireEM2 = new TGeoCombiTrans(colarR+wireEL/2,0,
1362  -wireT,wireER);
1363  wireEM1->RotateZ(45);
1364  wireEM2->RotateZ(135);
1365  support->AddNode(wireEV, 1, wireEM1);
1366  support->AddNode(wireEV, 2, wireEM2);
1367 
1368 
1369 
1370 
1371  //__________________________________________________________________
1372  // Place support volumes in half-detector volumes
1373  Double_t z = fmd3->GetInnerZ();
1374  AliFMDDebug(1, ("FMD3 support at z=%f", -fmd3->GetNoseZ()));
1375  TGeoTranslation* t1 = new TGeoTranslation(0, 0, -fmd3->GetNoseZ());
1376  fmd3TopVolume->AddNode(support, 1, t1);
1377  TGeoCombiTrans* t2 = new TGeoCombiTrans(*t1);
1378  t2->RotateZ(180);
1379  fmd3BotVolume->AddNode(support, 2, t2);
1380 
1381  TGeoRotation* rot = new TGeoRotation("FMD3 rotatation");
1382  rot->RotateY(180);
1383  TGeoVolume* top = gGeoManager->GetVolume("ALIC");
1384  TGeoMatrix* mmatrix = new TGeoCombiTrans("FMD3 trans", 0, 0, z, rot);
1385  AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
1386  fmd3TopVolume->GetName(), fmd3BotVolume->GetName(), z));
1387  top->AddNode(fmd3TopVolume, fmd3->GetId(), mmatrix);
1388  top->AddNode(fmd3BotVolume, fmd3->GetId(), mmatrix);
1389 
1390  return 0;
1391 }
1392 
1393 
1394 //____________________________________________________________________
1395 void
1397 {
1398  // Setup up the FMD geometry.
1399  AliFMDDebug(1, ("\tGeometry options: %s",
1400  (fDetailed ? "divided into strips" : "one volume")));
1401  if (!gGeoManager) {
1402  AliFatal("No TGeoManager defined");
1403  return;
1404  }
1405 
1406  fSi = gGeoManager->GetMedium("FMD_Si$");
1407  fC = gGeoManager->GetMedium("FMD_Carbon$");
1408  fAl = gGeoManager->GetMedium("FMD_Aluminum$");
1409  fChip = gGeoManager->GetMedium("FMD_Si Chip$");
1410  fAir = gGeoManager->GetMedium("FMD_Air$");
1411  fPCB = gGeoManager->GetMedium("FMD_PCB$");
1412  fPlastic = gGeoManager->GetMedium("FMD_Plastic$");
1413  fCopper = gGeoManager->GetMedium("FMD_Copper$");
1414  fSteel = gGeoManager->GetMedium("FMD_Steel$");
1415 
1416  if (!fSi||!fC||!fAl||!fChip||!fAir||!fPCB||!fPlastic||!fCopper||!fSteel) {
1417  AliError("Failed to get some or all tracking mediums");
1418  return;
1419  }
1421  AliFMDRing* inner = fmd->GetInner();
1422  AliFMDRing* outer = fmd->GetOuter();
1423  RingGeometry(inner);
1424  RingGeometry(outer);
1425  TGeoVolume* innerTop = gGeoManager->GetVolume(Form(fgkRingTopName,
1426  inner->GetId()));
1427  TGeoVolume* innerBot = gGeoManager->GetVolume(Form(fgkRingBotName,
1428  inner->GetId()));
1429  TGeoVolume* outerTop = gGeoManager->GetVolume(Form(fgkRingTopName,
1430  outer->GetId()));
1431  TGeoVolume* outerBot = gGeoManager->GetVolume(Form(fgkRingBotName,
1432  outer->GetId()));
1433 
1434  FMD1Geometry(fmd->GetFMD1(), innerTop, innerBot);
1435  FMD2Geometry(fmd->GetFMD2(), innerTop, innerBot, outerTop, outerBot);
1436  FMD3Geometry(fmd->GetFMD3(), innerTop, innerBot, outerTop, outerBot);
1437 #ifndef USE_PRE_MOVE
1438  fmd->SetSectorOff(fSectorOff);
1439  fmd->SetModuleOff(fModuleOff);
1440  fmd->SetRingOff(fRingOff);
1442  fmd->SetActive(fActiveId.fArray, fActiveId.fN);
1443 #endif
1444  // fmd->ExtractGeomInfo();
1445 
1446 }
1447 
1448 
1449 //____________________________________________________________________
1450 //
1451 // EOF
1452 //
Double_t GetHoleOffset() const
Definition: AliFMD3.h:58
Double_t GetOuterZ() const
Double_t GetBoltRadius() const
Definition: AliFMD3.h:71
AliFMDRing * GetInner() const
Geometry parameters of the FMD3 detector. FMD3 has a fairly complicated support structure. The cone also supports the beam-pipe.
Definition: AliFMD3.h:27
Geometry mananger for the FMD.
Double_t GetFlangeWidth() const
Definition: AliFMD3.h:47
static const Char_t * fgkSensorName
Declaration of FMD1 declaration.
TVector2 * GetFootPosition(Int_t i) const
Definition: AliFMDRing.cxx:235
static const Char_t * fgkCuName
Double_t GetInnerHoneyHighR() const
Double_t ConeR(Double_t z, Option_t *opt="O") const
Definition: AliFMD3.cxx:124
static const Char_t * fgkFMDDPCBName
AliFMDRing * GetOuter() const
Double_t GetConeOuterAngle() const
Definition: AliFMD3.h:53
TGeoMedium * fCopper
Plastic Medium.
Double_t GetHighR() const
Definition: AliFMDRing.h:194
Double_t GetInnerZ() const
#define TObjArray
Double_t GetChipThickness() const
Definition: AliFMDRing.h:254
Double_t GetHoleHighWidth() const
Definition: AliFMD3.h:66
static const Char_t * fgkFlangeName
static const Char_t * fgkTopName
const TObjArray & GetSensorVerticies() const
Definition: AliFMDRing.h:338
Double_t GetAlThickness() const
Definition: AliFMDRing.h:269
virtual TGeoVolume * FMD2Geometry(const AliFMD2 *d, TGeoVolume *innerTop, TGeoVolume *innerBot, TGeoVolume *outerTop, TGeoVolume *outerBot)
const TObjArray & ConeRadii() const
Definition: AliFMD3.h:76
virtual TGeoVolume * TensionBox()
virtual void Exec(Option_t *option="")
FMD ring geometry parameters.
void SetSectorOff(Int_t off)
Double_t GetCopperThickness() const
Definition: AliFMDRing.h:249
static const Char_t * fgkStripName
TGeoMedium * fPlastic
Air Medium.
Double_t GetModuleDepth() const
Definition: AliFMDRing.cxx:262
static const Char_t * fgkRingBotName
Double_t GetHoleLowWidth() const
Definition: AliFMD3.h:64
const TObjArray & FiducialHoles() const
Definition: AliFMD3.h:80
Char_t GetId() const
Definition: AliFMDRing.h:159
void SetModuleOff(Int_t off)
virtual TGeoVolume * DetectorGeometry(const AliFMDDetector *d, TGeoVolume *motherTop, TGeoVolume *motherBot, Double_t zmother, TGeoVolume *innerTop, TGeoVolume *innerBot, TGeoVolume *outerTop=0, TGeoVolume *outerBot=0)
Double_t GetHoneycombThickness() const
Definition: AliFMDRing.h:264
Double_t GetSpacing() const
Definition: AliFMDRing.h:259
Base class for the geometry description and parameters of the FMD sub detectors FMD1, FMD2, and FMD3.
static const Char_t * fgkBackVName
#define AliWarning(message)
Definition: AliLog.h:541
Double_t GetSiThickness() const
Definition: AliFMDRing.h:174
static const Char_t * fgkLongLegName
bool trans(const AliFMDIndex &x, const AliFMDIndex &y, const AliFMDIndex &z)
Definition: TestIndex.C:94
Class to build the FMD geometry.
static const Char_t * fgkFMDDName
static const Char_t * fgkFrontVName
virtual TGeoVolume * FMD1Geometry(const AliFMD1 *d, TGeoVolume *innerTop, TGeoVolume *innerBot)
Double_t GetLegRadius() const
Definition: AliFMDRing.h:224
const TObjArray & GetHybridVerticies() const
Definition: AliFMDRing.h:349
Singleton object of FMD geometry descriptions and parameters. This class is a singleton that handles ...
AliFMDRing * GetInner() const
static const Char_t * fgkPCBName
TGeoMedium * fC
Si Medium.
Double_t GetLowR() const
Definition: AliFMDRing.h:189
Int_t GetNModules() const
Definition: AliFMDRing.h:214
Double_t GetFMDDLowR() const
Definition: AliFMDRing.h:295
TGeoManager * gGeoManager
static const Char_t * fgkBackName
Double_t GetFMDDCopperThickness() const
Definition: AliFMDRing.h:311
AliComparisonDraw comp
Definition: TestAnalisys.C:74
static const Char_t * fgkFMDDCuName
Int_t GetNStrips() const
Definition: AliFMDRing.h:204
Double_t GetFlangeDepth() const
Definition: AliFMD3.h:43
#define AliFMDDebug(N, A)
Definition: AliFMDDebug.h:39
AliFMD3 * GetFMD3() const
static const Char_t * fgkHCName
virtual TGeoShape * MakeXTRU(const TObjArray &verticies, Double_t thick) const
Double_t GetFMDDChipThickness() const
Definition: AliFMDRing.h:316
Double_t GetFMDDHighR() const
Definition: AliFMDRing.h:301
Geometry description and parameters of the FMD1 detector. The FMD1 has only one ring.
Definition: AliFMD1.h:26
Builder of FMD geometry. This class takes care of actually building the geometry using the TGeo class...
static const Char_t * fgkSectorName
static const Char_t * fgkChipName
Double_t GetPrintboardThickness() const
Definition: AliFMDRing.h:244
virtual TGeoVolume * RingGeometry(const AliFMDRing *r)
Double_t GetFMDDPrintboardThickness() const
Definition: AliFMDRing.h:306
#define AliFatal(message)
Definition: AliLog.h:640
AliFMD1 * GetFMD1() const
void SetActive(Int_t *active, Int_t n)
Double_t GetNoseZ() const
Definition: AliFMD3.h:40
static const Char_t * fgkShortLegName
virtual TGeoVolume * FMD3Geometry(const AliFMD3 *d, TGeoVolume *innerTop, TGeoVolume *innerBot, TGeoVolume *outerTop, TGeoVolume *outerBot)
Double_t GetOuterHoneyHighR() const
static const Char_t * fgkActiveName
Steel Medium.
TGeoMedium * fChip
PCB Medium.
Double_t GetTheta() const
Definition: AliFMDRing.h:199
static const Char_t * fgkFMDDChipName
Geometry description and parameters of a ring in the FMD detector.
Definition: AliFMDRing.h:41
static const Char_t * fgkNoseName
Double_t GetHoleDepth() const
Definition: AliFMD3.h:60
Geometry parameters of the FMD3 detector.
Double_t GetOuterHoneyLowR() const
Geometry parameters of the FMD2 detector. This has two rings.
Definition: AliFMD2.h:27
Double_t GetHoleLength() const
Definition: AliFMD3.h:62
TGeoMedium * fSteel
Copper Medium.
#define AliError(message)
Definition: AliLog.h:591
Double_t GetFlangeLength() const
Definition: AliFMD3.h:45
TGeoMedium * fAir
Chip Medium.
static const Char_t * fgkIHCName
Double_t GetModuleSpacing() const
Definition: AliFMDRing.h:239
AliFMDRing * GetOuter() const
Int_t GetId() const
static AliFMDGeometry * Instance()
static const Char_t * fgkRingTopName
static const Char_t * fgkFMDName
Double_t GetBoltLength() const
Definition: AliFMD3.h:69
Bool_t fDetailed
Active volume ID&#39;s.
void SetRingOff(Int_t off)
TGeoMedium * fPCB
Al Medium.
Double_t GetFullDepth() const
Definition: AliFMDRing.cxx:285
TGeoMedium * fAl
C Medium.
Sub-detector base class declaration.
void SetDetectorOff(Int_t off)
Geometry parameters of the FMD2 detector.
Double_t GetInnerHoneyLowR() const
Double_t GetFiducialRadius() const
Definition: AliFMD3.h:50
virtual TGeoShape * HoneycombShape(Int_t id, Char_t ring, double r1, double r2, double w, double t, double c=0.3)
Double_t GetLegLength() const
Definition: AliFMDRing.h:229
static const Char_t * fgkBeamName
AliFMD2 * GetFMD2() const