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