Skip to content

Commit

Permalink
feat: material mapper in core (MM4) (#3087)
Browse files Browse the repository at this point in the history
This is the first PR in a series that divides the Material Mapping into logical, unit testable modules:

1) Finding intersections with surfaces and associations to volumes (MM2)
2) Assigning material interactions to those intersections (MM1)
3) Mapping those onto dedicated Surface / Volume Material Mappers (MM3)
4) Steer that by a chained algorithm (MM4, this PR)

This PR:

Introduces a MaterialMapper which just needs I/O connection in the relevant framework/experiment context implementation.

All cases are showcased and tested in a set of UnitTests.
  • Loading branch information
asalzburger authored Apr 10, 2024
1 parent 5d3461f commit 21cbbf7
Show file tree
Hide file tree
Showing 5 changed files with 446 additions and 0 deletions.
98 changes: 98 additions & 0 deletions Core/include/Acts/Material/MaterialMapper.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// This file is part of the Acts project.
//
// Copyright (C) 2024 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/MagneticField/MagneticFieldContext.hpp"
#include "Acts/Material/MaterialInteraction.hpp"
#include "Acts/Material/MaterialInteractionAssignment.hpp"
#include "Acts/Material/interface/IAssignmentFinder.hpp"
#include "Acts/Material/interface/ISurfaceMaterialAccumulater.hpp"
#include "Acts/Utilities/Logger.hpp"

#include <memory>
#include <utility>
#include <vector>

namespace Acts {
/// @brief material mapping procedure
class MaterialMapper {
public:
/// @brief The material maps
using SurfaceMaterialMaps =
std::map<GeometryIdentifier, std::shared_ptr<const ISurfaceMaterial>>;
using VolumeMaterialMaps =
std::map<GeometryIdentifier, std::shared_ptr<const IVolumeMaterial>>;
using DetectorMaterialMaps =
std::pair<SurfaceMaterialMaps, VolumeMaterialMaps>;

/// @brief nested configuration struct
struct Config {
// The assignment finder
std::shared_ptr<const IAssignmentFinder> assignmentFinder = nullptr;
// The material accumulater for surfaces
std::shared_ptr<const ISurfaceMaterialAccumulater>
surfaceMaterialAccumulater = nullptr;
};

/// @brief nested state struct
///
/// It holds the states of the sub structs
struct State {
std::unique_ptr<ISurfaceMaterialAccumulater::State>
surfaceMaterialAccumulaterState;
};

/// @brief nested options struct
/// holds some options for the delegated calls
struct Options {
// The assignment options (including vetos and re-assignments)
MaterialInteractionAssignment::Options assignmentOptions;
};

/// @brief MaterialMapper constructor
///
/// @param cfg the configuration struct
/// @param mlogger the logger instance
MaterialMapper(const Config& cfg,
std::unique_ptr<const Logger> mlogger = getDefaultLogger(
"BinnedSurfaceMaterialAccumulater", Logging::INFO));

/// @brief Factory for creating the state
std::unique_ptr<State> createState() const;

/// @brief Map the material interactions to the surfaces
///
/// @param state the state object holding the sub states
/// @param gctx the geometry context
/// @param mctx the magnetic field context
/// @param rmTrack the recorded material track
/// @param options the call options (see above)
///
/// @return the mapped and unmapped material tracks
std::pair<RecordedMaterialTrack, RecordedMaterialTrack> mapMaterial(
State& state, const GeometryContext& gctx,
const MagneticFieldContext& mctx, const RecordedMaterialTrack& rmTrack,
const Options& options = Options{}) const;

/// Finalize the maps
DetectorMaterialMaps finalizeMaps(const State& state) const;

private:
/// Access method to the logger
const Logger& logger() const { return *m_logger; }

/// The configuration
Config m_cfg;

/// The logger
std::unique_ptr<const Logger> m_logger;
};

} // namespace Acts
1 change: 1 addition & 0 deletions Core/src/Material/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ target_sources(
MaterialGridHelper.cpp
MaterialInteractionAssignment.cpp
MaterialMapUtils.cpp
MaterialMapper.cpp
MaterialSlab.cpp
ProtoVolumeMaterial.cpp
SurfaceMaterialMapper.cpp
Expand Down
92 changes: 92 additions & 0 deletions Core/src/Material/MaterialMapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// This file is part of the Acts project.
//
// Copyright (C) 2024 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "Acts/Material/MaterialMapper.hpp"

Acts::MaterialMapper::MaterialMapper(const Config& cfg,
std::unique_ptr<const Logger> mlogger)
: m_cfg(cfg), m_logger(std::move(mlogger)) {
if (m_cfg.assignmentFinder == nullptr) {
throw std::invalid_argument("The assignment finder is not set");
}
if (m_cfg.surfaceMaterialAccumulater == nullptr) {
throw std::invalid_argument("The surface material accumulater is not set");
}
}

std::unique_ptr<Acts::MaterialMapper::State> Acts::MaterialMapper::createState()
const {
// Create the state
auto state = std::make_unique<State>();
// Create the surface material accumulater state
state->surfaceMaterialAccumulaterState =
m_cfg.surfaceMaterialAccumulater->createState();
// Return the state object
return state;
}

std::pair<Acts::RecordedMaterialTrack, Acts::RecordedMaterialTrack>
Acts::MaterialMapper::mapMaterial(State& state, const GeometryContext& gctx,
const MagneticFieldContext& mctx,
const RecordedMaterialTrack& rmTrack,
const Options& options) const {
// The recorded material track
const auto& [starDir, recordedMaterial] = rmTrack;
const auto& [position, direction] = starDir;
auto [surfaceAssignments, volumeAssignments] =
m_cfg.assignmentFinder->assignmentCandidates(gctx, mctx, position,
direction);

// The mapped and unmapped material
RecordedMaterialTrack mappedMaterial = {starDir, {}};
RecordedMaterialTrack unmappedMaterial = {starDir, {}};
// Assign the surface interactions
auto [assigned, unassigned, emptyBinSurfaces] =
MaterialInteractionAssignment::assign(
gctx, recordedMaterial.materialInteractions, surfaceAssignments,
options.assignmentOptions);

// Record the assigned ones - as mapped ones
mappedMaterial.second.materialInteractions.insert(
mappedMaterial.second.materialInteractions.end(), assigned.begin(),
assigned.end());

// Record the unassigned ones - as unmapped ones
unmappedMaterial.second.materialInteractions.insert(
unmappedMaterial.second.materialInteractions.end(), unassigned.begin(),
unassigned.end());

// The material interactions
m_cfg.surfaceMaterialAccumulater->accumulate(
*state.surfaceMaterialAccumulaterState.get(), assigned, emptyBinSurfaces);

// The function to calculate the total material before returning
auto calculateTotalMaterial = [](RecordedMaterialTrack& rTrack) -> void {
for (const auto& mi : rTrack.second.materialInteractions) {
rTrack.second.materialInX0 += mi.materialSlab.thicknessInX0();
rTrack.second.materialInL0 += mi.materialSlab.thicknessInL0();
}
};
// Fill the totals to the material tracks (useful for debugging)
calculateTotalMaterial(mappedMaterial);
calculateTotalMaterial(unmappedMaterial);
// Return the mapped and unmapped material
return {mappedMaterial, unmappedMaterial};
}

Acts::MaterialMapper::DetectorMaterialMaps Acts::MaterialMapper::finalizeMaps(
const State& state) const {
// The final maps
DetectorMaterialMaps detectorMaterialMaps;
// The surface maps
detectorMaterialMaps.first =
m_cfg.surfaceMaterialAccumulater->finalizeMaterial(
*state.surfaceMaterialAccumulaterState.get());

return detectorMaterialMaps;
}
1 change: 1 addition & 0 deletions Tests/UnitTests/Core/Material/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ add_unittest(IntersectionMaterialAssigner IntersectionMaterialAssignerTests.cpp)
add_unittest(MaterialComposition MaterialCompositionTests.cpp)
add_unittest(MaterialGridHelper MaterialGridHelperTests.cpp)
add_unittest(MaterialInteractionAssignment MaterialInteractionAssignmentTests.cpp)
add_unittest(MaterialMapper MaterialMapperTests.cpp)
add_unittest(MaterialSlab MaterialSlabTests.cpp)
add_unittest(Material MaterialTests.cpp)
add_unittest(ProtoSurfaceMaterial ProtoSurfaceMaterialTests.cpp)
Expand Down
Loading

0 comments on commit 21cbbf7

Please sign in to comment.