31{
40
41
42 if(numSides==0)return;
43
44 double midRadius = 0.5*(rminSide+rmaxSide);
46
47 const GeoMaterial* air =
m_mat_mgr->getMaterial(
"std::Air");
48
49
51
53
54
55
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
65
66
67
68
69
70
71
72
73
75
77
78
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
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
103
104
105
106
107
108
109
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
119
120
121
122
124 const GeoMaterial* cornerMat =
m_mat_mgr->getMaterialForVolume(cornerMatName,numSides*cornerShape->volume());
125
126 GeoLogVol * cornerLV = new GeoLogVol("FrameCorner",cornerShape,cornerMat);
127
128
130
132
133
134
135 GeoPhysVol * sideEnvelopePV = nullptr;
136 double zSideCenter = 0;
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
148 double zSideMin = 0;
149 double zSideMax = 0;
150 double totSideVolume = 0;
151 for (int iElement = 0; iElement < numElements; iElement++) {
152
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;
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
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
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
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
189 totSideVolume += shapeVolume;
190 }
191
192
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
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
215 GeoPhysVol * cornerPV = new GeoPhysVol(cornerLV);
216
217
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
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);
229 }
230 GeoTransform * sideTrans = new GeoTransform(GeoTrf::TranslateZ3D(zSideCenter)*GeoTrf::RotateZ3D(angleSide)
231 *GeoTrf::TranslateX3D(midRadius)*oddEvenRotate);
232
233
235 parent->add(sideEnvelopePV);
236 }
237 }
238
239}
bool same(double v1, double v2)
PixelGeometryManager * m_gmt_mgr
InDetMaterialManager * m_mat_mgr