Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-03-28 07:45:39

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
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   /// Create the surface accumulation
0028   for (const auto& surface : m_cfg.materialSurfaces) {
0029     GeometryIdentifier geoID = surface->geometryId();
0030 
0031     // Get the Surface Material
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     // First attempt from ProtoSurfaceMaterial
0039     auto psm = dynamic_cast<const ProtoSurfaceMaterial*>(surfaceMaterial);
0040     if (psm != nullptr) {
0041       auto binUtility = psm->binning();
0042       // Screen output for Binned Surface material
0043       ACTS_DEBUG("       - (proto) binning from ProtoSurfaceMateria is "
0044                  << binUtility);
0045       // Now adjust to surface type
0046       binUtility = adjustBinUtility(binUtility, *surface, gctx);
0047       // Screen output for Binned Surface material
0048       ACTS_DEBUG("       - adjusted binning is " << binUtility);
0049       state->accumulatedMaterial[geoID] =
0050           AccumulatedSurfaceMaterial(binUtility);
0051       // Material accumulation  is created for this
0052       continue;
0053     }
0054     // Second attempt from ProtoGridSurfaceMaterial
0055     auto psgm = dynamic_cast<const ProtoGridSurfaceMaterial*>(surfaceMaterial);
0056     if (psgm != nullptr) {
0057       BinUtility binUtility(psgm->binning());
0058       // Screen output for Binned Surface material
0059       ACTS_DEBUG("       - (proto) binning from ProtoGridSurfaceMaterial is "
0060                  << binUtility);
0061       // Now adjust to surface type
0062       binUtility = adjustBinUtility(binUtility, *surface, gctx);
0063       // Screen output for Binned Surface material
0064       ACTS_DEBUG("       - adjusted binning is " << binUtility);
0065       state->accumulatedMaterial[geoID] =
0066           AccumulatedSurfaceMaterial(binUtility);
0067       // Material accumulation  is created for this
0068       continue;
0069     }
0070     // Third attempt: binned material
0071     auto bmp = dynamic_cast<const BinnedSurfaceMaterial*>(surfaceMaterial);
0072     if (bmp != nullptr) {
0073       // Screen output for Binned Surface material
0074       ACTS_DEBUG("       - binning from BinnedSurfaceMaterial is "
0075                  << bmp->binUtility());
0076       state->accumulatedMaterial[geoID] =
0077           AccumulatedSurfaceMaterial(bmp->binUtility());
0078       // Material accumulation  is created for this
0079       continue;
0080     }
0081     // Create a homogeneous type of material
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& /*gctx*/,
0090     const std::vector<MaterialInteraction>& interactions,
0091     const std::vector<IAssignmentFinder::SurfaceAssignment>&
0092         surfacesWithoutAssignment) const {
0093   // Cast into the right state object (guaranteed by upstream algorithm)
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   // Assign the hits
0106   for (const auto& mi : interactions) {
0107     // Get the surface
0108     const Surface* surface = mi.surface;
0109     GeometryIdentifier geoID = surface->geometryId();
0110     // Get the accumulated material
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     // Accumulate the material - remember the touched bin
0117     auto tBin = accMaterial->second.accumulate(mi.intersection, mi.materialSlab,
0118                                                mi.pathCorrection);
0119     touchedMapBins.insert(MapBin(&(accMaterial->second), tBin));
0120   }
0121 
0122   // After mapping this track, average the touched bins
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   // Empty bin correction
0129   if (m_cfg.emptyBinCorrection) {
0130     for (const auto& [surface, position, direction] :
0131          surfacesWithoutAssignment) {
0132       // Get the accumulated material
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       // Apply empty hit correction
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& /*gctx*/) const {
0150   std::map<GeometryIdentifier, std::shared_ptr<const ISurfaceMaterial>>
0151       sMaterials;
0152 
0153   // Cast into the right state object (guaranteed by upstream algorithm)
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   // iterate over the map to call the total average
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 }