ATLAS Offline Software
Loading...
Searching...
No Matches
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 <Acts/Utilities/AxisDefinitions.hpp>
32#include <iterator>
33#include <unordered_map>
34
35using Acts::Surface;
36using Acts::Transform3;
37using Acts::Translation3;
38
39using namespace Acts::UnitLiterals;
40
42 std::unique_ptr<const Acts::Logger> logger)
43 : m_cfg (cfg),
44 m_logger(std::move(logger))
45{
46}
47
48const Acts::LayerVector
49ActsHGTDLayerBuilder::negativeLayers(const Acts::GeometryContext &gctx) const {
50 ACTS_VERBOSE("Building negative layers");
51 Acts::LayerVector nVector;
52 buildEndcap(gctx, nVector, -1);
53 return nVector;
54}
55
56const Acts::LayerVector
57ActsHGTDLayerBuilder::centralLayers(const Acts::GeometryContext & /*gctx*/) const {
58 ACTS_VERBOSE("HGTD has no central layers");
59 Acts::LayerVector layers;
60 return layers;
61}
62
63const Acts::LayerVector
64ActsHGTDLayerBuilder::positiveLayers(const Acts::GeometryContext &gctx) const {
65 ACTS_VERBOSE("Building positive layers");
66 Acts::LayerVector pVector;
67 buildEndcap(gctx, pVector, 1);
68 return pVector;
69}
70
71void ActsHGTDLayerBuilder::buildEndcap(const Acts::GeometryContext &gctx,
72 Acts::LayerVector &layersOutput, int type) const
73{
74 using enum Acts::AxisDirection;
75
76 ACTS_VERBOSE("Build layers: " << (type < 0 ? "NEGATIVE" : "POSITIVE")
77 << " ENDCAP");
78
79 std::vector<std::shared_ptr<const ActsDetectorElement>> elements =
81 std::map<int, std::vector<const Acts::Surface *>>
82 initialLayers{};
83
84 for (const auto &element : elements) {
85
86 Identifier currentId(element->identify());
87 // Check if the element is in the correct endcap (type -1 or 1)
88 if (m_cfg.idHelper->endcap(currentId) * type <= 0) {
89 continue;
90 }
91
92 m_cfg.elementStore->push_back(element);
93 int currentLayer {m_cfg.idHelper->layer(currentId)};
94
95 initialLayers[currentLayer].push_back(&element->surface());
96 }
97
98 ACTS_VERBOSE("Found " << initialLayers.size() << " "
99 << (type < 0 ? "NEGATIVE" : "POSITIVE")
100 << " ENDCAP inital layers");
101
102 // Loops over a provided vector of surface and calculates the various
103 // min/max values in one go. Also takes into account the thickness
104 // of an associated DetectorElement, if it exists.
105 //
106 // @param gctx The current geometry context object, e.g. alignment
107 // @param surfaces The vector of surfaces to consider
108
109 std::vector<Acts::ProtoLayer> protoLayers;
110 protoLayers.reserve(initialLayers.size());
111
112 for (const auto &[key, surfaces] : initialLayers) {
113 auto &pl = protoLayers.emplace_back(gctx, surfaces);
114 pl.envelope[AxisR] = m_cfg.endcapEnvelopeR;
115 pl.envelope[AxisZ] = m_cfg.endcapEnvelopeZ;
116 }
117
118
119 // sort proto layers by their medium z position
120 std::sort(protoLayers.begin(), protoLayers.end(),
121 [type](const Acts::ProtoLayer &a, const Acts::ProtoLayer &b) {
122 double midA = (a.min(AxisZ) + a.max(AxisZ)) / 2.0;
123 double midB = (b.min(AxisZ) + b.max(AxisZ)) / 2.0;
124 if (type < 0) {
125 return midA < midB;
126 } else {
127 return midA > midB;
128 }
129 });
130
131 std::vector<std::shared_ptr<const Surface>> ownedSurfaces;
132 for (const auto &pl : protoLayers) {
133
134 std::unique_ptr<Acts::ApproachDescriptor> approachDescriptor = nullptr;
135 std::shared_ptr<const Acts::ProtoSurfaceMaterial> materialProxy = nullptr;
136
137 double layerZ = pl.medium(AxisZ);
138 double layerHalfZ = 0.5 * pl.range(AxisZ);
139
140 double layerZInner = layerZ - layerHalfZ;
141 double layerZOuter = layerZ + layerHalfZ;
142
143 if (std::abs(layerZInner) > std::abs(layerZOuter))
144 std::swap(layerZInner, layerZOuter);
145
146 std::vector<std::shared_ptr<const Acts::Surface>> aSurfaces;
147
148 Acts::Transform3 transformNominal(Translation3(0., 0., layerZ));
149 Acts::Transform3 transformInner(Translation3(0., 0., layerZInner));
150 Acts::Transform3 transformOuter(Translation3(0., 0., layerZOuter));
151
152 std::shared_ptr<Acts::DiscSurface> innerBoundary =
153 Acts::Surface::makeShared<Acts::DiscSurface>(
154 transformInner, pl.min(AxisR), pl.max(AxisR));
155 aSurfaces.push_back(innerBoundary);
156
157 std::shared_ptr<Acts::DiscSurface> nominalSurface =
158 Acts::Surface::makeShared<Acts::DiscSurface>(
159 transformNominal, pl.min(AxisR), pl.max(AxisR));
160 aSurfaces.push_back(nominalSurface);
161
162 std::shared_ptr<Acts::DiscSurface> outerBoundary =
163 Acts::Surface::makeShared<Acts::DiscSurface>(
164 transformOuter, pl.min(AxisR), pl.max(AxisR));
165 aSurfaces.push_back(outerBoundary);
166
167 size_t matBinsPhi = m_cfg.endcapMaterialBins.first;
168 size_t matBinsR = m_cfg.endcapMaterialBins.second;
169
170 Acts::BinUtility materialBinUtil(matBinsPhi, -M_PI, M_PI, Acts::closed,
171 AxisPhi);
172 materialBinUtil +=
173 Acts::BinUtility(matBinsR, pl.min(AxisR), pl.max(AxisR),
174 Acts::open, AxisR, transformNominal);
175
176 materialProxy =
177 std::make_shared<const Acts::ProtoSurfaceMaterial>(materialBinUtil);
178
179 ACTS_VERBOSE("[L] Layer is marked to carry support material on Surface ( "
180 "inner=0 / center=1 / outer=2 ) : "
181 << "inner");
182 ACTS_VERBOSE("with binning: [" << matBinsPhi << ", " << matBinsR << "]");
183
184 ACTS_VERBOSE("Created ApproachSurfaces for disc layer at:");
185 ACTS_VERBOSE(" - inner: Z=" << layerZInner);
186 ACTS_VERBOSE(" - central: Z=" << layerZ);
187 ACTS_VERBOSE(" - outer: Z=" << layerZOuter);
188
189 // set material on inner
190 innerBoundary->assignSurfaceMaterial(materialProxy);
191
192 std::set<int> phiModuleByRing;
193 // want to figure out bins in phi
194 for (const auto &srf : pl.surfaces()) {
195 auto elm = dynamic_cast<const ActsDetectorElement *>(
196 srf->associatedDetectorElement());
197 if (elm) {
198 auto id = elm->identify();
199 phiModuleByRing.insert(m_cfg.idHelper->phi_module(id));
200 }
201 }
202
203 size_t nModPhi = 50; //phiModuleByRing.size();
204 size_t nModR = 1;// pl.surfaces().size()/nModPhi;
205
206 ACTS_VERBOSE("Identifier reports: " << nModPhi << " is lowest for " << nModR
207 << " r-rings");
208
209 size_t nBinsPhi = nModPhi * m_cfg.numberOfBinsFactor;
210 size_t nBinsR = nModR * m_cfg.numberOfBinsFactor;
211
212
213 ACTS_VERBOSE("Creating r x phi binned layer with " << nBinsR << " x "
214 << nBinsPhi << " bins");
215
216
217 approachDescriptor =
218 std::make_unique<Acts::GenericApproachDescriptor>(aSurfaces);
219
220 // get ownership of pl surfaces
221 ownedSurfaces.clear();
222 ownedSurfaces.reserve(pl.surfaces().size());
223 std::transform(pl.surfaces().begin(), pl.surfaces().end(),
224 std::back_inserter(ownedSurfaces),
225 [](const auto &s) { return s->getSharedPtr(); });
226
227 auto layer = m_cfg.layerCreator->discLayer(gctx, ownedSurfaces, nBinsR,
228 nBinsPhi, pl, Transform3::Identity(),
229 std::move(approachDescriptor));
230
231 layersOutput.push_back( std::move(layer) );
232 }
233}
234
235std::vector<std::shared_ptr<const ActsDetectorElement>>
237 ACTS_VERBOSE("Retrieving detector elements from detector manager");
238 if ( not m_cfg.mng ) {
239 ACTS_ERROR("Manager is null");
240 throw std::runtime_error{"Detector manager is null"};
241 }
242 auto hgtdDetMng = static_cast<const HGTD_DetectorManager *>(m_cfg.mng);
243 ACTS_VERBOSE("Detector manager has "
244 << std::distance(hgtdDetMng->getDetectorElementCollection()->begin(),
245 hgtdDetMng->getDetectorElementCollection()->end())
246 << " elements");
247
248 std::vector<std::shared_ptr<const ActsDetectorElement>> elements;
249
250 for (auto iter = hgtdDetMng->getDetectorElementCollection()->begin();
251 iter != hgtdDetMng->getDetectorElementCollection()->end(); ++iter) {
252 const InDetDD::HGTD_DetectorElement *detElement =
253 dynamic_cast<const InDetDD::HGTD_DetectorElement *>(*iter);
254
255 if (not detElement) {
256 ACTS_ERROR("Detector element was nullptr");
257 throw std::runtime_error{"Corrupt detector element collection"};
258 }
259 elements.push_back(
260 std::make_shared<const ActsDetectorElement>(*detElement, (*iter)->identify()));
261 }
262 ACTS_VERBOSE("Retrieved " << elements.size() << " elements");
263
264 return elements;
265}
#define M_PI
static Double_t a
virtual const Acts::LayerVector negativeLayers(const Acts::GeometryContext &gctx) const override
ActsHGTDLayerBuilder(const Config &cfg, std::unique_ptr< const Acts::Logger > logger)
Constructor.
std::unique_ptr< const Acts::Logger > m_logger
logging instance
std::vector< std::shared_ptr< const ActsDetectorElement > > getDetectorElements() const
virtual const Acts::LayerVector centralLayers(const Acts::GeometryContext &gctx) const override
virtual const Acts::LayerVector positiveLayers(const Acts::GeometryContext &gctx) const override
Config m_cfg
configuration object
void buildEndcap(const Acts::GeometryContext &gctx, Acts::LayerVector &layersOutput, int type=0) const
const Acts::Logger & logger() const
Private access to the logger.
The Detector manager has methods to retrieve the Identifier helper and methods to retrieve the detect...
Class to hold geometrical description of an HGTD detector element.
virtual Identifier identify() const override final
identifier of this detector element (inline)
@ layer
Definition HitInfo.h:79
STL namespace.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)
nested configuration struct for steering of the layer builder