29 std::unique_ptr<Acts::SurfaceArray>
32 std::vector<std::shared_ptr<const Surface>> surfaces,
size_t binsPhi,
33 size_t binsZ, std::optional<ProtoLayer> protoLayerOpt,
38 protoLayerOpt ? *protoLayerOpt :
ProtoLayer(gctx, surfacesRaw);
41 ACTS_VERBOSE(
" -- with " << surfaces.size() <<
" surfaces.")
42 ACTS_VERBOSE(
" -- with phi x z = " << binsPhi <<
" x " << binsZ <<
" = "
43 << binsPhi * binsZ <<
" bins.");
47 protoLayer, ftransform, binsPhi);
55 auto globalToLocal = [ftransform](
const Vector3D&
pos) {
59 auto localToGlobal = [itransform,
R](
const Vector2D& loc) {
64 std::unique_ptr<SurfaceArray::ISurfaceGridLookup> sl =
66 detail::AxisBoundaryType::Bound>(
67 globalToLocal, localToGlobal, pAxisPhi, pAxisZ);
69 sl->fill(gctx, surfacesRaw);
72 return std::make_unique<SurfaceArray>(std::move(sl), std::move(surfaces),
76 std::unique_ptr<Acts::SurfaceArray>
80 BinningType bTypeZ, std::optional<ProtoLayer> protoLayerOpt,
85 protoLayerOpt ? *protoLayerOpt :
ProtoLayer(gctx, surfacesRaw);
95 pAxisPhi = createEquidistantAxis(gctx, surfacesRaw,
binPhi, protoLayer,
99 createVariableAxis(gctx, surfacesRaw,
binPhi, protoLayer, ftransform);
104 createEquidistantAxis(gctx, surfacesRaw,
binZ, protoLayer, ftransform);
107 createVariableAxis(gctx, surfacesRaw,
binZ, protoLayer, ftransform);
111 auto globalToLocal = [ftransform](
const Vector3D&
pos) {
115 auto localToGlobal = [itransform,
R](
const Vector2D& loc) {
120 std::unique_ptr<SurfaceArray::ISurfaceGridLookup> sl =
121 makeSurfaceGridLookup2D<detail::AxisBoundaryType::Closed,
122 detail::AxisBoundaryType::Bound>(
123 globalToLocal, localToGlobal, pAxisPhi, pAxisZ);
125 sl->
fill(gctx, surfacesRaw);
126 completeBinning(gctx, *sl, surfacesRaw);
130 size_t bins0 = axes.at(0)->getNBins();
131 size_t bins1 = axes.at(1)->getNBins();
134 ACTS_VERBOSE(
" -- with " << surfaces.size() <<
" surfaces.")
135 ACTS_VERBOSE(
" -- with phi x z = " << bins0 <<
" x " << bins1 <<
" = "
136 << bins0 * bins1 <<
" bins.");
138 return std::make_unique<SurfaceArray>(std::move(sl), std::move(surfaces),
142 std::unique_ptr<Acts::SurfaceArray>
145 std::vector<std::shared_ptr<const Surface>> surfaces,
size_t binsR,
146 size_t binsPhi, std::optional<ProtoLayer> protoLayerOpt,
151 protoLayerOpt ? *protoLayerOpt :
ProtoLayer(gctx, surfacesRaw);
156 ProtoAxis pAxisR = createEquidistantAxis(gctx, surfacesRaw,
binR, protoLayer,
159 protoLayer, ftransform, binsPhi);
162 ACTS_VERBOSE(
"- z-position of disk estimated as " << Z);
166 auto globalToLocal = [ftransform](
const Vector3D&
pos) {
170 auto localToGlobal = [itransform, Z](
const Vector2D& loc) {
175 std::unique_ptr<SurfaceArray::ISurfaceGridLookup> sl =
176 makeSurfaceGridLookup2D<detail::AxisBoundaryType::Bound,
177 detail::AxisBoundaryType::Closed>(
178 globalToLocal, localToGlobal, pAxisR, pAxisPhi);
182 size_t bins0 = axes.at(0)->getNBins();
183 size_t bins1 = axes.at(1)->getNBins();
185 ACTS_VERBOSE(
" -- with " << surfaces.size() <<
" surfaces.")
186 ACTS_VERBOSE(
" -- with r x phi = " << bins0 <<
" x " << bins1 <<
" = "
187 << bins0 * bins1 <<
" bins.");
188 sl->
fill(gctx, surfacesRaw);
189 completeBinning(gctx, *sl, surfacesRaw);
191 return std::make_unique<SurfaceArray>(std::move(sl), std::move(surfaces),
195 std::unique_ptr<Acts::SurfaceArray>
199 BinningType bTypePhi, std::optional<ProtoLayer> protoLayerOpt,
204 protoLayerOpt ? *protoLayerOpt :
ProtoLayer(gctx, surfacesRaw);
215 createEquidistantAxis(gctx, surfacesRaw,
binR, protoLayer, ftransform);
218 createVariableAxis(gctx, surfacesRaw,
binR, protoLayer, ftransform);
223 if (pAxisR.
nBins > 1) {
226 std::vector<std::vector<const Surface*>> phiModules(pAxisR.
nBins);
227 for (
const auto& srf : surfacesRaw) {
230 phiModules.at(bin).push_back(srf);
233 std::vector<size_t> nPhiModules;
234 auto matcher = m_cfg.surfaceMatcher;
236 return matcher(gctx,
binPhi, a, b);
240 phiModules.begin(), phiModules.end(), std::back_inserter(nPhiModules),
241 [&equal,
this](std::vector<const Surface*> surfaces_) ->
size_t {
242 return this->findKeySurfaces(surfaces_, equal).size();
252 (*std::min_element(nPhiModules.begin(), nPhiModules.end()));
253 pAxisPhi = createEquidistantAxis(gctx, surfacesRaw,
binPhi, protoLayer,
254 ftransform, nBinsPhi);
259 pAxisPhi = createEquidistantAxis(gctx, surfacesRaw,
binPhi, protoLayer,
263 createVariableAxis(gctx, surfacesRaw,
binPhi, protoLayer, ftransform);
268 ACTS_VERBOSE(
"- z-position of disk estimated as " << Z);
272 auto globalToLocal = [ftransform](
const Vector3D&
pos) {
276 auto localToGlobal = [itransform, Z](
const Vector2D& loc) {
281 std::unique_ptr<SurfaceArray::ISurfaceGridLookup> sl =
282 makeSurfaceGridLookup2D<detail::AxisBoundaryType::Bound,
283 detail::AxisBoundaryType::Closed>(
284 globalToLocal, localToGlobal, pAxisR, pAxisPhi);
288 size_t bins0 = axes.at(0)->getNBins();
289 size_t bins1 = axes.at(1)->getNBins();
291 ACTS_VERBOSE(
" -- with " << surfaces.size() <<
" surfaces.")
292 ACTS_VERBOSE(
" -- with r x phi = " << bins0 <<
" x " << bins1 <<
" = "
293 << bins0 * bins1 <<
" bins.");
295 sl->
fill(gctx, surfacesRaw);
296 completeBinning(gctx, *sl, surfacesRaw);
298 return std::make_unique<SurfaceArray>(std::move(sl), std::move(surfaces),
303 std::unique_ptr<Acts::SurfaceArray>
306 std::vector<std::shared_ptr<const Surface>> surfaces,
size_t bins1,
307 size_t bins2,
BinningValue bValue, std::optional<ProtoLayer> protoLayerOpt,
312 protoLayerOpt ? *protoLayerOpt :
ProtoLayer(gctx, surfacesRaw);
315 ACTS_VERBOSE(
" -- with " << surfaces.size() <<
" surfaces.")
316 ACTS_VERBOSE(
" -- with " << bins1 <<
" x " << bins2 <<
" = " << bins1 * bins2
321 auto globalToLocal = [ftransform](
const Vector3D&
pos) {
325 auto localToGlobal = [itransform](
const Vector2D& loc) {
326 return itransform *
Vector3D(loc.x(), loc.y(), 0.);
329 std::unique_ptr<SurfaceArray::ISurfaceGridLookup> sl;
334 ProtoAxis pAxis1 = createEquidistantAxis(gctx, surfacesRaw,
binY,
335 protoLayer, ftransform, bins1);
336 ProtoAxis pAxis2 = createEquidistantAxis(gctx, surfacesRaw,
binZ,
337 protoLayer, ftransform, bins2);
338 sl = makeSurfaceGridLookup2D<detail::AxisBoundaryType::Bound,
339 detail::AxisBoundaryType::Bound>(
340 globalToLocal, localToGlobal, pAxis1, pAxis2);
344 ProtoAxis pAxis1 = createEquidistantAxis(gctx, surfacesRaw,
binX,
345 protoLayer, ftransform, bins1);
346 ProtoAxis pAxis2 = createEquidistantAxis(gctx, surfacesRaw,
binZ,
347 protoLayer, ftransform, bins2);
348 sl = makeSurfaceGridLookup2D<detail::AxisBoundaryType::Bound,
349 detail::AxisBoundaryType::Bound>(
350 globalToLocal, localToGlobal, pAxis1, pAxis2);
354 ProtoAxis pAxis1 = createEquidistantAxis(gctx, surfacesRaw,
binX,
355 protoLayer, ftransform, bins1);
356 ProtoAxis pAxis2 = createEquidistantAxis(gctx, surfacesRaw,
binY,
357 protoLayer, ftransform, bins2);
358 sl = makeSurfaceGridLookup2D<detail::AxisBoundaryType::Bound,
359 detail::AxisBoundaryType::Bound>(
360 globalToLocal, localToGlobal, pAxis1, pAxis2);
364 throw std::invalid_argument(
365 "Acts::SurfaceArrayCreator::"
366 "surfaceArrayOnPlane: Invalid binning "
371 sl->
fill(gctx, surfacesRaw);
372 completeBinning(gctx, *sl, surfacesRaw);
374 return std::make_unique<SurfaceArray>(std::move(sl), std::move(surfaces),
380 const std::vector<const Surface*>& surfaces,
381 const std::function<
bool(
const Surface*,
const Surface*)>& equal)
const {
382 std::vector<const Surface*> keys;
383 for (
const auto& srfA : surfaces) {
385 for (
const auto& srfB : keys) {
386 if (equal(srfA, srfB)) {
392 keys.push_back(srfA);
402 auto matcher = m_cfg.surfaceMatcher;
404 return matcher(gctx, bValue, a, b);
406 std::vector<const Surface*> keys = findKeySurfaces(surfaces, equal);
415 if (surfaces.empty()) {
416 throw std::logic_error(
417 "No surfaces handed over for creating arbitrary bin utility!");
423 auto matcher = m_cfg.surfaceMatcher;
426 return matcher(gctx, bValue, a, b);
428 std::vector<const Acts::Surface*> keys = findKeySurfaces(surfaces, equal);
430 std::vector<double> bValues;
432 std::stable_sort(keys.begin(), keys.end(),
438 double maxPhi = 0.5 * (
phi(keys.at(0)->binningPosition(gctx,
binPhi)) +
439 phi(keys.at(1)->binningPosition(gctx,
binPhi)));
448 double previous =
phi(keys.at(0)->binningPosition(gctx,
binPhi));
450 for (
size_t i = 1; i < keys.size(); i++) {
458 bValues.push_back(edge);
463 unsigned int segments = 72;
469 if (backBounds ==
nullptr)
471 "Given SurfaceBounds are not planar - not implemented for "
472 "other bounds yet! ");
474 std::vector<Acts::Vector3D> backVertices =
475 makeGlobalVertices(gctx, *backSurface, backBounds->
vertices(segments));
476 double maxBValue =
phi(
477 *std::max_element(backVertices.begin(), backVertices.end(),
482 bValues.push_back(maxBValue);
484 bValues.push_back(
M_PI);
487 std::stable_sort(keys.begin(), keys.end(),
490 b->binningPosition(gctx,
binZ).z());
493 bValues.push_back(protoLayer.
min(
binZ));
494 bValues.push_back(protoLayer.
max(
binZ));
497 double previous = keys.front()->binningPosition(gctx,
binZ).z();
504 0.5 * (previous + (*surface)->binningPosition(gctx,
binZ).z()));
505 previous = (*surface)->binningPosition(gctx,
binZ).z();
508 std::stable_sort(keys.begin(), keys.end(),
511 perp(b->binningPosition(gctx,
binR)));
514 bValues.push_back(protoLayer.
min(
binR));
515 bValues.push_back(protoLayer.
max(
binR));
518 double previous =
perp(keys.front()->binningPosition(gctx,
binR));
526 0.5 * (previous +
perp((*surface)->binningPosition(gctx,
binR))));
527 previous =
perp((*surface)->binningPosition(gctx,
binR));
530 std::sort(bValues.begin(), bValues.end());
531 ACTS_VERBOSE(
"Create variable binning Axis for binned SurfaceArray");
534 " (binX = 0, binY = 1, binZ = 2, binR = 3, binPhi = 4, "
535 "binRPhi = 5, binH = 6, binEta = 7)");
536 ACTS_VERBOSE(
" Number of bins: " << (bValues.size() - 1));
538 << bValues.back() <<
")");
542 pAxis.bValue = bValue;
543 pAxis.binEdges = bValues;
544 pAxis.nBins = bValues.size() - 1;
553 size_t nBins)
const {
554 if (surfaces.empty()) {
555 throw std::logic_error(
556 "No surfaces handed over for creating equidistant axis!");
568 std::vector<const Acts::Surface*> keys;
573 binNumber = determineBinCount(gctx, surfaces, bValue);
580 auto matcher = m_cfg.surfaceMatcher;
584 if (m_cfg.doPhiBinningOptimization) {
589 surfaces.begin(), surfaces.end(),
592 phi(b->binningPosition(gctx,
binR));
596 auto equal = [&
gctx, &bValue, &matcher](
const Surface* a,
598 return matcher(gctx, bValue, a, b);
600 keys = findKeySurfaces(surfaces, equal);
603 if (keys.size() > 1) {
615 double angle =
M_PI - (max + 0.5 *
step);
630 maximum = protoLayer.
max(bValue,
false);
631 minimum = protoLayer.
min(bValue,
false);
635 ACTS_VERBOSE(
"Create equidistant binning Axis for binned SurfaceArray");
638 " (binX = 0, binY = 1, binZ = 2, binR = 3, binPhi = 4, "
639 "binRPhi = 5, binH = 6, binEta = 7)");
641 ACTS_VERBOSE(
" (Min/Max) = (" << minimum <<
"/" << maximum <<
")");
648 pAxis.
nBins = binNumber;
655 const std::vector<Acts::Vector2D>& locVertices)
const {
656 std::vector<Acts::Vector3D> globVertices;
657 for (
auto& vertex : locVertices) {
660 globVertices.push_back(globVertex);