Warning, file /acts/Plugins/GeoModel/src/GeoModelDetectorObjectFactory.cpp 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 #include "Acts/Plugins/GeoModel/GeoModelDetectorObjectFactory.hpp"
0010
0011 #include "Acts/Detector/GeometryIdGenerator.hpp"
0012 #include "Acts/Detector/PortalGenerators.hpp"
0013 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0014 #include "Acts/Geometry/CutoutCylinderVolumeBounds.hpp"
0015 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0016 #include "Acts/Geometry/GeometryIdentifier.hpp"
0017 #include "Acts/Geometry/TrapezoidVolumeBounds.hpp"
0018 #include "Acts/Navigation/InternalNavigation.hpp"
0019 #include "Acts/Plugins/GeoModel/GeoModelConverters.hpp"
0020 #include "Acts/Plugins/GeoModel/IGeoShapeConverter.hpp"
0021
0022 #include <algorithm>
0023 #include <iostream>
0024 #include <typeinfo>
0025
0026 #include <GeoModelHelpers/GeoShapeUtils.h>
0027 #include <GeoModelKernel/GeoBox.h>
0028 #include <GeoModelKernel/GeoPcon.h>
0029 #include <GeoModelKernel/GeoShapeShift.h>
0030 #include <GeoModelKernel/GeoShapeSubtraction.h>
0031 #include <GeoModelKernel/GeoShapeUnion.h>
0032 #include <GeoModelKernel/GeoSimplePolygonBrep.h>
0033 #include <GeoModelKernel/GeoTrd.h>
0034 #include <GeoModelKernel/GeoTube.h>
0035 #include <GeoModelKernel/GeoTubs.h>
0036
0037 namespace Acts {
0038
0039 GeoModelDetectorObjectFactory::GeoModelDetectorObjectFactory(
0040 const Config &cfg, std::unique_ptr<const Logger> mlogger)
0041 : m_logger(std::move(mlogger)), m_cfg(cfg) {}
0042
0043 void GeoModelDetectorObjectFactory::construct(Cache &cache,
0044 const GeometryContext &gctx,
0045 const GeoModelTree &geoModelTree,
0046 const Options &options) {
0047 for (const std::string &q : options.queries) {
0048 ACTS_VERBOSE("Constructing detector elements for query " << q);
0049
0050 auto qFPV = geoModelTree.publisher->getPublishedVol(q);
0051
0052
0053 for (const auto &[name, physVol] : qFPV) {
0054 ACTS_DEBUG("Convert volume " << name);
0055 convertFpv(name, physVol, cache, gctx);
0056 }
0057 }
0058 }
0059
0060 void GeoModelDetectorObjectFactory::convertSensitive(
0061 const PVConstLink &geoPV, const Transform3 &transform,
0062 SurfaceBoundFactory &boundFactory,
0063 std::vector<GeoModelSensitiveSurface> &sensitives) {
0064 const GeoLogVol *logVol = geoPV->getLogVol();
0065 const GeoShape *shape = logVol->getShape();
0066 int shapeId = shape->typeID();
0067 const std::string &name = logVol->getName();
0068 std::shared_ptr<const IGeoShapeConverter> converter =
0069 geoShapesConverters(shapeId);
0070 if (converter == nullptr) {
0071 throw std::runtime_error("The converter for " + printGeoShape(shape) +
0072 " is a nullptr");
0073 }
0074
0075 auto converted =
0076 converter->toSensitiveSurface(geoPV, transform, boundFactory);
0077 if (converted.ok()) {
0078 const auto &[el, sf] = converted.value();
0079
0080 if (!el || !sf) {
0081 throw std::runtime_error(
0082 "The Detector Element or the Surface is a nullptr");
0083 }
0084 sensitives.push_back(converted.value());
0085 ACTS_VERBOSE("(successfully converted: "
0086 << name << " / " << printGeoShape(shape) << " / "
0087 << logVol->getMaterial()->getName() << ")");
0088 return;
0089 }
0090 ACTS_ERROR(name << " / " << printGeoShape(shape)
0091 << " could not be converted by any converter");
0092 }
0093
0094 std::vector<GeoChildNodeWithTrf>
0095 GeoModelDetectorObjectFactory::findAllSubVolumes(const PVConstLink &vol) const {
0096
0097 std::vector<GeoChildNodeWithTrf> subvolumes = getChildrenWithRef(vol, false);
0098 std::vector<GeoChildNodeWithTrf> sensitives;
0099 sensitives.reserve(subvolumes.size());
0100 for (auto &subvolume : subvolumes) {
0101
0102 if (matches(subvolume.nodeName, subvolume.volume)) {
0103 sensitives.push_back(subvolume);
0104 }
0105
0106 if (subvolume.volume->getNChildVols() == 0) {
0107 continue;
0108 }
0109
0110
0111 std::vector<GeoChildNodeWithTrf> senssubsubvolumes =
0112 findAllSubVolumes(subvolume.volume);
0113
0114
0115
0116
0117 std::transform(std::make_move_iterator(senssubsubvolumes.begin()),
0118 std::make_move_iterator(senssubsubvolumes.end()),
0119 std::back_inserter(sensitives),
0120 [&subvolume](GeoChildNodeWithTrf &&volume) {
0121 volume.transform = subvolume.transform * volume.transform;
0122 return volume;
0123 });
0124 }
0125 return sensitives;
0126 }
0127
0128 bool GeoModelDetectorObjectFactory::convertBox(const std::string &name) const {
0129 auto convB = std::ranges::any_of(m_cfg.convertBox, [&](const auto &n) {
0130 return name.find(n) != std::string::npos;
0131 });
0132 return convB;
0133 }
0134
0135 void GeoModelDetectorObjectFactory::convertFpv(const std::string &name,
0136 const FpvConstLink &fpv,
0137 Cache &cache,
0138 const GeometryContext &gctx) {
0139 const std::size_t prevSize = cache.sensitiveSurfaces.size();
0140 {
0141
0142 std::vector<GeoChildNodeWithTrf> subVolToTrf = findAllSubVolumes(fpv);
0143
0144 std::vector<GeoModelSensitiveSurface> sensitives;
0145 sensitives.reserve(subVolToTrf.size());
0146
0147 for (const auto &convertMe : subVolToTrf) {
0148
0149 const Transform3 transform =
0150 fpv->getAbsoluteTransform() * convertMe.transform;
0151 convertSensitive(convertMe.volume, transform, *cache.surfBoundFactory,
0152 sensitives);
0153 }
0154
0155 if (sensitives.empty() && matches(name, fpv)) {
0156 convertSensitive(fpv, fpv->getAbsoluteTransform(),
0157 *cache.surfBoundFactory, cache.sensitiveSurfaces);
0158 }
0159 cache.sensitiveSurfaces.insert(cache.sensitiveSurfaces.end(),
0160 std::make_move_iterator(sensitives.begin()),
0161 std::make_move_iterator(sensitives.end()));
0162
0163 for (auto i = prevSize; i < cache.sensitiveSurfaces.size(); ++i) {
0164 const auto &detEl = std::get<0>(cache.sensitiveSurfaces[i]);
0165 detEl->setDatabaseEntryName(name);
0166 ACTS_VERBOSE("Set database name of the DetectorElement to "
0167 << detEl->databaseEntryName());
0168 }
0169 }
0170
0171 if (convertBox(name)) {
0172 ConvertedGeoVol &convEnvelope = cache.volumeBoxFPVs.emplace_back();
0173 convEnvelope.name = name;
0174 convEnvelope.fullPhysVol = fpv;
0175 convEnvelope.volume = GeoModel::convertVolume(fpv->getAbsoluteTransform(),
0176 fpv->getLogVol()->getShape(),
0177 *cache.volumeBoundFactory);
0178 std::transform(cache.sensitiveSurfaces.begin() + prevSize,
0179 cache.sensitiveSurfaces.end(),
0180 std::back_inserter(convEnvelope.surfaces),
0181 [](const GeoModelSensitiveSurface &sensitive) {
0182 return std::get<1>(sensitive);
0183 });
0184
0185 convEnvelope.gen2Volume = GeoModel::convertDetectorVolume(
0186 gctx, *convEnvelope.volume, name, convEnvelope.surfaces);
0187 }
0188 }
0189
0190 bool GeoModelDetectorObjectFactory::matches(const std::string &name,
0191 const PVConstLink &physvol) const {
0192 if (m_cfg.nameList.empty() && m_cfg.materialList.empty()) {
0193 return true;
0194 }
0195
0196 auto matchName = std::ranges::any_of(m_cfg.nameList, [&](const auto &n) {
0197 return name.find(n) != std::string::npos;
0198 });
0199
0200 std::string matStr = physvol->getLogVol()->getMaterial()->getName();
0201
0202 auto matchMaterial = std::ranges::any_of(
0203 m_cfg.materialList,
0204 [&](const auto &m) { return matStr.find(m) != std::string::npos; });
0205
0206 bool match = matchMaterial && matchName;
0207
0208
0209 if (m_cfg.nameList.empty()) {
0210 return matchMaterial;
0211 }
0212
0213
0214 if (m_cfg.materialList.empty() ||
0215 dynamic_pointer_cast<const GeoVFullPhysVol>(physvol)) {
0216 return matchName;
0217 }
0218 return match;
0219 }
0220 }