EIC 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
13 
14 #include <array>
15 #include <iostream>
16 #include <memory>
17 #include <vector>
18 
19 namespace Acts {
20 
31 class BinUtility {
32  public:
35  : m_binningData(),
36  m_transform(Transform3D::Identity()),
37  m_itransform(Transform3D::Identity()) {
38  m_binningData.reserve(3);
39  }
40 
44  BinUtility(const Transform3D& tForm)
45  : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) {
46  m_binningData.reserve(3);
47  }
48 
53  BinUtility(const BinningData& bData,
54  const Transform3D& tForm = Transform3D::Identity())
55  : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) {
56  m_binningData.reserve(3);
57  m_binningData.push_back(bData);
58  }
59 
68  BinUtility(size_t bins, float min, float max, BinningOption opt = open,
70  const Transform3D& tForm = Transform3D::Identity())
71  : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) {
72  m_binningData.reserve(3);
73  m_binningData.push_back(BinningData(opt, value, bins, min, max));
74  }
75 
82  BinUtility(std::vector<float>& bValues, BinningOption opt = open,
84  const Transform3D& tForm = Transform3D::Identity())
85  : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) {
86  m_binningData.reserve(3);
87  m_binningData.push_back(BinningData(opt, value, bValues));
88  }
89 
93  BinUtility(const BinUtility& sbu)
97 
102  if (this != &sbu) {
104  m_transform = sbu.m_transform;
106  }
107  return (*this);
108  }
109 
114  const std::vector<BinningData>& bData = gbu.binningData();
115 
117  m_itransform = m_transform.inverse();
118  if (m_binningData.size() + bData.size() > 3) {
119  throw "BinUtility does not support dim > 3";
120  }
121  m_binningData.insert(m_binningData.end(), bData.begin(), bData.end());
122  return (*this);
123  }
124 
126  ~BinUtility() = default;
127 
129  const std::vector<BinningData>& binningData() const { return m_binningData; }
130 
132  size_t bins() const { return bins(0) * bins(1) * bins(2); }
133 
141  std::array<size_t, 3> binTriple(const Vector3D& position) const {
143  const Vector3D bPosition = m_itransform * position;
144  // get the dimension
145  size_t mdim = m_binningData.size();
147  size_t bin0 = m_binningData[0].searchGlobal(bPosition);
148  size_t bin1 = mdim > 1 ? m_binningData[1].searchGlobal(bPosition) : 0;
149  size_t bin2 = mdim > 2 ? m_binningData[2].searchGlobal(bPosition) : 0;
151  return {{bin0, bin1, bin2}};
152  }
153 
160  size_t bin(const Vector3D& position, size_t ba = 0) const {
161  if (ba >= m_binningData.size()) {
162  return 0;
163  }
164  size_t bEval = m_binningData[ba].searchGlobal(m_itransform * position);
165  return bEval;
166  }
167 
178  std::vector<size_t> neighbourRange(const Vector3D& position,
179  size_t ba = 0) const {
180  if (ba >= m_binningData.size()) {
181  return {0};
182  }
183  std::vector<size_t> neighbourRange;
184  size_t cbin = bin(position, ba);
185  size_t pbin = cbin;
186  size_t nbin = cbin;
187  if (m_binningData[ba].decrement(pbin)) {
188  neighbourRange.push_back(pbin);
189  }
190  neighbourRange.push_back(cbin);
191  if (m_binningData[ba].increment(nbin) && nbin != pbin) {
192  neighbourRange.push_back(nbin);
193  }
194  return neighbourRange;
195  }
196 
206  int nextDirection(const Vector3D& position, const Vector3D& direction,
207  size_t ba = 0) const {
208  if (ba >= m_binningData.size()) {
209  return 0;
210  }
211  return m_binningData[ba].nextDirection(position, direction);
212  }
213 
225  size_t bin(const Vector2D& lposition, size_t ba = 0) const {
226  if (ba >= m_binningData.size()) {
227  return 0;
228  }
229  return m_binningData[ba].searchLocal(lposition);
230  }
235  bool inside(const Vector3D& position) const {
237  const Vector3D& bPosition = m_itransform * position;
238  // loop and break
239  for (auto& bData : m_binningData) {
240  if (!(bData.inside(bPosition))) {
241  return false;
242  }
243  }
244  // survived all the checks
245  return true;
246  }
247 
252  bool inside(const Vector2D& lposition) const {
253  return true;
254  std::vector<BinningData>::const_iterator bdIter = m_binningData.begin();
255  for (; bdIter != m_binningData.end(); ++bdIter) {
256  if (!(*bdIter).inside(lposition)) {
257  return false;
258  }
259  }
260  return true;
261  }
262 
265  size_t dimensions() const { return m_binningData.size(); }
266 
272  size_t max(size_t ba = 0) const {
273  if (ba >= m_binningData.size()) {
274  return 0;
275  }
276  return (m_binningData[ba].bins() - 1);
277  }
278 
284  size_t bins(size_t ba) const {
285  if (ba >= m_binningData.size()) {
286  return 1;
287  }
288  return (m_binningData[ba].bins());
289  }
290 
294  const Transform3D& transform() const { return m_transform; }
295 
301  BinningValue binningValue(size_t ba = 0) const {
302  if (ba >= m_binningData.size()) {
303  throw "dimension out of bounds";
304  }
305  return (m_binningData[ba].binvalue);
306  }
307 
312  size_t serialize(const std::array<size_t, 3>& bin) const {
313  size_t serializedBin = bin[0];
314  if (m_binningData.size() == 2) {
315  serializedBin += bin[1] * m_binningData[0].bins();
316  } else if (m_binningData.size() == 3) {
317  serializedBin +=
318  (bin[1] * m_binningData[0].bins() * bin[2] * m_binningData[1].bins());
319  }
320  return serializedBin;
321  }
322 
326  std::ostream& toStream(std::ostream& sl) const {
327  sl << "BinUtility for " << m_binningData.size()
328  << "- dimensional array:" << std::endl;
329  std::vector<BinningData>::const_iterator bdIter = m_binningData.begin();
330  for (size_t ibd = 0; bdIter != m_binningData.end(); ++bdIter, ++ibd) {
331  sl << "dimension : " << ibd << std::endl;
332  sl << " - type : " << size_t((*bdIter).type) << std::endl;
333  sl << " - option : " << size_t((*bdIter).option) << std::endl;
334  sl << " - value : " << size_t((*bdIter).binvalue) << std::endl;
335  sl << " - bins : " << (*bdIter).bins() << std::endl;
336  sl << " - min/max : " << (*bdIter).min << " / " << (*bdIter).max
337  << std::endl;
338  if ((*bdIter).type == equidistant) {
339  sl << " - step : " << (*bdIter).step << std::endl;
340  }
341  sl << " - boundaries : | ";
342  std::vector<float>::const_iterator bIter = (*bdIter).boundaries().begin();
343  for (; bIter != (*bdIter).boundaries().end(); ++bIter) {
344  sl << (*bIter) << " | ";
345  }
346  sl << std::endl;
347  }
348  return sl;
349  }
350 
351  private:
352  std::vector<BinningData> m_binningData;
355 };
356 
358 std::ostream& operator<<(std::ostream& sl, const BinUtility& bgen);
359 
360 } // namespace Acts