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