ATLAS Offline Software
GeoPixelIBLFwdSvcModel1.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
6 // Build IBL fwd services (wavy shape)
7 // This is built one time per layer.
8 
10 
11 #include "GeoModelKernel/GeoTube.h"
12 #include "GeoModelKernel/GeoTubs.h"
13 #include "GeoModelKernel/GeoSimplePolygonBrep.h"
14 #include "GeoModelKernel/GeoShape.h"
15 #include "GeoModelKernel/GeoShapeUnion.h"
16 #include "GeoModelKernel/GeoShapeShift.h"
17 #include "GeoModelKernel/GeoLogVol.h"
18 #include "GeoModelKernel/GeoPhysVol.h"
19 #include "GeoModelKernel/GeoMaterial.h"
20 #include "GeoModelKernel/GeoNameTag.h"
21 
22 #include "GeoModelKernel/GeoTransform.h"
23 #include "GaudiKernel/SystemOfUnits.h"
24 
25 #include <algorithm>
26 #include <cmath>
27 #include <iomanip>
28 #include <iostream>
29 #include <utility>
30 using std::max;
31 
34  GeoModelIO::ReadGeoModel* sqliteReader,
35  std::shared_ptr<std::map<std::string, GeoFullPhysVol*>> mapFPV,
36  std::shared_ptr<std::map<std::string, GeoAlignableTransform*>> mapAX,
37  int /*section*/)
38  : GeoVPixelFactory (ddmgr, mgr, sqliteReader, std::move(mapFPV), std::move(mapAX)),
39  m_supportPhysA(nullptr),
40  m_supportPhysC(nullptr),
41  m_xformSupportA(nullptr),
42  m_xformSupportC(nullptr)
43 {
44 }
45 
47 {
48 
49  m_gmt_mgr->msg(MSG::INFO) <<"Build IBL fwd services"<<endmsg;
50 
51  // double safety = 0.01*Gaudi::Units::mm;
52 
53  // IBL layer shift ( 2mm shift issue )
54  double layerZshift = m_gmt_mgr->PixelLayerGlobalShift();
55  int nSectors = m_gmt_mgr->NPixelSectors();
56  double phiOfModuleZero = m_gmt_mgr->PhiOfModuleZero();
57  double layerRadius = m_gmt_mgr->PixelLayerRadius();
58 
59  // check if sectors are properly defined
60  if(nSectors==0) return nullptr;
61  double angle=360./(double)nSectors*Gaudi::Units::deg;
62 
63  // Defines the IBL_Fwd02 section in the IBL services area
64  double innerRadius = 33.;
65  double outerRadius = 42.499;
66  double zMin = 834.607;
67  double zMax = 3290.795;
68 
69  double zLength = zMax-zMin;
70  double halfLength = zLength*.5;
71  double zMiddle = (zMin+zMax)*.5;
72 
73  // Define IBL fwd svc section for side A and C
74  std::ostringstream lnameA;
75  lnameA<<"Brl0A_FwdSvc";
76  std::ostringstream lnameC;
77  lnameC<<"Brl0C_FwdSvc";
78 
79  // Build encompassing volume for both A and C sides (assemblies)
80  const GeoTube* supportShapeA = new GeoTube(innerRadius,outerRadius,halfLength);
81  const GeoTube* supportShapeC = new GeoTube(innerRadius,outerRadius,halfLength);
82  const GeoMaterial* ether = m_mat_mgr->getMaterial("special::Ether");
83  // const GeoMaterial* ether = m_mat_mgr->getMaterial("std::Air");
84  GeoLogVol* supportLogVol_A = new GeoLogVol(lnameA.str(),supportShapeA,ether);
85  GeoLogVol* supportLogVol_C = new GeoLogVol(lnameC.str(),supportShapeC,ether);
86 
87  // Shift in phi
88  double pi = M_PI;
89  // double deltaPhi = pi/28.;
90 
91  // Data taken fron CATIA desgin file
92  double devTotalLength = 2460.188;
93 
94  // Cable bundle sizes
95  double rminCable = 0.;
96  double rmaxCable = 8.*.5;
97  double surfCable = rmaxCable*rmaxCable*pi;
98 
99  // Cooling tube sizes
100  double rminCooling = 0.;
101  double rmaxCooling = 1.75*.5;
102  double surfCooling = rmaxCooling*rmaxCooling*pi;
103 
104  // IPT clip starting position
105  // double zpos0 = 903.;
106  double zpos = 0.;
107  // double zposRing = 0.;
108  // double hermJunction = .4;
109  double breakAngle = 11.*Gaudi::Units::deg;
110 
111  double cooling_radius = 35.1;
112  double cooling_angle = -2.154*Gaudi::Units::deg;
113 
114  if(m_gmt_mgr->PixelStaveAxe()==1)
115  {
116  cooling_radius = 34.7 + layerRadius-33.25;
117  cooling_angle = -.1*Gaudi::Units::deg;
118  }
119 
120  double cable_radius = 36.501;
121  // double cable_radius = innerRadius+rmaxCable+0.001;
122 
123  // Eta steps
124  int nbSteps = 3;
125  double etaSteps[3] = {3.8, 4.3, 4.8 };
126 
127  // Z steps
128  // double zDelta1 = 50;
129  std::vector<double> zSteps;
130  bool bFirstLin = true;
131  for(int i=0; i<nbSteps; i++){
132  double tmp = 2.*atan(exp(etaSteps[i]));
133  double tmp2 = tan(tmp);
134  double z = fabs(cable_radius/tmp2);
135 
136  if(i==0) {
137  if(z>zMin){
138  zSteps.push_back(zMin+0.001);
139  zSteps.push_back(z);
140  }
141  else {
142  // bFirstLin = false;
143  zSteps.push_back(zMin+0.001);
144  zSteps.push_back(zMin+10.);
145  }
146  }
147  else
148  zSteps.push_back(z);
149 
150  // std::cout<<"Eta/Z : "<<etaSteps[i]<<" "<<z<<std::endl;
151  }
152  zSteps.push_back(zMax-0.001);
153  nbSteps+=1;
154  if(bFirstLin)nbSteps++;
155 
156  // Loop over the wavy shape sections to build a cable and a cooling pipe
157  const GeoShape * gblShapeCableA = nullptr;
158  const GeoShape * gblShapeCoolingA = nullptr;
159  const GeoShape * gblShapeCableC = nullptr;
160  const GeoShape * gblShapeCoolingC = nullptr;
161 
162 // deltaPhi = (2.*pi)/28.;
163 // deltaPhi = .2815;
164 // double deltaMiddle_all = cable_radius*tan(deltaPhi);
165 
166  double deltaMiddle_all = 18.;
167 
168  // deltaMiddle_all = 10.5.;
169  // std::cout<<"IBL fwd : "<<deltaMiddle_all<<std::endl;
170 
171  zpos = zSteps[0];
172  int angleSign = 1;
173  for(int iStep=0; iStep<nbSteps-1; iStep++)
174  {
175  double zInit = zSteps[iStep];
176  double zFinal = zSteps[iStep+1];
177  double zMid = (zInit+zFinal)*.5;
178  double zHalfLength = zMid-zInit;
179  double zLength = zFinal-zInit;
180 
181  // std::cout<<"--- STEP "<<std::setprecision(13)<<iStep<<" "<<zInit<<" "<<zFinal<<std::endl;
182 
183 // double deltaPhiLoc = fabs(atan(deltaMiddle_all/(zHalfLength));
184 // double cableHalfLength = zHalfLength / cos(deltaPhiLoc);
185 // double cableLength = zHalfLength / cos(deltaPhiLoc);
186 // double deltaMiddleLoc = deltaMiddle_all*.5;
187 
188  double deltaPhiLoc = fabs(atan(deltaMiddle_all/zLength));
189  double cableHalfLength = (zLength / cos(deltaPhiLoc))*.5;
190  double deltaMiddleLoc = deltaMiddle_all*.5;
191 
192  // std::cout<<" "<<zHalfLength<<"/"<<cableHalfLength<<" "<<deltaMiddleLoc<<std::endl;
193 
194  if((iStep==0&&bFirstLin)||iStep==nbSteps-2) {
195  // linear section
196  zpos += zHalfLength;
197 
198  // Cable
199  const GeoTube* cableShape = new GeoTube(rminCable, rmaxCable, zHalfLength);
200  double angle = 0.; //11.*Gaudi::Units::deg;
201  GeoTrf::Transform3D trfA1 = GeoTrf::RotateZ3D(angle)*GeoTrf::TranslateZ3D(zpos-zMiddle);
202  gblShapeCableA = addShape(gblShapeCableA, cableShape, trfA1 );
203  GeoTrf::Transform3D trfC1 = GeoTrf::RotateZ3D(angle)*GeoTrf::TranslateZ3D(zMax-(zpos-zMin)-zMiddle);
204  gblShapeCableC = addShape(gblShapeCableC, cableShape, trfC1 );
205 
206  // Cooling
207  const GeoTube* coolingShape = new GeoTube(rminCooling, rmaxCooling, zHalfLength);
208  gblShapeCoolingA = addShape(gblShapeCoolingA, coolingShape, trfA1 );
209  gblShapeCoolingC = addShape(gblShapeCoolingC, coolingShape, trfC1 );
210 
211  zpos += zHalfLength;
212  }
213  else {
214 
215  // First section
216  zpos += zHalfLength;
217 
218  // Cable
219  const GeoTube* cableShape = new GeoTube(rminCable, rmaxCable, cableHalfLength);
220  double angle= 0.;
221  GeoTrf::Transform3D trfA1 = GeoTrf::RotateZ3D(angle)*GeoTrf::TranslateY3D(deltaMiddleLoc)* GeoTrf::TranslateZ3D(zpos-zMiddle)*GeoTrf::RotateX3D(-angleSign*deltaPhiLoc);
222  gblShapeCableA = addShape(gblShapeCableA, cableShape, trfA1 );
223  GeoTrf::Transform3D trfC1 = GeoTrf::RotateZ3D(angle)*GeoTrf::TranslateY3D(deltaMiddleLoc)* GeoTrf::TranslateZ3D(zMax-(zpos-zMin)-zMiddle)*GeoTrf::RotateX3D(angleSign*deltaPhiLoc);
224  gblShapeCableC = addShape(gblShapeCableC, cableShape, trfC1 );
225 
226  // Cooling
227  const GeoTube* coolingShape = new GeoTube(rminCooling, rmaxCooling, cableHalfLength);
228  gblShapeCoolingA = addShape(gblShapeCoolingA, coolingShape, trfA1 );
229  gblShapeCoolingC = addShape(gblShapeCoolingC, coolingShape, trfC1 );
230 
231  zpos += zHalfLength;
232  angleSign*=-1;
233  }
234 
235 
236  }
237 
238  // std::cout<<"--- MATERIAL : length "<<devTotalLength<<" surf "<<surfCable<<std::endl;
239 
240  // Material (material budget computed based on the detailed description of a cable bundle and cooling pipe
241  const GeoMaterial* cableMat = m_mat_mgr->getMaterialForVolume("pix::IBL_Fwd02_Cable_Wvy_M1",surfCable*devTotalLength);
242 
243  // std::cout<<"--- MATERIAL : cable defined "<<(cableMat==0)<<std::endl;
244 
245  GeoLogVol * cable_logA = new GeoLogVol("IBL_Fwd02_Cable_A",gblShapeCableA,cableMat);
246  GeoLogVol * cable_logC = new GeoLogVol("IBL_Fwd02_Cable_C",gblShapeCableC,cableMat);
247 
248  const GeoMaterial* coolingMat = m_mat_mgr->getMaterialForVolume("pix::IBL_Fwd02_Cooling_Wvy_M1",surfCooling*devTotalLength);
249  // std::cout<<"--- MATERIAL : cooling defined "<<(cableMat==0)<<std::endl;
250  GeoLogVol * cooling_logA = new GeoLogVol("IBL_Fwd02_Cooling_A",gblShapeCoolingA,coolingMat);
251  GeoLogVol * cooling_logC = new GeoLogVol("IBL_Fwd02_Cooling_C",gblShapeCoolingC,coolingMat);
252 
253  // ----------- Create the PhysVol object
254  m_supportPhysA = new GeoPhysVol(supportLogVol_A);
255  m_supportPhysC = new GeoPhysVol(supportLogVol_C);
256 
257  // -------------- Alignement of the services with the previous services (Fwd01 area)
258  GeoPhysVol* cablePhysVolA = new GeoPhysVol(cable_logA);
259  GeoPhysVol* cablePhysVolC = new GeoPhysVol(cable_logC);
260  GeoPhysVol* coolingPhysVolA = new GeoPhysVol(cooling_logA);
261  GeoPhysVol* coolingPhysVolC = new GeoPhysVol(cooling_logC);
262 
263  // std::cout<<"--- LOOP over sectors"<<std::endl;
264 
265  // nSectors = 1;
266 
267  // Loop over the sectors to place the 14 bundles and cooling pipes
268  for(int ii=0; ii<nSectors; ii++)
269  {
270  m_gmt_mgr->SetPhi(ii);
271 
272  // cooling transform
273  double phiOfCooling = phiOfModuleZero+ cooling_angle + ii*angle;
274 
275  std::ostringstream tmp1;
276  tmp1 << "IBL_Fwd02_Cooling_AC" << ii;
277  GeoNameTag * tag1 = new GeoNameTag(tmp1.str());
278  GeoTransform* xformA1 = new GeoTransform(GeoTrf::RotateZ3D(phiOfCooling)*GeoTrf::TranslateX3D(cooling_radius));
279  m_supportPhysA->add(tag1);
280  m_supportPhysA->add(xformA1);
281  m_supportPhysA->add(coolingPhysVolA);
282 
283  GeoTransform* xformC1 = new GeoTransform(GeoTrf::RotateZ3D(phiOfCooling)*GeoTrf::TranslateX3D(cooling_radius));
284  m_supportPhysC->add(tag1);
285  m_supportPhysC->add(xformC1);
286  m_supportPhysC->add(coolingPhysVolC);
287 
288  double phiOfCable = phiOfCooling + angle*.5;
289 
290  std::ostringstream tmp2;
291  tmp2 << "IBL_Fwd02_Cable_AC" << ii;
292  GeoNameTag * tag2 = new GeoNameTag(tmp2.str());
293  GeoTransform* xformA2 = new GeoTransform(GeoTrf::RotateZ3D(phiOfCable)*GeoTrf::TranslateX3D(cable_radius)*GeoTrf::RotateZ3D(breakAngle));
294  m_supportPhysA->add(tag2);
295  m_supportPhysA->add(xformA2);
296  m_supportPhysA->add(cablePhysVolA);
297 
298  GeoTransform* xformC2 = new GeoTransform(GeoTrf::RotateZ3D(phiOfCable)*GeoTrf::TranslateX3D(cable_radius)*GeoTrf::RotateZ3D(breakAngle));
299  m_supportPhysC->add(tag2);
300  m_supportPhysC->add(xformC2);
301  m_supportPhysC->add(cablePhysVolC);
302  }
303 
304  // Global transforms that include the IBL shift in Z
305  double middleA = zMiddle+layerZshift;
306  double middleC = -zMiddle+layerZshift;
307 
308  GeoTrf::Transform3D supportTrfA = GeoTrf::TranslateZ3D(middleA);
309  m_xformSupportA = new GeoTransform(supportTrfA);
310 
311  GeoTrf::Transform3D supportTrfC = GeoTrf::TranslateZ3D(middleC);
312  m_xformSupportC = new GeoTransform(supportTrfC);
313 
314  return nullptr;
315 }
316 
317 
318 const GeoShape * GeoPixelIBLFwdSvcModel1::addShape(const GeoShape * lastShape, const GeoShape * nextShape, const GeoTrf::Transform3D & trans)
319 {
320  const GeoShape * shiftedShape = &(*nextShape << trans);
321  if (lastShape) {
322  lastShape = &(lastShape->add(*shiftedShape));
323  } else {
324  lastShape = shiftedShape;
325  }
326  return lastShape;
327 }
PixelGeometryManager::PixelLayerGlobalShift
virtual double PixelLayerGlobalShift()=0
GeoPixelIBLFwdSvcModel1::Build
virtual GeoVPhysVol * Build() override
Definition: GeoPixelIBLFwdSvcModel1.cxx:46
DeMoUpdate.tmp2
string tmp2
Definition: DeMoUpdate.py:1168
PixelGeometryManager
Definition: PixelGeometryManager.h:28
PixelGeometryManager::msg
MsgStream & msg(MSG::Level lvl) const
Definition: PixelGeometryManager.h:611
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
GeoPixelIBLFwdSvcModel1.h
M_PI
#define M_PI
Definition: ActiveFraction.h:11
GeoPixelIBLFwdSvcModel1::m_xformSupportA
GeoTransform * m_xformSupportA
Definition: GeoPixelIBLFwdSvcModel1.h:40
deg
#define deg
Definition: SbPolyhedron.cxx:17
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
GeoPixelIBLFwdSvcModel1::GeoPixelIBLFwdSvcModel1
GeoPixelIBLFwdSvcModel1(InDetDD::PixelDetectorManager *ddmgr, PixelGeometryManager *mgr, GeoModelIO::ReadGeoModel *sqliteReader, std::shared_ptr< std::map< std::string, GeoFullPhysVol * >> mapFPV, std::shared_ptr< std::map< std::string, GeoAlignableTransform * >> mapAX, int)
Definition: GeoPixelIBLFwdSvcModel1.cxx:32
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
GeoPixelIBLFwdSvcModel1::m_supportPhysC
GeoPhysVol * m_supportPhysC
Definition: GeoPixelIBLFwdSvcModel1.h:39
GeoPixelIBLFwdSvcModel1::m_supportPhysA
GeoPhysVol * m_supportPhysA
Definition: GeoPixelIBLFwdSvcModel1.h:38
pi
#define pi
Definition: TileMuonFitter.cxx:65
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
GeoVPixelFactory::m_gmt_mgr
PixelGeometryManager * m_gmt_mgr
Definition: GeoVPixelFactory.h:43
PixelGeometryManager::NPixelSectors
virtual int NPixelSectors()=0
BchCleanup.mgr
mgr
Definition: BchCleanup.py:294
GeoPixelIBLFwdSvcModel1::m_xformSupportC
GeoTransform * m_xformSupportC
Definition: GeoPixelIBLFwdSvcModel1.h:41
lumiFormat.i
int i
Definition: lumiFormat.py:85
z
#define z
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
plotBeamSpotCompare.tag1
string tag1
Definition: plotBeamSpotCompare.py:75
angle
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Definition: TRTDetectorFactory_Full.cxx:73
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
InDetMaterialManager::getMaterialForVolume
const GeoMaterial * getMaterialForVolume(const std::string &materialName, double volume, const std::string &newName="")
Create and get material with a density calculated to give weight in predefined weight table.
Definition: InDetMaterialManager.cxx:460
PixelGeometryManager::SetPhi
virtual void SetPhi(int phi)=0
plotBeamSpotCompare.tag2
string tag2
Definition: plotBeamSpotCompare.py:76
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
xAOD::double
double
Definition: CompositeParticle_v1.cxx:159
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
InDetDD::PixelDetectorManager
Definition: PixelDetectorManager.h:47
GeoVPixelFactory::m_mat_mgr
InDetMaterialManager * m_mat_mgr
Definition: GeoVPixelFactory.h:44
PixelGeometryManager::PixelStaveAxe
virtual int PixelStaveAxe()=0
PixelGeometryManager::PhiOfModuleZero
virtual double PhiOfModuleZero()=0
GeoPixelIBLFwdSvcModel1::addShape
const GeoShape * addShape(const GeoShape *lastShape, const GeoShape *nextShape, const GeoTrf::Transform3D &trans)
Definition: GeoPixelIBLFwdSvcModel1.cxx:318
PixelGeometryManager::PixelLayerRadius
virtual double PixelLayerRadius()=0
GeoVPixelFactory
This is the base class for all the pieces of the Pixel detector.
Definition: GeoVPixelFactory.h:31
InDetMaterialManager::getMaterial
const GeoMaterial * getMaterial(const std::string &materialName)
Get material. First looks for locally defined material and if not found looks in GeoModel material ma...
Definition: InDetMaterialManager.cxx:96