10#include <klm/eklm/geometry/GeometryData.h>
13#include <klm/eklm/geometry/Circle2D.h>
14#include <klm/eklm/geometry/Line2D.h>
17#include <framework/database/DBObjPtr.h>
18#include <framework/database/Database.h>
19#include <framework/logging/Logger.h>
22#include <CLHEP/Geometry/Point3D.h>
23#include <CLHEP/Units/SystemOfUnits.h>
30static const char c_MemErr[] =
"Memory allocation error.";
68static void readSectorSupportGeometry(
97static void readShieldDetailGeometry(
98 EKLMGeometry::ShieldDetailGeometry* sdg,
const GearDir* gd)
101 EKLMGeometry::Point p;
106 for (i = 0; i < n; i++) {
108 std::string name =
"/Point[" + std::to_string(i + 1) +
"]";
110 p.setX(point.getLength(
"X") * CLHEP::cm);
111 p.setY(point.getLength(
"Y") * CLHEP::cm);
178 p.setX(intersections[1].x());
191 p.setY(intersections[1].y());
196static bool compareLength(
double a,
double b)
203 const char err[] =
"Strip sorting algorithm error.";
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;
213 mapLengthStrip.insert(
216 sort(strips.begin(), strips.end(), compareLength);
219 for (it = strips.begin(); it != strips.end(); ++it) {
230 itm = mapLengthStrip.find(l);
231 if (itm == mapLengthStrip.end())
234 mapLengthStrip2.insert(std::pair<double, int>(l, i));
235 for (it = strips.begin(); it != strips.end(); ++it) {
239 itm = mapLengthStrip.find(l);
240 if (itm == mapLengthStrip.end())
243 mapLengthStrip2.insert(std::pair<double, int>(l, i));
251 if (itm == mapLengthStrip2.end())
267 Strips.
getLength(
"NoScintillationThickness") * CLHEP::cm);
271 }
catch (std::bad_alloc& ba) {
276 std::string name =
"/Strip[" + std::to_string(i + 1) +
"]";
277 StripContent.
append(name);
296 double r,
double kx,
double ky,
297 double& dx,
double& dy)
302 double a, b, c, d, t, maxt = 0, x1, y1, x2, y2, u;
309 a = kx * kx + ky * ky;
310 intersection =
false;
311 for (i = 0; i < nPoints; i++) {
314 b = 2.0 * (kx * x1 + ky * y1);
315 c = x1 * x1 + y1 * y1 - r * r;
316 d = b * b - 4.0 * a * c;
318 t = (-b +
sqrt(d)) / (2.0 * a);
329 B2FATAL(
"Shield layer geometry calculation error.");
340 for (i = 0; i < nPoints; i++) {
343 if (i < nPoints - 1) {
344 x2 = points[i + 1].x();
345 y2 = points[i + 1].y();
350 a = (x2 - x1) * ky - (y2 - y1) * kx;
353 b = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
354 t = (x1 * y2 - x2 * y1 + r *
sqrt(b)) / a;
360 u = -((x2 - x1) * (x1 + kx * t) + (y2 - y1) * (y2 + ky * t)) / b;
375static void EKLMPointToCLHEP(
const EKLMGeometry::Point* pointEKLM,
376 HepGeom::Point3D<double>& pointCLHEP)
378 pointCLHEP.setX(pointEKLM->
getX());
379 pointCLHEP.setY(pointEKLM->
getY());
386 double r, l, dx, dy, xCenter, yCenter;
387 const double asqrt2 = 1.0 /
sqrt(2.0);
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]);
404 EKLMPointToCLHEP(detailA->
getPoint(5), points[6]);
405 EKLMPointToCLHEP(detailA->
getPoint(6), points[7]);
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,
415 getDetailDxDy(points, 8, r, 1, 1, dx, dy);
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]);
435 for (i = 0; i < 8; i++)
436 points[i] = HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
437 HepGeom::Translate3D(-detailB->
getLengthX() / 2,
440 getDetailDxDy(points, 8, r, 1, 1, dx, dy);
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]);
451 EKLMPointToCLHEP(detailC->
getPoint(5), points[6]);
452 EKLMPointToCLHEP(detailC->
getPoint(6), points[7]);
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,
463 getDetailDxDy(points, 8, r, 1, 1, dx, dy);
470 d.append(
"/EndcapStructure");
509 section.append(
"/Section");
513 layer.append(
"/Layer");
517 sector.append(
"/Sector");
520 sectorSupport.
append(
"/SectorSupport");
525 plane.append(
"/Plane");
529 plasticSheet.
append(
"/PlasticSheet");
534 segmentSupport.
append(
"/SegmentSupport");
536 segmentSupport.
getLength(
"TopWidth") * CLHEP::cm);
538 segmentSupport.
getLength(
"TopThickness") * CLHEP::cm);
540 segmentSupport.
getLength(
"MiddleWidth") * CLHEP::cm);
542 segmentSupport.
getLength(
"MiddleThickness") * CLHEP::cm);
546 }
catch (std::bad_alloc& ba) {
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);
558 segmentSupport2.getLength(
"Length") * CLHEP::cm);
560 segmentSupport2.getLength(
"X") * CLHEP::cm);
562 segmentSupport2.getLength(
"Y") * CLHEP::cm);
564 segmentSupport2.getLength(
"Z") * CLHEP::cm);
566 segmentSupport2.getLength(
"DeltaLRight") * CLHEP::cm);
568 segmentSupport2.getLength(
"DeltaLLeft") * CLHEP::cm);
576 shieldDetailA.
append(
"/Detail[@id=\"A\"]");
577 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailA);
580 shieldDetailB.
append(
"/Detail[@id=\"B\"]");
581 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailB);
584 shieldDetailC.
append(
"/Detail[@id=\"C\"]");
585 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailC);
588 shieldDetailD.
append(
"/Detail[@id=\"D\"]");
589 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailD);
598 B2FATAL(
"No EKLM geometry data in the database.");
607 switch (dataSource) {
656 HepGeom::RotateY3D(180.*CLHEP::deg);
672 *t = HepGeom::Translate3D(0., 0., 0.);
675 *t = HepGeom::RotateY3D(180.0 * CLHEP::deg);
678 *t = HepGeom::RotateZ3D(90.0 * CLHEP::deg) *
679 HepGeom::RotateY3D(180.0 * CLHEP::deg);
682 *t = HepGeom::RotateZ3D(-90.0 * CLHEP::deg);
693 HepGeom::Rotate3D(180. * CLHEP::deg,
694 HepGeom::Vector3D<double>(1., 1., 0.));
726 double stripWidth = stripGeom->
getWidth() / 10.0;
730 double layerArea = 0.0;
731 for (
int stripId = 1; stripId <= nStrips; ++stripId) {
733 layerArea += stripLength * stripWidth;
bool isValid() const
Check whether a valid object was obtained from the database.
Class for accessing objects in the database.
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.
Sector support geometry data.
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.
Segment support position.
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.
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.
~GeometryData()
Destructor.
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.
GearDir is the basic class used for accessing the parameter store.
void append(const std::string &path)
Append something to the current path, modifying the GearDir in place.
virtual int getNumberNodes(const std::string &path="") const override
Return the number of nodes a given path will expand to.
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.
double getLength(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard length unit.
bool getBool(const std::string &path="") const noexcept(false)
Get the parameter path as a bool.
int getInt(const std::string &path="") const noexcept(false)
Get the parameter path as a int.
static Database & Instance()
Instance of a singleton Database.
bool storeData(const std::string &name, TObject *object, const IntervalOfValidity &iov)
Store an object in the database.
double tan(double a)
tan for double
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.