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);
39 outVec.emplace_back(vol, Trk::do_not_delete<Trk::TrackingVolume>);
54 declareInterface<ITrackingVolumeArrayCreator>(
this);
68 ATH_MSG_VERBOSE(
"Create VolumeArray of "<< vols.size() <<
" Volumes (with CylinderVolumeBounds) with R-binning. ");
71 double lastZmin{0.}, lastZmax{0.}, lastOuterRadius{0.};
74 std::vector<float> boundaries;
75 boundaries.reserve(vols.size() + 1);
78 std::vector<TrackingVolumeOrderPosition> volOrder;
80 auto volIter = vols.begin();
81 for (
unsigned int ivol = 0; volIter != vols.end(); ++volIter, ++ivol) {
83 if (*volIter) currentCylBounds =
dynamic_cast<const CylinderVolumeBounds*
>(&((*volIter)->volumeBounds()));
84 if (!currentCylBounds) {
85 ATH_MSG_ERROR(
"Given TrackingVolume doesn't exist or is not of shape "
86 "'CylinderVolumeBounds': return 0");
90 double currentRmin = currentCylBounds->
innerRadius();
91 double currentRmax = currentCylBounds->
outerRadius();
93 boundaries.push_back(currentRmin);
94 boundaries.push_back(currentRmax);
97 double currentZmin = (*volIter)->center().z() - currentCylBounds->
halflengthZ();
98 double currentZmax = (*volIter)->center().z() + currentCylBounds->
halflengthZ();
101 if (ivol && !navtype) {
103 if (std::abs(currentZmin - lastZmin) > 0.1 || std::abs(currentZmax - lastZmax) > 0.1) {
104 ATH_MSG_ERROR(
"Given TrackingVolume(s) do not extend in z to the same point (required) : return 0");
105 ATH_MSG_VERBOSE(
"Information : lastZmin / lastZmin = "<< lastZmin <<
" / " << currentZmin);
106 ATH_MSG_VERBOSE(
" lastZmax / currentZmax = "<< lastZmax <<
" / " << currentZmax);
110 if (std::abs(currentRmin - lastOuterRadius) > 0.1) {
111 ATH_MSG_ERROR(
"Given TrackingVolume(s) are not wrapping, neither inside-out, nor v.v. : return 0");
112 ATH_MSG_VERBOSE(
"Information : currentRmin / lastOuterRadius = "<< currentRmin <<
" / " << lastOuterRadius);
117 lastZmin = currentZmin;
118 lastZmax = currentZmax;
119 lastOuterRadius = currentRmax;
121 ATH_MSG_VERBOSE(
"Adding Volume '" << (*volIter)->volumeName() <<
"' to Array");
123 volOrder.emplace_back((*volIter), currentCylBounds->
mediumRadius() * Amg::Vector3D::UnitX());
127 if (!volOrder.empty()) {
130 return std::make_unique<BinnedArray1D<TrackingVolume>>(volOrder, volBinUtilR);
132 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
138 bool navtype)
const {
142 std::unique_ptr<TrackingVolumeArray>
144 bool navtype)
const {
147 <<
" Volumes (with CylinderVolumeBounds) with Z-binning. ");
150 double lastRmin{0.}, lastRmax{0.}, lastZmax{0.};
153 std::vector<float> boundaries;
154 boundaries.reserve(vols.size() + 1);
157 std::vector<TrackingVolumeOrderPosition> volOrder;
159 auto volIter = vols.begin();
160 for (
unsigned int ivol = 0; volIter != vols.end(); ++volIter, ++ivol) {
162 if (*volIter)currentCylBounds =
dynamic_cast<const CylinderVolumeBounds*
>( &((*volIter)->volumeBounds()));
163 if (!currentCylBounds) {
164 ATH_MSG_ERROR(
"Given TrackingVolume doesn't exist or is not of shape 'CylinderVolumeBounds': return 0");
169 double halflengthZ = currentCylBounds->
halflengthZ();
171 double currentZmin = volCenter.z() - halflengthZ;
172 double currentZmax = volCenter.z() + halflengthZ;
173 if (!ivol) boundaries.push_back(currentZmin);
174 boundaries.push_back(currentZmax);
177 double currentRmin = currentCylBounds->
innerRadius();
178 double currentRmax = currentCylBounds->
outerRadius();
181 if (ivol && !navtype) {
183 if (std::abs(lastRmin - currentRmin) > 0.1 || std::abs(lastRmax - currentRmax) > 0.1) {
184 ATH_MSG_ERROR(
"Given TrackingVolume(s) do not have same radial extends (required): return 0");
185 ATH_MSG_VERBOSE(
"Information : lastRmin / currentRmin = " << lastRmin <<
" / " << currentRmin);
186 ATH_MSG_VERBOSE(
" lastRmax / currentRmax = " << lastRmax <<
" / " << currentRmax);
190 if (std::abs(lastZmax - currentZmin) > 0.1) {
191 ATH_MSG_ERROR(
"Given TrackingVolume(s) are not attaching in z (required) : return 0");
196 lastRmin = currentRmin;
197 lastRmax = currentRmax;
198 lastZmax = currentZmax;
203 volOrder.emplace_back((*volIter), (*volIter)->center());
206 if (!volOrder.empty()) {
209 return std::make_unique<BinnedArray1D<TrackingVolume>>(volOrder, volBinUtil);
211 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
216 bool navtype)
const {
220 std::unique_ptr<TrackingVolumeArray>
225 <<
" Volumes (with CylinderVolumeBounds) with Phi-binning. ");
228 int nPhiBins = !vols.empty() ? vols.size() : 1;
231 std::vector<TrackingVolumeOrderPosition> volOrder;
233 auto volIter = vols.begin();
234 for (; volIter != vols.end(); ++volIter) {
238 ATH_MSG_ERROR(
"Given TrackingVolume doesn't exist or is not of shape 'CylinderVolumeBounds': return 0");
242 ATH_MSG_VERBOSE(
"Adding Volume '" << (*volIter)->volumeName()<<
"' to Array");
244 volOrder.emplace_back((*volIter), (*volIter)->transform() * (cyl->
mediumRadius() * Amg::Vector3D::UnitX()));
247 if (!volOrder.empty()) {
249 return std::make_unique<BinnedArray1D<TrackingVolume>>(volOrder, volBinUtil);
251 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
257 bool navtype)
const {
260 std::unique_ptr<TrackingVolumeArray>
262 bool navtype)
const {
266 const bool bevelled = std::find_if(vols.begin(),vols.end(),
268 return dynamic_cast<const BevelledCylinderVolumeBounds*>(&(ptr->volumeBounds()));
274 std::vector<TrackingVolumeOrderPosition> volOrder;
278 <<
" Volumes (with CylinderVolumeBounds) with PhiH-binning. ");
280 std::vector<std::pair<std::pair<double, int>, std::pair<double, double>>>
282 std::vector<VolumePtr> fullPhiVols;
287 double rmin{0.}, rmax{0.}, dphi{0.}, mRad{0.};
291 rmin = cyl->innerRadius();
292 rmax = cyl->outerRadius();
293 dphi = cyl->halfPhiSector();
294 mRad = cyl->mediumRadius();
296 rmin = bcyl->innerRadius();
297 rmax = bcyl->outerRadius();
298 dphi = bcyl->halfPhiSector();
299 mRad = bcyl->mediumRadius();
308 Amg::Vector3D ngp((vol->transform()) * (mRad * Amg::Vector3D::UnitX()));
309 volOrder.emplace_back(vol, ngp);
312 volPos.emplace_back(std::pair<double, int>(ngp.phi(),
type),
313 std::pair<double, double>(rmin, rmax));
315 double phi1 = ngp.phi() - dphi;
316 double phi2 = ngp.phi() + dphi;
317 if (phi1 < -2 *
M_PI) {
319 }
if (phi2 < -2 *
M_PI) {
321 }
if (phi1 > 2 *
M_PI) {
323 }
if (phi2 > 2 *
M_PI) {
331 if (std::abs(phi1 - (*iter)) < tol) {
335 if (phi1 < (*iter)) {
347 if (std::abs(phi2 - (*iter)) < tol) {
351 if (phi2 < (*iter)) {
361 phiSteps.push_back(fmin(phi1, phi2));
362 phiSteps.push_back(fmax(phi1, phi2));
365 fullPhiVols.push_back(vol);
373 for (
auto & fullPhiVol : fullPhiVols) {
376 ATH_MSG_WARNING(
"dynamic_cast<const CylinderVolumeBounds*> failed ... trying to continue loop");
379 double rmin = cyl->innerRadius();
380 double rmax = cyl->outerRadius();
382 for (
unsigned int iphi = 0; iphi <
phiSteps.size(); ++iphi) {
384 double phiRef = 0.5 *
phiSteps[iphi];
392 volOrder.emplace_back(fullPhiVol, ngp);
395 volPos.emplace_back(std::pair<double, int>(ngp.phi(), 0),
396 std::pair<double, double>(rmin, rmax));
410 std::vector<std::vector<std::pair<int, float>>> hSteps(
phiSteps.size());
411 std::vector<float> phiRef(
phiSteps.size());
415 phiRef.back() += (phiRef.back() > 0) ? -
M_PI :
M_PI;
421 for (
unsigned int i = 0;
i < volPos.size(); ++
i) {
424 int type = volPos[
i].first.second;
425 double rmin = volPos[
i].second.first;
426 double rmax = volPos[
i].second.second;
427 int tmin = (
type != 1 &&
type != 3) ? 0 : 1;
428 int tmax = (
type < 2) ? 0 : 1;
430 int phibin = phiBinUtil.bin(volOrder[
i].
second);
432 if (!hSteps[phibin].empty()) {
433 std::vector<std::pair<int, float>>
::iterator iter =
434 hSteps[phibin].begin();
436 while (iter != hSteps[phibin].
end()) {
437 if (std::abs(rmin - (*iter).second) < tol) {
441 if (rmin < (*iter).second) {
442 hSteps[phibin].insert(iter, std::pair<int, float>(tmin, rmin));
449 hSteps[phibin].emplace_back(tmin, rmin);
450 iter = hSteps[phibin].begin();
452 while (iter != hSteps[phibin].
end()) {
453 if (std::abs(rmax - (*iter).second) < tol) {
457 if (rmax < (*iter).second) {
458 hSteps[phibin].insert(iter, std::pair<int, float>(tmax, rmax));
465 hSteps[phibin].emplace_back(tmax, rmax);
467 hSteps[phibin].emplace_back(tmin, rmin);
468 hSteps[phibin].emplace_back(tmax, rmax);
474 auto hUtil = std::vector<BinUtility>(
phiSteps.size());
476 for (
unsigned int ih = 0; ih <
phiSteps.size(); ++ih) {
477 (hUtil)[ih] =
BinUtility(phiRef[ih], hSteps[ih]);
480 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, phiBinUtil, 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 const int rStepsSizem1 = rSteps.size() - 1;
551 std::vector<double>
phi(rStepsSizem1,
M_PI);
552 std::vector<int> phiSect(rStepsSizem1,
int(
M_PI / phiSector));
555 if (rSteps.size() == 1) {
558 if (phiSector ==
M_PI) {
563 auto phiUtil = std::vector<BinUtility>(rSteps.size() - 1);
564 for (
unsigned int ip = 0;
ip < phiUtil.size(); ++
ip) {
567 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, rBinUtil, phiUtil);
574 std::vector<std::vector<float>>
phiSteps(rSteps.size() - 1);
576 for (
unsigned int i = 0;
i < volPos.size(); ++
i) {
578 double phi = volPos[
i].second.first;
579 double dphi = volPos[
i].second.second;
581 int binr = binGenR.bin(volOrder[
i].
second);
583 float phi1 =
phi - dphi;
584 float phi2 =
phi + dphi;
594 if (std::abs(phi1 - (*iter)) < tol) {
598 if (phi1 < (*iter)) {
610 if (std::abs(phi2 - (*iter)) < tol) {
614 if (phi2 < (*iter)) {
624 phiSteps[binr].push_back(std::fmin(phi1, phi2));
625 phiSteps[binr].push_back(std::fmax(phi1, phi2));
630 auto phiUtil = std::vector<BinUtility>(
phiSteps.size());
636 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, binGenR, phiUtil);
641 bool navtype)
const {
644 std::unique_ptr<TrackingVolumeArray>
646 bool navtype)
const {
649 <<
" Volumes (with CylinderVolumeBounds) with PhiZ-binning. ");
653 std::vector<TrackingVolumeOrderPosition> volOrder;
655 std::vector<float> zSteps;
657 double phiSector =
M_PI;
658 std::vector<std::pair<float, std::pair<float, float>>> volPos;
663 double zmin{0.},
zmax{0.}, dphi{0.}, mRad{0.};
665 zmin = vol->center().z() - cyl->halflengthZ();
666 zmax = vol->center().z() + cyl->halflengthZ();
667 dphi = cyl->halfPhiSector();
668 mRad = cyl->mediumRadius();
670 zmin = vol->center().z() - bcyl->halflengthZ();
671 zmax = vol->center().z() + bcyl->halflengthZ();
672 dphi = bcyl->halfPhiSector();
673 mRad = bcyl->mediumRadius();
679 if (phiSector > 0. && std::abs(dphi - phiSector) > 0.001)
680 phiSector = phiSector <
M_PI ? -1. : dphi;
683 const Amg::Vector3D ngp{vol->transform() * (mRad * Amg::Vector3D::UnitX())};
685 volOrder.emplace_back(vol, ngp);
687 volPos.emplace_back(vol->center().z(), std::make_pair(ngp.phi(), dphi));
689 if (!zSteps.empty()) {
692 while (iter != zSteps.end()) {
693 if (std::abs(
zmin - (*iter)) < tol) {
697 if (
zmin < (*iter)) {
698 zSteps.insert(iter,
zmin);
705 zSteps.push_back(
zmin);
706 iter = zSteps.begin();
708 while (iter != zSteps.end()) {
709 if (std::abs(
zmax - (*iter)) < tol) {
713 if (
zmax < (*iter)) {
714 zSteps.insert(iter,
zmax);
721 zSteps.push_back(
zmax);
723 zSteps.push_back(
zmin);
724 zSteps.push_back(
zmax);
728 if (phiSector > 0.) {
730 const int zStepsSizem1 = zSteps.size() - 1;
731 std::vector<double>
phi(zStepsSizem1,
M_PI);
732 std::vector<int> phiSect(zStepsSizem1,
int(
M_PI / phiSector));
735 if (phiSector ==
M_PI) {
738 if (zSteps.size() == 2) {
744 return std::make_unique<BinnedArray2D<TrackingVolume>>(volOrder, binGenZPhi);
751 std::vector<std::vector<float>>
phiSteps(zSteps.size() - 1);
753 for (
unsigned int i = 0;
i < volPos.size(); ++
i) {
755 float phi = volPos[
i].second.first;
756 float dphi = volPos[
i].second.second;
760 float phi1 =
phi - dphi;
761 float phi2 =
phi + dphi;
771 if (std::abs(phi1 - (*iter)) < tol) {
775 if (phi1 < (*iter)) {
787 if (std::abs(phi2 - (*iter)) < tol) {
791 if (phi2 < (*iter)) {
808 auto phiUtil = std::vector<BinUtility>(
phiSteps.size());
814 return std::make_unique<BinnedArray1D1D<TrackingVolume>>(volOrder, binGenZ, phiUtil);
821 bool navtype)
const {
824 std::unique_ptr<TrackingVolumeArray>
828 std::vector<VolumePtr> volOrder;
830 auto volIter = vols.begin();
831 for (; volIter != vols.end(); ++volIter) {
832 const auto *currentCubBounds =
dynamic_cast<const CuboidVolumeBounds*
>(&((*volIter)->volumeBounds()));
833 if (!currentCubBounds) {
834 ATH_MSG_ERROR(
"Given TrackingVolume to TrackingVolumeArrayCreator didn't "
835 "match specified shape: return 0");
838 volOrder.push_back(*volIter);
840 if (!volOrder.empty()) {
841 auto navTransform = std::make_unique<Amg::Transform3D>(Amg::Transform3D::Identity());
842 return std::make_unique<NavBinnedArray1D<TrackingVolume>>(volOrder, binUtil, navTransform.release());
844 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
855 std::unique_ptr<TrackingVolumeArray>
858 std::vector<VolumePtr> volOrder;
860 auto volIter = vols.begin();
861 for (; volIter != vols.end(); ++volIter) {
862 const auto *currentTrdBounds =
dynamic_cast<const TrapezoidVolumeBounds*
>(&((*volIter)->volumeBounds()));
863 if (!currentTrdBounds) {
864 ATH_MSG_ERROR(
"Given TrackingVolume to TrackingVolumeArrayCreator didn't "
865 "match specified shape: return 0");
869 volOrder.push_back(*volIter);
871 if (!volOrder.empty()) {
873 return std::make_unique<NavBinnedArray1D<TrackingVolume>>(volOrder, binUtil, navTransform);
875 ATH_MSG_ERROR(
"No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");
881 bool navtype)
const {
885 std::unique_ptr<TrackingVolumeArray>
888 std::vector<VolumePtr> volOrder;
890 auto volIter = vols.begin();
891 for (; volIter != vols.end(); ++volIter) {
893 if (!currentDTrdBounds) {
894 ATH_MSG_ERROR(
"Given TrackingVolume to TrackingVolumeArrayCreator didn't "
895 "match specified shape: return 0");
899 volOrder.push_back(*volIter);
901 if (!volOrder.empty()) {
903 return std::make_unique<NavBinnedArray1D<TrackingVolume>>(volOrder, binUtil, navTransform);
906 "No TrackingVolumes provided to the TrackingVolumeArrayCreator: return 0");