ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MaterialProperties.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MaterialProperties.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-2020 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
11 #include <climits>
12 #include <limits>
13 #include <ostream>
14 
15 static constexpr auto eps = 2 * std::numeric_limits<float>::epsilon();
16 
18  : m_thickness(thickness) {}
19 
20 Acts::MaterialProperties::MaterialProperties(float X0, float L0, float Ar,
21  float Z, float rho,
22  float thickness)
23  : m_material(X0, L0, Ar, Z, rho),
24  m_thickness(thickness),
25  m_thicknessInX0((X0 > eps) ? (thickness / X0) : 0),
26  m_thicknessInL0((L0 > eps) ? (thickness / L0) : 0) {}
27 
29  float thickness)
30  : m_material(material),
31  m_thickness(thickness),
32  m_thicknessInX0((material.X0() > eps) ? (thickness / material.X0()) : 0),
33  m_thicknessInL0((material.L0() > eps) ? (thickness / material.L0()) : 0) {
34 }
35 
37  const std::vector<MaterialProperties>& layers)
38  : MaterialProperties() {
39  // use double for computations to avoid precision loss
40  double Ar = 0.0;
41  double Z = 0.0;
42  double weight = 0.0;
43  double thickness = 0.0;
44  double thicknessInX0 = 0.0;
45  double thicknessInL0 = 0.0;
46  // sum-up contributions from each layer
47  for (const auto& layer : layers) {
48  const auto& mat = layer.material();
49  // weight of the layer assuming a unit area, i.e. volume = thickness*1*1
50  const auto layerWeight = mat.massDensity() * layer.thickness();
51  // Ar,Z are weighted by mass
52  Ar += mat.Ar() * layerWeight;
53  Z += mat.Z() * layerWeight;
54  weight += layerWeight;
55  // thickness and relative thickness in X0,L0 are strictly additive
56  thickness += layer.thickness();
57  thicknessInX0 += layer.thicknessInX0();
58  thicknessInL0 += layer.thicknessInL0();
59  }
60  // store averaged material constants
61  Ar /= weight;
62  Z /= weight;
63  // this is weight/volume w/ volume = thickness*unitArea = thickness*1*1
64  const auto density = weight / thickness;
65  const auto X0 = thickness / thicknessInX0;
66  const auto L0 = thickness / thicknessInL0;
67  m_material = Material(X0, L0, Ar, Z, density);
68  // thickness properties do not need to be averaged
72 }
73 
75  m_thickness *= scale;
76  m_thicknessInX0 *= scale;
77  m_thicknessInL0 *= scale;
78 }
79 
80 std::ostream& Acts::operator<<(std::ostream& os,
81  const MaterialProperties& materialProperties) {
82  os << materialProperties.material()
83  << "|t=" << materialProperties.thickness();
84  return os;
85 }