Project
Loading...
Searching...
No Matches
V3Layer.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
16
21
22#include <fairlogger/Logger.h> // for LOG
23
24#include <TGeoArb8.h> // for TGeoArb8
25#include <TGeoBBox.h> // for TGeoBBox
26#include <TGeoCone.h> // for TGeoConeSeg, TGeoCone
27#include <TGeoPcon.h> // for TGeoPcon
28#include <TGeoManager.h> // for TGeoManager, gGeoManager
29#include <TGeoMatrix.h> // for TGeoCombiTrans, TGeoRotation, etc
30#include <TGeoTrd1.h> // for TGeoTrd1
31#include <TGeoTube.h> // for TGeoTube, TGeoTubeSeg
32#include <TGeoVolume.h> // for TGeoVolume, TGeoVolumeAssembly
33#include <TGeoXtru.h> // for TGeoXtru
34#include <TGeoCompositeShape.h> // for TGeoCompositeShape
35#include "TMathBase.h" // for Abs
36#include <TMath.h> // for Sin, RadToDeg, DegToRad, Cos, Tan, etc
37
38#include <cstdio> // for snprintf
39
40class TGeoMedium;
41
42using namespace TMath;
43using namespace o2::its;
44using namespace o2::itsmft;
46
47// General Parameters
48const Int_t V3Layer::sNumberOfInnerLayers = 3;
49
50// Inner Barrel Parameters
51const Int_t V3Layer::sIBChipsPerRow = 9;
52const Int_t V3Layer::sIBNChipRows = 1;
53const Double_t V3Layer::sIBChipZGap = 150.0 * sMicron;
54
55const Double_t V3Layer::sIBModuleZLength = 27.12 * sCm;
56const Double_t V3Layer::sIBFPCWiderXPlus = 950.0 * sMicron;
57const Double_t V3Layer::sIBFPCWiderXNeg = 400.0 * sMicron;
58const Double_t V3Layer::sIBFlexCableAlThick = 25.0 * sMicron;
59const Double_t V3Layer::sIBFPCAlGNDWidth = (4.1 + 11.15) * sMm;
60const Double_t V3Layer::sIBFPCAlAnodeWidth1 = 13.0 * sMm;
61const Double_t V3Layer::sIBFPCAlAnodeWidth2 = 14.7 * sMm;
62const Double_t V3Layer::sIBFlexCableKapThick = 75.0 * sMicron;
63const Double_t V3Layer::sIBFlexCablePolyThick = 20.0 * sMicron;
64const Double_t V3Layer::sIBFlexCapacitor1XWid = 0.5 * sMm;
65const Double_t V3Layer::sIBFlexCapacitor1YHi = 0.5 * sMm;
66const Double_t V3Layer::sIBFlexCapacitor1ZLen = 1.0 * sMm;
67const Double_t V3Layer::sIBFlexCapacitor22XWid = 0.7 * sMm;
68const Double_t V3Layer::sIBFlexCapacitor22YHi = 0.6 * sMm;
69const Double_t V3Layer::sIBFlexCapacitor22ZLen = 1.1 * sMm;
70const Double_t V3Layer::sIBFlexResistorXWid = 0.2 * sMm;
71const Double_t V3Layer::sIBFlexResistorYHi = 0.2 * sMm;
72const Double_t V3Layer::sIBFlexResistorZLen = 0.4 * sMm;
73const Double_t V3Layer::sIBColdPlateWidth = 15.4 * sMm;
74const Double_t V3Layer::sIBColdPlateZLen = 290.0 * sMm;
75const Double_t V3Layer::sIBGlueThick = 50.0 * sMicron;
76const Double_t V3Layer::sIBCarbonFleeceThick = 20.0 * sMicron;
77const Double_t V3Layer::sIBCarbonPaperThick = 30.0 * sMicron;
78const Double_t V3Layer::sIBCarbonPaperWidth = 12.5 * sMm;
79const Double_t V3Layer::sIBCarbonPaperZLen = 280.0 * sMm;
80const Double_t V3Layer::sIBK13D2UThick = 70.0 * sMicron;
81const Double_t V3Layer::sIBCoolPipeInnerD = 1.024 * sMm;
82const Double_t V3Layer::sIBCoolPipeThick = 25.4 * sMicron;
83const Double_t V3Layer::sIBCoolPipeXDist = 5.0 * sMm;
84const Double_t V3Layer::sIBCoolPipeZLen = 302.0 * sMm;
85const Double_t V3Layer::sIBTopVertexWidth1 = 0.258 * sMm;
86const Double_t V3Layer::sIBTopVertexWidth2 = 0.072 * sCm;
87const Double_t V3Layer::sIBTopVertexHeight = 0.04 * sCm;
88const Double_t V3Layer::sIBTopVertexAngle = 60.0; // Deg
89const Double_t V3Layer::sIBSideVertexWidth = 0.05 * sCm;
90const Double_t V3Layer::sIBSideVertexHeight = 0.074 * sCm;
91const Double_t V3Layer::sIBTopFilamentSide = 0.04 * sCm;
92const Double_t V3Layer::sIBTopFilamentAlpha = 109.8; // Deg
93const Double_t V3Layer::sIBTopFilamentInterZ = 15.0 * sMm;
94const Double_t V3Layer::sIBEndSupportThick = 0.149 * sMm;
95const Double_t V3Layer::sIBEndSupportZLen = 2.5 * sMm;
96const Double_t V3Layer::sIBEndSupportXUp = 1.0 * sMm;
97const Double_t V3Layer::sIBEndSupportOpenPhi = 120.0; // Deg
98
99const Double_t V3Layer::sIBConnectorXWidth = 10.0 * sMm;
100const Double_t V3Layer::sIBConnectorYTot = 4.7 * sMm;
101const Double_t V3Layer::sIBConnectBlockZLen = 16.5 * sMm;
102const Double_t V3Layer::sIBConnBodyYHeight = 2.5 * sMm;
103const Double_t V3Layer::sIBConnTailYShift = 0.9 * sMm;
104const Double_t V3Layer::sIBConnTailYMid = 2.5 * sMm;
105const Double_t V3Layer::sIBConnTailZLen = 2.5 * sMm;
106const Double_t V3Layer::sIBConnTailOpenPhi = 120.0; // Deg
107const Double_t V3Layer::sIBConnRoundHoleD = 2.0 * sMm;
108const Double_t V3Layer::sIBConnRoundHoleZ = (9.0 - 4.0) * sMm;
109const Double_t V3Layer::sIBConnSquareHoleX = 2.0 * sMm;
110const Double_t V3Layer::sIBConnSquareHoleZ = 2.8 * sMm;
111const Double_t V3Layer::sIBConnSquareHoleZPos = 9.0 * sMm;
112const Double_t V3Layer::sIBConnInsertHoleD = 2.0 * sMm;
113const Double_t V3Layer::sIBConnInsertHoleZPos = 9.0 * sMm;
114const Double_t V3Layer::sIBConnTubeHole1D = 1.6 * sMm;
115const Double_t V3Layer::sIBConnTubeHole1ZLen = 3.0 * sMm;
116const Double_t V3Layer::sIBConnTubeHole1ZLen2 = 2.7 * sMm;
117const Double_t V3Layer::sIBConnTubeHole2D = 1.2 * sMm;
118const Double_t V3Layer::sIBConnTubeHole3XPos = 1.0 * sMm;
119const Double_t V3Layer::sIBConnTubeHole3ZPos = 14.5 * sMm;
120const Double_t V3Layer::sIBConnTubesXDist = 5.0 * sMm;
121const Double_t V3Layer::sIBConnTubesYPos = 1.25 * sMm;
122const Double_t V3Layer::sIBConnInsertD = 2.0 * sMm;
123const Double_t V3Layer::sIBConnInsertHeight = 2.3 * sMm;
124const Double_t V3Layer::sIBConnSideHole1D = 1.0 * sMm;
125const Double_t V3Layer::sIBConnSideHole1YPos = 1.25 * sMm;
126const Double_t V3Layer::sIBConnSideHole1ZPos = 11.5 * sMm;
127const Double_t V3Layer::sIBConnSideHole1XWid = 1.0 * sMm;
128const Double_t V3Layer::sIBConnSideHole2YPos = 1.25 * sMm;
129const Double_t V3Layer::sIBConnSideHole2ZPos = 11.0 * sMm;
130const Double_t V3Layer::sIBConnSideHole2XWid = 1.0 * sMm;
131const Double_t V3Layer::sIBConnSideHole2YWid = 1.0 * sMm;
132const Double_t V3Layer::sIBConnSideHole2ZWid = 1.0 * sMm;
133const Double_t V3Layer::sIBConnectAFitExtD = 1.65 * sMm;
134const Double_t V3Layer::sIBConnectAFitIntD = 1.19 * sMm;
135const Double_t V3Layer::sIBConnectAFitZLen = 12.5 * sMm;
136const Double_t V3Layer::sIBConnectAFitZOut = 10.0 * sMm;
137const Double_t V3Layer::sIBConnPlugInnerD = 0.8 * sMm;
138const Double_t V3Layer::sIBConnPlugTotLen = 1.7 * sMm;
139const Double_t V3Layer::sIBConnPlugInnerLen = 1.0 * sMm;
140
141const Double_t V3Layer::sIBStaveHeight = 0.5 * sCm;
142
143// Outer Barrel Parameters
144const Int_t V3Layer::sOBChipsPerRow = 7;
145const Int_t V3Layer::sOBNChipRows = 2;
146
147const Double_t V3Layer::sOBChipThickness = 100.0 * sMicron;
148
149const Double_t V3Layer::sOBHalfStaveWidth = 3.01 * sCm;
150const Double_t V3Layer::sOBModuleGap = 200.0 * sMicron;
151const Double_t V3Layer::sOBChipXGap = 150.0 * sMicron;
152const Double_t V3Layer::sOBChipZGap = 150.0 * sMicron;
153const Double_t V3Layer::sOBFlexCableXWidth = 3.3 * sCm;
154const Double_t V3Layer::sOBFlexCableAlThick = 0.005 * sCm;
155const Double_t V3Layer::sOBFlexCableKapThick = 75.0 * sMicron;
156const Double_t V3Layer::sOBFPCSoldMaskThick = 30.0 * sMicron;
157const Double_t V3Layer::sOBFPCCopperThick = 18.0 * sMicron;
158const Double_t V3Layer::sOBFPCCuAreaFracGnd = 0.954; // F.Benotto
159const Double_t V3Layer::sOBFPCCuAreaFracSig = 0.617; // F.Benotto
160const Double_t V3Layer::sOBGlueFPCThick = 50 * sMicron;
161const Double_t V3Layer::sOBGlueColdPlThick = 80 * sMicron;
162const Double_t V3Layer::sOBPowerBusXWidth = 3.04 * sCm;
163const Double_t V3Layer::sOBPowerBusAlThick = 100.0 * sMicron;
164const Double_t V3Layer::sOBPowerBusAlFrac = 0.90; // L.Greiner
165const Double_t V3Layer::sOBPowerBusDielThick = 50.0 * sMicron;
166const Double_t V3Layer::sOBPowerBusKapThick = 27.5 * sMicron;
167const Double_t V3Layer::sOBBiasBusXWidth = 7.7 * sMm;
168const Double_t V3Layer::sOBBiasBusAlThick = 25.0 * sMicron;
169const Double_t V3Layer::sOBBiasBusAlFrac = 0.90; // L.Greiner
170const Double_t V3Layer::sOBBiasBusDielThick = 50.0 * sMicron;
171const Double_t V3Layer::sOBBiasBusKapThick = 25.0 * sMicron;
172const Double_t V3Layer::sOBColdPlateXWidth = 3.04 * sCm;
173const Double_t V3Layer::sOBColdPlateZLenML = 87.55 * sCm;
174const Double_t V3Layer::sOBColdPlateZLenOL = 150.15 * sCm;
175const Double_t V3Layer::sOBColdPlateThick = 0.012 * sCm;
176const Double_t V3Layer::sOBHalfStaveYPos = 2.067 * sCm;
177const Double_t V3Layer::sOBHalfStaveYTrans = 3.6 * sMm;
178const Double_t V3Layer::sOBHalfStaveXOverlap = 7.2 * sMm;
179const Double_t V3Layer::sOBGraphiteFoilThick = 30.0 * sMicron;
180const Double_t V3Layer::sOBCarbonFleeceThick = 20.0 * sMicron;
181const Double_t V3Layer::sOBCoolTubeInnerD = 2.05 * sMm;
182const Double_t V3Layer::sOBCoolTubeThick = 32.0 * sMicron;
183const Double_t V3Layer::sOBCoolTubeXDist = 10.0 * sMm;
184
185const Double_t V3Layer::sOBCPConnectorXWidth = 16.0 * sMm;
186const Double_t V3Layer::sOBCPConnBlockZLen = 15.0 * sMm;
187const Double_t V3Layer::sOBCPConnBlockYHei = 3.6 * sMm;
188const Double_t V3Layer::sOBCPConnHollowZLen = 3.0 * sMm;
189const Double_t V3Layer::sOBCPConnHollowYHei = 0.9 * sMm;
190const Double_t V3Layer::sOBCPConnSquareHoleX = 4.0 * sMm;
191const Double_t V3Layer::sOBCPConnSquareHoleZ = 5.0 * sMm;
192const Double_t V3Layer::sOBCPConnSqrHoleZPos = 4.0 * sMm;
193const Double_t V3Layer::sOBCPConnSqrInsertRZ = 3.5 * sMm;
194const Double_t V3Layer::sOBCPConnRoundHoleD = 4.0 * sMm;
195const Double_t V3Layer::sOBCPConnRndHoleZPos = 7.0 * sMm;
196const Double_t V3Layer::sOBCPConnTubesXDist = 10.0 * sMm;
197const Double_t V3Layer::sOBCPConnTubesYPos = 1.8 * sMm;
198const Double_t V3Layer::sOBCPConnTubeHole1D = 2.6 * sMm;
199const Double_t V3Layer::sOBCPConnTubeHole1Z = 3.5 * sMm;
200const Double_t V3Layer::sOBCPConnTubeHole2D = 2.2 * sMm;
201const Double_t V3Layer::sOBCPConnFitHoleD = 2.8 * sMm;
202const Double_t V3Layer::sOBCPConnTubeHole3XP = 1.0 * sMm;
203const Double_t V3Layer::sOBCPConnTubeHole3ZP = 2.0 * sMm;
204const Double_t V3Layer::sOBCPConnInstZThick = 1.0 * sMm;
205const Double_t V3Layer::sOBCPConnInsertYHei = 3.4 * sMm;
206const Double_t V3Layer::sOBCPConnAFitExtD = 2.8 * sMm;
207const Double_t V3Layer::sOBCPConnAFitThick = 0.3 * sMm;
208const Double_t V3Layer::sOBCPConnAFitZLen = 17.0 * sMm;
209const Double_t V3Layer::sOBCPConnAFitZIn = 3.0 * sMm;
210const Double_t V3Layer::sOBCPConnPlugInnerD = 0.8 * sMm;
211const Double_t V3Layer::sOBCPConnPlugTotLen = 1.7 * sMm;
212const Double_t V3Layer::sOBCPConnPlugThick = 0.5 * sMm;
213
214const Double_t V3Layer::sOBSpaceFrameZLen[2] = {900.0 * sMm, 1526.0 * sMm};
215const Int_t V3Layer::sOBSpaceFrameNUnits[2] = {23, 39};
216const Double_t V3Layer::sOBSpaceFrameUnitLen = 39.1 * sMm;
217const Double_t V3Layer::sOBSpaceFrameWidth = 42.44 * sMm;
218const Double_t V3Layer::sOBSpaceFrameHeight = 36.45 * sMm;
219const Double_t V3Layer::sOBSpaceFrameTopVL = 4.0 * sMm;
220const Double_t V3Layer::sOBSpaceFrameTopVH = 0.35 * sMm;
221const Double_t V3Layer::sOBSpaceFrameSideVL = 4.5 * sMm;
222const Double_t V3Layer::sOBSpaceFrameSideVH = 0.35 * sMm;
223const Double_t V3Layer::sOBSpaceFrameVAlpha = 60.0; // deg
224const Double_t V3Layer::sOBSpaceFrameVBeta = 68.0; // deg
225const Double_t V3Layer::sOBSFrameBaseRibDiam = 1.33 * sMm;
226const Double_t V3Layer::sOBSFrameBaseRibPhi = 54.0; // deg
227const Double_t V3Layer::sOBSFrameSideRibDiam = 1.25 * sMm;
228const Double_t V3Layer::sOBSFrameSideRibPhi = 70.0; // deg
229const Double_t V3Layer::sOBSFrameULegLen = 14.2 * sMm;
230const Double_t V3Layer::sOBSFrameULegWidth = 1.5 * sMm;
231const Double_t V3Layer::sOBSFrameULegHeight1 = 6.3 * sMm;
232const Double_t V3Layer::sOBSFrameULegHeight2 = 2.7 * sMm;
233const Double_t V3Layer::sOBSFrameULegThick = 0.3 * sMm;
234const Double_t V3Layer::sOBSFrameULegXPos = 12.9 * sMm;
235const Double_t V3Layer::sOBSFrameConnWidth = 42.0 * sMm;
236const Double_t V3Layer::sOBSFrameConnTotLen = 29.0 * sMm;
237const Double_t V3Layer::sOBSFrameConnTotHei = 4.8 * sMm;
238const Double_t V3Layer::sOBSFrameConnTopLen = 14.0 * sMm;
239const Double_t V3Layer::sOBSFrameConnInsWide = 36.869 * sMm;
240const Double_t V3Layer::sOBSFrameConnInsBase = 39.6 * sMm;
241const Double_t V3Layer::sOBSFrameConnInsHei = 2.8 * sMm;
242const Double_t V3Layer::sOBSFrameConnHoleZPos = 7.0 * sMm;
243const Double_t V3Layer::sOBSFrameConnHoleZDist = 15.0 * sMm;
244const Double_t V3Layer::sOBSFrameConnTopHoleD = 3.0 * sMm;
245const Double_t V3Layer::sOBSFrConnTopHoleXDist = 24.0 * sMm;
246const Double_t V3Layer::sOBSFrameConnAHoleWid = 4.0 * sMm;
247const Double_t V3Layer::sOBSFrameConnAHoleLen = 5.0 * sMm;
248const Double_t V3Layer::sOBSFrConnASideHoleD = 3.0 * sMm;
249const Double_t V3Layer::sOBSFrConnASideHoleL = 2.5 * sMm;
250const Double_t V3Layer::sOBSFrConnASideHoleY = 2.3 * sMm;
251const Double_t V3Layer::sOBSFrameConnCHoleZPos = 3.0 * sMm;
252const Double_t V3Layer::sOBSFrConnCHoleXDist = 32.0 * sMm;
253const Double_t V3Layer::sOBSFrConnCTopHoleD = 4.0 * sMm;
254const Double_t V3Layer::sOBSFrameConnInsHoleD = 5.0 * sMm;
255const Double_t V3Layer::sOBSFrameConnInsHoleX = 25.8 * sMm;
256
258
259#define SQ(A) (A) * (A)
260
262 : V11Geometry(0, "ITS"),
263 mLayerNumber(0),
264 mPhi0(0),
265 mLayerRadius(0),
266 mSensorThickness(0),
267 mChipThickness(0),
268 mStaveWidth(0),
269 mStaveTilt(0),
270 mNumberOfStaves(0),
271 mNumberOfModules(0),
272 mNumberOfChips(0),
273 mChipTypeID(0),
274 mIsTurbo(0),
275 mBuildLevel(0),
276 mStaveModel(kIBModelDummy),
277 mIBModuleZLength(0),
278 mOBModuleZLength(0)
279{
280 for (int i = kNHLevels; i--;) {
281 mHierarchy[i] = 0;
282 }
283}
284
285V3Layer::V3Layer(Int_t lay, Bool_t turbo, Int_t debug, const char* name)
287 mLayerNumber(lay),
288 mPhi0(0),
289 mLayerRadius(0),
290 mSensorThickness(0),
291 mChipThickness(0),
292 mStaveWidth(0),
293 mStaveTilt(0),
294 mNumberOfStaves(0),
295 mNumberOfModules(0),
296 mNumberOfChips(0),
297 mChipTypeID(0),
298 mIsTurbo(turbo),
299 mBuildLevel(0),
300 mStaveModel(kIBModelDummy),
301 mIBModuleZLength(0),
302 mOBModuleZLength(0)
303{
304 for (int i = kNHLevels; i--;) {
305 mHierarchy[i] = 0;
306 }
307}
308
309V3Layer::~V3Layer() = default;
310
311void V3Layer::createLayer(TGeoVolume* motherVolume)
312{
313 std::string volumeName;
314
315 volumeName = fmt::format("{:s}{:d}", GeometryTGeo::getITSLayerPattern(), mLayerNumber);
316 TGeoVolume* layerVolume = new TGeoVolumeAssembly(volumeName.c_str());
317
318 // Call for creation of a single Half Barrel
319 // and put two copies in the Layer volume
320 TGeoVolume* halfBarrel;
321
322 // If a Turbo layer is requested, do it
323 if (mIsTurbo) {
324 halfBarrel = createHalfBarrelTurbo();
325 } else {
326 halfBarrel = createHalfBarrel();
327 }
328
329 layerVolume->AddNode(halfBarrel, 0, nullptr);
330 layerVolume->AddNode(halfBarrel, 1, new TGeoRotation("", 180, 0, 0));
331 mHierarchy[kHalfBarrel] = 2;
332
333 // Finally put everything in the mother volume
334 motherVolume->AddNode(layerVolume, 1, nullptr);
335
336 // geometry is served
337 return;
338}
339
340TGeoVolume* V3Layer::createHalfBarrel()
341{
342 const Int_t nameLen = 30;
343 char volumeName[nameLen];
344 Double_t xpos, ypos, zpos;
345 Double_t alpha;
346
347 // Check if the user set the proper parameters
348 if (mLayerRadius <= 0) {
349 LOG(fatal) << "Wrong layer radius " << mLayerRadius;
350 }
351
352 if (mNumberOfStaves <= 0) {
353 LOG(fatal) << "Wrong number of staves " << mNumberOfStaves;
354 }
355
356 if (mNumberOfChips <= 0) {
357 LOG(fatal) << "Wrong number of chips " << mNumberOfChips;
358 }
359
360 if (mLayerNumber >= sNumberOfInnerLayers && mNumberOfModules <= 0) {
361 LOG(fatal) << "Wrong number of modules " << mNumberOfModules;
362 }
363
364 if (mChipThickness <= 0) {
365 LOG(fatal) << "Chip thickness wrong or not set " << mChipThickness;
366 }
367
368 if (mSensorThickness <= 0) {
369 LOG(fatal) << "Sensor thickness wrong or not set " << mSensorThickness;
370 }
371
372 if (mSensorThickness > mChipThickness) {
373 LOG(fatal) << "Sensor thickness " << mSensorThickness << " is greater than chip thickness " << mChipThickness;
374 }
375
376 // First create the stave container
377 alpha = (360. / (2 * mNumberOfStaves)) * DegToRad();
378
379 // mStaveWidth = mLayerRadius*Tan(alpha);
380
381 snprintf(volumeName, nameLen, "%s%d", GeometryTGeo::getITSHalfBarrelPattern(), mLayerNumber);
382 TGeoVolume* halfBarrelVolume = new TGeoVolumeAssembly(volumeName);
383 halfBarrelVolume->SetUniqueID(mChipTypeID);
384
385 // halfBarrelVolume->SetVisibility(kFALSE);
386 halfBarrelVolume->SetVisibility(kTRUE);
387 halfBarrelVolume->SetLineColor(1);
388
389 TGeoVolume* stavVol = createStave();
390
391 // Now build up the layer
392 alpha = 360. / mNumberOfStaves;
393 Double_t r = mLayerRadius + (static_cast<TGeoBBox*>(stavVol->GetShape()))->GetDY();
394 mHierarchy[kStave] = 0;
395 for (Int_t j = 0; j < mNumberOfStaves / 2; j++) {
396 Double_t phi = j * alpha + mPhi0;
397 xpos = r * cosD(phi); // r*sinD(-phi);
398 ypos = r * sinD(phi); // r*cosD(-phi);
399 zpos = 0.;
400 phi += 90;
401 halfBarrelVolume->AddNode(stavVol, j, new TGeoCombiTrans(xpos, ypos, zpos, new TGeoRotation("", phi, 0, 0)));
402 mHierarchy[kStave]++;
403 }
404
405 // geometry is served
406 return halfBarrelVolume;
407}
408
409TGeoVolume* V3Layer::createHalfBarrelTurbo()
410{
411 const Int_t nameLen = 30;
412 char volumeName[nameLen];
413 Double_t xpos, ypos, zpos;
414 Double_t alpha;
415
416 // Check if the user set the proper (remaining) parameters
417 if (mStaveWidth <= 0) {
418 LOG(fatal) << "Wrong stave width " << mStaveWidth;
419 }
420
421 if (Abs(mStaveTilt) > 45) {
422 LOG(warning) << "Stave tilt angle (" << mStaveTilt << ") greater than 45deg";
423 }
424
425 snprintf(volumeName, nameLen, "%s%d", GeometryTGeo::getITSHalfBarrelPattern(), mLayerNumber);
426 TGeoVolume* halfBarrelVolume = new TGeoVolumeAssembly(volumeName);
427 halfBarrelVolume->SetUniqueID(mChipTypeID);
428 halfBarrelVolume->SetVisibility(kTRUE);
429 halfBarrelVolume->SetLineColor(1);
430 TGeoVolume* stavVol = createStave();
431
432 // Now build up the layer
433 alpha = 360. / mNumberOfStaves;
434 Double_t r = mLayerRadius /* +chip thick ?! */;
435 mHierarchy[kStave] = 0;
436 for (Int_t j = 0; j < mNumberOfStaves / 2; j++) {
437 Double_t phi = j * alpha + mPhi0;
438 xpos = r * cosD(phi); // r*sinD(-phi);
439 ypos = r * sinD(phi); // r*cosD(-phi);
440 zpos = 0.;
441 phi += 90;
442 halfBarrelVolume->AddNode(stavVol, j,
443 new TGeoCombiTrans(xpos, ypos, zpos, new TGeoRotation("", phi - mStaveTilt, 0, 0)));
444 mHierarchy[kStave]++;
445 }
446
447 return halfBarrelVolume;
448}
449
450TGeoVolume* V3Layer::createStave(const TGeoManager* /*mgr*/)
451{
452 //
453 // Creates the actual Stave
454 //
455 // Input:
456 // mgr : the GeoManager (used only to get the proper material)
457 //
458 // Output:
459 //
460 // Return:
461 //
462 // Created: 22 Jun 2011 Mario Sitta
463 // Updated: 18 Dec 2013 Mario Sitta Handle IB and OB
464 // Updated: 12 Jan 2015 Mario Sitta Fix overlap with new OB space frame
465 // (by moving the latter, not the sensors to avoid
466 // spoiling their position in space)
467 // Updated: 03 Mar 2015 Mario Sitta Fix chip position
468 // Updated: 16 Mar 2017 Mario Sitta AliceO2 version
469 // Updated: 10 Jan 2018 Mario Sitta Compute all dimensions using
470 // AlpideChip as basis
471 // Updated: 10 Mar 2021 Mario Sitta Get rid of fake IB HS and Module
472 //
473
474 const Int_t nameLen = 30;
475 char volumeName[nameLen];
476
477 Double_t xpos, ypos, ymod;
478
479 // The stave
480 snprintf(volumeName, nameLen, "%s%d", GeometryTGeo::getITSStavePattern(), mLayerNumber);
481 TGeoVolume* staveVol = new TGeoVolumeAssembly(volumeName);
482 staveVol->SetVisibility(kTRUE);
483 staveVol->SetLineColor(2);
484
485 TGeoVolume* mechStaveVol = nullptr;
486
487 // Now build up the stave
488 if (mLayerNumber < sNumberOfInnerLayers) {
489 ymod = createStaveInnerB(staveVol);
490 ypos = ymod - mChipThickness; // = 0 if not kIBModel4
491 mHierarchy[kHalfStave] = 0;
492 mHierarchy[kModule] = 0;
493
494 // Mechanical stave structure
495 mechStaveVol = createStaveStructInnerB();
496 if (mechStaveVol) {
497 ypos = ymod - ypos;
498 if (mStaveModel != kIBModel4) {
499 ypos += (static_cast<TGeoBBox*>(mechStaveVol->GetShape()))->GetDY();
500 }
501 staveVol->AddNode(mechStaveVol, 1, new TGeoCombiTrans(0, -ypos, 0, new TGeoRotation("", 0, 0, 180)));
502 }
503 } else {
504 TGeoVolume* hstaveVol = createStaveOuterB();
505 if (mStaveModel == kOBModel0) { // Create simplified stave struct as in v0
506 staveVol->AddNode(hstaveVol, 0);
507 mHierarchy[kHalfStave] = 1;
508 } else { // (if mStaveModel) Create new stave struct as in TDR
509 xpos = (static_cast<TGeoBBox*>(hstaveVol->GetShape()))->GetDX() - sOBHalfStaveXOverlap / 2;
510 // ypos is now a parameter to avoid HS displacement wrt nominal radii
511 ypos = sOBHalfStaveYPos;
512 staveVol->AddNode(hstaveVol, 0, new TGeoTranslation(-xpos, ypos + sOBHalfStaveYTrans, 0));
513 staveVol->AddNode(hstaveVol, 1, new TGeoTranslation(xpos, ypos, 0));
514 mHierarchy[kHalfStave] = 2; // RS
515 mechStaveVol = createSpaceFrameOuterB();
516
517 if (mechStaveVol) {
518 if (mBuildLevel < 6) { // Carbon
519 staveVol->AddNode(mechStaveVol, 1,
520 new TGeoCombiTrans(0, -sOBSFrameULegHeight2, 0, new TGeoRotation("", 180, 0, 0)));
521 }
522 }
523 }
524 }
525
526 staveVol->GetShape()->ComputeBBox(); // RS: enfore recompting of BBox
527
528 // Done, return the stave
529 return staveVol;
530}
531
532Double_t V3Layer::createStaveInnerB(TGeoVolume* mother, const TGeoManager* mgr)
533{
534 Double_t xtot, ytot, ztot, xchip, zchip, ymod;
535 Double_t xpos, ypos, zpos;
536 Bool_t dummyChip;
537 const Int_t nameLen = 30;
538 char chipName[nameLen], sensName[nameLen], volumeName[nameLen];
539
540 // For material budget studies
541 if (mBuildLevel < 6) {
542 dummyChip = kFALSE; // will be made of Si
543 } else {
544 dummyChip = kTRUE; // will be made of Air
545 }
546
547 // First create the single chip
548 snprintf(chipName, nameLen, "%s%d", GeometryTGeo::getITSChipPattern(), mLayerNumber);
549 snprintf(sensName, nameLen, "%s%d", GeometryTGeo::getITSSensorPattern(), mLayerNumber);
550
551 ymod = 0.5 * mChipThickness;
552
553 TGeoVolume* chipVol = AlpideChip::createChip(ymod, mSensorThickness / 2, chipName, sensName, dummyChip);
554
555 xchip = (static_cast<TGeoBBox*>(chipVol->GetShape()))->GetDX();
556 zchip = (static_cast<TGeoBBox*>(chipVol->GetShape()))->GetDZ();
557
558 mIBModuleZLength = 2 * zchip * sIBChipsPerRow + (sIBChipsPerRow - 1) * sIBChipZGap;
559
560 xtot = xchip + (sIBFPCWiderXPlus + sIBFPCWiderXNeg) / 2;
561 ztot = mIBModuleZLength / 2;
562
563 // Then create all other elements (glue and FPC)
564 TGeoVolume* ibModule = createModuleInnerB(xchip, zchip);
565
566 // Build up the stave
567 // Chips are rotated by 180deg around Y axis
568 // in order to have the correct X and Z axis orientation
569 ypos = ymod - mChipThickness;
570
571 for (Int_t j = 0; j < sIBChipsPerRow; j++) {
572 zpos = ztot - j * (2 * zchip + sIBChipZGap) - zchip;
573 mother->AddNode(chipVol, j, new TGeoCombiTrans(0, ypos, zpos, new TGeoRotation("", 0, 180, 180)));
574 mHierarchy[kChip]++;
575 }
576 ytot = ymod;
577
578 // Place the FPC and glue
579 if (mStaveModel == kIBModel4) {
580 Double_t yvol = (static_cast<TGeoBBox*>(ibModule->GetShape()))->GetDY();
581 xpos = 0.5 * (xtot - xchip);
582 ypos += (ymod + yvol);
583 mother->AddNode(ibModule, 1, new TGeoTranslation(xpos, ypos, 0));
584 ytot += yvol;
585 }
586
587 // Done, return the total thickness (used to properly place the services)
588 return ytot;
589}
590
591TGeoVolume* V3Layer::createModuleInnerB(const Double_t xchip, const Double_t zchip, const TGeoManager* mgr)
592{
593 //
594 // Creates the FPC and glue volumes
595 // (zimilar to previous method, except the Chips)
596 //
597 // Input:
598 // xchip : the Chip width
599 // zchip : the Chip length
600 // mgr : the GeoManager (used only to get the proper material)
601 //
602 // Output:
603 //
604 // Return:
605 // the module as a TGeoVolume
606 //
607 // Updated: 03 Apr 2021
608 // Updated: 03 Nov 2025 Change volume from BBox to Xtru to avoid fake overlaps
609
610 Double_t xtot, ytot, ztot;
611 Double_t ymid, shrinkFactor = 0.73;
612 Double_t xv[5], yv[5];
613 Double_t xpos, ypos, zpos;
614 const Int_t nameLen = 30;
615 char volumeName[nameLen];
616
617 // Create the Glue, the Kapton and the two Aluminum cables
618 xtot = xchip + (sIBFPCWiderXPlus + sIBFPCWiderXNeg) / 2;
619 ztot = mIBModuleZLength / 2;
620
621 TGeoBBox* glue = new TGeoBBox(xchip, sIBGlueThick / 2, ztot);
622 TGeoBBox* kapCable = new TGeoBBox(xtot, sIBFlexCableKapThick / 2, ztot);
623
624 TGeoVolume* aluGndCableVol = createIBFPCAlGnd(xtot, ztot);
625 TGeoVolume* aluAnodeCableVol = createIBFPCAlAnode(xtot, ztot);
626
627 // Then create the module volume
628 Double_t ygnd = (static_cast<TGeoBBox*>(aluGndCableVol->GetShape()))->GetDY();
629 Double_t yano = (static_cast<TGeoBBox*>(aluAnodeCableVol->GetShape()))->GetDY();
630
631 ytot = sIBGlueThick / 2 + ygnd + sIBFlexCableKapThick / 2 + yano + sIBFlexCapacitor22YHi / 2;
632 ymid = sIBGlueThick / 2 + ygnd + sIBFlexCableKapThick / 2 + yano;
633
634 xv[0] = xtot;
635 yv[0] = -ytot;
636 xv[1] = xv[0];
637 yv[1] = yv[0] + 6 * ymid;
638 xv[2] = xtot * shrinkFactor;
639 yv[2] = ytot;
640 xv[3] = -xtot;
641 yv[3] = yv[2];
642 xv[4] = xv[3];
643 yv[4] = yv[0];
644
645 TGeoXtru* module = new TGeoXtru(2);
646 module->DefinePolygon(6, xv, yv);
647 module->DefinePolygon(5, xv, yv);
648 module->DefineSection(0, -ztot);
649 module->DefineSection(1, ztot);
650
651 // Now the volumes
652 TGeoMedium* medAir = mgr->GetMedium(Form("%s_AIR$", GetDetName()));
653 TGeoMedium* medKapton = mgr->GetMedium(Form("%s_KAPTON(POLYCH2)$", GetDetName()));
654 TGeoMedium* medGlue = mgr->GetMedium(Form("%s_GLUE_IBFPC$", GetDetName()));
655
656 snprintf(volumeName, nameLen, "ServicesContainer%d", mLayerNumber);
657 TGeoVolume* modVol = new TGeoVolume(volumeName, module, medAir);
658
659 TGeoVolume* glueVol = new TGeoVolume("FPCGlue", glue, medGlue);
660 glueVol->SetLineColor(kBlack);
661 glueVol->SetFillColor(kBlack);
662
663 TGeoVolume* kapCableVol = new TGeoVolume("FPCKapton", kapCable, medKapton);
664 kapCableVol->SetLineColor(kBlue);
665 kapCableVol->SetFillColor(kBlue);
666
667 // Build up the module
668 xpos = -xtot + xchip + sIBFPCWiderXNeg;
669 ypos = -ytot + glue->GetDY();
670 if (mBuildLevel < 2) { // Glue
671 modVol->AddNode(glueVol, 1, new TGeoTranslation(xpos, ypos, 0));
672 }
673 ypos += glue->GetDY();
674
675 if (mBuildLevel < 4) { // Kapton
676 ypos += ygnd;
677 modVol->AddNode(aluGndCableVol, 1, new TGeoTranslation(0, ypos, 0));
678
679 ypos += (ygnd + kapCable->GetDY());
680 modVol->AddNode(kapCableVol, 1, new TGeoTranslation(0, ypos, 0));
681
682 ypos += (kapCable->GetDY() + yano);
683 modVol->AddNode(aluAnodeCableVol, 1, new TGeoTranslation(0, ypos, 0));
684
685 ypos += yano;
686 }
687
688 // Add the capacitors
689 createIBCapacitors(modVol, zchip, ypos);
690
691 // Done, return the module
692 return modVol;
693}
694
695void V3Layer::createIBCapacitors(TGeoVolume* modvol, Double_t zchip, Double_t yzero, const TGeoManager* mgr)
696{
697 //
698 // Adds the capacitors to the IB FPC
699 //
700 // Created: 13 Feb 2018 Mario Sitta
701 // Updated: 03 Apr 2019 Mario Sitta Fix positions (180' rotation)
702 // Updated: 31 Oct 2025 Mario Sitta Fix dimensions and weight
703 //
704
705 // Position of the various capacitors (A.Junique private communication
706 // where: X_capacitor = Z_module , Y_capacitor = X_module)
707 // Capacitors (different groups)
708 const Double_t xGroup1A = 4265.9 * sMicron;
709 const Double_t zGroup1A[2] = {-7142.9 * sMicron, 7594.1 * sMicron};
710 const Double_t xGroup1B = 690.9 * sMicron;
711 const Double_t zGroup1B = -7142.9 * sMicron;
712 const Double_t xGroup2 = 6300.0 * sMicron;
713 const Double_t zGroup2 = 15075.0 * sMicron;
714 const Double_t xGroup3 = 5575.0 * sMicron;
715 const Double_t zGroup3 = 131900.0 * sMicron;
716 const Double_t xGroup4[2] = {5600.0 * sMicron, 5575.0 * sMicron};
717 const Double_t zGroup4[sIBChipsPerRow] = {275.0 * sMicron, 250.0 * sMicron, 275.0 * sMicron,
718 250.0 * sMicron, 250.0 * sMicron, 300.0 * sMicron,
719 250.0 * sMicron, 300.0 * sMicron, 250.0 * sMicron};
720 const Int_t nGroup5A = 5, nGroup5B = 4;
721 const Double_t xGroup5A[2] = {1400.0 * sMicron, 1350.0 * sMicron};
722 const Double_t zGroup5A[nGroup5A] = {-112957.5 * sMicron, -82854.5 * sMicron, 7595.5 * sMicron, 37745.5 * sMicron,
723 128194.1 * sMicron};
724 const Double_t xGroup5B = 1100.0 * sMicron;
725 const Double_t zGroup5B[nGroup5B] = {-51525.0 * sMicron, -21375.0 * sMicron, 69075.0 * sMicron, 99225.0 * sMicron};
726 // Resistors
727 const Int_t nResist = 2;
728 const Double_t xResist = -7975.0 * sMicron;
729 const Double_t zResist[nResist] = {114403.0 * sMicron, 119222.0 * sMicron};
730
731 Double_t xpos, ypos, zpos;
732 Int_t nCapacitors;
733
734 TGeoVolume *capacitorSmall, *capacitorLarge, *resistor;
735
736 // Check whether we already have the volumes, otherwise create them
737 // (so as to avoid creating multiple copies of the very same volumes
738 // for each layer)
739 // The "small" capacitor is the 1 uF substrate capacitor
740 // The "large" capacitor is the 22 uF analog/digital PS capacitor
741 capacitorSmall = mgr->GetVolume("IBFPCCapacitorSmall");
742
743 if (!capacitorSmall) {
744 TGeoBBox* capSmsh = new TGeoBBox(sIBFlexCapacitor1XWid / 2, sIBFlexCapacitor1YHi / 2, sIBFlexCapacitor1ZLen / 2);
745 TGeoBBox* capLgsh = new TGeoBBox(sIBFlexCapacitor22XWid / 2, sIBFlexCapacitor22YHi / 2, sIBFlexCapacitor22ZLen / 2);
746
747 TGeoMedium* medCeramic = mgr->GetMedium(Form("%s_CERAMIC$", GetDetName()));
748
749 capacitorSmall = new TGeoVolume("IBFPCCapacitorSmall", capSmsh, medCeramic);
750 capacitorSmall->SetLineColor(kBlack);
751 capacitorSmall->SetFillColor(kBlack);
752
753 capacitorLarge = new TGeoVolume("IBFPCCapacitorLarge", capLgsh, medCeramic);
754 capacitorLarge->SetLineColor(kBlack);
755 capacitorLarge->SetFillColor(kBlack);
756
757 TGeoBBox* ressh = new TGeoBBox(sIBFlexResistorXWid / 2,
758 sIBFlexResistorYHi / 2,
759 sIBFlexResistorZLen / 2);
760
761 resistor = new TGeoVolume("IBFPCResistor", ressh, medCeramic);
762 resistor->SetLineColor(kBlack);
763 resistor->SetFillColor(kBlack);
764 } else { // Volumes already defined, get them
765 capacitorLarge = mgr->GetVolume("IBFPCCapacitorLarge");
766 resistor = mgr->GetVolume("IBFPCResistor");
767 }
768
769 // Place all the capacitors (they are really a lot...)
770 ypos = yzero + sIBFlexCapacitor22YHi / 2;
771
772 xpos = xGroup1A;
773 for (Int_t j = 0; j < sIBChipsPerRow; j++) {
774 zpos = -mIBModuleZLength / 2 + j * (2 * zchip + sIBChipZGap) + zchip + zGroup1A[0];
775 modvol->AddNode(capacitorLarge, 2 * j + 1, new TGeoTranslation(-xpos, ypos, -zpos));
776 zpos = -mIBModuleZLength / 2 + j * (2 * zchip + sIBChipZGap) + zchip + zGroup1A[1];
777 modvol->AddNode(capacitorLarge, 2 * j + 2, new TGeoTranslation(-xpos, ypos, -zpos));
778 }
779
780 nCapacitors = 2 * sIBChipsPerRow;
781 xpos = xGroup1B;
782 for (Int_t j = 0; j < sIBChipsPerRow; j++) {
783 zpos = -mIBModuleZLength / 2 + j * (2 * zchip + sIBChipZGap) + zchip + zGroup1B;
784 modvol->AddNode(capacitorLarge, j + 1 + nCapacitors, new TGeoTranslation(-xpos, ypos, -zpos));
785 }
786
787 nCapacitors += sIBChipsPerRow;
788 ypos = yzero + sIBFlexCapacitor1YHi / 2;
789 xpos = xGroup2;
790 // We have only 8 in these group, missing the central one
791 for (Int_t j = 0; j < sIBChipsPerRow - 1; j++) {
792 zpos = -mIBModuleZLength / 2 + j * (2 * zchip + sIBChipZGap) + zchip + zGroup2;
793 modvol->AddNode(capacitorSmall, j + 1 + nCapacitors, new TGeoTranslation(-xpos, ypos, -zpos));
794 }
795
796 nCapacitors += (sIBChipsPerRow - 1);
797 xpos = xGroup3;
798 zpos = zGroup3;
799 modvol->AddNode(capacitorSmall, 1 + nCapacitors, new TGeoTranslation(-xpos, ypos, -zpos));
800
801 nCapacitors++;
802 for (Int_t j = 0; j < sIBChipsPerRow; j++) {
803 if (j == (sIBChipsPerRow - 1)) {
804 xpos = xGroup4[1];
805 } else {
806 xpos = xGroup4[0];
807 }
808 zpos = -mIBModuleZLength / 2 + j * (2 * zchip + sIBChipZGap) + zchip + zGroup4[j];
809 modvol->AddNode(capacitorSmall, j + 1 + nCapacitors, new TGeoTranslation(-xpos, ypos, -zpos));
810 }
811
812 nCapacitors += sIBChipsPerRow;
813 ypos = yzero + sIBFlexCapacitor22YHi / 2;
814 for (Int_t j = 0; j < nGroup5A; j++) {
815 if (j == 0) {
816 xpos = xGroup5A[0];
817 } else {
818 xpos = xGroup5A[1];
819 }
820 zpos = zGroup5A[j];
821 modvol->AddNode(capacitorLarge, j + 1 + nCapacitors, new TGeoTranslation(-xpos, ypos, -zpos));
822 }
823
824 nCapacitors += nGroup5A;
825 xpos = xGroup5B;
826 for (Int_t j = 0; j < nGroup5B; j++) {
827 zpos = zGroup5B[j];
828 modvol->AddNode(capacitorLarge, j + 1 + nCapacitors, new TGeoTranslation(-xpos, ypos, -zpos));
829 }
830
831 // Place the resistors
832 xpos = xResist;
833 for (Int_t j = 0; j < nResist; j++) {
834 zpos = zResist[j];
835 modvol->AddNode(resistor, j + 1, new TGeoTranslation(-xpos, ypos, -zpos));
836 }
837}
838
839TGeoVolume* V3Layer::createIBFPCAlGnd(const Double_t xcable, const Double_t zcable, const TGeoManager* mgr)
840{
841 //
842 // Create the IB FPC Aluminum Ground cable
843 //
844 // Created: 20 Oct 2017 Mario Sitta
845 //
846
847 Double_t ytot, ypos;
848
849 // First create all needed shapes
850 ytot = sIBFlexCablePolyThick + sIBFlexCableAlThick;
851 TGeoBBox* coverlay = new TGeoBBox(xcable, ytot / 2, zcable);
852 TGeoBBox* aluminum = new TGeoBBox(xcable, sIBFlexCableAlThick / 2, zcable);
853
854 // Then the volumes
855 TGeoMedium* medKapton = mgr->GetMedium(Form("%s_KAPTON(POLYCH2)$", GetDetName()));
856 TGeoMedium* medAluminum = mgr->GetMedium(Form("%s_ALUMINUM$", GetDetName()));
857
858 TGeoVolume* coverlayVol = new TGeoVolume("FPCCoverlayGround", coverlay, medKapton);
859 coverlayVol->SetLineColor(kBlue);
860 coverlayVol->SetFillColor(kBlue);
861
862 TGeoVolume* aluminumVol = new TGeoVolume("FPCAluminumGround", aluminum, medAluminum);
863 aluminumVol->SetLineColor(kCyan);
864 aluminumVol->SetFillColor(kCyan);
865
866 ypos = coverlay->GetDY() - aluminum->GetDY();
867 if (mBuildLevel < 1) { // Aluminum
868 coverlayVol->AddNode(aluminumVol, 1, new TGeoTranslation(0, ypos, 0));
869 }
870
871 return coverlayVol;
872}
873
874TGeoVolume* V3Layer::createIBFPCAlAnode(const Double_t xcable, const Double_t zcable, const TGeoManager* mgr)
875{
876 //
877 // Create the IB FPC Aluminum Anode cable
878 //
879 //
880 // Created: 20 Oct 2017 Mario Sitta
881 // Updated: 03 Apr 2019 Mario Sitta Fix Al position (180' rotation)
882 //
883
884 Double_t ytot, ypos;
885 Double_t xtru[4], ytru[4];
886
887 // First create all needed shapes
888 ytot = sIBFlexCablePolyThick + sIBFlexCableAlThick;
889 TGeoBBox* coverlay = new TGeoBBox(xcable, ytot / 2, zcable);
890
891 // A trapezoid
892 xtru[0] = -sIBFPCAlAnodeWidth2 / 2;
893 ytru[0] = -zcable;
894 xtru[1] = sIBFPCAlAnodeWidth2 / 2;
895 ytru[1] = ytru[0];
896 xtru[2] = xtru[0] + sIBFPCAlAnodeWidth1;
897 ytru[2] = zcable;
898 xtru[3] = xtru[0];
899 ytru[3] = ytru[2];
900
901 TGeoXtru* aluminum = new TGeoXtru(2);
902 aluminum->DefinePolygon(4, xtru, ytru);
903 aluminum->DefineSection(0, -sIBFlexCableAlThick / 2);
904 aluminum->DefineSection(1, sIBFlexCableAlThick / 2);
905
906 // Then the volumes
907 TGeoMedium* medKapton = mgr->GetMedium(Form("%s_KAPTON(POLYCH2)$", GetDetName()));
908 TGeoMedium* medAluminum = mgr->GetMedium(Form("%s_ALUMINUM$", GetDetName()));
909
910 TGeoVolume* coverlayVol = new TGeoVolume("FPCCoverlayAnode", coverlay, medKapton);
911 coverlayVol->SetLineColor(kBlue);
912 coverlayVol->SetFillColor(kBlue);
913
914 TGeoVolume* aluminumVol = new TGeoVolume("FPCAluminumAnode", aluminum, medAluminum);
915 aluminumVol->SetLineColor(kCyan);
916 aluminumVol->SetFillColor(kCyan);
917
918 ypos = -coverlay->GetDY() + aluminum->GetZ(1);
919 if (mBuildLevel < 1) { // Aluminum
920 coverlayVol->AddNode(aluminumVol, 1, new TGeoCombiTrans(0, ypos, 0, new TGeoRotation("", 0, -90, 0)));
921 }
922
923 return coverlayVol;
924}
925
926TGeoVolume* V3Layer::createStaveStructInnerB(const TGeoManager* mgr)
927{
928 //
929 // Create the mechanical stave structure
930 //
931 // Created: 22 Mar 2013 Chinorat Kobdaj
932 // Updated: 26 Apr 2013 Mario Sitta
933 // Updated: 04 Apr 2017 Mario Sitta O2 version - All models obsolete except last one
934 // Updated: 25 Jan 2018 Mario Sitta Stave width is now a constant
935 //
936
937 TGeoVolume* mechStavVol = nullptr;
938
939 switch (mStaveModel) {
940 case kIBModelDummy:
941 mechStavVol = createStaveModelInnerBDummy(mgr);
942 break;
943 case kIBModel0:
944 case kIBModel1:
945 case kIBModel21:
946 case kIBModel22:
947 case kIBModel3:
948 LOG(fatal) << "Stave model " << mStaveModel << " obsolete and no longer supported";
949 break;
950 case kIBModel4:
951 mechStavVol = createStaveModelInnerB4(mgr);
952 break;
953 default:
954 LOG(fatal) << "Unknown stave model " << mStaveModel;
955 break;
956 }
957 return mechStavVol;
958}
959
960TGeoVolume* V3Layer::createStaveModelInnerBDummy(const TGeoManager*) const
961{
962 //
963 // Create dummy stave
964 //
965 // Created: 22 Mar 2013 Chinorat Kobdaj
966 // Updated: 26 Apr 2013 Mario Sitta
967 // Updated: 04 Apr 2017 Mario Sitta O2 version
968 //
969
970 // Done, return the stave structur
971 return nullptr;
972}
973
974// model4
975//________________________________________________________________________
976TGeoVolume* V3Layer::createStaveModelInnerB4(const TGeoManager* mgr)
977{
978 //
979 // Create the mechanical stave structure for Model 4 of TDR
980 //
981 // Input:
982 // mgr : the GeoManager (used only to get the proper material)
983 //
984 // Output:
985 //
986 // Return:
987 //
988 // Created: 04 Dec 2014 Mario Sitta
989 // Updated: 03 Mar 2015 Mario Sitta FPC in right position (beyond chip)
990 // Updated: 06 Mar 2015 Mario Sitta Space Frame corrected (C.G. data)
991 // Updated: 30 Apr 2015 Mario Sitta End-stave connectors added
992 // Updated: 04 Apr 2017 Mario Sitta O2 version
993 // Updated: 25 Jan 2018 Mario Sitta Stave width is now a constant
994 // Updated: 03 Feb 2018 Mario Sitta To last drawings (ALIITSUP0051)
995 //
996
997 // Local parameters
998 const Double_t xstave = sIBColdPlateWidth / 2;
999
1000 Double_t layerHeight = 0.;
1001
1002 Double_t rPipeMin = sIBCoolPipeInnerD / 2;
1003 Double_t rPipeMax = rPipeMin + sIBCoolPipeThick;
1004
1005 const Int_t nv = 16;
1006 Double_t xv[nv], yv[nv]; // The stave container Xtru
1007 Double_t xlen, ylen, zlen, ztot;
1008 Double_t xpos, ypos, zpos, ylay, yposPipe;
1009 Double_t beta, gamma, theta;
1010
1011 // First create all needed shapes
1012 ztot = sIBColdPlateZLen / 2;
1013
1014 TGeoBBox* glue = new TGeoBBox(xstave, sIBGlueThick / 2, ztot);
1015
1016 TGeoBBox* fleecbot = new TGeoBBox(xstave, sIBCarbonFleeceThick / 2, ztot);
1017
1018 TGeoBBox* cfplate = new TGeoBBox(xstave, sIBK13D2UThick / 2, ztot);
1019
1020 TGeoTube* pipe = new TGeoTube(rPipeMin, rPipeMax, sIBCoolPipeZLen / 2);
1021
1022 TGeoTube* water = new TGeoTube(0., rPipeMin, sIBCoolPipeZLen / 2);
1023
1024 TGeoTubeSeg* cpaptub = new TGeoTubeSeg(rPipeMax, rPipeMax + sIBCarbonPaperThick, sIBCarbonPaperZLen / 2, 0, 180);
1025
1026 TGeoBBox* cpapvert = new TGeoBBox(sIBCarbonPaperThick / 2, pipe->GetRmax() / 2, sIBCarbonPaperZLen / 2);
1027
1028 xlen = sIBCoolPipeXDist / 2 - pipe->GetRmax() - sIBCarbonPaperThick;
1029 TGeoBBox* cpapmid = new TGeoBBox(xlen, sIBCarbonPaperThick / 2, sIBCarbonPaperZLen / 2);
1030
1031 xlen = sIBCarbonPaperWidth / 2 - sIBCoolPipeXDist / 2 - pipe->GetRmax() - sIBCarbonPaperThick;
1032 TGeoBBox* cpaplr = new TGeoBBox(xlen / 2, sIBCarbonPaperThick / 2, sIBCarbonPaperZLen / 2);
1033
1034 TGeoTubeSeg* fleecpipe = new TGeoTubeSeg(cpaptub->GetRmax(), cpaptub->GetRmax() + sIBCarbonFleeceThick, ztot, 0, 180);
1035
1036 TGeoBBox* fleecvert = new TGeoBBox(sIBCarbonFleeceThick / 2, (pipe->GetRmax() - sIBCarbonPaperThick) / 2, ztot);
1037
1038 xlen = sIBCoolPipeXDist / 2 - pipe->GetRmax() - sIBCarbonPaperThick - sIBCarbonFleeceThick;
1039 TGeoBBox* fleecmid = new TGeoBBox(xlen, sIBCarbonFleeceThick / 2, ztot);
1040
1041 xlen = xstave - sIBCoolPipeXDist / 2 - pipe->GetRmax() - sIBCarbonPaperThick - sIBCarbonFleeceThick;
1042 TGeoBBox* fleeclr = new TGeoBBox(xlen / 2, sIBCarbonFleeceThick / 2, ztot);
1043
1044 // The total height of the layer can now be computed
1045 layerHeight = 2 * (glue->GetDY() + fleecbot->GetDY() + cfplate->GetDY() + cpaplr->GetDY() + fleeclr->GetDY());
1046
1047 // The spaceframe structure
1048 TGeoTrd1* topv = new TGeoTrd1(sIBTopVertexWidth1 / 2, sIBTopVertexWidth2 / 2, ztot, sIBTopVertexHeight / 2);
1049
1050 xv[0] = 0;
1051 yv[0] = 0;
1052 xv[1] = sIBSideVertexWidth;
1053 yv[1] = yv[0];
1054 xv[2] = xv[0];
1055 yv[2] = sIBSideVertexHeight;
1056
1057 TGeoXtru* sidev = new TGeoXtru(2);
1058 sidev->DefinePolygon(3, xv, yv);
1059 sidev->DefineSection(0, -ztot);
1060 sidev->DefineSection(1, ztot);
1061
1062 xv[0] = sIBEndSupportXUp / 2;
1063 yv[0] = sIBStaveHeight - sIBEndSupportThick;
1064 xv[1] = xstave - sIBSideVertexWidth;
1065 yv[1] = layerHeight + sIBSideVertexHeight;
1066 xv[2] = xstave;
1067 yv[2] = layerHeight;
1068 xv[3] = xv[2];
1069 yv[3] = 0;
1070 xv[4] = xstave + sIBEndSupportThick;
1071 yv[4] = yv[3];
1072 xv[5] = xv[4];
1073 yv[5] = yv[2];
1074 xv[6] = xv[1] + sIBEndSupportThick * sinD(sIBEndSupportOpenPhi / 2);
1075 yv[6] = yv[1] + sIBEndSupportThick * cosD(sIBEndSupportOpenPhi / 2);
1076 xv[7] = xv[0];
1077 yv[7] = sIBStaveHeight;
1078 for (Int_t i = 0; i < nv / 2; i++) {
1079 xv[8 + i] = -xv[7 - i];
1080 yv[8 + i] = yv[7 - i];
1081 }
1082
1083 TGeoXtru* endsupp = new TGeoXtru(2);
1084 endsupp->DefinePolygon(16, xv, yv);
1085 endsupp->DefineSection(0, -sIBEndSupportZLen / 2);
1086 endsupp->DefineSection(1, sIBEndSupportZLen / 2);
1087
1088 xlen = TMath::Sqrt((yv[7] - yv[6]) * (yv[7] - yv[6]) + (xv[7] - xv[6]) * (xv[7] - xv[6]) +
1089 sIBTopFilamentInterZ * sIBTopFilamentInterZ / 4);
1090 theta = TMath::ATan((yv[7] - yv[6]) / (xv[7] - xv[6])) * TMath::RadToDeg();
1091 TGeoBBox* topfil = new TGeoBBox(xlen / 2, sIBTopFilamentSide / 2, sIBTopFilamentSide / 2);
1092
1093 // The half stave container (an XTru to avoid overlaps between neighbours)
1094 xv[0] = xstave + sIBTopFilamentSide;
1095 yv[0] = 0;
1096 xv[1] = xv[0];
1097 yv[1] = layerHeight + sIBSideVertexHeight + topfil->GetDZ();
1098 ;
1099 xv[2] = sIBEndSupportXUp / 2;
1100 yv[2] = sIBStaveHeight + sIBTopFilamentSide / sinD(-theta) - 0.01; // theta is neg
1101 for (Int_t i = 0; i < 3; i++) {
1102 xv[3 + i] = -xv[2 - i];
1103 yv[3 + i] = yv[2 - i];
1104 }
1105
1106 TGeoXtru* mechStruct = new TGeoXtru(2);
1107 mechStruct->DefinePolygon(6, xv, yv);
1108 mechStruct->SetName("mechStruct");
1109 mechStruct->DefineSection(0, -ztot);
1110 mechStruct->DefineSection(1, ztot);
1111
1112 // The connectors' containers
1113 zlen = sIBConnectBlockZLen - sIBConnTailZLen + sIBConnectAFitZOut;
1114 TGeoBBox* connAside = new TGeoBBox("connAsideIB", sIBConnectorXWidth / 2, sIBConnBodyYHeight / 2, zlen / 2);
1115
1116 zlen = sIBConnectBlockZLen - sIBConnTailZLen;
1117 TGeoBBox* connCside = new TGeoBBox("connCsideIB", sIBConnectorXWidth / 2, sIBConnBodyYHeight / 2, zlen / 2);
1118
1119 // The StaveStruct container, a Composite Shape
1120 yposPipe = 2 * glue->GetDY() + 2 * fleecbot->GetDY() + 2 * cfplate->GetDY() + pipe->GetRmax();
1121 ypos = connAside->GetDY() - sIBConnTubesYPos + yposPipe;
1122 zpos = ztot + connAside->GetDZ();
1123 TGeoTranslation* transAside = new TGeoTranslation("transAsideIB", 0, ypos, zpos);
1124 transAside->RegisterYourself();
1125
1126 ypos = connCside->GetDY() - sIBConnTubesYPos + yposPipe;
1127 zpos = ztot + connCside->GetDZ();
1128 TGeoTranslation* transCside = new TGeoTranslation("transCsideIB", 0, ypos, -zpos);
1129 transCside->RegisterYourself();
1130
1131 TGeoCompositeShape* mechStavSh =
1132 new TGeoCompositeShape("mechStruct+connAsideIB:transAsideIB+connCsideIB:transCsideIB");
1133
1134 // We have all shapes: now create the real volumes
1135
1136 TGeoMedium* medAir = mgr->GetMedium(Form("%s_AIR$", GetDetName()));
1137 TGeoMedium* medWater = mgr->GetMedium(Form("%s_WATER$", GetDetName()));
1138 TGeoMedium* medM55J6K = mgr->GetMedium(Form("%s_M55J6K$", GetDetName()));
1139 TGeoMedium* medM60J3K = mgr->GetMedium(Form("%s_M60J3K$", GetDetName()));
1140 TGeoMedium* medKapton = mgr->GetMedium(Form("%s_KAPTON(POLYCH2)$", GetDetName()));
1141 TGeoMedium* medGlue = mgr->GetMedium(Form("%s_GLUE$", GetDetName()));
1142 TGeoMedium* medK13D2U2k = mgr->GetMedium(Form("%s_K13D2U2k$", GetDetName()));
1143 TGeoMedium* medFGS003 = mgr->GetMedium(Form("%s_FGS003$", GetDetName()));
1144 TGeoMedium* medCarbonFleece = mgr->GetMedium(Form("%s_CarbonFleece$", GetDetName()));
1145
1146 const Int_t nameLen = 30;
1147 char volname[nameLen];
1148 snprintf(volname, nameLen, "%s%d_StaveStruct", GeometryTGeo::getITSStavePattern(), mLayerNumber);
1149 TGeoVolume* mechStavVol = new TGeoVolume(volname, mechStavSh, medAir);
1150 mechStavVol->SetLineColor(12);
1151 mechStavVol->SetFillColor(12);
1152 mechStavVol->SetVisibility(kFALSE);
1153
1154 TGeoVolume* glueVol = new TGeoVolume("Glue", glue, medGlue);
1155 glueVol->SetLineColor(kBlack);
1156 glueVol->SetFillColor(kBlack);
1157
1158 TGeoVolume* fleecbotVol = new TGeoVolume("CarbonFleeceBottom", fleecbot, medCarbonFleece);
1159 fleecbotVol->SetFillColor(kViolet);
1160 fleecbotVol->SetLineColor(kViolet);
1161
1162 TGeoVolume* cfplateVol = new TGeoVolume("CFPlate", cfplate, medK13D2U2k);
1163 cfplateVol->SetFillColor(5); // Yellow
1164 cfplateVol->SetLineColor(5);
1165
1166 TGeoVolume* pipeVol = new TGeoVolume("PolyimidePipe", pipe, medKapton);
1167 pipeVol->SetFillColor(35); // Blue shade
1168 pipeVol->SetLineColor(35);
1169
1170 TGeoVolume* waterVol = new TGeoVolume("Water", water, medWater);
1171 waterVol->SetFillColor(4); // Bright blue
1172 waterVol->SetLineColor(4);
1173
1174 TGeoVolume* cpaptubVol = new TGeoVolume("ThermasolPipeCover", cpaptub, medFGS003);
1175 cpaptubVol->SetFillColor(2); // Red
1176 cpaptubVol->SetLineColor(2);
1177
1178 TGeoVolume* cpapvertVol = new TGeoVolume("ThermasolVertical", cpapvert, medFGS003);
1179 cpapvertVol->SetFillColor(2); // Red
1180 cpapvertVol->SetLineColor(2);
1181
1182 TGeoVolume* cpapmidVol = new TGeoVolume("ThermasolMiddle", cpapmid, medFGS003);
1183 cpapmidVol->SetFillColor(2); // Red
1184 cpapmidVol->SetLineColor(2);
1185
1186 TGeoVolume* cpaplrVol = new TGeoVolume("ThermasolLeftRight", cpaplr, medFGS003);
1187 cpaplrVol->SetFillColor(2); // Red
1188 cpaplrVol->SetLineColor(2);
1189
1190 TGeoVolume* fleecpipeVol = new TGeoVolume("CarbonFleecePipeCover", fleecpipe, medCarbonFleece);
1191 fleecpipeVol->SetFillColor(28); // Brown shade
1192 fleecpipeVol->SetLineColor(28);
1193
1194 TGeoVolume* fleecvertVol = new TGeoVolume("CarbonFleeceVertical", fleecvert, medCarbonFleece);
1195 fleecvertVol->SetFillColor(28); // Brown shade
1196 fleecvertVol->SetLineColor(28);
1197
1198 TGeoVolume* fleecmidVol = new TGeoVolume("CarbonFleeceMiddle", fleecmid, medCarbonFleece);
1199 fleecmidVol->SetFillColor(28); // Brown shade
1200 fleecmidVol->SetLineColor(28);
1201
1202 TGeoVolume* fleeclrVol = new TGeoVolume("CarbonFleeceLeftRight", fleeclr, medCarbonFleece);
1203 fleeclrVol->SetFillColor(28); // Brown shade
1204 fleeclrVol->SetLineColor(28);
1205
1206 TGeoVolume* topvVol = new TGeoVolume("TopVertex", topv, medM55J6K);
1207 topvVol->SetFillColor(12); // Gray shade
1208 topvVol->SetLineColor(12);
1209
1210 TGeoVolume* sidevVol = new TGeoVolume("SideVertex", sidev, medM55J6K);
1211 sidevVol->SetFillColor(12); // Gray shade
1212 sidevVol->SetLineColor(12);
1213
1214 TGeoVolume* topfilVol = new TGeoVolume("TopFilament", topfil, medM60J3K);
1215 topfilVol->SetFillColor(12); // Gray shade
1216 topfilVol->SetLineColor(12);
1217
1218 TGeoVolume* endsuppVol = new TGeoVolume("EndSupport", endsupp, medM55J6K);
1219 endsuppVol->SetFillColor(12); // Gray shade
1220 endsuppVol->SetLineColor(12);
1221
1222 // Now build up the half stave
1223 ypos = glue->GetDY();
1224 if (mBuildLevel < 2) { // Glue
1225 mechStavVol->AddNode(glueVol, 1, new TGeoTranslation(0, ypos, 0));
1226 }
1227
1228 ypos += (glue->GetDY() + fleecbot->GetDY());
1229 if (mBuildLevel < 5) { // Carbon
1230 mechStavVol->AddNode(fleecbotVol, 1, new TGeoTranslation(0, ypos, 0));
1231 }
1232
1233 ypos += (fleecbot->GetDY() + cfplate->GetDY());
1234 if (mBuildLevel < 5) { // Carbon
1235 mechStavVol->AddNode(cfplateVol, 1, new TGeoTranslation(0, ypos, 0));
1236 }
1237
1238 ylay = ypos + cfplate->GetDY(); // The level where tubes etc. lay
1239
1240 xpos = sIBCoolPipeXDist / 2;
1241 ypos = ylay + pipe->GetRmax();
1242 yposPipe = ypos; // Save for later use
1243 if (mBuildLevel < 4) { // Kapton
1244 mechStavVol->AddNode(pipeVol, 1, new TGeoTranslation(-xpos, ypos, 0));
1245 mechStavVol->AddNode(pipeVol, 2, new TGeoTranslation(xpos, ypos, 0));
1246 }
1247
1248 if (mBuildLevel < 3) { // Water
1249 mechStavVol->AddNode(waterVol, 1, new TGeoTranslation(-xpos, ypos, 0));
1250 mechStavVol->AddNode(waterVol, 2, new TGeoTranslation(xpos, ypos, 0));
1251 }
1252
1253 if (mBuildLevel < 5) { // Carbon (stave components)
1254 mechStavVol->AddNode(cpaptubVol, 1, new TGeoTranslation(-xpos, ypos, 0));
1255 mechStavVol->AddNode(cpaptubVol, 2, new TGeoTranslation(xpos, ypos, 0));
1256
1257 mechStavVol->AddNode(fleecpipeVol, 1, new TGeoTranslation(-xpos, ypos, 0));
1258 mechStavVol->AddNode(fleecpipeVol, 2, new TGeoTranslation(xpos, ypos, 0));
1259
1260 xpos = sIBCoolPipeXDist / 2 - pipe->GetRmax() - cpapvert->GetDX();
1261 ypos = ylay + cpapvert->GetDY();
1262 mechStavVol->AddNode(cpapvertVol, 1, new TGeoTranslation(-xpos, ypos, 0));
1263 mechStavVol->AddNode(cpapvertVol, 2, new TGeoTranslation(xpos, ypos, 0));
1264
1265 xpos = sIBCoolPipeXDist / 2 + pipe->GetRmax() + cpapvert->GetDX();
1266 mechStavVol->AddNode(cpapvertVol, 3, new TGeoTranslation(-xpos, ypos, 0));
1267 mechStavVol->AddNode(cpapvertVol, 4, new TGeoTranslation(xpos, ypos, 0));
1268
1269 ypos = ylay + sIBCarbonPaperThick / 2;
1270 mechStavVol->AddNode(cpapmidVol, 1, new TGeoTranslation(0, ypos, 0));
1271
1272 xpos = xstave - cpaplr->GetDX();
1273 mechStavVol->AddNode(cpaplrVol, 1, new TGeoTranslation(-xpos, ypos, 0));
1274 mechStavVol->AddNode(cpaplrVol, 2, new TGeoTranslation(xpos, ypos, 0));
1275
1276 xpos = sIBCoolPipeXDist / 2 - pipe->GetRmax() - 2 * cpapvert->GetDX() - fleecvert->GetDX();
1277 ypos = ylay + sIBCarbonPaperThick + fleecvert->GetDY();
1278 mechStavVol->AddNode(fleecvertVol, 1, new TGeoTranslation(-xpos, ypos, 0));
1279 mechStavVol->AddNode(fleecvertVol, 2, new TGeoTranslation(xpos, ypos, 0));
1280
1281 xpos = sIBCoolPipeXDist / 2 + pipe->GetRmax() + 2 * cpapvert->GetDX() + fleecvert->GetDX();
1282 mechStavVol->AddNode(fleecvertVol, 3, new TGeoTranslation(-xpos, ypos, 0));
1283 mechStavVol->AddNode(fleecvertVol, 4, new TGeoTranslation(xpos, ypos, 0));
1284
1285 ypos = ylay + sIBCarbonPaperThick + sIBCarbonFleeceThick / 2;
1286 mechStavVol->AddNode(fleecmidVol, 1, new TGeoTranslation(0, ypos, 0));
1287
1288 xpos = xstave - fleeclr->GetDX();
1289 mechStavVol->AddNode(fleeclrVol, 1, new TGeoTranslation(-xpos, ypos, 0));
1290 mechStavVol->AddNode(fleeclrVol, 2, new TGeoTranslation(xpos, ypos, 0));
1291 }
1292
1293 ylay += (sIBCarbonPaperThick + sIBCarbonFleeceThick);
1294
1295 if (mBuildLevel < 5) { // Carbon (spaceframe)
1296 ypos = sIBStaveHeight - sIBEndSupportThick - topv->GetDz(); // Due to rotation, z is on Y
1297 mechStavVol->AddNode(topvVol, 1, new TGeoCombiTrans(0, ypos, 0, new TGeoRotation("", 0, -90, 0)));
1298
1299 xpos = xstave - sidev->GetX(1);
1300 ypos = ylay;
1301 mechStavVol->AddNode(sidevVol, 1, new TGeoTranslation(xpos, ypos, 0));
1302 mechStavVol->AddNode(sidevVol, 2, new TGeoCombiTrans(-xpos, ypos, 0, new TGeoRotation("", 90, 180, -90)));
1303
1304 zpos = ztot - endsupp->GetZ(1);
1305 mechStavVol->AddNode(endsuppVol, 1, new TGeoTranslation(0, 0, zpos));
1306 mechStavVol->AddNode(endsuppVol, 2, new TGeoTranslation(0, 0, -zpos));
1307
1308 gamma = 180. - sIBTopFilamentAlpha;
1309 xpos = xstave / 2 + topfil->GetDZ();
1310 ypos = (endsupp->GetY(7) + endsupp->GetY(6)) / 2;
1311 Int_t nFilamentGroups = (Int_t)(2 * (ztot - sIBEndSupportZLen) / sIBTopFilamentInterZ);
1312 // theta was computed when filament volume was created
1313 for (int i = 0; i < nFilamentGroups; i++) { // i<19
1314 // 1) Front Left Top Filament
1315 zpos = -(ztot - sIBEndSupportZLen) + i * sIBTopFilamentInterZ + sIBTopFilamentInterZ / 4;
1316 mechStavVol->AddNode(topfilVol, i * 4 + 1,
1317 new TGeoCombiTrans(xpos, ypos, zpos, new TGeoRotation("", 90 + theta, gamma / 2, -90)));
1318 // 2) Front Right Top Filament
1319 mechStavVol->AddNode(topfilVol, i * 4 + 2,
1320 new TGeoCombiTrans(-xpos, ypos, zpos, new TGeoRotation("", 90 - theta, -gamma / 2, -90)));
1321 // 3) Back Left Top Filament
1322 zpos += sIBTopFilamentInterZ / 2;
1323 mechStavVol->AddNode(topfilVol, i * 4 + 3,
1324 new TGeoCombiTrans(xpos, ypos, zpos, new TGeoRotation("", 90 + theta, -gamma / 2, -90)));
1325 // 4) Back Right Top Filament
1326 mechStavVol->AddNode(topfilVol, i * 4 + 4,
1327 new TGeoCombiTrans(-xpos, ypos, zpos, new TGeoRotation("", 90 - theta, gamma / 2, -90)));
1328 }
1329 }
1330
1331 // Add the end-stave connectors
1332 TGeoVolume *connectorASide, *connectorCSide;
1333
1334 // Check whether we have already all pieces
1335 // Otherwise create them
1336 connectorASide = mgr->GetVolume("IBConnectorASide");
1337
1338 if (!connectorASide) {
1339 createIBConnectors(mgr);
1340 connectorASide = mgr->GetVolume("IBConnectorASide");
1341 }
1342 connectorCSide = mgr->GetVolume("IBConnectorCSide");
1343
1344 ypos = (static_cast<TGeoBBox*>(connectorASide->GetShape()))->GetDY() - sIBConnTubesYPos +
1345 yposPipe; // We center the pipe and hole axes
1346 zpos = ztot + (sIBConnectBlockZLen - sIBConnTailZLen + sIBConnectAFitZOut) / 2;
1347 mechStavVol->AddNode(connectorASide, 1, new TGeoTranslation(0, ypos, zpos));
1348
1349 zpos = ztot + (sIBConnectBlockZLen - sIBConnTailZLen) / 2;
1350 mechStavVol->AddNode(connectorCSide, 1, new TGeoCombiTrans(0, ypos, -zpos, new TGeoRotation("", 90, 180, -90)));
1351
1352 // Done, return the stave structure
1353 return mechStavVol;
1354}
1355
1356void V3Layer::createIBConnectors(const TGeoManager* mgr)
1357{
1358 //
1359 // Create the end-stave connectors for IB staves
1360 // (simply call the actual creator methods)
1361 //
1362 // Created: 20 Apr 2015 Mario Sitta
1363 //
1364
1365 createIBConnectorsASide(mgr);
1366 createIBConnectorsCSide(mgr);
1367}
1368
1369void V3Layer::createIBConnectorsASide(const TGeoManager* mgr)
1370{
1371 //
1372 // Create the A-Side end-stave connectors for IB staves
1373 //
1374 // Created: 22 Apr 2015 Mario Sitta
1375 // Updated: 04 Apr 2017 Mario Sitta O2 version
1376 // Updated: 28 Jan 2018 Mario Sitta To last drawings (ALIITSUP0051)
1377 // Updated: 19 Jun 2019 Mario Sitta Avoid fake overlaps with EndWheels
1378 //
1379
1380 // Local variables
1381 const Int_t nv = 8;
1382 Double_t xv[nv], yv[nv];
1383 Double_t xlen, ylen, zlen;
1384 Double_t xpos, ypos, zpos;
1385
1386 // Gather all material pointers
1387 TGeoMedium* medAir = mgr->GetMedium(Form("%s_AIR$", GetDetName()));
1388 TGeoMedium* medPEEK = mgr->GetMedium(Form("%s_PEEKCF30$", GetDetName()));
1389 TGeoMedium* medInox304 = mgr->GetMedium(Form("%s_INOX304$", GetDetName()));
1390
1391 // First create all elements
1392 // (All measures refer to the blueprint ALIITSUP0051)
1393
1394 // The connector block, two Composite Shapes:
1395 // the body...
1396 xlen = sIBConnectorXWidth;
1397 ylen = sIBConnBodyYHeight;
1398 zlen = sIBConnectBlockZLen - sIBConnTailZLen;
1399 TGeoBBox* connBody = new TGeoBBox("connBodyA", xlen / 2, ylen / 2, zlen / 2);
1400
1401 TGeoTube* connRoundHole = new TGeoTube("connRoundHoleA", 0., sIBConnRoundHoleD / 2, sIBConnBodyYHeight / 1.5);
1402
1403 zpos = -connBody->GetDZ() + sIBConnRoundHoleZ;
1404 TGeoCombiTrans* connRoundHoleTrans =
1405 new TGeoCombiTrans("roundHoleTransA", 0, 0, zpos, new TGeoRotation("", 0, 90, 0));
1406 connRoundHoleTrans->RegisterYourself();
1407
1408 xlen = sIBConnSquareHoleX / 2;
1409 ylen = sIBConnBodyYHeight / 1.5;
1410 zlen = sIBConnSquareHoleZ / 2;
1411 TGeoBBox* connSquareHole = new TGeoBBox("connSquareHoleA", xlen, ylen, zlen);
1412
1413 zpos = -connBody->GetDZ() + sIBConnSquareHoleZPos;
1414 TGeoTranslation* connSquareHoleTrans = new TGeoTranslation("squareHoleTransA", 0, 0, zpos);
1415 connSquareHoleTrans->RegisterYourself();
1416
1417 TGeoTube* connTubeHole2 = new TGeoTube("tube2HoleA", 0, sIBConnTubeHole2D / 2, connBody->GetDZ());
1418
1419 xpos = sIBConnTubesXDist / 2;
1420 ypos = -connBody->GetDY() + sIBConnTubesYPos;
1421
1422 TGeoTranslation* connTubes2Trans1 = new TGeoTranslation("tubes2Trans1A", -xpos, ypos, 0);
1423 connTubes2Trans1->RegisterYourself();
1424
1425 TGeoTranslation* connTubes2Trans2 = new TGeoTranslation("tubes2Trans2A", xpos, ypos, 0);
1426 connTubes2Trans2->RegisterYourself();
1427
1428 zlen = sIBConnTubeHole1ZLen - sIBConnTailZLen;
1429 TGeoTube* connTubeHole3 = new TGeoTube("tube3HoleA", 0, sIBConnTubeHole1D / 2, zlen);
1430
1431 zpos = connBody->GetDZ();
1432 TGeoTranslation* connTubes3Trans1 = new TGeoTranslation("tubes3Trans1A", -xpos, ypos, -zpos);
1433 connTubes3Trans1->RegisterYourself();
1434 TGeoTranslation* connTubes3Trans2 = new TGeoTranslation("tubes3Trans2A", xpos, ypos, -zpos);
1435 connTubes3Trans2->RegisterYourself();
1436
1437 zlen = sIBConnTubeHole1ZLen2;
1438 TGeoTube* connFitHole = new TGeoTube("fitHoleA", 0, sIBConnectAFitExtD / 2, zlen);
1439
1440 TGeoTranslation* connFitHoleTrans1 = new TGeoTranslation("fitTrans1A", -xpos, ypos, zpos);
1441 connFitHoleTrans1->RegisterYourself();
1442 TGeoTranslation* connFitHoleTrans2 = new TGeoTranslation("fitTrans2A", xpos, ypos, zpos);
1443 connFitHoleTrans2->RegisterYourself();
1444
1445 zlen = sIBConnSideHole1XWid / 1.5;
1446 TGeoTube* sideHole1 = new TGeoTube("sideHole1A", 0, sIBConnSideHole1D / 2, zlen);
1447
1448 xpos = connBody->GetDX() - sIBConnSideHole1XWid + sideHole1->GetDz();
1449 ypos = connBody->GetDY() - sIBConnSideHole1YPos;
1450 zpos = -connBody->GetDZ() + (sIBConnSideHole1ZPos - sIBConnTailZLen);
1451 TGeoCombiTrans* connSideHole1Trans =
1452 new TGeoCombiTrans("sideHole1TransA", xpos, ypos, zpos, new TGeoRotation("", 90, 90, 0));
1453 connSideHole1Trans->RegisterYourself();
1454
1455 TGeoBBox* sideHole2Box =
1456 new TGeoBBox("sideHole2AB", sIBConnSideHole2XWid, sIBConnSideHole2YWid / 2, sIBConnSideHole2ZWid / 2);
1457
1458 xpos = -connBody->GetDX();
1459 ypos = connBody->GetDY() - sIBConnSideHole2YPos;
1460 zpos = -connBody->GetDZ() + (sIBConnSideHole2ZPos - sIBConnTailZLen) + sideHole2Box->GetDZ();
1461 TGeoTranslation* sideHole2BTrans = new TGeoTranslation("sideHole2TransBA", xpos, ypos, zpos);
1462 sideHole2BTrans->RegisterYourself();
1463
1464 TGeoTubeSeg* sideHole2TubeSeg =
1465 new TGeoTubeSeg("sideHole2ATS", 0, sIBConnSideHole2YWid / 2, sIBConnSideHole2XWid, 0, 180);
1466
1467 zpos = -connBody->GetDZ() + (sIBConnSideHole2ZPos - sIBConnTailZLen);
1468 TGeoCombiTrans* sideHole2TSTrans1 =
1469 new TGeoCombiTrans("sideHole2TSTrans1A", xpos, ypos, zpos, new TGeoRotation("", 90, -90, 0));
1470 sideHole2TSTrans1->RegisterYourself();
1471
1472 zpos = -connBody->GetDZ() + (sIBConnSideHole2ZPos - sIBConnTailZLen) + 2 * sideHole2Box->GetDZ();
1473 TGeoCombiTrans* sideHole2TSTrans2 =
1474 new TGeoCombiTrans("sideHole2TSTrans2A", xpos, ypos, zpos, new TGeoRotation("", 90, 90, 0));
1475 sideHole2TSTrans2->RegisterYourself();
1476
1477 TGeoCompositeShape* connBodySh = new TGeoCompositeShape(
1478 "connBodyA-connRoundHoleA:roundHoleTransA-connSquareHoleA:squareHoleTransA-tube2HoleA:tubes2Trans1A-tube2HoleA:"
1479 "tubes2Trans2A-fitHoleA:fitTrans1A-fitHoleA:fitTrans2A-tube3HoleA:tubes3Trans1A-tube3HoleA:tubes3Trans2A-"
1480 "sideHole1A:sideHole1TransA-sideHole2AB:sideHole2TransBA-sideHole2ATS:sideHole2TSTrans1A-sideHole2ATS:"
1481 "sideHole2TSTrans2A");
1482
1483 TGeoVolume* connBlockBody = new TGeoVolume("IBConnectorBlockBodyASide", connBodySh, medPEEK);
1484 connBlockBody->SetFillColor(42); // Brownish shade
1485 connBlockBody->SetLineColor(42);
1486
1487 // ...and the tail
1488 xv[0] = sIBConnectorXWidth / 2;
1489 yv[0] = sIBConnTailYShift;
1490 xv[1] = xv[0];
1491 yv[1] = sIBConnTailYMid;
1492 xv[2] = xv[1] - (sIBConnectorYTot - sIBConnTailYMid) / tanD(90 - sIBConnTailOpenPhi / 2);
1493 yv[2] = sIBConnectorYTot;
1494
1495 for (Int_t i = 0; i < 3; i++) {
1496 xv[3 + i] = -xv[2 - i];
1497 yv[3 + i] = yv[2 - i];
1498 }
1499
1500 TGeoXtru* connTail = new TGeoXtru(2);
1501 connTail->SetName("connTailA");
1502 connTail->DefinePolygon(6, xv, yv);
1503 connTail->DefineSection(0, 0);
1504 connTail->DefineSection(1, sIBConnTailZLen);
1505
1506 TGeoTube* connTubeHole1 = new TGeoTube("tube1HoleA", 0, sIBConnTubeHole1D / 2, sIBConnTubeHole1ZLen / 1.5);
1507
1508 xpos = sIBConnTubesXDist / 2;
1509 ypos = sIBConnTubesYPos;
1510 zpos = connTail->GetZ(1) / 2;
1511 TGeoTranslation* connTubes1Trans1 = new TGeoTranslation("tubes1Trans1A", -xpos, ypos, zpos);
1512 connTubes1Trans1->RegisterYourself();
1513 TGeoTranslation* connTubes1Trans2 = new TGeoTranslation("tubes1Trans2A", xpos, ypos, zpos);
1514 connTubes1Trans2->RegisterYourself();
1515
1516 TGeoCompositeShape* connTailSh =
1517 new TGeoCompositeShape("connTailA-tube1HoleA:tubes1Trans1A-tube1HoleA:tubes1Trans2A");
1518
1519 TGeoVolume* connBlockTail = new TGeoVolume("IBConnectorBlockTailASide", connTailSh, medPEEK);
1520 connBlockTail->SetFillColor(42); // Brownish shade
1521 connBlockTail->SetLineColor(42);
1522
1523 // The fitting tubes, a Tube
1524 TGeoTube* connFitSh = new TGeoTube(sIBConnectAFitIntD / 2, sIBConnectAFitExtD / 2, sIBConnectAFitZLen / 2);
1525
1526 TGeoVolume* connFit = new TGeoVolume("IBConnectorFitting", connFitSh, medInox304);
1527 connFit->SetFillColor(kGray);
1528 connFit->SetLineColor(kGray);
1529
1530 // Now create the container: cannot be a simple box
1531 // to avoid fake overlaps with stave elements
1532 xlen = sIBConnectorXWidth;
1533 ylen = sIBConnBodyYHeight;
1534 zlen = sIBConnectBlockZLen - sIBConnTailZLen + sIBConnectAFitZOut;
1535
1536 TGeoBBox* connBox = new TGeoBBox("connBoxA", xlen / 2, ylen / 2, zlen / 2);
1537
1538 ypos = -sIBConnectorYTot / 2 + connBox->GetDY();
1539 TGeoTranslation* transBodyA = new TGeoTranslation("transBodyA", 0, ypos, 0);
1540 transBodyA->RegisterYourself();
1541
1542 ypos = -sIBConnectorYTot / 2;
1543 zpos = -connBox->GetDZ() - connTail->GetZ(1);
1544 TGeoTranslation* transTailA = new TGeoTranslation("transTailA", 0, ypos, zpos);
1545 transTailA->RegisterYourself();
1546
1547 TGeoTube* connTubeHollow = new TGeoTube("tubeHollowA", 0, sIBConnTubeHole1D / 2, sIBConnTubeHole1ZLen / 2);
1548
1549 xpos = sIBConnTubesXDist / 2;
1550 ypos = -sIBConnectorYTot / 2 + sIBConnTubesYPos;
1551 zpos = -connBox->GetDZ() - connTail->GetZ(1) + sIBConnTubeHole1ZLen / 2;
1552 TGeoTranslation* connTubeHollTrans1 = new TGeoTranslation("tubeHollTrans1A", -xpos, ypos, zpos);
1553 connTubeHollTrans1->RegisterYourself();
1554 TGeoTranslation* connTubeHollTrans2 = new TGeoTranslation("tubeHollTrans2A", xpos, ypos, zpos);
1555 connTubeHollTrans2->RegisterYourself();
1556
1557 zpos = -connBox->GetDZ() + connTubeHole2->GetDz() - 2 * connFitHole->GetDz();
1558 TGeoTranslation* connTubes2Trans1Body = new TGeoTranslation("tubes2Trans1BA", -xpos, ypos, zpos);
1559 connTubes2Trans1Body->RegisterYourself();
1560 TGeoTranslation* connTubes2Trans2Body = new TGeoTranslation("tubes2Trans2BA", xpos, ypos, zpos);
1561 connTubes2Trans2Body->RegisterYourself();
1562
1563 TGeoCompositeShape* connBoxSh = new TGeoCompositeShape(
1564 "connBoxA:transBodyA-tube2HoleA:tubes2Trans1BA-tube2HoleA:tubes2Trans2BA+connTailA:transTailA-tubeHollowA:tubeHollTrans1A-"
1565 "tubeHollowA:tubeHollTrans2A");
1566
1567 TGeoVolume* connBoxASide = new TGeoVolume("IBConnectorASide", connBoxSh, medAir);
1568
1569 // Finally build up the connector
1570 // (NB: the origin is in the connBox, i.e. w/o the tail in Z)
1571 ypos = -sIBConnectorYTot / 2;
1572 zpos = -connBox->GetDZ() - connTail->GetZ(1);
1573 connBoxASide->AddNode(connBlockTail, 1, new TGeoTranslation(0, ypos, zpos));
1574
1575 ypos = -sIBConnectorYTot / 2 + connBody->GetDY();
1576 zpos = -connBox->GetDZ() + connBody->GetDZ();
1577 connBoxASide->AddNode(connBlockBody, 1, new TGeoTranslation(0, ypos, zpos));
1578
1579 xpos = sIBConnTubesXDist / 2;
1580 ypos = -sIBConnectorYTot / 2 + sIBConnTubesYPos;
1581 zpos = connBox->GetDZ() - connFitSh->GetDz();
1582 connBoxASide->AddNode(connFit, 1, new TGeoTranslation(xpos, ypos, zpos));
1583 connBoxASide->AddNode(connFit, 2, new TGeoTranslation(-xpos, ypos, zpos));
1584}
1585
1586void V3Layer::createIBConnectorsCSide(const TGeoManager* mgr)
1587{
1588 //
1589 // Create the C-Side end-stave connectors for IB staves
1590 //
1591 // Created: 05 May 2015 Mario Sitta
1592 // Updated: 04 Apr 2017 Mario Sitta O2 version
1593 // Updated: 28 Jan 2018 Mario Sitta To last drawings (ALIITSUP0051)
1594 // Updated: 15 May 2019 Mario Sitta Avoid fake overlaps with EndWheels
1595 //
1596
1597 // Local variables
1598 const Int_t nv = 8;
1599 Double_t xv[nv], yv[nv];
1600 Double_t xlen, ylen, zlen;
1601 Double_t xpos, ypos, zpos;
1602
1603 // Gather all material pointers
1604 TGeoMedium* medAir = mgr->GetMedium(Form("%s_AIR$", GetDetName()));
1605 TGeoMedium* medPEEK = mgr->GetMedium(Form("%s_PEEKCF30$", GetDetName()));
1606
1607 // First create all elements
1608 // (All measures refer to the blueprint ALIITSUP0051)
1609
1610 // The connector block, two Composite Shapes:
1611 // the body...
1612 xlen = sIBConnectorXWidth;
1613 ylen = sIBConnBodyYHeight;
1614 zlen = sIBConnectBlockZLen - sIBConnTailZLen;
1615 TGeoBBox* connBody = new TGeoBBox("connBodyC", xlen / 2, ylen / 2, zlen / 2);
1616
1617 TGeoTube* connRoundHole = new TGeoTube("connRoundHoleC", 0., sIBConnRoundHoleD / 2, sIBConnBodyYHeight / 1.5);
1618
1619 zpos = -connBody->GetDZ() + sIBConnRoundHoleZ;
1620 TGeoCombiTrans* connRoundHoleTrans =
1621 new TGeoCombiTrans("roundHoleTransC", 0, 0, zpos, new TGeoRotation("", 0, 90, 0));
1622 connRoundHoleTrans->RegisterYourself();
1623
1624 TGeoTube* connInsertHole = new TGeoTube("connInsertHoleC", 0, sIBConnInsertHoleD / 2, sIBConnBodyYHeight / 1.5);
1625
1626 zpos = -connBody->GetDZ() + sIBConnInsertHoleZPos;
1627 TGeoCombiTrans* connInsertHoleTrans =
1628 new TGeoCombiTrans("insertHoleTransC", 0, 0, zpos, new TGeoRotation("", 0, 90, 0));
1629 connInsertHoleTrans->RegisterYourself();
1630
1631 TGeoTube* connTubeHole2 = new TGeoTube("tube2HoleC", 0, sIBConnTubeHole2D / 2, connBody->GetDZ());
1632
1633 xpos = sIBConnTubesXDist / 2;
1634 ypos = -connBody->GetDY() + sIBConnTubesYPos;
1635 zpos = sIBConnectBlockZLen - sIBConnTubeHole3ZPos;
1636 TGeoTranslation* connTubes2Trans1 = new TGeoTranslation("tubes2Trans1C", -xpos, ypos, -zpos);
1637 connTubes2Trans1->RegisterYourself();
1638 TGeoTranslation* connTubes2Trans2 = new TGeoTranslation("tubes2Trans2C", xpos, ypos, -zpos);
1639 connTubes2Trans2->RegisterYourself();
1640
1641 zlen = sIBConnectorXWidth;
1642 TGeoTube* connTubeHole3 = new TGeoTube("tube3HoleC", 0, sIBConnTubeHole2D / 2, zlen / 2);
1643
1644 xpos = sIBConnTubeHole3XPos;
1645 zpos = connBody->GetDZ() - (sIBConnectBlockZLen - sIBConnTubeHole3ZPos);
1646 TGeoCombiTrans* connTubes3Trans =
1647 new TGeoCombiTrans("tubes3TransC", xpos, ypos, zpos, new TGeoRotation("", 90, -90, 90));
1648 connTubes3Trans->RegisterYourself();
1649
1650 zlen = sIBConnTubeHole1ZLen - sIBConnTailZLen;
1651 TGeoTube* connTubeHole4 = new TGeoTube("tube4HoleC", 0, sIBConnTubeHole1D / 2, zlen);
1652
1653 xpos = sIBConnTubesXDist / 2;
1654 zpos = connBody->GetDZ();
1655 TGeoTranslation* connTubes4Trans1 = new TGeoTranslation("tubes4Trans1C", -xpos, ypos, -zpos);
1656 connTubes4Trans1->RegisterYourself();
1657 TGeoTranslation* connTubes4Trans2 = new TGeoTranslation("tubes4Trans2C", xpos, ypos, -zpos);
1658 connTubes4Trans2->RegisterYourself();
1659
1660 zlen = sIBConnSideHole1XWid / 1.5;
1661 TGeoTube* sideHole1 = new TGeoTube("sideHole1C", 0, sIBConnSideHole1D / 2, zlen);
1662
1663 xpos = -connBody->GetDX() + sIBConnSideHole1XWid - sideHole1->GetDz();
1664 ypos = connBody->GetDY() - sIBConnSideHole1YPos;
1665 zpos = -connBody->GetDZ() + (sIBConnSideHole1ZPos - sIBConnTailZLen);
1666 TGeoCombiTrans* connSideHole1Trans =
1667 new TGeoCombiTrans("sideHole1TransC", xpos, ypos, zpos, new TGeoRotation("", 90, 90, 0));
1668 connSideHole1Trans->RegisterYourself();
1669
1670 TGeoBBox* sideHole2Box =
1671 new TGeoBBox("sideHole2CB", sIBConnSideHole2XWid, sIBConnSideHole2YWid / 2, sIBConnSideHole2ZWid / 2);
1672
1673 xpos = connBody->GetDX();
1674 ypos = connBody->GetDY() - sIBConnSideHole2YPos;
1675 zpos = -connBody->GetDZ() + (sIBConnSideHole2ZPos - sIBConnTailZLen) + sideHole2Box->GetDZ();
1676 TGeoTranslation* sideHole2BTrans = new TGeoTranslation("sideHole2TransBC", xpos, ypos, zpos);
1677 sideHole2BTrans->RegisterYourself();
1678
1679 TGeoTubeSeg* sideHole2TubeSeg =
1680 new TGeoTubeSeg("sideHole2CTS", 0, sIBConnSideHole2YWid / 2, sIBConnSideHole2XWid, 180, 360);
1681
1682 zpos = -connBody->GetDZ() + (sIBConnSideHole2ZPos - sIBConnTailZLen);
1683 TGeoCombiTrans* sideHole2TSTrans1 =
1684 new TGeoCombiTrans("sideHole2TSTrans1C", xpos, ypos, zpos, new TGeoRotation("", -90, 90, 0));
1685 sideHole2TSTrans1->RegisterYourself();
1686
1687 zpos = -connBody->GetDZ() + (sIBConnSideHole2ZPos - sIBConnTailZLen) + 2 * sideHole2Box->GetDZ();
1688 TGeoCombiTrans* sideHole2TSTrans2 =
1689 new TGeoCombiTrans("sideHole2TSTrans2C", xpos, ypos, zpos, new TGeoRotation("", -90, -90, 0));
1690 sideHole2TSTrans2->RegisterYourself();
1691
1692 TGeoCompositeShape* connBodySh = new TGeoCompositeShape(
1693 "connBodyC-tube2HoleC:tubes2Trans1C-tube2HoleC:tubes2Trans2C-tube3HoleC:tubes3TransC-tube4HoleC:tubes4Trans1C-"
1694 "tube4HoleC:tubes4Trans2C-sideHole1C:sideHole1TransC-sideHole2CTS:sideHole2TSTrans1C-sideHole2CTS:"
1695 "sideHole2TSTrans2C-sideHole2CB:sideHole2TransBC-connRoundHoleC:roundHoleTransC-connInsertHoleC:insertHoleTransC");
1696
1697 TGeoVolume* connBlockBody = new TGeoVolume("IBConnectorBlockBodyCSide", connBodySh, medPEEK);
1698 connBlockBody->SetFillColor(42); // Brownish shade
1699 connBlockBody->SetLineColor(42);
1700
1701 // ...and the tail
1702 xv[0] = sIBConnectorXWidth / 2;
1703 yv[0] = sIBConnTailYShift;
1704 xv[1] = xv[0];
1705 yv[1] = sIBConnTailYMid;
1706 xv[2] = xv[1] - (sIBConnectorYTot - sIBConnTailYMid) / tanD(90 - sIBConnTailOpenPhi / 2);
1707 yv[2] = sIBConnectorYTot;
1708
1709 for (Int_t i = 0; i < 3; i++) {
1710 xv[3 + i] = -xv[2 - i];
1711 yv[3 + i] = yv[2 - i];
1712 }
1713
1714 TGeoXtru* connTail = new TGeoXtru(2);
1715 connTail->SetName("connTailC");
1716 connTail->DefinePolygon(6, xv, yv);
1717 connTail->DefineSection(0, 0);
1718 connTail->DefineSection(1, sIBConnTailZLen);
1719
1720 TGeoTube* connTubeHole1 = new TGeoTube("tube1HoleC", 0, sIBConnTubeHole1D / 2, sIBConnTubeHole1ZLen / 1.5);
1721
1722 xpos = sIBConnTubesXDist / 2;
1723 ypos = sIBConnTubesYPos;
1724 zpos = connTail->GetZ(1) / 2;
1725 TGeoTranslation* connTubes1Trans1 = new TGeoTranslation("tubes1Trans1C", -xpos, ypos, zpos);
1726 connTubes1Trans1->RegisterYourself();
1727 TGeoTranslation* connTubes1Trans2 = new TGeoTranslation("tubes1Trans2C", xpos, ypos, zpos);
1728 connTubes1Trans2->RegisterYourself();
1729
1730 TGeoCompositeShape* connTailSh =
1731 new TGeoCompositeShape("connTailC-tube1HoleC:tubes1Trans1C-tube1HoleC:tubes1Trans2C");
1732
1733 TGeoVolume* connBlockTail = new TGeoVolume("IBConnectorBlockTailCSide", connTailSh, medPEEK);
1734 connBlockTail->SetFillColor(42); // Brownish shade
1735 connBlockTail->SetLineColor(42);
1736
1737 // The plug, a Pcon
1738 zlen = sIBConnPlugTotLen - sIBConnPlugInnerLen;
1739 TGeoPcon* connPlugSh = new TGeoPcon(0, 360, 4);
1740 connPlugSh->DefineSection(0, 0., 0., sIBConnTubeHole2D / 2);
1741 connPlugSh->DefineSection(1, zlen, 0., sIBConnTubeHole2D / 2);
1742 connPlugSh->DefineSection(2, zlen, sIBConnPlugInnerD / 2, sIBConnTubeHole2D / 2);
1743 connPlugSh->DefineSection(3, sIBConnPlugTotLen, sIBConnPlugInnerD / 2, sIBConnTubeHole2D / 2);
1744
1745 TGeoVolume* connPlug = new TGeoVolume("IBConnectorPlugC", connPlugSh, medPEEK);
1746 connPlug->SetFillColor(44); // Brownish shade (a bit darker to spot it)
1747 connPlug->SetLineColor(44);
1748
1749 // Now create the container: cannot be a simple box
1750 // to avoid fake overlaps with stave elements
1751 xlen = sIBConnectorXWidth;
1752 ylen = sIBConnBodyYHeight;
1753 zlen = sIBConnectBlockZLen - sIBConnTailZLen;
1754
1755 TGeoBBox* connBox = new TGeoBBox("connBoxC", xlen / 2, ylen / 2, zlen / 2);
1756
1757 ypos = -sIBConnectorYTot / 2 + connBox->GetDY();
1758 TGeoTranslation* transBodyC = new TGeoTranslation("transBodyC", 0, ypos, 0);
1759 transBodyC->RegisterYourself();
1760
1761 ypos = -sIBConnectorYTot / 2;
1762 zpos = -connBox->GetDZ() - connTail->GetZ(1);
1763 TGeoTranslation* transTailC = new TGeoTranslation("transTailC", 0, ypos, zpos);
1764 transTailC->RegisterYourself();
1765
1766 TGeoTube* connTubeHollow = new TGeoTube("tubeHollowC", 0, sIBConnTubeHole1D / 2, sIBConnTubeHole1ZLen / 2);
1767
1768 xpos = sIBConnTubesXDist / 2;
1769 ypos = -sIBConnectorYTot / 2 + sIBConnTubesYPos;
1770 zpos = -connBox->GetDZ() - connTail->GetZ(1) + sIBConnTubeHole1ZLen / 2;
1771 TGeoTranslation* connTubeHollTrans1 = new TGeoTranslation("tubeHollTrans1C", -xpos, ypos, zpos);
1772 connTubeHollTrans1->RegisterYourself();
1773 TGeoTranslation* connTubeHollTrans2 = new TGeoTranslation("tubeHollTrans2C", xpos, ypos, zpos);
1774 connTubeHollTrans2->RegisterYourself();
1775
1776 zpos = connBody->GetDZ() - (sIBConnectBlockZLen - sIBConnTubeHole3ZPos);
1777 TGeoTranslation* connTubes2Trans1Body = new TGeoTranslation("tubes2Trans1BC", -xpos, ypos, -zpos);
1778 connTubes2Trans1Body->RegisterYourself();
1779 TGeoTranslation* connTubes2Trans2Body = new TGeoTranslation("tubes2Trans2BC", xpos, ypos, -zpos);
1780 connTubes2Trans2Body->RegisterYourself();
1781
1782 TGeoCompositeShape* connBoxSh = new TGeoCompositeShape(
1783 "connBoxC:transBodyC-tube2HoleC:tubes2Trans1BC-tube2HoleC:tubes2Trans2BC+connTailC:transTailC-tubeHollowC:tubeHollTrans1C-"
1784 "tubeHollowC:tubeHollTrans2C");
1785
1786 TGeoVolume* connBoxCSide = new TGeoVolume("IBConnectorCSide", connBoxSh, medAir);
1787
1788 // Finally build up the connector
1789 // (NB: the origin is in the connBox, i.e. w/o the tail in Z)
1790 ypos = -connBoxSh->GetDY();
1791 zpos = -connBodySh->GetDZ() - connTail->GetZ(1);
1792 connBoxCSide->AddNode(connBlockTail, 1, new TGeoTranslation(0, ypos, zpos));
1793
1794 ypos = -connBoxSh->GetDY() + connBody->GetDY();
1795 connBoxCSide->AddNode(connBlockBody, 1, new TGeoTranslation(0, ypos, 0));
1796
1797 xpos = connBox->GetDX();
1798 ypos = -sIBConnectorYTot / 2 + sIBConnTubesYPos;
1799 zpos = connBody->GetDZ() - (sIBConnectBlockZLen - sIBConnTubeHole3ZPos);
1800 connBoxCSide->AddNode(connPlug, 1, new TGeoCombiTrans(xpos, ypos, zpos, new TGeoRotation("", 90, -90, 90)));
1801}
1802
1803TGeoVolume* V3Layer::createStaveOuterB(const TGeoManager* mgr)
1804{
1805 // Create the chip stave for the Outer Barrel
1806 //
1807 // Input:
1808 // mgr : the GeoManager (used only to get the proper material)
1809 //
1810 // Output:
1811 //
1812 // Return:
1813 //
1814 // Created: 20 Dec 2013 Mario Sitta
1815 // Updated: 12 Mar 2014 Mario Sitta
1816 // Updated: 19 Jul 2017 Mario Sitta O2 version
1817 //
1818 TGeoVolume* mechStavVol = nullptr;
1819
1820 switch (mStaveModel) {
1821 case kOBModelDummy:
1822 mechStavVol = createStaveModelOuterBDummy(mgr);
1823 break;
1824 case kOBModel0:
1825 case kOBModel1:
1826 LOG(fatal) << "Stave model " << mStaveModel << " obsolete and no longer supported";
1827 break;
1828 case kOBModel2:
1829 mechStavVol = createStaveModelOuterB2(mgr);
1830 break;
1831 default:
1832 LOG(fatal) << "Unknown stave model " << mStaveModel;
1833 break;
1834 }
1835 return mechStavVol;
1836}
1837
1838TGeoVolume* V3Layer::createStaveModelOuterBDummy(const TGeoManager*) const
1839{
1840 //
1841 // Create dummy stave
1842 //
1843 // Input:
1844 // mgr : the GeoManager (used only to get the proper material)
1845 //
1846 // Output:
1847 //
1848 // Return:
1849 //
1850 // Created: 20 Dec 2013 Mario Sitta
1851 //
1852
1853 // Done, return the stave structure
1854 return nullptr;
1855}
1856
1857TGeoVolume* V3Layer::createStaveModelOuterB2(const TGeoManager* mgr)
1858{
1859 //
1860 // Create the mechanical half stave structure
1861 // for the Outer Barrel as in TDR
1862 //
1863 // Input:
1864 // mgr : the GeoManager (used only to get the proper material)
1865 //
1866 // Output:
1867 //
1868 // Return:
1869 //
1870 // Created: 20 Nov 2013 Anastasia Barbano
1871 // Updated: 16 Jan 2014 Mario Sitta
1872 // Updated: 24 Feb 2014 Mario Sitta
1873 // Updated: 11 Nov 2014 Mario Sitta Model2
1874 // Updated: 03 Dec 2014 Mario Sitta Revised with C.Gargiulo latest infos
1875 // Updated: 19 Jul 2017 Mario Sitta O2 version
1876 // Updated: 04 Aug 2018 Mario Sitta Updated geometry
1877 // Updated: 25 Aug 2018 Mario Sitta To latest blueprints
1878 //
1879
1880 // Local parameters
1881 Double_t yFlex1 = sOBFlexCableAlThick;
1882 Double_t yFlex2 = sOBFlexCableKapThick;
1883 Double_t flexOverlap = 5; // to be checked - unused for the time being
1884 Double_t yCFleece = sOBCarbonFleeceThick;
1885 Double_t yGraph = sOBGraphiteFoilThick;
1886 Double_t xHalfSt, yHalfSt;
1887
1888 Double_t xmod, ymod, zmod, ypowbus, zbias;
1889 Double_t xtru[12], ytru[12];
1890 Double_t xpos, ypos, ypos1, zpos /*, zpos5cm*/;
1891 Double_t xlen, ylen, zlen;
1892 const Int_t nameLen = 30;
1893 char volname[nameLen];
1894
1895 Double_t rCoolMin, rCoolMax;
1896 rCoolMin = sOBCoolTubeInnerD / 2;
1897
1898 rCoolMax = rCoolMin + sOBCoolTubeThick;
1899
1900 // First create all needed shapes
1901
1902 TGeoVolume* moduleVol = createModuleOuterB();
1903 moduleVol->SetVisibility(kTRUE);
1904 xmod = (static_cast<TGeoBBox*>(moduleVol->GetShape()))->GetDX();
1905 ymod = (static_cast<TGeoBBox*>(moduleVol->GetShape()))->GetDY();
1906 zmod = (static_cast<TGeoBBox*>(moduleVol->GetShape()))->GetDZ();
1907
1908 if (mLayerNumber <= 4) {
1909 zlen = sOBColdPlateZLenML / 2; // Middle Layer
1910 } else {
1911 zlen = sOBColdPlateZLenOL / 2; // Outer Layer
1912 }
1913
1914 xlen = sOBColdPlateXWidth / 2;
1915
1916 TGeoBBox* coldPlate = new TGeoBBox("ColdPlate", xlen, sOBColdPlateThick / 2, zlen);
1917
1918 TGeoBBox* fleeccent = new TGeoBBox("FleeceCent", xlen, yCFleece / 2, zlen);
1919
1920 TGeoTube* coolTube = new TGeoTube("CoolingTube", rCoolMin, rCoolMax, zlen);
1921 TGeoTube* coolWater = new TGeoTube("CoolingWater", 0., rCoolMin, zlen);
1922
1923 xlen = sOBColdPlateXWidth / 2 - sOBCoolTubeXDist / 2 - coolTube->GetRmax();
1924 TGeoBBox* graphlat = new TGeoBBox("GraphLateral", xlen / 2, yGraph / 2, zlen);
1925
1926 xlen = sOBCoolTubeXDist / 2 - coolTube->GetRmax();
1927 TGeoBBox* graphmid = new TGeoBBox("GraphMiddle", xlen, yGraph / 2, zlen);
1928
1929 ylen = coolTube->GetRmax() - yGraph;
1930 TGeoBBox* graphvert = new TGeoBBox("GraphVertical", yGraph / 2, ylen / 2, zlen);
1931
1932 TGeoTubeSeg* graphtub = new TGeoTubeSeg("GraphTube", rCoolMax, rCoolMax + yGraph, zlen, 180., 360.);
1933
1934 xlen = sOBColdPlateXWidth / 2 - sOBCoolTubeXDist / 2 - coolTube->GetRmax() - yGraph;
1935 TGeoBBox* fleeclat = new TGeoBBox("FleecLateral", xlen / 2, yCFleece / 2, zlen);
1936
1937 xlen = sOBCoolTubeXDist / 2 - coolTube->GetRmax() - yGraph;
1938 TGeoBBox* fleecmid = new TGeoBBox("FleecMiddle", xlen, yCFleece / 2, zlen);
1939
1940 ylen = coolTube->GetRmax() - yGraph - yCFleece;
1941 TGeoBBox* fleecvert = new TGeoBBox("FleecVertical", yCFleece / 2, ylen / 2, zlen);
1942
1943 TGeoTubeSeg* fleectub =
1944 new TGeoTubeSeg("FleecTube", rCoolMax + yGraph, rCoolMax + yCFleece + yGraph, zlen, 180., 360.);
1945
1946 // TGeoBBox* flex1_5cm = new TGeoBBox("Flex1MV_5cm", xHalfSt, yFlex1 / 2, flexOverlap / 2);
1947 // TGeoBBox* flex2_5cm = new TGeoBBox("Flex2MV_5cm", xHalfSt, yFlex2 / 2, flexOverlap / 2);
1948
1949 // The power bus
1950 TGeoVolume* powerBusVol = createOBPowerBiasBuses(zlen);
1951 powerBusVol->SetVisibility(kTRUE);
1952 ypowbus = (static_cast<TGeoBBox*>(powerBusVol->GetShape()))->GetDY();
1953
1954 // The half stave container (an XTru to avoid overlaps between neightbours)
1955 xHalfSt = xmod; // add the cross cables when done!
1956 yHalfSt = ypowbus + ymod + coldPlate->GetDY() + 2 * fleeccent->GetDY() + graphlat->GetDY() + fleeclat->GetDY();
1957
1958 xtru[0] = xHalfSt;
1959 ytru[0] = 0;
1960 xtru[1] = xtru[0];
1961 ytru[1] = -2 * yHalfSt;
1962 xtru[2] = sOBCoolTubeXDist / 2 + fleectub->GetRmax();
1963 ytru[2] = ytru[1];
1964 xtru[3] = xtru[2];
1965 ytru[3] = ytru[2] - (coolTube->GetRmax() + fleectub->GetRmax());
1966 xtru[4] = sOBCoolTubeXDist / 2 - fleectub->GetRmax();
1967 ytru[4] = ytru[3];
1968 xtru[5] = xtru[4];
1969 ytru[5] = ytru[2];
1970 for (Int_t i = 0; i < 6; i++) {
1971 xtru[6 + i] = -xtru[5 - i];
1972 ytru[6 + i] = ytru[5 - i];
1973 }
1974 TGeoXtru* halfStaveCent = new TGeoXtru(2);
1975 halfStaveCent->DefinePolygon(12, xtru, ytru);
1976 halfStaveCent->DefineSection(0, -zlen);
1977 halfStaveCent->DefineSection(1, zlen);
1978 snprintf(volname, nameLen, "staveCentral%d", mLayerNumber);
1979 halfStaveCent->SetName(volname);
1980
1981 // The connectors' containers
1982 TGeoBBox* connAside = new TGeoBBox("connAsideOB", sOBCPConnectorXWidth / 2, sOBCPConnBlockYHei / 2,
1983 (sOBCPConnBlockZLen + sOBCPConnAFitZLen - sOBCPConnAFitZIn) / 2);
1984
1985 TGeoBBox* connCside =
1986 new TGeoBBox("connCsideOB", sOBCPConnectorXWidth / 2, sOBCPConnBlockYHei / 2, sOBCPConnBlockZLen / 2);
1987
1988 // The StaveStruct container, a Composite Shape
1989 ypos = 2 * yHalfSt + connAside->GetDY() - sOBCPConnHollowYHei;
1990 zpos = zlen + connAside->GetDZ() - sOBCPConnHollowZLen;
1991 snprintf(volname, nameLen, "transAsideOB%d", mLayerNumber);
1992 TGeoTranslation* transAside = new TGeoTranslation(volname, 0, -ypos, zpos);
1993 transAside->RegisterYourself();
1994
1995 zpos = zlen + connCside->GetDZ() - sOBCPConnHollowZLen;
1996 snprintf(volname, nameLen, "transCsideOB%d", mLayerNumber);
1997 TGeoTranslation* transCside = new TGeoTranslation(volname, 0, -ypos, -zpos);
1998 transCside->RegisterYourself();
1999
2000 char componame[70];
2001 snprintf(componame, 70, "staveCentral%d+connAsideOB:transAsideOB%d+connCsideOB:transCsideOB%d", mLayerNumber,
2002 mLayerNumber, mLayerNumber);
2003
2004 TGeoCompositeShape* halfStave = new TGeoCompositeShape(componame);
2005
2006 // We have all shapes: now create the real volumes
2007
2008 TGeoMedium* medAluminum = mgr->GetMedium(Form("%s_ALUMINUM$", GetDetName()));
2009 TGeoMedium* medK13D2U120 = mgr->GetMedium(Form("%s_K13D2U120$", GetDetName()));
2010 TGeoMedium* medKapton = mgr->GetMedium(Form("%s_KAPTON(POLYCH2)$", GetDetName()));
2011 TGeoMedium* medWater = mgr->GetMedium(Form("%s_WATER$", GetDetName()));
2012 TGeoMedium* medCarbonFleece = mgr->GetMedium(Form("%s_CarbonFleece$", GetDetName()));
2013 TGeoMedium* medFGS003 = mgr->GetMedium(Form("%s_FGS003$", GetDetName())); // amec thermasol
2014 TGeoMedium* medAir = mgr->GetMedium(Form("%s_AIR$", GetDetName()));
2015 TGeoMedium* medTungsten = mgr->GetMedium(Form("%s_TUNGSTEN$", GetDetName()));
2016
2017 TGeoVolume* coldPlateVol = new TGeoVolume("ColdPlateVol", coldPlate, medK13D2U120);
2018 coldPlateVol->SetLineColor(kYellow - 3);
2019 coldPlateVol->SetFillColor(coldPlateVol->GetLineColor());
2020 coldPlateVol->SetFillStyle(4000); // 0% transparent
2021
2022 TGeoVolume* fleeccentVol = new TGeoVolume("CarbonFleeceCentral", fleeccent, medCarbonFleece);
2023 fleeccentVol->SetLineColor(kViolet);
2024 fleeccentVol->SetFillColor(fleeccentVol->GetLineColor());
2025 fleeccentVol->SetFillStyle(4000); // 0% transparent
2026
2027 TGeoVolume* coolTubeVol = new TGeoVolume("CoolingTubeVol", coolTube, medKapton);
2028 coolTubeVol->SetLineColor(kGray);
2029 coolTubeVol->SetFillColor(coolTubeVol->GetLineColor());
2030 coolTubeVol->SetFillStyle(4000); // 0% transparent
2031
2032 TGeoVolume* coolWaterVol;
2033 coolWaterVol = new TGeoVolume("CoolingWaterVol", coolWater, medWater);
2034 coolWaterVol->SetLineColor(kBlue);
2035 coolWaterVol->SetFillColor(coolWaterVol->GetLineColor());
2036 coolWaterVol->SetFillStyle(4000); // 0% transparent
2037
2038 TGeoVolume* graphlatVol = new TGeoVolume("GraphiteFoilLateral", graphlat, medFGS003);
2039 graphlatVol->SetLineColor(kGreen);
2040 graphlatVol->SetFillColor(graphlatVol->GetLineColor());
2041 graphlatVol->SetFillStyle(4000); // 0% transparent
2042
2043 TGeoVolume* graphmidVol = new TGeoVolume("GraphiteFoilMiddle", graphmid, medFGS003);
2044 graphmidVol->SetLineColor(kGreen);
2045 graphmidVol->SetFillColor(graphmidVol->GetLineColor());
2046 graphmidVol->SetFillStyle(4000); // 0% transparent
2047
2048 TGeoVolume* graphvertVol = new TGeoVolume("GraphiteFoilVertical", graphvert, medFGS003);
2049 graphvertVol->SetLineColor(kGreen);
2050 graphvertVol->SetFillColor(graphvertVol->GetLineColor());
2051 graphvertVol->SetFillStyle(4000); // 0% transparent
2052
2053 TGeoVolume* graphtubVol = new TGeoVolume("GraphiteFoilPipeCover", graphtub, medFGS003);
2054 graphtubVol->SetLineColor(kGreen);
2055 graphtubVol->SetFillColor(graphtubVol->GetLineColor());
2056 graphtubVol->SetFillStyle(4000); // 0% transparent
2057
2058 TGeoVolume* fleeclatVol = new TGeoVolume("CarbonFleeceLateral", fleeclat, medCarbonFleece);
2059 fleeclatVol->SetLineColor(kViolet);
2060 fleeclatVol->SetFillColor(fleeclatVol->GetLineColor());
2061 fleeclatVol->SetFillStyle(4000); // 0% transparent
2062
2063 TGeoVolume* fleecmidVol = new TGeoVolume("CarbonFleeceMiddle", fleecmid, medCarbonFleece);
2064 fleecmidVol->SetLineColor(kViolet);
2065 fleecmidVol->SetFillColor(fleecmidVol->GetLineColor());
2066 fleecmidVol->SetFillStyle(4000); // 0% transparent
2067
2068 TGeoVolume* fleecvertVol = new TGeoVolume("CarbonFleeceVertical", fleecvert, medCarbonFleece);
2069 fleecvertVol->SetLineColor(kViolet);
2070 fleecvertVol->SetFillColor(fleecvertVol->GetLineColor());
2071 fleecvertVol->SetFillStyle(4000); // 0% transparent
2072
2073 TGeoVolume* fleectubVol = new TGeoVolume("CarbonFleecePipeCover", fleectub, medCarbonFleece);
2074 fleectubVol->SetLineColor(kViolet);
2075 fleectubVol->SetFillColor(fleectubVol->GetLineColor());
2076 fleectubVol->SetFillStyle(4000); // 0% transparent
2077
2078 snprintf(volname, nameLen, "%s%d", GeometryTGeo::getITSHalfStavePattern(), mLayerNumber);
2079 TGeoVolume* halfStaveVol = new TGeoVolume(volname, halfStave, medAir);
2080 // halfStaveVol->SetLineColor(12);
2081 // halfStaveVol->SetFillColor(12);
2082 // halfStaveVol->SetVisibility(kTRUE);
2083
2084 // TGeoVolume* flex1_5cmVol = new TGeoVolume("Flex1Vol5cm", flex1_5cm, medAluminum);
2085 // TGeoVolume* flex2_5cmVol = new TGeoVolume("Flex2Vol5cm", flex2_5cm, medKapton);
2086
2087 // flex1_5cmVol->SetLineColor(kRed);
2088 // flex2_5cmVol->SetLineColor(kGreen);
2089
2090 // Compute starting Z pos to center modules in stave
2091 // (no need to divide by 2, these are already half-lengths)
2092 zbias = zlen - mNumberOfModules * zmod - (mNumberOfModules - 1) * 0.5 * sOBModuleGap;
2093
2094 // Now build up the half stave
2095 ypos = -ypowbus;
2096 halfStaveVol->AddNode(powerBusVol, 1, new TGeoTranslation(0, ypos, 0));
2097
2098 ypos -= (ypowbus + ymod);
2099 for (Int_t j = 0; j < mNumberOfModules; j++) {
2100 zpos = zlen - zbias - j * (2 * zmod + sOBModuleGap) - zmod;
2101 halfStaveVol->AddNode(moduleVol, j, new TGeoTranslation(0, ypos, zpos));
2102 mHierarchy[kModule]++;
2103 }
2104
2105 ypos -= ymod;
2106
2107 ypos -= fleeccent->GetDY();
2108 if (mBuildLevel < 6) { // Carbon
2109 halfStaveVol->AddNode(fleeccentVol, 1, new TGeoTranslation(0, ypos, 0));
2110 }
2111 ypos -= fleeccent->GetDY();
2112
2113 ypos -= coldPlate->GetDY();
2114 if (mBuildLevel < 6) { // Carbon
2115 halfStaveVol->AddNode(coldPlateVol, 1, new TGeoTranslation(0, ypos, 0));
2116 }
2117 ypos -= coldPlate->GetDY();
2118
2119 ypos -= fleeccent->GetDY();
2120 if (mBuildLevel < 6) { // Carbon
2121 halfStaveVol->AddNode(fleeccentVol, 2, new TGeoTranslation(0, ypos, 0));
2122 }
2123
2124 xpos = sOBCoolTubeXDist / 2;
2125 ypos1 = ypos - (fleeccent->GetDY() + coolTube->GetRmax());
2126 if (mBuildLevel < 4) { // Water
2127 halfStaveVol->AddNode(coolWaterVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
2128 halfStaveVol->AddNode(coolWaterVol, 2, new TGeoTranslation(xpos, ypos1, 0));
2129 }
2130
2131 if (mBuildLevel < 5) { // Kapton
2132 halfStaveVol->AddNode(coolTubeVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
2133 halfStaveVol->AddNode(coolTubeVol, 2, new TGeoTranslation(xpos, ypos1, 0));
2134 }
2135
2136 if (mBuildLevel < 6) { // Carbon
2137 halfStaveVol->AddNode(graphtubVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
2138 halfStaveVol->AddNode(graphtubVol, 2, new TGeoTranslation(xpos, ypos1, 0));
2139
2140 halfStaveVol->AddNode(fleectubVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
2141 halfStaveVol->AddNode(fleectubVol, 2, new TGeoTranslation(xpos, ypos1, 0));
2142 }
2143
2144 xpos = sOBColdPlateXWidth / 2 - graphlat->GetDX();
2145 ypos1 = ypos - (fleeccent->GetDY() + graphlat->GetDY());
2146 if (mBuildLevel < 6) { // Carbon
2147 halfStaveVol->AddNode(graphlatVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
2148 halfStaveVol->AddNode(graphlatVol, 2, new TGeoTranslation(xpos, ypos1, 0));
2149
2150 halfStaveVol->AddNode(graphmidVol, 1, new TGeoTranslation(0, ypos1, 0));
2151
2152 xpos = sOBColdPlateXWidth / 2 - 2 * graphlat->GetDX() + graphvert->GetDX();
2153 ypos1 = ypos - (fleeccent->GetDY() + 2 * graphlat->GetDY() + graphvert->GetDY());
2154 halfStaveVol->AddNode(graphvertVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
2155 halfStaveVol->AddNode(graphvertVol, 2, new TGeoTranslation(xpos, ypos1, 0));
2156 xpos = graphmid->GetDX() - graphvert->GetDX();
2157 halfStaveVol->AddNode(graphvertVol, 3, new TGeoTranslation(-xpos, ypos1, 0));
2158 halfStaveVol->AddNode(graphvertVol, 4, new TGeoTranslation(xpos, ypos1, 0));
2159 }
2160
2161 xpos = sOBColdPlateXWidth / 2 - fleeclat->GetDX();
2162 ypos1 = ypos - (fleeccent->GetDY() + 2 * graphlat->GetDY() + fleeclat->GetDY());
2163 if (mBuildLevel < 6) { // Carbon
2164 halfStaveVol->AddNode(fleeclatVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
2165 halfStaveVol->AddNode(fleeclatVol, 2, new TGeoTranslation(xpos, ypos1, 0));
2166
2167 halfStaveVol->AddNode(fleecmidVol, 1, new TGeoTranslation(0, ypos1, 0));
2168
2169 xpos = sOBColdPlateXWidth / 2 - 2 * fleeclat->GetDX() + fleecvert->GetDX();
2170 ypos1 = ypos - (fleeccent->GetDY() + 2 * graphlat->GetDY() + 2 * fleeclat->GetDY() + fleecvert->GetDY());
2171 halfStaveVol->AddNode(fleecvertVol, 1, new TGeoTranslation(-xpos, ypos1, 0));
2172 halfStaveVol->AddNode(fleecvertVol, 2, new TGeoTranslation(xpos, ypos1, 0));
2173 xpos = fleecmid->GetDX() - fleecvert->GetDX();
2174 halfStaveVol->AddNode(fleecvertVol, 3, new TGeoTranslation(-xpos, ypos1, 0));
2175 halfStaveVol->AddNode(fleecvertVol, 4, new TGeoTranslation(xpos, ypos1, 0));
2176 }
2177
2178 // Add the end-stave connectors
2179 TGeoVolume *connectorASide, *connectorCSide;
2180
2181 // Check whether we have already all pieces
2182 // Otherwise create them
2183 connectorASide = mgr->GetVolume("OBColdPlateConnectorASide");
2184
2185 if (!connectorASide) {
2186 createOBColdPlateConnectors();
2187 connectorASide = mgr->GetVolume("OBColdPlateConnectorASide");
2188 }
2189 connectorCSide = mgr->GetVolume("OBColdPlateConnectorCSide");
2190
2191 ypos = 2 * yHalfSt + (static_cast<TGeoBBox*>(connectorASide->GetShape()))->GetDY() - sOBCPConnHollowYHei;
2192 zpos = zlen + (static_cast<TGeoBBox*>(connectorASide->GetShape()))->GetDZ() - sOBCPConnHollowZLen;
2193 halfStaveVol->AddNode(connectorASide, 1, new TGeoCombiTrans(0, -ypos, zpos, new TGeoRotation("", 180, 0, 0)));
2194
2195 zpos = zlen + (static_cast<TGeoBBox*>(connectorCSide->GetShape()))->GetDZ() - sOBCPConnHollowZLen;
2196 halfStaveVol->AddNode(connectorCSide, 1, new TGeoCombiTrans(0, -ypos, -zpos, new TGeoRotation("", 180, 0, 0)));
2197
2198 // Done, return the half stave structure
2199 return halfStaveVol;
2200}
2201
2202TGeoVolume* V3Layer::createOBPowerBiasBuses(const Double_t zcable, const TGeoManager* mgr)
2203{
2204 //
2205 // Create the OB Power Bus and Bias Bus cables
2206 //
2207 // Input:
2208 // zcable : the cable half Z length
2209 // mgr : the GeoManager (used only to get the proper material)
2210 //
2211 // Output:
2212 //
2213 // Return:
2214 // a TGeoVolume with both the Power and the Bias Buses
2215 //
2216 // Created: 05 Aug 2018 Mario Sitta
2217 // Updated: 06 Sep 2018 Mario Sitta
2218 //
2219
2220 Double_t xcable, ytot, ypos;
2221
2222 // First create all needed shapes
2223 xcable = sOBPowerBusXWidth / 2;
2224 TGeoBBox* gndPB = new TGeoBBox(xcable, sOBPowerBusAlThick / 2, zcable);
2225 TGeoBBox* dielPB = new TGeoBBox(xcable, sOBPowerBusDielThick / 2, zcable);
2226 TGeoBBox* kapPB = new TGeoBBox(xcable, sOBPowerBusKapThick / 2, zcable);
2227 xcable *= sOBPowerBusAlFrac;
2228 TGeoBBox* topPB = new TGeoBBox(xcable, sOBPowerBusAlThick / 2, zcable);
2229
2230 xcable = sOBBiasBusXWidth / 2;
2231 TGeoBBox* botBB = new TGeoBBox(xcable, sOBBiasBusAlThick / 2, zcable);
2232 TGeoBBox* dielBB = new TGeoBBox(xcable, sOBBiasBusDielThick / 2, zcable);
2233 TGeoBBox* kapBB = new TGeoBBox(xcable, sOBBiasBusKapThick / 2, zcable);
2234 xcable *= sOBBiasBusAlFrac;
2235 TGeoBBox* topBB = new TGeoBBox(xcable, sOBBiasBusAlThick / 2, zcable);
2236
2237 // Then the volumes
2238 TGeoMedium* medKapton = mgr->GetMedium(Form("%s_KAPTON(POLYCH2)$", GetDetName()));
2239 TGeoMedium* medAluminum = mgr->GetMedium(Form("%s_ALUMINUM$", GetDetName()));
2240 TGeoMedium* medAir = mgr->GetMedium(Form("%s_AIR$", GetDetName()));
2241
2242 TGeoVolume* gndPBVol = new TGeoVolume("PowerBusGround", gndPB, medAluminum);
2243 gndPBVol->SetLineColor(kCyan);
2244 gndPBVol->SetFillColor(gndPBVol->GetLineColor());
2245 gndPBVol->SetFillStyle(4000); // 0% transparent
2246
2247 TGeoVolume* dielPBVol = new TGeoVolume("PowerBusDielectric", dielPB, medKapton);
2248 dielPBVol->SetLineColor(kBlue);
2249 dielPBVol->SetFillColor(dielPBVol->GetLineColor());
2250 dielPBVol->SetFillStyle(4000); // 0% transparent
2251
2252 TGeoVolume* kapPBVol = new TGeoVolume("PowerBusKapton", kapPB, medKapton);
2253 kapPBVol->SetLineColor(kBlue);
2254 kapPBVol->SetFillColor(kapPBVol->GetLineColor());
2255 kapPBVol->SetFillStyle(4000); // 0% transparent
2256
2257 TGeoVolume* topPBVol = new TGeoVolume("PowerBusTop", topPB, medAluminum);
2258 topPBVol->SetLineColor(kCyan);
2259 topPBVol->SetFillColor(topPBVol->GetLineColor());
2260 topPBVol->SetFillStyle(4000); // 0% transparent
2261
2262 TGeoVolume* botBBVol = new TGeoVolume("BiasBusBottom", botBB, medAluminum);
2263 botBBVol->SetLineColor(kCyan);
2264 botBBVol->SetFillColor(botBBVol->GetLineColor());
2265 botBBVol->SetFillStyle(4000); // 0% transparent
2266
2267 TGeoVolume* dielBBVol = new TGeoVolume("BiasBusDielectric", dielBB, medKapton);
2268 dielBBVol->SetLineColor(kBlue);
2269 dielBBVol->SetFillColor(dielBBVol->GetLineColor());
2270 dielBBVol->SetFillStyle(4000); // 0% transparent
2271
2272 TGeoVolume* kapBBVol = new TGeoVolume("BiasBusKapton", kapBB, medKapton);
2273 kapBBVol->SetLineColor(kBlue);
2274 kapBBVol->SetFillColor(kapBBVol->GetLineColor());
2275 kapBBVol->SetFillStyle(4000); // 0% transparent
2276
2277 TGeoVolume* topBBVol = new TGeoVolume("BiasBusTop", topBB, medAluminum);
2278 topBBVol->SetLineColor(kCyan);
2279 topBBVol->SetFillColor(topBBVol->GetLineColor());
2280 topBBVol->SetFillStyle(4000); // 0% transparent
2281
2282 // Finally the volume containing both the Power Bus and the Bias Bus
2283 xcable = sOBPowerBusXWidth / 2;
2284 ytot = 2 * kapPB->GetDY() + topPB->GetDY() + dielPB->GetDY() + gndPB->GetDY() + 2 * kapBB->GetDY() + topBB->GetDY() + dielBB->GetDY() + botBB->GetDY();
2285
2286 TGeoBBox* pnbBus = new TGeoBBox(xcable, ytot, zcable);
2287
2288 TGeoVolume* pnbBusVol = new TGeoVolume("OBPowerBiasBus", pnbBus, medAir);
2289
2290 // Volumes are piled up from bottom to top
2291 ypos = -pnbBus->GetDY() + kapPB->GetDY();
2292 if (mBuildLevel < 5) { // Kapton
2293 pnbBusVol->AddNode(kapPBVol, 1, new TGeoTranslation(0, ypos, 0));
2294 }
2295
2296 ypos += (kapPB->GetDY() + gndPB->GetDY());
2297 if (mBuildLevel < 2) { // Aluminum
2298 pnbBusVol->AddNode(gndPBVol, 1, new TGeoTranslation(0, ypos, 0));
2299 }
2300
2301 ypos += (gndPB->GetDY() + dielPB->GetDY());
2302 if (mBuildLevel < 5) { // Kapton
2303 pnbBusVol->AddNode(dielPBVol, 1, new TGeoTranslation(0, ypos, 0));
2304 }
2305
2306 ypos += (dielPB->GetDY() + topPB->GetDY());
2307 if (mBuildLevel < 2) { // Aluminum
2308 pnbBusVol->AddNode(topPBVol, 1, new TGeoTranslation(0, ypos, 0));
2309 }
2310
2311 ypos += (topPB->GetDY() + kapPB->GetDY());
2312 if (mBuildLevel < 5) { // Kapton
2313 pnbBusVol->AddNode(kapPBVol, 2, new TGeoTranslation(0, ypos, 0));
2314 }
2315
2316 //
2317 ypos += (kapPB->GetDY() + kapBB->GetDY());
2318 if (mBuildLevel < 5) { // Kapton
2319 pnbBusVol->AddNode(kapBBVol, 1, new TGeoTranslation(0, ypos, 0));
2320 }
2321
2322 ypos += (kapBB->GetDY() + botBB->GetDY());
2323 if (mBuildLevel < 2) { // Aluminum
2324 pnbBusVol->AddNode(botBBVol, 1, new TGeoTranslation(0, ypos, 0));
2325 }
2326
2327 ypos += (botBB->GetDY() + dielBB->GetDY());
2328 if (mBuildLevel < 5) { // Kapton
2329 pnbBusVol->AddNode(dielBBVol, 1, new TGeoTranslation(0, ypos, 0));
2330 }
2331
2332 ypos += (dielBB->GetDY() + topBB->GetDY());
2333 if (mBuildLevel < 2) { // Aluminum
2334 pnbBusVol->AddNode(topBBVol, 1, new TGeoTranslation(0, ypos, 0));
2335 }
2336
2337 ypos += (topBB->GetDY() + kapBB->GetDY());
2338 if (mBuildLevel < 5) { // Kapton
2339 pnbBusVol->AddNode(kapBBVol, 2, new TGeoTranslation(0, ypos, 0));
2340 }
2341
2342 //
2343 return pnbBusVol;
2344}
2345
2346void V3Layer::createOBColdPlateConnectors()
2347{
2348 //
2349 // Create the Cold Plate connectors for OB half staves
2350 // (simply call the actual creator methods)
2351 //
2352 // Input:
2353 //
2354 // Output:
2355 //
2356 // Return:
2357 //
2358 // Created: 26 May 2015 Mario Sitta
2359 //
2360
2361 createOBColdPlateConnectorsASide();
2362 createOBColdPlateConnectorsCSide();
2363}
2364
2365void V3Layer::createOBColdPlateConnectorsASide()
2366{
2367 //
2368 // Create the A-Side end-stave connectors for IB staves
2369 //
2370 // Input:
2371 //
2372 // Output:
2373 //
2374 // Return:
2375 //
2376 // Created: 26 May 2015 Mario Sitta
2377 // Updated: 20 Jul 2017 Mario Sitta O2 version
2378 // Updated: 15 Oct 2018 Mario Sitta To latest blueprints
2379 //
2380
2381 // The geoManager
2382 const TGeoManager* mgr = gGeoManager;
2383
2384 // Local variables
2385 const Int_t nv = 16;
2386 Double_t xv[nv], yv[nv];
2387 Double_t xlen, ylen, zlen;
2388 Double_t xpos, ypos, zpos;
2389
2390 // Gather all material pointers
2391 TGeoMedium* medAir = mgr->GetMedium(Form("%s_AIR$", GetDetName()));
2392 TGeoMedium* medPEEK = mgr->GetMedium(Form("%s_PEEKCF30$", GetDetName()));
2393 TGeoMedium* medInox304 = mgr->GetMedium(Form("%s_INOX304$", GetDetName()));
2394
2395 // First create all elements
2396
2397 // The connector block, a Composite Shape
2398 xlen = sOBCPConnectorXWidth;
2399 ylen = sOBCPConnBlockYHei;
2400 zlen = sOBCPConnBlockZLen;
2401 TGeoBBox* connBlock = new TGeoBBox("connBlockA", xlen / 2, ylen / 2, zlen / 2);
2402
2403 xv[0] = sOBCPConnectorXWidth * 0.6;
2404 yv[0] = -sOBCPConnHollowYHei;
2405 xv[1] = xv[0];
2406 yv[1] = sOBCPConnHollowYHei;
2407 xv[2] = sOBCPConnTubesXDist / 2 + sOBCPConnTubeHole1D / 2;
2408 yv[2] = yv[1];
2409 xv[3] = xv[2];
2410 yv[3] = sOBCPConnTubesYPos;
2411 xv[4] = sOBCPConnTubesXDist / 2 - sOBCPConnTubeHole1D / 2;
2412 yv[4] = yv[3];
2413 xv[5] = xv[4];
2414 yv[5] = yv[2];
2415
2416 for (Int_t i = 0; i < 6; i++) {
2417 xv[6 + i] = -xv[5 - i];
2418 yv[6 + i] = yv[5 - i];
2419 }
2420
2421 TGeoXtru* connBlockHoll = new TGeoXtru(2);
2422 connBlockHoll->SetName("connBlockHollA");
2423 connBlockHoll->DefinePolygon(12, xv, yv);
2424 connBlockHoll->DefineSection(0, -sOBCPConnHollowZLen);
2425 connBlockHoll->DefineSection(1, sOBCPConnHollowZLen);
2426
2427 ypos = -connBlock->GetDY();
2428 zpos = -connBlock->GetDZ();
2429 TGeoTranslation* transBlockHoll = new TGeoTranslation("transBlockHollA", 0, ypos, zpos);
2430 transBlockHoll->RegisterYourself();
2431
2432 xlen = sOBCPConnSquareHoleX / 2;
2433 ylen = sOBCPConnBlockYHei / 1.5;
2434 zlen = sOBCPConnSquareHoleZ / 2;
2435 TGeoBBox* connSquareHole = new TGeoBBox("connASquareHole", xlen, ylen, zlen);
2436
2437 zpos =
2438 -connBlock->GetDZ() + (sOBCPConnSqrHoleZPos + connSquareHole->GetDZ());
2439 TGeoTranslation* transSquareHole = new TGeoTranslation("transASquareHole", 0, 0, zpos);
2440 transSquareHole->RegisterYourself();
2441
2442 zlen = sOBCPConnTubeHole1Z;
2443 TGeoTube* connTubeHole1 = new TGeoTube("tube1AHole", 0, sOBCPConnTubeHole1D / 2, zlen);
2444
2445 xpos = sOBCPConnTubesXDist / 2;
2446 ypos = -connBlock->GetDY() + sOBCPConnTubesYPos;
2447 zpos = connBlock->GetDZ();
2448 TGeoTranslation* trans1Tube1AHole = new TGeoTranslation("trans1Tube1AHole", -xpos, ypos, -zpos);
2449 trans1Tube1AHole->RegisterYourself();
2450 TGeoTranslation* trans2Tube1AHole = new TGeoTranslation("trans2Tube1AHole", xpos, ypos, -zpos);
2451 trans2Tube1AHole->RegisterYourself();
2452
2453 zlen = sOBCPConnBlockZLen;
2454 TGeoTube* connTubeHole2 = new TGeoTube("tube2AHole", 0, sOBCPConnTubeHole2D / 2, zlen);
2455
2456 TGeoTranslation* trans1Tube2AHole = new TGeoTranslation("trans1Tube2AHole", -xpos, ypos, 0);
2457 trans1Tube2AHole->RegisterYourself();
2458 TGeoTranslation* trans2Tube2AHole = new TGeoTranslation("trans2Tube2AHole", xpos, ypos, 0);
2459 trans2Tube2AHole->RegisterYourself();
2460
2461 zlen = sOBCPConnAFitZIn;
2462 TGeoTube* connFitHole = new TGeoTube("fitAHole", 0, sOBCPConnFitHoleD / 2, zlen);
2463
2464 TGeoTranslation* trans1FitAHole = new TGeoTranslation("trans1FitAHole", -xpos, ypos, zpos);
2465 trans1FitAHole->RegisterYourself();
2466 TGeoTranslation* trans2FitAHole = new TGeoTranslation("trans2FitAHole", xpos, ypos, zpos);
2467 trans2FitAHole->RegisterYourself();
2468
2469 TGeoCompositeShape* connBlockSh = new TGeoCompositeShape(
2470 "connBlockA-connBlockHollA:transBlockHollA-connASquareHole:transASquareHole-tube1AHole:trans1Tube1AHole-tube1AHole:"
2471 "trans2Tube1AHole-tube2AHole:trans1Tube2AHole-tube2AHole:trans2Tube2AHole-fitAHole:trans1FitAHole-fitAHole:"
2472 "trans2FitAHole");
2473
2474 TGeoVolume* connBlockA = new TGeoVolume("OBColdPlateConnectorBlockASide", connBlockSh, medPEEK);
2475 connBlockA->SetFillColor(42); // Brownish shade
2476 connBlockA->SetLineColor(42);
2477
2478 // The fitting tubes, a Tube
2479 Double_t rmin = sOBCPConnAFitExtD / 2 - sOBCPConnAFitThick;
2480 TGeoTube* connFitSh = new TGeoTube(rmin, sOBCPConnAFitExtD / 2, sOBCPConnAFitZLen / 2);
2481
2482 TGeoVolume* connFit = new TGeoVolume("OBColdPlateConnectorFitting", connFitSh, medInox304);
2483 connFit->SetFillColor(kGray);
2484 connFit->SetLineColor(kGray);
2485
2486 // Now create the container: cannot be a simple box
2487 // to avoid fake overlaps with stave elements
2488 xlen = sOBCPConnectorXWidth;
2489 ylen = sOBCPConnBlockYHei;
2490 zlen = sOBCPConnBlockZLen + (sOBCPConnAFitZLen - sOBCPConnAFitZIn);
2491 TGeoBBox* connBox = new TGeoBBox("connectorOBCPA", xlen / 2, ylen / 2, zlen / 2);
2492
2493 ypos = -connBox->GetDY();
2494 zpos = -connBox->GetDZ();
2495 TGeoTranslation* transBoxHoll = new TGeoTranslation("transBoxHollA", 0, ypos, zpos);
2496 transBoxHoll->RegisterYourself();
2497
2498 xpos = sOBCPConnTubesXDist / 2;
2499 ypos = -connBox->GetDY() + sOBCPConnTubesYPos;
2500 zpos = connBox->GetDZ();
2501 TGeoTranslation* trans1BoxHole = new TGeoTranslation("trans1BoxAHole", -xpos, ypos, -zpos);
2502 trans1BoxHole->RegisterYourself();
2503 TGeoTranslation* trans2BoxHole = new TGeoTranslation("trans2BoxAHole", xpos, ypos, -zpos);
2504 trans2BoxHole->RegisterYourself();
2505
2506 TGeoCompositeShape* connectSh = new TGeoCompositeShape(
2507 "connectorOBCPA-connBlockHollA:transBoxHollA-tube1AHole:trans1BoxAHole-tube1AHole:trans2BoxAHole");
2508
2509 TGeoVolume* connectorASide = new TGeoVolume("OBColdPlateConnectorASide", connectSh, medAir);
2510
2511 // Finally build up the connector
2512 zpos = -connectSh->GetDZ() + connBlock->GetDZ();
2513 connectorASide->AddNode(connBlockA, 1, new TGeoTranslation(0, 0, zpos));
2514
2515 xpos = sOBCPConnTubesXDist / 2;
2516 ypos = -connBlock->GetDY() + sOBCPConnTubesYPos;
2517 zpos = connectSh->GetDZ() - connFitSh->GetDz();
2518 connectorASide->AddNode(connFit, 1, new TGeoTranslation(-xpos, ypos, zpos));
2519 connectorASide->AddNode(connFit, 2, new TGeoTranslation(xpos, ypos, zpos));
2520}
2521
2522void V3Layer::createOBColdPlateConnectorsCSide()
2523{
2524 //
2525 // Create the C-Side end-stave connectors for IB staves
2526 //
2527 // Input:
2528 //
2529 // Output:
2530 //
2531 // Return:
2532 //
2533 // Created: 29 May 2015 Mario Sitta
2534 // Updated: 20 Jul 2017 Mario Sitta O2 version
2535 // Updated: 15 Oct 2018 Mario Sitta To latest blueprints
2536 //
2537
2538 // The geoManager
2539 const TGeoManager* mgr = gGeoManager;
2540
2541 // Local variables
2542 const Int_t nv = 16;
2543 Double_t xv[nv], yv[nv];
2544 Double_t xlen, ylen, zlen;
2545 Double_t xpos, ypos, zpos;
2546
2547 // Gather all material pointers
2548 TGeoMedium* medAir = mgr->GetMedium(Form("%s_AIR$", GetDetName()));
2549 TGeoMedium* medPEEK = mgr->GetMedium(Form("%s_PEEKCF30$", GetDetName()));
2550
2551 // First create all elements
2552
2553 // The connector block, a Composite Shape
2554 xlen = sOBCPConnectorXWidth;
2555 ylen = sOBCPConnBlockYHei;
2556 zlen = sOBCPConnBlockZLen;
2557 TGeoBBox* connBlock = new TGeoBBox("connBlockC", xlen / 2, ylen / 2, zlen / 2);
2558
2559 xv[0] = sOBCPConnectorXWidth * 0.6;
2560 yv[0] = -sOBCPConnHollowYHei;
2561 xv[1] = xv[0];
2562 yv[1] = sOBCPConnHollowYHei;
2563 xv[2] = sOBCPConnTubesXDist / 2 + sOBCPConnTubeHole1D / 2;
2564 yv[2] = yv[1];
2565 xv[3] = xv[2];
2566 yv[3] = sOBCPConnTubesYPos;
2567 xv[4] = sOBCPConnTubesXDist / 2 - sOBCPConnTubeHole1D / 2;
2568 yv[4] = yv[3];
2569 xv[5] = xv[4];
2570 yv[5] = yv[2];
2571
2572 for (Int_t i = 0; i < 6; i++) {
2573 xv[6 + i] = -xv[5 - i];
2574 yv[6 + i] = yv[5 - i];
2575 }
2576
2577 TGeoXtru* connBlockHoll = new TGeoXtru(2);
2578 connBlockHoll->SetName("connBlockHollC");
2579 connBlockHoll->DefinePolygon(12, xv, yv);
2580 connBlockHoll->DefineSection(0, -sOBCPConnHollowZLen);
2581 connBlockHoll->DefineSection(1, sOBCPConnHollowZLen);
2582
2583 ypos = -connBlock->GetDY();
2584 zpos = connBlock->GetDZ();
2585 TGeoTranslation* transBlockHoll = new TGeoTranslation("transBlockHollC", 0, ypos, zpos);
2586 transBlockHoll->RegisterYourself();
2587
2588 TGeoTube* connRoundHole = new TGeoTube("connCRoundHole", 0, sOBCPConnRoundHoleD / 2, sOBCPConnBlockYHei / 1.5);
2589
2590 zpos = connBlock->GetDZ() - sOBCPConnRndHoleZPos;
2591 TGeoCombiTrans* transRoundHole = new TGeoCombiTrans("transCRoundHole", 0, 0, zpos, new TGeoRotation("", 0, 90, 0));
2592 transRoundHole->RegisterYourself();
2593
2594 zlen = sOBCPConnTubeHole1Z;
2595 TGeoTube* connTubeHole1 = new TGeoTube("tube1CHole", 0, sOBCPConnTubeHole1D / 2, zlen);
2596
2597 xpos = sOBCPConnTubesXDist / 2;
2598 ypos = -connBlock->GetDY() + sOBCPConnTubesYPos;
2599 zpos = connBlock->GetDZ();
2600 TGeoTranslation* trans1Tube1AHole = new TGeoTranslation("trans1Tube1CHole", -xpos, ypos, zpos);
2601 trans1Tube1AHole->RegisterYourself();
2602 TGeoTranslation* trans2Tube1AHole = new TGeoTranslation("trans2Tube1CHole", xpos, ypos, zpos);
2603 trans2Tube1AHole->RegisterYourself();
2604
2605 TGeoTube* connTubeHole2 = new TGeoTube("tube2CHole", 0, sOBCPConnTubeHole2D / 2, connBlock->GetDZ());
2606
2607 zpos = sOBCPConnTubeHole3ZP;
2608 TGeoTranslation* connTubes2Trans1 = new TGeoTranslation("trans1Tube2CHole", -xpos, ypos, zpos);
2609 connTubes2Trans1->RegisterYourself();
2610 TGeoTranslation* connTubes2Trans2 = new TGeoTranslation("trans2Tube2CHole", xpos, ypos, zpos);
2611 connTubes2Trans2->RegisterYourself();
2612
2613 TGeoTube* connTubeHole3 = new TGeoTube("tube3CHole", 0, sOBCPConnTubeHole2D / 2, connBlock->GetDX());
2614
2615 xpos = -sOBCPConnTubeHole3XP;
2616 zpos = -connBlock->GetDZ() + sOBCPConnTubeHole3ZP;
2617 TGeoCombiTrans* connTubes3Trans =
2618 new TGeoCombiTrans("transTube3CHole", xpos, ypos, zpos, new TGeoRotation("", 90, -90, 90));
2619 connTubes3Trans->RegisterYourself();
2620
2621 TGeoCompositeShape* connBlockSh = new TGeoCompositeShape(
2622 "connBlockC-connBlockHollC:transBlockHollC-connCRoundHole:transCRoundHole-tube1CHole:trans1Tube1CHole-tube1CHole:"
2623 "trans2Tube1CHole-tube2CHole:trans1Tube2CHole-tube2CHole:trans2Tube2CHole-tube3CHole:transTube3CHole");
2624
2625 TGeoVolume* connBlockC = new TGeoVolume("OBColdPlateConnectorBlockCSide", connBlockSh, medPEEK);
2626 connBlockC->SetFillColor(42); // Brownish shade
2627 connBlockC->SetLineColor(42);
2628
2629 // The plug, a Pcon
2630 TGeoPcon* connPlugSh = new TGeoPcon(0, 360, 4);
2631 connPlugSh->DefineSection(0, 0., 0., sOBCPConnTubeHole2D / 2);
2632 connPlugSh->DefineSection(1, sOBCPConnPlugThick, 0., sOBCPConnTubeHole2D / 2);
2633 connPlugSh->DefineSection(2, sOBCPConnPlugThick, sOBCPConnPlugInnerD / 2, sOBCPConnTubeHole2D / 2);
2634 connPlugSh->DefineSection(3, sOBCPConnPlugTotLen, sOBCPConnPlugInnerD / 2, sOBCPConnTubeHole2D / 2);
2635
2636 TGeoVolume* connPlug = new TGeoVolume("OBCPConnectorPlugC", connPlugSh, medPEEK);
2637 connPlug->SetFillColor(44); // Brownish shade (a bit darker to spot it)
2638 connPlug->SetLineColor(44);
2639
2640 // Now create the container: cannot be a simple box
2641 // to avoid fake overlaps with stave elements
2642 xlen = sOBCPConnectorXWidth;
2643 ylen = sOBCPConnBlockYHei;
2644 zlen = sOBCPConnBlockZLen;
2645 TGeoBBox* connBox = new TGeoBBox("connectorOBCPC", xlen / 2, ylen / 2, zlen / 2);
2646
2647 ypos = -connBox->GetDY();
2648 zpos = connBox->GetDZ();
2649 TGeoTranslation* transBoxHoll = new TGeoTranslation("transBoxHollC", 0, ypos, zpos);
2650 transBoxHoll->RegisterYourself();
2651
2652 xpos = sOBCPConnTubesXDist / 2;
2653 ypos = -connBox->GetDY() + sOBCPConnTubesYPos;
2654 zpos = connBox->GetDZ();
2655 TGeoTranslation* trans1BoxHole = new TGeoTranslation("trans1BoxCHole", -xpos, ypos, zpos);
2656 trans1BoxHole->RegisterYourself();
2657 TGeoTranslation* trans2BoxHole = new TGeoTranslation("trans2BoxCHole", xpos, ypos, zpos);
2658 trans2BoxHole->RegisterYourself();
2659
2660 TGeoCompositeShape* connectSh = new TGeoCompositeShape(
2661 "connectorOBCPC-connBlockHollC:transBoxHollC-tube1CHole:trans1BoxCHole-tube1CHole:trans2BoxCHole");
2662
2663 TGeoVolume* connectorCSide = new TGeoVolume("OBColdPlateConnectorCSide", connectSh, medAir);
2664
2665 // Finally build up the connector
2666 connectorCSide->AddNode(connBlockC, 1);
2667
2668 xpos = -connBlock->GetDX();
2669 ypos = -connBlock->GetDY() + sOBCPConnTubesYPos;
2670 zpos = -connBlock->GetDZ() + sOBCPConnTubeHole3ZP;
2671 connectorCSide->AddNode(connPlug, 1, new TGeoCombiTrans(xpos, ypos, zpos, new TGeoRotation("", 90, 90, 90)));
2672}
2673
2674TGeoVolume* V3Layer::createSpaceFrameOuterB(const TGeoManager* mgr)
2675{
2676 TGeoVolume* mechStavVol = nullptr;
2677
2678 switch (mStaveModel) {
2679 case kOBModelDummy:
2680 case kOBModel0:
2681 mechStavVol = createSpaceFrameOuterBDummy(mgr);
2682 break;
2683 case kOBModel1:
2684 case kOBModel2:
2685 mechStavVol = createSpaceFrameOuterB2(mgr);
2686 break;
2687 default:
2688 LOG(fatal) << "Unknown stave model " << mStaveModel;
2689 break;
2690 }
2691
2692 return mechStavVol;
2693}
2694
2695TGeoVolume* V3Layer::createSpaceFrameOuterBDummy(const TGeoManager*) const
2696{
2697 //
2698 // Create dummy stave
2699 //
2700 // Input:
2701 // mgr : the GeoManager (used only to get the proper material)
2702 //
2703 // Output:
2704 //
2705 // Return:
2706 //
2707
2708 // Done, return the stave structur
2709 return nullptr;
2710}
2711
2712TGeoVolume* V3Layer::createSpaceFrameOuterB2(const TGeoManager* mgr)
2713{
2714 //
2715 // Create the space frame for the Outer Barrel (Model 2)
2716 // The building blocks are created in another method to avoid
2717 // replicating the same volumes for all OB staves
2718 //
2719 // Input:
2720 // mgr : the GeoManager (used only to get the proper material)
2721 //
2722 // Output:
2723 //
2724 // Return:
2725 // a TGeoVolume with the Space Frame of a stave
2726 //
2727 // Created: 03 Feb 2015 Mario Sitta
2728 // Updated: 04 Jun 2015 Mario Sitta Change container to avoid overlaps
2729 // Updated: 20 Jul 2017 Mario Sitta O2 version
2730 //
2731
2732 TGeoMedium* medAir = mgr->GetMedium(Form("%s_AIR$", GetDetName()));
2733
2734 TGeoVolume *unitVol[2], *next2EndVol[2], *endVol[2];
2735 Double_t *xtru, *ytru;
2736 Double_t zlen, zpos;
2737 Int_t nPoints;
2738 const Int_t nameLen = 30;
2739 char volname[nameLen];
2740
2741 // Check whether we have already all pieces
2742 // Otherwise create them
2743 unitVol[0] = mgr->GetVolume("SpaceFrameUnit0");
2744
2745 if (!unitVol[0]) {
2746 createOBSpaceFrameObjects(mgr);
2747 unitVol[0] = mgr->GetVolume("SpaceFrameUnit0");
2748 }
2749
2750 unitVol[1] = mgr->GetVolume("SpaceFrameUnit1");
2751
2752 next2EndVol[0] = mgr->GetVolume("SpaceFrameNext2EndUnit0");
2753 next2EndVol[1] = mgr->GetVolume("SpaceFrameNext2EndUnit1");
2754
2755 endVol[0] = mgr->GetVolume("SpaceFrameEndUnit0");
2756 endVol[1] = mgr->GetVolume("SpaceFrameEndUnit1");
2757
2758 // Get the shape of the units
2759 // and create a similar shape for the Space Frame container
2760 TGeoXtru* volShape = static_cast<TGeoXtru*>(unitVol[0]->GetShape());
2761
2762 nPoints = volShape->GetNvert();
2763 xtru = new Double_t[nPoints];
2764 ytru = new Double_t[nPoints];
2765
2766 for (Int_t i = 0; i < nPoints; i++) {
2767 xtru[i] = volShape->GetX(i);
2768 ytru[i] = volShape->GetY(i);
2769 }
2770
2771 Int_t nUnits = sOBSpaceFrameNUnits[mLayerNumber / 5]; // 3,4 -> 0 - 5,6 -> 1
2772 zlen = (nUnits - 2) * sOBSpaceFrameUnitLen; // Take end units out
2773
2774 TGeoXtru* spaceFrameCentral = new TGeoXtru(2);
2775 spaceFrameCentral->DefinePolygon(nPoints, xtru, ytru);
2776 spaceFrameCentral->DefineSection(0, -zlen / 2);
2777 spaceFrameCentral->DefineSection(1, zlen / 2);
2778 snprintf(volname, nameLen, "sframecentral%d", mLayerNumber);
2779 spaceFrameCentral->SetName(volname);
2780
2781 zpos = zlen / 2 + sOBSpaceFrameUnitLen / 2;
2782 snprintf(volname, nameLen, "endUnit0Trans%d", mLayerNumber);
2783 TGeoCombiTrans* endUnit0Trans = new TGeoCombiTrans(volname, 0, 0, -zpos, new TGeoRotation("", 90, 180, -90));
2784 endUnit0Trans->RegisterYourself();
2785 snprintf(volname, nameLen, "endUnit1Trans%d", mLayerNumber);
2786 TGeoTranslation* endUnit1Trans = new TGeoTranslation(volname, 0, 0, zpos);
2787 endUnit1Trans->RegisterYourself();
2788
2789 // The Space Frame container: a Composite Shape to avoid overlaps
2790 // between the U-legs space and the end-stave connectors
2791 // ("endunitcontainer" is defined in CreateOBSpaceFrameObjects)
2792 char componame[100];
2793 snprintf(componame, 100, "sframecentral%d+endunitcontainer:endUnit0Trans%d+endunitcontainer:endUnit1Trans%d",
2794 mLayerNumber, mLayerNumber, mLayerNumber);
2795
2796 TGeoCompositeShape* spaceFrame = new TGeoCompositeShape(componame);
2797
2798 snprintf(volname, nameLen, "SpaceFrameVolumeLay%d", mLayerNumber);
2799 TGeoVolume* spaceFrameVol = new TGeoVolume(volname, spaceFrame, medAir);
2800 spaceFrameVol->SetVisibility(kFALSE);
2801
2802 // Finally build up the space frame
2803 TGeoXtru* frameUnit = static_cast<TGeoXtru*>(unitVol[0]->GetShape());
2804
2805 zpos = -spaceFrame->GetDZ() + frameUnit->GetDZ() + sOBSFrameConnTopLen;
2806 spaceFrameVol->AddNode(endVol[0], 1, new TGeoCombiTrans(0, 0, zpos, new TGeoRotation("", 90, 180, -90)));
2807
2808 zpos += (2 * frameUnit->GetDZ());
2809 spaceFrameVol->AddNode(next2EndVol[0], 1, new TGeoTranslation(0, 0, zpos));
2810
2811 for (Int_t i = 2; i < nUnits - 2; i++) {
2812 zpos += (2 * frameUnit->GetDZ());
2813 Int_t j = i / 2;
2814 Int_t k = i - j * 2; // alternatively 0 or 1
2815 spaceFrameVol->AddNode(unitVol[k], j, new TGeoTranslation(0, 0, zpos));
2816 }
2817
2818 zpos += (2 * frameUnit->GetDZ());
2819 spaceFrameVol->AddNode(next2EndVol[1], 1, new TGeoTranslation(0, 0, zpos));
2820
2821 zpos += (2 * frameUnit->GetDZ());
2822 spaceFrameVol->AddNode(endVol[1], 1, new TGeoTranslation(0, 0, zpos));
2823
2824 // Done, clean up and return the space frame structure
2825 delete[] xtru;
2826 delete[] ytru;
2827
2828 return spaceFrameVol;
2829}
2830
2831void V3Layer::createOBSpaceFrameObjects(const TGeoManager* mgr)
2832{
2833 //
2834 // Create the space frame building blocks for the Outer Barrel
2835 // This method is practically identical to previous versions of
2836 // CreateSpaceFrameOuterB1
2837 // NB: it is pretty cumbersome, because we don't want to use assemblies
2838 // so we are forced to have well-crafted containers to avoid fake overlaps
2839 //
2840 // Input:
2841 // mgr : the GeoManager (used only to get the proper material)
2842 //
2843 // Output:
2844 //
2845 // Return:
2846 // a TGeoVolume with the Space Frame of a stave
2847 //
2848 // Created: 03 Feb 2015 Mario Sitta
2849 // Updated: 03 Jun 2015 Mario Sitta End units w/o U-legs
2850 // Updated: 20 Jul 2017 Mario Sitta O2 version
2851 // Updated: 09 Sep 2019 Mario Sitta Connectors added
2852 // Updated: 27 Sep 2019 Mario Sitta New TopV for End Units
2853 //
2854
2855 // Materials defined in AliITSUv2
2856 TGeoMedium* medCarbon = mgr->GetMedium(Form("%s_M55J6K$", GetDetName()));
2857 TGeoMedium* medF6151B05M = mgr->GetMedium(Form("%s_F6151B05M$", GetDetName()));
2858 TGeoMedium* medAir = mgr->GetMedium(Form("%s_AIR$", GetDetName()));
2859
2860 // Local parameters
2861 Double_t halfFrameWidth = sOBSpaceFrameWidth / 2;
2862 Double_t triangleHeight = sOBSpaceFrameHeight;
2863 Double_t sframeHeight = triangleHeight + sOBSFrameBaseRibDiam + sOBSFrameULegHeight2 * 2;
2864 Double_t staveLa = sOBSpaceFrameTopVL;
2865 Double_t staveHa = sOBSpaceFrameTopVH;
2866 Double_t staveLb = sOBSpaceFrameSideVL;
2867 Double_t staveHb = sOBSpaceFrameSideVH;
2868 Double_t alphaDeg = sOBSpaceFrameVAlpha;
2869 Double_t alphaRad = alphaDeg * TMath::DegToRad() / 2;
2870 Double_t beta = sOBSpaceFrameVBeta * TMath::DegToRad() / 2;
2871 Double_t sideRibRadius = sOBSFrameSideRibDiam / 2;
2872 Double_t sidePhiDeg = sOBSFrameSideRibPhi;
2873 Double_t sidePhiRad = sidePhiDeg * TMath::DegToRad();
2874 Double_t baseRibRadius = sOBSFrameBaseRibDiam / 2;
2875 Double_t basePhiDeg = sOBSFrameBaseRibPhi;
2876 Double_t basePhiRad = basePhiDeg * TMath::DegToRad();
2877 Double_t ulegHalfLen = sOBSFrameULegLen / 2;
2878 Double_t ulegHalfWidth = sOBSFrameULegWidth / 2;
2879 Double_t ulegHigh1 = sOBSFrameULegHeight1;
2880 Double_t ulegHigh2 = sOBSFrameULegHeight2;
2881 Double_t ulegThick = sOBSFrameULegThick;
2882 Double_t topVFactorEU = 0.60; // Fraction of TopV total length for End Units
2883
2884 Double_t xlen, zlen;
2885 Double_t xpos, ypos, zpos;
2886 Double_t unitlen;
2887 Double_t xtru[22], ytru[22];
2888
2889 unitlen = sOBSpaceFrameUnitLen;
2890
2891 xlen = halfFrameWidth + sideRibRadius;
2892
2893 // We need a properly shaped Xtru to accomodate the ribs avoiding
2894 // overlaps with the HalfStave cooling tubes
2895 xtru[0] = sOBSFrameULegXPos - ulegHalfLen;
2896 ytru[0] = -(triangleHeight / 2 + baseRibRadius);
2897 xtru[1] = xtru[0];
2898 ytru[1] = ytru[0] - ulegHigh1;
2899 xtru[2] = xtru[1] + ulegThick;
2900 ytru[2] = ytru[1];
2901 xtru[3] = xtru[2];
2902 ytru[3] = ytru[0] - ulegThick;
2903 xtru[7] = sOBSFrameULegXPos + ulegHalfLen;
2904 ytru[7] = ytru[0];
2905 xtru[6] = xtru[7];
2906 ytru[6] = ytru[1];
2907 xtru[5] = xtru[6] - ulegThick;
2908 ytru[5] = ytru[6];
2909 xtru[4] = xtru[5];
2910 ytru[4] = ytru[3];
2911 xtru[8] = xlen;
2912 ytru[8] = ytru[7];
2913 xtru[9] = xtru[8];
2914 ytru[9] = 0.9 * ytru[8];
2915 xtru[10] = 0.3 * xtru[8];
2916 ytru[10] = triangleHeight / 2;
2917 for (Int_t i = 0; i < 11; i++) { // Reflect on the X negative side
2918 xtru[i + 11] = -xtru[10 - i];
2919 ytru[i + 11] = ytru[10 - i];
2920 }
2921 ytru[15] = ytru[0] - ulegHigh2; // U-legs on negative X are longer
2922 ytru[16] = ytru[15];
2923 ytru[19] = ytru[15];
2924 ytru[20] = ytru[15];
2925
2926 // The space frame single units
2927 // We need two units because the base ribs are alternately oriented
2928 // The next-to-end units are slightly different
2929 TGeoXtru* frameUnit = new TGeoXtru(2);
2930 frameUnit->DefinePolygon(22, xtru, ytru);
2931 frameUnit->DefineSection(0, -unitlen / 2);
2932 frameUnit->DefineSection(1, unitlen / 2);
2933
2934 TGeoXtru* next2EndUnit = new TGeoXtru(2);
2935 next2EndUnit->DefinePolygon(22, xtru, ytru);
2936 next2EndUnit->DefineSection(0, -unitlen / 2);
2937 next2EndUnit->DefineSection(1, unitlen / 2);
2938
2939 // The end units have no U-legs, but they contain the end-stave connectors
2940 // so we build a CompositeShape using two Xtru's
2941 xtru[0] = xlen;
2942 ytru[0] = -(triangleHeight / 2 + baseRibRadius);
2943 xtru[1] = xtru[0];
2944 ytru[1] = 0.9 * ytru[0];
2945 xtru[2] = 0.3 * xtru[0];
2946 ytru[2] = triangleHeight / 2;
2947 for (Int_t i = 0; i < 3; i++) { // Reflect on the X negative side
2948 xtru[i + 3] = -xtru[2 - i];
2949 ytru[i + 3] = ytru[2 - i];
2950 }
2951
2952 TGeoXtru* endUnitBody = new TGeoXtru(2);
2953 endUnitBody->SetName("endunitbody");
2954 endUnitBody->DefinePolygon(6, xtru, ytru);
2955 endUnitBody->DefineSection(0, -unitlen / 2);
2956 endUnitBody->DefineSection(1, 0.8 * unitlen / 2);
2957
2958 xtru[2] = 0.25 * (3 * xtru[1] + xtru[2]);
2959 ytru[2] = 0.25 * (3 * ytru[1] + ytru[2]);
2960 for (Int_t i = 0; i < 3; i++) { // Reflect on the X negative side
2961 xtru[i + 3] = -xtru[2 - i];
2962 ytru[i + 3] = ytru[2 - i];
2963 }
2964
2965 TGeoXtru* endUnitBodyLow = new TGeoXtru(2);
2966 endUnitBodyLow->SetName("endunitbodylow");
2967 endUnitBodyLow->DefinePolygon(6, xtru, ytru);
2968 endUnitBodyLow->DefineSection(0, 0.8 * unitlen / 2);
2969 endUnitBodyLow->DefineSection(1, unitlen / 2);
2970
2971 // (See createOBSpaceFrameConnector lower down for details)
2972 xtru[0] = sOBSFrameConnWidth / 2.;
2973 ytru[0] = 0.;
2974 xtru[1] = xtru[0];
2975 ytru[1] = sOBSFrameConnInsHei;
2976 xtru[2] = xtru[1] - sOBSFrameConnTotHei + sOBSFrameConnInsHei;
2977 ytru[2] = sOBSFrameConnTotHei;
2978 for (Int_t i = 0; i < 3; i++) { // Reflect on the X negative side
2979 xtru[i + 3] = -xtru[2 - i];
2980 ytru[i + 3] = ytru[2 - i];
2981 }
2982
2983 TGeoXtru* endUnitConn = new TGeoXtru(2);
2984 endUnitConn->SetName("endunitconn");
2985 endUnitConn->DefinePolygon(6, xtru, ytru);
2986 endUnitConn->DefineSection(0, 0.);
2987 endUnitConn->DefineSection(1, sOBSFrameConnTopLen);
2988
2989 // We create a fake side V to have its dimensions, needed for
2990 // the creation of the end unit container
2991 TGeoXtru* vside =
2992 createStaveSide("fakeCornerSide", unitlen / 2., alphaRad, beta, staveLb, staveHb, kFALSE);
2993
2994 ypos = -triangleHeight / 2 + vside->GetY(3);
2995 TGeoTranslation* endUnitConnTrans = new TGeoTranslation("endunitconntrans", 0, ypos, unitlen / 2);
2996 endUnitConnTrans->RegisterYourself();
2997
2998 TGeoCompositeShape* endUnit = new TGeoCompositeShape("endunitbody+endunitbodylow+endunitconn:endunitconntrans");
2999 endUnit->SetName("endunitcontainer"); // Will be used when create spaceframe
3000
3001 // The air containers
3002 TGeoVolume* unitVol[2];
3003 unitVol[0] = new TGeoVolume("SpaceFrameUnit0", frameUnit, medAir);
3004 unitVol[1] = new TGeoVolume("SpaceFrameUnit1", frameUnit, medAir);
3005 unitVol[0]->SetVisibility(kFALSE);
3006 unitVol[1]->SetVisibility(kFALSE);
3007
3008 TGeoVolume* next2EndVol[2];
3009 next2EndVol[0] = new TGeoVolume("SpaceFrameNext2EndUnit0", next2EndUnit, medAir);
3010 next2EndVol[1] = new TGeoVolume("SpaceFrameNext2EndUnit1", next2EndUnit, medAir);
3011 next2EndVol[0]->SetVisibility(kFALSE);
3012 next2EndVol[1]->SetVisibility(kFALSE);
3013
3014 TGeoVolume* endVol[2];
3015 endVol[0] = new TGeoVolume("SpaceFrameEndUnit0", endUnit, medAir);
3016 endVol[1] = new TGeoVolume("SpaceFrameEndUnit1", endUnit, medAir);
3017 endVol[0]->SetVisibility(kFALSE);
3018 endVol[1]->SetVisibility(kFALSE);
3019
3020 // The actual volumes
3021
3022 //--- The top V of the Carbon Fiber Stave (segment)
3023 TGeoXtru* cfStavTop =
3024 createStaveSide("CFstavTopCornerVolshape", unitlen / 2., alphaRad, beta, staveLa, staveHa, kTRUE);
3025
3026 TGeoVolume* cfStavTopVol = new TGeoVolume("CFstavTopCornerVol", cfStavTop, medCarbon);
3027 cfStavTopVol->SetLineColor(35);
3028
3029 unitVol[0]->AddNode(cfStavTopVol, 1, new TGeoTranslation(0, triangleHeight / 2, 0));
3030
3031 unitVol[1]->AddNode(cfStavTopVol, 1, new TGeoTranslation(0, triangleHeight / 2, 0));
3032
3033 next2EndVol[0]->AddNode(cfStavTopVol, 1, new TGeoTranslation(0, triangleHeight / 2, 0));
3034
3035 next2EndVol[1]->AddNode(cfStavTopVol, 1, new TGeoTranslation(0, triangleHeight / 2, 0));
3036
3037 zlen = topVFactorEU * unitlen;
3038 TGeoXtru* cfStavTopEU =
3039 createStaveSide("CFstavTopCornerEUVolshape", zlen / 2., alphaRad, beta, staveLa, staveHa, kTRUE);
3040
3041 TGeoVolume* cfStavTopVolEU = new TGeoVolume("CFstavTopCornerEUVol", cfStavTopEU, medCarbon);
3042 cfStavTopVol->SetLineColor(35);
3043
3044 zpos = endUnitBody->GetDZ() - zlen / 2.;
3045
3046 endVol[0]->AddNode(cfStavTopVolEU, 1, new TGeoTranslation(0, triangleHeight / 2, -zpos));
3047
3048 endVol[1]->AddNode(cfStavTopVolEU, 1, new TGeoTranslation(0, triangleHeight / 2, -zpos));
3049
3050 //--- The two side V's
3051 TGeoXtru* cfStavSide =
3052 createStaveSide("CFstavSideCornerVolshape", unitlen / 2., alphaRad, beta, staveLb, staveHb, kFALSE);
3053
3054 TGeoVolume* cfStavSideVol = new TGeoVolume("CFstavSideCornerVol", cfStavSide, medCarbon);
3055 cfStavSideVol->SetLineColor(35);
3056
3057 unitVol[0]->AddNode(cfStavSideVol, 1, new TGeoTranslation(halfFrameWidth, -triangleHeight / 2, 0));
3058 unitVol[0]->AddNode(cfStavSideVol, 2,
3059 new TGeoCombiTrans(-halfFrameWidth, -triangleHeight / 2, 0, new TGeoRotation("", 90, 180, -90)));
3060
3061 unitVol[1]->AddNode(cfStavSideVol, 1, new TGeoTranslation(halfFrameWidth, -triangleHeight / 2, 0));
3062 unitVol[1]->AddNode(cfStavSideVol, 2,
3063 new TGeoCombiTrans(-halfFrameWidth, -triangleHeight / 2, 0, new TGeoRotation("", 90, 180, -90)));
3064
3065 next2EndVol[0]->AddNode(cfStavSideVol, 1, new TGeoTranslation(halfFrameWidth, -triangleHeight / 2, 0));
3066 next2EndVol[0]->AddNode(
3067 cfStavSideVol, 2, new TGeoCombiTrans(-halfFrameWidth, -triangleHeight / 2, 0, new TGeoRotation("", 90, 180, -90)));
3068
3069 next2EndVol[1]->AddNode(cfStavSideVol, 1, new TGeoTranslation(halfFrameWidth, -triangleHeight / 2, 0));
3070 next2EndVol[1]->AddNode(
3071 cfStavSideVol, 2, new TGeoCombiTrans(-halfFrameWidth, -triangleHeight / 2, 0, new TGeoRotation("", 90, 180, -90)));
3072
3073 endVol[0]->AddNode(cfStavSideVol, 1, new TGeoTranslation(halfFrameWidth, -triangleHeight / 2, 0));
3074 endVol[0]->AddNode(cfStavSideVol, 2,
3075 new TGeoCombiTrans(-halfFrameWidth, -triangleHeight / 2, 0, new TGeoRotation("", 90, 180, -90)));
3076
3077 endVol[1]->AddNode(cfStavSideVol, 1, new TGeoTranslation(halfFrameWidth, -triangleHeight / 2, 0));
3078 endVol[1]->AddNode(cfStavSideVol, 2,
3079 new TGeoCombiTrans(-halfFrameWidth, -triangleHeight / 2, 0, new TGeoRotation("", 90, 180, -90)));
3080
3081 //--- The beams
3082 // Ribs on the sides
3083 Double_t ribZProj = triangleHeight / TMath::Tan(sidePhiRad);
3084 Double_t sideRibLen =
3085 TMath::Sqrt(ribZProj * ribZProj + triangleHeight * triangleHeight + halfFrameWidth * halfFrameWidth);
3086
3087 TGeoTubeSeg* sideRib = new TGeoTubeSeg(0, sideRibRadius, sideRibLen / 2, 0, 180);
3088 TGeoVolume* sideRibVol = new TGeoVolume("CFstavSideBeamVol", sideRib, medCarbon);
3089 sideRibVol->SetLineColor(35);
3090
3091 TGeoCombiTrans* sideTransf[4];
3092 xpos = halfFrameWidth / 2 + 0.8 * staveHa * TMath::Cos(alphaRad / 2);
3093 ypos = -sideRibRadius / 2;
3094 zpos = unitlen / 4;
3095
3096 sideTransf[0] = new TGeoCombiTrans(xpos, ypos, -zpos, new TGeoRotation("", 90 - alphaDeg, -sidePhiDeg, -90));
3097 sideTransf[1] = new TGeoCombiTrans(xpos, ypos, zpos, new TGeoRotation("", 90 - alphaDeg, sidePhiDeg, -90));
3098 sideTransf[2] = new TGeoCombiTrans(-xpos, ypos, -zpos, new TGeoRotation("", 90 + alphaDeg, sidePhiDeg, -90));
3099 sideTransf[3] = new TGeoCombiTrans(-xpos, ypos, zpos, new TGeoRotation("", 90 + alphaDeg, -sidePhiDeg, -90));
3100
3101 unitVol[0]->AddNode(sideRibVol, 1, sideTransf[0]);
3102 unitVol[0]->AddNode(sideRibVol, 2, sideTransf[1]);
3103 unitVol[0]->AddNode(sideRibVol, 3, sideTransf[2]);
3104 unitVol[0]->AddNode(sideRibVol, 4, sideTransf[3]);
3105
3106 unitVol[1]->AddNode(sideRibVol, 1, sideTransf[0]);
3107 unitVol[1]->AddNode(sideRibVol, 2, sideTransf[1]);
3108 unitVol[1]->AddNode(sideRibVol, 3, sideTransf[2]);
3109 unitVol[1]->AddNode(sideRibVol, 4, sideTransf[3]);
3110
3111 next2EndVol[0]->AddNode(sideRibVol, 1, sideTransf[0]);
3112 next2EndVol[0]->AddNode(sideRibVol, 2, sideTransf[1]);
3113 next2EndVol[0]->AddNode(sideRibVol, 3, sideTransf[2]);
3114 next2EndVol[0]->AddNode(sideRibVol, 4, sideTransf[3]);
3115
3116 next2EndVol[1]->AddNode(sideRibVol, 1, sideTransf[0]);
3117 next2EndVol[1]->AddNode(sideRibVol, 2, sideTransf[1]);
3118 next2EndVol[1]->AddNode(sideRibVol, 3, sideTransf[2]);
3119 next2EndVol[1]->AddNode(sideRibVol, 4, sideTransf[3]);
3120
3121 endVol[0]->AddNode(sideRibVol, 1, sideTransf[0]);
3122 endVol[0]->AddNode(sideRibVol, 2, sideTransf[1]);
3123 endVol[0]->AddNode(sideRibVol, 3, sideTransf[2]);
3124 endVol[0]->AddNode(sideRibVol, 4, sideTransf[3]);
3125
3126 endVol[1]->AddNode(sideRibVol, 1, sideTransf[0]);
3127 endVol[1]->AddNode(sideRibVol, 2, sideTransf[1]);
3128 endVol[1]->AddNode(sideRibVol, 3, sideTransf[2]);
3129 endVol[1]->AddNode(sideRibVol, 4, sideTransf[3]);
3130
3131 // Ribs on the bottom
3132 // Rib1 are the inclined ones, Rib2 the straight ones
3133 Double_t baseRibLen = 0.98 * 2 * halfFrameWidth / TMath::Sin(basePhiRad);
3134
3135 TGeoTubeSeg* baseRib1 = new TGeoTubeSeg(0, baseRibRadius, baseRibLen / 2, 0, 180);
3136 TGeoVolume* baseRib1Vol = new TGeoVolume("CFstavBaseBeam1Vol", baseRib1, medCarbon);
3137 baseRib1Vol->SetLineColor(35);
3138
3139 TGeoTubeSeg* baseRib2 = new TGeoTubeSeg(0, baseRibRadius, halfFrameWidth, 0, 90);
3140 TGeoVolume* baseRib2Vol = new TGeoVolume("CFstavBaseBeam2Vol", baseRib2, medCarbon);
3141 baseRib2Vol->SetLineColor(35);
3142
3143 TGeoTubeSeg* baseEndRib = new TGeoTubeSeg(0, baseRibRadius, halfFrameWidth, 0, 180);
3144 TGeoVolume* baseEndRibVol = new TGeoVolume("CFstavBaseEndBeamVol", baseEndRib, medCarbon);
3145 baseEndRibVol->SetLineColor(35);
3146
3147 TGeoCombiTrans* baseTransf[6];
3148 ypos = triangleHeight / 2;
3149 zpos = unitlen / 2;
3150
3151 baseTransf[0] = new TGeoCombiTrans("", 0, -ypos, -zpos, new TGeoRotation("", 90, 90, 90));
3152 baseTransf[1] = new TGeoCombiTrans("", 0, -ypos, zpos, new TGeoRotation("", -90, 90, -90));
3153 baseTransf[2] = new TGeoCombiTrans(0, -ypos, 0, new TGeoRotation("", -90, basePhiDeg, -90));
3154 baseTransf[3] = new TGeoCombiTrans(0, -ypos, 0, new TGeoRotation("", -90, -basePhiDeg, -90));
3155 zpos -= baseEndRib->GetRmax();
3156 baseTransf[4] = new TGeoCombiTrans("", 0, -ypos, -zpos, new TGeoRotation("", 90, 90, 90));
3157 baseTransf[5] = new TGeoCombiTrans("", 0, -ypos, zpos, new TGeoRotation("", 90, 90, 90));
3158
3159 unitVol[0]->AddNode(baseRib2Vol, 1, baseTransf[0]);
3160 unitVol[0]->AddNode(baseRib2Vol, 2, baseTransf[1]);
3161 unitVol[0]->AddNode(baseRib1Vol, 1, baseTransf[2]);
3162
3163 unitVol[1]->AddNode(baseRib2Vol, 1, baseTransf[0]);
3164 unitVol[1]->AddNode(baseRib2Vol, 2, baseTransf[1]);
3165 unitVol[1]->AddNode(baseRib1Vol, 1, baseTransf[3]);
3166
3167 next2EndVol[0]->AddNode(baseRib2Vol, 1, baseTransf[0]);
3168 next2EndVol[0]->AddNode(baseRib2Vol, 2, baseTransf[1]);
3169 next2EndVol[0]->AddNode(baseRib1Vol, 1, baseTransf[3]);
3170
3171 next2EndVol[1]->AddNode(baseRib2Vol, 1, baseTransf[0]);
3172 next2EndVol[1]->AddNode(baseRib2Vol, 2, baseTransf[1]);
3173 next2EndVol[1]->AddNode(baseRib1Vol, 1, baseTransf[3]);
3174
3175 endVol[0]->AddNode(baseEndRibVol, 1, baseTransf[4]);
3176 endVol[0]->AddNode(baseRib2Vol, 1, baseTransf[1]);
3177 endVol[0]->AddNode(baseRib1Vol, 1, baseTransf[2]);
3178
3179 endVol[1]->AddNode(baseEndRibVol, 1, baseTransf[5]);
3180 endVol[1]->AddNode(baseRib2Vol, 1, baseTransf[0]);
3181 endVol[1]->AddNode(baseRib1Vol, 1, baseTransf[2]);
3182
3183 // The Space Frame connectors
3184 ypos = -triangleHeight / 2 + cfStavSide->GetY(3);
3185 zpos = unitlen / 2;
3186 createOBSpaceFrameConnector(endVol[0], ypos, zpos, kFALSE); // Side C
3187 createOBSpaceFrameConnector(endVol[1], ypos, zpos, kTRUE); // Side A
3188
3189 // U-Legs
3190 // The shorter
3191 xtru[0] = ulegHalfLen;
3192 ytru[0] = 0;
3193 xtru[1] = xtru[0];
3194 ytru[1] = -ulegHigh1;
3195 xtru[2] = xtru[1] - ulegThick;
3196 ytru[2] = ytru[1];
3197 xtru[3] = xtru[2];
3198 ytru[3] = ytru[0] - ulegThick;
3199 for (Int_t i = 0; i < 4; i++) { // Reflect on the X negative side
3200 xtru[i + 4] = -xtru[3 - i];
3201 ytru[i + 4] = ytru[3 - i];
3202 }
3203
3204 TGeoXtru* uleg1full = new TGeoXtru(2); // This will go in the next end units
3205 uleg1full->DefinePolygon(8, xtru, ytru);
3206 uleg1full->DefineSection(0, -ulegHalfWidth);
3207 uleg1full->DefineSection(1, ulegHalfWidth);
3208
3209 TGeoXtru* uleg1half = new TGeoXtru(2); // This will go in the middle unitys
3210 uleg1half->DefinePolygon(8, xtru, ytru);
3211 uleg1half->DefineSection(0, -ulegHalfWidth / 2);
3212 uleg1half->DefineSection(1, ulegHalfWidth / 2);
3213
3214 TGeoVolume* uleg1fullVol = new TGeoVolume("CFstavULeg1FullVol", uleg1full, medF6151B05M);
3215 uleg1fullVol->SetLineColor(35);
3216
3217 TGeoVolume* uleg1halfVol = new TGeoVolume("CFstavULeg1HalfVol", uleg1half, medF6151B05M);
3218 uleg1halfVol->SetLineColor(35);
3219
3220 // The longer
3221 ytru[1] = -ulegHigh2;
3222 ytru[2] = -ulegHigh2;
3223 ytru[5] = -ulegHigh2;
3224 ytru[6] = -ulegHigh2;
3225
3226 TGeoXtru* uleg2full = new TGeoXtru(2); // This will go in the next end units
3227 uleg2full->DefinePolygon(8, xtru, ytru);
3228 uleg2full->DefineSection(0, -ulegHalfWidth);
3229 uleg2full->DefineSection(1, ulegHalfWidth);
3230
3231 TGeoXtru* uleg2half = new TGeoXtru(2); // This will go in the middle unitys
3232 uleg2half->DefinePolygon(8, xtru, ytru);
3233 uleg2half->DefineSection(0, -ulegHalfWidth / 2);
3234 uleg2half->DefineSection(1, ulegHalfWidth / 2);
3235
3236 TGeoVolume* uleg2fullVol = new TGeoVolume("CFstavULeg2FullVol", uleg2full, medF6151B05M);
3237 uleg2fullVol->SetLineColor(35);
3238
3239 TGeoVolume* uleg2halfVol = new TGeoVolume("CFstavULeg2HalfVol", uleg2half, medF6151B05M);
3240 uleg2halfVol->SetLineColor(35);
3241
3242 xpos = sOBSFrameULegXPos;
3243 ypos = triangleHeight / 2 + baseRibRadius;
3244 zpos = unitlen / 2 - uleg1half->GetZ(1);
3245
3246 unitVol[0]->AddNode(uleg1halfVol, 1, // Shorter on +X
3247 new TGeoTranslation(xpos, -ypos, -zpos));
3248 unitVol[0]->AddNode(uleg1halfVol, 2, new TGeoTranslation(xpos, -ypos, zpos));
3249
3250 unitVol[1]->AddNode(uleg1halfVol, 1, new TGeoTranslation(xpos, -ypos, -zpos));
3251 unitVol[1]->AddNode(uleg1halfVol, 2, new TGeoTranslation(xpos, -ypos, zpos));
3252
3253 unitVol[0]->AddNode(uleg2halfVol, 1, // Longer on -X
3254 new TGeoTranslation(-xpos, -ypos, -zpos));
3255 unitVol[0]->AddNode(uleg2halfVol, 2, new TGeoTranslation(-xpos, -ypos, zpos));
3256
3257 unitVol[1]->AddNode(uleg2halfVol, 1, new TGeoTranslation(-xpos, -ypos, -zpos));
3258 unitVol[1]->AddNode(uleg2halfVol, 2, new TGeoTranslation(-xpos, -ypos, zpos));
3259
3260 next2EndVol[0]->AddNode(uleg1halfVol, 1, new TGeoTranslation(xpos, -ypos, zpos));
3261 next2EndVol[0]->AddNode(uleg2halfVol, 1, new TGeoTranslation(-xpos, -ypos, zpos));
3262
3263 next2EndVol[1]->AddNode(uleg1halfVol, 1, new TGeoTranslation(xpos, -ypos, -zpos));
3264 next2EndVol[1]->AddNode(uleg2halfVol, 1, new TGeoTranslation(-xpos, -ypos, -zpos));
3265
3266 zpos = unitlen / 2 - uleg1full->GetZ(1);
3267 next2EndVol[0]->AddNode(uleg1fullVol, 1, new TGeoTranslation(xpos, -ypos, -zpos));
3268 next2EndVol[0]->AddNode(uleg2fullVol, 1, new TGeoTranslation(-xpos, -ypos, -zpos));
3269
3270 next2EndVol[1]->AddNode(uleg1fullVol, 1, new TGeoTranslation(xpos, -ypos, zpos));
3271 next2EndVol[1]->AddNode(uleg2fullVol, 1, new TGeoTranslation(-xpos, -ypos, zpos));
3272
3273 // Done
3274 return;
3275}
3276
3277void V3Layer::createOBSpaceFrameConnector(TGeoVolume* mother, const Double_t ymot, const Double_t zmot, const Bool_t sideA, const TGeoManager* mgr)
3278{
3279 //
3280 // Creates the OB Space Frame Connectors
3281 // (ALIITSUP0070+ALIITSUP0069)
3282 //
3283 // Input:
3284 // mother : the SF unit volume to contain the connector
3285 // ymot : the Y position of the connector in the mother volume
3286 // zmot : the Z position of the connector in the mother volume
3287 // sideA : true for Side A, false for Side C
3288 // mgr : the GeoManager (used only to get the proper material)
3289 //
3290 // Output:
3291 //
3292 // Return:
3293 //
3294 // Created: 09 Sep 2019 M. Sitta
3295
3296 // Materials defined in AliITSUv2
3297 TGeoMedium* medPEEK = mgr->GetMedium(Form("%s_PEEKCF30$", GetDetName()));
3298
3299 // Local parameters
3300 TString connName, compoShape;
3301
3302 Double_t xlen, ylen, zlen;
3303 Double_t xpos, ypos, zpos;
3304 Double_t xtru[6], ytru[6];
3305
3306 // The external (higher) part: a Xtru
3307 ylen = sOBSFrameConnTotHei - sOBSFrameConnInsHei;
3308
3309 xtru[0] = sOBSFrameConnWidth / 2.;
3310 ytru[0] = 0.;
3311 xtru[1] = xtru[0];
3312 ytru[1] = sOBSFrameConnInsHei;
3313 xtru[2] = xtru[1] - ylen; // Because side is at 45' so dx = dy
3314 ytru[2] = sOBSFrameConnTotHei;
3315 for (Int_t i = 0; i < 3; i++) { // Reflect on the X negative side
3316 xtru[i + 3] = -xtru[2 - i];
3317 ytru[i + 3] = ytru[2 - i];
3318 }
3319
3320 TGeoXtru* topConn = new TGeoXtru(2);
3321 topConn->SetName("connectorTop");
3322 topConn->DefinePolygon(6, xtru, ytru);
3323 topConn->DefineSection(0, 0.);
3324 topConn->DefineSection(1, sOBSFrameConnTopLen);
3325
3326 // The insert: a Xtru
3327 zlen = sOBSFrameConnTotLen - sOBSFrameConnTopLen;
3328
3329 xtru[0] = sOBSFrameConnInsBase / 2.;
3330 ytru[0] = 0.;
3331 xtru[1] = sOBSFrameConnInsWide / 2.;
3332 ytru[1] = sOBSFrameConnInsHei;
3333 xtru[2] = -xtru[1];
3334 ytru[2] = ytru[1];
3335 xtru[3] = -xtru[0];
3336 ytru[3] = ytru[0];
3337
3338 TGeoXtru* insConn = new TGeoXtru(2);
3339 insConn->SetName("connectorIns");
3340 insConn->DefinePolygon(4, xtru, ytru);
3341 insConn->DefineSection(0, -zlen);
3342 insConn->DefineSection(1, 0.);
3343
3344 // The holes in the external (higher) part: Tube's and a BBox
3345 TGeoTube* topHoleR = new TGeoTube("topholer", 0., sOBSFrameConnTopHoleD / 2., 1.1 * sOBSFrameConnTotHei);
3346
3347 xpos = sOBSFrConnTopHoleXDist / 2.;
3348 ypos = sOBSFrameConnTotHei / 2.;
3349 zpos = sOBSFrameConnTopLen - sOBSFrameConnHoleZPos;
3350 TGeoCombiTrans* topHoleR1Trans = new TGeoCombiTrans("topholer1tr", xpos, ypos, zpos, new TGeoRotation("", 0, 90, 0));
3351 topHoleR1Trans->RegisterYourself();
3352
3353 TGeoCombiTrans* topHoleR2Trans = new TGeoCombiTrans("topholer2tr", -xpos, ypos, zpos, new TGeoRotation("", 0, 90, 0));
3354 topHoleR2Trans->RegisterYourself();
3355
3356 xpos = sOBSFrConnCHoleXDist / 2.;
3357 zpos = sOBSFrameConnTopLen - sOBSFrameConnCHoleZPos;
3358 TGeoCombiTrans* topCHoleR1Trans = new TGeoCombiTrans("topcholer1tr", xpos, ypos, zpos, new TGeoRotation("", 0, 90, 0));
3359 topCHoleR1Trans->RegisterYourself();
3360
3361 TGeoCombiTrans* topCHoleR2Trans = new TGeoCombiTrans("topcholer2tr", -xpos, ypos, zpos, new TGeoRotation("", 0, 90, 0));
3362 topCHoleR2Trans->RegisterYourself();
3363
3364 TGeoBBox* topAHole = new TGeoBBox("topahole", sOBSFrameConnAHoleWid / 2., sOBSFrameConnTotHei, sOBSFrameConnAHoleLen / 2.);
3365
3366 zpos = sOBSFrameConnTopLen - sOBSFrameConnHoleZPos;
3367 TGeoTranslation* topAHoleTrans = new TGeoTranslation("topaholetr", 0, ypos, zpos);
3368 topAHoleTrans->RegisterYourself();
3369
3370 TGeoTube* topCHole = new TGeoTube("topchole", 0., sOBSFrConnCTopHoleD / 2., sOBSFrameConnTotHei);
3371
3372 TGeoCombiTrans* topCHoleTrans = new TGeoCombiTrans("topcholetr", 0, ypos, zpos, new TGeoRotation("", 0, 90, 0));
3373 topCHoleTrans->RegisterYourself();
3374
3375 TGeoTube* topASide = new TGeoTube("topaside", 0., sOBSFrConnASideHoleD / 2., 1.1 * sOBSFrConnASideHoleL);
3376
3377 zpos = sOBSFrameConnTopLen + topASide->GetDz() - sOBSFrConnASideHoleL;
3378 TGeoTranslation* topASideTrans = new TGeoTranslation("topasidetr", 0, sOBSFrConnASideHoleY, zpos);
3379 topASideTrans->RegisterYourself();
3380
3381 // The holes in the insert: a Tube
3382 TGeoTube* insHole = new TGeoTube("inshole", 0., sOBSFrameConnInsHoleD / 2., sOBSFrameConnInsHei);
3383
3384 xpos = sOBSFrameConnInsHoleX / 2.;
3385 ypos = sOBSFrameConnInsHei / 2.;
3386 zpos = sOBSFrameConnTopLen - sOBSFrameConnHoleZPos - sOBSFrameConnHoleZDist;
3387 TGeoCombiTrans* insHole1Trans = new TGeoCombiTrans("inshole1tr", xpos, ypos, zpos, new TGeoRotation("", 0, 90, 0));
3388 insHole1Trans->RegisterYourself();
3389
3390 TGeoCombiTrans* insHole2Trans = new TGeoCombiTrans("inshole2tr", -xpos, ypos, zpos, new TGeoRotation("", 0, 90, 0));
3391 insHole2Trans->RegisterYourself();
3392
3393 // The connector: a CompositeShape
3394 if (sideA) {
3395 connName = "OBSFConnectorA";
3396 compoShape = "(connectorTop-topholer:topholer2tr-topholer:topholer1tr-topahole:topaholetr-topaside:topasidetr)+(connectorIns-inshole:inshole1tr-inshole:inshole2tr)";
3397 } else {
3398 connName = "OBSFConnectorC";
3399 compoShape = "(connectorTop-topholer:topholer2tr-topholer:topholer1tr-topholer:topcholer1tr-topholer:topcholer2tr-topchole:topcholetr)+(connectorIns-inshole:inshole1tr-inshole:inshole2tr)";
3400 }
3401
3402 TGeoCompositeShape* obsfConnSh = new TGeoCompositeShape(compoShape.Data());
3403
3404 TGeoVolume* obsfConnVol = new TGeoVolume(connName, obsfConnSh, medPEEK);
3405
3406 // Finally put the connector into its mother volume
3407 mother->AddNode(obsfConnVol, 1, new TGeoTranslation(0, ymot, zmot));
3408}
3409
3410TGeoVolume* V3Layer::createModuleOuterB(const TGeoManager* mgr)
3411{
3412 //
3413 // Creates the OB Module: HIC + FPC
3414 //
3415 // Input:
3416 // mgr : the GeoManager (used only to get the proper material)
3417 //
3418 // Output:
3419 //
3420 // Return:
3421 // the module as a TGeoVolume
3422 //
3423 // Created: 18 Dec 2013 M. Sitta, A. Barbano
3424 // Updated: 26 Feb 2014 M. Sitta
3425 // Updated: 12 Nov 2014 M. Sitta Model2 is w/o Carbon Plate and Glue
3426 // and Cu instead of Al
3427 // Updated: 20 Jul 2017 M. Sitta O2 version
3428 // Updated: 30 Jul 2018 M. Sitta Updated geometry
3429 //
3430
3431 const Int_t nameLen = 30;
3432 char chipName[nameLen], sensName[nameLen], volName[nameLen];
3433
3434 Double_t xGap = sOBChipXGap;
3435 Double_t zGap = sOBChipZGap;
3436
3437 Double_t xchip, ychip, zchip;
3438 Double_t xlen, ylen, zlen;
3439 Double_t xpos, ypos, zpos;
3440
3441 Bool_t dummyChip;
3442
3443 // First create all needed shapes
3444
3445 // For material budget studies
3446 if (mBuildLevel < 7) {
3447 dummyChip = kFALSE; // will be made of Si
3448 } else {
3449 dummyChip = kTRUE; // will be made of Air
3450 }
3451
3452 // The chip (the same as for IB)
3453 snprintf(chipName, nameLen, "%s%d", GeometryTGeo::getITSChipPattern(), mLayerNumber);
3454 snprintf(sensName, nameLen, "%s%d", GeometryTGeo::getITSSensorPattern(), mLayerNumber);
3455
3456 ylen = 0.5 * sOBChipThickness;
3457
3458 TGeoVolume* chipVol = AlpideChip::createChip(ylen, mSensorThickness / 2, chipName, sensName, dummyChip);
3459
3460 xchip = (static_cast<TGeoBBox*>(chipVol->GetShape()))->GetDX();
3461 ychip = (static_cast<TGeoBBox*>(chipVol->GetShape()))->GetDY();
3462 zchip = (static_cast<TGeoBBox*>(chipVol->GetShape()))->GetDZ();
3463
3464 mOBModuleZLength = 2 * zchip * sOBChipsPerRow + (sOBChipsPerRow - 1) * sOBChipZGap;
3465
3466 zlen = mOBModuleZLength / 2;
3467
3468 // The glue
3469 xlen = (4 * xchip + xGap) / 2;
3470 ylen = sOBGlueFPCThick / 2;
3471 TGeoBBox* glueFPC = new TGeoBBox("GlueFPC", xlen, ylen, zlen);
3472
3473 ylen = sOBGlueColdPlThick / 2;
3474 TGeoBBox* glueCP = new TGeoBBox("GlueCP", xlen, ylen, zlen);
3475
3476 // The FPC cables
3477 xlen = sOBFlexCableXWidth / 2;
3478 ylen = sOBFlexCableKapThick / 2;
3479 TGeoBBox* flexKap = new TGeoBBox("MidFlexKap", xlen, ylen, zlen);
3480
3481 TGeoVolume* cuGndCableVol = createOBFPCCuGnd(zlen);
3482 TGeoVolume* cuSignalCableVol = createOBFPCCuSig(zlen);
3483
3484 // The module
3485 Double_t ygnd = (static_cast<TGeoBBox*>(cuGndCableVol->GetShape()))->GetDY();
3486 Double_t ysig = (static_cast<TGeoBBox*>(cuSignalCableVol->GetShape()))->GetDY();
3487
3488 xlen = (static_cast<TGeoBBox*>(cuGndCableVol->GetShape()))->GetDX();
3489 ylen = glueCP->GetDY() + ychip + glueFPC->GetDY() + ysig + flexKap->GetDY() + ygnd;
3490 TGeoBBox* module = new TGeoBBox("OBModule", xlen, ylen, zlen);
3491
3492 // We have all shapes: now create the real volumes
3493
3494 TGeoMedium* medAir = mgr->GetMedium(Form("%s_AIR$", GetDetName()));
3495 TGeoMedium* medGlue = mgr->GetMedium(Form("%s_GLUE$", GetDetName()));
3496 TGeoMedium* medKapton = mgr->GetMedium(Form("%s_KAPTON(POLYCH2)$", GetDetName()));
3497
3498 TGeoVolume* glueFPCVol = new TGeoVolume("GlueFPCVol", glueFPC, medGlue);
3499 glueFPCVol->SetLineColor(kBlack);
3500 glueFPCVol->SetFillColor(glueFPCVol->GetLineColor());
3501 glueFPCVol->SetFillStyle(4000); // 0% transparent
3502
3503 TGeoVolume* glueCPVol = new TGeoVolume("GlueColdPlVol", glueCP, medGlue);
3504 glueCPVol->SetLineColor(kBlack);
3505 glueCPVol->SetFillColor(glueCPVol->GetLineColor());
3506 glueCPVol->SetFillStyle(4000); // 0% transparent
3507
3508 TGeoVolume* flexKapVol = new TGeoVolume("FPCMidKapVol", flexKap, medKapton);
3509 flexKapVol->SetLineColor(kGreen);
3510 flexKapVol->SetFillColor(flexKapVol->GetLineColor());
3511 flexKapVol->SetFillStyle(4000); // 0% transparent
3512
3513 snprintf(volName, nameLen, "%s%d", GeometryTGeo::getITSModulePattern(), mLayerNumber);
3514 TGeoVolume* modVol = new TGeoVolume(volName, module, medAir);
3515 modVol->SetVisibility(kTRUE);
3516
3517 // Now build up the module
3518 ypos = -module->GetDY() + glueCP->GetDY();
3519
3520 if (mBuildLevel < 3) { // Glue
3521 modVol->AddNode(glueCPVol, 1, new TGeoTranslation(0, ypos, 0));
3522 }
3523
3524 xpos = xchip + xGap / 2;
3525 ypos += (ychip + glueCP->GetDY());
3526 // We use two loops here to have the same chip numbering as in HW
3527 // X ^ | 6| 5| 4| 3| 2| 1| 0|
3528 // ----|--------------------------> Z
3529 // | | 7| 8| 9|10|11|12|13|
3530 //
3531 for (Int_t k = 0; k < sOBChipsPerRow; k++) // put first 7 chip row
3532 {
3533 zpos = module->GetDZ() - zchip - k * (2 * zchip + zGap);
3534 modVol->AddNode(chipVol, k, new TGeoCombiTrans(xpos, ypos, zpos, new TGeoRotation("", 0, 180, 180)));
3535 mHierarchy[kChip] += 1;
3536 }
3537
3538 for (Int_t k = 0; k < sOBChipsPerRow; k++) // put second 7 chip row
3539 {
3540 zpos = -module->GetDZ() + zchip + k * (2 * zchip + zGap);
3541 modVol->AddNode(chipVol, k + sOBChipsPerRow, new TGeoTranslation(-xpos, ypos, zpos));
3542 mHierarchy[kChip] += 1;
3543 }
3544
3545 ypos += (ychip + glueFPC->GetDY());
3546 if (mBuildLevel < 3) { // Glue
3547 modVol->AddNode(glueFPCVol, 1, new TGeoTranslation(0, ypos, 0));
3548 }
3549 ypos += glueFPC->GetDY();
3550
3551 if (mBuildLevel < 5) { // Kapton
3552 ypos += ysig;
3553 modVol->AddNode(cuSignalCableVol, 1, new TGeoTranslation(0, ypos, 0));
3554
3555 ypos += (ysig + flexKap->GetDY());
3556 modVol->AddNode(flexKapVol, 1, new TGeoTranslation(0, ypos, 0));
3557
3558 ypos += (flexKap->GetDY() + ygnd);
3559 modVol->AddNode(cuGndCableVol, 1, new TGeoTranslation(0, ypos, 0));
3560 }
3561
3562 // Done, return the module
3563 return modVol;
3564}
3565
3566TGeoVolume* V3Layer::createOBFPCCuGnd(const Double_t zcable, const TGeoManager* mgr)
3567{
3568 //
3569 // Create the OB FPC Copper Ground cable
3570 //
3571 // Input:
3572 // zcable : the cable half Z length
3573 // mgr : the GeoManager (used only to get the proper material)
3574 //
3575 // Output:
3576 //
3577 // Return:
3578 // the FPC cable as a TGeoVolume
3579 //
3580 // Created: 30 Jul 2018 Mario Sitta
3581 //
3582
3583 Double_t xcable, ytot, ypos;
3584
3585 // First create all needed shapes
3586 xcable = sOBFlexCableXWidth / 2;
3587 ytot = sOBFPCSoldMaskThick + sOBFPCCopperThick;
3588 TGeoBBox* soldmask = new TGeoBBox(xcable, ytot / 2, zcable);
3589 xcable *= sOBFPCCuAreaFracGnd;
3590 TGeoBBox* copper = new TGeoBBox(xcable, sOBFPCCopperThick / 2, zcable);
3591
3592 // Then the volumes
3593 TGeoMedium* medKapton = mgr->GetMedium(Form("%s_KAPTON(POLYCH2)$", GetDetName()));
3594 TGeoMedium* medCopper = mgr->GetMedium(Form("%s_COPPER$", GetDetName()));
3595
3596 TGeoVolume* soldmaskVol = new TGeoVolume("FPCGndSolderMask", soldmask, medKapton);
3597 soldmaskVol->SetLineColor(kBlue);
3598 soldmaskVol->SetFillColor(kBlue);
3599
3600 TGeoVolume* copperVol = new TGeoVolume("FPCCopperGround", copper, medCopper);
3601 copperVol->SetLineColor(kCyan);
3602 copperVol->SetFillColor(kCyan);
3603
3604 ypos = -soldmask->GetDY() + copper->GetDY();
3605 if (mBuildLevel < 1) { // Copper
3606 soldmaskVol->AddNode(copperVol, 1, new TGeoTranslation(0, ypos, 0));
3607 }
3608
3609 return soldmaskVol;
3610}
3611
3612TGeoVolume* V3Layer::createOBFPCCuSig(const Double_t zcable, const TGeoManager* mgr)
3613{
3614 //
3615 // Create the OB FPC Copper Signal cable
3616 //
3617 // Input:
3618 // zcable : the cable half Z length
3619 // mgr : the GeoManager (used only to get the proper material)
3620 //
3621 // Output:
3622 //
3623 // Return:
3624 // the FPC cable as a TGeoVolume
3625 //
3626 // Created: 30 Jul 2018 Mario Sitta
3627 //
3628
3629 Double_t xcable, ytot, ypos;
3630
3631 // First create all needed shapes
3632 xcable = sOBFlexCableXWidth / 2;
3633 ytot = sOBFPCSoldMaskThick + sOBFPCCopperThick;
3634 TGeoBBox* soldmask = new TGeoBBox(xcable, ytot / 2, zcable);
3635 xcable *= sOBFPCCuAreaFracSig;
3636 TGeoBBox* copper = new TGeoBBox(xcable, sOBFPCCopperThick / 2, zcable);
3637
3638 // Then the volumes
3639 TGeoMedium* medKapton = mgr->GetMedium(Form("%s_KAPTON(POLYCH2)$", GetDetName()));
3640 TGeoMedium* medCopper = mgr->GetMedium(Form("%s_COPPER$", GetDetName()));
3641
3642 TGeoVolume* soldmaskVol = new TGeoVolume("FPCSigSolderMask", soldmask, medKapton);
3643 soldmaskVol->SetLineColor(kBlue);
3644 soldmaskVol->SetFillColor(kBlue);
3645
3646 TGeoVolume* copperVol = new TGeoVolume("FPCCopperSignal", copper, medCopper);
3647 copperVol->SetLineColor(kCyan);
3648 copperVol->SetFillColor(kCyan);
3649
3650 ypos = soldmask->GetDY() - copper->GetDY();
3651 if (mBuildLevel < 1) { // Copper
3652 soldmaskVol->AddNode(copperVol, 1, new TGeoTranslation(0, ypos, 0));
3653 }
3654
3655 return soldmaskVol;
3656}
3657
3658Double_t V3Layer::radiusOmTurboContainer()
3659{
3660 Double_t rr, delta, z, lstav, rstav;
3661
3662 if (mChipThickness > 89.) { // Very big angle: avoid overflows since surely
3663 return -1; // the radius from lower vertex is the right value
3664 }
3665
3666 rstav = mLayerRadius + 0.5 * mChipThickness;
3667 delta = (0.5 * mChipThickness) / cosD(mStaveTilt);
3668 z = (0.5 * mChipThickness) * tanD(mStaveTilt);
3669
3670 rr = rstav - delta;
3671 lstav = (0.5 * mStaveWidth) - z;
3672
3673 if ((rr * sinD(mStaveTilt) < lstav)) {
3674 return (rr * cosD(mStaveTilt));
3675 } else {
3676 return -1;
3677 }
3678}
3679
3681{
3682 if (mLayerNumber < sNumberOfInnerLayers) {
3683 mNumberOfChips = u;
3684 } else {
3685 mNumberOfModules = u;
3686 mNumberOfChips = sOBChipsPerRow;
3687 }
3688}
3689
3690void V3Layer::setStaveTilt(const Double_t t)
3691{
3692 if (mIsTurbo) {
3693 mStaveTilt = t;
3694 } else {
3695 LOG(error) << "Not a Turbo layer";
3696 }
3697}
3698
3699void V3Layer::setStaveWidth(const Double_t w)
3700{
3701 if (mIsTurbo) {
3702 mStaveWidth = w;
3703 } else {
3704 LOG(error) << "Not a Turbo layer";
3705 }
3706}
3707
3708TGeoXtru* V3Layer::createStaveSide(const char* name, Double_t dz, Double_t alpha, Double_t beta, Double_t L, Double_t H,
3709 Bool_t top)
3710{
3711 //
3712 // Creates the V-shaped sides of the OB space frame
3713 // (from a similar method with same name and function
3714 // in AliITSv11GeometrySDD class by L.Gaudichet)
3715 //
3716 // Updated: 15 Dec 2014 Mario Sitta Rewritten using Xtru
3717 // Updated: 09 Jan 2015 Mario Sitta Rewritten again using different
3718 // aperture angles (info by C.Gargiulo)
3719 // Updated: 21 Jul 2017 Mario Sitta O2 version
3720 //
3721
3722 // Create the V shape corner of CF stave
3723
3724 const Int_t nv = 6;
3725 Double_t xv[nv], yv[nv];
3726
3727 TGeoXtru* cfStavSide = new TGeoXtru(2);
3728 cfStavSide->SetName(name);
3729
3730 Double_t theta = TMath::PiOver2() - beta;
3731 Double_t gamma = beta - alpha;
3732 // Points must be in clockwise order
3733 if (top) { // TOP - vertices not in order
3734 xv[3] = 0;
3735 yv[3] = 0;
3736 xv[2] = L * TMath::Sin(alpha);
3737 yv[2] = -L * TMath::Cos(alpha);
3738 xv[1] = xv[2] - H * TMath::Cos(alpha);
3739 yv[1] = yv[2] - H * TMath::Sin(alpha);
3740 xv[0] = 0;
3741 yv[0] = yv[1] + TMath::Tan(theta) * xv[1];
3742 xv[4] = -xv[2]; // Reflect
3743 yv[4] = yv[2];
3744 xv[5] = -xv[1];
3745 yv[5] = yv[1];
3746 } else { // SIDE
3747 Double_t m = -TMath::Tan(alpha), n = TMath::Tan(gamma);
3748 xv[0] = 0;
3749 yv[0] = 0;
3750 xv[1] = -L * TMath::Cos(2 * alpha);
3751 yv[1] = L * TMath::Sin(2 * alpha);
3752 xv[2] = xv[1] - H * TMath::Sin(2 * alpha);
3753 yv[2] = yv[1] - H * TMath::Cos(2 * alpha);
3754 xv[4] = -L;
3755 yv[4] = H;
3756 xv[5] = xv[4];
3757 yv[5] = 0;
3758 xv[3] = (yv[4] - n * xv[4]) / (m - n);
3759 yv[3] = m * xv[3];
3760 }
3761
3762 cfStavSide->DefinePolygon(nv, xv, yv);
3763 cfStavSide->DefineSection(0, -dz);
3764 cfStavSide->DefineSection(1, dz);
3765
3766 return cfStavSide;
3767}
3768
3769TGeoCombiTrans* V3Layer::createCombiTrans(const char* name, Double_t dy, Double_t dz, Double_t dphi, Bool_t planeSym)
3770{
3771 TGeoTranslation t1(dy * cosD(90. + dphi), dy * sinD(90. + dphi), dz);
3772 TGeoRotation r1("", 0., 0., dphi);
3773 TGeoRotation r2("", 90, 180, -90 - dphi);
3774
3775 TGeoCombiTrans* combiTrans1 = new TGeoCombiTrans(name);
3776 combiTrans1->SetTranslation(t1);
3777 if (planeSym) {
3778 combiTrans1->SetRotation(r1);
3779 } else {
3780 combiTrans1->SetRotation(r2);
3781 }
3782 return combiTrans1;
3783}
3784
3785void V3Layer::addTranslationToCombiTrans(TGeoCombiTrans* ct, Double_t dx, Double_t dy, Double_t dz) const
3786{
3787 // Add a dx,dy,dz translation to the initial TGeoCombiTrans
3788 const Double_t* vect = ct->GetTranslation();
3789 Double_t newVect[3] = {vect[0] + dx, vect[1] + dy, vect[2] + dz};
3790 ct->SetTranslation(newVect);
3791}
Creates an ALPIDE chip in simulation.
std::ostringstream debug
int32_t i
Definition of the GeometryTGeo class.
uint32_t j
Definition RawData.h:0
Definition of the SegmentationAlpide class.
ClassImp(V3Layer)
Definition of the V3Layer class.
static const char * getITSLayerPattern()
static const char * getITSSensorPattern()
static const char * getITSHalfBarrelPattern()
static const char * getITSChipPattern()
static const char * getITSModulePattern()
static const char * getITSHalfStavePattern()
static const char * getITSStavePattern()
Double_t cosD(Double_t deg) const
Cosine function.
Definition V11Geometry.h:91
const char * GetDetName() const
Get detector name.
Definition V11Geometry.h:58
Double_t sinD(Double_t deg) const
Definition V11Geometry.h:85
Double_t tanD(Double_t deg) const
Tangent function.
Definition V11Geometry.h:97
static const Double_t sMicron
Convert micron to TGeom's cm.
void setStaveWidth(Double_t w)
Definition V3Layer.cxx:3699
void setStaveTilt(Double_t t)
Definition V3Layer.cxx:3690
void setNumberOfUnits(Int_t u)
Definition V3Layer.cxx:3680
virtual void createLayer(TGeoVolume *motherVolume)
Definition V3Layer.cxx:311
~V3Layer() override
Default destructor.
static TGeoVolume * createChip(Double_t yc, Double_t ys, char const *chipName="AlpideChip", char const *sensName="AlpideSensor", Bool_t dummy=kFALSE, const TGeoManager *mgr=gGeoManager)
GLdouble n
Definition glcorearb.h:1982
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
const GLfloat * m
Definition glcorearb.h:4066
GLdouble GLdouble GLdouble GLdouble top
Definition glcorearb.h:4077
GLuint const GLchar * name
Definition glcorearb.h:781
GLboolean r
Definition glcorearb.h:1233
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t1
Definition glcorearb.h:5034
value_T std::array< value_T, 7 > & vect
Definition TrackUtils.h:42
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"