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