30 inline std::vector<VolumePtr> translateToShared(
const std::vector<Trk::TrackingVolume*>& inVols,
32 std::vector<VolumePtr> outVec{};
33 outVec.reserve(inVols.size());
36 outVec.emplace_back(vol);
38 outVec.emplace_back(vol, Trk::do_not_delete<Trk::TrackingVolume>);
53 declareInterface<ITrackingVolumeArrayCreator>(
this);
67 ATH_MSG_VERBOSE(
"Create VolumeArray of "<< vols.size() <<
" Volumes (with CylinderVolumeBounds) with R-binning. ");
70 double lastZmin{0.}, lastZmax{0.}, lastOuterRadius{0.};
73 std::vector<float> boundaries;
74 boundaries.reserve(vols.size() + 1);
77 std::vector<TrackingVolumeOrderPosition> volOrder;
79 auto volIter = vols.begin();
80 for (
unsigned int ivol = 0; volIter != vols.end(); ++volIter, ++ivol) {
82 if (*volIter) currentCylBounds =
dynamic_cast<const CylinderVolumeBounds*
>(&((*volIter)->volumeBounds()));
83 if (!currentCylBounds) {
84 ATH_MSG_ERROR(
"Given TrackingVolume doesn't exist or is not of shape "
85 "'CylinderVolumeBounds': return 0");
89 double currentRmin = currentCylBounds->
innerRadius();
90 double currentRmax = currentCylBounds->
outerRadius();
92 boundaries.push_back(currentRmin);
93 boundaries.push_back(currentRmax);
96 double currentZmin = (*volIter)->center().z() - currentCylBounds->
halflengthZ();
97 double currentZmax = (*volIter)->center().z() + currentCylBounds->
halflengthZ();
100 if (ivol && !navtype) {
102 if (std::abs(currentZmin - lastZmin) > 0.1 || std::abs(currentZmax - lastZmax) > 0.1) {
103 ATH_MSG_ERROR(
"Given TrackingVolume(s) do not extend in z to the same point (required) : return 0");
104 ATH_MSG_VERBOSE(
"Information : lastZmin / lastZmin = "<< lastZmin <<
" / " << currentZmin);
105 ATH_MSG_VERBOSE(
" lastZmax / currentZmax = "<< lastZmax <<
" / " << currentZmax);
109 if (std::abs(currentRmin - lastOuterRadius) > 0.1) {
110 ATH_MSG_ERROR(
"Given TrackingVolume(s) are not wrapping, neither inside-out, nor v.v. : return 0");
111 ATH_MSG_VERBOSE(
"Information : currentRmin / lastOuterRadius = "<< currentRmin <<
" / " << lastOuterRadius);
116 lastZmin = currentZmin;
117 lastZmax = currentZmax;
118 lastOuterRadius = currentRmax;
120 ATH_MSG_VERBOSE(
"Adding Volume '" << (*volIter)->volumeName() <<
"' to Array");
122 volOrder.emplace_back((*volIter), currentCylBounds->
mediumRadius() * Amg::Vector3D::UnitX());
126 if (!volOrder.empty()) {
127 auto volBinUtilR = std::make_unique<BinUtility>(boundaries,
open,
binR);
129 return std::make_unique<BinnedArray1D<TrackingVolume>>(volOrder, volBinUtilR.release());
131 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
137 bool navtype)
const {
141 std::unique_ptr<TrackingVolumeArray>
143 bool navtype)
const {
146 <<
" Volumes (with CylinderVolumeBounds) with Z-binning. ");
149 double lastRmin{0.}, lastRmax{0.}, lastZmax{0.};
152 std::vector<float> boundaries;
153 boundaries.reserve(vols.size() + 1);
156 std::vector<TrackingVolumeOrderPosition> volOrder;
158 auto volIter = vols.begin();
159 for (
unsigned int ivol = 0; volIter != vols.end(); ++volIter, ++ivol) {
161 if (*volIter)currentCylBounds =
dynamic_cast<const CylinderVolumeBounds*
>( &((*volIter)->volumeBounds()));
162 if (!currentCylBounds) {
163 ATH_MSG_ERROR(
"Given TrackingVolume doesn't exist or is not of shape 'CylinderVolumeBounds': return 0");
168 double halflengthZ = currentCylBounds->
halflengthZ();
170 double currentZmin = volCenter.z() - halflengthZ;
171 double currentZmax = volCenter.z() + halflengthZ;
172 if (!ivol) boundaries.push_back(currentZmin);
173 boundaries.push_back(currentZmax);
176 double currentRmin = currentCylBounds->
innerRadius();
177 double currentRmax = currentCylBounds->
outerRadius();
180 if (ivol && !navtype) {
182 if (std::abs(lastRmin - currentRmin) > 0.1 || std::abs(lastRmax - currentRmax) > 0.1) {
183 ATH_MSG_ERROR(
"Given TrackingVolume(s) do not have same radial extends (required): return 0");
184 ATH_MSG_VERBOSE(
"Information : lastRmin / currentRmin = " << lastRmin <<
" / " << currentRmin);
185 ATH_MSG_VERBOSE(
" lastRmax / currentRmax = " << lastRmax <<
" / " << currentRmax);
189 if (std::abs(lastZmax - currentZmin) > 0.1) {
190 ATH_MSG_ERROR(
"Given TrackingVolume(s) are not attaching in z (required) : return 0");
195 lastRmin = currentRmin;
196 lastRmax = currentRmax;
197 lastZmax = currentZmax;
202 volOrder.emplace_back((*volIter), (*volIter)->center());
205 if (!volOrder.empty()) {
206 auto volBinUtil = std::make_unique<BinUtility>(boundaries,
open,
binZ);
208 return std::make_unique<BinnedArray1D<TrackingVolume>>(volOrder, volBinUtil.release());
210 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
215 bool navtype)
const {
219 std::unique_ptr<TrackingVolumeArray>
224 <<
" Volumes (with CylinderVolumeBounds) with Phi-binning. ");
227 int nPhiBins = !vols.empty() ? vols.size() : 1;
230 std::vector<TrackingVolumeOrderPosition> volOrder;
232 auto volIter = vols.begin();
233 for (; volIter != vols.end(); ++volIter) {
237 ATH_MSG_ERROR(
"Given TrackingVolume doesn't exist or is not of shape 'CylinderVolumeBounds': return 0");
241 ATH_MSG_VERBOSE(
"Adding Volume '" << (*volIter)->volumeName()<<
"' to Array");
243 volOrder.emplace_back((*volIter), (*volIter)->transform() * (cyl->
mediumRadius() * Amg::Vector3D::UnitX()));
246 if (!volOrder.empty()) {
248 return std::make_unique<BinnedArray1D<TrackingVolume>>(volOrder, volBinUtil.release());
250 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
256 bool navtype)
const {
259 std::unique_ptr<TrackingVolumeArray>
261 bool navtype)
const {
265 const bool bevelled = std::find_if(vols.begin(),vols.end(),
267 return dynamic_cast<const BevelledCylinderVolumeBounds*>(&(ptr->volumeBounds()));
273 std::vector<TrackingVolumeOrderPosition> volOrder;
277 <<
" Volumes (with CylinderVolumeBounds) with PhiH-binning. ");
279 std::vector<std::pair<std::pair<double, int>, std::pair<double, double>>>
281 std::vector<VolumePtr> fullPhiVols;
286 double rmin{0.}, rmax{0.}, dphi{0.}, mRad{0.};
290 rmin = cyl->innerRadius();
291 rmax = cyl->outerRadius();
292 dphi = cyl->halfPhiSector();
293 mRad = cyl->mediumRadius();
295 rmin = bcyl->innerRadius();
296 rmax = bcyl->outerRadius();
297 dphi = bcyl->halfPhiSector();
298 mRad = bcyl->mediumRadius();
307 Amg::Vector3D ngp((vol->transform()) * (mRad * Amg::Vector3D::UnitX()));
308 volOrder.emplace_back(vol, ngp);
311 volPos.emplace_back(std::pair<double, int>(ngp.phi(),
type),
312 std::pair<double, double>(rmin, rmax));
314 double phi1 = ngp.phi() - dphi;
315 double phi2 = ngp.phi() + dphi;
316 if (phi1 < -2 *
M_PI) {
318 }
if (phi2 < -2 *
M_PI) {
320 }
if (phi1 > 2 *
M_PI) {
322 }
if (phi2 > 2 *
M_PI) {
330 if (std::abs(phi1 - (*iter)) < tol) {
334 if (phi1 < (*iter)) {
346 if (std::abs(phi2 - (*iter)) < tol) {
350 if (phi2 < (*iter)) {
360 phiSteps.push_back(fmin(phi1, phi2));
361 phiSteps.push_back(fmax(phi1, phi2));
364 fullPhiVols.push_back(vol);
372 for (
auto & fullPhiVol : fullPhiVols) {
375 ATH_MSG_WARNING(
"dynamic_cast<const CylinderVolumeBounds*> failed ... trying to continue loop");
378 double rmin = cyl->innerRadius();
379 double rmax = cyl->outerRadius();
381 for (
unsigned int iphi = 0; iphi <
phiSteps.size(); ++iphi) {
383 double phiRef = 0.5 *
phiSteps[iphi];
391 volOrder.emplace_back(fullPhiVol, ngp);
394 volPos.emplace_back(std::pair<double, int>(ngp.phi(), 0),
395 std::pair<double, double>(rmin, rmax));
409 std::vector<std::vector<std::pair<int, float>>> hSteps(
phiSteps.size());
410 std::vector<float> phiRef(
phiSteps.size());
414 phiRef.back() += (phiRef.back() > 0) ? -
M_PI :
M_PI;
420 for (
unsigned int i = 0;
i < volPos.size(); ++
i) {
423 int type = volPos[
i].first.second;
424 double rmin = volPos[
i].second.first;
425 double rmax = volPos[
i].second.second;
426 int tmin = (
type != 1 &&
type != 3) ? 0 : 1;
427 int tmax = (
type < 2) ? 0 : 1;
429 int phibin = phiBinUtil->bin(volOrder[
i].
second);
431 if (!hSteps[phibin].
empty()) {
432 std::vector<std::pair<int, float>>
::iterator iter =
433 hSteps[phibin].begin();
435 while (iter != hSteps[phibin].
end()) {
436 if (std::abs(rmin - (*iter).second) < tol) {
440 if (rmin < (*iter).second) {
441 hSteps[phibin].insert(iter, std::pair<int, float>(tmin, rmin));
448 hSteps[phibin].emplace_back(tmin, rmin);
449 iter = hSteps[phibin].begin();
451 while (iter != hSteps[phibin].
end()) {
452 if (std::abs(rmax - (*iter).second) < tol) {
456 if (rmax < (*iter).second) {
457 hSteps[phibin].insert(iter, std::pair<int, float>(tmax, rmax));
464 hSteps[phibin].emplace_back(tmax, rmax);
466 hSteps[phibin].emplace_back(tmin, rmin);
467 hSteps[phibin].emplace_back(tmax, rmax);
473 std::vector<BinUtility*>* hUtil =
474 new std::vector<BinUtility*>(
phiSteps.size());
476 for (
unsigned int ih = 0; ih <
phiSteps.size(); ++ih) {
477 (*hUtil)[ih] =
new BinUtility(phiRef[ih], hSteps[ih]);
480 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, phiBinUtil.release(), hUtil);
484 <<
" Volumes (with CylinderVolumeBounds) with PhiR-binning. ");
486 std::vector<float> rSteps;
487 double phiSector =
M_PI;
488 std::vector<std::pair<double, std::pair<double, double>>> volPos;
490 for (
const auto& vol : vols) {
493 ATH_MSG_WARNING(
"dynamic_cast<const CylinderVolumeBounds*> failed ... trying to continue loop");
496 double rmin = cyl->innerRadius();
497 double rmax = cyl->outerRadius();
498 double dphi = cyl->halfPhiSector();
499 if (phiSector > 0. && std::abs(dphi - phiSector) > 0.001)
500 phiSector = phiSector <
M_PI ? -1. : dphi;
503 const Amg::Vector3D ngp{vol->transform() * (cyl->mediumRadius()* Amg::Vector3D::UnitX())};
504 volOrder.emplace_back(vol, ngp);
507 volPos.emplace_back(cyl->mediumRadius(), std::make_pair(ngp.phi(), dphi));
509 if (!rSteps.empty()) {
512 while (iter != rSteps.end()) {
513 if (std::abs(rmin - (*iter)) < tol) {
517 if (rmin < (*iter)) {
518 rSteps.insert(iter, rmin);
525 rSteps.push_back(rmin);
526 iter = rSteps.begin();
528 while (iter != rSteps.end()) {
529 if (std::abs(rmax - (*iter)) < tol) {
533 if (rmax < (*iter)) {
534 rSteps.insert(iter, rmax);
541 rSteps.push_back(rmax);
543 rSteps.push_back(rmin);
544 rSteps.push_back(rmax);
548 if (phiSector > 0.) {
550 std::vector<double>
phi;
551 std::vector<int> phiSect;
552 for (
unsigned int i = 0;
i < rSteps.size() - 1; ++
i)
554 for (
unsigned int i = 0;
i < rSteps.size() - 1; ++
i)
555 phiSect.push_back(
int(
M_PI / phiSector));
558 if (rSteps.size() == 1) {
561 if (phiSector ==
M_PI) {
565 auto rBinUtil = std::make_unique<BinUtility>(rSteps,
open,
binR);
566 std::vector<BinUtility*>* phiUtil =
new std::vector<BinUtility*>(rSteps.size() - 1);
567 for (
unsigned int ip = 0;
ip < phiUtil->size(); ++
ip) {
570 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, rBinUtil.release(), phiUtil);
574 auto binGenR = std::make_unique<BinUtility>(rSteps,
open,
binR);
577 std::vector<std::vector<float>>
phiSteps(rSteps.size() - 1);
579 for (
unsigned int i = 0;
i < volPos.size(); ++
i) {
581 double phi = volPos[
i].second.first;
582 double dphi = volPos[
i].second.second;
584 int binr = binGenR->bin(volOrder[
i].
second);
586 float phi1 =
phi - dphi;
587 float phi2 =
phi + dphi;
597 if (std::abs(phi1 - (*iter)) < tol) {
601 if (phi1 < (*iter)) {
613 if (std::abs(phi2 - (*iter)) < tol) {
617 if (phi2 < (*iter)) {
627 phiSteps[binr].push_back(std::fmin(phi1, phi2));
628 phiSteps[binr].push_back(std::fmax(phi1, phi2));
633 std::vector<BinUtility*>* phiUtil =
new std::vector<BinUtility*>(
phiSteps.size());
640 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, binGenR.release(), phiUtil);
645 bool navtype)
const {
648 std::unique_ptr<TrackingVolumeArray>
650 bool navtype)
const {
653 <<
" Volumes (with CylinderVolumeBounds) with PhiZ-binning. ");
657 std::vector<TrackingVolumeOrderPosition> volOrder;
659 std::vector<float> zSteps;
661 double phiSector =
M_PI;
662 std::vector<std::pair<float, std::pair<float, float>>> volPos;
667 double zmin{0.},
zmax{0.}, dphi{0.}, mRad{0.};
669 zmin = vol->center().z() - cyl->halflengthZ();
670 zmax = vol->center().z() + cyl->halflengthZ();
671 dphi = cyl->halfPhiSector();
672 mRad = cyl->mediumRadius();
674 zmin = vol->center().z() - bcyl->halflengthZ();
675 zmax = vol->center().z() + bcyl->halflengthZ();
676 dphi = bcyl->halfPhiSector();
677 mRad = bcyl->mediumRadius();
683 if (phiSector > 0. && std::abs(dphi - phiSector) > 0.001)
684 phiSector = phiSector <
M_PI ? -1. : dphi;
687 const Amg::Vector3D ngp{vol->transform() * (mRad * Amg::Vector3D::UnitX())};
689 volOrder.emplace_back(vol, ngp);
691 volPos.emplace_back(vol->center().z(), std::make_pair(ngp.phi(), dphi));
693 if (!zSteps.empty()) {
696 while (iter != zSteps.end()) {
697 if (std::abs(
zmin - (*iter)) < tol) {
701 if (
zmin < (*iter)) {
702 zSteps.insert(iter,
zmin);
709 zSteps.push_back(
zmin);
710 iter = zSteps.begin();
712 while (iter != zSteps.end()) {
713 if (std::abs(
zmax - (*iter)) < tol) {
717 if (
zmax < (*iter)) {
718 zSteps.insert(iter,
zmax);
725 zSteps.push_back(
zmax);
727 zSteps.push_back(
zmin);
728 zSteps.push_back(
zmax);
732 if (phiSector > 0.) {
734 std::vector<float>
phi;
735 std::vector<int> phiSect;
736 for (
unsigned int i = 0;
i < zSteps.size() - 1; ++
i)
738 for (
unsigned int i = 0;
i < zSteps.size() - 1; ++
i)
739 phiSect.push_back(
int(
M_PI / phiSector));
742 if (phiSector ==
M_PI) {
745 if (zSteps.size() == 2) {
749 auto binGenZPhi =std::make_unique<BinUtility>(zSteps,
open,
binZ);
751 return std::make_unique<BinnedArray2D<TrackingVolume>>(volOrder, binGenZPhi.release());
755 auto binGenZ = std::make_unique<BinUtility>(zSteps,
open,
binZ);
758 std::vector<std::vector<float>>
phiSteps(zSteps.size() - 1);
760 for (
unsigned int i = 0;
i < volPos.size(); ++
i) {
762 float phi = volPos[
i].second.first;
763 float dphi = volPos[
i].second.second;
767 float phi1 =
phi - dphi;
768 float phi2 =
phi + dphi;
778 if (std::abs(phi1 - (*iter)) < tol) {
782 if (phi1 < (*iter)) {
794 if (std::abs(phi2 - (*iter)) < tol) {
798 if (phi2 < (*iter)) {
815 std::vector<BinUtility*>* phiUtil =
new std::vector<BinUtility*>(
phiSteps.size());
821 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, binGenZ.release(), phiUtil);
828 bool navtype)
const {
831 std::unique_ptr<TrackingVolumeArray>
835 std::vector<VolumePtr> volOrder;
837 auto volIter = vols.begin();
838 for (; volIter != vols.end(); ++volIter) {
839 const auto *currentCubBounds =
dynamic_cast<const CuboidVolumeBounds*
>(&((*volIter)->volumeBounds()));
840 if (!currentCubBounds) {
841 ATH_MSG_ERROR(
"Given TrackingVolume to TrackingVolumeArrayCreator didn't "
842 "match specified shape: return 0");
845 volOrder.push_back(*volIter);
847 if (!volOrder.empty()) {
848 auto navTransform = std::make_unique<Amg::Transform3D>(Amg::Transform3D::Identity());
849 return std::make_unique<NavBinnedArray1D<TrackingVolume>>(volOrder, binUtil, navTransform.release());
851 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
862 std::unique_ptr<TrackingVolumeArray>
865 std::vector<VolumePtr> volOrder;
867 auto volIter = vols.begin();
868 for (; volIter != vols.end(); ++volIter) {
869 const auto *currentTrdBounds =
dynamic_cast<const TrapezoidVolumeBounds*
>(&((*volIter)->volumeBounds()));
870 if (!currentTrdBounds) {
871 ATH_MSG_ERROR(
"Given TrackingVolume to TrackingVolumeArrayCreator didn't "
872 "match specified shape: return 0");
876 volOrder.push_back(*volIter);
878 if (!volOrder.empty()) {
880 return std::make_unique<NavBinnedArray1D<TrackingVolume>>(volOrder, binUtil, navTransform);
882 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
888 bool navtype)
const {
892 std::unique_ptr<TrackingVolumeArray>
895 std::vector<VolumePtr> volOrder;
897 auto volIter = vols.begin();
898 for (; volIter != vols.end(); ++volIter) {
900 if (!currentDTrdBounds) {
901 ATH_MSG_ERROR(
"Given TrackingVolume to TrackingVolumeArrayCreator didn't "
902 "match specified shape: return 0");
906 volOrder.push_back(*volIter);
908 if (!volOrder.empty()) {
910 return std::make_unique<NavBinnedArray1D<TrackingVolume>>(volOrder, binUtil, navTransform);
913 "No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");