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