Analysis Software
Documentation for sPHENIX simulation 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 <algorithm>
12 #include <cassert>
13 #include <cstdint>
14 #include <vector>
15 
16 namespace Acts {
17 
34  public:
39  constexpr ElementFraction(unsigned int e, float f)
40  : m_element(static_cast<uint8_t>(e)),
41  m_fraction(static_cast<uint8_t>(f * UINT8_MAX)) {
42  assert((0u < e) and ("The atomic number must be positive"));
43  assert((0.0f <= f) and (f <= 1.0f) and
44  "Relative fraction must be in [0,1]");
45  }
50  constexpr explicit ElementFraction(unsigned int e, unsigned int w)
51  : m_element(static_cast<uint8_t>(e)),
52  m_fraction(static_cast<uint8_t>(w)) {
53  assert((0u < e) and ("The atomic number must be positive"));
54  assert((w < 256u) and "Integer weight must be in [0,256)");
55  }
56 
58  ElementFraction() = delete;
59  ElementFraction(ElementFraction&&) = default;
60  ElementFraction(const ElementFraction&) = default;
61  ~ElementFraction() = default;
63  ElementFraction& operator=(const ElementFraction&) = default;
64 
66  constexpr uint8_t element() const { return m_element; }
68  constexpr float fraction() const {
69  return static_cast<float>(m_fraction) / UINT8_MAX;
70  }
71 
72  private:
73  // element atomic number
74  uint8_t m_element;
75  // element fraction in the compound scaled to the [0,256) range.
76  uint8_t m_fraction;
77 
78  friend constexpr bool operator==(ElementFraction lhs, ElementFraction rhs) {
79  return (lhs.m_fraction == rhs.m_fraction) and
80  (lhs.m_element == rhs.m_element);
81  }
83  friend constexpr bool operator<(ElementFraction lhs, ElementFraction rhs) {
84  return lhs.m_fraction < rhs.m_fraction;
85  }
86  friend class MaterialComposition;
87 };
88 
93  public:
95  MaterialComposition() = default;
99  MaterialComposition(std::vector<ElementFraction> elements)
100  : m_elements(std::move(elements)) {
101  std::sort(m_elements.begin(), m_elements.end());
102  // compute the total weight first
103  unsigned total = 0u;
104  for (auto element : m_elements) {
105  total += element.m_fraction;
106  }
107  // compute scale factor into the [0, 256) range
108  float scale = float(UINT8_MAX) / float(total);
109  for (auto& element : m_elements) {
110  element.m_fraction = static_cast<uint8_t>(element.m_fraction * scale);
111  }
112  }
113 
115  MaterialComposition(const MaterialComposition&) = default;
116  ~MaterialComposition() = default;
119 
120  // Support range-based iteration over contained elements.
121  auto begin() const { return m_elements.begin(); }
122  auto end() const { return m_elements.end(); }
123 
125  operator bool() const { return !m_elements.empty(); }
127  std::size_t size() const { return m_elements.size(); }
128 
129  private:
130  std::vector<ElementFraction> m_elements;
131 
132  friend inline bool operator==(const MaterialComposition& lhs,
133  const MaterialComposition& rhs) {
134  return (lhs.m_elements == rhs.m_elements);
135  }
136 };
137 
138 } // namespace Acts