Belle II Software development
GeometryData.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9/* Own header. */
10#include <klm/eklm/geometry/GeometryData.h>
11
12/* KLM headers. */
13#include <klm/eklm/geometry/Circle2D.h>
14#include <klm/eklm/geometry/Line2D.h>
15
16/* Basf2 headers. */
17#include <framework/database/DBObjPtr.h>
18#include <framework/database/Database.h>
19#include <framework/logging/Logger.h>
20
21/* CLHEP headers. */
22#include <CLHEP/Geometry/Point3D.h>
23#include <CLHEP/Units/SystemOfUnits.h>
24
25/* C++ headers. */
26#include <string>
27
28using namespace Belle2;
29
30static const char c_MemErr[] = "Memory allocation error.";
31
33EKLM::GeometryData::Instance(enum DataSource dataSource, const GearDir* gearDir)
34{
35 static EKLM::GeometryData gd(dataSource, gearDir);
36 return gd;
37}
38
44static void readPositionData(EKLMGeometry::ElementPosition* epos, GearDir* gd)
45{
46 epos->setX(gd->getLength("X") * CLHEP::cm);
47 epos->setY(gd->getLength("Y") * CLHEP::cm);
48 epos->setZ(gd->getLength("Z") * CLHEP::cm);
49}
50
56static void readSizeData(EKLMGeometry::ElementPosition* epos, GearDir* gd)
57{
58 epos->setInnerR(gd->getLength("InnerR") * CLHEP::cm);
59 epos->setOuterR(gd->getLength("OuterR") * CLHEP::cm);
60 epos->setLength(gd->getLength("Length") * CLHEP::cm);
61}
62
68static void readSectorSupportGeometry(
70{
71 ssg->setThickness(gd->getLength("Thickness") * CLHEP::cm);
72 ssg->setDeltaLY(gd->getLength("DeltaLY") * CLHEP::cm);
73 ssg->setCornerX(gd->getLength("CornerX") * CLHEP::cm);
74 ssg->setCorner1LX(gd->getLength("Corner1LX") * CLHEP::cm);
75 ssg->setCorner1Width(gd->getLength("Corner1Width") * CLHEP::cm);
76 ssg->setCorner1Thickness(gd->getLength("Corner1Thickness") * CLHEP::cm);
77 ssg->setCorner1Z(gd->getLength("Corner1Z") * CLHEP::cm);
78 ssg->setCorner2LX(gd->getLength("Corner2LX") * CLHEP::cm);
79 ssg->setCorner2LY(gd->getLength("Corner2LY") * CLHEP::cm);
80 ssg->setCorner2Thickness(gd->getLength("Corner2Thickness") * CLHEP::cm);
81 ssg->setCorner2Z(gd->getLength("Corner2Z") * CLHEP::cm);
82 ssg->setCorner3LX(gd->getLength("Corner3LX") * CLHEP::cm);
83 ssg->setCorner3LY(gd->getLength("Corner3LY") * CLHEP::cm);
84 ssg->setCorner3Thickness(gd->getLength("Corner3Thickness") * CLHEP::cm);
85 ssg->setCorner3Z(gd->getLength("Corner3Z") * CLHEP::cm);
86 ssg->setCorner4LX(gd->getLength("Corner4LX") * CLHEP::cm);
87 ssg->setCorner4LY(gd->getLength("Corner4LY") * CLHEP::cm);
88 ssg->setCorner4Thickness(gd->getLength("Corner4Thickness") * CLHEP::cm);
89 ssg->setCorner4Z(gd->getLength("Corner4Z") * CLHEP::cm);
90}
91
97static void readShieldDetailGeometry(
99{
100 int i, n;
101 std::string name;
103 sdg->setLengthX(gd->getLength("LengthX") * CLHEP::cm);
104 sdg->setLengthY(gd->getLength("LengthY") * CLHEP::cm);
105 n = gd->getNumberNodes("Point");
106 sdg->setNPoints(n);
107 for (i = 0; i < n; i++) {
108 GearDir point(*gd);
109 name = "/Point[" + std::to_string(i + 1) + "]";
110 point.append(name);
111 p.setX(point.getLength("X") * CLHEP::cm);
112 p.setY(point.getLength("Y") * CLHEP::cm);
113 sdg->setPoint(i, p);
114 }
115}
116
118{
120 Line2D line23Outer(0, m_SectorSupportPosition.getY(), 1, 0);
121 Line2D line23Inner(0, m_SectorSupportPosition.getY() +
122 m_SectorSupportGeometry.getThickness(), 1, 0);
123 Line2D line23Prism(0, m_SectorSupportPosition.getY() +
124 m_SectorSupportGeometry.getThickness() +
125 m_SectorSupportGeometry.getCorner3LY(), 1, 0);
126 Line2D line41Outer(m_SectorSupportPosition.getX(), 0, 0, 1);
127 Line2D line41Inner(m_SectorSupportPosition.getX() +
128 m_SectorSupportGeometry.getThickness(), 0, 0, 1);
129 Line2D line41Prism(m_SectorSupportPosition.getX() +
130 m_SectorSupportGeometry.getThickness() +
131 m_SectorSupportGeometry.getCorner4LX(), 0, 0, 1);
132 Line2D line41Corner1B(m_SectorSupportPosition.getX() +
133 m_SectorSupportGeometry.getCornerX(), 0, 0, 1);
134 Circle2D circleInnerOuter(0, 0, m_SectorSupportPosition.getInnerR());
135 Circle2D circleInnerInner(0, 0, m_SectorSupportPosition.getInnerR() +
136 m_SectorSupportGeometry.getThickness());
137 Circle2D circleOuterInner(0, 0, m_SectorSupportPosition.getOuterR() -
138 m_SectorSupportGeometry.getThickness());
139 Circle2D circleOuterOuter(0, 0, m_SectorSupportPosition.getOuterR());
140 HepGeom::Point3D<double> intersections[2];
141 /* Corner 1. */
142 p.setX(m_SectorSupportPosition.getX());
143 p.setY(m_SectorSupportPosition.getOuterR() -
144 m_SectorSupportGeometry.getDeltaLY());
145 p.setZ(0);
146 m_SectorSupportGeometry.setCorner1A(p);
147 line41Corner1B.findIntersection(circleOuterOuter, intersections);
148 m_SectorSupportGeometry.setCorner1B(intersections[1]);
149 m_SectorSupportGeometry.setCornerAngle(
150 atan2(m_SectorSupportGeometry.getCorner1B().y() -
151 m_SectorSupportGeometry.getCorner1A().y(),
152 m_SectorSupportGeometry.getCorner1B().x() -
153 m_SectorSupportGeometry.getCorner1A().x()) * CLHEP::rad);
154 p.setX(m_SectorSupportPosition.getX() +
155 m_SectorSupportGeometry.getThickness());
156 p.setY(m_SectorSupportGeometry.getCorner1A().y() -
157 m_SectorSupportGeometry.getThickness() *
158 (1.0 / cos(m_SectorSupportGeometry.getCornerAngle()) -
159 tan(m_SectorSupportGeometry.getCornerAngle())));
160 p.setZ(0);
161 m_SectorSupportGeometry.setCorner1AInner(p);
162 Line2D lineCorner1(m_SectorSupportGeometry.getCorner1AInner().x(),
163 m_SectorSupportGeometry.getCorner1AInner().y(),
164 m_SectorSupportGeometry.getCorner1B().x() -
165 m_SectorSupportGeometry.getCorner1A().x(),
166 m_SectorSupportGeometry.getCorner1B().y() -
167 m_SectorSupportGeometry.getCorner1A().y());
168 lineCorner1.findIntersection(circleOuterInner, intersections);
169 m_SectorSupportGeometry.setCorner1BInner(intersections[1]);
170 /* Corner 2. */
171 line23Inner.findIntersection(circleOuterInner, intersections);
172 m_SectorSupportGeometry.setCorner2Inner(intersections[1]);
173 /* Corner 3. */
174 line23Outer.findIntersection(circleInnerOuter, intersections);
175 m_SectorSupportGeometry.setCorner3(intersections[1]);
176 line23Inner.findIntersection(circleInnerInner, intersections);
177 m_SectorSupportGeometry.setCorner3Inner(intersections[1]);
178 line23Prism.findIntersection(circleInnerInner, intersections);
179 p.setX(intersections[1].x());
180 p.setY(m_SectorSupportPosition.getY() +
181 m_SectorSupportGeometry.getThickness());
182 p.setZ(0);
183 m_SectorSupportGeometry.setCorner3Prism(p);
184 /* Corner 4. */
185 line41Outer.findIntersection(circleInnerOuter, intersections);
186 m_SectorSupportGeometry.setCorner4(intersections[1]);
187 line41Inner.findIntersection(circleInnerInner, intersections);
188 m_SectorSupportGeometry.setCorner4Inner(intersections[1]);
189 line41Prism.findIntersection(circleInnerInner, intersections);
190 p.setX(m_SectorSupportPosition.getX() +
191 m_SectorSupportGeometry.getThickness());
192 p.setY(intersections[1].y());
193 p.setZ(0);
194 m_SectorSupportGeometry.setCorner4Prism(p);
195}
196
197static bool compareLength(double a, double b)
198{
199 return a < b;
200}
201
203{
204 const char err[] = "Strip sorting algorithm error.";
205 int i;
206 double l;
207 std::vector<double> strips;
208 std::vector<double>::iterator it;
209 std::map<double, int> mapLengthStrip;
210 std::map<double, int> mapLengthStrip2;
211 std::map<double, int>::iterator itm;
212 for (i = 0; i < m_NStrips; i++) {
213 strips.push_back(m_StripPosition[i].getLength());
214 mapLengthStrip.insert(
215 std::pair<double, int>(m_StripPosition[i].getLength(), i));
216 }
217 sort(strips.begin(), strips.end(), compareLength);
218 l = strips[0];
219 m_nStripDifferent = 1;
220 for (it = strips.begin(); it != strips.end(); ++it) {
221 if ((*it) != l) {
222 l = (*it);
223 m_nStripDifferent++;
224 }
225 }
226 m_StripLenToAll = (int*)malloc(m_nStripDifferent * sizeof(int));
227 if (m_StripLenToAll == nullptr)
228 B2FATAL(c_MemErr);
229 i = 0;
230 l = strips[0];
231 itm = mapLengthStrip.find(l);
232 if (itm == mapLengthStrip.end())
233 B2FATAL(err);
234 m_StripLenToAll[i] = itm->second;
235 mapLengthStrip2.insert(std::pair<double, int>(l, i));
236 for (it = strips.begin(); it != strips.end(); ++it) {
237 if ((*it) != l) {
238 l = (*it);
239 i++;
240 itm = mapLengthStrip.find(l);
241 if (itm == mapLengthStrip.end())
242 B2FATAL(err);
243 m_StripLenToAll[i] = itm->second;
244 mapLengthStrip2.insert(std::pair<double, int>(l, i));
245 }
246 }
247 m_StripAllToLen = (int*)malloc(m_NStrips * sizeof(int));
248 if (m_StripAllToLen == nullptr)
249 B2FATAL(c_MemErr);
250 for (i = 0; i < m_NStrips; i++) {
251 itm = mapLengthStrip2.find(m_StripPosition[i].getLength());
252 if (itm == mapLengthStrip2.end())
253 B2FATAL(err);
254 m_StripAllToLen[i] = itm->second;
255 }
256}
257
259{
260 int i;
261 std::string name;
262 GearDir Strips(gd);
263 Strips.append("/Strip");
264 m_StripGeometry.setWidth(Strips.getLength("Width") * CLHEP::cm);
265 m_StripGeometry.setThickness(Strips.getLength("Thickness") * CLHEP::cm);
266 m_StripGeometry.setGrooveDepth(Strips.getLength("GrooveDepth") * CLHEP::cm);
267 m_StripGeometry.setGrooveWidth(Strips.getLength("GrooveWidth") * CLHEP::cm);
268 m_StripGeometry.setNoScintillationThickness(
269 Strips.getLength("NoScintillationThickness") * CLHEP::cm);
270 m_StripGeometry.setRSSSize(Strips.getLength("RSSSize") * CLHEP::cm);
271 try {
272 m_StripPosition = new EKLMGeometry::ElementPosition[m_NStrips];
273 } catch (std::bad_alloc& ba) {
274 B2FATAL(c_MemErr);
275 }
276 for (i = 0; i < m_NStrips; i++) {
277 GearDir StripContent(Strips);
278 name = "/Strip[" + std::to_string(i + 1) + "]";
279 StripContent.append(name);
280 m_StripPosition[i].setLength(StripContent.getLength("Length") * CLHEP::cm);
281 m_StripPosition[i].setX(StripContent.getLength("X") * CLHEP::cm);
282 m_StripPosition[i].setY(StripContent.getLength("Y") * CLHEP::cm);
283 m_StripPosition[i].setZ(StripContent.getLength("Z") * CLHEP::cm);
284 }
285}
286
297static void getDetailDxDy(HepGeom::Point3D<double>* points, int nPoints,
298 double r, double kx, double ky,
299 double& dx, double& dy)
300{
301 int i;
302 /* Variable maxt is initialized to avoid a false-positive warning. */
303 /* cppcheck-suppress variableScope */
304 double a, b, c, d, t, maxt = 0, x1, y1, x2, y2, u;
305 bool intersection;
306 /*
307 * Contact by one of the detail points.
308 * Solve equation (x1 + kx * t)^2 + (y1 + ky * t)^2 = R^2,
309 * (kx^2 + ky^2) * t^2 + 2 * (kx * x1 + ky * y1) * t + x1^2 + y1^2 - r^2 = 0.
310 */
311 a = kx * kx + ky * ky;
312 intersection = false;
313 for (i = 0; i < nPoints; i++) {
314 x1 = points[i].x();
315 y1 = points[i].y();
316 b = 2.0 * (kx * x1 + ky * y1);
317 c = x1 * x1 + y1 * y1 - r * r;
318 d = b * b - 4.0 * a * c;
319 if (d >= 0) {
320 t = (-b + sqrt(d)) / (2.0 * a);
321 if (!intersection) {
322 intersection = true;
323 maxt = t;
324 } else {
325 if (t > maxt)
326 maxt = t;
327 }
328 }
329 }
330 if (!intersection)
331 B2FATAL("Shield layer geometry calculation error.");
332 /*
333 * Contact by one of the detail lines.
334 * Find t such as the equation
335 * (x1 + kx * t + (x2 - x1) * u)^2 + (y1 + ky * t + (y2 - y1) * u) = r^2
336 * has one solution relatively to u. Equation on t is
337 * 0 = ((x2 - x1) * (x1 + kx * t) + (y2 - y1) * (y1 + ky * t))^2 +
338 * ((x2 - x1)^2 + (y2 - y1)^2) * ((x1 + kx * t)^2 + (y1 + ky * t)^2 - r^2),
339 * t = (x1 * y2 - x2 * y1 +- r * sqrt((x2 - x1)^2 + (y2 - y1)^2)) /
340 * ((x2 - x1) * ky - (y2 - y1) * kx).
341 */
342 for (i = 0; i < nPoints; i++) {
343 x1 = points[i].x();
344 y1 = points[i].y();
345 if (i < nPoints - 1) {
346 x2 = points[i + 1].x();
347 y2 = points[i + 1].y();
348 } else {
349 x2 = points[0].x();
350 y2 = points[0].y();
351 }
352 a = (x2 - x1) * ky - (y2 - y1) * kx;
353 if (a == 0)
354 continue;
355 b = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
356 t = (x1 * y2 - x2 * y1 + r * sqrt(b)) / a;
357 /*
358 * Check whether intersection occurs between the translated points
359 * (x1 + kx * t, y1 + ky * t) and (x2 + kx * t, y2 + ky * t).
360 * (find solition of the original equation relatively to u for that).
361 */
362 u = -((x2 - x1) * (x1 + kx * t) + (y2 - y1) * (y2 + ky * t)) / b;
363 if (u < 0 || u > 1)
364 continue;
365 if (t > maxt)
366 maxt = t;
367 }
368 dx = kx * maxt;
369 dy = ky * maxt;
370}
371
377static void EKLMPointToCLHEP(const EKLMGeometry::Point* pointEKLM,
378 HepGeom::Point3D<double>& pointCLHEP)
379{
380 pointCLHEP.setX(pointEKLM->getX());
381 pointCLHEP.setY(pointEKLM->getY());
382 pointCLHEP.setZ(0);
383}
384
386{
387 int i;
388 double r, l, dx, dy, xCenter, yCenter;
389 const double asqrt2 = 1.0 / sqrt(2.0);
390 HepGeom::Point3D<double> points[8];
391 const ShieldDetailGeometry* detailA = m_ShieldGeometry.getDetailA();
392 const ShieldDetailGeometry* detailB = m_ShieldGeometry.getDetailB();
393 const ShieldDetailGeometry* detailC = m_ShieldGeometry.getDetailC();
394 const ShieldDetailGeometry* detailD = m_ShieldGeometry.getDetailD();
395 r = m_SectorSupportPosition.getInnerR() +
396 m_SectorSupportGeometry.getThickness();
397 /* Detail A. */
398 EKLMPointToCLHEP(detailA->getPoint(0), points[0]);
399 EKLMPointToCLHEP(detailA->getPoint(1), points[1]);
400 EKLMPointToCLHEP(detailA->getPoint(2), points[2]);
401 EKLMPointToCLHEP(detailA->getPoint(3), points[3]);
402 EKLMPointToCLHEP(detailA->getPoint(4), points[4]);
403 points[5].setX(detailA->getLengthX());
404 points[5].setY(detailA->getLengthY());
405 points[5].setZ(0);
406 EKLMPointToCLHEP(detailA->getPoint(5), points[6]);
407 EKLMPointToCLHEP(detailA->getPoint(6), points[7]);
408 l = 0.5 * (detailA->getLengthX() + detailB->getLengthX());
409 xCenter = -asqrt2 * l;
410 yCenter = asqrt2 * l;
411 for (i = 0; i < 8; i++)
412 points[i] = HepGeom::Translate3D(xCenter, yCenter, 0) *
413 HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
414 HepGeom::Translate3D(-detailA->getLengthX() / 2,
415 -detailA->getLengthY() / 2, 0) *
416 points[i];
417 getDetailDxDy(points, 8, r, 1, 1, dx, dy);
418 m_ShieldGeometry.setDetailACenter(xCenter + dx, yCenter + dy);
419 /* Details B, D, E. */
420 points[0].setX(0);
421 points[0].setY(-detailD->getLengthY());
422 points[0].setZ(0);
423 points[1].setX(detailD->getLengthX());
424 points[1].setY(0);
425 points[1].setZ(0);
426 points[2].setX(detailB->getLengthX() - detailD->getLengthX());
427 points[2].setY(0);
428 points[2].setZ(0);
429 points[3].setX(detailB->getLengthX());
430 points[3].setY(-detailD->getLengthY());
431 points[3].setZ(0);
432 EKLMPointToCLHEP(detailB->getPoint(0), points[4]);
433 EKLMPointToCLHEP(detailB->getPoint(1), points[5]);
434 EKLMPointToCLHEP(detailB->getPoint(2), points[6]);
435 EKLMPointToCLHEP(detailB->getPoint(3), points[7]);
436 /* Detail B center coordinates before its shift are (0, 0). */
437 for (i = 0; i < 8; i++)
438 points[i] = HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
439 HepGeom::Translate3D(-detailB->getLengthX() / 2,
440 -detailB->getLengthY() / 2, 0) *
441 points[i];
442 getDetailDxDy(points, 8, r, 1, 1, dx, dy);
443 m_ShieldGeometry.setDetailBCenter(dx, dy);
444 /* Detail C. */
445 EKLMPointToCLHEP(detailC->getPoint(0), points[0]);
446 EKLMPointToCLHEP(detailC->getPoint(1), points[1]);
447 EKLMPointToCLHEP(detailC->getPoint(2), points[2]);
448 EKLMPointToCLHEP(detailC->getPoint(3), points[3]);
449 EKLMPointToCLHEP(detailC->getPoint(4), points[4]);
450 points[5].setX(detailC->getLengthX());
451 points[5].setY(detailC->getLengthY());
452 points[5].setZ(0);
453 EKLMPointToCLHEP(detailC->getPoint(5), points[6]);
454 EKLMPointToCLHEP(detailC->getPoint(6), points[7]);
455 l = 0.5 * (detailB->getLengthX() + detailC->getLengthX());
456 xCenter = asqrt2 * l;
457 yCenter = -asqrt2 * l;
458 for (i = 0; i < 8; i++)
459 points[i] = HepGeom::Translate3D(xCenter, yCenter, 0) *
460 HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
461 HepGeom::RotateY3D(180.0 * CLHEP::deg) *
462 HepGeom::Translate3D(-detailC->getLengthX() / 2,
463 -detailC->getLengthY() / 2, 0) *
464 points[i];
465 getDetailDxDy(points, 8, r, 1, 1, dx, dy);
466 m_ShieldGeometry.setDetailCCenter(xCenter + dx, yCenter + dy);
467}
468
470{
471 GearDir d(gd);
472 d.append("/EndcapStructure");
473 m_EndcapStructureGeometry.setPhi(d.getAngle("Phi") * CLHEP::rad);
474 m_EndcapStructureGeometry.setNSides(d.getInt("NSides"));
475}
476
478{
479 int i, j, k;
480 std::string name;
481 ShieldDetailGeometry shieldDetailGeometry;
482 GearDir gd(*gearDir);
483 gd.append("/EKLM");
484 /* Beam-background study. */
485 m_BeamBackgroundStudy = gd.getBool("BeamBackgroundStudy");
486 /* Numbers of elements. */
487 m_NSections = gd.getInt("NSections");
488 m_ElementNumbers->checkSection(m_NSections);
489 m_NLayers = gd.getInt("NLayers");
490 m_ElementNumbers->checkLayer(m_NLayers);
491 m_NDetectorLayers = new int[m_NSections];
492 m_NDetectorLayers[0] = gd.getInt("NDetectorLayersBackward");
493 checkDetectorLayerNumber(1, m_NDetectorLayers[0]);
494 if (m_NSections == 2) {
495 m_NDetectorLayers[1] = gd.getInt("NDetectorLayersForward");
496 checkDetectorLayerNumber(2, m_NDetectorLayers[1]);
497 }
498 m_NSectors = gd.getInt("NSectors");
499 m_ElementNumbers->checkSector(m_NSectors);
500 m_NPlanes = gd.getInt("NPlanes");
501 m_ElementNumbers->checkPlane(m_NPlanes);
502 m_NSegments = gd.getInt("NSegments");
503 m_ElementNumbers->checkSegment(m_NSegments);
504 m_NSegmentSupportElementsSector = (m_NSegments + 1) * m_NPlanes;
505 m_NStrips = gd.getInt("NStrips");
506 m_ElementNumbers->checkStrip(m_NStrips);
507 /* Geometry parameters. */
508 m_SolenoidZ = gd.getLength("SolenoidZ") * CLHEP::cm;
509 readEndcapStructureGeometry(gd);
510 GearDir section(gd);
511 section.append("/Section");
512 readPositionData(&m_SectionPosition, &section);
513 readSizeData(&m_SectionPosition, &section);
514 GearDir layer(gd);
515 layer.append("/Layer");
516 readSizeData(&m_LayerPosition, &layer);
517 m_LayerShiftZ = layer.getLength("ShiftZ") * CLHEP::cm;
518 GearDir sector(gd);
519 sector.append("/Sector");
520 readSizeData(&m_SectorPosition, &sector);
521 GearDir sectorSupport(gd);
522 sectorSupport.append("/SectorSupport");
523 readPositionData(&m_SectorSupportPosition, &sectorSupport);
524 readSizeData(&m_SectorSupportPosition, &sectorSupport);
525 readSectorSupportGeometry(&m_SectorSupportGeometry, &sectorSupport);
526 GearDir plane(gd);
527 plane.append("/Plane");
528 readPositionData(&m_PlanePosition, &plane);
529 readSizeData(&m_PlanePosition, &plane);
530 GearDir plasticSheet(gd);
531 plasticSheet.append("/PlasticSheet");
532 m_PlasticSheetGeometry.setWidth(plasticSheet.getLength("Width") * CLHEP::cm);
533 m_PlasticSheetGeometry.setDeltaL(plasticSheet.getLength("DeltaL") *
534 CLHEP::cm);
535 GearDir segmentSupport(gd);
536 segmentSupport.append("/SegmentSupport");
537 m_SegmentSupportGeometry.setTopWidth(
538 segmentSupport.getLength("TopWidth") * CLHEP::cm);
539 m_SegmentSupportGeometry.setTopThickness(
540 segmentSupport.getLength("TopThickness") * CLHEP::cm);
541 m_SegmentSupportGeometry.setMiddleWidth(
542 segmentSupport.getLength("MiddleWidth") * CLHEP::cm);
543 m_SegmentSupportGeometry.setMiddleThickness(
544 segmentSupport.getLength("MiddleThickness") * CLHEP::cm);
545 try {
546 m_SegmentSupportPosition =
547 new EKLMGeometry::SegmentSupportPosition[m_NSegmentSupportElementsSector];
548 } catch (std::bad_alloc& ba) {
549 B2FATAL(c_MemErr);
550 }
551 for (j = 0; j < m_NPlanes; j++) {
552 for (i = 0; i <= m_NSegments; i++) {
553 k = j * (m_NSegments + 1) + i;
554 GearDir segmentSupport2(segmentSupport);
555 name = "/SegmentSupportPlane[" + std::to_string(j + 1) + "]";
556 segmentSupport2.append(name);
557 name = "/SegmentSupport[" + std::to_string(i + 1) + "]";
558 segmentSupport2.append(name);
559 m_SegmentSupportPosition[k].setLength(
560 segmentSupport2.getLength("Length") * CLHEP::cm);
561 m_SegmentSupportPosition[k].setX(
562 segmentSupport2.getLength("X") * CLHEP::cm);
563 m_SegmentSupportPosition[k].setY(
564 segmentSupport2.getLength("Y") * CLHEP::cm);
565 m_SegmentSupportPosition[k].setZ(
566 segmentSupport2.getLength("Z") * CLHEP::cm);
567 m_SegmentSupportPosition[k].setDeltaLRight(
568 segmentSupport2.getLength("DeltaLRight") * CLHEP::cm);
569 m_SegmentSupportPosition[k].setDeltaLLeft(
570 segmentSupport2.getLength("DeltaLLeft") * CLHEP::cm);
571 }
572 }
573 readXMLDataStrips(gd);
574 GearDir shield(gd);
575 shield.append("/Shield");
576 m_ShieldGeometry.setThickness(shield.getLength("Thickness") * CLHEP::cm);
577 GearDir shieldDetailA(shield);
578 shieldDetailA.append("/Detail[@id=\"A\"]");
579 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailA);
580 m_ShieldGeometry.setDetailA(shieldDetailGeometry);
581 GearDir shieldDetailB(shield);
582 shieldDetailB.append("/Detail[@id=\"B\"]");
583 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailB);
584 m_ShieldGeometry.setDetailB(shieldDetailGeometry);
585 GearDir shieldDetailC(shield);
586 shieldDetailC.append("/Detail[@id=\"C\"]");
587 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailC);
588 m_ShieldGeometry.setDetailC(shieldDetailGeometry);
589 GearDir shieldDetailD(shield);
590 shieldDetailD.append("/Detail[@id=\"D\"]");
591 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailD);
592 m_ShieldGeometry.setDetailD(shieldDetailGeometry);
593 m_Geometry = new EKLMGeometry(*this);
594}
595
597{
598 DBObjPtr<EKLMGeometry> eklmGeometry;
599 if (!eklmGeometry.isValid())
600 B2FATAL("No EKLM geometry data in the database.");
601 EKLMGeometry::operator=(*eklmGeometry);
602 m_Geometry = new EKLMGeometry(*this);
603}
604
606 const GearDir* gearDir)
607{
608 m_Geometry = nullptr;
609 switch (dataSource) {
610 case c_Gearbox:
611 initializeFromGearbox(gearDir);
612 break;
613 case c_Database:
614 initializeFromDatabase();
615 break;
616 }
617 m_MinZForward = m_SolenoidZ + m_SectionPosition.getZ() -
618 0.5 * m_SectionPosition.getLength();
619 m_MaxZBackward = m_SolenoidZ - m_SectionPosition.getZ() +
620 0.5 * m_SectionPosition.getLength();
621 calculateSectorSupportGeometry();
622 fillStripIndexArrays();
623 calculateShieldGeometry();
624}
625
627{
628 if (m_Geometry != nullptr)
629 delete m_Geometry;
630 free(m_StripLenToAll);
631 free(m_StripAllToLen);
632}
633
635{
636 Database::Instance().storeData("EKLMGeometry", m_Geometry, iov);
637}
638
640{
641 double zMm;
642 zMm = z / Unit::cm * CLHEP::cm;
643 return (zMm > m_MinZForward) || (zMm < m_MaxZBackward);
644}
645
646/*
647 * Note that numbers of elements are 0-based for all transformation functions.
648 */
649void
650EKLM::GeometryData::getSectionTransform(HepGeom::Transform3D* t, int n) const
651{
652 if (n == 0)
653 *t = HepGeom::Translate3D(m_SectionPosition.getX(), m_SectionPosition.getY(),
654 -m_SectionPosition.getZ() + m_SolenoidZ);
655 else
656 *t = HepGeom::Translate3D(m_SectionPosition.getX(), m_SectionPosition.getY(),
657 m_SectionPosition.getZ() + m_SolenoidZ) *
658 HepGeom::RotateY3D(180.*CLHEP::deg);
659}
660
661void
662EKLM::GeometryData::getLayerTransform(HepGeom::Transform3D* t, int n) const
663{
664 *t = HepGeom::Translate3D(0.0, 0.0, m_SectionPosition.getLength() / 2.0 -
665 (n + 1) * m_LayerShiftZ +
666 0.5 * m_LayerPosition.getLength());
667}
668
669void
670EKLM::GeometryData::getSectorTransform(HepGeom::Transform3D* t, int n) const
671{
672 switch (n) {
673 case 0:
674 *t = HepGeom::Translate3D(0., 0., 0.);
675 break;
676 case 1:
677 *t = HepGeom::RotateY3D(180.0 * CLHEP::deg);
678 break;
679 case 2:
680 *t = HepGeom::RotateZ3D(90.0 * CLHEP::deg) *
681 HepGeom::RotateY3D(180.0 * CLHEP::deg);
682 break;
683 case 3:
684 *t = HepGeom::RotateZ3D(-90.0 * CLHEP::deg);
685 break;
686 }
687}
688
689void
690EKLM::GeometryData::getPlaneTransform(HepGeom::Transform3D* t, int n) const
691{
692 if (n == 0)
693 *t = HepGeom::Translate3D(m_PlanePosition.getX(), m_PlanePosition.getY(),
694 m_PlanePosition.getZ()) *
695 HepGeom::Rotate3D(180. * CLHEP::deg,
696 HepGeom::Vector3D<double>(1., 1., 0.));
697 else
698 *t = HepGeom::Translate3D(m_PlanePosition.getX(), m_PlanePosition.getY(),
699 -m_PlanePosition.getZ());
700}
701
702void
703EKLM::GeometryData::getStripTransform(HepGeom::Transform3D* t, int n) const
704{
705 *t = HepGeom::Translate3D(m_StripPosition[n].getX(),
706 m_StripPosition[n].getY(), 0.0);
707}
708
709void
710EKLM::GeometryData::getSheetTransform(HepGeom::Transform3D* t, int n) const
711{
712 double y;
713 y = m_StripPosition[n].getY();
714 if (n % m_ElementNumbers->getNStripsSegment() == 0)
715 y = y + 0.5 * m_PlasticSheetGeometry.getDeltaL();
716 else if (n % m_ElementNumbers->getNStripsSegment() ==
717 m_ElementNumbers->getNStripsSegment() - 1)
718 y = y - 0.5 * m_PlasticSheetGeometry.getDeltaL();
719 *t = HepGeom::Translate3D(m_StripPosition[n].getX(), y, 0.0);
720}
721
bool isValid() const
Check whether a valid object was obtained from the database.
Class for accessing objects in the database.
Definition: DBObjPtr.h:21
Position information for the elements of detector.
Definition: EKLMGeometry.h:100
void setInnerR(double innerR)
Set inner radius.
Definition: EKLMGeometry.h:121
void setOuterR(double outerR)
Set outer radius.
Definition: EKLMGeometry.h:138
void setZ(double z)
Set Z coordinate.
Definition: EKLMGeometry.h:206
void setLength(double length)
Set length.
Definition: EKLMGeometry.h:155
void setY(double y)
Set Y coordinate.
Definition: EKLMGeometry.h:189
void setX(double x)
Set X coordinate.
Definition: EKLMGeometry.h:172
double getX() const
Get X coordinate.
double getY() const
Get Y coordinate.
Sector support geometry data.
Definition: EKLMGeometry.h:239
void setCornerX(double cornerX)
Set coordinate X of corner 1.
Definition: EKLMGeometry.h:294
void setCorner1LX(double corner1LX)
Set corner 1 X length.
Definition: EKLMGeometry.h:311
void setCorner2LY(double corner2LY)
Set corner 2 Y length.
Definition: EKLMGeometry.h:396
void setCorner4Thickness(double corner4Thickness)
Set corner 4 thickness.
Definition: EKLMGeometry.h:549
void setThickness(double thickness)
Set thickness.
Definition: EKLMGeometry.h:260
void setCorner1Z(double corner1Z)
Set corner 1 Z coordinate.
Definition: EKLMGeometry.h:362
void setCorner1Thickness(double corner1Thickness)
Set corner 1 thickness.
Definition: EKLMGeometry.h:345
void setCorner2Thickness(double corner2Thickness)
Set corner 2 thickness.
Definition: EKLMGeometry.h:413
void setCorner3LY(double corner3LY)
Set corner 3 Y length.
Definition: EKLMGeometry.h:464
void setDeltaLY(double deltaLY)
Set outerR - Y of upper edge of BoxY.
Definition: EKLMGeometry.h:277
void setCorner4LY(double corner4LY)
Set corner 4 Y length.
Definition: EKLMGeometry.h:532
void setCorner3LX(double corner3LX)
Set corner 3 X length.
Definition: EKLMGeometry.h:447
void setCorner4Z(double corner4Z)
Set corner 4 Z coordinate.
Definition: EKLMGeometry.h:566
void setCorner3Thickness(double corner3Thickness)
Set corner 3 thickness.
Definition: EKLMGeometry.h:481
void setCorner3Z(double corner3Z)
Set corner 3 Z coordinate.
Definition: EKLMGeometry.h:498
void setCorner2LX(double corner2LX)
Set corner 2 X length.
Definition: EKLMGeometry.h:379
void setCorner2Z(double corner2Z)
Set corner 2 Z coordinate.
Definition: EKLMGeometry.h:430
void setCorner1Width(double corner1Width)
Set corner 1 width.
Definition: EKLMGeometry.h:328
void setCorner4LX(double corner4LX)
Set corner 4 X length.
Definition: EKLMGeometry.h:515
Shield layer detail geometry data.
void setPoint(int i, const Point &point)
Set point.
void setLengthY(double lengthY)
Set Y length.
const Point * getPoint(int i) const
Get point.
double getLengthY() const
Get Y length.
double getLengthX() const
Get X length.
void setLengthX(double lengthX)
Set X length.
void setNPoints(int nPoints)
Set number of points.
Class to store EKLM geometry data in the database.
Definition: EKLMGeometry.h:29
EKLMGeometry & operator=(const EKLMGeometry &geometry)
Operator =.
EKLM geometry data.
Definition: GeometryData.h:38
void getSectorTransform(HepGeom::Transform3D *t, int n) const
Get sector transformation.
void fillStripIndexArrays()
Fill strip index arrays.
void getSheetTransform(HepGeom::Transform3D *t, int n) const
Get plastic sheet element transformation.
bool hitInEKLM(double z) const
Check if z coordinate may be in EKLM.
static const GeometryData & Instance(enum DataSource dataSource=c_Database, const GearDir *gearDir=nullptr)
Instantiation.
Definition: GeometryData.cc:33
void calculateSectorSupportGeometry()
Calculate sector support geometry data.
void saveToDatabase(const IntervalOfValidity &iov) const
Save geometry data to database.
GeometryData(enum DataSource dataSource, const GearDir *gearDir)
Constructor.
void initializeFromGearbox(const GearDir *gearDir)
Initialize from Gearbox (XML).
void getStripTransform(HepGeom::Transform3D *t, int n) const
Get strip transformation.
void readEndcapStructureGeometry(const GearDir &gd)
Read section structure geometry data.
void getSectionTransform(HepGeom::Transform3D *t, int n) const
Get section transformation.
void getLayerTransform(HepGeom::Transform3D *t, int n) const
Get layer transformation.
void calculateShieldGeometry()
Calculate shield geometry data.
void initializeFromDatabase()
Initialize from database.
DataSource
Geometry data source.
Definition: GeometryData.h:43
void getPlaneTransform(HepGeom::Transform3D *t, int n) const
Get plane transformation.
void readXMLDataStrips(const GearDir &gd)
Read strip parameters from XML database.
int findIntersection(const Line2D &line, HepGeom::Point3D< double > *intersection) const
Find intersection with a line.
Definition: Line2D.cc:28
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:31
void append(const std::string &path)
Append something to the current path, modifying the GearDir in place.
Definition: GearDir.h:52
virtual int getNumberNodes(const std::string &path="") const override
Return the number of nodes a given path will expand to.
Definition: GearDir.h:58
A class that describes the interval of experiments/runs for which an object in the database is valid.
static const double cm
Standard units with the value = 1.
Definition: Unit.h:47
double getLength(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard length unit.
Definition: Interface.h:259
bool getBool(const std::string &path="") const noexcept(false)
Get the parameter path as a bool.
Definition: Interface.cc:80
int getInt(const std::string &path="") const noexcept(false)
Get the parameter path as a int.
Definition: Interface.cc:60
static Database & Instance()
Instance of a singleton Database.
Definition: Database.cc:42
bool storeData(const std::string &name, TObject *object, const IntervalOfValidity &iov)
Store an object in the database.
Definition: Database.cc:141
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.