ATLAS Offline Software
GeoPixelFrame.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 // Build the global support frame
6 
7 #include "GeoPixelFrame.h"
8 #include "GaudiKernel/PhysicalConstants.h"
9 #include "GeoModelKernel/GeoBox.h"
10 #include "GeoModelKernel/GeoLogVol.h"
11 #include "GeoModelKernel/GeoMaterial.h"
12 #include "GeoModelKernel/GeoPara.h"
13 #include "GeoModelKernel/GeoPgon.h"
14 #include "GeoModelKernel/GeoPhysVol.h"
15 #include "GeoModelKernel/GeoSimplePolygonBrep.h"
16 #include "GeoModelKernel/GeoTransform.h"
17 #include "GeoModelKernel/GeoTrap.h"
19 #include <algorithm>
20 #include <utility>
21 
23  PixelGeometryManager* mgr, GeoModelIO::ReadGeoModel* sqliteReader,
24  std::shared_ptr<std::map<std::string, GeoFullPhysVol*>> mapFPV,
25  std::shared_ptr<std::map<std::string, GeoAlignableTransform*>> mapAX)
26  : GeoVPixelFactory (ddmgr, mgr, sqliteReader, std::move(mapFPV), std::move(mapAX))
27 {
28 }
29 
30 void GeoPixelFrame::BuildAndPlace(GeoFullPhysVol * parent, int section)
31 {
32  double rminSide = m_gmt_mgr->PixelFrameRMinSide(section);
33  double rmaxSide = m_gmt_mgr->PixelFrameRMaxSide(section);
34  double sideWidth = m_gmt_mgr->PixelFrameSideWidth(section);
37  double phiLoc = m_gmt_mgr->PixelFramePhiStart(section);
38  int numSides = m_gmt_mgr->PixelFrameNumSides(section);
39  bool mirrorSides = m_gmt_mgr->PixelFrameMirrorSides(section);
40 
41  // No frame defined in the DB table
42  if(numSides==0)return;
43 
44  double midRadius = 0.5*(rminSide+rmaxSide);
45  double zCenter = 0.5*(zmin+zmax);
46 
47  const GeoMaterial* air = m_mat_mgr->getMaterial("std::Air");
48 
49 
51  // The Frame envelope
53 
54  // Make envelope to hold the frame
55  //double safety = 0.001 * Gaudi::Units::mm;
56  double epsilon = 0.00001 * Gaudi::Units::mm;
57  double halflength = 0.5*std::abs(zmax - zmin);
58 
59  double alpha = Gaudi::Units::pi/numSides;
60  double cosalpha = cos(alpha);
61  double sinalpha = sin(alpha);
62 
63  /*
64  double rminEnv = (rminSide-safety)/cosalpha;
65  double rmaxEnv = (rmaxSide+safety)/cosalpha;
66  GeoPgon * frameEnvShape = new GeoPgon(phiLoc-alpha,2*Gaudi::Units::pi,numSides);
67  frameEnvShape->addPlane(zCenter-halflength-0.5*epsilon,rminEnv,rmaxEnv);
68  frameEnvShape->addPlane(zCenter+halflength+0.5*epsilon,rminEnv,rmaxEnv);
69 
70  GeoLogVol * frameEnvLV = new GeoLogVol("Frame",frameEnvShape,air);
71  GeoPhysVol * frameEnvPV = new GeoPhysVol(frameEnvLV);
72  */
73 
75  // The Corners
77 
78  // Calculate corner parameters. This is made using a BREP by defining the vertices.
79  double rmin = rminSide/cosalpha;
80  double rmax = rmaxSide/cosalpha;
81  double innerFullSideHalfWidth = rmin * sinalpha;
82  double outerFullSideHalfWidth = rmax * sinalpha;
83  double sideHalfWidth = 0.5 * sideWidth;
84  if (innerFullSideHalfWidth - sideHalfWidth < 0) {
85  std::cout << "Error. innerFullSideWidth is smaller than sideWidth" << std::endl;
86  // ERROR
87  }
88 
89  double v1x = rmax;
90  double v1y = 0;
91  double v2x = rmax - (outerFullSideHalfWidth - sideHalfWidth) * sinalpha;
92  double v2y = (outerFullSideHalfWidth - sideHalfWidth) * cosalpha;
93  double v3x = rmin - (innerFullSideHalfWidth - sideHalfWidth) * sinalpha;
94  double v3y = (innerFullSideHalfWidth - sideHalfWidth) * cosalpha;
95  double v4x = rmin;
96  double v4y = 0;
97  double v5x = v3x;
98  double v5y = -v3y;
99  double v6x = v2x;
100  double v6y = -v2y;
101 
102  //std::cout << "Point 1: (" << v1x << ", " << v1y << ")" << std::endl;
103  //std::cout << "Point 2: (" << v2x << ", " << v2y << ")" << std::endl;
104  //std::cout << "Point 3: (" << v3x << ", " << v3y << ")" << std::endl;
105  //std::cout << "Point 4: (" << v4x << ", " << v4y << ")" << std::endl;
106  //std::cout << "Point 5: (" << v5x << ", " << v5y << ")" << std::endl;
107  //std::cout << "Point 6: (" << v6x << ", " << v6y << ")" << std::endl;
108 
109  // Make the Corner shape
110  GeoSimplePolygonBrep * cornerShape = new GeoSimplePolygonBrep(halflength-epsilon);
111  cornerShape->addVertex(v1x,v1y);
112  cornerShape->addVertex(v2x,v2y);
113  cornerShape->addVertex(v3x,v3y);
114  cornerShape->addVertex(v4x,v4y);
115  cornerShape->addVertex(v5x,v5y);
116  cornerShape->addVertex(v6x,v6y);
117 
118  // Test GeoModel volume calculation. OK.
119  // double volumeBrepTest = (innerFullSideHalfWidth + outerFullSideHalfWidth - 2*sideHalfWidth)
120  // * (rmaxSide-rminSide)*2*(halflength-epsilon);
121  // std::cout << "Volume BREP: GeoModel: " << cornerShape->volume() << " My calc: " << volumeBrepTest << std::endl;
122 
123  std::string cornerMatName = m_gmt_mgr->PixelFrameCornerMaterial(section);
124  const GeoMaterial* cornerMat = m_mat_mgr->getMaterialForVolume(cornerMatName,numSides*cornerShape->volume()); // CHeck volume calc.
125  //const GeoMaterial* cornerMat = m_mat_mgr->getMaterial("std::Carbon");
126  GeoLogVol * cornerLV = new GeoLogVol("FrameCorner",cornerShape,cornerMat);
127 
128 
130  // The Sides
132 
133  // Make the side
134  // Put the side in a box
135  GeoPhysVol * sideEnvelopePV = nullptr;
136  double zSideCenter = 0;
137  int numElements = m_gmt_mgr->PixelFrameNumSideElements(section);
138 
139  if (numElements) {
140  double sideThick = rmaxSide - rminSide;
141 
142  std::vector<GeoTrf::Transform3D> sideTransVec;
143  std::vector<GeoShape *> sideElementShapeVec;
144  sideTransVec.reserve(numElements);
145  sideElementShapeVec.reserve(numElements);
146 
147  bool first = true;
148  double zSideMin = 0;
149  double zSideMax = 0;
150  double totSideVolume = 0;
151  for (int iElement = 0; iElement < numElements; iElement++) {
152  // 1, 2 (ie zMin1, zMin2 and zMax1 and zMax2 refers to the lower and upper (in phi) edges of the side element of the frame.
153  double zMin1 = m_gmt_mgr->PixelFrameElementZMin1(section, iElement)+2*epsilon;
154  double zMax1 = m_gmt_mgr->PixelFrameElementZMax1(section, iElement)-2*epsilon;
155  double zMin2 = m_gmt_mgr->PixelFrameElementZMin2(section, iElement)+2*epsilon;
156  double zMax2 = m_gmt_mgr->PixelFrameElementZMax2(section, iElement)-2*epsilon;
157  double zminInput = std::min(zMin1,std::min(zMax1,std::min(zMin2,zMax2)));
158  double zmaxInput = std::max(zMin1,std::max(zMax1,std::max(zMin2,zMax2)));
159  if (first) {
160  zSideMin = zminInput;
161  zSideMax = zmaxInput;
162  first = false;
163  } else {
164  zSideMin = std::min(zSideMin, zminInput);
165  zSideMax = std::max(zSideMax, zmaxInput);
166  }
167  GeoShape * sideElementShape = nullptr;
168  GeoTrf::Transform3D rotateShape(GeoTrf::Transform3D::Identity());
169  double shapeVolume = 0;
170  if (same(zMin1,zMin2) && same(zMax1,zMax2)) {
171  // Use a box
172  sideElementShape = new GeoBox(0.5*sideThick, 0.5*sideWidth-2*epsilon, 0.5*std::abs(zMax1-zMin1));
173  shapeVolume = sideElementShape->volume();
174  } else if (same(zMax1-zMin1, zMax2-zMin2)) {
175  // Use a parallelepiped
176  double alphaPara = atan2(zMin2-zMin1,sideWidth);
177  double thetaPara = 0;
178  double phiPara = 0;
179  sideElementShape = new GeoPara(0.5*std::abs(zMax1-zMin1), 0.5*sideWidth-epsilon, 0.5*sideThick, alphaPara, thetaPara, phiPara);
180  rotateShape = GeoTrf::RotateY3D(-90*Gaudi::Units::deg);
181  shapeVolume = std::abs(zMax1-zMin1) * (sideWidth-2*epsilon) * sideThick;
182  } else {//
183  // other cases not implemented. Should not occur for the frame.
184  std::cout << "GeoPixelFrame: This case is not handled for building the frame" << std::endl;
185  }
186  sideTransVec.push_back(GeoTrf::TranslateZ3D(0.25*(zMin1+zMin2+zMax1+zMax2))*rotateShape);
187  sideElementShapeVec.push_back(sideElementShape);
188  //totSideVolume += sideElementShape->volume();
189  totSideVolume += shapeVolume;
190  }
191 
192  // Make envelope
193  GeoBox * sideEnvelope = new GeoBox(0.5*sideThick+epsilon, 0.5*sideWidth-epsilon, 0.5*std::abs(zSideMax-zSideMin)+epsilon);
194  GeoLogVol * sideEnvelopeLV = new GeoLogVol("PixelFrameSideEnv", sideEnvelope, air);
195  sideEnvelopePV = new GeoPhysVol(sideEnvelopeLV);
196 
197  zSideCenter = 0.5*(zSideMin+zSideMax);
198 
199  std::string sideMatName = m_gmt_mgr->PixelFrameSideMaterial(section);
200  const GeoMaterial* sideMat = m_mat_mgr->getMaterialForVolume(sideMatName,numSides*totSideVolume);
201  for (int iElement = 0; iElement < numElements; iElement++) {
202  GeoTransform * transSideElement = new GeoTransform(GeoTrf::TranslateZ3D(-zSideCenter)*sideTransVec[iElement]);
203  std::ostringstream frameSideName;
204  frameSideName << "FrameSide" << iElement;
205  GeoLogVol * sideElementLV = new GeoLogVol(frameSideName.str(), sideElementShapeVec[iElement], sideMat);
206  GeoPhysVol * sideElementPV = new GeoPhysVol(sideElementLV);
207  sideEnvelopePV->add(transSideElement);
208  sideEnvelopePV->add(sideElementPV);
209  }
210  }
211 
213  // Put it together
215  GeoPhysVol * cornerPV = new GeoPhysVol(cornerLV);
216 
217  // place the corners and sides.
218  for (int iSide = 0; iSide<numSides; iSide++) {
219  double angleCorner = phiLoc + alpha * (2*iSide - 1);
220  GeoTransform * cornerTrans = new GeoTransform(GeoTrf::TranslateZ3D(zCenter)*GeoTrf::RotateZ3D(angleCorner));
221  // Place the corners
222  parent->add(cornerTrans);
223  parent->add(cornerPV);
224  if (sideEnvelopePV) {
225  double angleSide = phiLoc + alpha * (2*iSide);
226  GeoTrf::Transform3D oddEvenRotate(GeoTrf::Transform3D::Identity());
227  if (iSide%2 && mirrorSides) {
228  oddEvenRotate = GeoTrf::RotateZ3D(Gaudi::Units::pi); // Every 2nd side we mirror the side.
229  }
230  GeoTransform * sideTrans = new GeoTransform(GeoTrf::TranslateZ3D(zSideCenter)*GeoTrf::RotateZ3D(angleSide)
231  *GeoTrf::TranslateX3D(midRadius)*oddEvenRotate);
232 
233  // Place the sides
234  parent->add(sideTrans);
235  parent->add(sideEnvelopePV);
236  }
237  }
238 
239 }
240 
241 bool GeoPixelFrame::same(double v1, double v2)
242 {
243  const double tol = 1e-9;
244  return (std::abs(v1-v2) < tol);
245 }
246 
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
GeoPixelFrame.h
PixelGeometryManager::PixelFrameElementZMin1
virtual double PixelFrameElementZMin1(int section, int element)=0
PixelGeometryManager
Definition: PixelGeometryManager.h:28
PixelGeometryManager::PixelFrameElementZMax1
virtual double PixelFrameElementZMax1(int section, int element)=0
PixelGeometryManager::PixelFrameCornerMaterial
virtual std::string PixelFrameCornerMaterial(int section)=0
PixelGeometryManager::PixelFrameZMin
virtual double PixelFrameZMin(int section)=0
PixelAthClusterMonAlgCfg.zmin
zmin
Definition: PixelAthClusterMonAlgCfg.py:169
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
PixelGeometryManager::PixelFrameNumSides
virtual int PixelFrameNumSides(int section)=0
deg
#define deg
Definition: SbPolyhedron.cxx:17
GeoPixelFrame::BuildAndPlace
void BuildAndPlace(GeoFullPhysVol *parent, int section)
Definition: GeoPixelFrame.cxx:30
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
pi
#define pi
Definition: TileMuonFitter.cxx:65
GeoVPixelFactory::m_gmt_mgr
PixelGeometryManager * m_gmt_mgr
Definition: GeoVPixelFactory.h:43
BchCleanup.mgr
mgr
Definition: BchCleanup.py:294
PixelGeometryManager::PixelFrameElementZMin2
virtual double PixelFrameElementZMin2(int section, int element)=0
GeoPrimitives.h
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
PixelAthClusterMonAlgCfg.zmax
zmax
Definition: PixelAthClusterMonAlgCfg.py:169
test_pyathena.parent
parent
Definition: test_pyathena.py:15
PixelGeometryManager::PixelFrameRMaxSide
virtual double PixelFrameRMaxSide(int section)=0
GeoPixelFrame::same
bool same(double v1, double v2)
Definition: GeoPixelFrame.cxx:241
InDetDD::PixelDetectorManager
Definition: PixelDetectorManager.h:47
PixelGeometryManager::PixelFrameSideMaterial
virtual std::string PixelFrameSideMaterial(int section)=0
PixelGeometryManager::PixelFrameRMinSide
virtual double PixelFrameRMinSide(int section)=0
PixelGeometryManager::PixelFrameElementZMax2
virtual double PixelFrameElementZMax2(int section, int element)=0
GeoVPixelFactory::m_mat_mgr
InDetMaterialManager * m_mat_mgr
Definition: GeoVPixelFactory.h:44
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
PixelGeometryManager::PixelFrameZMax
virtual double PixelFrameZMax(int section)=0
ReadCellNoiseFromCoolCompare.v2
v2
Definition: ReadCellNoiseFromCoolCompare.py:364
PixelGeometryManager::PixelFramePhiStart
virtual double PixelFramePhiStart(int section)=0
DeMoScan.first
bool first
Definition: DeMoScan.py:536
GeoVPixelFactory
This is the base class for all the pieces of the Pixel detector.
Definition: GeoVPixelFactory.h:31
GeoPixelFrame::GeoPixelFrame
GeoPixelFrame(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)
Definition: GeoPixelFrame.cxx:22
PixelGeometryManager::PixelFrameMirrorSides
virtual bool PixelFrameMirrorSides(int sectionIndex)=0
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
section
void section(const std::string &sec)
Definition: TestTriggerMenuAccess.cxx:22
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
PixelGeometryManager::PixelFrameNumSideElements
virtual int PixelFrameNumSideElements(int section)=0
PixelGeometryManager::PixelFrameSideWidth
virtual double PixelFrameSideWidth(int section)=0