-
Notifications
You must be signed in to change notification settings - Fork 173
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: material mapper in core (MM4) (#3087)
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
1 parent
5d3461f
commit 21cbbf7
Showing
5 changed files
with
446 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.