File indexing completed on 2025-09-16 08:13:21
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/SurfaceArrayCreator.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Surfaces/PlanarBounds.hpp"
0013 #include "Acts/Surfaces/Surface.hpp"
0014 #include "Acts/Surfaces/SurfaceArray.hpp"
0015 #include "Acts/Utilities/BinningType.hpp"
0016 #include "Acts/Utilities/Helpers.hpp"
0017 #include "Acts/Utilities/IAxis.hpp"
0018
0019 #include <algorithm>
0020 #include <numbers>
0021 #include <stdexcept>
0022
0023 namespace Acts {
0024
0025 using VectorHelpers::perp;
0026 using VectorHelpers::phi;
0027
0028 std::unique_ptr<SurfaceArray> SurfaceArrayCreator::surfaceArrayOnCylinder(
0029 const GeometryContext& gctx,
0030 std::vector<std::shared_ptr<const Surface>> surfaces, std::size_t binsPhi,
0031 std::size_t binsZ, std::optional<ProtoLayer> protoLayerOpt,
0032 const Transform3& transform) const {
0033 std::vector<const Surface*> surfacesRaw = unpackSmartPointers(surfaces);
0034
0035 ProtoLayer protoLayer =
0036 protoLayerOpt ? *protoLayerOpt : ProtoLayer(gctx, surfacesRaw);
0037
0038 ACTS_VERBOSE("Creating a SurfaceArray on a cylinder");
0039 ACTS_VERBOSE(" -- with " << surfaces.size() << " surfaces.");
0040 ACTS_VERBOSE(" -- with phi x z = " << binsPhi << " x " << binsZ << " = "
0041 << binsPhi * binsZ << " bins.");
0042
0043 Transform3 ftransform = transform;
0044 ProtoAxis pAxisPhi =
0045 createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisPhi,
0046 protoLayer, ftransform, binsPhi);
0047 ProtoAxis pAxisZ = createEquidistantAxis(
0048 gctx, surfacesRaw, AxisDirection::AxisZ, protoLayer, ftransform, binsZ);
0049
0050 double R = protoLayer.medium(AxisDirection::AxisR, true);
0051
0052 std::unique_ptr<SurfaceArray::ISurfaceGridLookup> sl =
0053 makeSurfaceGridLookup2D<AxisBoundaryType::Closed,
0054 AxisBoundaryType::Bound>(
0055 Surface::SurfaceType::Cylinder, ftransform, R, 0, pAxisPhi, pAxisZ);
0056
0057 sl->fill(gctx, surfacesRaw);
0058 completeBinning(gctx, *sl, surfacesRaw);
0059
0060 return std::make_unique<SurfaceArray>(std::move(sl), std::move(surfaces),
0061 ftransform);
0062 }
0063
0064 std::unique_ptr<SurfaceArray> SurfaceArrayCreator::surfaceArrayOnCylinder(
0065 const GeometryContext& gctx,
0066 std::vector<std::shared_ptr<const Surface>> surfaces, BinningType bTypePhi,
0067 BinningType bTypeZ, std::optional<ProtoLayer> protoLayerOpt,
0068 const Transform3& transform) const {
0069 std::vector<const Surface*> surfacesRaw = unpackSmartPointers(surfaces);
0070
0071 ProtoLayer protoLayer =
0072 protoLayerOpt ? *protoLayerOpt : ProtoLayer(gctx, surfacesRaw);
0073
0074 double R = protoLayer.medium(AxisDirection::AxisR, true);
0075
0076 ProtoAxis pAxisPhi;
0077 ProtoAxis pAxisZ;
0078
0079 Transform3 ftransform = transform;
0080
0081 if (bTypePhi == equidistant) {
0082 pAxisPhi = createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisPhi,
0083 protoLayer, ftransform, 0);
0084 } else {
0085 pAxisPhi = createVariableAxis(gctx, surfacesRaw, AxisDirection::AxisPhi,
0086 protoLayer, ftransform);
0087 }
0088
0089 if (bTypeZ == equidistant) {
0090 pAxisZ = createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisZ,
0091 protoLayer, ftransform);
0092 } else {
0093 pAxisZ = createVariableAxis(gctx, surfacesRaw, AxisDirection::AxisZ,
0094 protoLayer, ftransform);
0095 }
0096
0097 std::unique_ptr<SurfaceArray::ISurfaceGridLookup> sl =
0098 makeSurfaceGridLookup2D<AxisBoundaryType::Closed,
0099 AxisBoundaryType::Bound>(
0100 Surface::SurfaceType::Cylinder, ftransform, R, 0, pAxisPhi, pAxisZ);
0101
0102 sl->fill(gctx, surfacesRaw);
0103 completeBinning(gctx, *sl, surfacesRaw);
0104
0105
0106 auto axes = sl->getAxes();
0107 std::size_t bins0 = axes.at(0)->getNBins();
0108 std::size_t bins1 = axes.at(1)->getNBins();
0109
0110 ACTS_VERBOSE("Creating a SurfaceArray on a cylinder");
0111 ACTS_VERBOSE(" -- with " << surfaces.size() << " surfaces.");
0112 ACTS_VERBOSE(" -- with phi x z = " << bins0 << " x " << bins1 << " = "
0113 << bins0 * bins1 << " bins.");
0114
0115 return std::make_unique<SurfaceArray>(std::move(sl), std::move(surfaces),
0116 ftransform);
0117 }
0118
0119 std::unique_ptr<SurfaceArray> SurfaceArrayCreator::surfaceArrayOnDisc(
0120 const GeometryContext& gctx,
0121 std::vector<std::shared_ptr<const Surface>> surfaces, std::size_t binsR,
0122 std::size_t binsPhi, std::optional<ProtoLayer> protoLayerOpt,
0123 const Transform3& transform) const {
0124 std::vector<const Surface*> surfacesRaw = unpackSmartPointers(surfaces);
0125
0126 ProtoLayer protoLayer =
0127 protoLayerOpt ? *protoLayerOpt : ProtoLayer(gctx, surfacesRaw);
0128
0129 ACTS_VERBOSE("Creating a SurfaceArray on a disc");
0130
0131 Transform3 ftransform = transform;
0132 ProtoAxis pAxisR = createEquidistantAxis(
0133 gctx, surfacesRaw, AxisDirection::AxisR, protoLayer, ftransform, binsR);
0134 ProtoAxis pAxisPhi =
0135 createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisPhi,
0136 protoLayer, ftransform, binsPhi);
0137
0138 double Z = protoLayer.medium(AxisDirection::AxisZ, true);
0139 ACTS_VERBOSE("- z-position of disc estimated as " << Z);
0140
0141 std::unique_ptr<SurfaceArray::ISurfaceGridLookup> sl =
0142 makeSurfaceGridLookup2D<AxisBoundaryType::Bound,
0143 AxisBoundaryType::Closed>(
0144 Surface::SurfaceType::Disc, ftransform, 0, Z, pAxisR, pAxisPhi);
0145
0146
0147 auto axes = sl->getAxes();
0148 std::size_t bins0 = axes.at(0)->getNBins();
0149 std::size_t bins1 = axes.at(1)->getNBins();
0150
0151 ACTS_VERBOSE(" -- with " << surfaces.size() << " surfaces.");
0152 ACTS_VERBOSE(" -- with r x phi = " << bins0 << " x " << bins1 << " = "
0153 << bins0 * bins1 << " bins.");
0154 sl->fill(gctx, surfacesRaw);
0155 completeBinning(gctx, *sl, surfacesRaw);
0156
0157 return std::make_unique<SurfaceArray>(std::move(sl), std::move(surfaces),
0158 ftransform);
0159 }
0160
0161 std::unique_ptr<SurfaceArray> SurfaceArrayCreator::surfaceArrayOnDisc(
0162 const GeometryContext& gctx,
0163 std::vector<std::shared_ptr<const Surface>> surfaces, BinningType bTypeR,
0164 BinningType bTypePhi, std::optional<ProtoLayer> protoLayerOpt,
0165 const Transform3& transform) const {
0166 std::vector<const Surface*> surfacesRaw = unpackSmartPointers(surfaces);
0167
0168 ProtoLayer protoLayer =
0169 protoLayerOpt ? *protoLayerOpt : ProtoLayer(gctx, surfacesRaw);
0170
0171 ACTS_VERBOSE("Creating a SurfaceArray on a disc");
0172
0173 ProtoAxis pAxisPhi;
0174 ProtoAxis pAxisR;
0175
0176 Transform3 ftransform = transform;
0177 Transform3 itransform = ftransform.inverse();
0178
0179 if (bTypeR == equidistant) {
0180 pAxisR = createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisR,
0181 protoLayer, ftransform);
0182 } else {
0183 pAxisR = createVariableAxis(gctx, surfacesRaw, AxisDirection::AxisR,
0184 protoLayer, ftransform);
0185 }
0186
0187
0188
0189 if (pAxisR.nBins > 1) {
0190
0191
0192 std::vector<std::vector<const Surface*>> phiModules(pAxisR.nBins);
0193 for (const auto& srf : surfacesRaw) {
0194 Vector3 bpos =
0195 itransform * srf->referencePosition(gctx, AxisDirection::AxisR);
0196 std::size_t bin = pAxisR.getBin(perp(bpos));
0197 phiModules.at(bin).push_back(srf);
0198 }
0199
0200 std::vector<std::size_t> nPhiModules;
0201 auto matcher = m_cfg.surfaceMatcher;
0202 auto equal = [&gctx, &matcher](const Surface* a, const Surface* b) {
0203 return matcher(gctx, AxisDirection::AxisPhi, a, b);
0204 };
0205
0206 std::transform(
0207 phiModules.begin(), phiModules.end(), std::back_inserter(nPhiModules),
0208 [&equal,
0209 this](const std::vector<const Surface*>& surfaces_) -> std::size_t {
0210 return this->findKeySurfaces(surfaces_, equal).size();
0211 });
0212
0213
0214
0215
0216
0217
0218
0219 std::size_t nBinsPhi =
0220 (*std::min_element(nPhiModules.begin(), nPhiModules.end()));
0221 pAxisPhi = createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisPhi,
0222 protoLayer, ftransform, nBinsPhi);
0223
0224 } else {
0225
0226 if (bTypePhi == equidistant) {
0227 pAxisPhi = createEquidistantAxis(
0228 gctx, surfacesRaw, AxisDirection::AxisPhi, protoLayer, ftransform, 0);
0229 } else {
0230 pAxisPhi = createVariableAxis(gctx, surfacesRaw, AxisDirection::AxisPhi,
0231 protoLayer, ftransform);
0232 }
0233 }
0234
0235 double Z = protoLayer.medium(AxisDirection::AxisZ, true);
0236 ACTS_VERBOSE("- z-position of disc estimated as " << Z);
0237
0238 std::unique_ptr<SurfaceArray::ISurfaceGridLookup> sl =
0239 makeSurfaceGridLookup2D<AxisBoundaryType::Bound,
0240 AxisBoundaryType::Closed>(
0241 Surface::SurfaceType::Disc, ftransform, 0, Z, pAxisR, pAxisPhi);
0242
0243
0244 auto axes = sl->getAxes();
0245 std::size_t bins0 = axes.at(0)->getNBins();
0246 std::size_t bins1 = axes.at(1)->getNBins();
0247
0248 ACTS_VERBOSE(" -- with " << surfaces.size() << " surfaces.");
0249 ACTS_VERBOSE(" -- with r x phi = " << bins0 << " x " << bins1 << " = "
0250 << bins0 * bins1 << " bins.");
0251
0252 sl->fill(gctx, surfacesRaw);
0253 completeBinning(gctx, *sl, surfacesRaw);
0254
0255 return std::make_unique<SurfaceArray>(std::move(sl), std::move(surfaces),
0256 ftransform);
0257 }
0258
0259
0260 std::unique_ptr<SurfaceArray> SurfaceArrayCreator::surfaceArrayOnPlane(
0261 const GeometryContext& gctx,
0262 std::vector<std::shared_ptr<const Surface>> surfaces, std::size_t bins1,
0263 std::size_t bins2, AxisDirection aDir,
0264 std::optional<ProtoLayer> protoLayerOpt,
0265 const Transform3& transform) const {
0266 std::vector<const Surface*> surfacesRaw = unpackSmartPointers(surfaces);
0267
0268 ProtoLayer protoLayer =
0269 protoLayerOpt ? *protoLayerOpt : ProtoLayer(gctx, surfacesRaw);
0270
0271 ACTS_VERBOSE("Creating a SurfaceArray on a plance");
0272 ACTS_VERBOSE(" -- with " << surfaces.size() << " surfaces.");
0273 ACTS_VERBOSE(" -- with " << bins1 << " x " << bins2 << " = " << bins1 * bins2
0274 << " bins.");
0275 Transform3 ftransform = transform;
0276
0277 std::unique_ptr<SurfaceArray::ISurfaceGridLookup> sl;
0278
0279
0280 switch (aDir) {
0281 case AxisDirection::AxisX: {
0282 ProtoAxis pAxis1 =
0283 createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisY,
0284 protoLayer, ftransform, bins1);
0285 ProtoAxis pAxis2 =
0286 createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisZ,
0287 protoLayer, ftransform, bins2);
0288 sl = makeSurfaceGridLookup2D<AxisBoundaryType::Bound,
0289 AxisBoundaryType::Bound>(
0290 Surface::SurfaceType::Plane, ftransform, 0, 0, pAxis1, pAxis2);
0291 break;
0292 }
0293 case AxisDirection::AxisY: {
0294 ProtoAxis pAxis1 =
0295 createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisX,
0296 protoLayer, ftransform, bins1);
0297 ProtoAxis pAxis2 =
0298 createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisZ,
0299 protoLayer, ftransform, bins2);
0300 sl = makeSurfaceGridLookup2D<AxisBoundaryType::Bound,
0301 AxisBoundaryType::Bound>(
0302 Surface::SurfaceType::Plane, ftransform, 0, 0, pAxis1, pAxis2);
0303 break;
0304 }
0305 case AxisDirection::AxisZ: {
0306 ProtoAxis pAxis1 =
0307 createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisX,
0308 protoLayer, ftransform, bins1);
0309 ProtoAxis pAxis2 =
0310 createEquidistantAxis(gctx, surfacesRaw, AxisDirection::AxisY,
0311 protoLayer, ftransform, bins2);
0312 sl = makeSurfaceGridLookup2D<AxisBoundaryType::Bound,
0313 AxisBoundaryType::Bound>(
0314 Surface::SurfaceType::Plane, ftransform, 0, 0, pAxis1, pAxis2);
0315 break;
0316 }
0317 default: {
0318 throw std::invalid_argument(
0319 "SurfaceArrayCreator::"
0320 "surfaceArrayOnPlane: Invalid binning "
0321 "direction");
0322 }
0323 }
0324
0325 sl->fill(gctx, surfacesRaw);
0326 completeBinning(gctx, *sl, surfacesRaw);
0327
0328 return std::make_unique<SurfaceArray>(std::move(sl), std::move(surfaces),
0329 ftransform);
0330
0331 }
0332
0333 std::vector<const Surface*> SurfaceArrayCreator::findKeySurfaces(
0334 const std::vector<const Surface*>& surfaces,
0335 const std::function<bool(const Surface*, const Surface*)>& equal) const {
0336 std::vector<const Surface*> keys;
0337 for (const auto& srfA : surfaces) {
0338 bool exists = false;
0339 for (const auto& srfB : keys) {
0340 if (equal(srfA, srfB)) {
0341 exists = true;
0342 break;
0343 }
0344 }
0345 if (!exists) {
0346 keys.push_back(srfA);
0347 }
0348 }
0349
0350 return keys;
0351 }
0352
0353 std::size_t SurfaceArrayCreator::determineBinCount(
0354 const GeometryContext& gctx, const std::vector<const Surface*>& surfaces,
0355 AxisDirection aDir) const {
0356 auto matcher = m_cfg.surfaceMatcher;
0357 auto equal = [&gctx, &aDir, &matcher](const Surface* a, const Surface* b) {
0358 return matcher(gctx, aDir, a, b);
0359 };
0360 std::vector<const Surface*> keys = findKeySurfaces(surfaces, equal);
0361
0362 return keys.size();
0363 }
0364
0365 SurfaceArrayCreator::ProtoAxis SurfaceArrayCreator::createVariableAxis(
0366 const GeometryContext& gctx, const std::vector<const Surface*>& surfaces,
0367 AxisDirection aDir, const ProtoLayer& protoLayer,
0368 Transform3& transform) const {
0369 if (surfaces.empty()) {
0370 throw std::logic_error(
0371 "No surfaces handed over for creating arbitrary bin utility!");
0372 }
0373
0374
0375
0376
0377 auto matcher = m_cfg.surfaceMatcher;
0378
0379 auto equal = [&gctx, &aDir, &matcher](const Surface* a, const Surface* b) {
0380 return matcher(gctx, aDir, a, b);
0381 };
0382 std::vector<const Surface*> keys = findKeySurfaces(surfaces, equal);
0383
0384 std::vector<AxisScalar> aDirs;
0385 if (aDir == AxisDirection::AxisPhi) {
0386 std::stable_sort(
0387 keys.begin(), keys.end(), [&gctx](const Surface* a, const Surface* b) {
0388 return (phi(a->referencePosition(gctx, AxisDirection::AxisPhi)) <
0389 phi(b->referencePosition(gctx, AxisDirection::AxisPhi)));
0390 });
0391
0392 AxisScalar maxPhi =
0393 0.5 *
0394 (phi(keys.at(0)->referencePosition(gctx, AxisDirection::AxisPhi)) +
0395 phi(keys.at(1)->referencePosition(gctx, AxisDirection::AxisPhi)));
0396
0397
0398 AxisScalar angle = -(std::numbers::pi + maxPhi);
0399 transform = (transform)*AngleAxis3(angle, Vector3::UnitZ());
0400
0401
0402
0403
0404 AxisScalar previous =
0405 phi(keys.at(0)->referencePosition(gctx, AxisDirection::AxisPhi));
0406
0407 for (std::size_t i = 1; i < keys.size(); i++) {
0408 const Surface* surface = keys.at(i);
0409
0410
0411
0412 AxisScalar edge = 0.5 * (previous + phi(surface->referencePosition(
0413 gctx, AxisDirection::AxisPhi))) +
0414 angle;
0415 aDirs.push_back(edge);
0416 previous = phi(surface->referencePosition(gctx, AxisDirection::AxisPhi));
0417 }
0418
0419
0420 unsigned int segments = 72;
0421
0422
0423 const Surface* backSurface = keys.back();
0424 const PlanarBounds* backBounds =
0425 dynamic_cast<const PlanarBounds*>(&(backSurface->bounds()));
0426 if (backBounds == nullptr) {
0427 ACTS_ERROR(
0428 "Given SurfaceBounds are not planar - not implemented for "
0429 "other bounds yet! ");
0430 }
0431
0432 std::vector<Vector3> backVertices =
0433 makeGlobalVertices(gctx, *backSurface, backBounds->vertices(segments));
0434 AxisScalar maxBValue = phi(*std::max_element(
0435 backVertices.begin(), backVertices.end(),
0436 [](const Vector3& a, const Vector3& b) { return phi(a) < phi(b); }));
0437
0438 aDirs.push_back(maxBValue);
0439
0440 aDirs.push_back(std::numbers::pi_v<AxisScalar>);
0441
0442 } else if (aDir == AxisDirection::AxisZ) {
0443 std::stable_sort(
0444 keys.begin(), keys.end(), [&gctx](const Surface* a, const Surface* b) {
0445 return (a->referencePosition(gctx, AxisDirection::AxisZ).z() <
0446 b->referencePosition(gctx, AxisDirection::AxisZ).z());
0447 });
0448
0449 aDirs.push_back(protoLayer.min(AxisDirection::AxisZ));
0450 aDirs.push_back(protoLayer.max(AxisDirection::AxisZ));
0451
0452
0453 AxisScalar previous =
0454 keys.front()->referencePosition(gctx, AxisDirection::AxisZ).z();
0455
0456 for (auto surface = keys.begin() + 1; surface != keys.end(); surface++) {
0457
0458
0459
0460 aDirs.push_back(
0461 0.5 *
0462 (previous +
0463 (*surface)->referencePosition(gctx, AxisDirection::AxisZ).z()));
0464 previous = (*surface)->referencePosition(gctx, AxisDirection::AxisZ).z();
0465 }
0466 } else {
0467 std::stable_sort(
0468 keys.begin(), keys.end(), [&gctx](const Surface* a, const Surface* b) {
0469 return (perp(a->referencePosition(gctx, AxisDirection::AxisR)) <
0470 perp(b->referencePosition(gctx, AxisDirection::AxisR)));
0471 });
0472
0473 aDirs.push_back(protoLayer.min(AxisDirection::AxisR));
0474 aDirs.push_back(protoLayer.max(AxisDirection::AxisR));
0475
0476
0477 AxisScalar previous =
0478 perp(keys.front()->referencePosition(gctx, AxisDirection::AxisR));
0479
0480
0481 for (auto surface = keys.begin() + 1; surface != keys.end(); surface++) {
0482
0483
0484
0485 aDirs.push_back(0.5 * (previous + perp((*surface)->referencePosition(
0486 gctx, AxisDirection::AxisR))));
0487 previous =
0488 perp((*surface)->referencePosition(gctx, AxisDirection::AxisR));
0489 }
0490 }
0491 std::ranges::sort(aDirs);
0492 ACTS_VERBOSE("Create variable binning Axis for binned SurfaceArray");
0493 ACTS_VERBOSE(" AxisDirection: " << aDir);
0494 ACTS_VERBOSE(" Number of bins: " << (aDirs.size() - 1));
0495 ACTS_VERBOSE(" (Min/Max) = (" << aDirs.front() << "/" << aDirs.back()
0496 << ")");
0497
0498 ProtoAxis pAxis;
0499 pAxis.bType = arbitrary;
0500 pAxis.axisDir = aDir;
0501 pAxis.binEdges = aDirs;
0502 pAxis.nBins = aDirs.size() - 1;
0503
0504 return pAxis;
0505 }
0506
0507 SurfaceArrayCreator::ProtoAxis SurfaceArrayCreator::createEquidistantAxis(
0508 const GeometryContext& gctx, const std::vector<const Surface*>& surfaces,
0509 AxisDirection aDir, const ProtoLayer& protoLayer, Transform3& transform,
0510 std::size_t nBins) const {
0511 if (surfaces.empty()) {
0512 throw std::logic_error(
0513 "No surfaces handed over for creating equidistant axis!");
0514 }
0515
0516
0517 double minimum = protoLayer.min(aDir, false);
0518 double maximum = protoLayer.max(aDir, false);
0519
0520 std::size_t binNumber = 0;
0521 if (nBins == 0) {
0522
0523 binNumber = determineBinCount(gctx, surfaces, aDir);
0524 } else {
0525
0526 binNumber = nBins;
0527 }
0528
0529
0530 auto matcher = m_cfg.surfaceMatcher;
0531
0532
0533 if (aDir == AxisDirection::AxisPhi) {
0534 minimum = protoLayer.min(AxisDirection::AxisPhi, true);
0535 maximum = protoLayer.max(AxisDirection::AxisPhi, true);
0536
0537 if (m_cfg.doPhiBinningOptimization) {
0538 minimum = -std::numbers::pi;
0539 maximum = std::numbers::pi;
0540
0541
0542
0543
0544 const Surface* maxElem = *std::max_element(
0545 surfaces.begin(), surfaces.end(),
0546 [&gctx](const Surface* a, const Surface* b) {
0547 return phi(a->referencePosition(gctx, AxisDirection::AxisR)) <
0548 phi(b->referencePosition(gctx, AxisDirection::AxisR));
0549 });
0550
0551
0552
0553
0554 double surfaceMax =
0555 phi(maxElem->referencePosition(gctx, AxisDirection::AxisR));
0556 double gridStep = 2 * std::numbers::pi / binNumber;
0557 double gridMax = std::numbers::pi - 0.5 * gridStep;
0558 double angle = gridMax - surfaceMax;
0559
0560
0561 transform = transform * AngleAxis3(angle, Vector3::UnitZ());
0562 }
0563 }
0564
0565
0566 ACTS_VERBOSE("Create equidistant binning Axis for binned SurfaceArray");
0567 ACTS_VERBOSE(" AxisDirection: " << aDir);
0568 ACTS_VERBOSE(" Number of bins: " << binNumber);
0569 ACTS_VERBOSE(" (Min/Max) = (" << minimum << "/" << maximum << ")");
0570
0571 ProtoAxis pAxis;
0572 pAxis.max = maximum;
0573 pAxis.min = minimum;
0574 pAxis.bType = equidistant;
0575 pAxis.axisDir = aDir;
0576 pAxis.nBins = binNumber;
0577
0578 return pAxis;
0579 }
0580
0581 std::vector<Vector3> SurfaceArrayCreator::makeGlobalVertices(
0582 const GeometryContext& gctx, const Surface& surface,
0583 const std::vector<Vector2>& locVertices) const {
0584 std::vector<Vector3> globVertices;
0585 for (auto& vertex : locVertices) {
0586 Vector3 globVertex = surface.localToGlobal(gctx, vertex, Vector3());
0587 globVertices.push_back(globVertex);
0588 }
0589 return globVertices;
0590 }
0591
0592 }