ATLAS Offline Software
ActsHGTDLayerBuilder.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 // ATHENA
5 
9 
10 // PACKAGE
13 
14 // ACTS
15 #include "Acts/Definitions/Algebra.hpp"
16 #include "Acts/Definitions/Units.hpp"
17 #include "Acts/Geometry/ApproachDescriptor.hpp"
18 #include "Acts/Geometry/GenericApproachDescriptor.hpp"
19 #include "Acts/Geometry/GeometryContext.hpp"
20 #include "Acts/Geometry/LayerCreator.hpp"
21 #include "Acts/Geometry/ProtoLayer.hpp"
22 #include "Acts/Material/ProtoSurfaceMaterial.hpp"
23 #include "Acts/Surfaces/CylinderSurface.hpp"
24 #include "Acts/Surfaces/DiscSurface.hpp"
25 #include "Acts/Utilities/BinningType.hpp"
26 #include "Acts/Surfaces/AnnulusBounds.hpp"
27 
28 #include "Acts/Visualization/GeometryView3D.hpp"
29 #include "Acts/Visualization/ObjVisualization3D.hpp"
30 
31 #include <iterator>
32 #include <unordered_map>
33 
34 using Acts::Surface;
35 using Acts::Transform3;
36 using Acts::Translation3;
37 
38 using namespace Acts::UnitLiterals;
39 
41  std::unique_ptr<const Acts::Logger> logger)
42  : m_cfg (cfg),
43  m_logger(std::move(logger))
44 {
45 }
46 
47 const Acts::LayerVector
48 ActsHGTDLayerBuilder::negativeLayers(const Acts::GeometryContext &gctx) const {
49  ACTS_VERBOSE("Building negative layers");
50  Acts::LayerVector nVector;
51  buildEndcap(gctx, nVector, -1);
52  return nVector;
53 }
54 
55 const Acts::LayerVector
56 ActsHGTDLayerBuilder::centralLayers(const Acts::GeometryContext & /*gctx*/) const {
57  ACTS_VERBOSE("HGTD has no central layers");
58  Acts::LayerVector layers;
59  return layers;
60 }
61 
62 const Acts::LayerVector
63 ActsHGTDLayerBuilder::positiveLayers(const Acts::GeometryContext &gctx) const {
64  ACTS_VERBOSE("Building positive layers");
65  Acts::LayerVector pVector;
66  buildEndcap(gctx, pVector, 1);
67  return pVector;
68 }
69 
70 void ActsHGTDLayerBuilder::buildEndcap(const Acts::GeometryContext &gctx,
71  Acts::LayerVector &layersOutput, int type) const
72 {
73 
74  ACTS_VERBOSE("Build layers: " << (type < 0 ? "NEGATIVE" : "POSITIVE")
75  << " ENDCAP");
76 
77  std::vector<std::shared_ptr<const ActsDetectorElement>> elements =
79  std::map<int, std::vector<const Acts::Surface *>>
80  initialLayers{};
81 
82  for (const auto &element : elements) {
83 
84  Identifier currentId(element->identify());
85  // Check if the element is in the correct endcap (type -1 or 1)
86  if (m_cfg.idHelper->endcap(currentId) * type <= 0) {
87  continue;
88  }
89 
90  m_cfg.elementStore->push_back(element);
91  int currentLayer {m_cfg.idHelper->layer(currentId)};
92 
93  initialLayers[currentLayer].push_back(&element->surface());
94  }
95 
96  ACTS_VERBOSE("Found " << initialLayers.size() << " "
97  << (type < 0 ? "NEGATIVE" : "POSITIVE")
98  << " ENDCAP inital layers");
99 
100  // Loops over a provided vector of surface and calculates the various
101  // min/max values in one go. Also takes into account the thickness
102  // of an associated DetectorElement, if it exists.
103  //
104  // @param gctx The current geometry context object, e.g. alignment
105  // @param surfaces The vector of surfaces to consider
106 
107  std::vector<Acts::ProtoLayer> protoLayers;
108  protoLayers.reserve(initialLayers.size());
109 
110  for (const auto &[key, surfaces] : initialLayers) {
111  auto &pl = protoLayers.emplace_back(gctx, surfaces);
112  pl.envelope[Acts::binR] = m_cfg.endcapEnvelopeR;
113  pl.envelope[Acts::binZ] = m_cfg.endcapEnvelopeZ;
114  }
115 
116 
117  // sort proto layers by their medium z position
118  std::sort(protoLayers.begin(), protoLayers.end(),
119  [type](const Acts::ProtoLayer &a, const Acts::ProtoLayer &b) {
120  double midA = (a.min(Acts::binZ) + a.max(Acts::binZ)) / 2.0;
121  double midB = (b.min(Acts::binZ) + b.max(Acts::binZ)) / 2.0;
122  if (type < 0) {
123  return midA < midB;
124  } else {
125  return midA > midB;
126  }
127  });
128 
129  std::vector<std::shared_ptr<const Surface>> ownedSurfaces;
130  for (const auto &pl : protoLayers) {
131 
132  std::unique_ptr<Acts::ApproachDescriptor> approachDescriptor = nullptr;
133  std::shared_ptr<const Acts::ProtoSurfaceMaterial> materialProxy = nullptr;
134 
135  double layerZ = pl.medium(Acts::binZ);
136  double layerHalfZ = 0.5 * pl.range(Acts::binZ);
137 
138  double layerZInner = layerZ - layerHalfZ;
139  double layerZOuter = layerZ + layerHalfZ;
140 
141  if (std::abs(layerZInner) > std::abs(layerZOuter))
142  std::swap(layerZInner, layerZOuter);
143 
144  std::vector<std::shared_ptr<const Acts::Surface>> aSurfaces;
145 
146  Acts::Transform3 transformNominal(Translation3(0., 0., layerZ));
147  Acts::Transform3 transformInner(Translation3(0., 0., layerZInner));
148  Acts::Transform3 transformOuter(Translation3(0., 0., layerZOuter));
149 
150  std::shared_ptr<Acts::DiscSurface> innerBoundary =
151  Acts::Surface::makeShared<Acts::DiscSurface>(
152  transformInner, pl.min(Acts::binR), pl.max(Acts::binR));
153  aSurfaces.push_back(innerBoundary);
154 
155  std::shared_ptr<Acts::DiscSurface> nominalSurface =
156  Acts::Surface::makeShared<Acts::DiscSurface>(
157  transformNominal, pl.min(Acts::binR), pl.max(Acts::binR));
158  aSurfaces.push_back(nominalSurface);
159 
160  std::shared_ptr<Acts::DiscSurface> outerBoundary =
161  Acts::Surface::makeShared<Acts::DiscSurface>(
162  transformOuter, pl.min(Acts::binR), pl.max(Acts::binR));
163  aSurfaces.push_back(outerBoundary);
164 
165  size_t matBinsPhi = m_cfg.endcapMaterialBins.first;
166  size_t matBinsR = m_cfg.endcapMaterialBins.second;
167 
168  Acts::BinUtility materialBinUtil(matBinsPhi, -M_PI, M_PI, Acts::closed,
169  Acts::binPhi);
170  materialBinUtil +=
171  Acts::BinUtility(matBinsR, pl.min(Acts::binR), pl.max(Acts::binR),
172  Acts::open, Acts::binR, transformNominal);
173 
174  materialProxy =
175  std::make_shared<const Acts::ProtoSurfaceMaterial>(materialBinUtil);
176 
177  ACTS_VERBOSE("[L] Layer is marked to carry support material on Surface ( "
178  "inner=0 / center=1 / outer=2 ) : "
179  << "inner");
180  ACTS_VERBOSE("with binning: [" << matBinsPhi << ", " << matBinsR << "]");
181 
182  ACTS_VERBOSE("Created ApproachSurfaces for disc layer at:");
183  ACTS_VERBOSE(" - inner: Z=" << layerZInner);
184  ACTS_VERBOSE(" - central: Z=" << layerZ);
185  ACTS_VERBOSE(" - outer: Z=" << layerZOuter);
186 
187  // set material on inner
188  innerBoundary->assignSurfaceMaterial(materialProxy);
189 
190  std::set<int> phiModuleByRing;
191  // want to figure out bins in phi
192  for (const auto &srf : pl.surfaces()) {
193  auto elm = dynamic_cast<const ActsDetectorElement *>(
194  srf->associatedDetectorElement());
195  if (elm) {
196  auto id = elm->identify();
197  phiModuleByRing.insert(m_cfg.idHelper->phi_module(id));
198  }
199  }
200 
201  size_t nModPhi = 50; //phiModuleByRing.size();
202  size_t nModR = 1;// pl.surfaces().size()/nModPhi;
203 
204  ACTS_VERBOSE("Identifier reports: " << nModPhi << " is lowest for " << nModR
205  << " r-rings");
206 
207  size_t nBinsPhi = nModPhi;
208  size_t nBinsR = nModR;
209 
210 
211  ACTS_VERBOSE("Creating r x phi binned layer with " << nBinsR << " x "
212  << nBinsPhi << " bins");
213 
214 
215  approachDescriptor =
216  std::make_unique<Acts::GenericApproachDescriptor>(aSurfaces);
217 
218  // get ownership of pl surfaces
219  ownedSurfaces.clear();
220  ownedSurfaces.reserve(pl.surfaces().size());
221  std::transform(pl.surfaces().begin(), pl.surfaces().end(),
222  std::back_inserter(ownedSurfaces),
223  [](const auto &s) { return s->getSharedPtr(); });
224 
225  auto layer = m_cfg.layerCreator->discLayer(gctx, ownedSurfaces, nBinsR,
226  nBinsPhi, pl, transformNominal,
227  std::move(approachDescriptor));
228 
229  layersOutput.push_back( std::move(layer) );
230  }
231 }
232 
233 std::vector<std::shared_ptr<const ActsDetectorElement>>
235  ACTS_VERBOSE("Retrieving detector elements from detector manager");
236  if ( not m_cfg.mng ) {
237  ACTS_ERROR("Manager is null");
238  throw std::runtime_error{"Detector manager is null"};
239  }
240  auto hgtdDetMng = static_cast<const HGTD_DetectorManager *>(m_cfg.mng);
241  ACTS_VERBOSE("Detector manager has "
242  << std::distance(hgtdDetMng->getDetectorElementBegin(),
243  hgtdDetMng->getDetectorElementEnd())
244  << " elements");
245 
246  std::vector<std::shared_ptr<const ActsDetectorElement>> elements;
247 
248  InDetDD::HGTD_DetectorElementCollection::const_iterator iter;
249  for (iter = hgtdDetMng->getDetectorElementBegin();
250  iter != hgtdDetMng->getDetectorElementEnd(); ++iter) {
251  const InDetDD::HGTD_DetectorElement *detElement =
252  dynamic_cast<InDetDD::HGTD_DetectorElement *>(*iter);
253 
254  if (not detElement) {
255  ACTS_ERROR("Detector element was nullptr");
256  throw std::runtime_error{"Corrupt detector element collection"};
257  }
258  elements.push_back(
259  std::make_shared<const ActsDetectorElement>(*detElement, (*iter)->identify()));
260  }
261  ACTS_VERBOSE("Retrieved " << elements.size() << " elements");
262 
263  return elements;
264 }
ActsHGTDLayerBuilder::Config::endcapEnvelopeZ
std::array< double, 2 > endcapEnvelopeZ
Definition: ActsHGTDLayerBuilder.h:63
ActsHGTDLayerBuilder::getDetectorElements
std::vector< std::shared_ptr< const ActsDetectorElement > > getDetectorElements() const
Definition: ActsHGTDLayerBuilder.cxx:234
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
Trk::binZ
@ binZ
Definition: BinningType.h:49
IdentityHelper.h
ActsHGTDLayerBuilder::Config
Definition: ActsHGTDLayerBuilder.h:45
ActsHGTDLayerBuilder::negativeLayers
virtual const Acts::LayerVector negativeLayers(const Acts::GeometryContext &gctx) const override
Definition: ActsHGTDLayerBuilder.cxx:48
HGTD_ID::endcap
int endcap(const Identifier &id) const
Values of different levels (failure returns 0)
Definition: HGTD_ID.h:468
ActsHGTDLayerBuilder::buildEndcap
void buildEndcap(const Acts::GeometryContext &gctx, Acts::LayerVector &layersOutput, int type=0) const
Definition: ActsHGTDLayerBuilder.cxx:70
module_driven_slicing.layers
layers
Definition: module_driven_slicing.py:114
InDetDD::HGTD_DetectorElement
Definition: HGTD_DetectorElement.h:40
M_PI
#define M_PI
Definition: ActiveFraction.h:11
Trk::closed
@ closed
Definition: BinningType.h:41
HGTD_ID::layer
int layer(const Identifier &id) const
Definition: HGTD_ID.h:475
HGTD_DetectorManager.h
ActsHGTDLayerBuilder::Config::idHelper
const HGTD_ID * idHelper
Definition: ActsHGTDLayerBuilder.h:49
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
HGTD_DetectorElement.h
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
ActsHGTDLayerBuilder::positiveLayers
virtual const Acts::LayerVector positiveLayers(const Acts::GeometryContext &gctx) const override
Definition: ActsHGTDLayerBuilder.cxx:63
ActsDetectorElement
Definition: ActsDetectorElement.h:42
ActsHGTDLayerBuilder.h
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
ActsDetectorElement::identify
Identifier identify() const override final
Identifier.
Definition: ActsDetectorElement.cxx:271
ActsHGTDLayerBuilder::ActsHGTDLayerBuilder
ActsHGTDLayerBuilder(const Config &cfg, std::unique_ptr< const Acts::Logger > logger)
Constructor.
Definition: ActsHGTDLayerBuilder.cxx:40
ActsHGTDLayerBuilder::Config::endcapEnvelopeR
std::array< double, 2 > endcapEnvelopeR
Definition: ActsHGTDLayerBuilder.h:61
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
HGTD_DetectorElementCollection.h
WriteCaloSwCorrections.cfg
cfg
Definition: WriteCaloSwCorrections.py:23
Trk::open
@ open
Definition: BinningType.h:40
ActsHGTDLayerBuilder::Config::mng
const HGTD_DetectorManager * mng
Definition: ActsHGTDLayerBuilder.h:48
Trk::binR
@ binR
Definition: BinningType.h:50
ActsHGTDLayerBuilder::centralLayers
virtual const Acts::LayerVector centralLayers(const Acts::GeometryContext &gctx) const override
Definition: ActsHGTDLayerBuilder.cxx:56
ActsHGTDLayerBuilder::Config::elementStore
std::shared_ptr< ElementVector > elementStore
Definition: ActsHGTDLayerBuilder.h:59
a
TList * a
Definition: liststreamerinfos.cxx:10
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
HGTD_DetectorManager
Definition: HGTD_DetectorManager.h:33
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
python.iconfTool.gui.pad.logger
logger
Definition: pad.py:14
ActsHGTDLayerBuilder::m_cfg
Config m_cfg
configuration object
Definition: ActsHGTDLayerBuilder.h:99
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
Trk::binPhi
@ binPhi
Definition: BinningType.h:51