10 #include "CaloDetDescr/CaloDetDescrElement.h"
13 #include "Acts/Geometry/TrackingVolume.hpp"
14 #include "Acts/Geometry/VolumeBounds.hpp"
15 #include "Acts/Geometry/GlueVolumesDescriptor.hpp"
18 #include "Acts/Geometry/GenericCuboidVolumeBounds.hpp"
19 #include "Acts/Geometry/CutoutCylinderVolumeBounds.hpp"
20 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
22 #include "Acts/Utilities/Helpers.hpp"
23 #include "Acts/Geometry/TrackingVolumeArrayCreator.hpp"
24 #include "Acts/Utilities/BinnedArrayXD.hpp"
25 #include "Acts/Geometry/CylinderVolumeHelper.hpp"
29 using Box = Acts::Volume::BoundingBox;
31 using CVBBV = Acts::CylinderVolumeBounds::BoundValues;
32 using CCVBBV = Acts::CutoutCylinderVolumeBounds::BoundValues;
35 const std::string&
name,
52 return StatusCode::SUCCESS;
55 std::shared_ptr<Acts::TrackingVolume>
57 const Acts::GeometryContext& gctx,
58 std::shared_ptr<const Acts::TrackingVolume> insideVolume,
59 std::shared_ptr<const Acts::VolumeBounds> )
const
64 std::vector<std::unique_ptr<Acts::Volume>>
cells;
71 std::vector<std::unique_ptr<Box>> boxStore;
72 std::vector<Box*> prims;
75 std::make_unique<Box>(
cell->boundingBox({0.1, 0.1, 0.1})));
76 prims.push_back(boxStore.back().get());
84 std::shared_ptr<Acts::CutoutCylinderVolumeBounds> caloVolBounds
95 std::vector<std::unique_ptr<const Acts::Volume>> cellVols;
96 cellVols.reserve(
cells.size());
98 std::unique_ptr<const Acts::Volume>
up;
100 up = std::unique_ptr<const Acts::Volume>(
dynamic_cast<const Acts::Volume*
>(
cell.release()));
101 cellVols.push_back(std::move(
up));
107 throw std::runtime_error{
"Calo building for ACTS currently disabled"};
352 std::shared_ptr<Acts::CutoutCylinderVolumeBounds>
354 std::shared_ptr<const Acts::TrackingVolume> insideVolume)
const
356 using namespace Acts::VectorHelpers;
361 double rmax = std::numeric_limits<double>::lowest();
363 double zmax = std::numeric_limits<double>::lowest();
370 for (
const auto& box : boxStore) {
371 Acts::Vector3
vmin = box->min().cast<
double>();
372 Acts::Vector3
vmax = box->max().cast<
double>();
383 if (std::abs(
vmin.z()) < 100) {
384 rmin_at_center =
std::min(vrmin, rmin_at_center);
386 if (std::abs(
vmax.z()) < 100) {
387 rmin_at_center =
std::min(vrmax, rmin_at_center);
391 for (
const auto& box : boxStore) {
392 Acts::Vector3
vmin = box->min().cast<
double>();
393 Acts::Vector3
vmax = box->max().cast<
double>();
397 if (vrmin < rmin_at_center * 0.9) {
398 cutout_zmin_abs =
std::min(cutout_zmin_abs, std::abs(
vmin.z()));
400 if (vrmax < rmin_at_center * 0.9) {
401 cutout_zmin_abs =
std::min(cutout_zmin_abs, std::abs(
vmax.z()));
406 double dz2 = cutout_zmin_abs;
414 if(rmin_at_choke > envR) rmin_at_choke -= envR;
415 rmin_at_center -= envR;
419 <<
" rmin at choke: " << rmin_at_choke
420 <<
" rmax: " << rmax <<
" zmin: " <<
zmin <<
" zmax: " <<
zmax
421 <<
" coutout_zmin_abs: " << cutout_zmin_abs);
429 =
dynamic_cast<const Acts::CylinderVolumeBounds*
>(&insideVolume->volumeBounds());
430 if (idCylBds ==
nullptr) {
431 ATH_MSG_ERROR(
"Unable to dynamic cast volume bounds to Acts::CylinderVolumeBounds");
432 throw std::runtime_error(
"Error casting to CylinderVolumeBounds");
435 double idRMax = idCylBds->get(CVBBV::eMaxR);
436 double idRMin = idCylBds->get(CVBBV::eMinR);
437 double idHlZ = idCylBds->get(CVBBV::eHalfLengthZ);
441 ATH_MSG_VERBOSE(
"Inside volume transform: \n" << insideVolume->transform().matrix());
443 if (!insideVolume->transform().isApprox(Acts::Transform3::Identity())) {
449 const auto&
trf = insideVolume->transform();
451 Acts::RotationMatrix3 rot =
trf.rotation();
452 bool unityRot = rot.isApprox(Acts::RotationMatrix3::Identity());
457 const Acts::Vector3 trl =
trf.translation();
458 bool transZOnly = std::abs(1 - std::abs(Acts::Vector3::UnitZ().
dot(trl.normalized()))) < 1
e-6;
461 ATH_MSG_VERBOSE(
"TRL "<< trl.normalized().dot(Acts::Vector3::UnitZ()));
463 if(!unityRot || !transZOnly) {
464 ATH_MSG_ERROR(
"The ID appears to be shifted from the origin. I cannot handle this.");
466 throw std::runtime_error(
"Error building calo");
469 ATH_MSG_VERBOSE(
"Checked: non unitarity is ONLY due to shift along z axis: that's ok");
470 double prevIdHlZ = idHlZ;
471 idHlZ += std::abs(trl.z());
472 ATH_MSG_VERBOSE(
"Modifying effective half length of ID cylinder: " << prevIdHlZ <<
" => " << idHlZ);
477 if (idRMax > rmin_at_center || idHlZ > dz2 || (idRMin > rmin_at_choke && idRMin != 0.)) {
479 ATH_MSG_ERROR(
"This can be because the ID overlaps into the calo volume");
480 ATH_MSG_ERROR(
"Or because the Calo choke radius is SMALLER than the ID inner radius");
481 ATH_MSG_ERROR(
"Currently, I can only make the choke radius smaller, I can not make it larger");
482 ATH_MSG_ERROR(
"nor can I manipulate the ID volume bounds at this point.");
483 ATH_MSG_ERROR(
"ID rMax: " << idRMax <<
" Calo rMin@center: " << rmin_at_center);
484 ATH_MSG_ERROR(
"ID hlZ: " << idHlZ <<
" Calo inner Z hl: " << dz2);
485 ATH_MSG_ERROR(
"ID rMin: " << idRMin <<
" Calo rMin@choke: " << rmin_at_choke);
487 throw std::runtime_error(
"Error building calo");
493 rmin_at_choke = idRMin;
495 std::shared_ptr<Acts::CutoutCylinderVolumeBounds> volBds =
nullptr;
496 volBds = std::make_shared<Acts::CutoutCylinderVolumeBounds>(
497 rmin_at_choke, rmin_at_center, rmax, dz1, dz2);
507 eta_to_theta(
double eta)
521 double eta_max =
eta + deta * 0.5;
522 double eta_min =
eta - deta * 0.5;
523 double theta_max = eta_to_theta(eta_max);
525 double theta_min = eta_to_theta(eta_min);
526 double phi_max =
phi + dphi * 0.5;
527 double phi_min =
phi - dphi * 0.5;
528 double z_min =
z - dz;
529 double z_max =
z + dz;
534 r_min =
std::tan(theta_min) * z_min;
535 r_max =
std::tan(theta_max) * z_min;
540 Acts::Vector3 p4(r_max *
std::cos(phi_min), r_max *
std::sin(phi_min), z_min);
543 r_min =
std::tan(theta_min) * z_max;
544 r_max =
std::tan(theta_max) * z_max;
546 Acts::Vector3 p5(r_min *
std::cos(phi_min), r_min *
std::sin(phi_min), z_max);
547 Acts::Vector3 p6(r_min *
std::cos(phi_max), r_min *
std::sin(phi_max), z_max);
548 Acts::Vector3 p7(r_max *
std::cos(phi_max), r_max *
std::sin(phi_max), z_max);
549 Acts::Vector3 p8(r_max *
std::cos(phi_min), r_max *
std::sin(phi_min), z_max);
552 Acts::Vector3 center;
557 Acts::Transform3 glob2vol = Acts::Transform3::Identity();
558 glob2vol *= Acts::AngleAxis3(-
phi, Acts::Vector3::UnitZ());
559 glob2vol *= Acts::AngleAxis3(
560 -
theta, Acts::Vector3::UnitZ().cross(center).normalized());
562 *= Acts::Translation3(-(
p1 +
p2 +
p3 + p4 + p5 + p6 + p7 + p8) / 8.);
575 auto cubo = std::make_shared<Acts::GenericCuboidVolumeBounds>(
576 std::array<Acts::Vector3, 8>({{
p1,
p2,
p3, p4, p5, p6, p7, p8}}));
592 double eta_max =
eta + deta * 0.5;
593 double eta_min =
eta - deta * 0.5;
595 double theta_max = eta_to_theta(eta_max);
596 double theta_min = eta_to_theta(eta_min);
597 double phi_max =
phi + dphi * 0.5;
598 double phi_min =
phi - dphi * 0.5;
600 double r_min =
r -
dr;
601 double r_max =
r +
dr;
606 z_min = r_min /
std::tan(theta_min);
607 z_max = r_min /
std::tan(theta_max);
612 Acts::Vector3 p4(r_min *
std::cos(phi_max), r_min *
std::sin(phi_max), z_min);
615 z_min = r_max /
std::tan(theta_min);
616 z_max = r_max /
std::tan(theta_max);
618 Acts::Vector3 p5(r_max *
std::cos(phi_min), r_max *
std::sin(phi_min), z_min);
619 Acts::Vector3 p6(r_max *
std::cos(phi_min), r_max *
std::sin(phi_min), z_max);
620 Acts::Vector3 p7(r_max *
std::cos(phi_max), r_max *
std::sin(phi_max), z_max);
621 Acts::Vector3 p8(r_max *
std::cos(phi_max), r_max *
std::sin(phi_max), z_min);
623 Acts::Vector3 center;
628 Acts::Transform3 glob2vol = Acts::Transform3::Identity();
629 glob2vol *= Acts::AngleAxis3(-
phi, Acts::Vector3::UnitZ());
630 glob2vol *= Acts::AngleAxis3(
631 -
theta, Acts::Vector3::UnitZ().cross(center).normalized());
633 *= Acts::Translation3(-(
p1 +
p2 +
p3 + p4 + p5 + p6 + p7 + p8) / 8.);
646 auto cubo = std::make_shared<Acts::GenericCuboidVolumeBounds>(
647 std::array<Acts::Vector3, 8>({{
p1,
p2,
p3, p4, p5, p6, p7, p8}}));
659 double x_min, x_max, y_min, y_max, z_min, z_max;
668 Acts::Vector3
p1(x_min, y_min, z_min);
669 Acts::Vector3
p2(x_min, y_max, z_min);
670 Acts::Vector3
p3(x_max, y_max, z_min);
671 Acts::Vector3 p4(x_max, y_min, z_min);
674 Acts::Vector3 p5(x_min, y_min, z_max);
675 Acts::Vector3 p6(x_min, y_max, z_max);
676 Acts::Vector3 p7(x_max, y_max, z_max);
677 Acts::Vector3 p8(x_max, y_min, z_max);
679 Acts::Transform3 glob2vol = Acts::Transform3::Identity();
681 *= Acts::Translation3(-(
p1 +
p2 +
p3 + p4 + p5 + p6 + p7 + p8) / 8.);
694 auto cubo = std::make_shared<Acts::GenericCuboidVolumeBounds>(
695 std::array<Acts::Vector3, 8>({{
p1,
p2,
p3, p4, p5, p6, p7, p8}}));
701 std::vector<std::unique_ptr<Acts::Volume>>
709 float z, dz, eta_raw, deta, phi_raw, dphi,
r,
dr,
x,
y,
dx,
dy;
714 std::vector<std::unique_ptr<Acts::Volume>>
cells;
736 if (calosample >= 12 && calosample <= 20) {
750 switch (calosample) {
761 cells.push_back(std::make_unique<Acts::Volume>(
777 cells.push_back(std::make_unique<Acts::Volume>(
787 cells.push_back(std::make_unique<Acts::Volume>(
791 std::stringstream
ss;
792 ss <<
"Unkown calo sample " << calosample;
793 std::runtime_error(
ss.str());