10#include <klm/eklm/geometry/TransformData.h>
13#include <klm/dbobjects/eklm/EKLMAlignment.h>
14#include <klm/dbobjects/eklm/EKLMSegmentAlignment.h>
15#include <klm/eklm/geometry/AlignmentChecker.h>
16#include <klm/eklm/geometry/GeometryData.h>
19#include <framework/database/DBObjPtr.h>
20#include <framework/logging/Logger.h>
21#include <framework/gearbox/Unit.h>
28 int iSection, iLayer, iSector, iPlane, iSegment, iStrip, sector, segment;
29 int nSections, nLayers, nSectors, nPlanes, nStrips, nSegments, nStripsSegment;
41 m_Section =
new HepGeom::Transform3D[nSections];
42 m_Layer =
new HepGeom::Transform3D*[nSections];
43 m_Sector =
new HepGeom::Transform3D** [nSections];
44 m_Plane =
new HepGeom::Transform3D** *[nSections];
46 m_Segment =
new HepGeom::Transform3D**** [nSections];
47 m_Strip =
new HepGeom::Transform3D**** [nSections];
49 for (iSection = 0; iSection < nSections; iSection++) {
52 m_Layer[iSection] =
new HepGeom::Transform3D[nLayers];
53 m_Sector[iSection] =
new HepGeom::Transform3D*[nLayers];
54 m_Plane[iSection] =
new HepGeom::Transform3D** [nLayers];
56 m_Segment[iSection] =
new HepGeom::Transform3D** *[nLayers];
57 m_Strip[iSection] =
new HepGeom::Transform3D** *[nLayers];
59 for (iLayer = 0; iLayer < nLayers; iLayer++) {
61 m_Sector[iSection][iLayer] =
new HepGeom::Transform3D[nSectors];
62 if (iLayer < nDetectorLayers) {
63 m_Plane[iSection][iLayer] =
new HepGeom::Transform3D*[nSectors];
65 new HepGeom::Transform3D*[nSectors];
66 m_Segment[iSection][iLayer] =
new HepGeom::Transform3D** [nSectors];
67 m_Strip[iSection][iLayer] =
new HepGeom::Transform3D** [nSectors];
68 m_StripInverse[iSection][iLayer] =
new HepGeom::Transform3D** [nSectors];
70 for (iSector = 0; iSector < nSectors; iSector++) {
73 if (iLayer >= nDetectorLayers)
75 m_Plane[iSection][iLayer][iSector] =
new HepGeom::Transform3D[nPlanes];
77 new HepGeom::Transform3D[nPlanes];
79 new HepGeom::Transform3D*[nPlanes];
80 m_Strip[iSection][iLayer][iSector] =
new HepGeom::Transform3D*[nPlanes];
82 new HepGeom::Transform3D*[nPlanes];
83 for (iPlane = 0; iPlane < nPlanes; iPlane++) {
85 &
m_Plane[iSection][iLayer][iSector][iPlane], iPlane);
87 HepGeom::Translate3D(0, 0, 0);
88 m_Segment[iSection][iLayer][iSector][iPlane] =
89 new HepGeom::Transform3D[nSegments];
90 for (iSegment = 0; iSegment < nSegments; iSegment++) {
91 m_Segment[iSection][iLayer][iSector][iPlane][iSegment] =
92 HepGeom::Translate3D(0, 0, 0);
94 m_Strip[iSection][iLayer][iSector][iPlane] =
95 new HepGeom::Transform3D[nStrips];
97 new HepGeom::Transform3D[nStrips];
98 for (iStrip = 0; iStrip < nStrips; iStrip++) {
100 &
m_Strip[iSection][iLayer][iSector][iPlane][iStrip], iStrip);
107 if (displacementType !=
c_None) {
108 std::string payload, segmentPayload;
110 payload =
"EKLMDisplacement";
111 segmentPayload =
"EKLMSegmentDisplacement";
113 payload =
"EKLMAlignment";
114 segmentPayload =
"EKLMSegmentAlignment";
118 if (!alignment.isValid())
119 B2FATAL(
"No EKLM displacement (alignment) data.");
121 if (!alignmentChecker.
checkAlignment(&(*alignment), &(*segmentAlignment)))
122 B2FATAL(
"EKLM displacement data are incorrect, overlaps exist.");
124 for (iSection = 1; iSection <= nSections; iSection++) {
126 for (iLayer = 1; iLayer <= nDetectorLayers; iLayer++) {
127 for (iSector = 1; iSector <= nSectors; iSector++) {
130 alignment->getModuleAlignment(sector);
131 if (sectorAlignment ==
nullptr)
132 B2FATAL(
"Incomplete EKLM displacement (alignment) data.");
133 for (iPlane = 1; iPlane <= nPlanes; iPlane++) {
137 HepGeom::Translate3D(
144 HepGeom::Translate3D(
150 for (iSegment = 1; iSegment <= nSegments; iSegment++) {
152 iSection, iLayer, iSector, iPlane, iSegment);
154 segmentAlignment->getSegmentAlignment(segment);
155 if (segmentAlignmentData ==
nullptr)
156 B2FATAL(
"Incomplete EKLM displacement (alignment) data.");
157 m_Segment[iSection - 1][iLayer - 1][iSector - 1][iPlane - 1]
159 HepGeom::Translate3D(
162 m_Segment[iSection - 1][iLayer - 1][iSector - 1][iPlane - 1]
166 for (iStrip = 1; iStrip <= nStripsSegment; iStrip++) {
167 m_Strip[iSection - 1][iLayer - 1][iSector - 1][iPlane - 1]
168 [nStripsSegment * (iSegment - 1) + iStrip - 1] =
169 HepGeom::Translate3D(
173 m_Strip[iSection - 1][iLayer - 1][iSector - 1][iPlane - 1]
174 [nStripsSegment * (iSegment - 1) + iStrip - 1] *
190 int iSection, iLayer, iSector, iPlane;
192 int nSections, nLayers, nDetectorLayers, nSectors, nPlanes;
193 nSections = m_GeoDat->getNSections();
194 nLayers = m_GeoDat->getNLayers();
195 nSectors = m_GeoDat->getNSectors();
196 nPlanes = m_GeoDat->getNPlanes();
197 for (iSection = 0; iSection < nSections; iSection++) {
198 nDetectorLayers = m_GeoDat->getNDetectorLayers(iSection + 1);
199 for (iLayer = 0; iLayer < nLayers; iLayer++) {
200 delete[] m_Sector[iSection][iLayer];
201 if (iLayer >= nDetectorLayers)
203 for (iSector = 0; iSector < nSectors; iSector++) {
204 for (iPlane = 0; iPlane < nPlanes; iPlane++) {
205 delete[] m_Segment[iSection][iLayer][iSector][iPlane];
206 delete[] m_Strip[iSection][iLayer][iSector][iPlane];
207 delete[] m_StripInverse[iSection][iLayer][iSector][iPlane];
209 delete[] m_Plane[iSection][iLayer][iSector];
210 delete[] m_PlaneDisplacement[iSection][iLayer][iSector];
211 delete[] m_Segment[iSection][iLayer][iSector];
212 delete[] m_Strip[iSection][iLayer][iSector];
213 delete[] m_StripInverse[iSection][iLayer][iSector];
215 delete[] m_Plane[iSection][iLayer];
216 delete[] m_PlaneDisplacement[iSection][iLayer];
217 delete[] m_Segment[iSection][iLayer];
218 delete[] m_Strip[iSection][iLayer];
219 delete[] m_StripInverse[iSection][iLayer];
221 delete[] m_Layer[iSection];
222 delete[] m_Sector[iSection];
223 delete[] m_PlaneDisplacement[iSection];
224 delete[] m_Plane[iSection];
225 delete[] m_Segment[iSection];
226 delete[] m_Strip[iSection];
227 delete[] m_StripInverse[iSection];
232 delete[] m_PlaneDisplacement;
236 delete[] m_StripInverse;
241 int iSection, iLayer, iSector, iPlane, iSegment, iStrip;
243 int nSections, nLayers, nDetectorLayers, nSectors, nPlanes, nSegments, nStrips;
244 nSections = m_GeoDat->getNSections();
245 nLayers = m_GeoDat->getNLayers();
246 nSectors = m_GeoDat->getNSectors();
247 nPlanes = m_GeoDat->getNPlanes();
248 nSegments = m_GeoDat->getNSegments();
249 nStrips = m_GeoDat->getNStrips();
250 for (iSection = 0; iSection < nSections; iSection++) {
251 nDetectorLayers = m_GeoDat->getNDetectorLayers(iSection + 1);
252 for (iLayer = 0; iLayer < nLayers; iLayer++) {
253 m_Layer[iSection][iLayer] = m_Section[iSection] * m_Layer[iSection][iLayer];
254 for (iSector = 0; iSector < nSectors; iSector++) {
255 m_Sector[iSection][iLayer][iSector] =
256 m_Layer[iSection][iLayer] * m_Sector[iSection][iLayer][iSector];
257 if (iLayer >= nDetectorLayers)
259 for (iPlane = 0; iPlane < nPlanes; iPlane++) {
260 m_Plane[iSection][iLayer][iSector][iPlane] =
261 m_Sector[iSection][iLayer][iSector] *
262 m_Plane[iSection][iLayer][iSector][iPlane];
263 for (iSegment = 0; iSegment < nSegments; iSegment++) {
264 m_Segment[iSection][iLayer][iSector][iPlane][iSegment] =
265 m_Plane[iSection][iLayer][iSector][iPlane] *
266 m_PlaneDisplacement[iSection][iLayer][iSector][iPlane] *
267 m_Segment[iSection][iLayer][iSector][iPlane][iSegment];
269 for (iStrip = 0; iStrip < nStrips; iStrip++) {
270 m_Strip[iSection][iLayer][iSector][iPlane][iStrip] =
271 m_Plane[iSection][iLayer][iSector][iPlane] *
272 m_PlaneDisplacement[iSection][iLayer][iSector][iPlane] *
273 m_Strip[iSection][iLayer][iSector][iPlane][iStrip];
274 m_StripInverse[iSection][iLayer][iSector][iPlane][iStrip] =
275 m_Strip[iSection][iLayer][iSector][iPlane][iStrip].inverse();
283const HepGeom::Transform3D*
286 return &m_Section[section - 1];
289const HepGeom::Transform3D*
292 return &m_Layer[section - 1][layer - 1];
298 return &m_Sector[section - 1][layer - 1][sector - 1];
304 return &m_Plane[section - 1][layer - 1][sector - 1][plane - 1];
310 return &m_PlaneDisplacement[section - 1][layer - 1][sector - 1][plane - 1];
317 return &m_Segment[section - 1][layer - 1][sector - 1][plane - 1][segment - 1];
323 return &m_Strip[section - 1][layer - 1][sector - 1][plane - 1][strip - 1];
326const HepGeom::Transform3D*
329 return &(m_Strip[hit->getSection() - 1][hit->getLayer() - 1]
330 [hit->getSector() - 1][hit->getPlane() - 1][hit->getStrip() - 1]);
333const HepGeom::Transform3D*
336 return &(m_StripInverse[hit->getSection() - 1][hit->getLayer() - 1]
337 [hit->getSector() - 1][hit->getPlane() - 1][hit->getStrip() - 1]);
340const HepGeom::Transform3D*
342 int plane,
int strip)
const
344 return &(m_StripInverse[section - 1][layer - 1][sector - 1][plane - 1]
350 double* d1,
double* d2,
double* sd,
364 double l1 = m_GeoDat->getStripLength(hit1->
getStrip());
367 const HepGeom::Transform3D* tr1 = getStripLocalToGlobal(hit1);
371 double l2 = m_GeoDat->getStripLength(hit2->
getStrip());
374 const HepGeom::Transform3D* tr2 = getStripLocalToGlobal(hit2);
386 HepGeom::Vector3D<double> v1 = s1_2g - s1_1g;
387 HepGeom::Vector3D<double> v2 = s2_2g - s2_1g;
388 HepGeom::Vector3D<double> d = s1_1g - s2_1g;
389 double v1sq = v1.mag2();
390 double v2sq = v2.mag2();
391 double v1dv2 = v1.dot(v2);
392 double ddv1 = d.dot(v1);
393 double ddv2 = d.dot(v2);
394 double den = v1sq * v2sq - v1dv2 * v1dv2;
395 double t1 = (v1dv2 * ddv2 - v2sq * ddv1) / den;
396 double t2 = (- v1dv2 * ddv1 + v1sq * ddv2) / den;
399 if (t1 < 0.0 || t1 > 1.0)
401 if (t2 < 0.0 || t2 > 1.0)
407 *d1 = s1_2g.distance(s1_cg) / CLHEP::mm *
Unit::mm;
408 *d2 = s2_2g.distance(s2_cg) / CLHEP::mm *
Unit::mm;
409 *cross = 0.5 * (s1_cg + s2_cg) / CLHEP::mm *
Unit::mm;
410 *sd = s1_cg.distance(s2_cg) / CLHEP::mm *
Unit::mm;
411 if (s2_cg.mag2() < s1_cg.mag2())
426 if (position.y() > 0) {
444 int section, layer, sector, plane, segment, strip, stripSegment, stripGlobal;
446 int nLayers, nPlanes, nSegments, nStripsSegment, minDistanceSegment;
447 double solenoidCenter, firstLayerCenter, layerShift;
449 double x, y, z, l, minY, maxY;
450 double minDistance = 0, minDistanceNew, stripWidth;
452 intersectionClhep = intersection * CLHEP::cm /
Unit::cm;
453 solenoidCenter = m_GeoDat->getSolenoidZ() / CLHEP::cm *
Unit::cm;
454 if (intersection.z() < solenoidCenter)
459 (m_GeoDat->getSectionPosition()->getZ()
460 - 0.5 * m_GeoDat->getSectionPosition()->getLength()
461 + m_GeoDat->getLayerShiftZ()
462 - 0.5 * m_GeoDat->getLayerPosition()->getLength()) /
464 layerShift = m_GeoDat->getLayerShiftZ() / CLHEP::cm *
Unit::cm;
465 z = fabs(intersection.z() - solenoidCenter);
466 layer = round((z - firstLayerCenter) / layerShift) + 1;
469 nLayers = m_GeoDat->getNDetectorLayers(section);
472 sector = getSectorByPosition(section, intersection);
473 nPlanes = m_GeoDat->getNPlanes();
474 nSegments = m_GeoDat->getNSegments();
475 nStripsSegment = m_ElementNumbers->getNStripsSegment();
476 stripWidth = m_GeoDat->getStripGeometry()->getWidth() / CLHEP::cm *
Unit::cm;
477 minY = -stripWidth / 2;
478 maxY = (double(nStripsSegment) - 0.5) * stripWidth;
479 for (plane = 1; plane <= nPlanes; plane++) {
480 minDistanceSegment = 1;
481 for (segment = 1; segment <= nSegments; segment++) {
482 strip = (segment - 1) * nStripsSegment;
483 intersectionLocal = m_StripInverse[section - 1][layer - 1]
484 [sector - 1][plane - 1][strip] * intersectionClhep;
485 y = intersectionLocal.y() / CLHEP::cm *
Unit::cm;
487 minDistanceNew = minY - y;
488 }
else if (y > maxY) {
489 minDistanceNew = y - maxY;
492 minDistanceSegment = segment;
496 minDistance = minDistanceNew;
497 }
else if (minDistanceNew < minDistance) {
498 minDistance = minDistanceNew;
499 minDistanceSegment = segment;
508 strip = (minDistanceSegment - 1) * nStripsSegment;
509 intersectionLocal = m_StripInverse[section - 1][layer - 1]
510 [sector - 1][plane - 1][strip] * intersectionClhep;
511 y = intersectionLocal.y() / CLHEP::cm *
Unit::cm;
512 stripSegment = ceil((y - 0.5 * stripWidth) / stripWidth);
513 if (stripSegment <= 0)
515 else if (stripSegment > nStripsSegment)
516 stripSegment = nStripsSegment;
517 strip = stripSegment + (minDistanceSegment - 1) * nStripsSegment;
518 intersectionLocal = m_StripInverse[section - 1][layer - 1]
519 [sector - 1][plane - 1][strip - 1] * intersectionClhep;
520 x = intersectionLocal.x();
521 l = m_GeoDat->getStripLength(strip);
526 if (fabs(x) > 0.5 * l)
528 stripGlobal = m_ElementNumbers->stripNumber(
529 section, layer, sector, plane, strip);
531 *strip1 = stripGlobal;
533 *strip2 = stripGlobal;
Class for accessing objects in the database.
static const EKLMElementNumbers & Instance()
Instantiation.
int sectorNumber(int section, int layer, int sector) const
Get sector number.
static constexpr int getNStripsSegment()
Get number of strips in a segment.
int segmentNumber(int section, int layer, int sector, int plane, int segment) const
Get segment number.
int getNPlanes() const
Get number of planes.
int getNSections() const
Get number of sections.
int getNLayers() const
Get number of layers.
int getNDetectorLayers(int section) const
Get number of detector layers.
int getNSegments() const
Get number of segments.
int getNStrips() const
Get number of strips.
int getNSectors() const
Get number of sectors.
Class for EKLM alignment checking.
bool checkAlignment(const EKLMAlignment *alignment, const EKLMSegmentAlignment *segmentAlignment) const
Check alignment.
void getSectorTransform(HepGeom::Transform3D *t, int n) const
Get sector transformation.
static const GeometryData & Instance(enum DataSource dataSource=c_Database, const GearDir *gearDir=nullptr)
Instantiation.
void getStripTransform(HepGeom::Transform3D *t, int n) const
Get strip transformation.
void getSectionTransform(HepGeom::Transform3D *t, int n) const
Get section transformation.
void getLayerTransform(HepGeom::Transform3D *t, int n) const
Get layer transformation.
void getPlaneTransform(HepGeom::Transform3D *t, int n) const
Get plane transformation.
float getDeltaU() const
Get shift in U.
float getDeltaV() const
Get shift in V.
float getDeltaGamma() const
Get rotation in alpha.
KLM digit (class representing a digitized hit in RPCs or scintillators).
int getLayer() const
Get layer number.
int getSection() const
Get section number.
int getPlane() const
Get plane number.
int getStrip() const
Get strip number.
int getSector() const
Get sector number.
static const double mm
[millimeters]
static const double rad
Standard of [angle].
static const double cm
Standard units with the value = 1.
Abstract base class for different kinds of events.