File indexing completed on 2025-01-18 09:11:21
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Geometry/CylinderVolumeHelper.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/BoundarySurfaceT.hpp"
0013 #include "Acts/Geometry/CylinderLayer.hpp"
0014 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0015 #include "Acts/Geometry/DiscLayer.hpp"
0016 #include "Acts/Geometry/GlueVolumesDescriptor.hpp"
0017 #include "Acts/Geometry/ILayerArrayCreator.hpp"
0018 #include "Acts/Geometry/ITrackingVolumeArrayCreator.hpp"
0019 #include "Acts/Geometry/Layer.hpp"
0020 #include "Acts/Geometry/TrackingVolume.hpp"
0021 #include "Acts/Geometry/VolumeBounds.hpp"
0022 #include "Acts/Material/ISurfaceMaterial.hpp"
0023 #include "Acts/Surfaces/CylinderBounds.hpp"
0024 #include "Acts/Surfaces/CylinderSurface.hpp"
0025 #include "Acts/Surfaces/DiscSurface.hpp"
0026 #include "Acts/Surfaces/RadialBounds.hpp"
0027 #include "Acts/Surfaces/RegularSurface.hpp"
0028 #include "Acts/Surfaces/Surface.hpp"
0029 #include "Acts/Surfaces/SurfaceArray.hpp"
0030 #include "Acts/Surfaces/SurfaceBounds.hpp"
0031 #include "Acts/Utilities/BinUtility.hpp"
0032 #include "Acts/Utilities/BinnedArray.hpp"
0033
0034 #include <algorithm>
0035 #include <cmath>
0036 #include <cstddef>
0037 #include <iosfwd>
0038 #include <memory>
0039 #include <numbers>
0040 #include <ostream>
0041 #include <utility>
0042
0043 namespace Acts {
0044 class DiscBounds;
0045 }
0046
0047 Acts::CylinderVolumeHelper::CylinderVolumeHelper(
0048 const Acts::CylinderVolumeHelper::Config& cvhConfig,
0049 std::unique_ptr<const Logger> logger)
0050 : Acts::ITrackingVolumeHelper(), m_cfg(), m_logger(std::move(logger)) {
0051 setConfiguration(cvhConfig);
0052 }
0053
0054
0055 void Acts::CylinderVolumeHelper::setConfiguration(
0056 const Acts::CylinderVolumeHelper::Config& cvhConfig) {
0057
0058
0059 m_cfg = cvhConfig;
0060 }
0061
0062 void Acts::CylinderVolumeHelper::setLogger(
0063 std::unique_ptr<const Logger> newLogger) {
0064 m_logger = std::move(newLogger);
0065 }
0066
0067 std::shared_ptr<Acts::TrackingVolume>
0068 Acts::CylinderVolumeHelper::createTrackingVolume(
0069 const GeometryContext& gctx, const LayerVector& layers,
0070 std::shared_ptr<const IVolumeMaterial> volumeMaterial,
0071 std::shared_ptr<VolumeBounds> volumeBounds,
0072 MutableTrackingVolumeVector mtvVector, const Transform3& transform,
0073 const std::string& volumeName, BinningType bType) const {
0074
0075 MutableTrackingVolumePtr tVolume = nullptr;
0076
0077 std::unique_ptr<const LayerArray> layerArray = nullptr;
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 bool idTrf = transform.isApprox(Transform3::Identity());
0088
0089 auto cylinderBounds =
0090 std::dynamic_pointer_cast<CylinderVolumeBounds>(volumeBounds);
0091
0092 if (volumeBounds != nullptr && cylinderBounds == nullptr) {
0093 ACTS_WARNING(
0094 "[!] Problem: given bounds are not cylindrical - return nullptr");
0095 return tVolume;
0096 }
0097
0098 if (!layers.empty()) {
0099
0100 double rMinRaw = 0.;
0101 double rMaxRaw = 0.;
0102 double zMinRaw = 0.;
0103 double zMaxRaw = 0.;
0104
0105 AxisDirection bValue = AxisDirection::AxisR;
0106
0107
0108 if (!estimateAndCheckDimension(gctx, layers, cylinderBounds, transform,
0109 rMinRaw, rMaxRaw, zMinRaw, zMaxRaw, bValue,
0110 bType)) {
0111 ACTS_WARNING(
0112 "[!] Problem with given dimensions - return nullptr and "
0113 "delete provided objects");
0114 return tVolume;
0115 }
0116
0117 volumeBounds = cylinderBounds;
0118
0119 double zMin =
0120 (!idTrf ? transform.translation().z() : 0.) +
0121 (cylinderBounds != nullptr
0122 ? -cylinderBounds->get(CylinderVolumeBounds::eHalfLengthZ)
0123 : 0.);
0124 double zMax = (!idTrf ? transform.translation().z() : 0.) +
0125 (cylinderBounds != nullptr
0126 ? cylinderBounds->get(CylinderVolumeBounds::eHalfLengthZ)
0127 : 0.);
0128
0129 double rMin = cylinderBounds != nullptr
0130 ? cylinderBounds->get(CylinderVolumeBounds::eMinR)
0131 : rMinRaw;
0132 double rMax = cylinderBounds != nullptr
0133 ? cylinderBounds->get(CylinderVolumeBounds::eMaxR)
0134 : rMaxRaw;
0135
0136 ACTS_VERBOSE(
0137 "Filling the layers into an appropriate layer array - with "
0138 "binningValue = "
0139 << bValue);
0140
0141
0142 layerArray = (bValue == AxisDirection::AxisR)
0143 ? m_cfg.layerArrayCreator->layerArray(gctx, layers, rMin,
0144 rMax, bType, bValue)
0145 : m_cfg.layerArrayCreator->layerArray(gctx, layers, zMin,
0146 zMax, bType, bValue);
0147
0148 }
0149
0150 tVolume = std::make_shared<TrackingVolume>(
0151 transform, volumeBounds, volumeMaterial, std::move(layerArray), nullptr,
0152 mtvVector, volumeName);
0153
0154 ACTS_VERBOSE(
0155 "Created cylindrical volume at z-position :" << tVolume->center().z());
0156 ACTS_VERBOSE(" created bounds : " << tVolume->volumeBounds());
0157
0158 return tVolume;
0159 }
0160
0161 std::shared_ptr<Acts::TrackingVolume>
0162 Acts::CylinderVolumeHelper::createTrackingVolume(
0163 const GeometryContext& gctx, const LayerVector& layers,
0164 MutableTrackingVolumeVector mtvVector,
0165 std::shared_ptr<const IVolumeMaterial> volumeMaterial, double rMin,
0166 double rMax, double zMin, double zMax, const std::string& volumeName,
0167 BinningType bType) const {
0168
0169 ACTS_VERBOSE("Create cylindrical TrackingVolume '" << volumeName << "'.");
0170 ACTS_VERBOSE(" -> with given dimensions of (rMin/rMax/zMin/Max) = "
0171 << rMin << " / " << rMax << " / " << zMin << " / " << zMax);
0172
0173
0174 if (zMin > zMax || rMin > rMax) {
0175 ACTS_WARNING("Inconsistent dimensions given :"
0176 << ((zMin > zMax) ? " zMin > zMax (" : " rMin > rMax (")
0177 << ((zMin > zMax) ? zMin : rMin) << " > "
0178 << ((zMin > zMax) ? zMax : rMax) << " ) - return 0");
0179 return nullptr;
0180 }
0181
0182
0183 double halflengthZ = 0.5 * (zMax - zMin);
0184 double zPosition = 0.5 * (zMin + zMax);
0185 zPosition = std::abs(zPosition) < 0.1 ? 0. : zPosition;
0186
0187
0188 auto cBounds =
0189 std::make_shared<CylinderVolumeBounds>(rMin, rMax, halflengthZ);
0190
0191
0192 const Transform3 transform = Transform3(Translation3(0., 0., zPosition));
0193
0194 return createTrackingVolume(gctx, layers, volumeMaterial, cBounds, mtvVector,
0195 transform, volumeName, bType);
0196 }
0197
0198 std::shared_ptr<Acts::TrackingVolume>
0199 Acts::CylinderVolumeHelper::createGapTrackingVolume(
0200 const GeometryContext& gctx, MutableTrackingVolumeVector& mtvVector,
0201 std::shared_ptr<const IVolumeMaterial> volumeMaterial, double rMin,
0202 double rMax, double zMin, double zMax, unsigned int materialLayers,
0203 bool cylinder, const std::string& volumeName) const {
0204
0205 ACTS_VERBOSE("Create cylindrical gap TrackingVolume '"
0206 << volumeName << "' with (rMin/rMax/zMin/Max) = ");
0207 ACTS_VERBOSE("\t" << rMin << " / " << rMax << " / " << zMin << " / " << zMax);
0208
0209
0210 double min = cylinder ? rMin : zMin;
0211 double max = cylinder ? rMax : zMax;
0212
0213
0214 std::vector<double> layerPositions;
0215 if (materialLayers > 1) {
0216 double step = (max - min) / (materialLayers - 1);
0217 for (unsigned int il = 0; il < materialLayers; ++il) {
0218 layerPositions.push_back(min + il * step);
0219 }
0220 } else {
0221 layerPositions.push_back(0.5 * (min + max));
0222 }
0223
0224
0225 return createGapTrackingVolume(gctx, mtvVector, volumeMaterial, rMin, rMax,
0226 zMin, zMax, layerPositions, cylinder,
0227 volumeName, arbitrary);
0228 }
0229
0230 std::shared_ptr<Acts::TrackingVolume>
0231 Acts::CylinderVolumeHelper::createGapTrackingVolume(
0232 const GeometryContext& gctx, MutableTrackingVolumeVector& mtvVector,
0233 std::shared_ptr<const IVolumeMaterial> volumeMaterial, double rMin,
0234 double rMax, double zMin, double zMax,
0235 const std::vector<double>& layerPositions, bool cylinder,
0236 const std::string& volumeName, BinningType bType) const {
0237
0238 ACTS_VERBOSE("Create cylindrical gap TrackingVolume '"
0239 << volumeName << "' with (rMin/rMax/zMin/Max) = ");
0240 ACTS_VERBOSE("\t" << rMin << " / " << rMax << " / " << zMin << " / " << zMax);
0241
0242
0243 LayerVector layers;
0244 layers.reserve(layerPositions.size());
0245
0246 std::vector<double>::const_iterator layerPropIter = layerPositions.begin();
0247 std::vector<double>::const_iterator layerPropEnd = layerPositions.end();
0248 for (; layerPropIter != layerPropEnd; ++layerPropIter) {
0249
0250 if (cylinder) {
0251
0252 double zMinLayer = zMin;
0253 double zMaxLayer = zMax;
0254
0255 layers.push_back(createCylinderLayer(
0256 0.5 * (zMinLayer + zMaxLayer), (*layerPropIter),
0257 std::abs(0.5 * (zMaxLayer - zMinLayer)), m_cfg.passiveLayerThickness,
0258 m_cfg.passiveLayerPhiBins, m_cfg.passiveLayerRzBins));
0259
0260 } else {
0261
0262 double rMinLayer = rMin;
0263 double rMaxLayer = rMax;
0264
0265 layers.push_back(createDiscLayer(
0266 (*layerPropIter), rMinLayer, rMaxLayer, m_cfg.passiveLayerThickness,
0267 m_cfg.passiveLayerPhiBins, m_cfg.passiveLayerRzBins));
0268 }
0269 }
0270
0271 return createTrackingVolume(gctx, layers, mtvVector, volumeMaterial, rMin,
0272 rMax, zMin, zMax, volumeName, bType);
0273 }
0274
0275 std::shared_ptr<Acts::TrackingVolume>
0276 Acts::CylinderVolumeHelper::createContainerTrackingVolume(
0277 const GeometryContext& gctx, const TrackingVolumeVector& volumes) const {
0278
0279 if (volumes.size() <= std::size_t{1}) {
0280 ACTS_WARNING(
0281 "None (only one) TrackingVolume given to create container "
0282 "volume (min required: 2) - returning 0 ");
0283 return nullptr;
0284 }
0285
0286 std::string volumeName = "{ ";
0287 ACTS_VERBOSE("[start] Creating a container volume with " << volumes.size()
0288 << " sub volumes:");
0289
0290
0291 auto firstVolume = volumes.begin();
0292 auto lastVolume = volumes.end();
0293
0294 for (std::size_t ivol = 0; firstVolume != lastVolume; ++firstVolume, ++ivol) {
0295 if (*firstVolume == nullptr) {
0296 ACTS_ERROR("Volume " << ivol << " is nullptr, return nullptr");
0297 return nullptr;
0298 }
0299 ACTS_VERBOSE(" - volume (" << ivol
0300 << ") is : " << (*firstVolume)->volumeName());
0301 ACTS_VERBOSE(" at position : " << (*firstVolume)->center().x() << ", "
0302 << (*firstVolume)->center().y() << ", "
0303 << (*firstVolume)->center().z());
0304
0305 ACTS_VERBOSE(" with bounds : " << (*firstVolume)->volumeBounds());
0306
0307 volumeName += (*firstVolume)->volumeName();
0308 if (ivol + 1 < volumes.size()) {
0309 volumeName += " | ";
0310 }
0311 }
0312
0313 volumeName += " }";
0314
0315 firstVolume = volumes.begin();
0316 --lastVolume;
0317
0318 if (firstVolume == lastVolume) {
0319 ACTS_WARNING(
0320 "Only one TrackingVolume given to create Top level volume "
0321 "(min required: 2) - returning 0 ");
0322 return nullptr;
0323 }
0324
0325 const CylinderVolumeBounds* firstVolumeBounds =
0326 dynamic_cast<const CylinderVolumeBounds*>(
0327 &((*firstVolume)->volumeBounds()));
0328 const CylinderVolumeBounds* lastVolumeBounds =
0329 dynamic_cast<const CylinderVolumeBounds*>(
0330 &((*lastVolume)->volumeBounds()));
0331
0332 if ((firstVolumeBounds == nullptr) || (lastVolumeBounds == nullptr)) {
0333 ACTS_WARNING(
0334 "VolumeBounds given are not of type: CylinderVolumeBounds "
0335 "(required) - returning 0 ");
0336 return nullptr;
0337 }
0338
0339 bool rCase =
0340 std::abs(firstVolumeBounds->get(CylinderVolumeBounds::eMinR) -
0341 lastVolumeBounds->get(CylinderVolumeBounds::eMinR)) > 0.1;
0342
0343
0344 double zMin = 0.;
0345 double zMax = 0.;
0346 double rMin = 0.;
0347 double rGlueMin = 0.;
0348 double rMax = 0.;
0349 double zSep1 = 0.;
0350 double zSep2 = 0.;
0351 if (rCase) {
0352 zMin = (*firstVolume)->center().z() -
0353 firstVolumeBounds->get(CylinderVolumeBounds::eHalfLengthZ);
0354 zMax = (*firstVolume)->center().z() +
0355 firstVolumeBounds->get(CylinderVolumeBounds::eHalfLengthZ);
0356 zSep1 = zMin;
0357 zSep2 = zMax;
0358 rMin = firstVolumeBounds->get(CylinderVolumeBounds::eMinR);
0359 rGlueMin = firstVolumeBounds->get(CylinderVolumeBounds::eMaxR);
0360 rMax = lastVolumeBounds->get(CylinderVolumeBounds::eMaxR);
0361 } else {
0362 zMin = (*firstVolume)->center().z() -
0363 firstVolumeBounds->get(CylinderVolumeBounds::eHalfLengthZ);
0364 zMax = (*lastVolume)->center().z() +
0365 lastVolumeBounds->get(CylinderVolumeBounds::eHalfLengthZ);
0366 zSep1 = (*firstVolume)->center().z() +
0367 firstVolumeBounds->get(CylinderVolumeBounds::eHalfLengthZ);
0368 zSep2 = zSep1;
0369 rMin = firstVolumeBounds->get(CylinderVolumeBounds::eMinR);
0370 rMax = firstVolumeBounds->get(CylinderVolumeBounds::eMaxR);
0371 }
0372
0373 double zPos = 0.5 * (zMin + zMax);
0374
0375 const Transform3 topVolumeTransform = Transform3(Translation3(0., 0., zPos));
0376
0377 auto topVolumeBounds = std::make_shared<CylinderVolumeBounds>(
0378 rMin, rMax, 0.5 * std::abs(zMax - zMin));
0379
0380
0381 ACTS_VERBOSE("Container volume bounds are " << (*topVolumeBounds));
0382
0383
0384 std::shared_ptr<const TrackingVolumeArray> volumeArray =
0385 (rCase) ? m_cfg.trackingVolumeArrayCreator->trackingVolumeArray(
0386 gctx, volumes, AxisDirection::AxisR)
0387 : m_cfg.trackingVolumeArrayCreator->trackingVolumeArray(
0388 gctx, volumes, AxisDirection::AxisZ);
0389 if (volumeArray == nullptr) {
0390 ACTS_WARNING(
0391 "Creation of TrackingVolume array did not succeed - returning 0 ");
0392 return nullptr;
0393 }
0394
0395 std::shared_ptr<TrackingVolume> topVolume = std::make_shared<TrackingVolume>(
0396 topVolumeTransform, topVolumeBounds, nullptr, nullptr, volumeArray,
0397 MutableTrackingVolumeVector{}, volumeName);
0398
0399
0400 if (!interGlueTrackingVolume(gctx, topVolume, rCase, rMin, rGlueMin, rMax,
0401 zSep1, zSep2)) {
0402 ACTS_WARNING(
0403 "Problem with inter-glueing of TrackingVolumes (needed) - "
0404 "returning 0 ");
0405 return nullptr;
0406 }
0407
0408 ACTS_VERBOSE(
0409 "[ end ] return newly created container : " << topVolume->volumeName());
0410
0411 return topVolume;
0412 }
0413
0414
0415
0416 bool Acts::CylinderVolumeHelper::estimateAndCheckDimension(
0417 const GeometryContext& gctx, const LayerVector& layers,
0418 std::shared_ptr<CylinderVolumeBounds>& cylinderVolumeBounds,
0419 const Transform3& transform, double& rMinClean, double& rMaxClean,
0420 double& zMinClean, double& zMaxClean, AxisDirection& bValue,
0421 BinningType ) const {
0422
0423
0424 ACTS_VERBOSE("Parsing the " << layers.size()
0425 << " layers to gather overall dimensions");
0426 if (cylinderVolumeBounds != nullptr) {
0427 ACTS_VERBOSE(
0428 "Cylinder volume bounds are given: (rmin/rmax/dz) = "
0429 << "(" << cylinderVolumeBounds->get(CylinderVolumeBounds::eMinR) << "/"
0430 << cylinderVolumeBounds->get(CylinderVolumeBounds::eMaxR) << "/"
0431 << cylinderVolumeBounds->get(CylinderVolumeBounds::eHalfLengthZ)
0432 << ")");
0433 }
0434
0435
0436 double layerRmin = 10e10;
0437 double layerRmax = 0.;
0438 double layerZmin = 10e10;
0439 double layerZmax = -10e10;
0440 bool radial = false;
0441
0442 rMinClean = 10e10;
0443 rMaxClean = 0.;
0444 zMinClean = 10e10;
0445 zMaxClean = -10e10;
0446
0447
0448 for (auto& layerIter : layers) {
0449
0450 double currentRmin = 0.;
0451 double currentRmax = 0.;
0452 double currentZmin = 0.;
0453 double currentZmax = 0.;
0454
0455 const CylinderBounds* cylBounds = dynamic_cast<const CylinderBounds*>(
0456 &(layerIter->surfaceRepresentation()).bounds());
0457
0458 if (cylBounds != nullptr) {
0459 radial = true;
0460
0461 double currentR = cylBounds->get(CylinderBounds::eR);
0462 double centerZ = (layerIter->surfaceRepresentation()).center(gctx).z();
0463
0464 currentRmin = currentR - (0.5 * (layerIter)->thickness());
0465 currentRmax = currentR + (0.5 * (layerIter)->thickness());
0466 currentZmin = centerZ - cylBounds->get(CylinderBounds::eHalfLengthZ);
0467 currentZmax = centerZ + cylBounds->get(CylinderBounds::eHalfLengthZ);
0468 }
0469
0470 const RadialBounds* discBounds = dynamic_cast<const RadialBounds*>(
0471 &(layerIter->surfaceRepresentation()).bounds());
0472 if (discBounds != nullptr) {
0473
0474 double centerZ = (layerIter->surfaceRepresentation()).center(gctx).z();
0475 currentRmin = discBounds->rMin();
0476 currentRmax = discBounds->rMax();
0477 currentZmin = centerZ - (0.5 * (layerIter)->thickness());
0478 currentZmax = centerZ + (0.5 * (layerIter)->thickness());
0479 }
0480
0481 rMinClean = std::min(rMinClean, currentRmin);
0482 rMaxClean = std::max(rMaxClean, currentRmax);
0483 zMinClean = std::min(zMinClean, currentZmin);
0484 zMaxClean = std::max(zMaxClean, currentZmax);
0485
0486 layerRmin = std::min(layerRmin, currentRmin);
0487 layerRmax = std::max(layerRmax, currentRmax);
0488 layerZmin = std::min(layerZmin, currentZmin);
0489 layerZmax = std::max(layerZmax, currentZmax);
0490 }
0491
0492
0493 bValue = radial ? AxisDirection::AxisR : AxisDirection::AxisZ;
0494
0495 ACTS_VERBOSE(
0496 "Estimate/check CylinderVolumeBounds from/w.r.t. enclosed "
0497 "layers + envelope covers");
0498
0499 double zEstFromLayerEnv = 0.5 * (layerZmax + layerZmin);
0500 double halflengthFromLayer = 0.5 * std::abs(layerZmax - layerZmin);
0501
0502
0503
0504
0505 bool concentric = std::abs(zEstFromLayerEnv) < 0.031622777;
0506
0507 bool idTrf = transform.isApprox(Transform3::Identity());
0508
0509 Transform3 vtransform = Transform3::Identity();
0510
0511 if ((cylinderVolumeBounds == nullptr) && idTrf) {
0512
0513 cylinderVolumeBounds = std::make_shared<CylinderVolumeBounds>(
0514 layerRmin, layerRmax, halflengthFromLayer);
0515
0516 vtransform = concentric ? Transform3(Translation3(0., 0., zEstFromLayerEnv))
0517 : Transform3::Identity();
0518 } else if ((cylinderVolumeBounds != nullptr) && idTrf && !concentric) {
0519 vtransform = Transform3(Translation3(0., 0., zEstFromLayerEnv));
0520 } else if (!idTrf && (cylinderVolumeBounds == nullptr)) {
0521
0522 cylinderVolumeBounds = std::make_shared<CylinderVolumeBounds>(
0523 layerRmin, layerRmax, halflengthFromLayer);
0524 }
0525
0526 ACTS_VERBOSE(" -> dimensions from layers (rMin/rMax/zMin/zMax) = "
0527 << layerRmin << " / " << layerRmax << " / " << layerZmin << " / "
0528 << layerZmax);
0529
0530 double zFromTransform = !idTrf ? transform.translation().z() : 0.;
0531 ACTS_VERBOSE(
0532 " -> while created bounds are (rMin/rMax/zMin/zMax) = "
0533 << cylinderVolumeBounds->get(CylinderVolumeBounds::eMinR) << " / "
0534 << cylinderVolumeBounds->get(CylinderVolumeBounds::eMaxR) << " / "
0535 << zFromTransform -
0536 cylinderVolumeBounds->get(CylinderVolumeBounds::eHalfLengthZ)
0537 << " / "
0538 << zFromTransform +
0539 cylinderVolumeBounds->get(CylinderVolumeBounds::eHalfLengthZ));
0540
0541
0542 if (cylinderVolumeBounds != nullptr) {
0543
0544 if (zFromTransform -
0545 cylinderVolumeBounds->get(CylinderVolumeBounds::eHalfLengthZ) <=
0546 layerZmin &&
0547 zFromTransform +
0548 cylinderVolumeBounds->get(CylinderVolumeBounds::eHalfLengthZ) >=
0549 layerZmax &&
0550 cylinderVolumeBounds->get(CylinderVolumeBounds::eMinR) <= layerRmin &&
0551 cylinderVolumeBounds->get(CylinderVolumeBounds::eMaxR) >= layerRmax) {
0552 return true;
0553 } else {
0554 ACTS_WARNING(
0555 "Provided layers are not contained by volume ! Bailing out. ");
0556 ACTS_WARNING("- zFromTransform: " << zFromTransform);
0557 ACTS_WARNING("- volumeZmin:"
0558 << zFromTransform - cylinderVolumeBounds->get(
0559 CylinderVolumeBounds::eHalfLengthZ)
0560 << ", layerZmin: " << layerZmin);
0561 ACTS_WARNING("- volumeZmax: "
0562 << zFromTransform + cylinderVolumeBounds->get(
0563 CylinderVolumeBounds::eHalfLengthZ)
0564 << ", layerZmax: " << layerZmax);
0565 ACTS_WARNING("- volumeRmin: "
0566 << cylinderVolumeBounds->get(CylinderVolumeBounds::eMinR)
0567 << ", layerRmin: " << layerRmin);
0568 ACTS_WARNING("- volumeRmax: "
0569 << cylinderVolumeBounds->get(CylinderVolumeBounds::eMaxR)
0570 << ", layerRmax: " << layerRmax);
0571 return false;
0572 }
0573 }
0574
0575 ACTS_VERBOSE("Created/Checked " << *cylinderVolumeBounds);
0576 return true;
0577 }
0578
0579 bool Acts::CylinderVolumeHelper::interGlueTrackingVolume(
0580 const GeometryContext& gctx, const std::shared_ptr<TrackingVolume>& tVolume,
0581 bool rBinned, double rMin, double rGlueMin, double rMax, double zMin,
0582 double zMax) const {
0583 ACTS_VERBOSE("Glue contained TrackingVolumes of container '"
0584 << tVolume->volumeName() << "'.");
0585
0586
0587 if (tVolume->confinedVolumes()) {
0588
0589
0590 GlueVolumesDescriptor& glueDescr = tVolume->glueVolumesDescriptor();
0591
0592
0593 auto& volumes = tVolume->confinedVolumes()->arrayObjects();
0594
0595
0596
0597 std::size_t ivol = 0;
0598 for (auto& vol : volumes) {
0599 ACTS_VERBOSE("[" << ivol++ << "] - volume : " << vol->volumeName());
0600 }
0601
0602
0603 auto tVolIter = volumes.begin();
0604 auto tVolFirst = volumes.begin();
0605 auto tVolLast = volumes.end();
0606 --tVolLast;
0607 auto tVolEnd = volumes.end();
0608
0609
0610 TrackingVolumeVector glueVolumesInnerTube;
0611 TrackingVolumeVector glueVolumesOuterTube;
0612 TrackingVolumeVector glueVolumesNegativeFace;
0613 TrackingVolumeVector glueVolumesPositiveFace;
0614
0615 ivol = 0;
0616
0617 if (rBinned) {
0618
0619 for (; tVolIter != tVolEnd;) {
0620
0621 ACTS_VERBOSE("r-binning: Processing volume [" << ivol++ << "]");
0622
0623 std::shared_ptr<TrackingVolume> tVol =
0624 std::const_pointer_cast<TrackingVolume>(*tVolIter);
0625 if (tVolIter == tVolFirst) {
0626 addFaceVolumes(tVol, tubeInnerCover, glueVolumesInnerTube);
0627 }
0628
0629 addFaceVolumes(tVol, negativeFaceXY, glueVolumesNegativeFace);
0630 addFaceVolumes(tVol, positiveFaceXY, glueVolumesPositiveFace);
0631 if (tVolIter == tVolLast) {
0632 addFaceVolumes(tVol, tubeOuterCover, glueVolumesOuterTube);
0633 ++tVolIter;
0634 } else {
0635 std::shared_ptr<TrackingVolume> tVol1 =
0636 std::const_pointer_cast<TrackingVolume>(*tVolIter);
0637 std::shared_ptr<TrackingVolume> tVol2 =
0638 std::const_pointer_cast<TrackingVolume>(*(++tVolIter));
0639
0640
0641 double rGlueR =
0642 0.5 * (tVol1->volumeBounds()
0643 .values()[CylinderVolumeBounds::BoundValues::eMaxR] +
0644 tVol2->volumeBounds()
0645 .values()[CylinderVolumeBounds::BoundValues::eMinR]);
0646
0647 glueTrackingVolumes(gctx, tVol1, tubeOuterCover, tVol2,
0648 tubeInnerCover, rMin, rGlueR, rMax, zMin, zMax);
0649 }
0650 }
0651 } else {
0652
0653
0654 for (; tVolIter != tVolEnd;) {
0655
0656 ACTS_VERBOSE("z-binning: Processing volume '"
0657 << (*tVolIter)->volumeName() << "'.");
0658 std::shared_ptr<TrackingVolume> tVol =
0659 std::const_pointer_cast<TrackingVolume>(*tVolIter);
0660 if (tVolIter == tVolFirst) {
0661 addFaceVolumes(tVol, negativeFaceXY, glueVolumesNegativeFace);
0662 }
0663 addFaceVolumes(tVol, tubeInnerCover, glueVolumesInnerTube);
0664 addFaceVolumes(tVol, tubeOuterCover, glueVolumesOuterTube);
0665 if (tVolIter == tVolLast) {
0666 addFaceVolumes(tVol, positiveFaceXY, glueVolumesPositiveFace);
0667 ++tVolIter;
0668 } else {
0669 std::shared_ptr<TrackingVolume> tVol1 =
0670 std::const_pointer_cast<TrackingVolume>(*tVolIter);
0671 std::shared_ptr<TrackingVolume> tVol2 =
0672 std::const_pointer_cast<TrackingVolume>(*(++tVolIter));
0673 glueTrackingVolumes(gctx, tVol1, positiveFaceXY, tVol2,
0674 negativeFaceXY, rMin, rGlueMin, rMax, zMin, zMax);
0675 }
0676 }
0677 }
0678
0679
0680 if (!glueVolumesNegativeFace.empty()) {
0681
0682 std::shared_ptr<const TrackingVolumeArray> glueVolumesNegativeFaceArray =
0683 m_cfg.trackingVolumeArrayCreator->trackingVolumeArray(
0684 gctx, glueVolumesNegativeFace, AxisDirection::AxisR);
0685
0686 glueDescr.registerGlueVolumes(negativeFaceXY,
0687 glueVolumesNegativeFaceArray);
0688 }
0689 if (!glueVolumesPositiveFace.empty()) {
0690
0691 std::shared_ptr<const TrackingVolumeArray> glueVolumesPositiveFaceArray =
0692 m_cfg.trackingVolumeArrayCreator->trackingVolumeArray(
0693 gctx, glueVolumesPositiveFace, AxisDirection::AxisR);
0694
0695 glueDescr.registerGlueVolumes(positiveFaceXY,
0696 glueVolumesPositiveFaceArray);
0697 }
0698 if (!glueVolumesInnerTube.empty()) {
0699
0700 std::shared_ptr<const TrackingVolumeArray> glueVolumesInnerTubeArray =
0701 m_cfg.trackingVolumeArrayCreator->trackingVolumeArray(
0702 gctx, glueVolumesInnerTube, AxisDirection::AxisZ);
0703
0704 glueDescr.registerGlueVolumes(tubeInnerCover, glueVolumesInnerTubeArray);
0705 }
0706 if (!glueVolumesOuterTube.empty()) {
0707
0708 std::shared_ptr<const TrackingVolumeArray> glueVolumesOuterTubeArray =
0709 m_cfg.trackingVolumeArrayCreator->trackingVolumeArray(
0710 gctx, glueVolumesOuterTube, AxisDirection::AxisZ);
0711
0712 glueDescr.registerGlueVolumes(tubeOuterCover, glueVolumesOuterTubeArray);
0713 }
0714
0715 ACTS_VERBOSE("[GV] Register " << glueVolumesNegativeFace.size()
0716 << " volumes at face negativeFaceXY:");
0717 for (tVolIter = glueVolumesNegativeFace.begin();
0718 tVolIter != glueVolumesNegativeFace.end(); ++tVolIter) {
0719 ACTS_VERBOSE(" -> volume '" << (*tVolIter)->volumeName() << "'");
0720 }
0721 ACTS_VERBOSE("[GV] Register " << glueVolumesPositiveFace.size()
0722 << " volumes at face positiveFaceXY: ");
0723 for (tVolIter = glueVolumesPositiveFace.begin();
0724 tVolIter != glueVolumesPositiveFace.end(); ++tVolIter) {
0725 ACTS_VERBOSE(" -> volume '" << (*tVolIter)->volumeName() << "'");
0726 }
0727 ACTS_VERBOSE("[GV] Register " << glueVolumesInnerTube.size()
0728 << " volumes at face tubeInnerCover: ");
0729 for (tVolIter = glueVolumesInnerTube.begin();
0730 tVolIter != glueVolumesInnerTube.end(); ++tVolIter) {
0731 ACTS_VERBOSE(" -> volume '" << (*tVolIter)->volumeName() << "'");
0732 }
0733 ACTS_VERBOSE("[GV] Register " << glueVolumesOuterTube.size()
0734 << " volumes at face tubeOuterCover:");
0735 for (tVolIter = glueVolumesOuterTube.begin();
0736 tVolIter != glueVolumesOuterTube.end(); ++tVolIter) {
0737 ACTS_VERBOSE(" -> volume '" << (*tVolIter)->volumeName() << "'");
0738 }
0739 }
0740
0741 return true;
0742 }
0743
0744
0745 void Acts::CylinderVolumeHelper::glueTrackingVolumes(
0746 const GeometryContext& gctx, const std::shared_ptr<TrackingVolume>& tvolOne,
0747 BoundarySurfaceFace faceOne, const std::shared_ptr<TrackingVolume>& tvolTwo,
0748 BoundarySurfaceFace faceTwo, double rMin, double rGlueMin, double rMax,
0749 double zMin, double zMax) const {
0750
0751 const GlueVolumesDescriptor& gvDescriptorOne =
0752 tvolOne->glueVolumesDescriptor();
0753 const GlueVolumesDescriptor& gvDescriptorTwo =
0754 tvolTwo->glueVolumesDescriptor();
0755
0756 std::size_t volOneGlueVols =
0757 gvDescriptorOne.glueVolumes(faceOne)
0758 ? gvDescriptorOne.glueVolumes(faceOne)->arrayObjects().size()
0759 : 0;
0760 ACTS_VERBOSE("GlueVolumeDescriptor of volume '"
0761 << tvolOne->volumeName() << "' has " << volOneGlueVols << " @ "
0762 << faceOne);
0763 std::size_t volTwoGlueVols =
0764 gvDescriptorTwo.glueVolumes(faceTwo)
0765 ? gvDescriptorTwo.glueVolumes(faceTwo)->arrayObjects().size()
0766 : 0;
0767 ACTS_VERBOSE("GlueVolumeDescriptor of volume '"
0768 << tvolTwo->volumeName() << "' has " << volTwoGlueVols << " @ "
0769 << faceTwo);
0770
0771
0772 TrackingVolumePtr glueVolOne =
0773 volOneGlueVols != 0u
0774 ? gvDescriptorOne.glueVolumes(faceOne)->arrayObjects()[0]
0775 : tvolOne;
0776 TrackingVolumePtr glueVolTwo =
0777 volTwoGlueVols != 0u
0778 ? gvDescriptorTwo.glueVolumes(faceTwo)->arrayObjects()[0]
0779 : tvolTwo;
0780
0781
0782 auto mutableGlueVolOne = std::const_pointer_cast<TrackingVolume>(glueVolOne);
0783 auto mutableGlueVolTwo = std::const_pointer_cast<TrackingVolume>(glueVolTwo);
0784
0785
0786 if (volOneGlueVols <= 1 && volTwoGlueVols <= 1) {
0787
0788 ACTS_VERBOSE(" glue : one[ " << glueVolOne->volumeName() << " @ "
0789 << faceOne << " ]-to-one[ "
0790 << glueVolTwo->volumeName() << " @ "
0791 << faceTwo << " ]");
0792
0793 mutableGlueVolOne->glueTrackingVolume(gctx, faceOne,
0794 mutableGlueVolTwo.get(), faceTwo);
0795
0796 } else if (volOneGlueVols <= 1) {
0797
0798 ACTS_VERBOSE(" glue : one[ "
0799 << glueVolOne->volumeName() << " @ " << faceOne
0800 << " ]-to-many[ " << tvolTwo->volumeName() << " @ " << faceTwo
0801 << " ]");
0802 auto mutableFaceTwoVolumes = std::const_pointer_cast<TrackingVolumeArray>(
0803 gvDescriptorTwo.glueVolumes(faceTwo));
0804 mutableGlueVolOne->glueTrackingVolumes(gctx, faceOne, mutableFaceTwoVolumes,
0805 faceTwo);
0806 } else if (volTwoGlueVols <= 1) {
0807
0808 ACTS_VERBOSE(" glue : many[ "
0809 << tvolOne->volumeName() << " @ " << faceOne << " ]-to-one[ "
0810 << glueVolTwo->volumeName() << " @ " << faceTwo << " ]");
0811 auto mutableFaceOneVolumes = std::const_pointer_cast<TrackingVolumeArray>(
0812 gvDescriptorOne.glueVolumes(faceOne));
0813 mutableGlueVolTwo->glueTrackingVolumes(gctx, faceTwo, mutableFaceOneVolumes,
0814 faceOne);
0815 } else {
0816
0817 ACTS_VERBOSE(" glue : many[ "
0818 << tvolOne->volumeName() << " @ " << faceOne << " ]-to-many[ "
0819 << tvolTwo->volumeName() << " @ " << faceTwo << " ]");
0820
0821
0822 std::shared_ptr<const BoundarySurfaceT<TrackingVolume>> boundarySurface =
0823 nullptr;
0824
0825
0826 Transform3 transform = Transform3::Identity();
0827 if (std::abs(zMin + zMax) > 0.1) {
0828
0829 transform =
0830 Transform3(Translation3(Vector3(0., 0., 0.5 * (zMin + zMax))));
0831 }
0832
0833 if (faceOne == cylinderCover || faceOne == tubeOuterCover) {
0834
0835 auto cBounds =
0836 std::make_shared<CylinderBounds>(rGlueMin, 0.5 * (zMax - zMin));
0837 std::shared_ptr<const RegularSurface> cSurface =
0838 Surface::makeShared<CylinderSurface>(transform, cBounds);
0839 ACTS_VERBOSE(
0840 " creating a new cylindrical boundary surface "
0841 "with bounds = "
0842 << cSurface->bounds());
0843 ACTS_VERBOSE(" at " << cSurface->center(gctx).transpose());
0844 boundarySurface =
0845 std::make_shared<const BoundarySurfaceT<TrackingVolume>>(
0846 std::move(cSurface), gvDescriptorOne.glueVolumes(faceOne),
0847 gvDescriptorTwo.glueVolumes(faceTwo));
0848 } else {
0849
0850
0851
0852 auto cylVolBounds = dynamic_cast<const Acts::CylinderVolumeBounds*>(
0853 &tvolOne->volumeBounds());
0854 double zPos = tvolOne->center().z();
0855 double zHL = cylVolBounds->get(CylinderVolumeBounds::eHalfLengthZ);
0856 transform = Transform3(Translation3(0, 0, zPos + zHL));
0857
0858
0859
0860
0861
0862 std::shared_ptr<const RegularSurface> dSurface =
0863 Surface::makeShared<DiscSurface>(transform, rMin, rMax);
0864 ACTS_VERBOSE(
0865 " creating a new disc-like boundary surface "
0866 "with bounds = "
0867 << dSurface->bounds());
0868 ACTS_VERBOSE(" at " << dSurface->center(gctx).transpose());
0869 boundarySurface =
0870 std::make_shared<const BoundarySurfaceT<TrackingVolume>>(
0871 std::move(dSurface), gvDescriptorOne.glueVolumes(faceOne),
0872 gvDescriptorTwo.glueVolumes(faceTwo));
0873 }
0874
0875
0876 std::shared_ptr<const ISurfaceMaterial> boundaryMaterial = nullptr;
0877
0878 ACTS_VERBOSE("New Boundary surface setting for containers");
0879 ACTS_VERBOSE(" - at first volume: " << tvolOne->volumeName());
0880
0881
0882 for (auto& oneVolume :
0883 gvDescriptorOne.glueVolumes(faceOne)->arrayObjects()) {
0884 auto mutableOneVolume =
0885 std::const_pointer_cast<TrackingVolume>(oneVolume);
0886
0887 if (boundaryMaterial == nullptr) {
0888 auto oneBSurface = mutableOneVolume->boundarySurfaces()[faceOne];
0889 boundaryMaterial =
0890 oneBSurface->surfaceRepresentation().surfaceMaterialSharedPtr();
0891 }
0892 mutableOneVolume->updateBoundarySurface(faceOne, boundarySurface);
0893 ACTS_VERBOSE(" -> setting boundary surface to volume: "
0894 << mutableOneVolume->volumeName());
0895 }
0896 ACTS_VERBOSE(" - at second volume: " << tvolTwo->volumeName());
0897 for (auto& twoVolume :
0898 gvDescriptorTwo.glueVolumes(faceTwo)->arrayObjects()) {
0899 auto mutableTwoVolume =
0900 std::const_pointer_cast<TrackingVolume>(twoVolume);
0901
0902 if (boundaryMaterial == nullptr) {
0903 auto twoBSurface = mutableTwoVolume->boundarySurfaces()[faceTwo];
0904 boundaryMaterial =
0905 twoBSurface->surfaceRepresentation().surfaceMaterialSharedPtr();
0906 }
0907 mutableTwoVolume->updateBoundarySurface(faceTwo, boundarySurface);
0908 ACTS_VERBOSE(" -> setting boundary surface to volume: "
0909 << mutableTwoVolume->volumeName());
0910 }
0911
0912
0913 if (boundaryMaterial != nullptr) {
0914
0915 ACTS_VERBOSE("- the new boundary surface has boundary material: ");
0916 ACTS_VERBOSE(" " << *boundaryMaterial);
0917 RegularSurface* newSurface = const_cast<RegularSurface*>(
0918 &(boundarySurface->surfaceRepresentation()));
0919 newSurface->assignSurfaceMaterial(boundaryMaterial);
0920 }
0921
0922 }
0923 }
0924
0925
0926 void Acts::CylinderVolumeHelper::addFaceVolumes(
0927 const std::shared_ptr<TrackingVolume>& tvol, BoundarySurfaceFace glueFace,
0928 TrackingVolumeVector& vols) const {
0929 ACTS_VERBOSE("Adding face volumes of face " << glueFace << " for the volume '"
0930 << tvol->volumeName() << "'.");
0931
0932 const GlueVolumesDescriptor& gvDescriptor = tvol->glueVolumesDescriptor();
0933
0934 if (gvDescriptor.glueVolumes(glueFace)) {
0935
0936 auto volIter = gvDescriptor.glueVolumes(glueFace)->arrayObjects().begin();
0937 auto volEnd = gvDescriptor.glueVolumes(glueFace)->arrayObjects().end();
0938 for (; volIter != volEnd; ++volIter) {
0939 ACTS_VERBOSE(" -> adding : " << (*volIter)->volumeName());
0940 vols.push_back(*volIter);
0941 }
0942
0943 ACTS_VERBOSE(vols.size()
0944 << " navigation volumes registered as glue volumes.");
0945 } else {
0946
0947 ACTS_VERBOSE(" -> adding only volume itself (at navigation level).");
0948 vols.push_back(tvol);
0949 }
0950 }
0951
0952 std::shared_ptr<const Acts::Layer>
0953 Acts::CylinderVolumeHelper::createCylinderLayer(double z, double r,
0954 double halflengthZ,
0955 double thickness, int binsPhi,
0956 int binsZ) const {
0957 ACTS_VERBOSE("Creating a CylinderLayer at position " << z << " and radius "
0958 << r);
0959
0960 const Transform3 transform(Translation3(0., 0., z));
0961
0962
0963 BinUtility layerBinUtility(binsZ, z - halflengthZ, z + halflengthZ, open,
0964 AxisDirection::AxisZ);
0965 if (binsPhi == 1) {
0966
0967
0968 ACTS_VERBOSE(" -> Preparing the binned material with " << binsZ
0969 << " bins in Z. ");
0970
0971 } else {
0972
0973 BinUtility layerBinUtilityPhiZ(binsPhi, -r * std::numbers::pi,
0974 r * std::numbers::pi, closed,
0975 AxisDirection::AxisPhi);
0976 layerBinUtilityPhiZ += layerBinUtility;
0977
0978 ACTS_VERBOSE(" -> Preparing the binned material with "
0979 << binsPhi << " / " << binsZ << " bins in phi / Z. ");
0980 }
0981
0982
0983 CylinderBounds* cylinderBounds = new CylinderBounds(r, halflengthZ);
0984
0985 return CylinderLayer::create(
0986 transform, std::shared_ptr<const CylinderBounds>(cylinderBounds), nullptr,
0987 thickness);
0988 }
0989
0990 std::shared_ptr<const Acts::Layer> Acts::CylinderVolumeHelper::createDiscLayer(
0991 double z, double rMin, double rMax, double thickness, int binsPhi,
0992 int binsR) const {
0993 ACTS_VERBOSE("Creating a DiscLayer at position " << z << " and rMin/rMax "
0994 << rMin << " / " << rMax);
0995
0996
0997 const Transform3 transform(Translation3(0., 0., z));
0998
0999
1000 BinUtility materialBinUtility(binsR, rMin, rMax, open, AxisDirection::AxisR);
1001 if (binsPhi == 1) {
1002 ACTS_VERBOSE(" -> Preparing the binned material with " << binsR
1003 << " bins in R. ");
1004 } else {
1005
1006 materialBinUtility +=
1007 BinUtility(binsPhi, -std::numbers::pi_v<float>,
1008 std::numbers::pi_v<float>, closed, AxisDirection::AxisPhi);
1009 ACTS_VERBOSE(" -> Preparing the binned material with "
1010 << binsPhi << " / " << binsR << " bins in phi / R. ");
1011 }
1012
1013
1014
1015 RadialBounds* discBounds = new RadialBounds(rMin, rMax);
1016
1017 return DiscLayer::create(transform,
1018 std::shared_ptr<const DiscBounds>(discBounds),
1019 nullptr, thickness);
1020 }