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