12 #include <klm/eklm/geometry/GeometryData.h>
15 #include <klm/eklm/geometry/Circle2D.h>
16 #include <klm/eklm/geometry/Line2D.h>
19 #include <framework/database/DBObjPtr.h>
20 #include <framework/database/Database.h>
21 #include <framework/logging/Logger.h>
24 #include <CLHEP/Geometry/Point3D.h>
25 #include <CLHEP/Units/SystemOfUnits.h>
32 static const char c_MemErr[] =
"Memory allocation error.";
70 static void readSectorSupportGeometry(
99 static void readShieldDetailGeometry(
109 for (i = 0; i < n; i++) {
111 name =
"/Point[" + std::to_string(i + 1) +
"]";
112 point.append(name.c_str());
113 p.setX(point.getLength(
"X") * CLHEP::cm);
114 p.setY(point.getLength(
"Y") * CLHEP::cm);
122 Line2D line23Outer(0, m_SectorSupportPosition.getY(), 1, 0);
123 Line2D line23Inner(0, m_SectorSupportPosition.getY() +
124 m_SectorSupportGeometry.getThickness(), 1, 0);
125 Line2D line23Prism(0, m_SectorSupportPosition.getY() +
126 m_SectorSupportGeometry.getThickness() +
127 m_SectorSupportGeometry.getCorner3LY(), 1, 0);
128 Line2D line41Outer(m_SectorSupportPosition.getX(), 0, 0, 1);
129 Line2D line41Inner(m_SectorSupportPosition.getX() +
130 m_SectorSupportGeometry.getThickness(), 0, 0, 1);
131 Line2D line41Prism(m_SectorSupportPosition.getX() +
132 m_SectorSupportGeometry.getThickness() +
133 m_SectorSupportGeometry.getCorner4LX(), 0, 0, 1);
134 Line2D line41Corner1B(m_SectorSupportPosition.getX() +
135 m_SectorSupportGeometry.getCornerX(), 0, 0, 1);
136 Circle2D circleInnerOuter(0, 0, m_SectorSupportPosition.getInnerR());
137 Circle2D circleInnerInner(0, 0, m_SectorSupportPosition.getInnerR() +
138 m_SectorSupportGeometry.getThickness());
139 Circle2D circleOuterInner(0, 0, m_SectorSupportPosition.getOuterR() -
140 m_SectorSupportGeometry.getThickness());
141 Circle2D circleOuterOuter(0, 0, m_SectorSupportPosition.getOuterR());
144 p.setX(m_SectorSupportPosition.getX());
145 p.setY(m_SectorSupportPosition.getOuterR() -
146 m_SectorSupportGeometry.getDeltaLY());
148 m_SectorSupportGeometry.setCorner1A(p);
150 m_SectorSupportGeometry.setCorner1B(intersections[1]);
151 m_SectorSupportGeometry.setCornerAngle(
152 atan2(m_SectorSupportGeometry.getCorner1B().y() -
153 m_SectorSupportGeometry.getCorner1A().y(),
154 m_SectorSupportGeometry.getCorner1B().x() -
155 m_SectorSupportGeometry.getCorner1A().x()) * CLHEP::rad);
156 p.setX(m_SectorSupportPosition.getX() +
157 m_SectorSupportGeometry.getThickness());
158 p.setY(m_SectorSupportGeometry.getCorner1A().y() -
159 m_SectorSupportGeometry.getThickness() *
160 (1.0 / cos(m_SectorSupportGeometry.getCornerAngle()) -
161 tan(m_SectorSupportGeometry.getCornerAngle())));
163 m_SectorSupportGeometry.setCorner1AInner(p);
164 Line2D lineCorner1(m_SectorSupportGeometry.getCorner1AInner().x(),
165 m_SectorSupportGeometry.getCorner1AInner().y(),
166 m_SectorSupportGeometry.getCorner1B().x() -
167 m_SectorSupportGeometry.getCorner1A().x(),
168 m_SectorSupportGeometry.getCorner1B().y() -
169 m_SectorSupportGeometry.getCorner1A().y());
171 m_SectorSupportGeometry.setCorner1BInner(intersections[1]);
174 m_SectorSupportGeometry.setCorner2Inner(intersections[1]);
177 m_SectorSupportGeometry.setCorner3(intersections[1]);
179 m_SectorSupportGeometry.setCorner3Inner(intersections[1]);
181 p.setX(intersections[1].x());
182 p.setY(m_SectorSupportPosition.getY() +
183 m_SectorSupportGeometry.getThickness());
185 m_SectorSupportGeometry.setCorner3Prism(p);
188 m_SectorSupportGeometry.setCorner4(intersections[1]);
190 m_SectorSupportGeometry.setCorner4Inner(intersections[1]);
192 p.setX(m_SectorSupportPosition.getX() +
193 m_SectorSupportGeometry.getThickness());
194 p.setY(intersections[1].y());
196 m_SectorSupportGeometry.setCorner4Prism(p);
199 static bool compareLength(
double a,
double b)
206 const char err[] =
"Strip sorting algorithm error.";
209 std::vector<double> strips;
210 std::vector<double>::iterator it;
211 std::map<double, int> mapLengthStrip;
212 std::map<double, int> mapLengthStrip2;
213 std::map<double, int>::iterator itm;
214 for (i = 0; i < m_NStrips; i++) {
215 strips.push_back(m_StripPosition[i].getLength());
216 mapLengthStrip.insert(
217 std::pair<double, int>(m_StripPosition[i].getLength(), i));
219 sort(strips.begin(), strips.end(), compareLength);
221 m_nStripDifferent = 1;
222 for (it = strips.begin(); it != strips.end(); ++it) {
228 m_StripLenToAll = (
int*)malloc(m_nStripDifferent *
sizeof(
int));
229 if (m_StripLenToAll ==
nullptr)
233 itm = mapLengthStrip.find(l);
234 if (itm == mapLengthStrip.end())
236 m_StripLenToAll[i] = itm->second;
237 mapLengthStrip2.insert(std::pair<double, int>(l, i));
238 for (it = strips.begin(); it != strips.end(); ++it) {
242 itm = mapLengthStrip.find(l);
243 if (itm == mapLengthStrip.end())
245 m_StripLenToAll[i] = itm->second;
246 mapLengthStrip2.insert(std::pair<double, int>(l, i));
249 m_StripAllToLen = (
int*)malloc(m_NStrips *
sizeof(
int));
250 if (m_StripAllToLen ==
nullptr)
252 for (i = 0; i < m_NStrips; i++) {
253 itm = mapLengthStrip2.find(m_StripPosition[i].getLength());
254 if (itm == mapLengthStrip2.end())
256 m_StripAllToLen[i] = itm->second;
266 m_StripGeometry.setWidth(Strips.
getLength(
"Width") * CLHEP::cm);
267 m_StripGeometry.setThickness(Strips.
getLength(
"Thickness") * CLHEP::cm);
268 m_StripGeometry.setGrooveDepth(Strips.
getLength(
"GrooveDepth") * CLHEP::cm);
269 m_StripGeometry.setGrooveWidth(Strips.
getLength(
"GrooveWidth") * CLHEP::cm);
270 m_StripGeometry.setNoScintillationThickness(
271 Strips.
getLength(
"NoScintillationThickness") * CLHEP::cm);
272 m_StripGeometry.setRSSSize(Strips.
getLength(
"RSSSize") * CLHEP::cm);
275 }
catch (std::bad_alloc& ba) {
278 for (i = 0; i < m_NStrips; i++) {
280 name =
"/Strip[" + std::to_string(i + 1) +
"]";
281 StripContent.
append(name.c_str());
282 m_StripPosition[i].setLength(StripContent.
getLength(
"Length") * CLHEP::cm);
283 m_StripPosition[i].setX(StripContent.
getLength(
"X") * CLHEP::cm);
284 m_StripPosition[i].setY(StripContent.
getLength(
"Y") * CLHEP::cm);
285 m_StripPosition[i].setZ(StripContent.
getLength(
"Z") * CLHEP::cm);
300 double r,
double kx,
double ky,
301 double& dx,
double& dy)
306 double a, b, c, d, t, maxt = 0, x1, y1, x2, y2, u;
313 a = kx * kx + ky * ky;
314 intersection =
false;
315 for (i = 0; i < nPoints; i++) {
318 b = 2.0 * (kx * x1 + ky * y1);
319 c = x1 * x1 + y1 * y1 - r * r;
320 d = b * b - 4.0 * a * c;
322 t = (-b + sqrt(d)) / (2.0 * a);
333 B2FATAL(
"Shield layer geometry calculation error.");
344 for (i = 0; i < nPoints; i++) {
347 if (i < nPoints - 1) {
348 x2 = points[i + 1].x();
349 y2 = points[i + 1].y();
354 a = (x2 - x1) * ky - (y2 - y1) * kx;
357 b = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
358 t = (x1 * y2 - x2 * y1 + r * sqrt(b)) / a;
364 u = -((x2 - x1) * (x1 + kx * t) + (y2 - y1) * (y2 + ky * t)) / b;
382 pointCLHEP.setX(pointEKLM->
getX());
383 pointCLHEP.setY(pointEKLM->
getY());
390 double r, l, dx, dy, xCenter, yCenter;
391 const double asqrt2 = 1.0 / sqrt(2.0);
397 r = m_SectorSupportPosition.getInnerR() +
398 m_SectorSupportGeometry.getThickness();
400 EKLMPointToCLHEP(detailA->
getPoint(0), points[0]);
401 EKLMPointToCLHEP(detailA->
getPoint(1), points[1]);
402 EKLMPointToCLHEP(detailA->
getPoint(2), points[2]);
403 EKLMPointToCLHEP(detailA->
getPoint(3), points[3]);
404 EKLMPointToCLHEP(detailA->
getPoint(4), points[4]);
408 EKLMPointToCLHEP(detailA->
getPoint(5), points[6]);
409 EKLMPointToCLHEP(detailA->
getPoint(6), points[7]);
411 xCenter = -asqrt2 * l;
412 yCenter = asqrt2 * l;
413 for (i = 0; i < 8; i++)
414 points[i] = HepGeom::Translate3D(xCenter, yCenter, 0) *
415 HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
416 HepGeom::Translate3D(-detailA->
getLengthX() / 2,
419 getDetailDxDy(points, 8, r, 1, 1, dx, dy);
420 m_ShieldGeometry.setDetailACenter(xCenter + dx, yCenter + dy);
434 EKLMPointToCLHEP(detailB->
getPoint(0), points[4]);
435 EKLMPointToCLHEP(detailB->
getPoint(1), points[5]);
436 EKLMPointToCLHEP(detailB->
getPoint(2), points[6]);
437 EKLMPointToCLHEP(detailB->
getPoint(3), points[7]);
439 for (i = 0; i < 8; i++)
440 points[i] = HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
441 HepGeom::Translate3D(-detailB->
getLengthX() / 2,
444 getDetailDxDy(points, 8, r, 1, 1, dx, dy);
445 m_ShieldGeometry.setDetailBCenter(dx, dy);
447 EKLMPointToCLHEP(detailC->
getPoint(0), points[0]);
448 EKLMPointToCLHEP(detailC->
getPoint(1), points[1]);
449 EKLMPointToCLHEP(detailC->
getPoint(2), points[2]);
450 EKLMPointToCLHEP(detailC->
getPoint(3), points[3]);
451 EKLMPointToCLHEP(detailC->
getPoint(4), points[4]);
455 EKLMPointToCLHEP(detailC->
getPoint(5), points[6]);
456 EKLMPointToCLHEP(detailC->
getPoint(6), points[7]);
458 xCenter = asqrt2 * l;
459 yCenter = -asqrt2 * l;
460 for (i = 0; i < 8; i++)
461 points[i] = HepGeom::Translate3D(xCenter, yCenter, 0) *
462 HepGeom::RotateZ3D(-45.0 * CLHEP::deg) *
463 HepGeom::RotateY3D(180.0 * CLHEP::deg) *
464 HepGeom::Translate3D(-detailC->
getLengthX() / 2,
467 getDetailDxDy(points, 8, r, 1, 1, dx, dy);
468 m_ShieldGeometry.setDetailCCenter(xCenter + dx, yCenter + dy);
474 d.append(
"/EndcapStructure");
475 m_EndcapStructureGeometry.setPhi(d.getAngle(
"Phi") * CLHEP::rad);
476 m_EndcapStructureGeometry.setNSides(d.getInt(
"NSides"));
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]);
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);
508 m_SolenoidZ = gd.
getLength(
"SolenoidZ") * CLHEP::cm;
509 readEndcapStructureGeometry(gd);
511 section.append(
"/Section");
512 readPositionData(&m_SectionPosition, §ion);
513 readSizeData(&m_SectionPosition, §ion);
515 layer.append(
"/Layer");
516 readSizeData(&m_LayerPosition, &layer);
517 m_LayerShiftZ = layer.getLength(
"ShiftZ") * CLHEP::cm;
519 sector.append(
"/Sector");
520 readSizeData(&m_SectorPosition, §or);
522 sectorSupport.
append(
"/SectorSupport");
523 readPositionData(&m_SectorSupportPosition, §orSupport);
524 readSizeData(&m_SectorSupportPosition, §orSupport);
525 readSectorSupportGeometry(&m_SectorSupportGeometry, §orSupport);
527 plane.append(
"/Plane");
528 readPositionData(&m_PlanePosition, &plane);
529 readSizeData(&m_PlanePosition, &plane);
531 plasticSheet.
append(
"/PlasticSheet");
532 m_PlasticSheetGeometry.setWidth(plasticSheet.
getLength(
"Width") * CLHEP::cm);
533 m_PlasticSheetGeometry.setDeltaL(plasticSheet.
getLength(
"DeltaL") *
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);
546 m_SegmentSupportPosition =
548 }
catch (std::bad_alloc& ba) {
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.c_str());
557 name =
"/SegmentSupport[" + std::to_string(i + 1) +
"]";
558 segmentSupport2.append(name.c_str());
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);
573 readXMLDataStrips(gd);
576 m_ShieldGeometry.setThickness(shield.
getLength(
"Thickness") * CLHEP::cm);
578 shieldDetailA.
append(
"/Detail[@id=\"A\"]");
579 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailA);
580 m_ShieldGeometry.setDetailA(shieldDetailGeometry);
582 shieldDetailB.
append(
"/Detail[@id=\"B\"]");
583 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailB);
584 m_ShieldGeometry.setDetailB(shieldDetailGeometry);
586 shieldDetailC.
append(
"/Detail[@id=\"C\"]");
587 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailC);
588 m_ShieldGeometry.setDetailC(shieldDetailGeometry);
590 shieldDetailD.
append(
"/Detail[@id=\"D\"]");
591 readShieldDetailGeometry(&shieldDetailGeometry, &shieldDetailD);
592 m_ShieldGeometry.setDetailD(shieldDetailGeometry);
600 B2FATAL(
"No EKLM geometry data in the database.");
608 m_Geometry =
nullptr;
609 switch (dataSource) {
611 initializeFromGearbox(gearDir);
614 initializeFromDatabase();
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();
628 if (m_Geometry !=
nullptr)
630 free(m_StripLenToAll);
631 free(m_StripAllToLen);
643 return (zMm > m_MinZForward) || (zMm < m_MaxZBackward);
653 *t = HepGeom::Translate3D(m_SectionPosition.getX(), m_SectionPosition.getY(),
654 -m_SectionPosition.getZ() + m_SolenoidZ);
656 *t = HepGeom::Translate3D(m_SectionPosition.getX(), m_SectionPosition.getY(),
657 m_SectionPosition.getZ() + m_SolenoidZ) *
658 HepGeom::RotateY3D(180.*CLHEP::deg);
664 *t = HepGeom::Translate3D(0.0, 0.0, m_SectionPosition.getLength() / 2.0 -
665 (n + 1) * m_LayerShiftZ +
666 0.5 * m_LayerPosition.getLength());
674 *t = HepGeom::Translate3D(0., 0., 0.);
677 *t = HepGeom::RotateY3D(180.0 * CLHEP::deg);
680 *t = HepGeom::RotateZ3D(90.0 * CLHEP::deg) *
681 HepGeom::RotateY3D(180.0 * CLHEP::deg);
684 *t = HepGeom::RotateZ3D(-90.0 * CLHEP::deg);
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.));
698 *t = HepGeom::Translate3D(m_PlanePosition.getX(), m_PlanePosition.getY(),
699 -m_PlanePosition.getZ());
705 *t = HepGeom::Translate3D(m_StripPosition[n].getX(),
706 m_StripPosition[n].getY(), 0.0);
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);