Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
BinUtility.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file BinUtility.hpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2016-2018 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 
15 
16 #include <array>
17 #include <cstddef>
18 #include <iostream>
19 #include <iterator>
20 #include <memory>
21 #include <string>
22 #include <vector>
23 
24 namespace Acts {
25 
36 class BinUtility {
37  public:
40  : m_binningData(),
43  m_binningData.reserve(3);
44  }
45 
49  BinUtility(const Transform3& tForm)
50  : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) {
51  m_binningData.reserve(3);
52  }
53 
58  BinUtility(const BinningData& bData,
59  const Transform3& tForm = Transform3::Identity())
60  : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) {
61  m_binningData.reserve(3);
62  m_binningData.push_back(bData);
63  }
64 
73  BinUtility(size_t bins, float min, float max, BinningOption opt = open,
75  const Transform3& tForm = Transform3::Identity())
76  : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) {
77  m_binningData.reserve(3);
78  m_binningData.push_back(BinningData(opt, value, bins, min, max));
79  }
80 
87  BinUtility(std::vector<float>& bValues, BinningOption opt = open,
89  const Transform3& tForm = Transform3::Identity())
90  : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) {
91  m_binningData.reserve(3);
92  m_binningData.push_back(BinningData(opt, value, bValues));
93  }
94 
98  BinUtility(const BinUtility& sbu) = default;
99 
100  BinUtility(BinUtility&& sbu) = default;
101 
106  if (this != &sbu) {
108  m_transform = sbu.m_transform;
110  }
111  return (*this);
112  }
113 
114  BinUtility& operator=(BinUtility&&) = default;
115 
120  const std::vector<BinningData>& bData = gbu.binningData();
121 
123  m_itransform = m_transform.inverse();
124  if (m_binningData.size() + bData.size() > 3) {
125  throw "BinUtility does not support dim > 3";
126  }
127  m_binningData.insert(m_binningData.end(), bData.begin(), bData.end());
128  return (*this);
129  }
130 
132  ~BinUtility() = default;
133 
135  bool operator==(const BinUtility& other) const {
136  return (m_transform.isApprox(other.m_transform) and
137  m_binningData == other.binningData());
138  }
139 
141  const std::vector<BinningData>& binningData() const { return m_binningData; }
142 
144  size_t bins() const { return bins(0) * bins(1) * bins(2); }
145 
153  std::array<size_t, 3> binTriple(const Vector3& position) const {
155  const Vector3 bPosition = m_itransform * position;
156  // get the dimension
157  size_t mdim = m_binningData.size();
159  size_t bin0 = m_binningData[0].searchGlobal(bPosition);
160  size_t bin1 = mdim > 1 ? m_binningData[1].searchGlobal(bPosition) : 0;
161  size_t bin2 = mdim > 2 ? m_binningData[2].searchGlobal(bPosition) : 0;
163  return {{bin0, bin1, bin2}};
164  }
165 
172  size_t bin(const Vector3& position, size_t ba = 0) const {
173  if (ba >= m_binningData.size()) {
174  return 0;
175  }
176  size_t bEval = m_binningData[ba].searchGlobal(m_itransform * position);
177  return bEval;
178  }
179 
189  int nextDirection(const Vector3& position, const Vector3& direction,
190  size_t ba = 0) const {
191  if (ba >= m_binningData.size()) {
192  return 0;
193  }
194  return m_binningData[ba].nextDirection(position, direction);
195  }
196 
208  size_t bin(const Vector2& lposition, size_t ba = 0) const {
209  if (ba >= m_binningData.size()) {
210  return 0;
211  }
212  return m_binningData[ba].searchLocal(lposition);
213  }
218  bool inside(const Vector3& position) const {
220  const Vector3& bPosition = m_itransform * position;
221  // loop and break
222  for (auto& bData : m_binningData) {
223  if (!(bData.inside(bPosition))) {
224  return false;
225  }
226  }
227  // survived all the checks
228  return true;
229  }
230 
235  bool inside(const Vector2& lposition) const {
236  return true;
237  std::vector<BinningData>::const_iterator bdIter = m_binningData.begin();
238  for (; bdIter != m_binningData.end(); ++bdIter) {
239  if (!(*bdIter).inside(lposition)) {
240  return false;
241  }
242  }
243  return true;
244  }
245 
248  size_t dimensions() const { return m_binningData.size(); }
249 
255  size_t max(size_t ba = 0) const {
256  if (ba >= m_binningData.size()) {
257  return 0;
258  }
259  return (m_binningData[ba].bins() - 1);
260  }
261 
267  size_t bins(size_t ba) const {
268  if (ba >= m_binningData.size()) {
269  return 1;
270  }
271  return (m_binningData[ba].bins());
272  }
273 
277  const Transform3& transform() const { return m_transform; }
278 
284  BinningValue binningValue(size_t ba = 0) const {
285  if (ba >= m_binningData.size()) {
286  throw "dimension out of bounds";
287  }
288  return (m_binningData[ba].binvalue);
289  }
290 
295  size_t serialize(const std::array<size_t, 3>& bin) const {
296  size_t serializedBin = bin[0];
297  if (m_binningData.size() == 2) {
298  serializedBin += bin[1] * m_binningData[0].bins();
299  } else if (m_binningData.size() == 3) {
300  serializedBin +=
301  (bin[1] * m_binningData[0].bins() * bin[2] * m_binningData[1].bins());
302  }
303  return serializedBin;
304  }
305 
312  std::ostream& toStream(std::ostream& sl,
313  const std::string& indent = "") const {
314  sl << indent << "BinUtility for " << m_binningData.size()
315  << "- dimensional array:" << std::endl;
316  for (auto [ibd, bd] : enumerate(m_binningData)) {
317  sl << indent << "dimension : " << ibd << std::endl;
318  sl << bd.toString(indent) << std::endl;
319  }
320  return sl;
321  }
322 
328  std::string toString(const std::string& indent = "") const {
329  std::stringstream ss;
330  toStream(ss, indent);
331  return ss.str();
332  }
333 
334  private:
335  std::vector<BinningData> m_binningData;
338 };
339 
341 std::ostream& operator<<(std::ostream& sl, const BinUtility& bgen);
342 
343 } // namespace Acts