Belle II Software  release-08-01-10
AlignmentChecker.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/AlignmentChecker.h>
11 
12 /* KLM headers. */
13 #include <klm/dbobjects/eklm/EKLMAlignment.h>
14 #include <klm/eklm/geometry/Polygon2D.h>
15 
16 /* Basf2 headers. */
17 #include <framework/gearbox/Unit.h>
18 #include <framework/logging/Logger.h>
19 
20 using namespace Belle2;
21 
23  m_PrintOverlaps(printOverlaps),
24  m_GeoDat(&(EKLM::GeometryData::Instance())),
25  m_ElementNumbers(&(EKLMElementNumbers::Instance()))
26 {
27  int iPlane, iSegmentSupport;
28  const EKLMGeometry::SectorSupportGeometry* sectorSupportGeometry =
30  const EKLMGeometry::ElementPosition* sectorSupportPosition =
32  m_LineCorner1 = new LineSegment2D(sectorSupportGeometry->getCorner1AInner(),
33  sectorSupportGeometry->getCorner1BInner());
34  m_ArcOuter = new Arc2D(
35  0, 0, sectorSupportPosition->getOuterR() -
36  sectorSupportGeometry->getThickness(),
37  atan2(sectorSupportGeometry->getCorner2Inner().y(),
38  sectorSupportGeometry->getCorner2Inner().x()),
39  atan2(sectorSupportGeometry->getCorner1BInner().y(),
40  sectorSupportGeometry->getCorner1BInner().x()));
41  m_Line23 = new LineSegment2D(sectorSupportGeometry->getCorner2Inner(),
42  sectorSupportGeometry->getCorner3Inner());
43  m_ArcInner = new Arc2D(
44  0, 0, sectorSupportPosition->getInnerR() +
45  sectorSupportGeometry->getThickness(),
46  atan2(sectorSupportGeometry->getCorner3Inner().y(),
47  sectorSupportGeometry->getCorner3Inner().x()),
48  atan2(sectorSupportGeometry->getCorner4Inner().y(),
49  sectorSupportGeometry->getCorner4Inner().x()));
50  m_Line41 = new LineSegment2D(sectorSupportGeometry->getCorner4Inner(),
51  sectorSupportGeometry->getCorner1AInner());
53  for (iPlane = 1; iPlane <= m_GeoDat->getNPlanes(); iPlane++) {
54  m_SegmentSupport[iPlane - 1] =
55  new Polygon2D*[m_GeoDat->getNSegments() + 1];
56  for (iSegmentSupport = 1; iSegmentSupport <= m_GeoDat->getNSegments() + 1;
57  iSegmentSupport++)
58  m_SegmentSupport[iPlane - 1][iSegmentSupport - 1] = nullptr;
59  }
60 }
61 
63 {
64  int iPlane, iSegmentSupport;
65  delete m_LineCorner1;
66  delete m_ArcOuter;
67  delete m_Line23;
68  delete m_ArcInner;
69  delete m_Line41;
70  for (iPlane = 1; iPlane <= m_GeoDat->getNPlanes(); iPlane++) {
71  for (iSegmentSupport = 1; iSegmentSupport <= m_GeoDat->getNSegments() + 1;
72  iSegmentSupport++) {
73  if (m_SegmentSupport[iPlane - 1][iSegmentSupport - 1] != nullptr)
74  delete m_SegmentSupport[iPlane - 1][iSegmentSupport - 1];
75  }
76  delete[] m_SegmentSupport[iPlane - 1];
77  }
78  delete[] m_SegmentSupport;
79 }
80 
82 checkSectorAlignment(int section, int layer, int sector,
83  const KLMAlignmentData* sectorAlignment) const
84 {
85  int iPlane, iSegmentSupport, iSegment, j;
86  double lx, ly;
87  HepGeom::Point3D<double> supportRectangle[4];
88  HepGeom::Transform3D t;
89  const EKLMGeometry::SegmentSupportPosition* segmentSupportPos;
90  const EKLMGeometry::SegmentSupportGeometry* segmentSupportGeometry =
91  m_GeoDat->getSegmentSupportGeometry();
92  KLMAlignmentData segmentAlignment(0, 0, 0, 0, 0, 0);
93  for (iPlane = 1; iPlane <= m_GeoDat->getNPlanes(); iPlane++) {
94  for (iSegmentSupport = 1; iSegmentSupport <= m_GeoDat->getNSegments() + 1;
95  iSegmentSupport++) {
96  segmentSupportPos =
97  m_GeoDat->getSegmentSupportPosition(iPlane, iSegmentSupport);
98  lx = 0.5 * (segmentSupportPos->getLength() -
99  segmentSupportPos->getDeltaLLeft() -
100  segmentSupportPos->getDeltaLRight());
101  ly = 0.5 * (segmentSupportGeometry->getMiddleWidth());
102  supportRectangle[0].setX(lx);
103  supportRectangle[0].setY(ly);
104  supportRectangle[0].setZ(0);
105  supportRectangle[1].setX(-lx);
106  supportRectangle[1].setY(ly);
107  supportRectangle[1].setZ(0);
108  supportRectangle[2].setX(-lx);
109  supportRectangle[2].setY(-ly);
110  supportRectangle[2].setZ(0);
111  supportRectangle[3].setX(lx);
112  supportRectangle[3].setY(-ly);
113  supportRectangle[3].setZ(0);
114  t = HepGeom::Translate3D(
115  0.5 * (segmentSupportPos->getDeltaLLeft() -
116  segmentSupportPos->getDeltaLRight()) +
117  segmentSupportPos->getX(), segmentSupportPos->getY(), 0);
118  if (iPlane == 1)
119  t = HepGeom::Rotate3D(180. * CLHEP::deg,
120  HepGeom::Vector3D<double>(1., 1., 0.)) * t;
121  t = HepGeom::Translate3D(sectorAlignment->getDeltaU() * CLHEP::cm / Unit::cm,
122  sectorAlignment->getDeltaV() * CLHEP::cm / Unit::cm,
123  0) *
124  HepGeom::RotateZ3D(sectorAlignment->getDeltaGamma() *
125  CLHEP::rad / Unit::rad) * t;
126  for (j = 0; j < 4; j++)
127  supportRectangle[j] = t * supportRectangle[j];
128  if (m_SegmentSupport[iPlane - 1][iSegmentSupport - 1] != nullptr)
129  delete m_SegmentSupport[iPlane - 1][iSegmentSupport - 1];
130  m_SegmentSupport[iPlane - 1][iSegmentSupport - 1] =
131  new Polygon2D(supportRectangle, 4);
132  }
133  }
134  for (iPlane = 1; iPlane <= m_GeoDat->getNPlanes(); iPlane++) {
135  for (iSegmentSupport = 1; iSegmentSupport <= m_GeoDat->getNSegments() + 1;
136  iSegmentSupport++) {
137  if (m_SegmentSupport[iPlane - 1][iSegmentSupport - 1]->hasIntersection(
138  *m_LineCorner1)) {
139  if (m_PrintOverlaps)
140  B2ERROR("Segment support overlaps with corner 1."
141  << LogVar("Section", section) << LogVar("Layer", layer)
142  << LogVar("Sector", sector)
143  << LogVar("Segment support", iSegmentSupport));
144  return false;
145  }
146  if (m_SegmentSupport[iPlane - 1][iSegmentSupport - 1]->hasIntersection(
147  *m_ArcOuter)) {
148  if (m_PrintOverlaps)
149  B2ERROR("Segment support overlaps with outer arc."
150  << LogVar("Section", section) << LogVar("Layer", layer)
151  << LogVar("Sector", sector)
152  << LogVar("Segment support", iSegmentSupport));
153  return false;
154  }
155  if (m_SegmentSupport[iPlane - 1][iSegmentSupport - 1]->hasIntersection(
156  *m_Line23)) {
157  if (m_PrintOverlaps)
158  B2ERROR("Segment support overlaps with line 2-3."
159  << LogVar("Section", section) << LogVar("Layer", layer)
160  << LogVar("Sector", sector)
161  << LogVar("Segment support", iSegmentSupport));
162  return false;
163  }
164  if (m_SegmentSupport[iPlane - 1][iSegmentSupport - 1]->hasIntersection(
165  *m_ArcInner)) {
166  if (m_PrintOverlaps)
167  B2ERROR("Segment support overlaps with inner arc."
168  << LogVar("Section", section) << LogVar("Layer", layer)
169  << LogVar("Sector", sector)
170  << LogVar("Segment support", iSegmentSupport));
171  return false;
172  }
173  if (m_SegmentSupport[iPlane - 1][iSegmentSupport - 1]->hasIntersection(
174  *m_Line41)) {
175  if (m_PrintOverlaps)
176  B2ERROR("Segment support overlaps with line 4-1."
177  << LogVar("Section", section) << LogVar("Layer", layer)
178  << LogVar("Sector", sector)
179  << LogVar("Segment support", iSegmentSupport));
180  return false;
181  }
182  }
183  }
184  for (iPlane = 1; iPlane <= m_GeoDat->getNPlanes(); iPlane++) {
185  for (iSegment = 1; iSegment <= m_GeoDat->getNSegments(); iSegment++) {
186  if (!checkSegmentAlignment(section, layer, sector, iPlane, iSegment,
187  sectorAlignment, &segmentAlignment, true))
188  return false;
189  }
190  }
191  return true;
192 }
193 
195 checkSegmentAlignment(int section, int layer, int sector, int plane, int segment,
196  const KLMAlignmentData* sectorAlignment,
197  const KLMAlignmentData* segmentAlignment,
198  bool calledFromSectorCheck) const
199 {
200  /* cppcheck-suppress variableScope */
201  int i, j, iStrip;
202  /* cppcheck-suppress variableScope */
203  double lx, ly;
204  HepGeom::Point3D<double> stripRectangle[4];
205  HepGeom::Transform3D t;
206  const EKLMGeometry::StripGeometry* stripGeometry =
207  m_GeoDat->getStripGeometry();
208  if (!calledFromSectorCheck) {
209  if (!checkSectorAlignment(section, layer, sector, sectorAlignment))
210  return false;
211  }
212  ly = 0.5 * stripGeometry->getWidth();
213  for (i = 1; i <= m_ElementNumbers->getNStripsSegment(); i++) {
214  iStrip = m_ElementNumbers->getNStripsSegment() * (segment - 1) + i;
215  const EKLMGeometry::ElementPosition* stripPosition =
216  m_GeoDat->getStripPosition(iStrip);
217  lx = 0.5 * stripPosition->getLength();
218  stripRectangle[0].setX(lx);
219  stripRectangle[0].setY(ly);
220  stripRectangle[0].setZ(0);
221  stripRectangle[1].setX(-lx);
222  stripRectangle[1].setY(ly);
223  stripRectangle[1].setZ(0);
224  stripRectangle[2].setX(-lx);
225  stripRectangle[2].setY(-ly);
226  stripRectangle[2].setZ(0);
227  stripRectangle[3].setX(lx);
228  stripRectangle[3].setY(-ly);
229  stripRectangle[3].setZ(0);
230  t = HepGeom::Translate3D(segmentAlignment->getDeltaU() * CLHEP::cm / Unit::cm,
231  segmentAlignment->getDeltaV() * CLHEP::cm / Unit::cm,
232  0) *
233  HepGeom::Translate3D(stripPosition->getX(), stripPosition->getY(), 0) *
234  HepGeom::RotateZ3D(segmentAlignment->getDeltaGamma() *
235  CLHEP::rad / Unit::rad);
236  if (plane == 1)
237  t = HepGeom::Rotate3D(180. * CLHEP::deg,
238  HepGeom::Vector3D<double>(1., 1., 0.)) * t;
239  t = HepGeom::Translate3D(sectorAlignment->getDeltaU() * CLHEP::cm / Unit::cm,
240  sectorAlignment->getDeltaV() * CLHEP::cm / Unit::cm,
241  0) *
242  HepGeom::RotateZ3D(sectorAlignment->getDeltaGamma() *
243  CLHEP::rad / Unit::rad) * t;
244  for (j = 0; j < 4; j++)
245  stripRectangle[j] = t * stripRectangle[j];
246  Polygon2D stripPolygon(stripRectangle, 4);
247  if (stripPolygon.hasIntersection(*m_LineCorner1)) {
248  if (m_PrintOverlaps)
249  B2ERROR("Strip overlaps with corner 1."
250  << LogVar("Section", section) << LogVar("Layer", layer)
251  << LogVar("Sector", sector) << LogVar("Plane", plane)
252  << LogVar("Strip", iStrip));
253  return false;
254  }
255  if (stripPolygon.hasIntersection(*m_ArcOuter)) {
256  if (m_PrintOverlaps)
257  B2ERROR("Strip overlaps with outer arc."
258  << LogVar("Section", section) << LogVar("Layer", layer)
259  << LogVar("Sector", sector) << LogVar("Plane", plane)
260  << LogVar("Strip", iStrip));
261  B2ERROR("Overlap (section " << section << ", layer " << layer <<
262  ", sector " << sector << ", plane " << plane <<
263  "): strip " << iStrip << ", outer arc.");
264  return false;
265  }
266  if (stripPolygon.hasIntersection(*m_Line23)) {
267  if (m_PrintOverlaps)
268  B2ERROR("Strip overlaps with line 2-3."
269  << LogVar("Section", section) << LogVar("Layer", layer)
270  << LogVar("Sector", sector) << LogVar("Plane", plane)
271  << LogVar("Strip", iStrip));
272  return false;
273  }
274  if (stripPolygon.hasIntersection(*m_ArcInner)) {
275  if (m_PrintOverlaps)
276  B2ERROR("Strip overlaps with inner arc."
277  << LogVar("Section", section) << LogVar("Layer", layer)
278  << LogVar("Sector", sector) << LogVar("Plane", plane)
279  << LogVar("Strip", iStrip));
280  B2ERROR("Overlap (section " << section << ", layer " << layer <<
281  ", sector " << sector << ", plane " << plane <<
282  "): strip " << iStrip << ", inner arc.");
283  return false;
284  }
285  if (stripPolygon.hasIntersection(*m_Line41)) {
286  if (m_PrintOverlaps)
287  B2ERROR("Strip overlaps with line 4-1."
288  << LogVar("Section", section) << LogVar("Layer", layer)
289  << LogVar("Sector", sector) << LogVar("Plane", plane)
290  << LogVar("Strip", iStrip));
291  return false;
292  }
293  for (j = 0; j <= m_GeoDat->getNSegments(); j++) {
294  if (stripPolygon.hasIntersection(*m_SegmentSupport[plane - 1][j])) {
295  if (m_PrintOverlaps)
296  B2ERROR("Strip overlaps with segment support."
297  << LogVar("Section", section) << LogVar("Layer", layer)
298  << LogVar("Sector", sector) << LogVar("Plane", plane)
299  << LogVar("Strip", iStrip)
300  << LogVar("Segment support", j + 1));
301  return false;
302  }
303  }
304  }
305  return true;
306 }
307 
309  const EKLMAlignment* alignment,
310  const EKLMSegmentAlignment* segmentAlignment) const
311 {
312  int iSection, iLayer, iSector, iPlane, iSegment, sector, segment;
313  for (iSection = 1; iSection <= m_GeoDat->getNSections(); iSection++) {
314  for (iLayer = 1; iLayer <= m_GeoDat->getNDetectorLayers(iSection);
315  iLayer++) {
316  for (iSector = 1; iSector <= m_GeoDat->getNSectors(); iSector++) {
317  sector = m_ElementNumbers->sectorNumber(iSection, iLayer, iSector);
318  const KLMAlignmentData* sectorAlignment =
319  alignment->getModuleAlignment(sector);
320  if (sectorAlignment == nullptr)
321  B2FATAL("Incomplete alignment data.");
322  if (!checkSectorAlignment(iSection, iLayer, iSector, sectorAlignment))
323  return false;
324  for (iPlane = 1; iPlane <= m_GeoDat->getNPlanes(); iPlane++) {
325  for (iSegment = 1; iSegment <= m_GeoDat->getNSegments(); iSegment++) {
326  segment = m_ElementNumbers->segmentNumber(
327  iSection, iLayer, iSector, iPlane, iSegment);
328  const KLMAlignmentData* segmentAlignmentData =
329  segmentAlignment->getSegmentAlignment(segment);
330  if (segmentAlignment == nullptr)
331  B2FATAL("Incomplete alignment data.");
332  if (!checkSegmentAlignment(iSection, iLayer, iSector, iPlane,
333  iSegment, sectorAlignment,
334  segmentAlignmentData, false))
335  return false;
336  }
337  }
338  }
339  }
340  }
341  return true;
342 }
343 
Class to store EKLM alignment data in the database.
Definition: EKLMAlignment.h:30
EKLM element numbers.
Position information for the elements of detector.
Definition: EKLMGeometry.h:100
double getX() const
Get X coordinate.
Definition: EKLMGeometry.h:163
double getOuterR() const
Get outer radius.
Definition: EKLMGeometry.h:129
double getInnerR() const
Get inner radius.
Definition: EKLMGeometry.h:112
double getY() const
Get Y coordinate.
Definition: EKLMGeometry.h:180
double getLength() const
Get length.
Definition: EKLMGeometry.h:146
Sector support geometry data.
Definition: EKLMGeometry.h:239
const HepGeom::Point3D< double > & getCorner2Inner() const
Get corner 2 coordinates (inner side).
Definition: EKLMGeometry.h:659
double getThickness() const
Get thickness.
Definition: EKLMGeometry.h:251
const HepGeom::Point3D< double > & getCorner1AInner() const
Get corner 1A coordinates (inner side).
Definition: EKLMGeometry.h:608
const HepGeom::Point3D< double > & getCorner4Inner() const
Get corner 4 coordinates (inner side).
Definition: EKLMGeometry.h:744
const HepGeom::Point3D< double > & getCorner1BInner() const
Get corner 1B coordinates (inner side).
Definition: EKLMGeometry.h:642
const HepGeom::Point3D< double > & getCorner3Inner() const
Get corner 3 coordinates (inner side).
Definition: EKLMGeometry.h:693
Segment support geometry data.
Definition: EKLMGeometry.h:939
double getMiddleWidth() const
Get middle part width.
Definition: EKLMGeometry.h:985
double getX() const
Get X coordinate.
double getY() const
Get Y coordinate.
double getDeltaLRight() const
Get right Delta L.
double getDeltaLLeft() const
Get left Delta L.
double getWidth() const
Get width.
const ElementPosition * getSectorSupportPosition() const
Get position data for sector support structure.
int getNPlanes() const
Get number of planes.
int getNSegments() const
Get number of segments.
const SectorSupportGeometry * getSectorSupportGeometry() const
Get sector support geometry data.
Class to store EKLM alignment data in the database.
const KLMAlignmentData * getSegmentAlignment(EKLMSegmentNumber segment) const
Get segment alignment data.
bool checkAlignment(const EKLMAlignment *alignment, const EKLMSegmentAlignment *segmentAlignment) const
Check alignment.
LineSegment2D * m_Line23
Sector support edge: line between corners 2 and 3.
bool checkSectorAlignment(int section, int layer, int sector, const KLMAlignmentData *sectorAlignment) const
Check sector alignment.
Arc2D * m_ArcOuter
Sector support edge: outer arc.
bool checkSegmentAlignment(int section, int layer, int sector, int plane, int segment, const KLMAlignmentData *sectorAlignment, const KLMAlignmentData *segmentAlignment, bool calledFromSectorCheck) const
Check segment alignment.
LineSegment2D * m_Line41
Sector support edge: line between corners 4 and 1.
AlignmentChecker(bool printOverlaps)
Constructor.
Polygon2D *** m_SegmentSupport
Segment support.
LineSegment2D * m_LineCorner1
Sector support edge: corner 1 line.
Arc2D * m_ArcInner
Sector support edge: inner arc.
const GeometryData * m_GeoDat
Geometry data.
EKLM geometry data.
Definition: GeometryData.h:38
bool hasIntersection(const LineSegment2D &lineSegment) const
Check whether polygon has an intersection with a line segment or this line segment is fully inside th...
Definition: Polygon2D.cc:63
KLM Alignment data.
float getDeltaU() const
Get shift in U.
float getDeltaV() const
Get shift in V.
float getDeltaGamma() const
Get rotation in alpha.
static const double rad
Standard of [angle].
Definition: Unit.h:50
static const double cm
Standard units with the value = 1.
Definition: Unit.h:47
Class to store variables with their name which were sent to the logging service.
Abstract base class for different kinds of events.