Estimation of the geometrical volume span.
438 {
439
440 const CuboidVolumeBounds* box =
441 dynamic_cast<const CuboidVolumeBounds*>(&volBounds);
442 const TrapezoidVolumeBounds* trd =
443 dynamic_cast<const TrapezoidVolumeBounds*>(&volBounds);
444 const DoubleTrapezoidVolumeBounds* dtrd =
445 dynamic_cast<const DoubleTrapezoidVolumeBounds*>(&volBounds);
446 const BevelledCylinderVolumeBounds* bcyl =
447 dynamic_cast<const BevelledCylinderVolumeBounds*>(&volBounds);
448 const CylinderVolumeBounds* cyl =
449 dynamic_cast<const CylinderVolumeBounds*>(&volBounds);
450 const SubtractedVolumeBounds* sub =
451 dynamic_cast<const SubtractedVolumeBounds*>(&volBounds);
452 const CombinedVolumeBounds* comb =
453 dynamic_cast<const CombinedVolumeBounds*>(&volBounds);
454 const SimplePolygonBrepVolumeBounds* spb =
455 dynamic_cast<const SimplePolygonBrepVolumeBounds*>(&volBounds);
456 const PrismVolumeBounds* prism =
457 dynamic_cast<const PrismVolumeBounds*>(&volBounds);
458
460
461 if (sub) {
463 transform * sub->outer()->transform(), zTol,
464 phiTol);
465 }
466
467 if (comb) {
469 comb->first()->volumeBounds(),
470 transform * comb->first()->transform(), zTol, phiTol);
472 comb->second()->volumeBounds(),
473 transform * comb->second()->transform(), zTol, phiTol);
474
475 VolumeSpan scomb;
476 scomb.rMin = std::min((*s1).rMin, (*s2).rMin);
477 scomb.rMax = std::max((*s1).rMax, (*s2).rMax);
478 scomb.xMin = std::min((*s1).xMin, (*s2).xMin);
479 scomb.xMax = std::max((*s1).xMax, (*s2).xMax);
480 scomb.yMin = std::min((*s1).yMin, (*s2).yMin);
481 scomb.yMax = std::max((*s1).yMax, (*s2).yMax);
482 scomb.zMin = std::min((*s1).zMin, (*s2).zMin);
483 scomb.zMax = std::max((*s1).zMax, (*s2).zMax);
484 if ((*s1).phiMin < (*s1).phiMax && (*s2).phiMin < (*s2).phiMax) {
485 scomb.phiMin = std::min((*s1).phiMin, (*s2).phiMin);
486 scomb.phiMax = std::max((*s1).phiMax, (*s2).phiMax);
487 } else if ((*s1).phiMin < (*s1).phiMax && (*s2).phiMin > (*s2).phiMax) {
488 if ((*s1).phiMin > (*s2).phiMax) {
489 scomb.phiMin = std::min((*s1).phiMin, (*s2).phiMin);
490 scomb.phiMax = (*s2).phiMax;
491 } else if ((*s1).phiMax < (*s2).phiMin) {
492 scomb.phiMin = (*s2).phiMin;
493 scomb.phiMax = std::max((*s1).phiMax, (*s2).phiMax);
494 } else {
495 scomb.phiMin = 0.;
496 scomb.phiMax = 2 *
M_PI;
497 }
498 } else if ((*s1).phiMin > (*s1).phiMax && (*s2).phiMin < (*s2).phiMax) {
499 if ((*s2).phiMin > (*s1).phiMax) {
500 scomb.phiMin = std::min((*s1).phiMin, (*s2).phiMin);
501 scomb.phiMax = (*s1).phiMax;
502 } else if ((*s2).phiMax < (*s1).phiMin) {
503 scomb.phiMin = (*s1).phiMin;
504 scomb.phiMax = std::max((*s1).phiMax, (*s2).phiMax);
505 } else {
506 scomb.phiMin = 0.;
507 scomb.phiMax = 2 *
M_PI;
508 }
509 } else {
510 scomb.phiMin = std::min((*s1).phiMin, (*s2).phiMin);
511 scomb.phiMax = std::max((*s1).phiMax, (*s2).phiMax);
512 }
513 return std::make_unique<VolumeSpan>(scomb);
514 }
515
516
517 double minZ{1.e6};
518 double maxZ{-1.e6};
519 double minPhi{2 *
M_PI};
520 double maxPhi{0.};
521 double minR{1.e6};
522 double maxR{0.};
523 double minX{1.e6};
524 double maxX{-1.e6};
525 double minY{1.e6};
526 double maxY{-1.e6};
527
528
529 std::vector<Amg::Vector3D> vtx;
530 std::vector<std::pair<int, int>> edges;
532
533 if (box) {
534 vtx.emplace_back(box->halflengthX(), box->halflengthY(),
535 box->halflengthZ());
536 vtx.emplace_back(-box->halflengthX(), box->halflengthY(),
537 box->halflengthZ());
538 vtx.emplace_back(box->halflengthX(), -box->halflengthY(),
539 box->halflengthZ());
540 vtx.emplace_back(-box->halflengthX(), -box->halflengthY(),
541 box->halflengthZ());
542 vtx.emplace_back(box->halflengthX(), box->halflengthY(),
543 -box->halflengthZ());
544 vtx.emplace_back(-box->halflengthX(), box->halflengthY(),
545 -box->halflengthZ());
546 vtx.emplace_back(box->halflengthX(), -box->halflengthY(),
547 -box->halflengthZ());
548 vtx.emplace_back(-box->halflengthX(), -box->halflengthY(),
549 -box->halflengthZ());
550 edges.emplace_back(0, 1);
551 edges.emplace_back(0, 2);
552 edges.emplace_back(1, 3);
553 edges.emplace_back(2, 3);
554 edges.emplace_back(4, 5);
555 edges.emplace_back(4, 6);
556 edges.emplace_back(5, 7);
557 edges.emplace_back(6, 7);
558 edges.emplace_back(0, 4);
559 edges.emplace_back(1, 5);
560 edges.emplace_back(2, 6);
561 edges.emplace_back(3, 7);
562 }
563 if (trd) {
564 vtx.emplace_back(trd->maxHalflengthX(), trd->halflengthY(),
565 trd->halflengthZ());
566 vtx.emplace_back(-trd->maxHalflengthX(), trd->halflengthY(),
567 trd->halflengthZ());
568 vtx.emplace_back(trd->minHalflengthX(), -trd->halflengthY(),
569 trd->halflengthZ());
570 vtx.emplace_back(-trd->minHalflengthX(), -trd->halflengthY(),
571 trd->halflengthZ());
572 vtx.emplace_back(trd->maxHalflengthX(), trd->halflengthY(),
573 -trd->halflengthZ());
574 vtx.emplace_back(-trd->maxHalflengthX(), trd->halflengthY(),
575 -trd->halflengthZ());
576 vtx.emplace_back(trd->minHalflengthX(), -trd->halflengthY(),
577 -trd->halflengthZ());
578 vtx.emplace_back(-trd->minHalflengthX(), -trd->halflengthY(),
579 -trd->halflengthZ());
580 edges.emplace_back(0, 1);
581 edges.emplace_back(0, 2);
582 edges.emplace_back(1, 3);
583 edges.emplace_back(2, 3);
584 edges.emplace_back(4, 5);
585 edges.emplace_back(4, 6);
586 edges.emplace_back(5, 7);
587 edges.emplace_back(6, 7);
588 edges.emplace_back(0, 4);
589 edges.emplace_back(1, 5);
590 edges.emplace_back(2, 6);
591 edges.emplace_back(3, 7);
592 }
593 if (dtrd) {
594 vtx.emplace_back(dtrd->maxHalflengthX(), 2 * dtrd->halflengthY2(),
595 dtrd->halflengthZ());
596 vtx.emplace_back(-dtrd->maxHalflengthX(), 2 * dtrd->halflengthY2(),
597 dtrd->halflengthZ());
598 vtx.emplace_back(dtrd->medHalflengthX(), 0., dtrd->halflengthZ());
599 vtx.emplace_back(-dtrd->medHalflengthX(), 0., dtrd->halflengthZ());
600 vtx.emplace_back(dtrd->minHalflengthX(), -2 * dtrd->halflengthY1(),
601 dtrd->halflengthZ());
602 vtx.emplace_back(-dtrd->minHalflengthX(), -2 * dtrd->halflengthY1(),
603 dtrd->halflengthZ());
604 vtx.emplace_back(dtrd->maxHalflengthX(), 2 * dtrd->halflengthY2(),
605 -dtrd->halflengthZ());
606 vtx.emplace_back(-dtrd->maxHalflengthX(), 2 * dtrd->halflengthY2(),
607 -dtrd->halflengthZ());
608 vtx.emplace_back(dtrd->medHalflengthX(), 0., -dtrd->halflengthZ());
609 vtx.emplace_back(-dtrd->medHalflengthX(), 0., -dtrd->halflengthZ());
610 vtx.emplace_back(dtrd->minHalflengthX(), -2 * dtrd->halflengthY1(),
611 -dtrd->halflengthZ());
612 vtx.emplace_back(-dtrd->minHalflengthX(), -2 * dtrd->halflengthY1(),
613 -dtrd->halflengthZ());
614 edges.emplace_back(0, 1);
615 edges.emplace_back(0, 2);
616 edges.emplace_back(1, 3);
617 edges.emplace_back(2, 4);
618 edges.emplace_back(3, 5);
619 edges.emplace_back(4, 5);
620 edges.emplace_back(6, 7);
621 edges.emplace_back(6, 8);
622 edges.emplace_back(7, 9);
623 edges.emplace_back(8, 10);
624 edges.emplace_back(9, 11);
625 edges.emplace_back(10, 11);
626 edges.emplace_back(0, 6);
627 edges.emplace_back(1, 7);
628 edges.emplace_back(2, 8);
629 edges.emplace_back(3, 9);
630 edges.emplace_back(4, 10);
631 edges.emplace_back(5, 11);
632 }
633 if (bcyl) {
634 dPhi = bcyl->halfPhiSector();
635 vtx.emplace_back(0., 0., bcyl->halflengthZ());
636 vtx.emplace_back(0., 0., -bcyl->halflengthZ());
637 edges.emplace_back(0, 1);
639 const double cosDphi = std::cos(dPhi);
640 const double sinDphi = std::sin(dPhi);
641 vtx.emplace_back(bcyl->outerRadius() * cosDphi,
642 bcyl->outerRadius() * sinDphi,
643 bcyl->halflengthZ());
644 vtx.emplace_back(bcyl->innerRadius() * cosDphi,
645 bcyl->innerRadius() * sinDphi,
646 bcyl->halflengthZ());
647 vtx.emplace_back(bcyl->outerRadius() * cosDphi,
648 -bcyl->outerRadius() * sinDphi,
649 bcyl->halflengthZ());
650 vtx.emplace_back(bcyl->innerRadius() * cosDphi,
651 -bcyl->innerRadius() * sinDphi,
652 bcyl->halflengthZ());
653 vtx.emplace_back(bcyl->outerRadius() * cosDphi,
654 bcyl->outerRadius() * sinDphi,
655 -bcyl->halflengthZ());
656 vtx.emplace_back(bcyl->innerRadius() * cosDphi,
657 bcyl->innerRadius() * sinDphi,
658 -bcyl->halflengthZ());
659 vtx.emplace_back(bcyl->outerRadius() * cosDphi,
660 -bcyl->outerRadius() * sinDphi,
661 -bcyl->halflengthZ());
662 vtx.emplace_back(bcyl->innerRadius() * cosDphi,
663 -bcyl->innerRadius() * sinDphi,
664 -bcyl->halflengthZ());
665 vtx.emplace_back(bcyl->outerRadius(), 0.,
666 0.);
667
668 edges.emplace_back(2, 3);
669 edges.emplace_back(4, 5);
670 edges.emplace_back(6, 7);
671 edges.emplace_back(8, 9);
672 if (bcyl->type() == 1 || bcyl->type() == 3) {
673 edges.emplace_back(3, 5);
674 edges.emplace_back(7, 9);
675 }
676 if (bcyl->type() == 2 || bcyl->type() == 3) {
677 edges.emplace_back(2, 4);
678 edges.emplace_back(6, 8);
679 }
680 }
681 }
682 if (cyl) {
683 dPhi = cyl->halfPhiSector();
684 vtx.emplace_back(0., 0., cyl->halflengthZ());
685 vtx.emplace_back(0., 0., -cyl->halflengthZ());
686 edges.emplace_back(0, 1);
688 const double cosDphi = std::cos(dPhi);
689 const double sinDphi = std::sin(dPhi);
690 vtx.emplace_back(cyl->outerRadius() * cosDphi,
691 cyl->outerRadius() * sinDphi, cyl->halflengthZ());
692 vtx.emplace_back(cyl->innerRadius() * cosDphi,
693 cyl->innerRadius() * sinDphi, cyl->halflengthZ());
694 vtx.emplace_back(cyl->outerRadius() * cosDphi,
695 -cyl->outerRadius() * sinDphi, cyl->halflengthZ());
696 vtx.emplace_back(cyl->outerRadius() * cosDphi,
697 -cyl->outerRadius() * sinDphi, cyl->halflengthZ());
698 vtx.emplace_back(cyl->outerRadius() * cosDphi,
699 cyl->outerRadius() * sinDphi, -cyl->halflengthZ());
700 vtx.emplace_back(cyl->innerRadius() * cosDphi,
701 cyl->innerRadius() * sinDphi, -cyl->halflengthZ());
702 vtx.emplace_back(cyl->outerRadius() * cosDphi,
703 -cyl->outerRadius() * sinDphi,
704 -cyl->halflengthZ());
705 vtx.emplace_back(cyl->outerRadius() * cosDphi,
706 -cyl->outerRadius() * sinDphi,
707 -cyl->halflengthZ());
708 vtx.emplace_back(cyl->outerRadius(), 0.,
709 0.);
710
711 edges.emplace_back(2, 3);
712 edges.emplace_back(4, 5);
713 edges.emplace_back(6, 7);
714 edges.emplace_back(8, 9);
715 }
716 }
717
718 if (spb) {
719 const std::vector<std::pair<double, double>> vtcs = spb->xyVertices();
720 for (const auto& vtc : vtcs) {
721 vtx.emplace_back(vtc.first, vtc.second, spb->halflengthZ());
722 vtx.emplace_back(vtc.first, vtc.second, -spb->halflengthZ());
723 edges.emplace_back(vtx.size() - 2, vtx.size() - 1);
724 if (vtx.size() > 2) {
725 edges.emplace_back(
726 vtx.size() - 4, vtx.size() - 2);
727 edges.emplace_back(
728 vtx.size() - 3, vtx.size() - 1);
729 }
730 if (vtx.size() > 4) {
731 edges.emplace_back(vtx.size() - 2, 1);
732 edges.emplace_back(vtx.size() - 1, 0);
733 }
734 }
735 edges.emplace_back(0, vtx.size() - 2);
736 edges.emplace_back(1, vtx.size() - 1);
737 }
738
739 if (prism) {
740 const std::vector<std::pair<double, double>> vtcs = prism->xyVertices();
741 for (const auto& vtc : vtcs) {
742 vtx.emplace_back(vtc.first, vtc.second, prism->halflengthZ());
743 vtx.emplace_back(vtc.first, vtc.second, -prism->halflengthZ());
744 edges.emplace_back(vtx.size() - 2, vtx.size() - 1);
745 if (vtx.size() > 2) {
746 edges.emplace_back(
747 vtx.size() - 4, vtx.size() - 2);
748 edges.emplace_back(
749 vtx.size() - 3, vtx.size() - 1);
750 }
751 }
752 edges.emplace_back(0, vtx.size() - 2);
753 edges.emplace_back(1, vtx.size() - 1);
754 }
755
756 std::vector<Amg::Vector3D> vtxt;
757
758 for (
unsigned int ie = 0;
ie < vtx.size();
ie++) {
760 vtxt.push_back(gp);
761
763 double rad = gp.perp();
764
765
766 minX = std::min(minX, gp[0]);
767 maxX = std::max(maxX, gp[0]);
768 minY = std::min(minY, gp[1]);
769 maxY = std::max(maxY, gp[1]);
770 minZ = std::min(minZ, gp[2]);
771 maxZ = std::max(maxZ, gp[2]);
772 minR = std::min(minR, rad);
773 maxR = std::max(maxR, rad);
774 maxPhi = std::max(maxPhi,
phi);
775 minPhi = std::min(minPhi,
phi);
776 }
777
778 if (cyl || bcyl) {
779
780 double ro = cyl ? cyl->outerRadius() : bcyl->outerRadius();
781 double ri = cyl ? cyl->innerRadius() : bcyl->innerRadius();
782
784 (vtxt[edges[0].first] - vtxt[edges[0].second]).
unit();
785 maxZ += ro *
sin(
dir.theta());
786 minZ += -ro *
sin(
dir.theta());
787
788 if (ro < minR) {
789
790 PerigeeSurface peri;
791 Intersection closest = peri.straightLineIntersection(vtxt[1], dir);
792 double le = (vtxt[0] - vtxt[1]).
norm();
793 if ((closest.position - vtxt[0]).norm() < le &&
794 (closest.position - vtxt[1]).norm() < le) {
795 if (minR > closest.position.perp() - ro)
796 minR = std::max(0., closest.position.perp() - ro);
797
798 double phiClosest = closest.position.phi() +
M_PI;
799 if (phiClosest < minPhi || phiClosest > maxPhi) {
800 double phiTmp = minPhi;
801 minPhi = maxPhi;
802 maxPhi = phiTmp;
803 }
804 } else
805 minR = std::max(0., minR - ro * std::abs(
dir.z()));
806
807 const double aTan = std::atan2(ro, minR);
808 minPhi += -aTan;
809 maxPhi += aTan;
810 if (minPhi < 0)
812 if (maxPhi > 2 *
M_PI)
814
815 maxR += ro * std::abs(
cos(
dir.theta()));
816 } else {
817
818 double rAx = std::max(vtxt[0].
perp(), vtxt[1].
perp());
819 if (rAx < ri)
820 minR = ri - rAx;
821 else
822 minR = std::max(0., minR - ro * std::abs(
cos(
dir.theta())));
823
824
825 PerigeeSurface peri;
826 for (
unsigned int ie = 0;
ie < edges.size();
ie++) {
828 (vtxt[edges[
ie].first] - vtxt[edges[
ie].second]).
unit();
829 Intersection closest =
830 peri.straightLineIntersection(vtxt[edges[ie].second], dir);
831 double le =
832 (vtxt[edges[
ie].first] - vtxt[edges[
ie].second]).
norm();
833 if ((closest.position - vtxt[edges[ie].first]).norm() < le &&
834 (closest.position - vtxt[edges[ie].second]).norm() < le)
835 if (minR > closest.position.perp())
836 minR = closest.position.perp();
837 }
838
839 if (vtxt.size() > 10) {
840
841
842 double phiSecLmin = std::min(
845 double phiSecLmax = std::max(
848
849
850 double phiSecUmin = std::min(
853 double phiSecUmax = std::max(
856 minPhi = std::min(std::min(phiSecLmin, phiSecLmax),
857 std::min(phiSecUmin, phiSecUmax));
858 maxPhi = std::max(std::max(phiSecLmin, phiSecLmax),
859 std::max(phiSecUmin, phiSecUmax));
860 if (vtxt[10].
phi() +
M_PI < minPhi ||
861 vtxt[10].
phi() +
M_PI > maxPhi) {
863 maxPhi = 0.;
864 double phiTmp;
865 for (unsigned int iv = 2; iv < vtxt.size(); iv++) {
866 phiTmp = vtxt[iv].phi() +
M_PI;
869 minPhi = phiTmp < minPhi ? phiTmp : minPhi;
870 maxPhi = phiTmp > maxPhi ? phiTmp : maxPhi;
871 }
872 if (minPhi > 2 *
M_PI)
874 if (maxPhi > 2 *
M_PI)
876 }
877 } else {
878 minPhi = 0.;
880 maxR += ro * std::abs(std::cos(
dir.theta()));
881 }
882 if (minPhi >= maxPhi && (minPhi - maxPhi) <
M_PI) {
883 minPhi = 0.;
885 }
886 }
887 }
888
889 if (!cyl && !bcyl) {
890
891 PerigeeSurface peri;
892 for (
unsigned int ie = 0;
ie < edges.size();
ie++) {
894 (vtxt[edges[
ie].first] - vtxt[edges[
ie].second]).
unit();
895 Intersection closest =
896 peri.straightLineIntersection(vtxt[edges[ie].second], dir);
897 double le = (vtxt[edges[
ie].first] - vtxt[edges[
ie].second]).
norm();
898 if ((closest.position - vtxt[edges[ie].first]).norm() < le &&
899 (closest.position - vtxt[edges[ie].second]).norm() < le)
900 if (minR > closest.position.perp())
901 minR = closest.position.perp();
902 }
903
904 if (std::abs(maxPhi - minPhi) >
M_PI) {
905 double phiTmp = minPhi;
907 maxPhi = 0.;
908 for (unsigned int iv = 0; iv < vtxt.size(); iv++) {
909 phiTmp = vtxt[iv].phi() +
M_PI;
912 minPhi = phiTmp < minPhi ? phiTmp : minPhi;
913 maxPhi = phiTmp > maxPhi ? phiTmp : maxPhi;
914 }
915 if (minPhi > 2 *
M_PI)
917 if (maxPhi > 2 *
M_PI)
919 if (minPhi >= maxPhi && (minPhi - maxPhi) <
M_PI) {
920 minPhi = 0.;
922 }
923 }
924 }
925
926 if (cyl || bcyl || box || trd || dtrd || spb || prism) {
927 span.zMin = minZ - zTol;
928 span.zMax = maxZ - +zTol;
929 minPhi = (minPhi - phiTol) < 0 ? minPhi - phiTol + 2 *
M_PI
930 : minPhi - phiTol;
931 span.phiMin = minPhi;
932 maxPhi = (maxPhi + phiTol) > 2 *
M_PI ? maxPhi + phiTol - 2 *
M_PI
933 : maxPhi + phiTol;
934 span.phiMax = maxPhi;
935 span.rMin = std::max(70.001, minR - zTol);
936 span.rMax = maxR + zTol;
937 span.xMin = minX - zTol;
938 span.xMax = maxX - +zTol;
939 span.yMin = minY - zTol;
940 span.yMax = maxY - +zTol;
941 } else {
943 }
944 return std::make_unique<VolumeSpan>(span);
945}
Scalar perp() const
perp method - perpendicular length
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
#define ATH_MSG_WARNING(x)
std::unique_ptr< VolumeSpan > findVolumeSpan(const VolumeBounds &volBounds, const Amg::Transform3D &transform, double zTol, double phiTol) const
Estimation of the geometrical volume span.
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Eigen::Matrix< double, 3, 1 > Vector3D
CxxUtils::transform_view_with_at< PackedLinkVector_span, ELSpanConverter > span
bool dPhi(const xAOD::TauJet &tau, const xAOD::CaloVertexedTopoCluster &cluster, float &out)