50 const Acts::GeometryContext& gctx,
51 std::shared_ptr<const Acts::TrackingVolume> insideVolume,
52 std::shared_ptr<const Acts::VolumeBounds> )
const
57 std::vector<std::unique_ptr<Acts::Volume>> cells;
64 std::vector<std::unique_ptr<Box>> boxStore;
65 std::vector<Box*> prims;
66 for (
const auto& cell : cells) {
68 std::make_unique<Box>(cell->boundingBox({0.1, 0.1, 0.1})));
69 prims.push_back(boxStore.back().get());
77 std::shared_ptr<Acts::CutoutCylinderVolumeBounds> caloVolBounds
88 std::vector<std::unique_ptr<const Acts::Volume>> cellVols;
89 cellVols.reserve(cells.size());
90 for(
auto& cell : cells) {
91 std::unique_ptr<const Acts::Volume> up;
93 up = std::unique_ptr<const Acts::Volume>(
dynamic_cast<const Acts::Volume*
>(cell.release()));
94 cellVols.push_back(std::move(up));
100 throw std::runtime_error{
"Calo building for ACTS currently disabled"};
347 const Acts::GeometryContext& gctx,
348 const std::vector<std::unique_ptr<Box>>& boxStore,
349 std::shared_ptr<const Acts::TrackingVolume> insideVolume)
const
351 using namespace Acts::VectorHelpers;
354 double rmin_at_center = std::numeric_limits<double>::max();
355 double rmin_at_choke = std::numeric_limits<double>::max();
356 double rmax = std::numeric_limits<double>::lowest();
357 double zmin = std::numeric_limits<double>::max();
358 double zmax = std::numeric_limits<double>::lowest();
359 double cutout_zmin_abs = std::numeric_limits<double>::max();
365 for (
const auto& box : boxStore) {
366 Acts::Vector3 vmin = box->min().cast<
double>();
367 Acts::Vector3 vmax = box->max().cast<
double>();
369 double vrmin =
perp(vmin);
370 double vrmax =
perp(vmax);
372 rmin_at_choke = std::min(rmin_at_choke, std::min(vrmin, vrmax));
374 rmax = std::max(rmax, std::max(vrmin, vrmax));
375 zmin = std::min(zmin, std::min(vmin.z(), vmax.z()));
376 zmax = std::max(zmax, std::max(vmin.z(), vmax.z()));
378 if (std::abs(vmin.z()) < 100) {
379 rmin_at_center = std::min(vrmin, rmin_at_center);
381 if (std::abs(vmax.z()) < 100) {
382 rmin_at_center = std::min(vrmax, rmin_at_center);
386 for (
const auto& box : boxStore) {
387 Acts::Vector3 vmin = box->min().cast<
double>();
388 Acts::Vector3 vmax = box->max().cast<
double>();
389 double vrmin =
perp(vmin);
390 double vrmax =
perp(vmax);
392 if (vrmin < rmin_at_center * 0.9) {
393 cutout_zmin_abs = std::min(cutout_zmin_abs, std::abs(vmin.z()));
395 if (vrmax < rmin_at_center * 0.9) {
396 cutout_zmin_abs = std::min(cutout_zmin_abs, std::abs(vmax.z()));
400 double dz1 = (zmax - zmin) / 2.;
401 double dz2 = cutout_zmin_abs;
409 if(rmin_at_choke > envR) rmin_at_choke -= envR;
410 rmin_at_center -= envR;
414 <<
" rmin at choke: " << rmin_at_choke
415 <<
" rmax: " << rmax <<
" zmin: " << zmin <<
" zmax: " << zmax
416 <<
" coutout_zmin_abs: " << cutout_zmin_abs);
424 =
dynamic_cast<const Acts::CylinderVolumeBounds*
>(&insideVolume->volumeBounds());
425 if (idCylBds ==
nullptr) {
426 ATH_MSG_ERROR(
"Unable to dynamic cast volume bounds to Acts::CylinderVolumeBounds");
427 throw std::runtime_error(
"Error casting to CylinderVolumeBounds");
430 double idRMax = idCylBds->get(CVBBV::eMaxR);
431 double idRMin = idCylBds->get(CVBBV::eMinR);
432 double idHlZ = idCylBds->get(CVBBV::eHalfLengthZ);
438 const auto& trf = insideVolume->localToGlobalTransform(gctx);
440 if (!trf.isApprox(Acts::Transform3::Identity())) {
446 Acts::RotationMatrix3 rot = trf.rotation();
447 bool unityRot = rot.isApprox(Acts::RotationMatrix3::Identity());
452 const Acts::Vector3 trl = trf.translation();
453 bool transZOnly = std::abs(1 - std::abs(Acts::Vector3::UnitZ().
dot(trl.normalized()))) < 1e-6;
456 ATH_MSG_VERBOSE(
"TRL "<< trl.normalized().dot(Acts::Vector3::UnitZ()));
458 if(!unityRot || !transZOnly) {
459 ATH_MSG_ERROR(
"The ID appears to be shifted from the origin. I cannot handle this.");
461 throw std::runtime_error(
"Error building calo");
464 ATH_MSG_VERBOSE(
"Checked: non unitarity is ONLY due to shift along z axis: that's ok");
465 double prevIdHlZ = idHlZ;
466 idHlZ += std::abs(trl.z());
467 ATH_MSG_VERBOSE(
"Modifying effective half length of ID cylinder: " << prevIdHlZ <<
" => " << idHlZ);
472 if (idRMax > rmin_at_center || idHlZ > dz2 || (idRMin > rmin_at_choke && idRMin != 0.)) {
474 ATH_MSG_ERROR(
"This can be because the ID overlaps into the calo volume");
475 ATH_MSG_ERROR(
"Or because the Calo choke radius is SMALLER than the ID inner radius");
476 ATH_MSG_ERROR(
"Currently, I can only make the choke radius smaller, I can not make it larger");
477 ATH_MSG_ERROR(
"nor can I manipulate the ID volume bounds at this point.");
478 ATH_MSG_ERROR(
"ID rMax: " << idRMax <<
" Calo rMin@center: " << rmin_at_center);
479 ATH_MSG_ERROR(
"ID hlZ: " << idHlZ <<
" Calo inner Z hl: " << dz2);
480 ATH_MSG_ERROR(
"ID rMin: " << idRMin <<
" Calo rMin@choke: " << rmin_at_choke);
482 throw std::runtime_error(
"Error building calo");
488 rmin_at_choke = idRMin;
490 std::shared_ptr<Acts::CutoutCylinderVolumeBounds> volBds =
nullptr;
491 volBds = std::make_shared<Acts::CutoutCylinderVolumeBounds>(
492 rmin_at_choke, rmin_at_center, rmax, dz1, dz2);
516 double eta_max =
eta + deta * 0.5;
517 double eta_min =
eta - deta * 0.5;
518 double theta_max = eta_to_theta(eta_max);
520 double theta_min = eta_to_theta(eta_min);
521 double phi_max =
phi + dphi * 0.5;
522 double phi_min =
phi - dphi * 0.5;
523 double z_min =
z - dz;
524 double z_max =
z + dz;
529 r_min = std::tan(theta_min) * z_min;
530 r_max = std::tan(theta_max) * z_min;
532 Acts::Vector3 p1(r_min * std::cos(phi_min), r_min * std::sin(phi_min), z_min);
533 Acts::Vector3 p2(r_min * std::cos(phi_max), r_min * std::sin(phi_max), z_min);
534 Acts::Vector3 p3(r_max * std::cos(phi_max), r_max * std::sin(phi_max), z_min);
535 Acts::Vector3 p4(r_max * std::cos(phi_min), r_max * std::sin(phi_min), z_min);
538 r_min = std::tan(theta_min) * z_max;
539 r_max = std::tan(theta_max) * z_max;
541 Acts::Vector3 p5(r_min * std::cos(phi_min), r_min * std::sin(phi_min), z_max);
542 Acts::Vector3 p6(r_min * std::cos(phi_max), r_min * std::sin(phi_max), z_max);
543 Acts::Vector3 p7(r_max * std::cos(phi_max), r_max * std::sin(phi_max), z_max);
544 Acts::Vector3 p8(r_max * std::cos(phi_min), r_max * std::sin(phi_min), z_max);
546 double r_mid = std::tan(
theta) * z_min;
547 Acts::Vector3 center;
548 center.x() = r_mid * std::cos(
phi);
549 center.y() = r_mid * std::sin(
phi);
552 Acts::Transform3 glob2vol = Acts::Transform3::Identity();
553 glob2vol *= Acts::AngleAxis3(-
phi, Acts::Vector3::UnitZ());
554 glob2vol *= Acts::AngleAxis3(
555 -
theta, Acts::Vector3::UnitZ().cross(center).normalized());
557 *= Acts::Translation3(-(p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8) / 8.);
568 auto globalToLocal = glob2vol.inverse();
570 auto cubo = std::make_shared<Acts::GenericCuboidVolumeBounds>(
571 std::array<Acts::Vector3, 8>({{p1, p2, p3, p4, p5, p6, p7, p8}}));
572 Acts::Volume vol(globalToLocal, std::move(cubo));
587 double eta_max =
eta + deta * 0.5;
588 double eta_min =
eta - deta * 0.5;
590 double theta_max = eta_to_theta(eta_max);
591 double theta_min = eta_to_theta(eta_min);
592 double phi_max =
phi + dphi * 0.5;
593 double phi_min =
phi - dphi * 0.5;
595 double r_min =
r - dr;
596 double r_max =
r + dr;
601 z_min = r_min / std::tan(theta_min);
602 z_max = r_min / std::tan(theta_max);
604 Acts::Vector3 p1(r_min * std::cos(phi_min), r_min * std::sin(phi_min), z_min);
605 Acts::Vector3 p2(r_min * std::cos(phi_min), r_min * std::sin(phi_min), z_max);
606 Acts::Vector3 p3(r_min * std::cos(phi_max), r_min * std::sin(phi_max), z_max);
607 Acts::Vector3 p4(r_min * std::cos(phi_max), r_min * std::sin(phi_max), z_min);
610 z_min = r_max / std::tan(theta_min);
611 z_max = r_max / std::tan(theta_max);
613 Acts::Vector3 p5(r_max * std::cos(phi_min), r_max * std::sin(phi_min), z_min);
614 Acts::Vector3 p6(r_max * std::cos(phi_min), r_max * std::sin(phi_min), z_max);
615 Acts::Vector3 p7(r_max * std::cos(phi_max), r_max * std::sin(phi_max), z_max);
616 Acts::Vector3 p8(r_max * std::cos(phi_max), r_max * std::sin(phi_max), z_min);
618 Acts::Vector3 center;
619 center.x() =
r * std::cos(
phi);
620 center.y() =
r * std::sin(
phi);
621 center.z() =
r / std::tan(
theta);
623 Acts::Transform3 glob2vol = Acts::Transform3::Identity();
624 glob2vol *= Acts::AngleAxis3(-
phi, Acts::Vector3::UnitZ());
625 glob2vol *= Acts::AngleAxis3(
626 -
theta, Acts::Vector3::UnitZ().cross(center).normalized());
628 *= Acts::Translation3(-(p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8) / 8.);
639 auto globalToLocal = glob2vol.inverse();
641 auto cubo = std::make_shared<Acts::GenericCuboidVolumeBounds>(
642 std::array<Acts::Vector3, 8>({{p1, p2, p3, p4, p5, p6, p7, p8}}));
644 Acts::Volume vol(globalToLocal, std::move(cubo));
654 double x_min, x_max, y_min, y_max, z_min, z_max;
663 Acts::Vector3 p1(x_min, y_min, z_min);
664 Acts::Vector3 p2(x_min, y_max, z_min);
665 Acts::Vector3 p3(x_max, y_max, z_min);
666 Acts::Vector3 p4(x_max, y_min, z_min);
669 Acts::Vector3 p5(x_min, y_min, z_max);
670 Acts::Vector3 p6(x_min, y_max, z_max);
671 Acts::Vector3 p7(x_max, y_max, z_max);
672 Acts::Vector3 p8(x_max, y_min, z_max);
674 Acts::Transform3 glob2vol = Acts::Transform3::Identity();
676 *= Acts::Translation3(-(p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8) / 8.);
687 auto globalToLocal = glob2vol.inverse();
689 auto cubo = std::make_shared<Acts::GenericCuboidVolumeBounds>(
690 std::array<Acts::Vector3, 8>({{p1, p2, p3, p4, p5, p6, p7, p8}}));
691 Acts::Volume vol(globalToLocal, std::move(cubo));
704 float z, dz, eta_raw, deta, phi_raw, dphi,
r, dr,
x,
y, dx, dy;
709 std::vector<std::unique_ptr<Acts::Volume>> cells;
710 cells.reserve(
m_caloMgr->element_size());
712 for(
auto it =
m_caloMgr->element_begin();it < m_caloMgr->element_end();++it) {
731 if (calosample >= 12 && calosample <= 20) {
745 switch (calosample) {
756 cells.push_back(std::make_unique<Acts::Volume>(
772 cells.push_back(std::make_unique<Acts::Volume>(
782 cells.push_back(std::make_unique<Acts::Volume>(
786 std::stringstream
ss;
787 ss <<
"Unkown calo sample " << calosample;
788 std::runtime_error(
ss.str());