ATLAS Offline Software
BinningData.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // BinningData.h, (c) ATLAS Detector software
8 
9 #ifndef TRKDETDESCRUTILS_BINNINGDATA_H
10 #define TRKDETDESCRUTILS_BINNINGDATA_H
11 
12 // Gaudi
13 #include "GaudiKernel/GaudiException.h"
14 // Eigen
17 
18 #include <cmath>
19 
20 #include <utility>
21 #include <vector>
22 
23 class MsgStream;
24 
25 namespace Trk {
26 
31 {
32  previous = -1,
33  next = 1
34 };
35 
47 {
48 public:
53  size_t bins;
54  float min;
55  float max;
56  float step;
57  float subStep;
58  float refphi; // ref Phi for binH
59  std::vector<float> boundaries;
60  std::vector<std::pair<int, float>> hbounds; // boundary for binH
61 
62  /* Default ctor,copy,move assignment,dtor*/
63  BinningData(const BinningData&) = default;
64  BinningData(BinningData&&) = default;
65  BinningData& operator=(const BinningData&) = default;
67  ~BinningData() = default;
68 
71  BinningOption bOption,
72  BinningValue bValue,
73  size_t bBins,
74  float bMin,
75  float bMax,
76  float bStep,
77  float bSubStep = 0,
78  std::vector<float> bBoundaries = std::vector<float>())
79  : type(bType)
80  , option(bOption)
81  , binvalue(bValue)
82  , bins(bBins)
83  , min(bMin)
84  , max(bMax)
85  , step(bStep != 0. ? bStep : 1.)
86  , subStep(bSubStep)
87  , refphi(0.)
88  , boundaries(std::move(bBoundaries))
89  , hbounds(std::vector<std::pair<int, float>>())
90  , m_mixPtr(nullptr)
91  {
92  if (bType == Trk::equidistant)
94  else if (bType == Trk::biequidistant)
96  else
98  }
99 
102  float bRefPhi,
103  const std::vector<std::pair<int, float>>& bBoundaries)
104  : type(Trk::arbitrary)
105  , option(bOption)
106  , binvalue(Trk::binH)
107  , bins(bOption == Trk::open ? bBoundaries.size() - 1 : bBoundaries.size())
108  , min(bBoundaries.front().second)
109  , max(bBoundaries.back().second)
110  , step(1.)
111  , subStep(0.) // non-zero value needed for next()
112  , refphi(bRefPhi)
113  , boundaries(std::vector<float>())
114  , hbounds(bBoundaries)
115  , m_functionPtr(nullptr)
117  {}
118 
120  float value(const Amg::Vector2D& lposition) const
121  {
122  // ordered after occurence
124  return lposition[0];
125  if (binvalue == Trk::binPhi)
126  return gaugePhi(lposition[1]);
127  return lposition[1];
128  }
129 
131  float value(const Amg::Vector3D& position) const
132  {
133  // ordered after occurence
134  if (binvalue == Trk::binR || binvalue == Trk::binH)
135  return (position.perp());
136  if (binvalue == Trk::binRPhi)
137  return (position.perp() * position.phi());
138  if (binvalue == Trk::binEta)
139  return (position.eta());
140  if (binvalue < 3)
141  return (position[binvalue]);
142  // phi gauging
143  return gaugePhi(position.phi());
144  }
145 
147  float gaugePhi(float phi) const
148  {
149  if (max > M_PI && phi < min && phi < 0.) {
150  phi = M_PI + phi;
151  phi += M_PI;
152  }
153  return phi;
154  }
155 
157  std::pair<float, float> valueH(const Amg::Vector2D& lposition) const
158  {
159  return (std::pair<double, double>(lposition[0], lposition[0] * cos(fabs(refphi - lposition[1]))));
160  }
161 
163  std::pair<float, float> valueH(const Amg::Vector3D& position) const
164  {
165  return (std::pair<double, double>(position.perp(), position.perp() * cos(fabs(position.phi() - refphi))));
166  }
167 
169  bool inside(const Amg::Vector3D& position) const
170  {
171  // closed one is always inside
172  if (option == Trk::closed)
173  return true;
174  // all other options except value H
175  if (binvalue != Trk::binH) {
176  float val = value(position);
177  return (val > min - 0.001 && val < max + 0.001);
178  }
179  // value H case
180  std::pair<double, double> valH = valueH(position);
181  float valmin = hbounds.front().first == 0 ? valH.first : valH.second;
182  float valmax = hbounds.back().first == 0 ? valH.first : valH.second;
183  return (valmin > min - 0.001 && valmax < max + 0.001);
184  }
185 
187  bool inside(const Amg::Vector2D& lp) const
188  {
189  if (option == Trk::closed)
190  return true;
191  if (binvalue != Trk::binH) {
192  float val = value(lp);
193  return (val > min - 0.001 && val < max + 0.001);
194  }
195  std::pair<double, double> valH = valueH(lp);
196  float valmin = hbounds.front().first == 0 ? valH.first : valH.second;
197  float valmax = hbounds.back().first == 0 ? valH.first : valH.second;
198  return (valmin > min - 0.001 && valmax < max + 0.001);
199  }
200 
202  size_t searchLocal(const Amg::Vector2D& lposition) const
203  {
204  return (binvalue == Trk::binH) ? searchH(valueH(lposition)) : search(value(lposition));
205  }
206 
208  size_t searchGlobal(const Amg::Vector3D& position) const
209  {
210  return (binvalue == Trk::binH) ? searchH(valueH(position)) : search(value(position));
211  }
212 
214  size_t search(float value) const
215  {
216  assert(m_functionPtr != nullptr);
217  return (*m_functionPtr)(value, *this);
218  }
219 
221  size_t searchH(std::pair<double, double> value) const
222  {
223  assert(m_mixPtr != nullptr);
224  return (*m_mixPtr)(value, *this);
225  }
226 
228  size_t entry(const Amg::Vector3D& position) const
229  {
230  size_t bin = (binvalue == Trk::binH) ? searchH(valueH(position)) : search(value(position));
231  return (bin < bins - bin) ? bin : bins - 1;
232  }
233 
235  size_t next(const Amg::Vector3D& position, const Amg::Vector3D& dir) const
236  {
237  float val = value(position);
238  Amg::Vector3D probe = position + 0.5 * step * dir.normalized();
239  float nextval = value(probe);
240  int bin = (binvalue == Trk::binH) ? searchH(valueH(position)) : search(val);
241  bin = (nextval > val && bin != int(bins - 1)) ? bin + 1 : (bin) ? bin - 1 : 0;
242  // closed setup
243  if (option == closed)
244  return (bin < 0 || bin + 1 > int(bins)) ? ((bin < 0) ? bins - 1 : 0) : bin;
245  // open setup
246  return bin;
247  }
248 
250  std::pair<size_t, float> distanceToNext(const Amg::Vector3D& position, const Amg::Vector3D& dir) const
251  {
252  // current value
253  float val = (binvalue == Trk::binH) ? valueH(position).first : value(position);
254  // probe value
255  Amg::Vector3D probe = position + 0.5 * step * dir.normalized();
256  float nextval = (binvalue == Trk::binH) ? valueH(probe).first : value(probe);
257  // current bin
258  int bin0 = (binvalue == Trk::binH) ? searchH(valueH(position)) : search(val);
259  // next bin
260  int bin = (nextval - val) > 0. ? bin0 + 1 : bin0 - 1;
261  if (bin > int(bins) - 1)
262  bin = (option == closed) ? 0 : bin0;
263  if (bin < 0)
264  bin = (option == closed) ? bins - 1 : 0;
265 
266  // boundary value
267  float bval = 0.;
268  if (binvalue == Trk::binH) {
269  bval = (nextval > val) ? hbounds[bin0 + 1].second : hbounds[bin0].second; // non-equidistant
270 
271  // may need to recalculate current value and probe
272  if (nextval > val) {
273  if (hbounds[bin0 + 1].first > 0) {
274  val = valueH(position).second;
275  nextval = valueH(probe).second;
276  }
277  } else {
278  if (hbounds[bin0].first > 0) {
279  val = valueH(position).second;
280  nextval = valueH(probe).second;
281  }
282  }
283  } else {
284  bval = (nextval > val) ? boundaries[bin0 + 1] : boundaries[bin0]; // non-equidistant
285  if (type == Trk::equidistant)
286  bval = min + bin0 * step;
287  }
288  // differential
289  float dd = 2 * (nextval - val) / step;
290  // distance estimate
291  float dist = std::fabs(dd) > 1.e-06 ? (bval - val) / dd : 1.e06;
292  return std::pair<size_t, float>(bin, dist);
293  }
294 
296  LayerOrder orderDirection(const Amg::Vector3D& position, const Amg::Vector3D& dir) const
297  {
298  float val = (binvalue == Trk::binH) ? valueH(position).first : value(position);
299  Amg::Vector3D probe = position + 0.5 * step * dir.normalized();
300  float nextval = (binvalue == Trk::binH) ? valueH(probe).first : value(probe);
301  return (nextval > val) ? Trk::next : Trk::previous;
302  }
303 
305  float binPosition(size_t bin, float pos) const
306  {
307 
308  if (type == Trk::equidistant)
309  return (min + (2. * bin + pos + 1.) * step / 2.);
310 
311  float bmin = (binvalue == Trk::binH) ? hbounds[bin].second : boundaries[bin];
312  float bmax = (binvalue == Trk::binH) ? hbounds[bin + 1].second
313  : bin + 1 < boundaries.size() ? boundaries[bin + 1] : boundaries[bin] + step;
314 
315  return (bmin + 0.5 * (pos + 1.) * (bmax - bmin));
316  }
317 
318 private:
320  size_t (*m_functionPtr)(float, const BinningData&);
321  size_t (*m_mixPtr)(std::pair<float, float>, const BinningData&);
322 
324  static size_t searchEaquidstantWithBoundary(float value, const BinningData& bData)
325  {
326  int bin = ((value - bData.min) / bData.step);
327  // special treatment of the 0 bin for closed
328  if (bData.option == closed) {
329  if (value < bData.min)
330  return (bData.bins - 1);
331  if (value > bData.max)
332  return 0;
333  }
334  // if outside boundary : return boundary for open, opposite bin for closed
335  bin = bin < 0 ? ((bData.option == Trk::open) ? 0 : (bData.bins - 1)) : bin;
336  return size_t((bin <= int(bData.bins - 1)) ? bin : ((bData.option == open) ? (bData.bins - 1) : 0));
337  }
338 
340  static size_t searchBiequidistantWithBoundary(float value, const BinningData& bData)
341  {
342  // the easy exits (first / last)
343  if (value < bData.min)
344  return (bData.option == closed) ? (bData.bins - 1) : 0;
345  if (value > bData.max)
346  return (bData.option == closed) ? 0 : (bData.bins - 1);
347  // special treatment for first and last bin
348  if (value > bData.max - bData.step)
349  return bData.bins - 1;
350  // decide the leading bin number (low leading bin)
351  size_t leadbin = int((value - bData.min) / bData.step);
352  float bDist = value - (bData.min + (leadbin + 1) * bData.step);
353  int addon = int(bDist / bData.subStep) ? 0 : 1;
354  // return the bin
355  return leadbin * 2 + addon;
356  }
357 
359  static size_t searchInVectorWithBoundary(float value, const BinningData& bData)
360  {
361  if (bData.binvalue == binPhi)
362  while (value < bData.boundaries[0])
363  value += 2 * M_PI;
364  if (bData.binvalue == binPhi)
365  while (value > bData.max)
366  value -= 2 * M_PI;
367  // lower boundary
368  if (value <= bData.boundaries[0]) {
369  return (bData.option == closed) ? (bData.bins - 1) : 0;
370  }
371  // higher boundary
372  if (value >= bData.max)
373  return (bData.option == closed) ? 0 : (bData.bins - 1);
374  // search
375  std::vector<float>::const_iterator vIter = bData.boundaries.begin();
376  size_t bin = 0;
377  for (; vIter != bData.boundaries.end(); ++vIter, ++bin)
378  if ((*vIter) > value)
379  break;
380  return (bin - 1);
381  }
382 
384  static size_t binarySearchWithBoundary(float value, const BinningData& bData)
385  {
386  // Binary search in an array of n values to locate value
387  if (bData.binvalue == binPhi)
388  while (value < bData.boundaries[0])
389  value += 2 * acos(-1.);
390  if (bData.binvalue == binPhi)
391  while (value > bData.max)
392  value -= 2 * acos(-1.);
393  // underflow
394  if (value <= bData.boundaries[0])
395  return (bData.option == closed) ? (bData.bins - 1) : 0;
396  size_t nabove;
397  size_t nbelow;
398  size_t middle;
399  // overflow
400  nabove = bData.boundaries.size() + 1;
401  if (value >= bData.max)
402  return (bData.option == closed) ? 0 : nabove - 2;
403  // binary search
404  nbelow = 0;
405  while (nabove - nbelow > 1) {
406  middle = (nabove + nbelow) / 2;
407  if (value == bData.boundaries[middle - 1])
408  return middle - 1;
409  if (value < bData.boundaries[middle - 1])
410  nabove = middle;
411  else
412  nbelow = middle;
413  }
414  return nbelow - 1;
415  }
416 
418  static size_t searchInVectorWithMixedBoundary(std::pair<float, float> val, const BinningData& bData)
419  {
420  if ((bData.hbounds[0].first == 0 ? val.first : val.second) < bData.hbounds[0].second)
421  return (bData.option == closed) ? (bData.bins - 1) : 0;
422  if ((bData.hbounds.back().first == 0 ? val.first : val.second) >= bData.max)
423  return (bData.option == closed) ? 0 : (bData.bins - 1);
424 
425  if (bData.hbounds.size() < 10) {
426  std::vector<std::pair<int, float>>::const_iterator vBeg = bData.hbounds.begin();
427  std::vector<std::pair<int, float>>::const_iterator vIter = vBeg + 1;
428  for (; vIter != bData.hbounds.end(); ++vIter)
429  if ((*vIter).second > ((*vIter).first == 0 ? val.first : val.second))
430  break;
431  return (vIter != bData.hbounds.end() ? vIter - vBeg - 1 : bData.bins - 1);
432  }
433 
434  // Binary search in an array of n values to locate value
435  size_t nabove;
436  size_t nbelow;
437  size_t middle;
438  nabove = bData.hbounds.size();
439  // binary search
440  nbelow = 0;
441  while (nabove - nbelow > 1) {
442  middle = (nabove + nbelow) / 2;
443  float valm = bData.hbounds[middle].first == 0 ? val.first : val.second;
444  if (valm == bData.hbounds[middle].second) {
445  nbelow = middle;
446  break;
447  }
448  if (valm < bData.hbounds[middle].second)
449  nabove = middle;
450  else
451  nbelow = middle;
452  }
453 
454  if (nbelow > bData.bins - 1)
455  return bData.bins - 1;
456  return nbelow;
457  }
458 };
459 
460 }
461 
462 #endif
Trk::BinningData::type
BinningType type
holding all the data for binning calculatuion
Definition: BinningData.h:50
python.SystemOfUnits.second
int second
Definition: SystemOfUnits.py:120
Trk::BinningData::searchGlobal
size_t searchGlobal(const Amg::Vector3D &position) const
generic search from a 3D position
Definition: BinningData.h:208
Trk::LayerOrder
LayerOrder
Definition: BinningData.h:31
Trk::BinningData::BinningData
BinningData(BinningData &&)=default
Trk::equidistant
@ equidistant
Definition: BinningType.h:32
Trk::BinningData::binvalue
BinningValue binvalue
Definition: BinningData.h:52
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
Trk::BinningData::inside
bool inside(const Amg::Vector2D &lp) const
Check if bin is inside from Vector2D.
Definition: BinningData.h:187
Trk::binH
@ binH
Definition: BinningType.h:53
Trk::next
@ next
Definition: BinningData.h:33
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
Trk::BinningData::valueH
std::pair< float, float > valueH(const Amg::Vector3D &position) const
take float values for binH
Definition: BinningData.h:163
Trk::BinningData::~BinningData
~BinningData()=default
Trk::BinningData::refphi
float refphi
Definition: BinningData.h:58
Trk::BinningData::gaugePhi
float gaugePhi(float phi) const
gauge phi
Definition: BinningData.h:147
M_PI
#define M_PI
Definition: ActiveFraction.h:11
bin
Definition: BinsDiffFromStripMedian.h:43
Trk::BinningData::operator=
BinningData & operator=(BinningData &&)=default
BinningType.h
Trk::biequidistant
@ biequidistant
Definition: BinningType.h:33
Trk::closed
@ closed
Definition: BinningType.h:41
Trk::binEta
@ binEta
Definition: BinningType.h:54
Trk::BinningType
BinningType
Definition: BinningType.h:31
PlotCalibFromCool.valmax
valmax
Definition: PlotCalibFromCool.py:89
Trk::BinningData::searchInVectorWithMixedBoundary
static size_t searchInVectorWithMixedBoundary(std::pair< float, float > val, const BinningData &bData)
Search in mixed vector - linear in O-10 bins, otherwise binary.
Definition: BinningData.h:418
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
Trk::BinningData::next
size_t next(const Amg::Vector3D &position, const Amg::Vector3D &dir) const
the next bin : gives -1 if the next one is outside
Definition: BinningData.h:235
Trk::BinningData::step
float step
Definition: BinningData.h:56
Trk::BinningData::binarySearchWithBoundary
static size_t binarySearchWithBoundary(float value, const BinningData &bData)
A binary search with underflow/overflow - faster than vector search for O(50) objects.
Definition: BinningData.h:384
Trk::BinningData::inside
bool inside(const Amg::Vector3D &position) const
Check if bin is inside from Vector3D.
Definition: BinningData.h:169
Trk::BinningData::min
float min
Definition: BinningData.h:54
Trk::arbitrary
@ arbitrary
Definition: BinningType.h:34
PlotCalibFromCool.valmin
valmin
Definition: PlotCalibFromCool.py:88
Trk::BinningData::orderDirection
LayerOrder orderDirection(const Amg::Vector3D &position, const Amg::Vector3D &dir) const
layer order is needed for value H binning
Definition: BinningData.h:296
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
GeoPrimitives.h
Trk::BinningData::bins
size_t bins
Definition: BinningData.h:53
Trk::BinningValue
BinningValue
how to take the global / local position
Definition: BinningType.h:46
Trk::BinningData::entry
size_t entry(const Amg::Vector3D &position) const
the entry bin
Definition: BinningData.h:228
Trk::BinningData::searchInVectorWithBoundary
static size_t searchInVectorWithBoundary(float value, const BinningData &bData)
Linear search in vector - superior in O(10) searches: arbitraty 2.
Definition: BinningData.h:359
Trk::BinningData::searchH
size_t searchH(std::pair< double, double > value) const
generic search - forwards to correct function pointer
Definition: BinningData.h:221
Trk::BinningData::m_functionPtr
size_t(* m_functionPtr)(float, const BinningData &)
the pointer to the function to be used
Definition: BinningData.h:320
CheckAppliedSFs.bmin
bmin
Definition: CheckAppliedSFs.py:242
vector
Definition: MultiHisto.h:13
Trk::BinningData::valueH
std::pair< float, float > valueH(const Amg::Vector2D &lposition) const
take float values for binH
Definition: BinningData.h:157
Trk::BinningData::BinningData
BinningData(BinningOption bOption, float bRefPhi, const std::vector< std::pair< int, float >> &bBoundaries)
Constructor for binH type : non-equidistant binning assumed.
Definition: BinningData.h:101
Trk::binX
@ binX
Definition: BinningType.h:47
Trk::BinningData::boundaries
std::vector< float > boundaries
Definition: BinningData.h:59
Trk::BinningData::searchBiequidistantWithBoundary
static size_t searchBiequidistantWithBoundary(float value, const BinningData &bData)
Biequidistant search : biequidist 1.
Definition: BinningData.h:340
beamspotman.dir
string dir
Definition: beamspotman.py:623
Trk::BinningData::max
float max
Definition: BinningData.h:55
Trk::BinningData::hbounds
std::vector< std::pair< int, float > > hbounds
Definition: BinningData.h:60
Trk::BinningData::searchEaquidstantWithBoundary
static size_t searchEaquidstantWithBoundary(float value, const BinningData &bData)
Equidistant search : equidist 0.
Definition: BinningData.h:324
CheckAppliedSFs.bmax
bmax
Definition: CheckAppliedSFs.py:264
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
Trk::BinningData::search
size_t search(float value) const
generic search - forwards to correct function pointer
Definition: BinningData.h:214
plotBeamSpotVxVal.bin
int bin
Definition: plotBeamSpotVxVal.py:83
Trk::BinningData::BinningData
BinningData(const BinningData &)=default
Trk::BinningData::operator=
BinningData & operator=(const BinningData &)=default
Trk::BinningData::BinningData
BinningData(BinningType bType, BinningOption bOption, BinningValue bValue, size_t bBins, float bMin, float bMax, float bStep, float bSubStep=0, std::vector< float > bBoundaries=std::vector< float >())
Constructor with arguments.
Definition: BinningData.h:70
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
library_scraper.dd
list dd
Definition: library_scraper.py:46
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
Trk::open
@ open
Definition: BinningType.h:40
Trk::binR
@ binR
Definition: BinningType.h:50
Trk::binRPhi
@ binRPhi
Definition: BinningType.h:52
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
DeMoScan.first
bool first
Definition: DeMoScan.py:534
Trk::BinningData::subStep
float subStep
Definition: BinningData.h:57
Trk::BinningData::searchLocal
size_t searchLocal(const Amg::Vector2D &lposition) const
generic search from a 2D position — corresponds to local coordinate schema
Definition: BinningData.h:202
Trk::BinningData::m_mixPtr
size_t(* m_mixPtr)(std::pair< float, float >, const BinningData &)
Definition: BinningData.h:321
Trk::phi
@ phi
Definition: ParamDefs.h:81
Trk::BinningData::value
float value(const Amg::Vector3D &position) const
take the right float value
Definition: BinningData.h:131
Trk::BinningData
Definition: BinningData.h:47
Trk::BinningData::option
BinningOption option
Definition: BinningData.h:51
readCCLHist.float
float
Definition: readCCLHist.py:83
Trk::BinningData::value
float value(const Amg::Vector2D &lposition) const
take the right float value - assumes the correct local position expression
Definition: BinningData.h:120
Trk::BinningData::binPosition
float binPosition(size_t bin, float pos) const
bin->BinningValue navigation : pos=+-1.
Definition: BinningData.h:305
Trk::BinningData::distanceToNext
std::pair< size_t, float > distanceToNext(const Amg::Vector3D &position, const Amg::Vector3D &dir) const
distance to the next bin : gives -1 if the next one is outside
Definition: BinningData.h:250
Trk::BinningOption
BinningOption
enum BinValue
Definition: BinningType.h:39
Trk::previous
@ previous
Definition: BinningData.h:32
Trk::binPhi
@ binPhi
Definition: BinningType.h:51