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
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
103
104
105
106
107
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
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))
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
190 innerBoundary->assignSurfaceMaterial(materialProxy);
191
192 std::set<int> phiModuleByRing;
193
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;
204 size_t nModR = 1;
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
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}
std::vector< std::shared_ptr< const ActsDetectorElement > > getDetectorElements() const
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)