diff --git a/Core/include/Acts/Material/AccumulatedSurfaceMaterial.hpp b/Core/include/Acts/Material/AccumulatedSurfaceMaterial.hpp index 85c522e8414..6073c345861 100644 --- a/Core/include/Acts/Material/AccumulatedSurfaceMaterial.hpp +++ b/Core/include/Acts/Material/AccumulatedSurfaceMaterial.hpp @@ -12,6 +12,8 @@ #include "Acts/Material/AccumulatedMaterialSlab.hpp" #include "Acts/Material/MaterialSlab.hpp" #include "Acts/Utilities/BinUtility.hpp" +#include "Acts/Utilities/ProtoAxis.hpp" +#include "Acts/Utilities/ProtoAxisHelpers.hpp" #include #include @@ -54,6 +56,12 @@ class AccumulatedSurfaceMaterial { explicit AccumulatedSurfaceMaterial(const BinUtility& binUtility, double splitFactor = 0.); + /// constructor using DirectedProtoAxes for binning + /// @param axes span of DirectedProtoAxis objects defining the binning + /// @param splitFactor is the pre/post splitting directive + AccumulatedSurfaceMaterial(const std::vector& axes, + double splitFactor = 0.); + /// Copy Constructor /// /// @param asma is the source object to be copied @@ -85,6 +93,9 @@ class AccumulatedSurfaceMaterial { /// @return Reference to the bin utility used for material binning const BinUtility& binUtility() const; + /// Return the proto axes + const std::vector& axes() const { return m_axes; } + /// Assign a material properties object /// /// @param lp local position for the bin assignment @@ -155,6 +166,9 @@ class AccumulatedSurfaceMaterial { /// The helper for the bin finding BinUtility m_binUtility{}; + /// The proto axes used for binning + std::vector m_axes{}; + /// the split factor double m_splitFactor{0.}; diff --git a/Core/include/Acts/Material/BinnedSurfaceMaterial.hpp b/Core/include/Acts/Material/BinnedSurfaceMaterial.hpp index 3b288eacf73..211a9df6744 100644 --- a/Core/include/Acts/Material/BinnedSurfaceMaterial.hpp +++ b/Core/include/Acts/Material/BinnedSurfaceMaterial.hpp @@ -12,6 +12,7 @@ #include "Acts/Material/ISurfaceMaterial.hpp" #include "Acts/Material/MaterialSlab.hpp" #include "Acts/Utilities/BinUtility.hpp" +#include "Acts/Utilities/ProtoAxis.hpp" #include @@ -62,6 +63,40 @@ class BinnedSurfaceMaterial : public ISurfaceMaterial { double splitFactor = 0., MappingType mappingType = MappingType::Default); + /// Explicit constructor with only full MaterialSlab, + /// for one-dimensional binning. + /// + /// The split factors: + /// - 1. : oppositePre + /// - 0. : alongPre + /// ===> 1 Dimensional array + /// + /// @param axes defines the binning structure on the surface (copied) + /// @param fullProperties is the vector of properties as recorded (moved) + /// @param splitFactor is the pre/post splitting directive + /// @param mappingType is the type of surface mapping associated to the surface + BinnedSurfaceMaterial(const std::vector& axes, + MaterialSlabVector fullProperties, + double splitFactor = 0., + MappingType mappingType = MappingType::Default); + + /// Explicit constructor with only full MaterialSlab, + /// for two-dimensional binning. + /// + /// The split factors: + /// - 1. : oppositePre + /// - 0. : alongPre + /// ===> 1 Dimensional array + /// + /// @param axes defines the binning structure on the surface (DirectedProtoAxis) (copied) + /// @param fullProperties is the vector of properties as recorded (moved) + /// @param splitFactor is the pre/post splitting directive + /// @param mappingType is the type of surface mapping associated to the surface + BinnedSurfaceMaterial(const std::vector& axes, + MaterialSlabMatrix fullProperties, + double splitFactor = 0., + MappingType mappingType = MappingType::Default); + /// Copy Move Constructor /// /// @param bsm is the source object to be copied @@ -114,6 +149,9 @@ class BinnedSurfaceMaterial : public ISurfaceMaterial { /// The helper for the bin finding BinUtility m_binUtility; + /// The proto axes used for binning + std::vector m_axes{}; + /// The five different MaterialSlab MaterialSlabMatrix m_fullMaterial; }; diff --git a/Core/src/Material/AccumulatedSurfaceMaterial.cpp b/Core/src/Material/AccumulatedSurfaceMaterial.cpp index 9fb08edc903..0f87db36ed3 100644 --- a/Core/src/Material/AccumulatedSurfaceMaterial.cpp +++ b/Core/src/Material/AccumulatedSurfaceMaterial.cpp @@ -22,6 +22,7 @@ Acts::AccumulatedSurfaceMaterial::AccumulatedSurfaceMaterial(double splitFactor) } // Binned Material constructor with split factor +// TODO: Remove this constructor after DirectedProtoAxis migration Acts::AccumulatedSurfaceMaterial::AccumulatedSurfaceMaterial( const BinUtility& binUtility, double splitFactor) : m_binUtility(binUtility), m_splitFactor(splitFactor) { @@ -31,15 +32,39 @@ Acts::AccumulatedSurfaceMaterial::AccumulatedSurfaceMaterial( m_accumulatedMaterial = AccumulatedMatrix(bins1, accVec); } +// Constructor using DirectedProtoAxes for binning +Acts::AccumulatedSurfaceMaterial::AccumulatedSurfaceMaterial( + const std::vector& axes, double splitFactor) + : m_axes(axes), m_splitFactor(splitFactor) { + if (m_axes.size() < 1 || m_axes.size() > 2) { + throw std::invalid_argument( + "AccumulatedSurfaceMaterial: At least one, maximum 2 proto axis is " + "required for binning."); + } + if (m_axes.size() == 1) { + std::size_t bins0 = m_axes[0].getAxis().getNBins(); + AccumulatedVector accVec(bins0, AccumulatedMaterialSlab()); + m_accumulatedMaterial = AccumulatedMatrix(1, accVec); + return; + } + if (m_axes.size() == 2) { + std::size_t bins0 = m_axes[0].getAxis().getNBins(); + std::size_t bins1 = m_axes[1].getAxis().getNBins(); + AccumulatedVector accVec(bins0, AccumulatedMaterialSlab()); + m_accumulatedMaterial = AccumulatedMatrix(bins1, accVec); + return; + } +} + // Assign a material properties object std::array Acts::AccumulatedSurfaceMaterial::accumulate( const Vector2& lp, const MaterialSlab& mp, double pathCorrection) { - if (m_binUtility.dimensions() == 0) { + if (m_axes.empty()) { m_accumulatedMaterial[0][0].accumulate(mp, pathCorrection); return {0, 0, 0}; } - std::size_t bin0 = m_binUtility.bin(lp, 0); - std::size_t bin1 = m_binUtility.bin(lp, 1); + std::size_t bin0 = Acts::ProtoAxisHelpers::binFromProtoAxis(m_axes[0], lp); + std::size_t bin1 = Acts::ProtoAxisHelpers::binFromProtoAxis(m_axes[1], lp); m_accumulatedMaterial[bin1][bin0].accumulate(mp, pathCorrection); return {bin0, bin1, 0}; } @@ -47,11 +72,12 @@ std::array Acts::AccumulatedSurfaceMaterial::accumulate( // Assign a material properties object std::array Acts::AccumulatedSurfaceMaterial::accumulate( const Vector3& gp, const MaterialSlab& mp, double pathCorrection) { - if (m_binUtility.dimensions() == 0) { + if (m_axes.empty()) { m_accumulatedMaterial[0][0].accumulate(mp, pathCorrection); return {0, 0, 0}; } - std::array bTriple = m_binUtility.binTriple(gp); + std::array bTriple = + Acts::ProtoAxisHelpers::binTripleFromProtoAxes(m_axes, gp); m_accumulatedMaterial[bTriple[1]][bTriple[0]].accumulate(mp, pathCorrection); return bTriple; } @@ -60,11 +86,12 @@ std::array Acts::AccumulatedSurfaceMaterial::accumulate( void Acts::AccumulatedSurfaceMaterial::trackVariance(const Vector3& gp, MaterialSlab slabReference, bool emptyHit) { - if (m_binUtility.dimensions() == 0) { + if (m_axes.empty()) { m_accumulatedMaterial[0][0].trackVariance(slabReference, emptyHit); return; } - std::array bTriple = m_binUtility.binTriple(gp); + std::array bTriple = + Acts::ProtoAxisHelpers::binTripleFromProtoAxes(m_axes, gp); std::vector> trackBins = {bTriple}; trackVariance(trackBins, slabReference); } @@ -74,7 +101,7 @@ void Acts::AccumulatedSurfaceMaterial::trackVariance( const std::vector>& trackBins, MaterialSlab slabReference, bool emptyHit) { // the homogeneous material case - if (m_binUtility.dimensions() == 0) { + if (m_axes.empty()) { m_accumulatedMaterial[0][0].trackVariance(slabReference, emptyHit); return; } @@ -96,12 +123,13 @@ void Acts::AccumulatedSurfaceMaterial::trackVariance( // Void average for vacuum assignment void Acts::AccumulatedSurfaceMaterial::trackAverage(const Vector3& gp, bool emptyHit) { - if (m_binUtility.dimensions() == 0) { + if (m_axes.empty()) { m_accumulatedMaterial[0][0].trackAverage(emptyHit); return; } - std::array bTriple = m_binUtility.binTriple(gp); + std::array bTriple = + Acts::ProtoAxisHelpers::binTripleFromProtoAxes(m_axes, gp); std::vector> trackBins = {bTriple}; trackAverage(trackBins, emptyHit); } @@ -110,7 +138,8 @@ void Acts::AccumulatedSurfaceMaterial::trackAverage(const Vector3& gp, void Acts::AccumulatedSurfaceMaterial::trackAverage( const std::vector>& trackBins, bool emptyHit) { // the homogeneous material case - if (m_binUtility.dimensions() == 0) { + // the homogeneous material case + if (m_axes.size() == 0) { m_accumulatedMaterial[0][0].trackAverage(emptyHit); return; } @@ -133,22 +162,26 @@ void Acts::AccumulatedSurfaceMaterial::trackAverage( /// Total average creates SurfaceMaterial std::unique_ptr Acts::AccumulatedSurfaceMaterial::totalAverage() { - if (m_binUtility.bins() == 1) { + std::cout << "AccumulatedSurfaceMaterial::totalAverage called with " + << m_axes.size() << " axes." << std::endl; + if (ProtoAxisHelpers::totalBinsFromProtoAxes(m_axes) <= 1) { // Return HomogeneousSurfaceMaterial return std::make_unique( m_accumulatedMaterial[0][0].totalAverage().first, m_splitFactor); } - // Create the properties matrix + + // number of bins per axis from DirectedProtoAxis + std::size_t bins0 = m_axes[0].getAxis().getNBins(); + std::size_t bins1 = m_axes[1].getAxis().getNBins(); + + // build the material-property matrix and fill from accumulated data MaterialSlabMatrix mpMatrix( - m_binUtility.bins(1), - MaterialSlabVector(m_binUtility.bins(0), MaterialSlab::Nothing())); - // Loop over and fill - for (std::size_t ib1 = 0; ib1 < m_binUtility.bins(1); ++ib1) { - for (std::size_t ib0 = 0; ib0 < m_binUtility.bins(0); ++ib0) { + bins1, MaterialSlabVector(bins0, MaterialSlab::Nothing())); + for (std::size_t ib1 = 0; ib1 < bins1; ++ib1) { + for (std::size_t ib0 = 0; ib0 < bins0; ++ib0) { mpMatrix[ib1][ib0] = m_accumulatedMaterial[ib1][ib0].totalAverage().first; } } - // Now return the BinnedSurfaceMaterial return std::make_unique( - m_binUtility, std::move(mpMatrix), m_splitFactor); + m_axes, std::move(mpMatrix), m_splitFactor); } diff --git a/Core/src/Material/BinnedSurfaceMaterial.cpp b/Core/src/Material/BinnedSurfaceMaterial.cpp index aae46bd02d7..448ef334782 100644 --- a/Core/src/Material/BinnedSurfaceMaterial.cpp +++ b/Core/src/Material/BinnedSurfaceMaterial.cpp @@ -29,6 +29,23 @@ Acts::BinnedSurfaceMaterial::BinnedSurfaceMaterial( m_binUtility(binUtility), m_fullMaterial(std::move(fullProperties)) {} +Acts::BinnedSurfaceMaterial::BinnedSurfaceMaterial( + const std::vector& axes, + MaterialSlabVector fullProperties, double splitFactor, + Acts::MappingType mappingType) + : ISurfaceMaterial(splitFactor, mappingType), m_axes(axes) { + // fill the material with deep copy + m_fullMaterial.push_back(std::move(fullProperties)); +} + +Acts::BinnedSurfaceMaterial::BinnedSurfaceMaterial( + const std::vector& axes, + MaterialSlabMatrix fullProperties, double splitFactor, + Acts::MappingType mappingType) + : ISurfaceMaterial(splitFactor, mappingType), + m_axes(axes), + m_fullMaterial(std::move(fullProperties)) {} + Acts::BinnedSurfaceMaterial& Acts::BinnedSurfaceMaterial::scale(double factor) { for (auto& materialVector : m_fullMaterial) { for (auto& materialBin : materialVector) { diff --git a/Tests/UnitTests/Core/Material/AccumulatedSurfaceMaterialTests.cpp b/Tests/UnitTests/Core/Material/AccumulatedSurfaceMaterialTests.cpp index 4e94f0f92e3..d6435266142 100644 --- a/Tests/UnitTests/Core/Material/AccumulatedSurfaceMaterialTests.cpp +++ b/Tests/UnitTests/Core/Material/AccumulatedSurfaceMaterialTests.cpp @@ -39,17 +39,19 @@ BOOST_AUTO_TEST_CASE(AccumulatedSurfaceMaterial_construction_test) { // Test: // BinsSurfaceMaterial accumulation - 1D - BinUtility binUtility1D(10, -5., 5., open, AxisDirection::AxisX); - AccumulatedSurfaceMaterial material1D{binUtility1D}; - auto accMat1D = material1D.accumulatedMaterial(); - BOOST_CHECK_EQUAL(accMat1D.size(), 1u); - BOOST_CHECK_EQUAL(accMat1D[0].size(), 10u); + DirectedProtoAxis axis00(AxisDirection::AxisX, AxisBoundaryType::Open, -5., + 5., 10); + std::vector axes0 = {axis00}; + AccumulatedSurfaceMaterial material1D{axes0}; // Test: // BinsSurfaceMaterial accumulation - 2D - BinUtility binUtility2D(10, -5., 5., open, AxisDirection::AxisX); - binUtility2D += BinUtility(20, -10., 10., open, AxisDirection::AxisY); - AccumulatedSurfaceMaterial material2D{binUtility2D}; + DirectedProtoAxis axis10(AxisDirection::AxisX, AxisBoundaryType::Open, -5., + 5., 10); + DirectedProtoAxis axis11(AxisDirection::AxisY, AxisBoundaryType::Open, -10., + 10., 20); + std::vector axes1 = {axis10, axis11}; + AccumulatedSurfaceMaterial material2D{axes1}; auto accMat2D = material2D.accumulatedMaterial(); BOOST_CHECK_EQUAL(accMat2D.size(), 20u); for (std::size_t ib = 0; ib < accMat2D.size(); ++ib) { @@ -95,9 +97,12 @@ BOOST_AUTO_TEST_CASE(AccumulatedSurfaceMaterial_fill_convert_1D) { MaterialSlab four(mat, 4.); // BinsSurfaceMaterial accumulation - 2D - BinUtility binUtility2D(2, -1., 1., open, AxisDirection::AxisX); - binUtility2D += BinUtility(2, -1., 1., open, AxisDirection::AxisY); - AccumulatedSurfaceMaterial material2D{binUtility2D}; + DirectedProtoAxis axis0{AxisDirection::AxisX, AxisBoundaryType::Open, -1., 1., + 2}; + DirectedProtoAxis axis1{AxisDirection::AxisY, AxisBoundaryType::Open, -1., 1., + 2}; + std::vector axes = {axis0, axis1}; + AccumulatedSurfaceMaterial material2D{axes}; const std::vector> bin; // assign in the different bins