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, const 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, const 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(
98 EKLMGeometry::ShieldDetailGeometry* sdg, const GearDir* gd)
99{
100 int i, n;
101 EKLMGeometry::Point p;
102 sdg->setLengthX(gd->getLength("LengthX") * CLHEP::cm);
103 sdg->setLengthY(gd->getLength("LengthY") * CLHEP::cm);
104 n = gd->getNumberNodes("Point");
105 sdg->setNPoints(n);
106 for (i = 0; i < n; i++) {
107 GearDir point(*gd);
108 std::string name = "/Point[" + std::to_string(i + 1) + "]";
109 point.append(name);
110 p.setX(point.getLength("X") * CLHEP::cm);
111 p.setY(point.getLength("Y") * CLHEP::cm);
112 sdg->setPoint(i, p);
113 }
114}
115
117{
119 Line2D line23Outer(0, m_SectorSupportPosition.getY(), 1, 0);
120 Line2D line23Inner(0, m_SectorSupportPosition.getY() +
121 m_SectorSupportGeometry.getThickness(), 1, 0);
122 Line2D line23Prism(0, m_SectorSupportPosition.getY() +
123 m_SectorSupportGeometry.getThickness() +
124 m_SectorSupportGeometry.getCorner3LY(), 1, 0);
125 Line2D line41Outer(m_SectorSupportPosition.getX(), 0, 0, 1);
126 Line2D line41Inner(m_SectorSupportPosition.getX() +
127 m_SectorSupportGeometry.getThickness(), 0, 0, 1);
128 Line2D line41Prism(m_SectorSupportPosition.getX() +
129 m_SectorSupportGeometry.getThickness() +
130 m_SectorSupportGeometry.getCorner4LX(), 0, 0, 1);
131 Line2D line41Corner1B(m_SectorSupportPosition.getX() +
132 m_SectorSupportGeometry.getCornerX(), 0, 0, 1);
133 Circle2D circleInnerOuter(0, 0, m_SectorSupportPosition.getInnerR());
134 Circle2D circleInnerInner(0, 0, m_SectorSupportPosition.getInnerR() +
135 m_SectorSupportGeometry.getThickness());
136 Circle2D circleOuterInner(0, 0, m_SectorSupportPosition.getOuterR() -
137 m_SectorSupportGeometry.getThickness());
138 Circle2D circleOuterOuter(0, 0, m_SectorSupportPosition.getOuterR());
139 HepGeom::Point3D<double> intersections[2];
140 /* Corner 1. */
141 p.setX(m_SectorSupportPosition.getX());
142 p.setY(m_SectorSupportPosition.getOuterR() -
143 m_SectorSupportGeometry.getDeltaLY());
144 p.setZ(0);
145 m_SectorSupportGeometry.setCorner1A(p);
146 line41Corner1B.findIntersection(circleOuterOuter, intersections);
147 m_SectorSupportGeometry.setCorner1B(intersections[1]);
148 m_SectorSupportGeometry.setCornerAngle(
149 atan2(m_SectorSupportGeometry.getCorner1B().y() -
150 m_SectorSupportGeometry.getCorner1A().y(),
151 m_SectorSupportGeometry.getCorner1B().x() -
152 m_SectorSupportGeometry.getCorner1A().x()) * CLHEP::rad);
153 p.setX(m_SectorSupportPosition.getX() +
154 m_SectorSupportGeometry.getThickness());
155 p.setY(m_SectorSupportGeometry.getCorner1A().y() -
156 m_SectorSupportGeometry.getThickness() *
157 (1.0 / cos(m_SectorSupportGeometry.getCornerAngle()) -
158 tan(m_SectorSupportGeometry.getCornerAngle())));
159 p.setZ(0);
160 m_SectorSupportGeometry.setCorner1AInner(p);
161 Line2D lineCorner1(m_SectorSupportGeometry.getCorner1AInner().x(),
162 m_SectorSupportGeometry.getCorner1AInner().y(),
163 m_SectorSupportGeometry.getCorner1B().x() -
164 m_SectorSupportGeometry.getCorner1A().x(),
165 m_SectorSupportGeometry.getCorner1B().y() -
166 m_SectorSupportGeometry.getCorner1A().y());
167 lineCorner1.findIntersection(circleOuterInner, intersections);
168 m_SectorSupportGeometry.setCorner1BInner(intersections[1]);
169 /* Corner 2. */
170 line23Inner.findIntersection(circleOuterInner, intersections);
171 m_SectorSupportGeometry.setCorner2Inner(intersections[1]);
172 /* Corner 3. */
173 line23Outer.findIntersection(circleInnerOuter, intersections);
174 m_SectorSupportGeometry.setCorner3(intersections[1]);
175 line23Inner.findIntersection(circleInnerInner, intersections);
176 m_SectorSupportGeometry.setCorner3Inner(intersections[1]);
177 line23Prism.findIntersection(circleInnerInner, intersections);
178 p.setX(intersections[1].x());
179 p.setY(m_SectorSupportPosition.getY() +
180 m_SectorSupportGeometry.getThickness());
181 p.setZ(0);
182 m_SectorSupportGeometry.setCorner3Prism(p);
183 /* Corner 4. */
184 line41Outer.findIntersection(circleInnerOuter, intersections);
185 m_SectorSupportGeometry.setCorner4(intersections[1]);
186 line41Inner.findIntersection(circleInnerInner, intersections);
187 m_SectorSupportGeometry.setCorner4Inner(intersections[1]);
188 line41Prism.findIntersection(circleInnerInner, intersections);
189 p.setX(m_SectorSupportPosition.getX() +
190 m_SectorSupportGeometry.getThickness());
191 p.setY(intersections[1].y());
192 p.setZ(0);
193 m_SectorSupportGeometry.setCorner4Prism(p);
194}
195
196static bool compareLength(double a, double b)
197{
198 return a < b;
199}
200
202{
203 const char err[] = "Strip sorting algorithm error.";
204 int i;
205 double l;
206 std::vector<double> strips;
207 std::vector<double>::iterator it;
208 std::map<double, int> mapLengthStrip;
209 std::map<double, int> mapLengthStrip2;
210 std::map<double, int>::iterator itm;
211 for (i = 0; i < m_NStrips; i++) {
212 strips.push_back(m_StripPosition[i].getLength());
213 mapLengthStrip.insert(
214 std::pair<double, int>(m_StripPosition[i].getLength(), i));
215 }
216 sort(strips.begin(), strips.end(), compareLength);
217 l = strips[0];
219 for (it = strips.begin(); it != strips.end(); ++it) {
220 if ((*it) != l) {
221 l = (*it);
223 }
224 }
225 m_StripLenToAll = static_cast<int*>(malloc(m_nStripDifferent * sizeof(int)));
226 if (m_StripLenToAll == nullptr)
227 B2FATAL(c_MemErr);
228 i = 0;
229 l = strips[0];
230 itm = mapLengthStrip.find(l);
231 if (itm == mapLengthStrip.end())
232 B2FATAL(err);
233 m_StripLenToAll[i] = itm->second;
234 mapLengthStrip2.insert(std::pair<double, int>(l, i));
235 for (it = strips.begin(); it != strips.end(); ++it) {
236 if ((*it) != l) {
237 l = (*it);
238 i++;
239 itm = mapLengthStrip.find(l);
240 if (itm == mapLengthStrip.end())
241 B2FATAL(err);
242 m_StripLenToAll[i] = itm->second;
243 mapLengthStrip2.insert(std::pair<double, int>(l, i));
244 }
245 }
246 m_StripAllToLen = static_cast<int*>(malloc(m_NStrips * sizeof(int)));
247 if (m_StripAllToLen == nullptr)
248 B2FATAL(c_MemErr);
249 for (i = 0; i < m_NStrips; i++) {
250 itm = mapLengthStrip2.find(m_StripPosition[i].getLength());
251 if (itm == mapLengthStrip2.end())
252 B2FATAL(err);
253 m_StripAllToLen[i] = itm->second;
254 }
255}
256
258{
259 int i;
260 GearDir Strips(gd);
261 Strips.append("/Strip");
262 m_StripGeometry.setWidth(Strips.getLength("Width") * CLHEP::cm);
263 m_StripGeometry.setThickness(Strips.getLength("Thickness") * CLHEP::cm);
264 m_StripGeometry.setGrooveDepth(Strips.getLength("GrooveDepth") * CLHEP::cm);
265 m_StripGeometry.setGrooveWidth(Strips.getLength("GrooveWidth") * CLHEP::cm);
266 m_StripGeometry.setNoScintillationThickness(
267 Strips.getLength("NoScintillationThickness") * CLHEP::cm);
268 m_StripGeometry.setRSSSize(Strips.getLength("RSSSize") * CLHEP::cm);
269 try {
271 } catch (std::bad_alloc& ba) {
272 B2FATAL(c_MemErr);
273 }
274 for (i = 0; i < m_NStrips; i++) {
275 GearDir StripContent(Strips);
276 std::string name = "/Strip[" + std::to_string(i + 1) + "]";
277 StripContent.append(name);
278 m_StripPosition[i].setLength(StripContent.getLength("Length") * CLHEP::cm);
279 m_StripPosition[i].setX(StripContent.getLength("X") * CLHEP::cm);
280 m_StripPosition[i].setY(StripContent.getLength("Y") * CLHEP::cm);
281 m_StripPosition[i].setZ(StripContent.getLength("Z") * CLHEP::cm);
282 }
283}
284
295static void getDetailDxDy(HepGeom::Point3D<double>* points, int nPoints,
296 double r, double kx, double ky,
297 double& dx, double& dy)
298{
299 int i;
300 /* Variable maxt is initialized to avoid a false-positive warning. */
301 /* cppcheck-suppress variableScope */
302 double a, b, c, d, t, maxt = 0, x1, y1, x2, y2, u;
303 bool intersection;
304 /*
305 * Contact by one of the detail points.
306 * Solve equation (x1 + kx * t)^2 + (y1 + ky * t)^2 = R^2,
307 * (kx^2 + ky^2) * t^2 + 2 * (kx * x1 + ky * y1) * t + x1^2 + y1^2 - r^2 = 0.
308 */
309 a = kx * kx + ky * ky;
310 intersection = false;
311 for (i = 0; i < nPoints; i++) {
312 x1 = points[i].x();
313 y1 = points[i].y();
314 b = 2.0 * (kx * x1 + ky * y1);
315 c = x1 * x1 + y1 * y1 - r * r;
316 d = b * b - 4.0 * a * c;
317 if (d >= 0) {
318 t = (-b + sqrt(d)) / (2.0 * a);
319 if (!intersection) {
320 intersection = true;
321 maxt = t;
322 } else {
323 if (t > maxt)
324 maxt = t;
325 }
326 }
327 }
328 if (!intersection)
329 B2FATAL("Shield layer geometry calculation error.");
330 /*
331 * Contact by one of the detail lines.
332 * Find t such as the equation
333 * (x1 + kx * t + (x2 - x1) * u)^2 + (y1 + ky * t + (y2 - y1) * u) = r^2
334 * has one solution relatively to u. Equation on t is
335 * 0 = ((x2 - x1) * (x1 + kx * t) + (y2 - y1) * (y1 + ky * t))^2 +
336 * ((x2 - x1)^2 + (y2 - y1)^2) * ((x1 + kx * t)^2 + (y1 + ky * t)^2 - r^2),
337 * t = (x1 * y2 - x2 * y1 +- r * sqrt((x2 - x1)^2 + (y2 - y1)^2)) /
338 * ((x2 - x1) * ky - (y2 - y1) * kx).
339 */
340 for (i = 0; i < nPoints; i++) {
341 x1 = points[i].x();
342 y1 = points[i].y();
343 if (i < nPoints - 1) {
344 x2 = points[i + 1].x();
345 y2 = points[i + 1].y();
346 } else {
347 x2 = points[0].x();
348 y2 = points[0].y();
349 }
350 a = (x2 - x1) * ky - (y2 - y1) * kx;
351 if (a == 0)
352 continue;
353 b = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
354 t = (x1 * y2 - x2 * y1 + r * sqrt(b)) / a;
355 /*
356 * Check whether intersection occurs between the translated points
357 * (x1 + kx * t, y1 + ky * t) and (x2 + kx * t, y2 + ky * t).
358 * (find solition of the original equation relatively to u for that).
359 */
360 u = -((x2 - x1) * (x1 + kx * t) + (y2 - y1) * (y2 + ky * t)) / b;
361 if (u < 0 || u > 1)
362 continue;
363 if (t > maxt)
364 maxt = t;
365 }
366 dx = kx * maxt;
367 dy = ky * maxt;
368}
369
375static void EKLMPointToCLHEP(const EKLMGeometry::Point* pointEKLM,
376 HepGeom::Point3D<double>& pointCLHEP)
377{
378 pointCLHEP.setX(pointEKLM->getX());
379 pointCLHEP.setY(pointEKLM->getY());
380 pointCLHEP.setZ(0);
381}
382
384{
385 int i;
386 double r, l, dx, dy, xCenter, yCenter;
387 const double asqrt2 = 1.0 / sqrt(2.0);
388 HepGeom::Point3D<double> points[8];
389 const ShieldDetailGeometry* detailA = m_ShieldGeometry.getDetailA();
390 const ShieldDetailGeometry* detailB = m_ShieldGeometry.getDetailB();
391 const ShieldDetailGeometry* detailC = m_ShieldGeometry.getDetailC();
392 const ShieldDetailGeometry* detailD = m_ShieldGeometry.getDetailD();
393 r = m_SectorSupportPosition.getInnerR() +
394 m_SectorSupportGeometry.getThickness();
395 /* Detail A. */
396 EKLMPointToCLHEP(detailA->getPoint(0), points[0]);
397 EKLMPointToCLHEP(detailA->getPoint(1), points[1]);
398 EKLMPointToCLHEP(detailA->getPoint(2), points[2]);
399 EKLMPointToCLHEP(detailA->getPoint(3), points[3]);
400 EKLMPointToCLHEP(detailA->getPoint(4), points[4]);
401 points[5].setX(detailA->getLengthX());
402 points[5].setY(detailA->getLengthY());
403 points[5].setZ(0);
404 EKLMPointToCLHEP(detailA->getPoint(5), points[6]);
405 EKLMPointToCLHEP(detailA->getPoint(6), points[7]);
406 l = 0.5 * (detailA->getLengthX() + detailB->getLengthX());
407 xCenter = -asqrt2 * l;
408 yCenter = asqrt2 * l;
409 for (i = 0; i < 8; i++)
410 points[i] = HepGeom::Translate3D(xCenter, yCenter, 0) *
411 HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
412 HepGeom::Translate3D(-detailA->getLengthX() / 2,
413 -detailA->getLengthY() / 2, 0) *
414 points[i];
415 getDetailDxDy(points, 8, r, 1, 1, dx, dy);
416 m_ShieldGeometry.setDetailACenter(xCenter + dx, yCenter + dy);
417 /* Details B, D, E. */
418 points[0].setX(0);
419 points[0].setY(-detailD->getLengthY());
420 points[0].setZ(0);
421 points[1].setX(detailD->getLengthX());
422 points[1].setY(0);
423 points[1].setZ(0);
424 points[2].setX(detailB->getLengthX() - detailD->getLengthX());
425 points[2].setY(0);
426 points[2].setZ(0);
427 points[3].setX(detailB->getLengthX());
428 points[3].setY(-detailD->getLengthY());
429 points[3].setZ(0);
430 EKLMPointToCLHEP(detailB->getPoint(0), points[4]);
431 EKLMPointToCLHEP(detailB->getPoint(1), points[5]);
432 EKLMPointToCLHEP(detailB->getPoint(2), points[6]);
433 EKLMPointToCLHEP(detailB->getPoint(3), points[7]);
434 /* Detail B center coordinates before its shift are (0, 0). */
435 for (i = 0; i < 8; i++)
436 points[i] = HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
437 HepGeom::Translate3D(-detailB->getLengthX() / 2,
438 -detailB->getLengthY() / 2, 0) *
439 points[i];
440 getDetailDxDy(points, 8, r, 1, 1, dx, dy);
441 m_ShieldGeometry.setDetailBCenter(dx, dy);
442 /* Detail C. */
443 EKLMPointToCLHEP(detailC->getPoint(0), points[0]);
444 EKLMPointToCLHEP(detailC->getPoint(1), points[1]);
445 EKLMPointToCLHEP(detailC->getPoint(2), points[2]);
446 EKLMPointToCLHEP(detailC->getPoint(3), points[3]);
447 EKLMPointToCLHEP(detailC->getPoint(4), points[4]);
448 points[5].setX(detailC->getLengthX());
449 points[5].setY(detailC->getLengthY());
450 points[5].setZ(0);
451 EKLMPointToCLHEP(detailC->getPoint(5), points[6]);
452 EKLMPointToCLHEP(detailC->getPoint(6), points[7]);
453 l = 0.5 * (detailB->getLengthX() + detailC->getLengthX());
454 xCenter = asqrt2 * l;
455 yCenter = -asqrt2 * l;
456 for (i = 0; i < 8; i++)
457 points[i] = HepGeom::Translate3D(xCenter, yCenter, 0) *
458 HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
459 HepGeom::RotateY3D(180.0 * CLHEP::deg) *
460 HepGeom::Translate3D(-detailC->getLengthX() / 2,
461 -detailC->getLengthY() / 2, 0) *
462 points[i];
463 getDetailDxDy(points, 8, r, 1, 1, dx, dy);
464 m_ShieldGeometry.setDetailCCenter(xCenter + dx, yCenter + dy);
465}
466
468{
469 GearDir d(gd);
470 d.append("/EndcapStructure");
471 m_EndcapStructureGeometry.setPhi(d.getAngle("Phi") * CLHEP::rad);
472 m_EndcapStructureGeometry.setNSides(d.getInt("NSides"));
473}
474
476{
477 int i, j, k;
478 std::string name;
479 ShieldDetailGeometry shieldDetailGeometry;
480 GearDir gd(*gearDir);
481 gd.append("/EKLM");
482 /* Beam-background study. */
483 m_BeamBackgroundStudy = gd.getBool("BeamBackgroundStudy");
484 /* Numbers of elements. */
485 m_NSections = gd.getInt("NSections");
486 m_ElementNumbers->checkSection(m_NSections);
487 m_NLayers = gd.getInt("NLayers");
488 m_ElementNumbers->checkLayer(m_NLayers);
490 m_NDetectorLayers[0] = gd.getInt("NDetectorLayersBackward");
492 if (m_NSections == 2) {
493 m_NDetectorLayers[1] = gd.getInt("NDetectorLayersForward");
495 }
496 m_NSectors = gd.getInt("NSectors");
497 m_ElementNumbers->checkSector(m_NSectors);
498 m_NPlanes = gd.getInt("NPlanes");
499 m_ElementNumbers->checkPlane(m_NPlanes);
500 m_NSegments = gd.getInt("NSegments");
501 m_ElementNumbers->checkSegment(m_NSegments);
503 m_NStrips = gd.getInt("NStrips");
504 m_ElementNumbers->checkStrip(m_NStrips);
505 /* Geometry parameters. */
506 m_SolenoidZ = gd.getLength("SolenoidZ") * CLHEP::cm;
508 GearDir section(gd);
509 section.append("/Section");
510 readPositionData(&m_SectionPosition, &section);
511 readSizeData(&m_SectionPosition, &section);
512 GearDir layer(gd);
513 layer.append("/Layer");
514 readSizeData(&m_LayerPosition, &layer);
515 m_LayerShiftZ = layer.getLength("ShiftZ") * CLHEP::cm;
516 GearDir sector(gd);
517 sector.append("/Sector");
518 readSizeData(&m_SectorPosition, &sector);
519 GearDir sectorSupport(gd);
520 sectorSupport.append("/SectorSupport");
521 readPositionData(&m_SectorSupportPosition, &sectorSupport);
522 readSizeData(&m_SectorSupportPosition, &sectorSupport);
523 readSectorSupportGeometry(&m_SectorSupportGeometry, &sectorSupport);
524 GearDir plane(gd);
525 plane.append("/Plane");
526 readPositionData(&m_PlanePosition, &plane);
527 readSizeData(&m_PlanePosition, &plane);
528 GearDir plasticSheet(gd);
529 plasticSheet.append("/PlasticSheet");
530 m_PlasticSheetGeometry.setWidth(plasticSheet.getLength("Width") * CLHEP::cm);
531 m_PlasticSheetGeometry.setDeltaL(plasticSheet.getLength("DeltaL") *
532 CLHEP::cm);
533 GearDir segmentSupport(gd);
534 segmentSupport.append("/SegmentSupport");
535 m_SegmentSupportGeometry.setTopWidth(
536 segmentSupport.getLength("TopWidth") * CLHEP::cm);
537 m_SegmentSupportGeometry.setTopThickness(
538 segmentSupport.getLength("TopThickness") * CLHEP::cm);
539 m_SegmentSupportGeometry.setMiddleWidth(
540 segmentSupport.getLength("MiddleWidth") * CLHEP::cm);
541 m_SegmentSupportGeometry.setMiddleThickness(
542 segmentSupport.getLength("MiddleThickness") * CLHEP::cm);
543 try {
546 } catch (std::bad_alloc& ba) {
547 B2FATAL(c_MemErr);
548 }
549 for (j = 0; j < m_NPlanes; j++) {
550 for (i = 0; i <= m_NSegments; i++) {
551 k = j * (m_NSegments + 1) + i;
552 GearDir segmentSupport2(segmentSupport);
553 name = "/SegmentSupportPlane[" + std::to_string(j + 1) + "]";
554 segmentSupport2.append(name);
555 name = "/SegmentSupport[" + std::to_string(i + 1) + "]";
556 segmentSupport2.append(name);
557 m_SegmentSupportPosition[k].setLength(
558 segmentSupport2.getLength("Length") * CLHEP::cm);
560 segmentSupport2.getLength("X") * CLHEP::cm);
562 segmentSupport2.getLength("Y") * CLHEP::cm);
564 segmentSupport2.getLength("Z") * CLHEP::cm);
565 m_SegmentSupportPosition[k].setDeltaLRight(
566 segmentSupport2.getLength("DeltaLRight") * CLHEP::cm);
567 m_SegmentSupportPosition[k].setDeltaLLeft(
568 segmentSupport2.getLength("DeltaLLeft") * CLHEP::cm);
569 }
570 }
572 GearDir shield(gd);
573 shield.append("/Shield");
574 m_ShieldGeometry.setThickness(shield.getLength("Thickness") * CLHEP::cm);
575 GearDir shieldDetailA(shield);
576 shieldDetailA.append("/Detail[@id=\"A\"]");
577 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailA);
578 m_ShieldGeometry.setDetailA(shieldDetailGeometry);
579 GearDir shieldDetailB(shield);
580 shieldDetailB.append("/Detail[@id=\"B\"]");
581 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailB);
582 m_ShieldGeometry.setDetailB(shieldDetailGeometry);
583 GearDir shieldDetailC(shield);
584 shieldDetailC.append("/Detail[@id=\"C\"]");
585 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailC);
586 m_ShieldGeometry.setDetailC(shieldDetailGeometry);
587 GearDir shieldDetailD(shield);
588 shieldDetailD.append("/Detail[@id=\"D\"]");
589 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailD);
590 m_ShieldGeometry.setDetailD(shieldDetailGeometry);
591 m_Geometry = new EKLMGeometry(*this);
592}
593
595{
596 DBObjPtr<EKLMGeometry> eklmGeometry;
597 if (!eklmGeometry.isValid())
598 B2FATAL("No EKLM geometry data in the database.");
599 EKLMGeometry::operator=(*eklmGeometry);
600 m_Geometry = new EKLMGeometry(*this);
601}
602
604 const GearDir* gearDir)
605{
606 m_Geometry = nullptr;
607 switch (dataSource) {
608 case c_Gearbox:
609 initializeFromGearbox(gearDir);
610 break;
611 case c_Database:
613 break;
614 }
616 0.5 * m_SectionPosition.getLength();
618 0.5 * m_SectionPosition.getLength();
622}
623
625{
626 if (m_Geometry != nullptr)
627 delete m_Geometry;
628 free(m_StripLenToAll);
629 free(m_StripAllToLen);
630}
631
633{
634 Database::Instance().storeData("EKLMGeometry", m_Geometry, iov);
635}
636
638{
639 double zMm;
640 zMm = z / Unit::cm * CLHEP::cm;
641 return (zMm > m_MinZForward) || (zMm < m_MaxZBackward);
642}
643
644/*
645 * Note that numbers of elements are 0-based for all transformation functions.
646 */
647void
648EKLM::GeometryData::getSectionTransform(HepGeom::Transform3D* t, int n) const
649{
650 if (n == 0)
651 *t = HepGeom::Translate3D(m_SectionPosition.getX(), m_SectionPosition.getY(),
653 else
654 *t = HepGeom::Translate3D(m_SectionPosition.getX(), m_SectionPosition.getY(),
656 HepGeom::RotateY3D(180.*CLHEP::deg);
657}
658
659void
660EKLM::GeometryData::getLayerTransform(HepGeom::Transform3D* t, int n) const
661{
662 *t = HepGeom::Translate3D(0.0, 0.0, m_SectionPosition.getLength() / 2.0 -
663 (n + 1) * m_LayerShiftZ +
664 0.5 * m_LayerPosition.getLength());
665}
666
667void
668EKLM::GeometryData::getSectorTransform(HepGeom::Transform3D* t, int n) const
669{
670 switch (n) {
671 case 0:
672 *t = HepGeom::Translate3D(0., 0., 0.);
673 break;
674 case 1:
675 *t = HepGeom::RotateY3D(180.0 * CLHEP::deg);
676 break;
677 case 2:
678 *t = HepGeom::RotateZ3D(90.0 * CLHEP::deg) *
679 HepGeom::RotateY3D(180.0 * CLHEP::deg);
680 break;
681 case 3:
682 *t = HepGeom::RotateZ3D(-90.0 * CLHEP::deg);
683 break;
684 }
685}
686
687void
688EKLM::GeometryData::getPlaneTransform(HepGeom::Transform3D* t, int n) const
689{
690 if (n == 0)
691 *t = HepGeom::Translate3D(m_PlanePosition.getX(), m_PlanePosition.getY(),
692 m_PlanePosition.getZ()) *
693 HepGeom::Rotate3D(180. * CLHEP::deg,
694 HepGeom::Vector3D<double>(1., 1., 0.));
695 else
696 *t = HepGeom::Translate3D(m_PlanePosition.getX(), m_PlanePosition.getY(),
697 -m_PlanePosition.getZ());
698}
699
700void
701EKLM::GeometryData::getStripTransform(HepGeom::Transform3D* t, int n) const
702{
703 *t = HepGeom::Translate3D(m_StripPosition[n].getX(),
704 m_StripPosition[n].getY(), 0.0);
705}
706
707void
708EKLM::GeometryData::getSheetTransform(HepGeom::Transform3D* t, int n) const
709{
710 double y;
711 y = m_StripPosition[n].getY();
712 if (n % m_ElementNumbers->getNStripsSegment() == 0)
713 y = y + 0.5 * m_PlasticSheetGeometry.getDeltaL();
714 else if (n % m_ElementNumbers->getNStripsSegment() ==
715 m_ElementNumbers->getNStripsSegment() - 1)
716 y = y - 0.5 * m_PlasticSheetGeometry.getDeltaL();
717 *t = HepGeom::Translate3D(m_StripPosition[n].getX(), y, 0.0);
718}
719
720
722{
723 // EKLM: all layers have the same area per sector
724 // Read strip parameters from EKLMGeometry (inherited)
726 double stripWidth = stripGeom->getWidth() / 10.0; // Convert mm to cm
727 int nStrips = getNStrips();
728
729 // Calculate total area per sector by summing strip areas
730 double layerArea = 0.0;
731 for (int stripId = 1; stripId <= nStrips; ++stripId) {
732 double stripLength = getStripLength(stripId) / 10.0; // Convert mm to cm
733 layerArea += stripLength * stripWidth;
734 }
735
736 return layerArea;
737}
738
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.
void setInnerR(double innerR)
Set inner radius.
void setOuterR(double outerR)
Set outer radius.
void setZ(double z)
Set Z coordinate.
void setLength(double length)
Set length.
void setY(double y)
Set Y coordinate.
void setX(double x)
Set X coordinate.
double getX() const
Get X coordinate.
double getY() const
Get Y coordinate.
void setCornerX(double cornerX)
Set coordinate X of corner 1.
void setCorner1LX(double corner1LX)
Set corner 1 X length.
void setCorner2LY(double corner2LY)
Set corner 2 Y length.
void setCorner4Thickness(double corner4Thickness)
Set corner 4 thickness.
void setThickness(double thickness)
Set thickness.
void setCorner1Z(double corner1Z)
Set corner 1 Z coordinate.
void setCorner1Thickness(double corner1Thickness)
Set corner 1 thickness.
void setCorner2Thickness(double corner2Thickness)
Set corner 2 thickness.
void setCorner3LY(double corner3LY)
Set corner 3 Y length.
void setDeltaLY(double deltaLY)
Set outerR - Y of upper edge of BoxY.
void setCorner4LY(double corner4LY)
Set corner 4 Y length.
void setCorner3LX(double corner3LX)
Set corner 3 X length.
void setCorner4Z(double corner4Z)
Set corner 4 Z coordinate.
void setCorner3Thickness(double corner3Thickness)
Set corner 3 thickness.
void setCorner3Z(double corner3Z)
Set corner 3 Z coordinate.
void setCorner2LX(double corner2LX)
Set corner 2 X length.
void setCorner2Z(double corner2Z)
Set corner 2 Z coordinate.
void setCorner1Width(double corner1Width)
Set corner 1 width.
void setCorner4LX(double corner4LX)
Set corner 4 X length.
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.
double getWidth() const
Get width.
int m_NSegments
Number of segments in one plane.
EKLMGeometry()
Constructor.
ShieldGeometry m_ShieldGeometry
Shield layer details geometry data.
int m_NLayers
Number of layers in one section.
bool m_BeamBackgroundStudy
ROOT streamer.
SectorSupportGeometry m_SectorSupportGeometry
Sector support geometry data.
ElementPosition m_SectionPosition
Position data for sections.
int m_NPlanes
Number of planes in one sector.
ElementPosition m_SectorSupportPosition
Position data for sector support structure.
double m_SolenoidZ
Solenoid center Z coordinate.
ElementPosition m_PlanePosition
Position data for planes.
ElementPosition m_LayerPosition
Position data for layers.
int m_NStrips
Number of strips in one plane.
int getNStrips() const
Get number of strips.
double m_LayerShiftZ
Z distance between two layers.
int m_NSectors
Number of sectors in one layer.
const EKLMElementNumbers * m_ElementNumbers
Element numbers.
int * m_NDetectorLayers
Number of detector layers.
int m_NSections
Number of sections.
PlasticSheetGeometry m_PlasticSheetGeometry
Plastic sheet geometry data.
ElementPosition m_SectorPosition
Position data for sectors.
SegmentSupportPosition * m_SegmentSupportPosition
Position data for segment support structure.
const StripGeometry * getStripGeometry() const
Get strip geometry data.
ElementPosition * m_StripPosition
Position data for strips.
StripGeometry m_StripGeometry
Strip geometry data.
EndcapStructureGeometry m_EndcapStructureGeometry
Section structure geometry data.
EKLMGeometry & operator=(const EKLMGeometry &geometry)
Operator =.
SegmentSupportGeometry m_SegmentSupportGeometry
Segment support geometry data.
void checkDetectorLayerNumber(int section, int layer) const
Check if number of detector layers is correct (fatal error if not).
int m_NSegmentSupportElementsSector
Number of segment support elements in one sector.
EKLM geometry data.
void getSectorTransform(HepGeom::Transform3D *t, int n) const
Get sector transformation.
int * m_StripLenToAll
Number of strip in position-based array.
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.
double getEKLMLayerArea() const
Get EKLM layer area (same for all layers).
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.
double m_MaxZBackward
Maximal z coordinate of the backward section.
EKLMGeometry * m_Geometry
Copy of data in this class used to write it to database.
double getStripLength(int strip) const
Get strip length.
double m_MinZForward
Minimal z coordinate of the forward section.
void initializeFromDatabase()
Initialize from database.
DataSource
Geometry data source.
@ c_Gearbox
Gearbox (XML).
int m_nStripDifferent
Number of strips with different lengths in one plane.
void getPlaneTransform(HepGeom::Transform3D *t, int n) const
Get plane transformation.
int * m_StripAllToLen
Number of strip in length-based array.
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 tan(double a)
tan for double
Definition beamHelpers.h:31
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28
Abstract base class for different kinds of events.