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) 2019-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/Material.hpp"
0010 
0011 #include "Acts/Definitions/Units.hpp"
0012 
0013 #include <cmath>
0014 #include <ostream>
0015 
0016 namespace {
0017 enum MaterialClassificationNumberIndices {
0018   eRadiationLength = 0,
0019   eInteractionLength = 1,
0020   eRelativeAtomicMass = 2,
0021   eNuclearCharge = 3,
0022   eMolarDensity = 4,
0023 };
0024 
0025 // Avogadro constant
0026 constexpr double kAvogadro = 6.02214076e23 / Acts::UnitConstants::mol;
0027 }  // namespace
0028 
0029 Acts::Material Acts::Material::fromMassDensity(float x0, float l0, float ar,
0030                                                float z, float massRho) {
0031   using namespace Acts::UnitLiterals;
0032 
0033   Material mat;
0034   mat.m_x0 = x0;
0035   mat.m_l0 = l0;
0036   mat.m_ar = ar;
0037   mat.m_z = z;
0038   // mass density is defined as
0039   //
0040   //     mass-density = atomic-mass * number-of-atoms / volume
0041   //                  = atomic-mass * molar-density * avogadro-constant
0042   // -> molar-density = mass-density / (atomic-mass * avogadro-constant)
0043   //
0044   // with the atomic mass given by
0045   //
0046   //      atomic-mass = relative-atomic-mass * atomic-mass-unit
0047   //
0048   // perform computations in double precision to avoid loss of precision
0049   const double atomicMass = static_cast<double>(ar) * 1_u;
0050   mat.m_molarRho = static_cast<double>(massRho) / (atomicMass * kAvogadro);
0051   return mat;
0052 }
0053 
0054 Acts::Material Acts::Material::fromMolarDensity(float x0, float l0, float ar,
0055                                                 float z, float molarRho) {
0056   Material mat;
0057   mat.m_x0 = x0;
0058   mat.m_l0 = l0;
0059   mat.m_ar = ar;
0060   mat.m_z = z;
0061   mat.m_molarRho = molarRho;
0062   return mat;
0063 }
0064 
0065 Acts::Material::Material(const ParametersVector& parameters)
0066     : m_x0(parameters[eRadiationLength]),
0067       m_l0(parameters[eInteractionLength]),
0068       m_ar(parameters[eRelativeAtomicMass]),
0069       m_z(parameters[eNuclearCharge]),
0070       m_molarRho(parameters[eMolarDensity]) {}
0071 
0072 float Acts::Material::massDensity() const {
0073   using namespace Acts::UnitLiterals;
0074 
0075   // perform computations in double precision to avoid loss of precision
0076   const double atomicMass = static_cast<double>(m_ar) * 1_u;
0077   const double numberDensity = static_cast<double>(m_molarRho) * kAvogadro;
0078   return atomicMass * numberDensity;
0079 }
0080 
0081 float Acts::Material::meanExcitationEnergy() const {
0082   using namespace Acts::UnitLiterals;
0083 
0084   // use approximative computation as defined in ATL-SOFT-PUB-2008-003
0085   return 16_eV * std::pow(m_z, 0.9f);
0086 }
0087 
0088 Acts::Material::ParametersVector Acts::Material::parameters() const {
0089   ParametersVector parameters;
0090   parameters[eRadiationLength] = m_x0;
0091   parameters[eInteractionLength] = m_l0;
0092   parameters[eRelativeAtomicMass] = m_ar;
0093   parameters[eNuclearCharge] = m_z;
0094   parameters[eMolarDensity] = m_molarRho;
0095   return parameters;
0096 }
0097 
0098 std::ostream& Acts::operator<<(std::ostream& os, const Material& material) {
0099   if (!material) {
0100     os << "vacuum";
0101   } else {
0102     os << "x0=" << material.X0();
0103     os << "|l0=" << material.L0();
0104     os << "|ar=" << material.Ar();
0105     os << "|z=" << material.Z();
0106     os << "|molar_rho=" << material.molarDensity();
0107   }
0108   return os;
0109 }