Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:09:39

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2016-2020 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 http://mozilla.org/MPL/2.0/.
0008 
0009 #include "Acts/Material/MaterialSlab.hpp"
0010 
0011 #include "Acts/Material/detail/AverageMaterials.hpp"
0012 
0013 #include <limits>
0014 #include <numeric>
0015 #include <ostream>
0016 #include <stdexcept>
0017 
0018 namespace Acts {
0019 
0020 namespace {
0021 static constexpr auto eps = 2 * std::numeric_limits<float>::epsilon();
0022 }
0023 
0024 MaterialSlab::MaterialSlab(float thickness) : m_thickness(thickness) {}
0025 
0026 MaterialSlab::MaterialSlab(const Material& material, float thickness)
0027     : m_material(material),
0028       m_thickness(thickness),
0029       m_thicknessInX0((eps < material.X0()) ? (thickness / material.X0()) : 0),
0030       m_thicknessInL0((eps < material.L0()) ? (thickness / material.L0()) : 0) {
0031   if (thickness < 0) {
0032     throw std::runtime_error("thickness < 0");
0033   }
0034 }
0035 
0036 MaterialSlab MaterialSlab::averageLayers(const MaterialSlab& layerA,
0037                                          const MaterialSlab& layerB) {
0038   return detail::combineSlabs(layerA, layerB);
0039 }
0040 
0041 MaterialSlab MaterialSlab::averageLayers(
0042     const std::vector<MaterialSlab>& layers) {
0043   // NOTE 2020-08-26 msmk
0044   //   the reduce work best (in the numerical stability sense) if the input
0045   //   layers are sorted by thickness/mass density. then, the later terms
0046   //   of the averaging are only small corrections to the large average of
0047   //   the initial layers. this could be enforced by sorting the layers first,
0048   //   but I am not sure if this is actually a problem.
0049   // NOTE yes, this loop is exactly like std::reduce which apparently does not
0050   //   exist on gcc 8 although it is required by C++17.
0051   MaterialSlab result;
0052   for (const auto& layer : layers) {
0053     result = detail::combineSlabs(result, layer);
0054   }
0055   return result;
0056 }
0057 
0058 void MaterialSlab::scaleThickness(float scale) {
0059   if (scale < 0) {
0060     throw std::runtime_error("scale < 0");
0061   }
0062 
0063   m_thickness *= scale;
0064   m_thicknessInX0 *= scale;
0065   m_thicknessInL0 *= scale;
0066 }
0067 
0068 std::ostream& operator<<(std::ostream& os, const MaterialSlab& materialSlab) {
0069   os << materialSlab.material() << "|t=" << materialSlab.thickness();
0070   return os;
0071 }
0072 
0073 }  // namespace Acts