]> git.uio.no Git - u/mrichter/AliRoot.git/blame - FMD/AliFMDGeometryBuilder.cxx
Adding position dependendent Q normalization (Marian)
[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
d98fbfa5 43#include <TGeoCompositeShape.h>
9edefa04 44#include <TMath.h>
45#include <TVector2.h> // ROOT_TVector2
46//#include <TGeoMaterial.h> // ROOT_TGeoMaterial
47//#include <TGeoMedium.h> // ROOT_TGeoMedium
48//#include <TGeoPcon.h> // ROOT_TGeoPcon
49//#include <TGeoPolygon.h> // ROOT_TGeoPolygon
50
54e415a8 51#include "AliFMDGeometryBuilder.h" // ALIFMDGEOSIMULATOR_H
52#include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H
53#include "AliFMDDetector.h" // ALIFMDDETECTOR_H
54#include "AliFMDRing.h" // ALIFMDRING_H
55#include "AliFMD1.h" // ALIFMD1_H
56#include "AliFMD2.h" // ALIFMD2_H
57#include "AliFMD3.h" // ALIFMD3_H
6169f936 58// #include "AliFMD.h" // ALIFMD_H
f95a63c4 59#include "AliFMDDebug.h" // ALILOG_H
54e415a8 60
61//====================================================================
62ClassImp(AliFMDGeometryBuilder)
63#if 0
64 ; // This is here to keep Emacs for indenting the next line
65#endif
66
67//____________________________________________________________________
68const Char_t* AliFMDGeometryBuilder::fgkActiveName = "F%cAC";
bf000c32 69const Char_t* AliFMDGeometryBuilder::fgkSectorName = "F%cSC";
54e415a8 70const Char_t* AliFMDGeometryBuilder::fgkStripName = "F%cST";
bf000c32 71const Char_t* AliFMDGeometryBuilder::fgkSensorName = "F%cSE";
72const Char_t* AliFMDGeometryBuilder::fgkPCBName = "F%cPB";
73const Char_t* AliFMDGeometryBuilder::fgkCuName = "F%cCU";
74const Char_t* AliFMDGeometryBuilder::fgkChipName = "F%cCH";
54e415a8 75const Char_t* AliFMDGeometryBuilder::fgkLongLegName = "F%cLL";
76const Char_t* AliFMDGeometryBuilder::fgkShortLegName = "F%cSL";
bf000c32 77const Char_t* AliFMDGeometryBuilder::fgkFrontVName = "F%cFH";
78const Char_t* AliFMDGeometryBuilder::fgkBackVName = "F%cBH";
79const Char_t* AliFMDGeometryBuilder::fgkRingTopName = "F%cTV";
80const Char_t* AliFMDGeometryBuilder::fgkRingBotName = "F%cBV";
81const Char_t* AliFMDGeometryBuilder::fgkHCName = "F%dH%c";
82const Char_t* AliFMDGeometryBuilder::fgkIHCName = "F%dI%c";
54e415a8 83const Char_t* AliFMDGeometryBuilder::fgkNoseName = "F3SN";
d98fbfa5 84const Char_t* AliFMDGeometryBuilder::fgkBackName = "F%dSB";
85const Char_t* AliFMDGeometryBuilder::fgkTopName = "F%dSU";
86const Char_t* AliFMDGeometryBuilder::fgkBeamName = "F%dSL";
87const Char_t* AliFMDGeometryBuilder::fgkFlangeName = "F%dSF";
88const Char_t* AliFMDGeometryBuilder::fgkFMDDCuName = "F%cDC";
89const Char_t* AliFMDGeometryBuilder::fgkFMDDPCBName = "F%cDP";
90const Char_t* AliFMDGeometryBuilder::fgkFMDDChipName = "F%cDI";
91const Char_t* AliFMDGeometryBuilder::fgkFMDDName = "F%cDD";
bf000c32 92const Char_t* AliFMDGeometryBuilder::fgkFMDName = "F%dM%c";
54e415a8 93
94//____________________________________________________________________
95AliFMDGeometryBuilder::AliFMDGeometryBuilder()
b5ee4425 96 : TTask("FMD", "Geomtry builder"),
97 fActiveId(0),
98 fDetailed(kTRUE),
54e415a8 99 fUseAssembly(kTRUE),
b5ee4425 100 fSectorOff(0),
101 fModuleOff(0),
102 fRingOff(0),
103 fDetectorOff(0),
54e415a8 104 fSi(0),
105 fC(0),
106 fAl(0),
107 fPCB(0),
108 fChip(0),
b5ee4425 109 fAir(0),
110 fPlastic(0),
d98fbfa5 111 fCopper(0),
112 fSteel(0)
54e415a8 113{
114 // Default constructor
088f8e79 115 fActiveId.Set(2);
54e415a8 116}
117
118//____________________________________________________________________
119AliFMDGeometryBuilder::AliFMDGeometryBuilder(Bool_t detailed)
120 : TTask("FMD", "Geometry builder"),
b5ee4425 121 fActiveId(0),
54e415a8 122 fDetailed(detailed),
123 fUseAssembly(kTRUE),
b5ee4425 124 fSectorOff(0),
125 fModuleOff(0),
126 fRingOff(0),
127 fDetectorOff(0),
54e415a8 128 fSi(0),
129 fC(0),
130 fAl(0),
131 fPCB(0),
132 fChip(0),
b5ee4425 133 fAir(0),
134 fPlastic(0),
d98fbfa5 135 fCopper(0),
136 fSteel(0)
54e415a8 137{
138 // Normal constructor
139 //
140 // Parameters:
141 //
142 // fmd Pointer to AliFMD object
143 // detailed Whether to make a detailed simulation or not
144 //
088f8e79 145 fActiveId.Set(2);
54e415a8 146}
147
148
149//____________________________________________________________________
150TGeoVolume*
151AliFMDGeometryBuilder::RingGeometry(AliFMDRing* r)
152{
153 // Setup the geometry of a ring. The defined TGeoVolume is
154 // returned, and should be used when setting up the rest of the
155 // volumes.
156 //
157 //
158 // Parameters:
159 //
160 // r Pointer to ring geometry object
161 //
162 // Returns:
163 // pointer to ring volume
164 //
165 if (!r) {
166 AliError("Didn't get a ring object");
167 return 0;
168 }
00f69754 169 Char_t id = r->GetId();
170 const Char_t* lName = (id == 'i' || id == 'I' ? "inner" : "outer");
171 Double_t siThick = r->GetSiThickness();
172 const Int_t knv = r->GetNVerticies();
173 TVector2* a = r->GetVertex(5);
174 TVector2* b = r->GetVertex(3);
175 TVector2* c = r->GetVertex(4);
176 Double_t theta = r->GetTheta();
177 Double_t off = (TMath::Tan(TMath::Pi() * theta / 180)
178 * r->GetBondingWidth());
179 Double_t rmax = b->Mod();
180 Double_t rmin = r->GetLowR();
181 Double_t pcbThick = r->GetPrintboardThickness();
182 Double_t cuThick = r->GetCopperThickness();
183 Double_t chipThick= r->GetChipThickness();
184 Double_t modSpace = r->GetModuleSpacing();
185 Double_t legr = r->GetLegRadius();
186 Double_t legl = r->GetLegLength();
187 Double_t legoff = r->GetLegOffset();
188 Int_t ns = r->GetNStrips();
189 Double_t stripoff = a->Mod();
190 Double_t dstrip = (rmax - stripoff) / ns;
191 Double_t space = r->GetSpacing();
192 TArrayD xs(knv);
193 TArrayD ys(knv);
02a27b50 194 for (Int_t i = 0; i < knv; i++) {
54e415a8 195 // Reverse the order
02a27b50 196 TVector2* vv = r->GetVertex(knv - 1 - i);
54e415a8 197 if (!vv) {
02a27b50 198 AliError(Form("Failed to get vertex # %d", knv - 1 - i));
54e415a8 199 continue;
200 }
201 xs[i] = vv->X();
202 ys[i] = vv->Y();
203 }
204
205 // Shape of actual sensor
bf000c32 206 TGeoXtru* sensorShape = new TGeoXtru(2);
02a27b50 207 sensorShape->DefinePolygon(knv, xs.fArray, ys.fArray);
bf000c32 208 sensorShape->DefineSection(0, - siThick/2);
209 sensorShape->DefineSection(1, siThick/2);
00f69754 210 sensorShape->SetName(Form(fgkSensorName, id));
211 sensorShape->SetTitle(Form("FMD %s Sensor", lName));
bf000c32 212 TGeoVolume* sensorVolume = new TGeoVolume(Form(fgkSensorName, id),
213 sensorShape, fSi);
00f69754 214 sensorVolume->SetTitle(Form("FMD %s Sensor", lName));
bf000c32 215 sensorVolume->VisibleDaughters(kFALSE);
216 Int_t sid = sensorVolume->GetNumber();
54e415a8 217 fSectorOff = -1;
218 fModuleOff = 1;
219 fRingOff = 2;
220 fDetectorOff = 3;
221 if (fDetailed) {
222 fSectorOff = 1;
d98fbfa5 223 fModuleOff = 4;
224 fRingOff = 5;
225 fDetectorOff = 6;
54e415a8 226 // Virtual volume shape to divide - This volume is only defined if
227 // the geometry is set to be detailed.
bf000c32 228 TGeoTubeSeg* activeShape = new TGeoTubeSeg(rmin, rmax, siThick/2,
229 - theta, theta);
00f69754 230 activeShape->SetName(Form(fgkActiveName, id));
231 activeShape->SetTitle(Form("FMD %s active area", lName));
54e415a8 232 TGeoVolume* activeVolume = new TGeoVolume(Form(fgkActiveName, id),
233 activeShape,fSi);
00f69754 234 activeVolume->SetTitle(Form("FMD %s active area", lName));
54e415a8 235 TGeoVolume* sectorVolume = activeVolume->Divide(Form(fgkSectorName,id),
236 2, 2, -theta,0,0,"N");
00f69754 237 sectorVolume->SetTitle(Form("FMD %s sector", lName));
54e415a8 238 TGeoVolume* stripVolume = sectorVolume->Divide(Form(fgkStripName, id),
239 1, ns, stripoff, dstrip,
240 0, "SX");
00f69754 241 stripVolume->SetTitle(Form("FMD %s strip", lName));
54e415a8 242 sid = stripVolume->GetNumber();
bf000c32 243 sensorVolume->AddNodeOverlap(activeVolume, 0);
54e415a8 244 }
245
246 switch (id) {
bf000c32 247 case 'i': case 'I': fActiveId[0] = sid; break;
248 case 'o': case 'O': fActiveId[1] = sid; break;
54e415a8 249 }
250
251 // Shape of Printed circuit Board
02a27b50 252 for (Int_t i = 0; i < knv / 2; i++) ys[i] -= off;
253 for (Int_t i = knv / 2; i < knv; i++) ys[i] += off;
bf000c32 254 TGeoXtru* pcbShape = new TGeoXtru(2);
02a27b50 255 pcbShape->DefinePolygon(knv, xs.fArray, ys.fArray);
54e415a8 256 pcbShape->DefineSection(0, - pcbThick/2);
257 pcbShape->DefineSection(1, pcbThick/2);
00f69754 258 pcbShape->SetName(Form(fgkPCBName, id));
259 pcbShape->SetTitle(Form("FMD %s hybrid PCB", lName));
bf000c32 260 TGeoVolume* pcbVolume = new TGeoVolume(Form(fgkPCBName, id),
261 pcbShape, fPCB);
00f69754 262 pcbVolume->SetTitle(Form("FMD %s hybrid PCB", lName));
bf000c32 263
264 // Copper layer
265 TGeoXtru* cuShape = new TGeoXtru(2);
266 cuShape->DefinePolygon(6, xs.fArray, ys.fArray);
267 cuShape->DefineSection(0, - cuThick/2);
268 cuShape->DefineSection(1, cuThick/2);
00f69754 269 cuShape->SetTitle(Form("FMD %s hybrid copper", lName));
bf000c32 270 TGeoVolume* cuVolume = new TGeoVolume(Form(fgkCuName,id),cuShape,fCopper);
00f69754 271 cuVolume->SetTitle(Form("FMD %s hybrid copper", lName));
bf000c32 272
273 // Chip layer
274 TGeoXtru* chipShape = new TGeoXtru(2);
275 chipShape->DefinePolygon(6, xs.fArray, ys.fArray);
276 chipShape->DefineSection(0, - chipThick/2);
277 chipShape->DefineSection(1, chipThick/2);
00f69754 278 chipShape->SetTitle(Form("FMD %s hybrid chip", lName));
bf000c32 279 TGeoVolume* chipVolume = new TGeoVolume(Form(fgkChipName,id),
280 chipShape,fChip);
00f69754 281 chipVolume->SetTitle(Form("FMD %s hybrid chip", lName));
54e415a8 282
283 // Short leg shape
284 TGeoTube* shortLegShape = new TGeoTube(0, legr, legl / 2);
00f69754 285 shortLegShape->SetName(Form(fgkShortLegName, id));
286 shortLegShape->SetTitle(Form("FMD %s short support foot", lName));
54e415a8 287 TGeoVolume* shortLegVolume = new TGeoVolume(Form(fgkShortLegName, id),
d98fbfa5 288 shortLegShape, fCopper);
00f69754 289 shortLegVolume->SetTitle(Form("FMD %s short support foot", lName));
54e415a8 290 // Long leg shape
291 TGeoTube* longLegShape = new TGeoTube(0, legr, (legl + modSpace) / 2);
00f69754 292 longLegShape->SetName(Form(fgkLongLegName, id));
293 longLegShape->SetTitle(Form("FMD %s long support foot", lName));
54e415a8 294 TGeoVolume* longLegVolume = new TGeoVolume(Form(fgkLongLegName, id),
d98fbfa5 295 longLegShape, fCopper);
00f69754 296 longLegVolume->SetTitle(Form("FMD %s long support foot", lName));
54e415a8 297
bf000c32 298
54e415a8 299 // Back container volume
bf000c32 300 TGeoVolume* backVolume = new TGeoVolumeAssembly(Form(fgkBackVName, id));
00f69754 301 backVolume->SetTitle(Form("FMD %s back module", lName));
54e415a8 302 Double_t x = 0;
303 Double_t y = 0;
65af05bc 304 Double_t z = siThick / 2;
305 backVolume->AddNode(sensorVolume, 0, new TGeoTranslation(x, y, z));
306 z += siThick / 2 + space + pcbThick / 2;
bf000c32 307 backVolume->AddNode(pcbVolume, 0, new TGeoTranslation(x,y,z));
308 z += (pcbThick + cuThick) / 2;
309 backVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, z));
310 z += (cuThick + chipThick) / 2;
311 backVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, z));
54e415a8 312 x = a->X() + legoff + legr;
313 y = 0;
314 z += pcbThick / 2 + legl / 2;
bf000c32 315 backVolume->AddNode(shortLegVolume, 0, new TGeoTranslation(x,y,z));
54e415a8 316 x = c->X();
317 y = c->Y() - legoff - legr - off;
bf000c32 318 backVolume->AddNode(shortLegVolume, 1, new TGeoTranslation(x,y,z));
54e415a8 319 y = -y;
bf000c32 320 backVolume->AddNode(shortLegVolume, 2, new TGeoTranslation(x,y,z));
54e415a8 321
322 // Front container volume
bf000c32 323 TGeoVolume* frontVolume = new TGeoVolumeAssembly(Form(fgkFrontVName, id));
00f69754 324 frontVolume->SetTitle(Form("FMD %s front module", lName));
54e415a8 325 x = 0;
326 y = 0;
65af05bc 327 z = siThick / 2;
328 frontVolume->AddNode(sensorVolume, 0, new TGeoTranslation(x, y, z));
329 z += siThick / 2 + space + pcbThick / 2;
330 frontVolume->AddNode(pcbVolume, 0, new TGeoTranslation(x,y,z));
bf000c32 331 z += (pcbThick + cuThick) / 2;
332 frontVolume->AddNode(cuVolume, 0, new TGeoTranslation(0, 0, z));
333 z += (cuThick + chipThick) / 2;
334 frontVolume->AddNode(chipVolume, 0, new TGeoTranslation(0, 0, z));
54e415a8 335 x = a->X() + legoff + legr;
336 y = 0;
337 z += pcbThick / 2 + (legl + modSpace)/ 2;
bf000c32 338 frontVolume->AddNode(longLegVolume, 0, new TGeoTranslation(x,y,z));
54e415a8 339 x = c->X();
340 y = c->Y() - legoff - legr - off;
bf000c32 341 frontVolume->AddNode(longLegVolume, 1, new TGeoTranslation(x,y,z));
54e415a8 342 y = -y;
bf000c32 343 frontVolume->AddNode(longLegVolume, 2, new TGeoTranslation(x,y,z));
d98fbfa5 344
345
346 // FMDD
347 Double_t ddlr = r->GetFMDDLowR();
348 Double_t ddhr = r->GetFMDDHighR();
349 Double_t ddpt = r->GetFMDDPrintboardThickness();
350 Double_t ddct = r->GetFMDDCopperThickness();
351 Double_t ddit = r->GetFMDDChipThickness();
352 Double_t ddt = ddpt + ddct + ddit;
54e415a8 353
d98fbfa5 354 TGeoShape* fmddPcbShape = new TGeoTubeSeg(ddlr, ddhr, ddpt/2,0,180);
355 TGeoShape* fmddCuShape = new TGeoTubeSeg(ddlr, ddhr, ddct/2,0,180);
356 TGeoShape* fmddChipShape = new TGeoTubeSeg(ddlr, ddhr, ddit/2,0,180);
357 fmddPcbShape->SetName(Form(fgkFMDDPCBName, id));
358 fmddCuShape->SetName(Form(fgkFMDDCuName, id));
359 fmddChipShape->SetName(Form(fgkFMDDChipName, id));
360 if (id == 'O' || id == 'o') {
361 TString pcbName(fmddPcbShape->GetName());
362 TString cuName(fmddCuShape->GetName());
363 TString chipName(fmddChipShape->GetName());
364
365 fmddPcbShape->SetName(Form("%s_inner", pcbName.Data()));
366 fmddCuShape->SetName(Form("%s_inner", cuName.Data()));
367 fmddChipShape->SetName(Form("%s_inner", chipName.Data()));
368 new TGeoBBox(Form("%s_clip", pcbName.Data()), ddlr+3, ddhr/2, ddpt);
369 new TGeoBBox(Form("%s_clip", cuName.Data()), ddlr+3, ddhr/2, ddpt);
370 new TGeoBBox(Form("%s_clip", chipName.Data()),ddlr+3, ddhr/2, ddpt);
371 TGeoTranslation* trans = new TGeoTranslation(Form("%s_trans",
372 pcbName.Data()),
373 0, ddhr/2, 0);
374 trans->RegisterYourself();
375 fmddPcbShape = new TGeoCompositeShape(pcbName.Data(),
376 Form("%s_inner*%s_clip:%s_trans",
377 pcbName.Data(),
378 pcbName.Data(),
379 pcbName.Data()));
380 fmddCuShape = new TGeoCompositeShape(cuName.Data(),
381 Form("%s_inner*%s_clip:%s_trans",
382 cuName.Data(),
383 cuName.Data(),
384 pcbName.Data()));
385 fmddChipShape = new TGeoCompositeShape(chipName.Data(),
386 Form("%s_inner*%s_clip:%s_trans",
387 chipName.Data(),
388 chipName.Data(),
389 pcbName.Data()));
390 }
00f69754 391 fmddPcbShape->SetTitle(Form("FMD %s digitiser PCB", lName));
392 fmddCuShape->SetTitle(Form("FMD %s digitiser copper", lName));
393 fmddChipShape->SetTitle(Form("FMD %s digitiser chip", lName));
d98fbfa5 394
395 TGeoVolume* fmddPcbVolume = new TGeoVolume(Form(fgkFMDDPCBName, id),
396 fmddPcbShape, fPCB);
397 TGeoVolume* fmddCuVolume = new TGeoVolume(Form(fgkFMDDCuName, id),
398 fmddCuShape, fCopper);
399 TGeoVolume* fmddChipVolume= new TGeoVolume(Form(fgkFMDDChipName, id),
400 fmddChipShape, fChip);
00f69754 401 fmddPcbVolume->SetTitle(Form("FMD %s digitiser PCB", lName));
402 fmddCuVolume->SetTitle(Form("FMD %s digitiser copper", lName));
403 fmddChipVolume->SetTitle(Form("FMD %s digitiser chip", lName));
404
bf000c32 405 // Half ring mother volumes.
406 TGeoVolume* ringTopVolume = new TGeoVolumeAssembly(Form(fgkRingTopName,id));
407 TGeoVolume* ringBotVolume = new TGeoVolumeAssembly(Form(fgkRingBotName,id));
408 TGeoVolume* halfRing = ringTopVolume;
00f69754 409 ringTopVolume->SetTitle(Form("FMD %s top half-ring", lName));
410 ringBotVolume->SetTitle(Form("FMD %s bottom half-ring", lName));
411
bf000c32 412 // Adding modules to half-rings
413 Int_t nmod = r->GetNModules();
f95a63c4 414 AliFMDDebug(10, ("making %d modules in ring %c", nmod, id));
54e415a8 415 for (Int_t i = 0; i < nmod; i++) {
bf000c32 416 if (i == nmod / 2) halfRing = ringBotVolume;
417 Bool_t front = (i % 2 == 0);
d98fbfa5 418 TGeoVolume* vol = (front ? frontVolume : backVolume);
65af05bc 419 // vol->AddNode(sensorVolume, i, new TGeoTranslation(0,0,siThick/2));
d98fbfa5 420 Double_t z1 = (i % 2) * modSpace;
421 Double_t th = (2 * i + 1) * theta;
422 TGeoMatrix* mat1 = new TGeoCombiTrans(0,0,z1,0);
423 mat1->RotateZ(th);
00f69754 424 mat1->SetName(Form("FMD%c_module_%02d", id, i));
425 mat1->SetTitle(Form("FMD %s module %2d matrix", lName, i));
d98fbfa5 426 halfRing->AddNode(vol, i, mat1);
427#if 0
bf000c32 428 Double_t z2 = z1 + siThick / 2 + space;
429 Double_t th = (2 * i + 1) * theta;
f95a63c4 430 AliFMDDebug(20, ("Placing copy %d of %s and %s in %s at z=%f and %f, "
bf000c32 431 "and theta=%f", i, sensorVolume->GetName(),
432 vol->GetName(), halfRing->GetName(), z1, z2, th));
433 TGeoMatrix* mat1 = new TGeoCombiTrans(0,0,z1,0);
434 mat1->RotateZ(th);
435 halfRing->AddNode(sensorVolume, i, mat1);
436 TGeoMatrix* mat2 = new TGeoCombiTrans(0,0,z2,0);
437 mat2->RotateZ(th);
438 halfRing->AddNode(vol, i, mat2);
d98fbfa5 439#endif
440 }
441
442 // Add the FMDD
443 Double_t zi = r->GetFullDepth() - ddt;
444 Int_t n = 2;
445 for (Int_t i = 0; i < n; i++) {
458e52e8 446 halfRing = (i == 0 ? ringTopVolume : ringBotVolume);
d98fbfa5 447 Double_t phi = 360. / n * i;
448 TGeoRotation* rot = new TGeoRotation(Form("FMDD%c rotation %d", id, i));
449 rot->RotateZ(phi);
00f69754 450 rot->SetTitle(Form("FMD %s digitiser rotation %2d", lName, i));
d98fbfa5 451 z = zi + ddpt / 2;
452 halfRing->AddNode(fmddPcbVolume, i, new TGeoCombiTrans(0,0,z,rot));
453 z += (ddpt + ddct) / 2;
454 halfRing->AddNode(fmddCuVolume, i, new TGeoCombiTrans(0,0,z,rot));
455 z += (ddct + ddit) / 2;
456 halfRing->AddNode(fmddChipVolume, i, new TGeoCombiTrans(0,0,z,rot));
54e415a8 457 }
d98fbfa5 458
54e415a8 459
bf000c32 460 return 0;
54e415a8 461}
462
463//____________________________________________________________________
464TGeoVolume*
465AliFMDGeometryBuilder::DetectorGeometry(AliFMDDetector* d,
bf000c32 466 TGeoVolume* topMother,
467 TGeoVolume* botMother,
468 Double_t zMother,
469 TGeoVolume* innerTop,
470 TGeoVolume* innerBot,
471 TGeoVolume* outerTop,
472 TGeoVolume* outerBot)
54e415a8 473{
474 // Common stuff for setting up the FMD1, FMD2, and FMD3 geometries.
475 // This includes putting the Honeycomb support plates and the rings
476 // into the mother volumes.
477 //
478 // Parameeters:
479 // d The detector geometry to use
480 // mother The mother volume of the detector
481 // zmother The midpoint in global coordinates of detector vol.
482 // inner Pointer to inner ring volume
483 // outer Pointer to outer ring volume
484 //
485 // Returns:
486 // Pointer to mother (detector volume)
487 //
488 if (!d) return 0;
489 // Loop over the defined rings
490 for (int i = 0; i < 2; i++) {
491 AliFMDRing* r = 0;
492 Double_t lowr = 0;
493 Double_t highr = 0;
494 Double_t rz = 0;
bf000c32 495 TGeoVolume* tvol = 0;
496 TGeoVolume* bvol = 0;
54e415a8 497 switch (i) {
498 case 0:
499 r = d->GetInner();
500 lowr = d->GetInnerHoneyLowR();
501 highr = d->GetInnerHoneyHighR();
502 rz = d->GetInnerZ();
bf000c32 503 tvol = innerTop;
504 bvol = innerBot;
54e415a8 505 break;
506 case 1:
507 r = d->GetOuter();
508 lowr = d->GetOuterHoneyLowR();
509 highr = d->GetOuterHoneyHighR();
510 rz = d->GetOuterZ();
bf000c32 511 tvol = outerTop;
512 bvol = outerBot;
54e415a8 513 break;
514 }
515 if (!r) continue;
516 Char_t c = r->GetId();
517 Int_t id = d->GetId();
d98fbfa5 518 Double_t hcThick = r->GetHoneycombThickness();
519 Double_t alThick = r->GetAlThickness();
bf000c32 520 Double_t z = TMath::Abs(rz - zMother);
521
54e415a8 522 // Place ring in mother volume
bf000c32 523 // TGeoMatrix*matrix=new TGeoTranslation(Form("FMD%d%c trans",id,c),0,0,0);
d98fbfa5 524 AliFMDDebug(1, ("Placing volumes %s and %s in %s and %s at z=%f",
bf000c32 525 tvol->GetName(), bvol->GetName(),
526 topMother->GetName(), botMother->GetName(), z));
527 topMother->AddNode(tvol, Int_t(c), new TGeoTranslation(0,0,z));
528 botMother->AddNode(bvol, Int_t(c), new TGeoTranslation(0,0,z));
54e415a8 529
54e415a8 530 // Top of Honeycomb
bf000c32 531 TGeoTubeSeg* hcSha = new TGeoTubeSeg(lowr, highr, hcThick/2, 0, 180);
00f69754 532 hcSha->SetName(Form(fgkHCName,id,c));
533 hcSha->SetTitle(Form("FMD%d%c honeycomb shell", id, c));
bf000c32 534 TGeoVolume* hcVol = new TGeoVolume(Form(fgkHCName,id,c),hcSha,fAl);
00f69754 535 hcVol->SetTitle(Form("FMD%d%c honeycomb shell", id, c));
54e415a8 536 // Air in top of honeycomb
bf000c32 537 TGeoTubeSeg* ihcSha = new TGeoTubeSeg(lowr+alThick, highr - alThick,
538 (hcThick-alThick)/2, 0, 180);
00f69754 539 ihcSha->SetName(Form(fgkIHCName,id,c));
540 ihcSha->SetTitle(Form("FMD%d%c honeycomb internal", id, c));
bf000c32 541 TGeoVolume* ihcVol = new TGeoVolume(Form(fgkIHCName,id,c),ihcSha,fAir);
00f69754 542 ihcVol->SetTitle(Form("FMD%d%c honeycomb internal", id, c));
bf000c32 543 hcVol->AddNode(ihcVol, 0);
544 hcVol->VisibleDaughters(kFALSE);
545 hcVol->SetVisibility(kTRUE);
d98fbfa5 546
bf000c32 547 z += (r->GetSiThickness() +
548 r->GetSpacing() +
549 r->GetPrintboardThickness() +
550 r->GetCopperThickness() +
551 r->GetChipThickness() +
552 r->GetModuleSpacing() +
553 r->GetLegLength() +
d98fbfa5 554 r->GetHoneycombThickness() +
555 r->GetFMDDPrintboardThickness() -
bf000c32 556 hcThick / 2);
557
f95a63c4 558 AliFMDDebug(15, ("Placing a copy of %s in %s and %s at z=%f",
bf000c32 559 hcVol->GetName(), topMother->GetName(),
560 botMother->GetName(), z));
561 // Add to top
562 topMother->AddNode(hcVol, 0, new TGeoTranslation(0, 0, z));
563
564 // Add to bottom
565 TGeoMatrix* bhcMatrix = new TGeoCombiTrans(0,0,z,0);
00f69754 566 bhcMatrix->SetName(Form("FMD%d%c_honeycomp", id, c));
567 bhcMatrix->SetTitle(Form("FMD%d%c honeycomp", id, c));
bf000c32 568 bhcMatrix->RotateZ(180);
569 botMother->AddNode(hcVol, 1, bhcMatrix);
54e415a8 570 }
bf000c32 571 return 0;
54e415a8 572}
573
574//____________________________________________________________________
575TGeoVolume*
bf000c32 576AliFMDGeometryBuilder::FMD1Geometry(AliFMD1* fmd1,
577 TGeoVolume* innerTop,
578 TGeoVolume* innerBot)
54e415a8 579{
580 // Setup the FMD1 geometry. The FMD1 only has one ring, and no
581 // special support as it is at the momement.
582 //
583 // See also AliFMDGeometryBuilder::DetectorGeometry
584 //
bf000c32 585 if (!fmd1 || !innerTop || !innerBot) return 0;
d98fbfa5 586 AliFMDRing* r = fmd1->GetInner();
bf000c32 587 Double_t z = fmd1->GetInnerZ();
d98fbfa5 588 Double_t disce = 2;
589 Double_t backlr = fmd1->GetInnerHoneyHighR();
590 Double_t backhr = fmd1->GetInnerHoneyHighR()+5;
591 Double_t backth = 0.2;
592 Double_t toplr = r->GetLowR();
593 Double_t tophr = fmd1->GetInnerHoneyHighR()+disce;
594 Double_t wallbh = (r->GetFullDepth() + disce);
595 Double_t wallth = wallbh+0.1;
596
bf000c32 597 TGeoVolume* fmd1TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
598 fmd1->GetId(), 'T'));
00f69754 599 fmd1TopVolume->SetTitle("FMD1 top half");
bf000c32 600 TGeoVolume* fmd1BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
601 fmd1->GetId(), 'B'));
00f69754 602 fmd1BotVolume->SetTitle("FMD1 bottom half");
54e415a8 603
bf000c32 604 // Basic detector geometry
605 DetectorGeometry(fmd1, fmd1TopVolume, fmd1BotVolume, z,
606 innerTop, innerBot, 0, 0);
607
d98fbfa5 608
609 // Back
610 TGeoTubeSeg* backShape = new TGeoTubeSeg(backlr, backhr, backth / 2, 0, 180);
611 TGeoTubeSeg* wallbShape = new TGeoTubeSeg(backlr, backlr + backth,
612 wallbh/2, 0, 180);
613 TGeoTubeSeg* topShape = new TGeoTubeSeg(toplr, tophr, backth / 2, 0, 180);
614 TGeoTubeSeg* walltShape = new TGeoTubeSeg(tophr, tophr + backth,
615 wallth/2, 0, 180);
616 TGeoVolume* backVolume = new TGeoVolume(Form(fgkBackName, fmd1->GetId()),
617 backShape, fC);
618 TGeoVolume* wallbVolume= new TGeoVolume(Form(fgkFlangeName, fmd1->GetId()),
619 wallbShape, fC);
620 TGeoVolume* topVolume = new TGeoVolume(Form(fgkTopName, fmd1->GetId()),
621 topShape, fC);
622 TGeoVolume* walltVolume= new TGeoVolume(Form(fgkBeamName, fmd1->GetId()),
623 walltShape, fC);
00f69754 624 backShape->SetName(Form(fgkBackName, fmd1->GetId()));
625 wallbShape->SetName(Form(fgkFlangeName, fmd1->GetId()));
626 topShape->SetName(Form(fgkTopName, fmd1->GetId()));
627 walltShape->SetName(Form(fgkBeamName, fmd1->GetId()));
628 backShape->SetTitle("FMD1 back saucer rim");
629 wallbShape->SetTitle("FMD1 back saucer wall");
630 topShape->SetTitle("FMD1 top lid");
631 walltShape->SetTitle("FMD1 top lid wall");
d98fbfa5 632 backVolume->SetFillColor(kGray);
633 topVolume->SetFillColor(kGray);
634 wallbVolume->SetFillColor(kGray);
635 walltVolume->SetFillColor(kGray);
00f69754 636 backVolume->SetTitle("FMD1 back saucer rim");
637 wallbVolume->SetTitle("FMD1 back saucer wall");
638 topVolume->SetTitle("FMD1 top lid");
639 walltVolume->SetTitle("FMD1 top lid wall");
d98fbfa5 640
641 // Place volumes
642 Double_t zb = TMath::Abs(fmd1->GetInnerZ() - z);
643 Double_t zi = zb;
644 Int_t n = 2;
645
646 // Place top cover
647 zi -= disce / 2 + backth / 2;
648 zb = zi;
649 for (Int_t i = 0; i < 2; i++) {
650 TGeoVolume* mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
651 Double_t phi = 360. / n * i;
00f69754 652 TGeoRotation* rot = new TGeoRotation(Form("FMD1 top rotation %d",i));
d98fbfa5 653 rot->RotateZ(phi);
00f69754 654 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD1 top wall trans %d", i),
655 0, 0, zi, rot);
d98fbfa5 656 mother->AddNode(topVolume, i, matrix);
657 }
658 // Place outer wall
659 zi += wallth / 2 + backth / 2;
660 for (Int_t i = 0; i < 2; i++) {
661 TGeoVolume* mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
662 Double_t phi = 360. / n * i;
663 TGeoRotation* rot = new TGeoRotation(Form("FMD1 outer wall rotation %d",
664 i));
665 rot->RotateZ(phi);
00f69754 666 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD1 outer wall trans %d",
667 i), 0, 0, zi, rot);
d98fbfa5 668 mother->AddNode(walltVolume, i, matrix);
669 }
670 // Place back
671 zi += wallth / 2 + backth / 2; // + disce / 2;
672 for (Int_t i = 0; i < 2; i++) {
673 TGeoVolume* mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
674 Double_t phi = 360. / n * i;
675 TGeoRotation* rot = new TGeoRotation(Form("FMD1 back rotation %d", i));
676 rot->RotateZ(phi);
677 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD1 back trans %d", i),
678 0, 0, zi, rot);
679 mother->AddNode(backVolume, i, matrix);
680 }
681 // Place inner wall
682 zi -= wallbh / 2 + backth / 2; // + disce / 2;
683 for (Int_t i = 0; i < 2; i++) {
684 TGeoVolume* mother = (i == 0 ? fmd1TopVolume : fmd1BotVolume);
685 Double_t phi = 360. / n * i;
686 TGeoRotation* rot = new TGeoRotation(Form("FMD1 inner wall rotation %d",
687 i));
688 rot->RotateZ(phi);
689 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD1 inner wall trans %d",
00f69754 690 i), 0, 0, zi, rot);
d98fbfa5 691 mother->AddNode(wallbVolume, i, matrix);
692 }
693
694
bf000c32 695 // Must add this after filling the assembly.
696 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
c1b9c050 697 // TGeoMatrix* matrix = new TGeoTranslation("FMD1 trans", 0, 0, z);
698 TGeoRotation* rot = new TGeoRotation("FMD1 rotatation");
0b1b84c9 699 rot->RotateZ(-90);
c1b9c050 700 TGeoMatrix* matrix = new TGeoCombiTrans("FMD1 trans", 0, 0, z, rot);
f95a63c4 701 AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
bf000c32 702 fmd1TopVolume->GetName(), fmd1BotVolume->GetName(), z));
703 top->AddNode(fmd1TopVolume, fmd1->GetId(), matrix);
704 top->AddNode(fmd1BotVolume, fmd1->GetId(), matrix);
705
706 return 0;
54e415a8 707}
708
709//____________________________________________________________________
710TGeoVolume*
711AliFMDGeometryBuilder::FMD2Geometry(AliFMD2* fmd2,
bf000c32 712 TGeoVolume* innerTop,
713 TGeoVolume* innerBot,
714 TGeoVolume* outerTop,
715 TGeoVolume* outerBot)
54e415a8 716{
717 // Setup the FMD2 geometry. The FMD2 has no
718 // special support as it is at the momement.
719 //
720 // See also AliFMDGeometryBuilder::DetectorGeometry
721 //
bf000c32 722 if (!fmd2 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
d98fbfa5 723 AliFMDRing* r = fmd2->GetOuter();
724 Double_t z = fmd2->GetOuterZ();
725 Double_t framelr = fmd2->GetOuterHoneyHighR()+0.5;
726 Double_t framehr = fmd2->GetOuterHoneyHighR()+1.8;
727 Double_t framelz = -1;
728 Double_t framehz = (fmd2->GetInnerZ()-z) + r->GetFullDepth() + 1;
729 Double_t framel = framehz - framelz;
730 Double_t coverlr = fmd2->GetInner()->GetLowR()+1;
731 Double_t backth = 0.05;
732
bf000c32 733 TGeoVolume* fmd2TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
734 fmd2->GetId(), 'T'));
735 TGeoVolume* fmd2BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
736 fmd2->GetId(), 'B'));
00f69754 737 fmd2TopVolume->SetTitle("FMD2 top half");
738 fmd2BotVolume->SetTitle("FMD2 bottom half");
54e415a8 739
bf000c32 740 DetectorGeometry(fmd2, fmd2TopVolume, fmd2BotVolume, z,
741 innerTop, innerBot, outerTop, outerBot);
742
d98fbfa5 743 TGeoShape* cylinderShape = new TGeoTubeSeg(framelr,framehr,framel/2,0,180);
744 TGeoVolume* cylinderVolume = new TGeoVolume(Form(fgkBackName, fmd2->GetId()),
745 cylinderShape, fC);
746 TGeoShape* coverShape = new TGeoTubeSeg(coverlr,framehr,backth/2,0,180);
747 TGeoVolume* coverVolume = new TGeoVolume(Form(fgkTopName, fmd2->GetId()),
748 coverShape, fC);
00f69754 749 cylinderShape->SetName(Form(fgkBackName, fmd2->GetId()));
750 cylinderShape->SetTitle("FMD2 cylinder");
751 cylinderVolume->SetTitle("FMD2 cylinder");
d98fbfa5 752 cylinderVolume->SetTransparency(63);
00f69754 753 coverShape->SetName(Form(fgkTopName, fmd2->GetId()));
754 coverShape->SetTitle("FMD2 cover");
755 coverVolume->SetTitle("FMD2 cover");
d98fbfa5 756 coverVolume->SetTransparency(63);
757
758 for (Int_t i = 0; i < 2; i++) {
759 TGeoVolume* mother = (i == 0 ? fmd2TopVolume : fmd2BotVolume);
760
761 Double_t phi = 360. / 2 * i;
762 TGeoRotation* rot = new TGeoRotation(Form("FMD2 support rot %d",i));
763 rot->RotateZ(phi);
764 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD2 cyl trans %d", i),
765 0, 0, framelz+framel/2, rot);
766 mother->AddNode(cylinderVolume, i, matrix);
767 matrix = new TGeoCombiTrans(Form("FMD2 fcov trans %d", i),
768 0, 0, framelz-backth/2, rot);
769 mother->AddNode(coverVolume, 2*i+0, matrix);
770 matrix = new TGeoCombiTrans(Form("FMD2 bcov trans %d", i),
771 0, 0, framelz+framel+backth/2,
772 rot);
773 mother->AddNode(coverVolume, 2*i+1, matrix);
774 }
775
776
777 Double_t f1l = 10;
778 Double_t f1w = 6;
779 Double_t f1d = 1.2;
780
781 TGeoBBox* flange1Shape = new TGeoBBox(f1l/2, f1w/2, f1d/2);
782 TGeoVolume* flange1Volume = new TGeoVolume(Form(fgkFlangeName, fmd2->GetId()),
783 flange1Shape, fAl);
784 TGeoBBox* flange2Shape = new TGeoBBox(f1w/2, f1d/2, (framel+backth)/2);
785 TGeoVolume* flange2Volume = new TGeoVolume(Form("F%dSG", fmd2->GetId()),
786 flange2Shape, fAl);
00f69754 787 flange1Shape->SetName(Form(fgkFlangeName, fmd2->GetId()));
788 flange1Shape->SetTitle("FMD2 vertical flange");
789 flange1Volume->SetTitle("FMD2 vertical flange");
790 flange2Shape->SetName(Form("F%dSG", fmd2->GetId()));
791 flange2Shape->SetTitle("FMD2 horizontal flange");
792 flange2Volume->SetTitle("FMD2 horizontal flange ");
793
d98fbfa5 794 flange1Volume->SetTransparency(42);
795 for (Int_t i = 0; i < 4; i++) {
796 TGeoVolume* mother = (i < 2 ? fmd2TopVolume : fmd2BotVolume);
797
798 Double_t phi = 360. / 4 * i - 45;
799 Double_t rphi = TMath::Pi()*phi/180;
800 Double_t x = (framelr + f1l/2) * TMath::Sin(rphi);
801 Double_t y = (framelr + f1l/2) * TMath::Cos(rphi);
802 TGeoRotation* rot = new TGeoRotation(Form("FMD2 support rot %d",i));
803 rot->RotateZ(phi);
804 TGeoMatrix* matrix = new TGeoCombiTrans(Form("FMD2 flange 1 trans %d", i),
805 x,y, framelz-backth-f1d/2, rot);
806 mother->AddNode(flange1Volume, 2*i+0, matrix);
807 matrix = new TGeoCombiTrans(Form("FMD2 flange 2 trans %d", i),
808 x,y,framelz+framel+backth+f1d/2,
809 rot);
810 mother->AddNode(flange1Volume, 2*i+1, matrix);
811 Double_t x1 = x - (f1w-f1d) / 2 * TMath::Cos(rphi);
812 Double_t y1 = y + (f1w-f1d) / 2 * TMath::Sin(rphi);
813 matrix = new TGeoCombiTrans(Form("FMD2 flange 3 trans %d", i),
814 x1,y1,framelz+framel/2, rot);
815 mother->AddNode(flange2Volume, 2*i+0, matrix);
816 Double_t x2 = x + (f1w-f1d) / 2 * TMath::Cos(rphi);
817 Double_t y2 = y - (f1w-f1d) / 2 * TMath::Sin(rphi);
818 matrix = new TGeoCombiTrans(Form("FMD2 flange 4 trans %d", i),
819 x2,y2,framelz+framel/2, rot);
820 mother->AddNode(flange2Volume, 2*i+1, matrix);
821 }
822
bf000c32 823 // Must be done after filling the assemblies
54e415a8 824 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
bf000c32 825 TGeoMatrix* matrix = new TGeoTranslation("FMD2 trans", 0, 0, z);
f95a63c4 826 AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
bf000c32 827 fmd2TopVolume->GetName(), fmd2BotVolume->GetName(), z));
828 top->AddNode(fmd2TopVolume, fmd2->GetId(), matrix);
829 top->AddNode(fmd2BotVolume, fmd2->GetId(), matrix);
54e415a8 830
d98fbfa5 831
bf000c32 832 return 0;
54e415a8 833}
834
835//____________________________________________________________________
836TGeoVolume*
837AliFMDGeometryBuilder::FMD3Geometry(AliFMD3* fmd3,
bf000c32 838 TGeoVolume* innerTop,
839 TGeoVolume* innerBot,
840 TGeoVolume* outerTop,
841 TGeoVolume* outerBot)
54e415a8 842{
843 // Setup the FMD3 geometry. The FMD2 has a rather elaborate support
844 // structure, as the support will also support the vacuum
845 // beam-pipe.
846 //
847 // See also AliFMDGeometryBuilder::DetectorGeometry
848 //
bf000c32 849 if (!fmd3 || !innerTop || !innerBot || !outerTop || !outerBot) return 0;
54e415a8 850 Double_t nlen = fmd3->GetNoseLength();
851 Double_t nz = fmd3->GetNoseZ();
852 Double_t noser1 = fmd3->GetNoseLowR();
853 Double_t noser2 = fmd3->GetNoseHighR();
d98fbfa5 854 Double_t conet = fmd3->GetBeamThickness();
54e415a8 855 Double_t conel = fmd3->GetConeLength();
856 Double_t backl = fmd3->GetBackLength();
00f69754 857 // Double_t backr1 = fmd3->GetBackLowR();
54e415a8 858 Double_t backr2 = fmd3->GetBackHighR();
859 Double_t zdist = conel - backl - nlen;
860 Double_t tdist = backr2 - noser2;
00f69754 861 // Double_t beaml = TMath::Sqrt(zdist * zdist + tdist * tdist);
54e415a8 862 Double_t theta = -180. * TMath::ATan2(tdist, zdist) / TMath::Pi();
54e415a8 863 Double_t flanger = fmd3->GetFlangeR();
bf000c32 864 Double_t z = fmd3->GetInnerZ(); // fmd3->GetZ();
54e415a8 865
bf000c32 866 TGeoVolume* fmd3TopVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
867 fmd3->GetId(), 'T'));
868 TGeoVolume* fmd3BotVolume = new TGeoVolumeAssembly(Form(fgkFMDName,
869 fmd3->GetId(), 'B'));
00f69754 870 fmd3TopVolume->SetTitle("FMD3 top half");
871 fmd3BotVolume->SetTitle("FMD3 bottom half");
872
54e415a8 873
bf000c32 874 DetectorGeometry(fmd3, fmd3TopVolume, fmd3BotVolume, z,
875 innerTop, innerBot, outerTop, outerBot);
876
54e415a8 877
d98fbfa5 878 TGeoVolumeAssembly* support = new TGeoVolumeAssembly("F3SU");
00f69754 879 support->SetTitle("FMD3 support");
bf000c32 880
d98fbfa5 881 // Nose volume
882 TGeoTubeSeg* noseShape = new TGeoTubeSeg(noser1, noser2, nlen / 2, 0, 180);
883 TGeoVolume* noseVolume = new TGeoVolume(fgkNoseName, noseShape, fC);
884 support->AddNode(noseVolume, 0, new TGeoTranslation(0, 0, nlen/2));
00f69754 885 noseShape->SetName(fgkNoseName);
886 noseShape->SetTitle("FMD3 nose");
887 noseVolume->SetTitle("FMD3 nose");
d98fbfa5 888
889 // Steel bolts
890 TGeoTube* boltShape = new TGeoTube("F3SB", 0, 0.3, conet / 2);
891 TGeoVolume* boltVolume = new TGeoVolume("F3SB", boltShape, fSteel);
892 Double_t z1 = -10;
893 Double_t x1 = (fmd3->ConeR(nz+z1));
894 TGeoRotation* r1 = new TGeoRotation();
895 r1->RotateY(theta);
896 TGeoCombiTrans* t = new TGeoCombiTrans("F3SB1",x1,0,-z1,r1);
897 support->AddNode(boltVolume, 1, t);
898 z1 = -20;
899 x1 = (fmd3->ConeR(nz+z1));
900 t = new TGeoCombiTrans("F3SB2",x1,0,-z1,r1);
901 support->AddNode(boltVolume, 2, t);
00f69754 902 boltShape->SetTitle("FMD3 steering bolt");
903 boltVolume->SetTitle("FMD3 steering bolt");
d98fbfa5 904
905 // Cooling plates
906 TGeoTrd1* plateShape = new TGeoTrd1(2, 8, 0.1, (conel-2-2)/2-.1);
907 TGeoVolume* plateVolume = new TGeoVolume("F3CO", plateShape, fAl);
00f69754 908 plateShape->SetName("F3C0");
909 plateShape->SetTitle("FMD3 cooling plate");
910 plateVolume->SetTitle("FMD3 cooling plate");
d98fbfa5 911
912 // Shape for carbon half-cone
00f69754 913 TGeoConeSeg* innerCone = new TGeoConeSeg("F3SC_inner", conel/2,
914 noser2-conet, noser2,
915 backr2-conet, backr2, 0., 180.);
916 innerCone->SetTitle("FMD3 cone inner");
917 TGeoTrd1* coneHole = new TGeoTrd1("F3SC_hole",2,8,conet*3,
918 (conel-2-2)/2);
919 coneHole->SetTitle("FMD3 cone hole");
d98fbfa5 920 Double_t holeAng = TMath::ATan2(backr2 - noser2, conel);
921 Double_t holeX = ((conel-2) / 2 * TMath::Sin(holeAng) +
922 conet * TMath::Cos(holeAng) +
923 noser2);
924 TGeoRotation* holeRot = new TGeoRotation();
00f69754 925 holeRot->SetName("FMD3 cone hole rotation");
d98fbfa5 926 holeRot->RotateZ(90);
927 holeRot->RotateY(holeAng*180./TMath::Pi());
928 TGeoCombiTrans* holeTrans = new TGeoCombiTrans(holeX, 0, -2, holeRot);
00f69754 929 holeRot->SetName("FMD3 cone hole");
d98fbfa5 930
931 // Build-up the composite shape for the cone, and add cooling plates
932 // at the same time.
933 TString coneExp("F3SC_inner-(");
934 for (int i = 0; i < 4; i++) {
935 Double_t thisAng = 360. / 8 * (i + .5);
936 TGeoCombiTrans* thisTrans = new TGeoCombiTrans(*holeTrans);
937 thisTrans->RotateZ(thisAng);
938 thisTrans->SetName(Form("F3SC_rot%d", i));
939 thisTrans->RegisterYourself();
940 coneExp.Append(Form("F3SC_hole:F3SC_rot%d+", i));
941
942 const Double_t* tt = thisTrans->GetTranslation();
943 Double_t x = tt[0]+1*TMath::Cos(thisAng*TMath::Pi()/180);
944 Double_t y = tt[1]+1*TMath::Sin(thisAng*TMath::Pi()/180);
945 TGeoCombiTrans* plateTrans = new TGeoCombiTrans(x,y,tt[2]-1+nlen+conel/2,
946 thisTrans->GetRotation());
947 support->AddNode(plateVolume, i, plateTrans);
948 }
949 // Remove bolt holes
950 coneExp.Append("F3SB:F3SB1+F3SB:F3SB2)");
951
952 // Finalize the half-cone shape and add volume
953 TGeoCompositeShape* coneShape = new TGeoCompositeShape(coneExp.Data());
954 TGeoVolume* coneVolume = new TGeoVolume("F3SC", coneShape, fC);
00f69754 955 coneShape->SetName("F3SC");
956 coneShape->SetTitle("FMD3 cone");
957 coneVolume->SetTitle("FMD3 cone");
d98fbfa5 958 support->AddNode(coneVolume,1,new TGeoTranslation(0,0,nlen+conel/2));
54e415a8 959
54e415a8 960 // The flanges
d98fbfa5 961 TGeoBBox* flangeShape = new TGeoBBox((flanger - backr2) / 2,
962 fmd3->GetBeamWidth() / 2,
963 backl / 2);
964 TGeoVolume* flangeVolume = new TGeoVolume(Form(fgkFlangeName, fmd3->GetId()),
965 flangeShape, fC);
00f69754 966 flangeShape->SetName(Form(fgkFlangeName, fmd3->GetId()));
967 flangeShape->SetTitle("FMD3 flange");
968 flangeVolume->SetTitle("FMD3 flange");
969
d98fbfa5 970 Int_t n = fmd3->GetNFlange();
971 Double_t r = backr2 + (flanger - backr2) / 2;
972 for (Int_t i = 0; i < n/2; i++) {
bf000c32 973 Double_t phi = 360. / n * i + 180. / n;
974 Double_t x = r * TMath::Cos(TMath::Pi() / 180 * phi);
975 Double_t y = r * TMath::Sin(TMath::Pi() / 180 * phi);
d98fbfa5 976 TGeoRotation* rot = new TGeoRotation;
54e415a8 977 rot->RotateZ(phi);
d98fbfa5 978 TGeoMatrix* matrix = new TGeoCombiTrans(x, y, nlen+conel-backl/2, rot);
00f69754 979 matrix->SetName(Form("FMD3_flange_%02d", i));
980 matrix->SetTitle(Form("FMD3_flange_%2d", i));
d98fbfa5 981 support->AddNode(flangeVolume, i, matrix);
54e415a8 982 }
983
d98fbfa5 984 // Place support volumes in half-detector volumes
985 z = fmd3->GetInnerZ();
986 z1 = z-nz;
987 fmd3TopVolume->AddNode(support, 1, new TGeoTranslation(0,0,z1));
988 r1 = new TGeoRotation();
989 r1->RotateZ(180);
990 t = new TGeoCombiTrans(0,0,z1,r1);
991 fmd3BotVolume->AddNode(support, 2, t);
992
993 TGeoRotation* rot = new TGeoRotation("FMD3 rotatation");
bf000c32 994 rot->RotateY(180);
d98fbfa5 995 TGeoVolume* top = gGeoManager->GetVolume("ALIC");
996 TGeoMatrix* mmatrix = new TGeoCombiTrans("FMD3 trans", 0, 0, z, rot);
f95a63c4 997 AliFMDDebug(5, ("Placing volumes %s and %s in ALIC at z=%f",
bf000c32 998 fmd3TopVolume->GetName(), fmd3BotVolume->GetName(), z));
999 top->AddNode(fmd3TopVolume, fmd3->GetId(), mmatrix);
1000 top->AddNode(fmd3BotVolume, fmd3->GetId(), mmatrix);
1001
1002 return 0;
54e415a8 1003}
1004
1005//____________________________________________________________________
1006void
1007AliFMDGeometryBuilder::Exec(Option_t*)
1008{
1009 // Setup up the FMD geometry.
f95a63c4 1010 AliFMDDebug(1, ("\tGeometry options: %s",
bf000c32 1011 (fDetailed ? "divided into strips" : "one volume")));
54e415a8 1012 if (!gGeoManager) {
1013 AliFatal("No TGeoManager defined");
1014 return;
1015 }
1016
1017 fSi = gGeoManager->GetMedium("FMD_Si$");
1018 fC = gGeoManager->GetMedium("FMD_Carbon$");
1019 fAl = gGeoManager->GetMedium("FMD_Aluminum$");
1020 fChip = gGeoManager->GetMedium("FMD_Si Chip$");
1021 fAir = gGeoManager->GetMedium("FMD_Air$");
1022 fPCB = gGeoManager->GetMedium("FMD_PCB$");
1023 fPlastic = gGeoManager->GetMedium("FMD_Plastic$");
1024 fCopper = gGeoManager->GetMedium("FMD_Copper$");
d98fbfa5 1025 fSteel = gGeoManager->GetMedium("FMD_Steel$");
54e415a8 1026
d98fbfa5 1027 if (!fSi||!fC||!fAl||!fChip||!fAir||!fPCB||!fPlastic||!fCopper||!fSteel) {
54e415a8 1028 AliError("Failed to get some or all tracking mediums");
1029 return;
1030 }
1031 AliFMDGeometry* fmd = AliFMDGeometry::Instance();
bf000c32 1032 AliFMDRing* inner = fmd->GetInner();
1033 AliFMDRing* outer = fmd->GetOuter();
1034 RingGeometry(inner);
1035 RingGeometry(outer);
1036 TGeoVolume* innerTop = gGeoManager->GetVolume(Form(fgkRingTopName,
1037 inner->GetId()));
1038 TGeoVolume* innerBot = gGeoManager->GetVolume(Form(fgkRingBotName,
1039 inner->GetId()));
1040 TGeoVolume* outerTop = gGeoManager->GetVolume(Form(fgkRingTopName,
1041 outer->GetId()));
1042 TGeoVolume* outerBot = gGeoManager->GetVolume(Form(fgkRingBotName,
1043 outer->GetId()));
1044
1045 FMD1Geometry(fmd->GetFMD1(), innerTop, innerBot);
1046 FMD2Geometry(fmd->GetFMD2(), innerTop, innerBot, outerTop, outerBot);
1047 FMD3Geometry(fmd->GetFMD3(), innerTop, innerBot, outerTop, outerBot);
54e415a8 1048#ifndef USE_PRE_MOVE
1049 fmd->SetSectorOff(fSectorOff);
1050 fmd->SetModuleOff(fModuleOff);
1051 fmd->SetRingOff(fRingOff);
1052 fmd->SetDetectorOff(fDetectorOff);
1053 fmd->SetActive(fActiveId.fArray, fActiveId.fN);
1054#endif
1055 // fmd->ExtractGeomInfo();
1056
1057}
1058
1059
1060//____________________________________________________________________
1061//
1062// EOF
1063//