Belle II Software  release-08-01-10
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 
28 using namespace Belle2;
29 
30 static const char c_MemErr[] = "Memory allocation error.";
31 
32 const EKLM::GeometryData&
33 EKLM::GeometryData::Instance(enum DataSource dataSource, const GearDir* gearDir)
34 {
35  static EKLM::GeometryData gd(dataSource, gearDir);
36  return gd;
37 }
38 
44 static 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 
56 static 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 
68 static 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 
97 static 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 
197 static 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 
297 static 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 orginal 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 
377 static 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 
639 bool EKLM::GeometryData::hitInEKLM(double z) const
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  */
649 void
650 EKLM::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 
661 void
662 EKLM::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 
669 void
670 EKLM::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 
689 void
690 EKLM::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 
702 void
703 EKLM::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 
709 void
710 EKLM::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
double tan(double a)
tan for double
Definition: beamHelpers.h:31
Abstract base class for different kinds of events.