Warning, file /include/Acts/Geometry/CylinderVolumeBuilder.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Units.hpp"
0012 #include "Acts/Geometry/GeometryContext.hpp"
0013 #include "Acts/Geometry/ITrackingVolumeBuilder.hpp"
0014 #include "Acts/Geometry/ITrackingVolumeHelper.hpp"
0015 #include "Acts/Utilities/BinningType.hpp"
0016 #include "Acts/Utilities/Logger.hpp"
0017
0018 #include <algorithm>
0019 #include <array>
0020 #include <limits>
0021 #include <memory>
0022 #include <ostream>
0023 #include <stdexcept>
0024 #include <string>
0025 #include <utility>
0026 #include <vector>
0027
0028 namespace Acts {
0029
0030 class IVolumeMaterial;
0031 class ISurfaceMaterial;
0032 class ILayerBuilder;
0033 class IConfinedTrackingVolumeBuilder;
0034
0035
0036 enum WrappingCondition {
0037 Undefined = 0,
0038 Attaching = 1,
0039 Inserting = 2,
0040 Wrapping = 3,
0041 CentralInserting = 4,
0042 CentralWrapping = 5,
0043 NoWrapping = 6
0044 };
0045
0046
0047 struct VolumeConfig {
0048 bool present{false};
0049 bool wrapping{false};
0050 double rMin;
0051 double rMax;
0052 double zMin;
0053 double zMax;
0054 LayerVector layers;
0055 MutableTrackingVolumeVector volumes;
0056
0057
0058 VolumeConfig()
0059 : rMin(std::numeric_limits<double>::max()),
0060 rMax(std::numeric_limits<double>::lowest()),
0061 zMin(std::numeric_limits<double>::max()),
0062 zMax(std::numeric_limits<double>::lowest()),
0063 layers() {}
0064
0065
0066
0067
0068
0069 void adaptZ(const VolumeConfig& lConfig) {
0070 if (lConfig) {
0071 zMin = std::min(zMin, lConfig.zMin);
0072 zMax = std::max(zMax, lConfig.zMax);
0073 }
0074 }
0075
0076
0077
0078
0079
0080 void adaptR(const VolumeConfig& lConfig) {
0081 if (lConfig) {
0082 rMin = std::min(rMin, lConfig.rMin);
0083 rMax = std::max(rMax, lConfig.rMax);
0084 }
0085 }
0086
0087
0088
0089
0090
0091 void adapt(const VolumeConfig& lConfig) {
0092 adaptZ(lConfig);
0093 adaptR(lConfig);
0094 }
0095
0096
0097
0098
0099
0100
0101
0102 void midPointAttachZ(VolumeConfig& lConfig) {
0103 if (lConfig.zMin >= zMax) {
0104 double zMid = 0.5 * (lConfig.zMin + zMax);
0105 lConfig.zMin = zMid;
0106 zMax = zMid;
0107 } else {
0108 double zMid = 0.5 * (zMin + lConfig.zMax);
0109 lConfig.zMax = zMid;
0110 zMin = zMid;
0111 }
0112 }
0113
0114
0115
0116
0117
0118 void attachZ(const VolumeConfig& lConfig) {
0119 if (lConfig.zMin >= zMax) {
0120 zMax = lConfig.zMin;
0121 } else {
0122 zMin = lConfig.zMax;
0123 }
0124 }
0125
0126
0127
0128
0129
0130 bool overlapsInR(const VolumeConfig& vConfig) const {
0131 if (!present) {
0132 return false;
0133 }
0134 return std::max(rMin, vConfig.rMin) <= std::min(rMax, vConfig.rMax);
0135 }
0136
0137
0138
0139
0140
0141 bool overlapsInZ(const VolumeConfig& vConfig) const {
0142 if (!present) {
0143 return false;
0144 }
0145 return std::max(zMin, vConfig.zMin) <= std::min(zMax, vConfig.zMax);
0146 }
0147
0148
0149
0150
0151
0152 bool wraps(const VolumeConfig& vConfig) const {
0153 if ((zMax <= vConfig.zMin) || (zMin >= vConfig.zMax)) {
0154 return true;
0155 }
0156 return containsInR(vConfig);
0157 }
0158
0159
0160
0161
0162 bool contains(const VolumeConfig& vConfig) const {
0163 return (containsInR(vConfig) && containsInZ(vConfig));
0164 }
0165
0166
0167
0168
0169 bool containsInR(const VolumeConfig& vConfig) const {
0170 return (rMin >= vConfig.rMax);
0171 }
0172
0173
0174
0175
0176 bool containsInZ(const VolumeConfig& vConfig) const {
0177 return (vConfig.zMin > zMin && vConfig.zMax < zMax);
0178 }
0179
0180
0181 std::string toString() const {
0182
0183 std::stringstream sl;
0184 sl << rMin << ", " << rMax << " / " << zMin << ", " << zMax;
0185 return sl.str();
0186 }
0187
0188
0189 operator bool() const { return present; }
0190 };
0191
0192
0193 struct WrappingConfig {
0194 public:
0195
0196 VolumeConfig nVolumeConfig;
0197 VolumeConfig cVolumeConfig;
0198 VolumeConfig pVolumeConfig;
0199
0200
0201 VolumeConfig containerVolumeConfig;
0202
0203
0204 VolumeConfig existingVolumeConfig;
0205 VolumeConfig fGapVolumeConfig;
0206 VolumeConfig sGapVolumeConfig;
0207
0208
0209
0210 VolumeConfig externalVolumeConfig;
0211
0212
0213 WrappingCondition wCondition = Undefined;
0214 std::string wConditionScreen = "[left untouched]";
0215
0216
0217 WrappingConfig() = default;
0218
0219
0220 void configureContainerVolume() {
0221
0222 containerVolumeConfig.present = true;
0223 std::string wConditionAddon = "";
0224
0225 if ((nVolumeConfig && cVolumeConfig) || (cVolumeConfig && pVolumeConfig) ||
0226 (nVolumeConfig && pVolumeConfig)) {
0227 wCondition = Wrapping;
0228 wConditionScreen = "grouped to ";
0229 }
0230
0231 if (nVolumeConfig) {
0232 containerVolumeConfig.adapt(nVolumeConfig);
0233 wConditionScreen += "[n]";
0234 }
0235 if (cVolumeConfig) {
0236 containerVolumeConfig.adapt(cVolumeConfig);
0237 wConditionScreen += "[c]";
0238 }
0239 if (pVolumeConfig) {
0240 containerVolumeConfig.adapt(pVolumeConfig);
0241 wConditionScreen += "[p]";
0242 }
0243
0244 if (externalVolumeConfig) {
0245 containerVolumeConfig.adapt(externalVolumeConfig);
0246 }
0247
0248 if (nVolumeConfig && cVolumeConfig) {
0249 nVolumeConfig.midPointAttachZ(cVolumeConfig);
0250 }
0251 if (cVolumeConfig && pVolumeConfig) {
0252 cVolumeConfig.midPointAttachZ(pVolumeConfig);
0253 }
0254
0255
0256
0257 if (!existingVolumeConfig || !cVolumeConfig) {
0258 nVolumeConfig.adaptR(containerVolumeConfig);
0259 cVolumeConfig.adaptR(containerVolumeConfig);
0260 pVolumeConfig.adaptR(containerVolumeConfig);
0261 }
0262 }
0263
0264
0265 void wrapInsertAttach() {
0266
0267
0268 if (existingVolumeConfig) {
0269
0270 if (!cVolumeConfig) {
0271
0272 if (nVolumeConfig && nVolumeConfig.zMax < existingVolumeConfig.zMin) {
0273 nVolumeConfig.attachZ(existingVolumeConfig);
0274
0275 wCondition = Attaching;
0276 wConditionScreen = "[n attached]";
0277 }
0278 if (pVolumeConfig && pVolumeConfig.zMin > existingVolumeConfig.zMax) {
0279 pVolumeConfig.attachZ(existingVolumeConfig);
0280
0281 wCondition = Attaching;
0282 wConditionScreen = "[p attached]";
0283 }
0284
0285 if (containerVolumeConfig.rMin > existingVolumeConfig.rMin) {
0286 nVolumeConfig.rMin = existingVolumeConfig.rMin;
0287 pVolumeConfig.rMin = existingVolumeConfig.rMin;
0288 } else {
0289 fGapVolumeConfig.present = true;
0290
0291 fGapVolumeConfig.adaptZ(existingVolumeConfig);
0292 fGapVolumeConfig.rMin = containerVolumeConfig.rMin;
0293 fGapVolumeConfig.rMax = existingVolumeConfig.rMin;
0294 }
0295
0296 if (containerVolumeConfig.rMax < existingVolumeConfig.rMax) {
0297 nVolumeConfig.rMax = existingVolumeConfig.rMax;
0298 pVolumeConfig.rMax = existingVolumeConfig.rMax;
0299 } else {
0300 sGapVolumeConfig.present = true;
0301
0302 sGapVolumeConfig.adaptZ(existingVolumeConfig);
0303 sGapVolumeConfig.rMin = existingVolumeConfig.rMax;
0304 sGapVolumeConfig.rMax = containerVolumeConfig.rMax;
0305 }
0306 } else {
0307
0308 if (existingVolumeConfig.rMax < containerVolumeConfig.rMin) {
0309
0310
0311 nVolumeConfig.rMin = existingVolumeConfig.rMax;
0312 cVolumeConfig.rMin = existingVolumeConfig.rMax;
0313 pVolumeConfig.rMin = existingVolumeConfig.rMax;
0314
0315 nVolumeConfig.rMax = containerVolumeConfig.rMax;
0316 cVolumeConfig.rMax = containerVolumeConfig.rMax;
0317 pVolumeConfig.rMax = containerVolumeConfig.rMax;
0318
0319 wCondition = Wrapping;
0320 wConditionScreen = "[fully wrapped]";
0321 } else if (existingVolumeConfig.rMin > containerVolumeConfig.rMax) {
0322
0323
0324 nVolumeConfig.rMax = existingVolumeConfig.rMin;
0325 cVolumeConfig.rMax = existingVolumeConfig.rMin;
0326 pVolumeConfig.rMax = existingVolumeConfig.rMin;
0327
0328 nVolumeConfig.rMin = containerVolumeConfig.rMin;
0329 cVolumeConfig.rMin = containerVolumeConfig.rMin;
0330 pVolumeConfig.rMin = containerVolumeConfig.rMin;
0331
0332 wCondition = Inserting;
0333 wConditionScreen = "[fully inserted]";
0334 } else if (cVolumeConfig.wraps(existingVolumeConfig)) {
0335
0336
0337 nVolumeConfig.rMax = containerVolumeConfig.rMax;
0338 cVolumeConfig.rMax = containerVolumeConfig.rMax;
0339 pVolumeConfig.rMax = containerVolumeConfig.rMax;
0340
0341 nVolumeConfig.rMin = existingVolumeConfig.rMin;
0342 cVolumeConfig.rMin = existingVolumeConfig.rMax;
0343 pVolumeConfig.rMin = existingVolumeConfig.rMin;
0344
0345 wCondition = CentralWrapping;
0346 wConditionScreen = "[centrally wrapped]";
0347 } else if (existingVolumeConfig.wraps(cVolumeConfig)) {
0348
0349
0350 nVolumeConfig.rMax = containerVolumeConfig.rMax;
0351 cVolumeConfig.rMax = existingVolumeConfig.rMin;
0352 pVolumeConfig.rMax = containerVolumeConfig.rMax;
0353
0354 nVolumeConfig.rMin = containerVolumeConfig.rMin;
0355 cVolumeConfig.rMin = containerVolumeConfig.rMin;
0356 pVolumeConfig.rMin = containerVolumeConfig.rMin;
0357
0358 wCondition = CentralWrapping;
0359 wConditionScreen = "[centrally inserted]";
0360 } else if ((existingVolumeConfig.rMax > containerVolumeConfig.rMin &&
0361 existingVolumeConfig.rMin < containerVolumeConfig.rMin) ||
0362 (existingVolumeConfig.rMax > containerVolumeConfig.rMax &&
0363 existingVolumeConfig.rMin < containerVolumeConfig.rMax)) {
0364
0365
0366 throw std::invalid_argument(
0367 "Volumes are overlapping, this shouldn't be happening. Please "
0368 "check your geometry building.");
0369 }
0370
0371
0372
0373
0374
0375
0376 VolumeConfig referenceVolume =
0377 (wCondition == Wrapping || wCondition == Inserting)
0378 ? containerVolumeConfig
0379 : cVolumeConfig;
0380
0381 if (existingVolumeConfig.zMin > referenceVolume.zMin) {
0382 fGapVolumeConfig.present = true;
0383 fGapVolumeConfig.adaptR(existingVolumeConfig);
0384 fGapVolumeConfig.zMin = referenceVolume.zMin;
0385 fGapVolumeConfig.zMax = existingVolumeConfig.zMin;
0386 } else {
0387
0388 if (nVolumeConfig) {
0389 nVolumeConfig.zMin = existingVolumeConfig.zMin;
0390 } else if (cVolumeConfig) {
0391 cVolumeConfig.zMin = existingVolumeConfig.zMin;
0392 }
0393 }
0394
0395 if (existingVolumeConfig.zMax < referenceVolume.zMax) {
0396 sGapVolumeConfig.present = true;
0397 sGapVolumeConfig.adaptR(existingVolumeConfig);
0398 sGapVolumeConfig.zMin = existingVolumeConfig.zMax;
0399 sGapVolumeConfig.zMax = referenceVolume.zMax;
0400 } else {
0401
0402 if (pVolumeConfig) {
0403 pVolumeConfig.zMax = existingVolumeConfig.zMax;
0404 } else if (cVolumeConfig) {
0405 cVolumeConfig.zMax = existingVolumeConfig.zMax;
0406 }
0407 }
0408 }
0409 }
0410 return;
0411 }
0412
0413
0414 std::string toString() const {
0415
0416 std::stringstream sl;
0417 if (containerVolumeConfig) {
0418 sl << "New container built with configuration: "
0419 << containerVolumeConfig.toString() << '\n';
0420 }
0421
0422 if (nVolumeConfig) {
0423 sl << " - n: Negative Endcap, current configuration: "
0424 << nVolumeConfig.toString() << '\n';
0425 }
0426 if (cVolumeConfig) {
0427 sl << " - c: Barrel, current configuration: "
0428 << cVolumeConfig.toString() << '\n';
0429 }
0430 if (pVolumeConfig) {
0431 sl << " - p: Negative Endcap, current configuration: "
0432 << pVolumeConfig.toString() << '\n';
0433 }
0434 if (existingVolumeConfig) {
0435 sl << "Existing volume with configuration: "
0436 << existingVolumeConfig.toString() << '\n';
0437 if (fGapVolumeConfig) {
0438 sl << " - g1: First gap volume, configuration : "
0439 << fGapVolumeConfig.toString() << '\n';
0440 }
0441 if (sGapVolumeConfig) {
0442 sl << " - g2: Second gap volume, configuration : "
0443 << sGapVolumeConfig.toString() << '\n';
0444 }
0445 if (wCondition != Undefined) {
0446 sl << "WrappingCondition = " << wCondition << '\n';
0447 }
0448 }
0449 return sl.str();
0450 }
0451 };
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469
0470
0471
0472 class CylinderVolumeBuilder : public ITrackingVolumeBuilder {
0473 public:
0474
0475
0476 struct Config {
0477
0478 std::shared_ptr<const ITrackingVolumeHelper> trackingVolumeHelper = nullptr;
0479
0480 std::string volumeName = "";
0481
0482 std::shared_ptr<const IVolumeMaterial> volumeMaterial = nullptr;
0483
0484 bool buildToRadiusZero = false;
0485
0486 bool checkRingLayout = false;
0487
0488 double ringTolerance = 0 * UnitConstants::mm;
0489
0490 std::shared_ptr<const ILayerBuilder> layerBuilder = nullptr;
0491
0492 std::shared_ptr<const IConfinedTrackingVolumeBuilder> ctVolumeBuilder =
0493 nullptr;
0494
0495 std::pair<double, double> layerEnvelopeR = {1. * UnitConstants::mm,
0496 1. * UnitConstants::mm};
0497
0498 double layerEnvelopeZ = 1. * UnitConstants::mm;
0499
0500
0501
0502
0503
0504 std::array<std::shared_ptr<const ISurfaceMaterial>, 6> boundaryMaterial{
0505 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
0506 };
0507
0508
0509
0510
0511
0512 CylinderVolumeBuilder(const Config& cvbConfig,
0513 std::unique_ptr<const Logger> logger = getDefaultLogger(
0514 "CylinderVolumeBuilder", Logging::INFO));
0515
0516
0517 ~CylinderVolumeBuilder() override;
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528 MutableTrackingVolumePtr trackingVolume(
0529 const GeometryContext& gctx, TrackingVolumePtr existingVolume = nullptr,
0530 std::shared_ptr<const VolumeBounds> externalBounds =
0531 nullptr) const override;
0532
0533
0534
0535
0536 void setConfiguration(const Config& cvbConfig);
0537
0538
0539
0540
0541 Config getConfiguration() const;
0542
0543
0544
0545
0546 void setLogger(std::unique_ptr<const Logger> newLogger);
0547
0548
0549
0550
0551
0552
0553
0554
0555 VolumeConfig analyzeContent(
0556 const GeometryContext& gctx, const LayerVector& lVector,
0557 const MutableTrackingVolumeVector& mtvVector) const;
0558
0559 private:
0560
0561 Config m_cfg;
0562
0563
0564
0565
0566 const Logger& logger() const { return *m_logger; }
0567
0568
0569 std::unique_ptr<const Logger> m_logger;
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583 bool checkLayerContainment(const GeometryContext& gctx,
0584 VolumeConfig& layerConfig,
0585 const VolumeConfig& insideConfig,
0586 const VolumeConfig& volumeConfig, int sign) const;
0587 };
0588
0589
0590 inline CylinderVolumeBuilder::Config CylinderVolumeBuilder::getConfiguration()
0591 const {
0592 return m_cfg;
0593 }
0594
0595 }