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"
23 std::shared_ptr<std::map<std::string, GeoFullPhysVol*>> mapFPV,
24 std::shared_ptr<std::map<std::string, GeoAlignableTransform*>> mapAX)
41 if(numSides==0)
return;
43 double midRadius = 0.5*(rminSide+rmaxSide);
56 double halflength = 0.5*std::abs(
zmax -
zmin);
59 double cosalpha =
cos(alpha);
60 double sinalpha =
sin(alpha);
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;
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;
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);
125 GeoLogVol * cornerLV =
new GeoLogVol(
"FrameCorner",cornerShape,cornerMat);
134 GeoPhysVol * sideEnvelopePV =
nullptr;
135 double zSideCenter = 0;
139 double sideThick = rmaxSide - rminSide;
141 std::vector<GeoTrf::Transform3D> sideTransVec;
142 std::vector<GeoShape *> sideElementShapeVec;
143 sideTransVec.reserve(numElements);
144 sideElementShapeVec.reserve(numElements);
149 double totSideVolume = 0;
150 for (
int iElement = 0; iElement < numElements; iElement++) {
159 zSideMin = zminInput;
160 zSideMax = zmaxInput;
163 zSideMin =
std::min(zSideMin, zminInput);
164 zSideMax =
std::max(zSideMax, zmaxInput);
166 GeoShape * sideElementShape =
nullptr;
168 double shapeVolume = 0;
169 if (
same(zMin1,zMin2) &&
same(zMax1,zMax2)) {
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)) {
175 double alphaPara = atan2(zMin2-zMin1,sideWidth);
176 double thetaPara = 0;
178 sideElementShape =
new GeoPara(0.5*std::abs(zMax1-zMin1), 0.5*sideWidth-epsilon, 0.5*sideThick, alphaPara, thetaPara, phiPara);
180 shapeVolume = std::abs(zMax1-zMin1) * (sideWidth-2*epsilon) * sideThick;
183 std::cout <<
"GeoPixelFrame: This case is not handled for building the frame" << std::endl;
185 sideTransVec.push_back(GeoTrf::TranslateZ3D(0.25*(zMin1+zMin2+zMax1+zMax2))*rotateShape);
186 sideElementShapeVec.push_back(sideElementShape);
188 totSideVolume += shapeVolume;
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);
196 zSideCenter = 0.5*(zSideMin+zSideMax);
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);
214 GeoPhysVol * cornerPV =
new GeoPhysVol(cornerLV);
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));
223 if (sideEnvelopePV) {
224 double angleSide = phiLoc + alpha * (2*iSide);
226 if (iSide%2 && mirrorSides) {
229 GeoTransform * sideTrans =
new GeoTransform(GeoTrf::TranslateZ3D(zSideCenter)*GeoTrf::RotateZ3D(angleSide)
230 *GeoTrf::TranslateX3D(midRadius)*oddEvenRotate);
234 parent->add(sideEnvelopePV);
242 const double tol = 1
e-9;
243 return (std::abs(v1-
v2) < tol);