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