ATLAS Offline Software
Public Member Functions | Private Member Functions | Private Attributes | List of all members
ActsCaloTrackingVolumeBuilder Class Reference

#include <ActsCaloTrackingVolumeBuilder.h>

Inheritance diagram for ActsCaloTrackingVolumeBuilder:
Collaboration diagram for ActsCaloTrackingVolumeBuilder:

Public Member Functions

StatusCode initialize () override
 
 ActsCaloTrackingVolumeBuilder (const std::string &type, const std::string &name, const IInterface *parent)
 
std::shared_ptr< Acts::TrackingVolume > trackingVolume (const Acts::GeometryContext &gctx, std::shared_ptr< const Acts::TrackingVolume > insideVolume=nullptr, std::shared_ptr< const Acts::VolumeBounds > outsideBounds=nullptr) const override
 

Private Member Functions

Acts::Volume build_endcap (double z, double dz, double eta, double deta, double phi, double dphi) const
 
Acts::Volume build_barrel (double r, double dr, double eta, double deta, double phi, double dphi) const
 
Acts::Volume build_box (double x, double dx, double y, double dy, double z, double dz) const
 
std::vector< std::unique_ptr< Acts::Volume > > cellFactory () const
 
std::shared_ptr< Acts::CutoutCylinderVolumeBounds > makeCaloVolumeBounds (const std::vector< std::unique_ptr< Acts::Volume::BoundingBox >> &boxStore, std::shared_ptr< const Acts::TrackingVolume > insideVolume) const
 

Private Attributes

const CaloDetDescrManagerm_caloMgr {nullptr}
 

Detailed Description

Definition at line 32 of file ActsCaloTrackingVolumeBuilder.h.

Constructor & Destructor Documentation

◆ ActsCaloTrackingVolumeBuilder()

ActsCaloTrackingVolumeBuilder::ActsCaloTrackingVolumeBuilder ( const std::string &  type,
const std::string &  name,
const IInterface *  parent 
)

Definition at line 33 of file ActsCaloTrackingVolumeBuilder.cxx.

36 : base_class(type, name, parent)
37 {
38 
39 }

Member Function Documentation

◆ build_barrel()

Acts::Volume ActsCaloTrackingVolumeBuilder::build_barrel ( double  r,
double  dr,
double  eta,
double  deta,
double  phi,
double  dphi 
) const
private

Definition at line 583 of file ActsCaloTrackingVolumeBuilder.cxx.

589 {
590  // std::cout << "build barrel" << std::endl;
591  double eta_max = eta + deta * 0.5;
592  double eta_min = eta - deta * 0.5;
593  double theta = eta_to_theta(eta);
594  double theta_max = eta_to_theta(eta_max);
595  double theta_min = eta_to_theta(eta_min);
596  double phi_max = phi + dphi * 0.5;
597  double phi_min = phi - dphi * 0.5;
598 
599  double r_min = r - dr;
600  double r_max = r + dr;
601 
602  double z_min, z_max;
603 
604  // inner face
605  z_min = r_min / std::tan(theta_min);
606  z_max = r_min / std::tan(theta_max);
607 
608  Acts::Vector3 p1(r_min * std::cos(phi_min), r_min * std::sin(phi_min), z_min);
609  Acts::Vector3 p2(r_min * std::cos(phi_min), r_min * std::sin(phi_min), z_max);
610  Acts::Vector3 p3(r_min * std::cos(phi_max), r_min * std::sin(phi_max), z_max);
611  Acts::Vector3 p4(r_min * std::cos(phi_max), r_min * std::sin(phi_max), z_min);
612 
613  // outer face
614  z_min = r_max / std::tan(theta_min);
615  z_max = r_max / std::tan(theta_max);
616 
617  Acts::Vector3 p5(r_max * std::cos(phi_min), r_max * std::sin(phi_min), z_min);
618  Acts::Vector3 p6(r_max * std::cos(phi_min), r_max * std::sin(phi_min), z_max);
619  Acts::Vector3 p7(r_max * std::cos(phi_max), r_max * std::sin(phi_max), z_max);
620  Acts::Vector3 p8(r_max * std::cos(phi_max), r_max * std::sin(phi_max), z_min);
621 
622  Acts::Vector3 center;
623  center.x() = r * std::cos(phi);
624  center.y() = r * std::sin(phi);
625  center.z() = r / std::tan(theta);
626 
627  Acts::Transform3 glob2vol = Acts::Transform3::Identity();
628  glob2vol *= Acts::AngleAxis3(-phi, Acts::Vector3::UnitZ());
629  glob2vol *= Acts::AngleAxis3(
630  -theta, Acts::Vector3::UnitZ().cross(center).normalized());
631  glob2vol
632  *= Acts::Translation3(-(p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8) / 8.);
633 
634  p1 = glob2vol * p1;
635  p2 = glob2vol * p2;
636  p3 = glob2vol * p3;
637  p4 = glob2vol * p4;
638  p5 = glob2vol * p5;
639  p6 = glob2vol * p6;
640  p7 = glob2vol * p7;
641  p8 = glob2vol * p8;
642 
643  auto globalToLocal = glob2vol.inverse();
644 
645  auto cubo = std::make_shared<Acts::GenericCuboidVolumeBounds>(
646  std::array<Acts::Vector3, 8>({{p1, p2, p3, p4, p5, p6, p7, p8}}));
647 
648  Acts::Volume vol(globalToLocal, std::move(cubo));
649 
650  return vol;
651 }

◆ build_box()

Acts::Volume ActsCaloTrackingVolumeBuilder::build_box ( double  x,
double  dx,
double  y,
double  dy,
double  z,
double  dz 
) const
private

Definition at line 654 of file ActsCaloTrackingVolumeBuilder.cxx.

655 {
656  // std::cout << "build box" << std::endl;
657 
658  double x_min, x_max, y_min, y_max, z_min, z_max;
659  x_min = x - dx;
660  x_max = x + dx;
661  y_min = y - dy;
662  y_max = y + dy;
663  z_min = z - dz;
664  z_max = z + dz;
665 
666  // inner face
667  Acts::Vector3 p1(x_min, y_min, z_min);
668  Acts::Vector3 p2(x_min, y_max, z_min);
669  Acts::Vector3 p3(x_max, y_max, z_min);
670  Acts::Vector3 p4(x_max, y_min, z_min);
671 
672  // outer face
673  Acts::Vector3 p5(x_min, y_min, z_max);
674  Acts::Vector3 p6(x_min, y_max, z_max);
675  Acts::Vector3 p7(x_max, y_max, z_max);
676  Acts::Vector3 p8(x_max, y_min, z_max);
677 
678  Acts::Transform3 glob2vol = Acts::Transform3::Identity();
679  glob2vol
680  *= Acts::Translation3(-(p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8) / 8.);
681 
682  p1 = glob2vol * p1;
683  p2 = glob2vol * p2;
684  p3 = glob2vol * p3;
685  p4 = glob2vol * p4;
686  p5 = glob2vol * p5;
687  p6 = glob2vol * p6;
688  p7 = glob2vol * p7;
689  p8 = glob2vol * p8;
690 
691  auto globalToLocal = glob2vol.inverse();
692 
693  auto cubo = std::make_shared<Acts::GenericCuboidVolumeBounds>(
694  std::array<Acts::Vector3, 8>({{p1, p2, p3, p4, p5, p6, p7, p8}}));
695  Acts::Volume vol(globalToLocal, std::move(cubo));
696 
697  return vol;
698 }

◆ build_endcap()

Acts::Volume ActsCaloTrackingVolumeBuilder::build_endcap ( double  z,
double  dz,
double  eta,
double  deta,
double  phi,
double  dphi 
) const
private

Definition at line 513 of file ActsCaloTrackingVolumeBuilder.cxx.

519 {
520  double eta_max = eta + deta * 0.5;
521  double eta_min = eta - deta * 0.5;
522  double theta_max = eta_to_theta(eta_max);
523  double theta = eta_to_theta(eta);
524  double theta_min = eta_to_theta(eta_min);
525  double phi_max = phi + dphi * 0.5;
526  double phi_min = phi - dphi * 0.5;
527  double z_min = z - dz;
528  double z_max = z + dz;
529 
530  double r_min, r_max;
531 
532  // inner face
533  r_min = std::tan(theta_min) * z_min;
534  r_max = std::tan(theta_max) * z_min;
535 
536  Acts::Vector3 p1(r_min * std::cos(phi_min), r_min * std::sin(phi_min), z_min);
537  Acts::Vector3 p2(r_min * std::cos(phi_max), r_min * std::sin(phi_max), z_min);
538  Acts::Vector3 p3(r_max * std::cos(phi_max), r_max * std::sin(phi_max), z_min);
539  Acts::Vector3 p4(r_max * std::cos(phi_min), r_max * std::sin(phi_min), z_min);
540 
541  // outer face
542  r_min = std::tan(theta_min) * z_max;
543  r_max = std::tan(theta_max) * z_max;
544 
545  Acts::Vector3 p5(r_min * std::cos(phi_min), r_min * std::sin(phi_min), z_max);
546  Acts::Vector3 p6(r_min * std::cos(phi_max), r_min * std::sin(phi_max), z_max);
547  Acts::Vector3 p7(r_max * std::cos(phi_max), r_max * std::sin(phi_max), z_max);
548  Acts::Vector3 p8(r_max * std::cos(phi_min), r_max * std::sin(phi_min), z_max);
549 
550  double r_mid = std::tan(theta) * z_min;
551  Acts::Vector3 center;
552  center.x() = r_mid * std::cos(phi);
553  center.y() = r_mid * std::sin(phi);
554  center.z() = z;
555 
556  Acts::Transform3 glob2vol = Acts::Transform3::Identity();
557  glob2vol *= Acts::AngleAxis3(-phi, Acts::Vector3::UnitZ());
558  glob2vol *= Acts::AngleAxis3(
559  -theta, Acts::Vector3::UnitZ().cross(center).normalized());
560  glob2vol
561  *= Acts::Translation3(-(p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8) / 8.);
562 
563  p1 = glob2vol * p1;
564  p2 = glob2vol * p2;
565  p3 = glob2vol * p3;
566  p4 = glob2vol * p4;
567  p5 = glob2vol * p5;
568  p6 = glob2vol * p6;
569  p7 = glob2vol * p7;
570  p8 = glob2vol * p8;
571 
572  auto globalToLocal = glob2vol.inverse();
573 
574  auto cubo = std::make_shared<Acts::GenericCuboidVolumeBounds>(
575  std::array<Acts::Vector3, 8>({{p1, p2, p3, p4, p5, p6, p7, p8}}));
576  Acts::Volume vol(globalToLocal, std::move(cubo));
577 
578  return vol;
579 }

◆ cellFactory()

std::vector< std::unique_ptr< Acts::Volume > > ActsCaloTrackingVolumeBuilder::cellFactory ( ) const
private

Definition at line 701 of file ActsCaloTrackingVolumeBuilder.cxx.

702 {
703  //Acts::ply_helper<double> ply_lar;
704  //Acts::ply_helper<double> ply_tile;
705  //Acts::ply_helper<double> ply_fcal;
706 
707  //float x, y, z, r, phi_raw, eta_raw, dphi, deta, dr, dx, dy, dz;
708  float z, dz, eta_raw, deta, phi_raw, dphi, r, dr, x, y, dx, dy;
709  size_t calosample;
710  float scale;
711 
712  // storage of cells we will produce
713  std::vector<std::unique_ptr<Acts::Volume>> cells;
714  cells.reserve(m_caloMgr->element_size()); // about 180k
715 
716  for(auto it = m_caloMgr->element_begin();it < m_caloMgr->element_end();++it) {
717  const CaloDetDescrElement* cde = *it;
718 
719  z = cde->z();
720  dz = cde->dz();
721  eta_raw = cde->eta_raw();
722  deta = cde->deta();
723  phi_raw = cde->phi_raw();
724  dphi = cde->dphi();
725  r = cde->r();
726  dr = cde->dr();
727  x = cde->x();
728  y = cde->y();
729  dx = cde->dx();
730  dy = cde->dy();
731 
732  calosample = cde->getSampling();
733 
734  scale = 1.;
735  if (calosample >= 12 && calosample <= 20) {
736  scale = 0.5;
737  }
738 
739  //Acts::ply_helper<double>* ply;
740  //if (calosample <= 11) {
741  //ply = &ply_lar;
742  //} else if (calosample <= 20) {
743  //ply = &ply_tile;
744  //} else {
745  //ply = &ply_fcal;
746  //}
747 
748 
749  switch (calosample) {
750  case 4:
751  case 5:
752  case 6:
753  case 7:
754  case 8:
755  case 9:
756  case 10:
757  case 11:
758  case 17:
759  dz *= scale;
760  cells.push_back(std::make_unique<Acts::Volume>(
761  build_endcap(z, dz, eta_raw, deta, phi_raw, dphi)));
762  break;
763  case 0:
764  case 1:
765  case 2:
766  case 3:
767  case 12:
768  case 13:
769  case 14:
770  case 15:
771  case 16:
772  case 18:
773  case 19:
774  case 20:
775  dr *= scale;
776  cells.push_back(std::make_unique<Acts::Volume>(
777  build_barrel(r, dr, eta_raw, deta, phi_raw, dphi)));
778  break;
779  case 21:
780  case 22:
781  case 23:
782  scale = 1.;
783  dx *= scale;
784  dy *= scale;
785  // dz *= scale;
786  cells.push_back(std::make_unique<Acts::Volume>(
787  build_box(x, dx, y, dy, z, dz)));
788  break;
789  default:
790  std::stringstream ss;
791  ss << "Unkown calo sample " << calosample;
792  std::runtime_error(ss.str());
793  }
794 
795  //cells.back()->boundingBox({0.1, 0.1, 0.1}).draw(*ply);
796  //auto cvb = dynamic_cast<const
797  //Acts::GenericCuboidVolumeBounds*>(&cells.back()->volumeBounds());
798  //cvb->draw(*ply, cells.back()->transform());
799  }
800 
801  //std::ofstream os("lar.ply");
802  //os << ply_lar << std::flush;
803  //os.close();
804 
805  //os = std::ofstream("tile.ply");
806  //os << ply_tile << std::flush;
807  //os.close();
808 
809  //os = std::ofstream("fcal.ply");
810  //os << ply_fcal << std::flush;
811  //os.close();
812 
813  return cells;
814 }

◆ initialize()

StatusCode ActsCaloTrackingVolumeBuilder::initialize ( )
override

Definition at line 42 of file ActsCaloTrackingVolumeBuilder.cxx.

43 {
44  m_caloMgr = detStore()->tryConstRetrieve<CaloDetDescrManager>(caloMgrStaticKey);
45  if(!m_caloMgr) {
46  std::unique_ptr<CaloDetDescrManager> caloMgrPtr = buildCaloDetDescrNoAlign(serviceLocator()
48  ATH_CHECK(detStore()->record(std::move(caloMgrPtr), caloMgrStaticKey));
49  ATH_CHECK(detStore()->retrieve(m_caloMgr, caloMgrStaticKey));
50  }
51  return StatusCode::SUCCESS;
52 }

◆ makeCaloVolumeBounds()

std::shared_ptr< Acts::CutoutCylinderVolumeBounds > ActsCaloTrackingVolumeBuilder::makeCaloVolumeBounds ( const std::vector< std::unique_ptr< Acts::Volume::BoundingBox >> &  boxStore,
std::shared_ptr< const Acts::TrackingVolume >  insideVolume 
) const
private

Definition at line 352 of file ActsCaloTrackingVolumeBuilder.cxx.

354 {
355  using namespace Acts::VectorHelpers;
356 
357  // determine the dimensions of the
358  double rmin_at_center = std::numeric_limits<double>::max();
359  double rmin_at_choke = std::numeric_limits<double>::max();
360  double rmax = std::numeric_limits<double>::lowest();
362  double zmax = std::numeric_limits<double>::lowest();
363  double cutout_zmin_abs = std::numeric_limits<double>::max();
364 
365  // We need to figure out what the size of the inner cutout cylinder is
366  // so we can make sure everything worked fine!
367  // We check what the min radius at small z, and then we turn it around and
368  // check z bounds at lower radii.
369  for (const auto& box : boxStore) {
370  Acts::Vector3 vmin = box->min().cast<double>();
371  Acts::Vector3 vmax = box->max().cast<double>();
372 
373  double vrmin = perp(vmin);
374  double vrmax = perp(vmax);
375 
376  rmin_at_choke = std::min(rmin_at_choke, std::min(vrmin, vrmax));
377 
378  rmax = std::max(rmax, std::max(vrmin, vrmax));
379  zmin = std::min(zmin, std::min(vmin.z(), vmax.z()));
380  zmax = std::max(zmax, std::max(vmin.z(), vmax.z()));
381 
382  if (std::abs(vmin.z()) < 100) {
383  rmin_at_center = std::min(vrmin, rmin_at_center);
384  }
385  if (std::abs(vmax.z()) < 100) {
386  rmin_at_center = std::min(vrmax, rmin_at_center);
387  }
388  }
389 
390  for (const auto& box : boxStore) {
391  Acts::Vector3 vmin = box->min().cast<double>();
392  Acts::Vector3 vmax = box->max().cast<double>();
393  double vrmin = perp(vmin);
394  double vrmax = perp(vmax);
395 
396  if (vrmin < rmin_at_center * 0.9) {
397  cutout_zmin_abs = std::min(cutout_zmin_abs, std::abs(vmin.z()));
398  }
399  if (vrmax < rmin_at_center * 0.9) {
400  cutout_zmin_abs = std::min(cutout_zmin_abs, std::abs(vmax.z()));
401  }
402  }
403 
404  double dz1 = (zmax - zmin) / 2.;
405  double dz2 = cutout_zmin_abs;
406 
407  // envelopes
408  double envZ = 5;
409  double envR = 5;
410  dz1 += envZ;
411  dz2 -= envZ;
412  rmax += envR;
413  if(rmin_at_choke > envR) rmin_at_choke -= envR;
414  rmin_at_center -= envR;
415 
416 
417  ATH_MSG_VERBOSE("rmin_at_center: " << rmin_at_center
418  << " rmin at choke: " << rmin_at_choke
419  << " rmax: " << rmax << " zmin: " << zmin << " zmax: " << zmax
420  << " coutout_zmin_abs: " << cutout_zmin_abs);
421 
422  // Ok now let's analyse what we're wrapping the calo around: the ID
423  // The ID will have to be built already.
424 
425  // We need to figure out the dimensions of the ID.
426  // Assuming the wrapping volume is a cylinder.
427  auto idCylBds
428  = dynamic_cast<const Acts::CylinderVolumeBounds*>(&insideVolume->volumeBounds());
429  if (idCylBds == nullptr) { // protection against nullptr
430  ATH_MSG_ERROR("Unable to dynamic cast volume bounds to Acts::CylinderVolumeBounds");
431  throw std::runtime_error("Error casting to CylinderVolumeBounds");
432  }
433 
434  double idRMax = idCylBds->get(CVBBV::eMaxR);
435  double idRMin = idCylBds->get(CVBBV::eMinR);
436  double idHlZ = idCylBds->get(CVBBV::eHalfLengthZ);
437 
438  ATH_MSG_VERBOSE("ID volume bounds:\n" << *idCylBds);
439 
440  ATH_MSG_VERBOSE("Inside volume transform: \n" << insideVolume->transform().matrix());
441 
442  if (!insideVolume->transform().isApprox(Acts::Transform3::Identity())) {
443  ATH_MSG_VERBOSE("Inside volume transform is not unity.");
444 
445  // transformation matrix is NOT unity. Let's check:
446  // - Rotation is approximate unity
447  // - Translation is only along z axis
448  const auto& trf = insideVolume->transform();
449 
450  Acts::RotationMatrix3 rot = trf.rotation();
451  bool unityRot = rot.isApprox(Acts::RotationMatrix3::Identity());
452 
453  ATH_MSG_VERBOSE("\n" << rot);
454 
455  // dot product with Z axis is about 1 => ok
456  const Acts::Vector3 trl = trf.translation();
457  bool transZOnly = std::abs(1 - std::abs(Acts::Vector3::UnitZ().dot(trl.normalized()))) < 1e-6;
458 
459  ATH_MSG_VERBOSE("TRL "<< trl.transpose());
460  ATH_MSG_VERBOSE("TRL "<< trl.normalized().dot(Acts::Vector3::UnitZ()));
461 
462  if(!unityRot || !transZOnly) {
463  ATH_MSG_ERROR("The ID appears to be shifted from the origin. I cannot handle this.");
464  ATH_MSG_ERROR("(I'm not building the Calo!)");
465  throw std::runtime_error("Error building calo");
466  }
467  else {
468  ATH_MSG_VERBOSE("Checked: non unitarity is ONLY due to shift along z axis: that's ok");
469  double prevIdHlZ = idHlZ;
470  idHlZ += std::abs(trl.z());
471  ATH_MSG_VERBOSE("Modifying effective half length of ID cylinder: " << prevIdHlZ << " => " << idHlZ);
472  }
473  }
474 
475  // make sure we can fit the ID inside the calo cutout
476  if (idRMax > rmin_at_center || idHlZ > dz2 || (idRMin > rmin_at_choke && idRMin != 0.)) {
477  ATH_MSG_ERROR("Cannot fit ID inside the Calo");
478  ATH_MSG_ERROR("This can be because the ID overlaps into the calo volume");
479  ATH_MSG_ERROR("Or because the Calo choke radius is SMALLER than the ID inner radius");
480  ATH_MSG_ERROR("Currently, I can only make the choke radius smaller, I can not make it larger");
481  ATH_MSG_ERROR("nor can I manipulate the ID volume bounds at this point.");
482  ATH_MSG_ERROR("ID rMax: " << idRMax << " Calo rMin@center: " << rmin_at_center);
483  ATH_MSG_ERROR("ID hlZ: " << idHlZ << " Calo inner Z hl: " << dz2);
484  ATH_MSG_ERROR("ID rMin: " << idRMin << " Calo rMin@choke: " << rmin_at_choke);
485  ATH_MSG_ERROR("(I'm not building the Calo!)");
486  throw std::runtime_error("Error building calo");
487  }
488 
489  // Let's harmonize the sizes, so we have a exact wrap of the ID
490  // Choke is now exactly as wide as space inside the ID.
491  // We can fit the beam pipe in there later.
492  rmin_at_choke = idRMin;
493 
494  std::shared_ptr<Acts::CutoutCylinderVolumeBounds> volBds = nullptr;
495  volBds = std::make_shared<Acts::CutoutCylinderVolumeBounds>(
496  rmin_at_choke, rmin_at_center, rmax, dz1, dz2);
497 
498  ATH_MSG_VERBOSE(*volBds);
499 
500  return volBds;
501 }

◆ trackingVolume()

std::shared_ptr< Acts::TrackingVolume > ActsCaloTrackingVolumeBuilder::trackingVolume ( const Acts::GeometryContext &  gctx,
std::shared_ptr< const Acts::TrackingVolume >  insideVolume = nullptr,
std::shared_ptr< const Acts::VolumeBounds >  outsideBounds = nullptr 
) const
override

Definition at line 55 of file ActsCaloTrackingVolumeBuilder.cxx.

59 {
60 
61 
62  // generate the calo cell volume description
63  std::vector<std::unique_ptr<Acts::Volume>> cells;
64  cells = cellFactory();
65 
66  ATH_MSG_VERBOSE("Collected " << cells.size() << " calo cells");
67 
68 
69  // we need to turn the cells into boundary boxes
70  std::vector<std::unique_ptr<Box>> boxStore;
71  std::vector<Box*> prims;
72  for (const auto& cell : cells) {
73  boxStore.push_back(
74  std::make_unique<Box>(cell->boundingBox({0.1, 0.1, 0.1})));
75  prims.push_back(boxStore.back().get());
76  }
77 
78  ATH_MSG_VERBOSE("Generated Bounding Boxes");
79 
80 
81  ATH_MSG_VERBOSE("Figure out dimensions of wrapping volume");
82 
83  std::shared_ptr<Acts::CutoutCylinderVolumeBounds> caloVolBounds
84  = makeCaloVolumeBounds(boxStore, std::move(insideVolume));
85 
86  // build a BVH octree for the bounding boxes
87  // but only AFTER we've built the calo volume bounds
88  // Box* top;
89  // top = Acts::make_octree(boxStore, prims, 1, 0.1);
90 
91  // Create Tracking Volume that coutains the Calo
92  // This needs to own the Abstract Volumes (cells), but we
93  // need to up-cast them to Volume, since that's what TrackingVolume can own
94  std::vector<std::unique_ptr<const Acts::Volume>> cellVols;
95  cellVols.reserve(cells.size());
96  for(auto& cell : cells) {
97  std::unique_ptr<const Acts::Volume> up;
98  // release, up-cast, then immediately pack again
99  up = std::unique_ptr<const Acts::Volume>(dynamic_cast<const Acts::Volume*>(cell.release()));
100  cellVols.push_back(std::move(up));
101  }
102 
103  // This was removed in https://github.com/acts-project/acts/pull/3029
104  // To be reimplemented using new geometry model instead of explicit TrackingVolume content
105  (void)gctx; // suppress compiler warning
106  throw std::runtime_error{"Calo building for ACTS currently disabled"};
107 
108  /***** TODO START *****
109  std::shared_ptr<Acts::TrackingVolume> calo;
110  // = Acts::TrackingVolume::create(Acts::Transform3::Identity(),
111  // caloVolBounds,
112  // std::move(boxStore),
113  // std::move(cellVols),
114  // top,
115  // nullptr, // no material for now
116  // "Calo");
117 
118  // We need to interglue all the volumes together
119  std::shared_ptr<Acts::TrackingVolume> mutInsideVolume
120  = std::const_pointer_cast<Acts::TrackingVolume>(insideVolume);
121  auto idBounds = dynamic_cast<const Acts::CylinderVolumeBounds*>(&insideVolume->volumeBounds());
122  if (idBounds == nullptr) { // protection against nullptr
123  ATH_MSG_ERROR("Unable to dynamic cast volume bounds to Acts::CylinderVolumeBounds");
124  throw std::runtime_error("Error casting to CylinderVolumeBounds");
125  }
126 
127  // we want gap volumes at pos and neg xy face, and at outer cyl cover
128  // which will include the solenoid area
129 
130  auto trackingVolumeArrayCreator
131  = std::make_shared<const Acts::TrackingVolumeArrayCreator>(
132  Acts::TrackingVolumeArrayCreator::Config{},
133  makeActsAthenaLogger(this, std::string("TrkVolArrCrtr"), std::string("ActsTGSvc")));
134  Acts::CylinderVolumeHelper::Config cvhCfg;
135  cvhCfg.trackingVolumeArrayCreator = trackingVolumeArrayCreator;
136  Acts::CylinderVolumeHelper cvh(cvhCfg, makeActsAthenaLogger(this, std::string("ACaloTrkVB"), std::string("CylVolHlp")));
137 
138  std::vector<double> lPos = {};
139  std::vector<std::shared_ptr<Acts::TrackingVolume>> noVolumes;
140 
141  ATH_MSG_VERBOSE("Creating gap volume to extend ID");
142  // positive xy gap
143  auto idGapPosXY = cvh.createGapTrackingVolume(gctx,
144  noVolumes,
145  nullptr,
146  idBounds->get(CVBBV::eMinR),
147  idBounds->get(CVBBV::eMaxR),
148  idBounds->get(CVBBV::eHalfLengthZ),
149  caloVolBounds->get(CCVBBV::eHalfLengthZcutout),
150  lPos,
151  false,
152  "ID::PositiveGap"
153  );
154  // negative xy gap
155  auto idGapNegXY = cvh.createGapTrackingVolume(gctx,
156  noVolumes,
157  nullptr,
158  idBounds->get(CVBBV::eMinR),
159  idBounds->get(CVBBV::eMaxR),
160  -caloVolBounds->get(CCVBBV::eHalfLengthZcutout),
161  -idBounds->get(CVBBV::eHalfLengthZ),
162  lPos,
163  false,
164  "ID::NegativeGap"
165  );
166  // outer cover gap
167  auto idGapCylOuter = cvh.createGapTrackingVolume(gctx,
168  noVolumes,
169  nullptr,
170  idBounds->get(CVBBV::eMaxR),
171  caloVolBounds->get(CCVBBV::eMedR),
172  -caloVolBounds->get(CCVBBV::eHalfLengthZcutout),
173  +caloVolBounds->get(CCVBBV::eHalfLengthZcutout),
174  lPos,
175  false,
176  "ID::CylOutGap"
177  );
178 
179  ATH_MSG_VERBOSE("Create container volume to contain ID and gap volumes");
180  auto idContainerZ = cvh.createContainerTrackingVolume(gctx, {idGapNegXY, mutInsideVolume, idGapPosXY});
181  auto idContainer = cvh.createContainerTrackingVolume(gctx, {idContainerZ, idGapCylOuter});
182 
183 
184  ATH_MSG_VERBOSE("Begin volume glueing");
185 
186  const Acts::GlueVolumesDescriptor& gvd
187  = idContainer->glueVolumesDescriptor();
188  // let's see what the GVD says is on the inner cover of the ID
189  const auto& tVolArrPos = gvd.glueVolumes(Acts::positiveFaceXY);
190  const auto& tVolArrNeg = gvd.glueVolumes(Acts::negativeFaceXY);
191 
192  std::cout << "POSITIVE: " << std::endl;
193  for(const auto& subvol : tVolArrPos->arrayObjects()) {
194  std::cout << subvol->volumeName() << std::endl;
195  std::cout << *subvol << std::endl;
196  }
197 
198  std::cout << "NEGATIVE: " << std::endl;
199  for(const auto& subvol : tVolArrNeg->arrayObjects()) {
200  std::cout << subvol->volumeName() << std::endl;
201  std::cout << *subvol << std::endl;
202  }
203 
204  using BoundarySurface = Acts::BoundarySurfaceT<Acts::TrackingVolume>;
205 
206 
207  // Glue outer radial cover of ID to inner cover of Calo cutout
208  auto idOutVolArray = gvd.glueVolumes(Acts::tubeOuterCover);
209  // Attach that volume array to the calo inner cover
210  ATH_MSG_VERBOSE("Glueing " << calo->volumeName() << " inner cover to " << idOutVolArray->arrayObjects().size() << " volumes");
211  std::const_pointer_cast<BoundarySurface>(calo->boundarySurfaces().at(Acts::tubeInnerCover))
212  ->attachVolumeArray(idOutVolArray, Acts::Direction::Backward);
213  // Loop through the array and attach their boundary surfaces to the calo
214  for(const auto& idVol : idOutVolArray->arrayObjects()){
215  ATH_MSG_VERBOSE("Glueing outer cover of " << idVol->volumeName()
216  << " to inner cover of " << calo->volumeName());
217  std::const_pointer_cast<BoundarySurface>(idVol->boundarySurfaces().at(Acts::tubeOuterCover))
218  ->attachVolume(calo.get(), Acts::Direction::Forward);
219  }
220 
221  // Glue positive XY face of ID to inner positive XY face of Calo.
222  // ID has multiple, Calo has only one
223  auto idPosXYVolArray = gvd.glueVolumes(Acts::positiveFaceXY);
224  ATH_MSG_VERBOSE("Glueing " << calo->volumeName() << " positive inner cutout disc to "
225  << idPosXYVolArray->arrayObjects().size() << " volumes");
226  std::const_pointer_cast<BoundarySurface>(calo->boundarySurfaces().at(Acts::index5))
227  ->attachVolumeArray(idPosXYVolArray, Acts::Direction::Backward);
228  // Other way round, attach ID volumes to calo
229  for(const auto& idVol : idPosXYVolArray->arrayObjects()){
230  ATH_MSG_VERBOSE("Glueing positive XY face of " << idVol->volumeName()
231  << " to positive inner coutout disc of " << calo->volumeName());
232  std::const_pointer_cast<BoundarySurface>(idVol->boundarySurfaces().at(Acts::positiveFaceXY))
233  ->attachVolume(calo.get(), Acts::Direction::Forward);
234  }
235 
236  // Glue negative XY face of ID to inner negative XY face of Calo.
237  // ID has multiple, Calo has only one
238  auto idNegXYVolArray = gvd.glueVolumes(Acts::negativeFaceXY);
239  ATH_MSG_VERBOSE("Glueing " << calo->volumeName() << " negative inner cutout disc to "
240  << idNegXYVolArray->arrayObjects().size() << " volumes");
241  std::const_pointer_cast<BoundarySurface>(calo->boundarySurfaces().at(Acts::index4))
242  ->attachVolumeArray(idNegXYVolArray, Acts::Direction::Forward);
243  // Other way round, attach ID volumes to calo
244  for(const auto& idVol : idNegXYVolArray->arrayObjects()){
245  ATH_MSG_VERBOSE("Glueing negative XY face of " << idVol->volumeName()
246  << " to negative inner coutout disc of " << calo->volumeName());
247  std::const_pointer_cast<BoundarySurface>(idVol->boundarySurfaces().at(Acts::negativeFaceXY))
248  ->attachVolume(calo.get(), Acts::Direction::Backward);
249  }
250 
251  // For navigational purposes we need to create three pseudo container cylinders.
252  // One for the middle, which includes the central part of the Calo and the ID, and
253  // two that fit cleanly at the +- XY face that then only include the Calo
254 
255  // Construct track vol array for use in positive and negative pseudocontainer.
256  // This will only contain the calo
257 
258  double caloRMin = caloVolBounds->get(CCVBBV::eMinR);
259  double caloRMed = caloVolBounds->get(CCVBBV::eMedR);
260  double caloRMax = caloVolBounds->get(CCVBBV::eMaxR);
261  double caloDZ1 = caloVolBounds->get(CCVBBV::eHalfLengthZ);
262  double caloDZ2 = caloVolBounds->get(CCVBBV::eHalfLengthZcutout);
263 
264  Acts::Vector3 caloChokeRPos
265  = {caloRMin + (caloRMax - caloRMin)/2., 0, 0};
266 
267  std::vector<Acts::TrackingVolumeOrderPosition> tVolOrdPosNeg;
268  tVolOrdPosNeg.push_back(std::make_pair(calo, caloChokeRPos));
269  std::vector<float> posNegBoundaries
270  = {float(caloRMin), float(caloRMax)};
271  auto binUtilityPosNeg = std::make_unique<const Acts::BinUtility>(posNegBoundaries,
272  Acts::open, Acts::AxisDirection::AxisR);
273 
274  auto tVolArrPosNeg
275  = std::make_shared<const Acts::BinnedArrayXD<Acts::TrackingVolumePtr>>(
276  tVolOrdPosNeg, std::move(binUtilityPosNeg));
277 
278  double chokeZOffset = caloDZ2 + (caloDZ1 - caloDZ2)/2.;
279  Acts::Transform3 posTrf(Acts::Translation3(Acts::Vector3::UnitZ() * chokeZOffset));
280  Acts::Transform3 negTrf(Acts::Translation3(Acts::Vector3::UnitZ()* -1 *chokeZOffset));
281 
282  auto posNegCylBounds = std::make_shared<Acts::CylinderVolumeBounds>(
283  caloRMin, caloRMax, (caloDZ1 - caloDZ2) / 2.);
284 
285  // they share the same bounds and tvol array
286  auto posContainer = std::make_shared<Acts::TrackingVolume>(
287  posTrf,
288  posNegCylBounds,
289  nullptr, nullptr,
290  tVolArrPosNeg,
291  Acts::MutableTrackingVolumeVector{});
292  ATH_MSG_VERBOSE("Built positive container " << *posContainer);
293  ATH_MSG_VERBOSE(" - containing: " << calo->volumeName());
294  auto negContainer = std::make_shared<Acts::TrackingVolume>(
295  negTrf,
296  posNegCylBounds,
297  nullptr, nullptr,
298  tVolArrPosNeg,
299  Acts::MutableTrackingVolumeVector{});
300  ATH_MSG_VERBOSE("Built negative container " << *negContainer);
301  ATH_MSG_VERBOSE(" - containing: " << calo->volumeName());
302 
303  // now build the central pseudocontainer
304  std::vector<Acts::TrackingVolumeOrderPosition> tVolOrderedCtr;
305  tVolOrderedCtr.push_back(std::make_pair(idContainer, Acts::Vector3(caloRMed / 2., 0, 0)));
306  tVolOrderedCtr.push_back(std::make_pair(calo,
307  Acts::Vector3(caloRMed +
308  (caloRMax- caloRMed) / 2., 0, 0)));
309 
310  std::vector<float> ctrBoundaries = {0, float(caloRMed), float(caloRMax)};
311  auto binUtilityCtr
312  = std::make_unique<const Acts::BinUtility>(
313  ctrBoundaries,
314  Acts::open, Acts::AxisDirection::AxisR);
315 
316  auto tVolArrCtr
317  = std::make_shared<const Acts::BinnedArrayXD<Acts::TrackingVolumePtr>>(
318  tVolOrderedCtr, std::move(binUtilityCtr));
319 
320 
321  auto ctrContainer = std::make_shared<Acts::TrackingVolume>(Acts::Transform3::Identity(),
322  std::make_shared<Acts::CylinderVolumeBounds>(
323  caloRMin, caloRMax, caloDZ2),
324  nullptr, nullptr,
325  tVolArrCtr,
326  Acts::MutableTrackingVolumeVector{}
327  );
328 
329  ATH_MSG_VERBOSE("Built central container " << *ctrContainer);
330  ATH_MSG_VERBOSE("- containing: " << idContainer->volumeName() << ", " << calo->volumeName());
331 
332  // and now combine those together into another one
333  Acts::TrackingVolumeArrayCreator tvac{Acts::TrackingVolumeArrayCreator::Config{}};
334 
335  auto mainContainer = std::make_shared<Acts::TrackingVolume>(Acts::Transform3::Identity(),
336  std::make_shared<Acts::CylinderVolumeBounds>(
337  caloRMin, caloRMax, caloDZ1),
338  nullptr, nullptr,
339  tvac.trackingVolumeArray(gctx, {negContainer, ctrContainer, posContainer},
340  Acts::AxisDirection::AxisZ),
341  Acts::MutableTrackingVolumeVector{}
342  );
343 
344 
345  ATH_MSG_VERBOSE("Built main container: " << *mainContainer);
346 
347  return mainContainer;
348  ***** TODO END *****/
349 }

Member Data Documentation

◆ m_caloMgr

const CaloDetDescrManager* ActsCaloTrackingVolumeBuilder::m_caloMgr {nullptr}
private

Definition at line 64 of file ActsCaloTrackingVolumeBuilder.h.


The documentation for this class was generated from the following files:
CaloDetDescrElement::deta
float deta() const
cell deta
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:356
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
beamspotman.r
def r
Definition: beamspotman.py:672
RunTileCalibRec.cells
cells
Definition: RunTileCalibRec.py:281
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
CaloDetDescrElement::y
float y() const
cell y
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:365
perp
Scalar perp() const
perp method - perpendicular length
Definition: AmgMatrixBasePlugin.h:44
ActsCaloTrackingVolumeBuilder::makeCaloVolumeBounds
std::shared_ptr< Acts::CutoutCylinderVolumeBounds > makeCaloVolumeBounds(const std::vector< std::unique_ptr< Acts::Volume::BoundingBox >> &boxStore, std::shared_ptr< const Acts::TrackingVolume > insideVolume) const
Definition: ActsCaloTrackingVolumeBuilder.cxx:352
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
PixelAthClusterMonAlgCfg.zmin
zmin
Definition: PixelAthClusterMonAlgCfg.py:169
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
CaloDetDescrElement
This class groups all DetDescr information related to a CaloCell. Provides a generic interface for al...
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:66
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:75
TRTCalib_cfilter.p1
p1
Definition: TRTCalib_cfilter.py:130
CaloDetDescrElement::dr
float dr() const
cell dr
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:360
skel.it
it
Definition: skel.GENtoEVGEN.py:407
PlotCalibFromCool.vmin
vmin
Definition: PlotCalibFromCool.py:696
python.TurnDataReader.dr
dr
Definition: TurnDataReader.py:111
ActsCaloTrackingVolumeBuilder::build_box
Acts::Volume build_box(double x, double dx, double y, double dy, double z, double dz) const
Definition: ActsCaloTrackingVolumeBuilder.cxx:654
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
x
#define x
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
CaloDetDescrElement::eta_raw
float eta_raw() const
cell eta_raw
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:350
CaloDetDescrElement::dz
float dz() const
cell dz
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:379
ActsCaloTrackingVolumeBuilder::build_barrel
Acts::Volume build_barrel(double r, double dr, double eta, double deta, double phi, double dphi) const
Definition: ActsCaloTrackingVolumeBuilder.cxx:583
TRTCalib_cfilter.p2
p2
Definition: TRTCalib_cfilter.py:131
ActsCaloTrackingVolumeBuilder::cellFactory
std::vector< std::unique_ptr< Acts::Volume > > cellFactory() const
Definition: ActsCaloTrackingVolumeBuilder.cxx:701
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
z
#define z
CalibCoolCompareRT.up
up
Definition: CalibCoolCompareRT.py:108
PixelAthClusterMonAlgCfg.zmax
zmax
Definition: PixelAthClusterMonAlgCfg.py:169
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
dot.dot
def dot(G, fn, nodesToHighlight=[])
Definition: dot.py:5
ActsCaloTrackingVolumeBuilder::build_endcap
Acts::Volume build_endcap(double z, double dz, double eta, double deta, double phi, double dphi) const
Definition: ActsCaloTrackingVolumeBuilder.cxx:513
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
CaloDetDescrManager_Base::element_begin
calo_element_const_iterator element_begin() const
first element
Definition: CaloDetDescrManager.cxx:111
CaloDetDescrElement::x
float x() const
cell x
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:363
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
CaloDetDescrElement::dphi
float dphi() const
cell dphi
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:358
ActsCaloTrackingVolumeBuilder::m_caloMgr
const CaloDetDescrManager * m_caloMgr
Definition: ActsCaloTrackingVolumeBuilder.h:64
y
#define y
CaloDetDescrManager
This class provides the client interface for accessing the detector description information common to...
Definition: CaloDetDescrManager.h:469
CaloDetDescrElement::dx
float dx() const
cell dx
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:375
CaloDetDescrElement::getSampling
CaloCell_ID::CaloSample getSampling() const
cell sampling
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:395
CaloDetDescrManager_Base::element_size
calo_element_vec_size element_size() const
total number of elements
Definition: CaloDetDescrManager.cxx:105
CaloDetDescrElement::z
float z() const
cell z
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:367
makeTRTBarrelCans.dx
tuple dx
Definition: makeTRTBarrelCans.py:20
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
CaloLCW_tf.trf
trf
Definition: CaloLCW_tf.py:20
CaloDetDescrElement::r
float r() const
cell r
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:348
TRTCalib_cfilter.p3
p3
Definition: TRTCalib_cfilter.py:132
CaloDetDescrElement::dy
float dy() const
cell dy
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:377
buildCaloDetDescrNoAlign
std::unique_ptr< CaloDetDescrManager > buildCaloDetDescrNoAlign(ISvcLocator *svcLocator, IMessageSvc *msgSvc)
Definition: CaloDetDescrBuilder.cxx:791
PlotCalibFromCool.vmax
vmax
Definition: PlotCalibFromCool.py:697
CaloDetDescrElement::phi_raw
float phi_raw() const
cell phi_raw
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:352