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