File indexing completed on 2026-03-28 07:45:39
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Material/BinnedSurfaceMaterialAccumulator.hpp"
0010
0011 #include "Acts/Geometry/GeometryContext.hpp"
0012 #include "Acts/Material/BinnedSurfaceMaterial.hpp"
0013 #include "Acts/Material/ProtoSurfaceMaterial.hpp"
0014 #include "Acts/Surfaces/Surface.hpp"
0015 #include "Acts/Utilities/BinAdjustment.hpp"
0016 #include "Acts/Utilities/BinUtility.hpp"
0017
0018 Acts::BinnedSurfaceMaterialAccumulator::BinnedSurfaceMaterialAccumulator(
0019 const Config& cfg, std::unique_ptr<const Logger> mlogger)
0020 : m_cfg(cfg), m_logger(std::move(mlogger)) {}
0021
0022 std::unique_ptr<Acts::ISurfaceMaterialAccumulator::State>
0023 Acts::BinnedSurfaceMaterialAccumulator::createState(
0024 const GeometryContext& gctx) const {
0025 auto state = std::make_unique<State>();
0026
0027
0028 for (const auto& surface : m_cfg.materialSurfaces) {
0029 GeometryIdentifier geoID = surface->geometryId();
0030
0031
0032 const ISurfaceMaterial* surfaceMaterial = surface->surfaceMaterial();
0033 if (surfaceMaterial == nullptr) {
0034 throw std::invalid_argument(
0035 "Surface material is not set, inconsistent configuration.");
0036 }
0037
0038
0039 auto psm = dynamic_cast<const ProtoSurfaceMaterial*>(surfaceMaterial);
0040 if (psm != nullptr) {
0041 auto binUtility = psm->binning();
0042
0043 ACTS_DEBUG(" - (proto) binning from ProtoSurfaceMateria is "
0044 << binUtility);
0045
0046 binUtility = adjustBinUtility(binUtility, *surface, gctx);
0047
0048 ACTS_DEBUG(" - adjusted binning is " << binUtility);
0049 state->accumulatedMaterial[geoID] =
0050 AccumulatedSurfaceMaterial(binUtility);
0051
0052 continue;
0053 }
0054
0055 auto psgm = dynamic_cast<const ProtoGridSurfaceMaterial*>(surfaceMaterial);
0056 if (psgm != nullptr) {
0057 BinUtility binUtility(psgm->binning());
0058
0059 ACTS_DEBUG(" - (proto) binning from ProtoGridSurfaceMaterial is "
0060 << binUtility);
0061
0062 binUtility = adjustBinUtility(binUtility, *surface, gctx);
0063
0064 ACTS_DEBUG(" - adjusted binning is " << binUtility);
0065 state->accumulatedMaterial[geoID] =
0066 AccumulatedSurfaceMaterial(binUtility);
0067
0068 continue;
0069 }
0070
0071 auto bmp = dynamic_cast<const BinnedSurfaceMaterial*>(surfaceMaterial);
0072 if (bmp != nullptr) {
0073
0074 ACTS_DEBUG(" - binning from BinnedSurfaceMaterial is "
0075 << bmp->binUtility());
0076 state->accumulatedMaterial[geoID] =
0077 AccumulatedSurfaceMaterial(bmp->binUtility());
0078
0079 continue;
0080 }
0081
0082 ACTS_DEBUG(" - this is homogeneous material.");
0083 state->accumulatedMaterial[geoID] = AccumulatedSurfaceMaterial();
0084 }
0085 return state;
0086 }
0087
0088 void Acts::BinnedSurfaceMaterialAccumulator::accumulate(
0089 ISurfaceMaterialAccumulator::State& state, const GeometryContext& ,
0090 const std::vector<MaterialInteraction>& interactions,
0091 const std::vector<IAssignmentFinder::SurfaceAssignment>&
0092 surfacesWithoutAssignment) const {
0093
0094 State* cState = static_cast<State*>(&state);
0095 if (cState == nullptr) {
0096 throw std::invalid_argument(
0097 "Invalid state object provided, something is seriously wrong.");
0098 }
0099
0100 using MapBin =
0101 std::pair<AccumulatedSurfaceMaterial*, std::array<std::size_t, 3>>;
0102 std::map<AccumulatedSurfaceMaterial*, std::array<std::size_t, 3>>
0103 touchedMapBins;
0104
0105
0106 for (const auto& mi : interactions) {
0107
0108 const Surface* surface = mi.surface;
0109 GeometryIdentifier geoID = surface->geometryId();
0110
0111 auto accMaterial = cState->accumulatedMaterial.find(geoID);
0112 if (accMaterial == cState->accumulatedMaterial.end()) {
0113 throw std::invalid_argument(
0114 "Surface material is not found, inconsistent configuration.");
0115 }
0116
0117 auto tBin = accMaterial->second.accumulate(mi.intersection, mi.materialSlab,
0118 mi.pathCorrection);
0119 touchedMapBins.insert(MapBin(&(accMaterial->second), tBin));
0120 }
0121
0122
0123 for (const auto& [key, value] : touchedMapBins) {
0124 std::vector<std::array<std::size_t, 3>> trackBins = {value};
0125 key->trackAverage(trackBins, true);
0126 }
0127
0128
0129 if (m_cfg.emptyBinCorrection) {
0130 for (const auto& [surface, position, direction] :
0131 surfacesWithoutAssignment) {
0132
0133 auto missedMaterial =
0134 cState->accumulatedMaterial.find(surface->geometryId());
0135 if (missedMaterial == cState->accumulatedMaterial.end()) {
0136 throw std::invalid_argument(
0137 "Surface material is not found, inconsistent configuration.");
0138 }
0139
0140 missedMaterial->second.trackAverage(position, true);
0141 }
0142 }
0143 }
0144
0145 std::map<Acts::GeometryIdentifier,
0146 std::shared_ptr<const Acts::ISurfaceMaterial>>
0147 Acts::BinnedSurfaceMaterialAccumulator::finalizeMaterial(
0148 ISurfaceMaterialAccumulator::State& state,
0149 const GeometryContext& ) const {
0150 std::map<GeometryIdentifier, std::shared_ptr<const ISurfaceMaterial>>
0151 sMaterials;
0152
0153
0154 State* cState = static_cast<State*>(&state);
0155 if (cState == nullptr) {
0156 throw std::invalid_argument(
0157 "Invalid state object provided, something is seriously wrong.");
0158 }
0159
0160
0161 for (auto& accMaterial : cState->accumulatedMaterial) {
0162 ACTS_DEBUG("Finalizing map for Surface " << accMaterial.first);
0163 auto sMaterial = accMaterial.second.totalAverage();
0164 sMaterials[accMaterial.first] = std::move(sMaterial);
0165 }
0166
0167 return sMaterials;
0168 }