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"
24 std::shared_ptr<std::map<std::string, GeoFullPhysVol*>> mapFPV,
25 std::shared_ptr<std::map<std::string, GeoAlignableTransform*>> mapAX)
42 if(numSides==0)
return;
44 double midRadius = 0.5*(rminSide+rmaxSide);
57 double halflength = 0.5*std::abs(
zmax -
zmin);
60 double cosalpha =
cos(alpha);
61 double sinalpha =
sin(alpha);
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;
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;
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);
126 GeoLogVol * cornerLV =
new GeoLogVol(
"FrameCorner",cornerShape,cornerMat);
135 GeoPhysVol * sideEnvelopePV =
nullptr;
136 double zSideCenter = 0;
140 double sideThick = rmaxSide - rminSide;
142 std::vector<GeoTrf::Transform3D> sideTransVec;
143 std::vector<GeoShape *> sideElementShapeVec;
144 sideTransVec.reserve(numElements);
145 sideElementShapeVec.reserve(numElements);
150 double totSideVolume = 0;
151 for (
int iElement = 0; iElement < numElements; iElement++) {
160 zSideMin = zminInput;
161 zSideMax = zmaxInput;
164 zSideMin =
std::min(zSideMin, zminInput);
165 zSideMax =
std::max(zSideMax, zmaxInput);
167 GeoShape * sideElementShape =
nullptr;
169 double shapeVolume = 0;
170 if (
same(zMin1,zMin2) &&
same(zMax1,zMax2)) {
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)) {
176 double alphaPara = atan2(zMin2-zMin1,sideWidth);
177 double thetaPara = 0;
179 sideElementShape =
new GeoPara(0.5*std::abs(zMax1-zMin1), 0.5*sideWidth-epsilon, 0.5*sideThick, alphaPara, thetaPara, phiPara);
181 shapeVolume = std::abs(zMax1-zMin1) * (sideWidth-2*epsilon) * sideThick;
184 std::cout <<
"GeoPixelFrame: This case is not handled for building the frame" << std::endl;
186 sideTransVec.push_back(GeoTrf::TranslateZ3D(0.25*(zMin1+zMin2+zMax1+zMax2))*rotateShape);
187 sideElementShapeVec.push_back(sideElementShape);
189 totSideVolume += shapeVolume;
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);
197 zSideCenter = 0.5*(zSideMin+zSideMax);
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);
215 GeoPhysVol * cornerPV =
new GeoPhysVol(cornerLV);
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));
224 if (sideEnvelopePV) {
225 double angleSide = phiLoc + alpha * (2*iSide);
227 if (iSide%2 && mirrorSides) {
230 GeoTransform * sideTrans =
new GeoTransform(GeoTrf::TranslateZ3D(zSideCenter)*GeoTrf::RotateZ3D(angleSide)
231 *GeoTrf::TranslateX3D(midRadius)*oddEvenRotate);
235 parent->add(sideEnvelopePV);
243 const double tol = 1
e-9;
244 return (std::abs(v1-
v2) < tol);