31 inline std::vector<VolumePtr> translateToShared(
const std::vector<Trk::TrackingVolume*>& inVols,
33 std::vector<VolumePtr> outVec{};
34 outVec.reserve(inVols.size());
37 outVec.emplace_back(vol);
41 outVec.emplace_back(vol, Trk::do_not_delete<Trk::TrackingVolume>);
56 declareInterface<ITrackingVolumeArrayCreator>(
this);
85 ATH_MSG_VERBOSE(
"Create VolumeArray of "<< vols.size() <<
" Volumes (with CylinderVolumeBounds) with R-binning. ");
90 double lastOuterRadius{0.};
93 std::vector<float> boundaries;
94 boundaries.reserve(vols.size() + 1);
97 std::vector<TrackingVolumeOrderPosition> volOrder;
99 auto volIter = vols.begin();
100 for (
unsigned int ivol = 0; volIter != vols.end(); ++volIter, ++ivol) {
102 if (*volIter) currentCylBounds =
dynamic_cast<const CylinderVolumeBounds*
>(&((*volIter)->volumeBounds()));
103 if (!currentCylBounds) {
104 ATH_MSG_ERROR(
"Given TrackingVolume doesn't exist or is not of shape "
105 "'CylinderVolumeBounds': return 0");
109 double currentRmin = currentCylBounds->
innerRadius();
110 double currentRmax = currentCylBounds->
outerRadius();
112 boundaries.push_back(currentRmin);
113 boundaries.push_back(currentRmax);
116 double currentZmin = (*volIter)->center().z() - currentCylBounds->
halflengthZ();
117 double currentZmax = (*volIter)->center().z() + currentCylBounds->
halflengthZ();
120 if (ivol && !navtype) {
122 if (std::abs(currentZmin - lastZmin) > 0.1 || std::abs(currentZmax - lastZmax) > 0.1) {
123 ATH_MSG_ERROR(
"Given TrackingVolume(s) do not extend in z to the same point (required) : return 0");
124 ATH_MSG_VERBOSE(
"Information : lastZmin / lastZmin = "<< lastZmin <<
" / " << currentZmin);
125 ATH_MSG_VERBOSE(
" lastZmax / currentZmax = "<< lastZmax <<
" / " << currentZmax);
129 if (std::abs(currentRmin - lastOuterRadius) > 0.1) {
130 ATH_MSG_ERROR(
"Given TrackingVolume(s) are not wrapping, neither inside-out, nor v.v. : return 0");
131 ATH_MSG_VERBOSE(
"Information : currentRmin / lastOuterRadius = "<< currentRmin <<
" / " << lastOuterRadius);
136 lastZmin = currentZmin;
137 lastZmax = currentZmax;
138 lastOuterRadius = currentRmax;
140 ATH_MSG_VERBOSE(
"Adding Volume '" << (*volIter)->volumeName() <<
"' to Array");
142 volOrder.emplace_back((*volIter), currentCylBounds->
mediumRadius() * Amg::Vector3D::UnitX());
146 if (!volOrder.empty()) {
149 return std::make_unique<BinnedArray1D<TrackingVolume>>(volOrder, volBinUtilR);
151 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
156 std::unique_ptr<TrackingVolumeArray>
158 bool navtype)
const {
161 <<
" Volumes (with CylinderVolumeBounds) with Z-binning. ");
169 std::vector<float> boundaries;
170 boundaries.reserve(vols.size() + 1);
173 std::vector<TrackingVolumeOrderPosition> volOrder;
175 auto volIter = vols.begin();
176 for (
unsigned int ivol = 0; volIter != vols.end(); ++volIter, ++ivol) {
178 if (*volIter)currentCylBounds =
dynamic_cast<const CylinderVolumeBounds*
>( &((*volIter)->volumeBounds()));
179 if (!currentCylBounds) {
180 ATH_MSG_ERROR(
"Given TrackingVolume doesn't exist or is not of shape 'CylinderVolumeBounds': return 0");
185 double halflengthZ = currentCylBounds->
halflengthZ();
187 double currentZmin = volCenter.z() - halflengthZ;
188 double currentZmax = volCenter.z() + halflengthZ;
189 if (!ivol) boundaries.push_back(currentZmin);
190 boundaries.push_back(currentZmax);
193 double currentRmin = currentCylBounds->
innerRadius();
194 double currentRmax = currentCylBounds->
outerRadius();
197 if (ivol && !navtype) {
199 if (std::abs(lastRmin - currentRmin) > 0.1 || std::abs(lastRmax - currentRmax) > 0.1) {
200 ATH_MSG_ERROR(
"Given TrackingVolume(s) do not have same radial extends (required): return 0");
201 ATH_MSG_VERBOSE(
"Information : lastRmin / currentRmin = " << lastRmin <<
" / " << currentRmin);
202 ATH_MSG_VERBOSE(
" lastRmax / currentRmax = " << lastRmax <<
" / " << currentRmax);
206 if (std::abs(lastZmax - currentZmin) > 0.1) {
207 ATH_MSG_ERROR(
"Given TrackingVolume(s) are not attaching in z (required) : return 0");
212 lastRmin = currentRmin;
213 lastRmax = currentRmax;
214 lastZmax = currentZmax;
219 volOrder.emplace_back((*volIter), (*volIter)->center());
222 if (!volOrder.empty()) {
225 return std::make_unique<BinnedArray1D<TrackingVolume>>(volOrder, volBinUtil);
227 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
231 std::unique_ptr<TrackingVolumeArray>
236 <<
" Volumes (with CylinderVolumeBounds) with Phi-binning. ");
239 int nPhiBins = !vols.empty() ? vols.size() : 1;
242 std::vector<TrackingVolumeOrderPosition> volOrder;
244 auto volIter = vols.begin();
245 for (; volIter != vols.end(); ++volIter) {
249 ATH_MSG_ERROR(
"Given TrackingVolume doesn't exist or is not of shape 'CylinderVolumeBounds': return 0");
253 ATH_MSG_VERBOSE(
"Adding Volume '" << (*volIter)->volumeName()<<
"' to Array");
255 volOrder.emplace_back((*volIter), (*volIter)->transform() * (cyl->
mediumRadius() * Amg::Vector3D::UnitX()));
258 if (!volOrder.empty()) {
260 return std::make_unique<BinnedArray1D<TrackingVolume>>(volOrder, volBinUtil);
262 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
266 std::unique_ptr<TrackingVolumeArray>
268 bool navtype)
const {
272 const bool bevelled = std::find_if(vols.begin(),vols.end(),
274 return dynamic_cast<const BevelledCylinderVolumeBounds*>(&(ptr->volumeBounds()));
280 std::vector<TrackingVolumeOrderPosition> volOrder;
284 <<
" Volumes (with CylinderVolumeBounds) with PhiH-binning. ");
286 std::vector<std::pair<std::pair<double, int>, std::pair<double, double>>>
288 std::vector<VolumePtr> fullPhiVols;
300 rmin = cyl->innerRadius();
301 rmax = cyl->outerRadius();
302 dphi = cyl->halfPhiSector();
303 mRad = cyl->mediumRadius();
305 rmin = bcyl->innerRadius();
306 rmax = bcyl->outerRadius();
307 dphi = bcyl->halfPhiSector();
308 mRad = bcyl->mediumRadius();
317 Amg::Vector3D ngp((vol->transform()) * (mRad * Amg::Vector3D::UnitX()));
318 volOrder.emplace_back(vol, ngp);
321 volPos.emplace_back(std::pair<double, int>(ngp.phi(),
type),
322 std::pair<double, double>(rmin, rmax));
324 double phi1 = ngp.phi() - dphi;
325 double phi2 = ngp.phi() + dphi;
326 if (phi1 < -2 *
M_PI) {
328 }
if (phi2 < -2 *
M_PI) {
330 }
if (phi1 > 2 *
M_PI) {
332 }
if (phi2 > 2 *
M_PI) {
340 if (std::abs(phi1 - (*
iter)) < tol) {
344 if (phi1 < (*
iter)) {
356 if (std::abs(phi2 - (*
iter)) < tol) {
360 if (phi2 < (*
iter)) {
370 phiSteps.push_back(fmin(phi1, phi2));
371 phiSteps.push_back(fmax(phi1, phi2));
374 fullPhiVols.push_back(vol);
382 for (
auto & fullPhiVol : fullPhiVols) {
385 ATH_MSG_WARNING(
"dynamic_cast<const CylinderVolumeBounds*> failed ... trying to continue loop");
388 double rmin = cyl->innerRadius();
389 double rmax = cyl->outerRadius();
391 for (
unsigned int iphi = 0; iphi <
phiSteps.size(); ++iphi) {
393 double phiRef = 0.5 *
phiSteps[iphi];
401 volOrder.emplace_back(fullPhiVol, ngp);
404 volPos.emplace_back(std::pair<double, int>(ngp.phi(), 0),
405 std::pair<double, double>(rmin, rmax));
419 std::vector<std::vector<std::pair<int, float>>> hSteps(
phiSteps.size());
420 std::vector<float> phiRef(
phiSteps.size());
424 phiRef.back() += (phiRef.back() > 0) ? -
M_PI :
M_PI;
430 for (
unsigned int i = 0;
i < volPos.size(); ++
i) {
433 int type = volPos[
i].first.second;
434 double rmin = volPos[
i].second.first;
435 double rmax = volPos[
i].second.second;
436 int tmin = (
type != 1 &&
type != 3) ? 0 : 1;
437 int tmax = (
type < 2) ? 0 : 1;
439 int phibin = phiBinUtil.bin(volOrder[
i].
second);
441 if (!hSteps[phibin].empty()) {
443 hSteps[phibin].begin();
445 while (
iter != hSteps[phibin].
end()) {
446 if (std::abs(rmin - (*iter).second) < tol) {
450 if (rmin < (*iter).second) {
451 hSteps[phibin].insert(
iter, std::pair<int, float>(tmin, rmin));
458 hSteps[phibin].emplace_back(tmin, rmin);
459 iter = hSteps[phibin].begin();
461 while (
iter != hSteps[phibin].
end()) {
462 if (std::abs(rmax - (*iter).second) < tol) {
466 if (rmax < (*iter).second) {
467 hSteps[phibin].insert(
iter, std::pair<int, float>(tmax, rmax));
474 hSteps[phibin].emplace_back(tmax, rmax);
476 hSteps[phibin].emplace_back(tmin, rmin);
477 hSteps[phibin].emplace_back(tmax, rmax);
483 auto hUtil = std::vector<BinUtility>(
phiSteps.size());
485 for (
unsigned int ih = 0; ih <
phiSteps.size(); ++ih) {
486 (hUtil)[ih] =
BinUtility(phiRef[ih], hSteps[ih]);
489 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, phiBinUtil, hUtil);
493 <<
" Volumes (with CylinderVolumeBounds) with PhiR-binning. ");
495 std::vector<float> rSteps;
496 double phiSector =
M_PI;
497 std::vector<std::pair<double, std::pair<double, double>>> volPos;
499 for (
const auto& vol : vols) {
502 ATH_MSG_WARNING(
"dynamic_cast<const CylinderVolumeBounds*> failed ... trying to continue loop");
505 double rmin = cyl->innerRadius();
506 double rmax = cyl->outerRadius();
507 double dphi = cyl->halfPhiSector();
508 if (phiSector > 0. && std::abs(dphi - phiSector) > 0.001)
509 phiSector = phiSector <
M_PI ? -1. : dphi;
512 const Amg::Vector3D ngp{vol->transform() * (cyl->mediumRadius()* Amg::Vector3D::UnitX())};
513 volOrder.emplace_back(vol, ngp);
516 volPos.emplace_back(cyl->mediumRadius(), std::make_pair(ngp.phi(), dphi));
518 if (!rSteps.empty()) {
521 while (
iter != rSteps.end()) {
522 if (std::abs(rmin - (*
iter)) < tol) {
526 if (rmin < (*
iter)) {
527 rSteps.insert(
iter, rmin);
534 rSteps.push_back(rmin);
535 iter = rSteps.begin();
537 while (
iter != rSteps.end()) {
538 if (std::abs(rmax - (*
iter)) < tol) {
542 if (rmax < (*
iter)) {
543 rSteps.insert(
iter, rmax);
550 rSteps.push_back(rmax);
552 rSteps.push_back(rmin);
553 rSteps.push_back(rmax);
557 if (phiSector > 0.) {
559 const int rStepsSizem1 = rSteps.size() - 1;
560 std::vector<double>
phi(rStepsSizem1,
M_PI);
561 std::vector<int> phiSect(rStepsSizem1,
int(
M_PI / phiSector));
564 if (rSteps.size() == 1) {
567 if (phiSector ==
M_PI) {
572 auto phiUtil = std::vector<BinUtility>(rSteps.size() - 1);
573 for (
unsigned int ip = 0;
ip < phiUtil.size(); ++
ip) {
576 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, rBinUtil, phiUtil);
583 std::vector<std::vector<float>>
phiSteps(rSteps.size() - 1);
585 for (
unsigned int i = 0;
i < volPos.size(); ++
i) {
587 double phi = volPos[
i].second.first;
588 double dphi = volPos[
i].second.second;
590 int binr = binGenR.bin(volOrder[
i].
second);
592 float phi1 =
phi - dphi;
593 float phi2 =
phi + dphi;
603 if (std::abs(phi1 - (*
iter)) < tol) {
607 if (phi1 < (*
iter)) {
619 if (std::abs(phi2 - (*
iter)) < tol) {
623 if (phi2 < (*
iter)) {
633 phiSteps[binr].push_back(std::fmin(phi1, phi2));
634 phiSteps[binr].push_back(std::fmax(phi1, phi2));
639 auto phiUtil = std::vector<BinUtility>(
phiSteps.size());
645 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, binGenR, phiUtil);
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;
672 zmin = vol->center().z() - cyl->halflengthZ();
673 zmax = vol->center().z() + cyl->halflengthZ();
674 dphi = cyl->halfPhiSector();
675 mRad = cyl->mediumRadius();
677 zmin = vol->center().z() - bcyl->halflengthZ();
678 zmax = vol->center().z() + bcyl->halflengthZ();
679 dphi = bcyl->halfPhiSector();
680 mRad = bcyl->mediumRadius();
686 if (phiSector > 0. && std::abs(dphi - phiSector) > 0.001)
687 phiSector = phiSector <
M_PI ? -1. : dphi;
690 const Amg::Vector3D ngp{vol->transform() * (mRad * Amg::Vector3D::UnitX())};
692 volOrder.emplace_back(vol, ngp);
694 volPos.emplace_back(vol->center().z(), std::make_pair(ngp.phi(), dphi));
696 if (!zSteps.empty()) {
699 while (
iter != zSteps.end()) {
700 if (std::abs(
zmin - (*
iter)) < tol) {
712 zSteps.push_back(
zmin);
713 iter = zSteps.begin();
715 while (
iter != zSteps.end()) {
716 if (std::abs(
zmax - (*
iter)) < tol) {
728 zSteps.push_back(
zmax);
730 zSteps.push_back(
zmin);
731 zSteps.push_back(
zmax);
735 if (phiSector > 0.) {
737 const int zStepsSizem1 = zSteps.size() - 1;
738 std::vector<double>
phi(zStepsSizem1,
M_PI);
739 std::vector<int> phiSect(zStepsSizem1,
int(
M_PI / phiSector));
742 if (phiSector ==
M_PI) {
745 if (zSteps.size() == 2) {
751 return std::make_unique<BinnedArray2D<TrackingVolume>>(volOrder, binGenZPhi);
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 auto phiUtil = std::vector<BinUtility>(
phiSteps.size());
821 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, binGenZ, phiUtil);
825 std::unique_ptr<TrackingVolumeArray>
829 std::vector<VolumePtr> volOrder;
831 auto volIter = vols.begin();
832 for (; volIter != vols.end(); ++volIter) {
833 const auto *currentCubBounds =
dynamic_cast<const CuboidVolumeBounds*
>(&((*volIter)->volumeBounds()));
834 if (!currentCubBounds) {
835 ATH_MSG_ERROR(
"Given TrackingVolume to TrackingVolumeArrayCreator didn't "
836 "match specified shape: return 0");
839 volOrder.push_back(*volIter);
841 if (!volOrder.empty()) {
843 return std::make_unique<NavBinnedArray1D<TrackingVolume>>(volOrder, binUtil, navTransform);
845 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
849 std::unique_ptr<TrackingVolumeArray>
852 std::vector<VolumePtr> volOrder;
854 auto volIter = vols.begin();
855 for (; volIter != vols.end(); ++volIter) {
856 const auto *currentTrdBounds =
dynamic_cast<const TrapezoidVolumeBounds*
>(&((*volIter)->volumeBounds()));
857 if (!currentTrdBounds) {
858 ATH_MSG_ERROR(
"Given TrackingVolume to TrackingVolumeArrayCreator didn't "
859 "match specified shape: return 0");
863 volOrder.push_back(*volIter);
865 if (!volOrder.empty()) {
867 return std::make_unique<NavBinnedArray1D<TrackingVolume>>(volOrder, binUtil, navTransform);
869 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
873 std::unique_ptr<TrackingVolumeArray>
876 std::vector<VolumePtr> volOrder;
878 auto volIter = vols.begin();
879 for (; volIter != vols.end(); ++volIter) {
881 if (!currentDTrdBounds) {
882 ATH_MSG_ERROR(
"Given TrackingVolume to TrackingVolumeArrayCreator didn't "
883 "match specified shape: return 0");
887 volOrder.push_back(*volIter);
889 if (!volOrder.empty()) {
891 return std::make_unique<NavBinnedArray1D<TrackingVolume>>(volOrder, binUtil, navTransform);
894 "No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");