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