Belle II Software  release-05-01-25
ESign.h
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2014 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Oliver Frost *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 #pragma once
11 
12 #include <algorithm>
13 #include <cstdlib> // for abs
14 #include <cmath> // for isnan
15 #include <climits> // for SHRT_MIN
16 
17 namespace Belle2 {
23  namespace TrackFindingCDC {
24 
26  namespace ESignUtil {
27 
29  enum ESign : signed short {
31  c_Plus = 1,
32 
34  c_Minus = -1,
35 
37  c_Zero = 0,
38 
40  c_Invalid = SHRT_MIN,
41  };
42 
44  inline ESign opposite(ESign s)
45  { return static_cast<ESign>(-s); }
46 
48  inline bool isValid(ESign s)
49  { return std::abs(s) <= 1; }
50 
59  static inline ESign common(ESign n1, ESign n2)
60  {
61  return ((not isValid(n1) and not isValid(n2)) ?
62  ESign::c_Invalid :
63  static_cast<ESign>((not(n1 <= 0) and not(n2 <= 0)) - (not(n1 >= 0) and not(n2 >= 0))));
64  }
65 
74  static inline ESign common(float n1, float n2)
75  {
76  return ((std::isnan(n1) and std::isnan(n2)) ?
77  ESign::c_Invalid :
78  static_cast<ESign>((not(n1 <= 0) and not(n2 <= 0)) - (not(n1 >= 0) and not(n2 >= 0))));
79  }
80 
89  static inline ESign common(float n1, float n2, float n3, float n4)
90  {
91  return ((std::isnan(n1) and std::isnan(n2) and std::isnan(n3) and std::isnan(n4)) ?
92  ESign::c_Invalid :
93  static_cast<ESign>((not(n1 <= 0) and not(n2 <= 0) and not(n3 <= 0) and not(n4 <= 0)) -
94  (not(n1 >= 0) and not(n2 >= 0) and not(n3 >= 0) and not(n4 >= 0))));
95  }
96 
105  template<class FloatRange>
106  static inline ESign common(const FloatRange& as)
107  {
108  bool allNaN = std::all_of(as.begin(), as.end(), [](float a) { return std::isnan(a); });
109  if (allNaN) {
110  return ESign::c_Invalid;
111  } else {
112  return static_cast<ESign>(std::all_of(as.begin(), as.end(), [](float a) { return not(a <= 0); }) -
113  std::all_of(as.begin(), as.end(), [](float a) { return not(a >= 0); }));
114  }
115  }
116 
117  };
118 
120  using ESign = ESignUtil::ESign;
121 
128  inline ESign sign(double x)
129  {
130  return std::isnan(x) ? ESign::c_Invalid : (std::signbit(x) ? ESign::c_Minus : ESign::c_Plus);
131  }
132 
134  inline ESign sign(int x)
135  {
136  return static_cast<ESign>((x > 0) - (x < 0));
137  }
138 
140  template<class Enum, Enum invalid = Enum::c_Invalid>
141  inline ESign sign(Enum x)
142  {
143  if (x == Enum::c_Invalid) return ESign::c_Invalid;
144  return sign(static_cast<int>(x));
145  }
146  }
147 
149 }
Belle2::TrackFindingCDC::ESignUtil::common
static ESign common(ESign n1, ESign n2)
Check if two values have a common sign.
Definition: ESign.h:67
Belle2::TrackFindingCDC::ESignUtil::c_Minus
@ c_Minus
Constant for minus sign.
Definition: ESign.h:42
Belle2::TrackFindingCDC::ESignUtil::c_Zero
@ c_Zero
Constant for undefined sign.
Definition: ESign.h:45
Belle2::TrackFindingCDC::ESignUtil::ESign
ESign
Enumeration for the distinct sign values of floating point variables.
Definition: ESign.h:37
Belle2::TrackFindingCDC::ESignUtil::isValid
bool isValid(ESign s)
Returns true if sign is ESign::c_Plus, ESign::c_Minus or ESign::c_Zero.
Definition: ESign.h:56
Belle2::TrackFindingCDC::ESignUtil::c_Invalid
@ c_Invalid
Constant for invalid sign, e.g. the sign of NAN.
Definition: ESign.h:48
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::TrackFindingCDC::ESignUtil::opposite
ESign opposite(ESign s)
Return the opposite sign. Leaves ESign::c_Invalid the same.
Definition: ESign.h:52
Belle2::TrackFindingCDC::ESignUtil::c_Plus
@ c_Plus
Constant for plus sign.
Definition: ESign.h:39