ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MaterialComposition.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file MaterialComposition.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2018-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 
9 #pragma once
10 
11 #include <cassert>
12 #include <cstdint>
13 #include <vector>
14 
15 namespace Acts {
16 
33  public:
38  constexpr ElementFraction(unsigned int e, float f)
39  : m_element(static_cast<uint8_t>(e)),
40  m_fraction(static_cast<uint8_t>(f * UINT8_MAX)) {
41  assert((0u < e) and ("The atomic number must be positive"));
42  assert((0.0f <= f) and (f <= 1.0f) and
43  "Relative fraction must be in [0,1]");
44  }
49  constexpr explicit ElementFraction(unsigned int e, unsigned int w)
50  : m_element(static_cast<uint8_t>(e)),
51  m_fraction(static_cast<uint8_t>(w)) {
52  assert((0u < e) and ("The atomic number must be positive"));
53  assert((w < 256u) and "Integer weight must be in [0,256)");
54  }
55 
57  ElementFraction() = delete;
58  ElementFraction(ElementFraction&&) = default;
59  ElementFraction(const ElementFraction&) = default;
60  ~ElementFraction() = default;
62  ElementFraction& operator=(const ElementFraction&) = default;
63 
65  constexpr uint8_t element() const { return m_element; }
67  constexpr float fraction() const {
68  return static_cast<float>(m_fraction) / UINT8_MAX;
69  }
70 
71  private:
72  // element atomic number
73  uint8_t m_element;
74  // element fraction in the compound scaled to the [0,256) range.
75  uint8_t m_fraction;
76 
77  friend constexpr bool operator==(ElementFraction lhs, ElementFraction rhs) {
78  return (lhs.m_fraction == rhs.m_fraction) and
79  (lhs.m_element == rhs.m_element);
80  }
82  friend constexpr bool operator<(ElementFraction lhs, ElementFraction rhs) {
83  return lhs.m_fraction < rhs.m_fraction;
84  }
85  friend class MaterialComposition;
86 };
87 
92  public:
94  MaterialComposition() = default;
98  MaterialComposition(std::vector<ElementFraction> elements)
99  : m_elements(std::move(elements)) {
100  std::sort(m_elements.begin(), m_elements.end());
101  // compute the total weight first
102  unsigned total = 0u;
103  for (auto element : m_elements) {
104  total += element.m_fraction;
105  }
106  // compute scale factor into the [0, 256) range
107  float scale = float(UINT8_MAX) / float(total);
108  for (auto& element : m_elements) {
109  element.m_fraction *= scale;
110  }
111  }
112 
114  MaterialComposition(const MaterialComposition&) = default;
115  ~MaterialComposition() = default;
118 
119  // Support range-based iteration over contained elements.
120  auto begin() const { return m_elements.begin(); }
121  auto end() const { return m_elements.end(); }
122 
124  operator bool() const { return !m_elements.empty(); }
126  size_t size() const { return m_elements.size(); }
127 
128  private:
129  std::vector<ElementFraction> m_elements;
130 
131  friend inline bool operator==(const MaterialComposition& lhs,
132  const MaterialComposition& rhs) {
133  return (lhs.m_elements == rhs.m_elements);
134  }
135 };
136 
137 } // namespace Acts