CMS 3D CMS Logo

Utilities.h
Go to the documentation of this file.
1 #ifndef CondFormats_JetMETObjects_Utilities_h
2 #define CondFormats_JetMETObjects_Utilities_h
3 
4 #ifdef STANDALONE
5 #include <stdexcept>
6 #else
8 #endif
9 
10 #include <cstdlib>
11 #include <sstream>
12 #include <string>
13 #include <vector>
14 #include <tuple>
15 #include <cmath>
16 #include <utility>
17 
18 namespace std
19 {
20  //These functions print a tuple using a provided std::ostream
21  template<typename Type, unsigned N, unsigned Last>
22  struct tuple_printer {
23 
24  static void print(std::ostream& out, const Type& value) {
25  out << std::get<N>(value) << ", ";
27  }
28  };
29  template<typename Type, unsigned N>
30  struct tuple_printer<Type, N, N> {
31 
32  static void print(std::ostream& out, const Type& value) {
33  out << std::get<N>(value);
34  }
35 
36  };
37  template<typename... Types>
38  std::ostream& operator<<(std::ostream& out, const std::tuple<Types...>& value) {
39  out << "(";
40  tuple_printer<std::tuple<Types...>, 0, sizeof...(Types) - 1>::print(out, value);
41  out << ")";
42  return out;
43  }
44  //----------------------------------------------------------------------
45  //Returns a list of type indices
46  template <size_t... n>
48  template <size_t m>
49  struct push_back
50  {
51  typedef ct_integers_list<n..., m> type;
52  };
53  };
54  template <size_t max>
55  struct ct_iota_1
56  {
58  };
59  template <>
60  struct ct_iota_1<0>
61  {
63  };
64  //----------------------------------------------------------------------
65  //Return a tuple which is a subset of the original tuple
66  //This function pops an entry off the font of the tuple
67  template <size_t... indices, typename Tuple>
69  -> decltype(std::make_tuple(std::get<indices>(tpl)...))
70  {
71  return std::make_tuple(std::get<indices>(tpl)...);
72  // this means:
73  // make_tuple(get<indices[0]>(tpl), get<indices[1]>(tpl), ...)
74  }
75  template <typename Head, typename... Tail>
76  std::tuple<Tail...> tuple_tail(const std::tuple<Head, Tail...>& tpl)
77  {
78  return tuple_subset(tpl, typename ct_iota_1<sizeof...(Tail)>::type());
79  // this means:
80  // tuple_subset<1, 2, 3, ..., sizeof...(Tail)-1>(tpl, ..)
81  }
82  //----------------------------------------------------------------------
83  //Recursive hashing function for tuples
84  template<typename Head, typename... ndims> struct hash_specialization
85  {
86  typedef std::tuple<Head,ndims...> argument_type;
87  typedef std::size_t result_type;
88  result_type operator()(const argument_type& t) const
89  {
90  const uint32_t& b = reinterpret_cast<const uint32_t&>(std::get<0>(t));
91  //const uint32_t& more = (*this)(tuple_tail(t));
92  const uint32_t& more = hash_specialization<ndims...>()(tuple_tail(t));
93  return b^more;
94  }
95  };
96  //Base case
97  template<> struct hash_specialization<float>
98  {
99  typedef std::tuple<float> argument_type;
100  typedef std::size_t result_type;
101  result_type operator()(const argument_type& t) const
102  {
103  const uint32_t& b = reinterpret_cast<const uint32_t&>(std::get<0>(t));
104  return static_cast<result_type>(b);
105  }
106  };
107  //Overloaded verions of std::hash for tuples
108  template<typename Head, typename... ndims> struct hash<std::tuple<Head, ndims...> >
109  {
110  typedef std::tuple<Head,ndims...> argument_type;
111  typedef std::size_t result_type;
112  result_type operator()(const argument_type& t) const
113  {
114  return hash_specialization<Head,ndims...>()(t);
115  }
116  };
117  template<> struct hash<std::tuple<> >
118  {
119  typedef std::tuple<> argument_type;
120  typedef std::size_t result_type;
121  result_type operator()(const argument_type& t) const
122  {
123  return -1;
124  }
125  };
126 }
127 
128 namespace
129 {
130  void handleError(const std::string& fClass, const std::string& fMessage)
131  {
132 #ifdef STANDALONE
133  std::stringstream sserr;
134  sserr<<fClass<<" ERROR: "<<fMessage;
135  throw std::runtime_error(sserr.str());
136 #else
137  edm::LogError(fClass) << fMessage;
138 #endif
139  }
140  //----------------------------------------------------------------------
141  inline float getFloat(const std::string& token)
142  {
143  char* endptr;
144  float result = strtod (token.c_str(), &endptr);
145  if (endptr == token.c_str())
146  {
147  std::stringstream sserr;
148  sserr<<"can't convert token "<<token<<" to float value";
149  handleError("getFloat",sserr.str());
150  }
151  return result;
152  }
153  //----------------------------------------------------------------------
154  inline unsigned getUnsigned(const std::string& token)
155  {
156  char* endptr;
157  unsigned result = strtoul (token.c_str(), &endptr, 0);
158  if (endptr == token.c_str())
159  {
160  std::stringstream sserr;
161  sserr<<"can't convert token "<<token<<" to unsigned value";
162  handleError("getUnsigned",sserr.str());
163  }
164  return result;
165  }
166  inline long int getSigned(const std::string& token)
167  {
168  char* endptr;
169  unsigned result = strtol (token.c_str(), &endptr, 0);
170  if (endptr == token.c_str())
171  {
172  std::stringstream sserr;
173  sserr<<"can't convert token "<<token<<" to signed value";
174  handleError("getSigned",sserr.str());
175  }
176  return result;
177  }
178  //----------------------------------------------------------------------
179  inline std::string getSection(const std::string& token)
180  {
181  size_t iFirst = token.find ('[');
182  size_t iLast = token.find (']');
183  if (iFirst != std::string::npos && iLast != std::string::npos && iFirst < iLast)
184  return std::string (token, iFirst+1, iLast-iFirst-1);
185  return "";
186  }
187  //----------------------------------------------------------------------
188  inline std::vector<std::string> getTokens(const std::string& fLine)
189  {
190  std::vector<std::string> tokens;
191  std::string currentToken;
192  for (unsigned ipos = 0; ipos < fLine.length (); ++ipos)
193  {
194  char c = fLine[ipos];
195  if (c == '#') break; // ignore comments
196  else if (c == ' ')
197  { // flush current token if any
198  if (!currentToken.empty())
199  {
200  tokens.push_back(currentToken);
201  currentToken.clear();
202  }
203  }
204  else
205  currentToken += c;
206  }
207  if (!currentToken.empty()) tokens.push_back(currentToken); // flush end
208  return tokens;
209  }
210  //----------------------------------------------------------------------
211  inline std::string getDefinitions(const std::string& token)
212  {
213  size_t iFirst = token.find ('{');
214  size_t iLast = token.find ('}');
215  if (iFirst != std::string::npos && iLast != std::string::npos && iFirst < iLast)
216  return std::string (token, iFirst+1, iLast-iFirst-1);
217  return "";
218  }
219  //------------------------------------------------------------------------
220  inline float quadraticInterpolation(float fZ, const float fX[3], const float fY[3])
221  {
222  // Quadratic interpolation through the points (x[i],y[i]). First find the parabola that
223  // is defined by the points and then calculate the y(z).
224  float D[4],a[3];
225  D[0] = fX[0]*fX[1]*(fX[0]-fX[1])+fX[1]*fX[2]*(fX[1]-fX[2])+fX[2]*fX[0]*(fX[2]-fX[0]);
226  D[3] = fY[0]*(fX[1]-fX[2])+fY[1]*(fX[2]-fX[0])+fY[2]*(fX[0]-fX[1]);
227  D[2] = fY[0]*(pow(fX[2],2)-pow(fX[1],2))+fY[1]*(pow(fX[0],2)-pow(fX[2],2))+fY[2]*(pow(fX[1],2)-pow(fX[0],2));
228  D[1] = fY[0]*fX[1]*fX[2]*(fX[1]-fX[2])+fY[1]*fX[0]*fX[2]*(fX[2]-fX[0])+fY[2]*fX[0]*fX[1]*(fX[0]-fX[1]);
229  if (D[0] != 0)
230  {
231  a[0] = D[1]/D[0];
232  a[1] = D[2]/D[0];
233  a[2] = D[3]/D[0];
234  }
235  else
236  {
237  a[0] = 0.0;
238  a[1] = 0.0;
239  a[2] = 0.0;
240  }
241  float r = a[0]+fZ*(a[1]+fZ*a[2]);
242  return r;
243  }
244  //------------------------------------------------------------------------
245  //Generates a std::tuple type based on a stored type and the number of
246  // objects in the tuple.
247  //Note: All of the objects will be of the same type
248  template<typename /*LEFT_TUPLE*/, typename /*RIGHT_TUPLE*/>
249  struct join_tuples
250  {
251  };
252  template<typename... LEFT, typename... RIGHT>
253  struct join_tuples<std::tuple<LEFT...>, std::tuple<RIGHT...>>
254  {
255  typedef std::tuple<LEFT..., RIGHT...> type;
256  };
257  template<typename T, unsigned N>
258  struct generate_tuple_type
259  {
260  typedef typename generate_tuple_type<T, N/2>::type left;
261  typedef typename generate_tuple_type<T, N/2 + N%2>::type right;
262  typedef typename join_tuples<left, right>::type type;
263  };
264  template<typename T>
265  struct generate_tuple_type<T, 1>
266  {
267  typedef std::tuple<T> type;
268  };
269  template<typename T>
270  struct generate_tuple_type<T, 0>
271  {
272  typedef std::tuple<> type;
273  };
274  //------------------------------------------------------------------------
275  //C++11 implementation of make_index_sequence, which is a C++14 function
276  // using aliases for cleaner syntax
277  template<class T> using Invoke = typename T::type;
278 
279  template<unsigned...> struct seq{ using type = seq; };
280 
281  template<class S1, class S2> struct concat;
282 
283  template<unsigned... I1, unsigned... I2>
284  struct concat<seq<I1...>, seq<I2...>>
285  : seq<I1..., (sizeof...(I1)+I2)...>{};
286 
287  template<class S1, class S2>
288  using Concat = Invoke<concat<S1, S2>>;
289 
290  template<unsigned N> struct gen_seq;
291  template<unsigned N> using GenSeq = Invoke<gen_seq<N>>;
292 
293  template<unsigned N>
294  struct gen_seq : Concat<GenSeq<N/2>, GenSeq<N - N/2>>{};
295 
296  template<> struct gen_seq<0> : seq<>{};
297  template<> struct gen_seq<1> : seq<0>{};
298  //------------------------------------------------------------------------
299  //Generates a tuple based on a given function (i.e. lambda expression)
300  template <typename F, unsigned... Is>
301  auto gen_tuple_impl(F func, seq<Is...> )
302  -> decltype(std::make_tuple(func(Is)...))
303  {
304  return std::make_tuple(func(Is)...);
305  }
306  template <unsigned N, typename F>
307  auto gen_tuple(F func)
308  -> decltype(gen_tuple_impl(func, GenSeq<N>() ))
309  {
310  return gen_tuple_impl(func, GenSeq<N>() );
311  }
312 }
313 #endif
type
Definition: HCALResponse.h:21
std::tuple< Head, ndims... > argument_type
Definition: Utilities.h:86
uint32_t hash(HcalTrigTowerDetId const &)
Definition: Utilities.cc:50
std::tuple< Tail... > tuple_tail(const std::tuple< Head, Tail... > &tpl)
Definition: Utilities.h:76
auto tuple_subset(const Tuple &tpl, ct_integers_list< indices... >) -> decltype(std::make_tuple(std::get< indices >(tpl)...))
Definition: Utilities.h:68
ct_iota_1< max-1 >::type::template push_back< max >::type type
Definition: Utilities.h:57
result_type operator()(const argument_type &t) const
Definition: Utilities.h:101
result_type operator()(const argument_type &t) const
Definition: Utilities.h:112
static void print(std::ostream &out, const Type &value)
Definition: Utilities.h:32
std::tuple< Head, ndims... > argument_type
Definition: Utilities.h:110
def template(fileName, svg, replaceme="REPLACEME")
Definition: svgfig.py:521
Definition: Types.py:1
Definition: value.py:1
std::ostream & operator<<(std::ostream &out, const std::tuple< Types... > &value)
Definition: Utilities.h:38
std::tuple< float > argument_type
Definition: Utilities.h:99
def getSection(rootNode, name)
#define N
Definition: blowfish.cc:9
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:152
std::size_t result_type
Definition: Utilities.h:87
double b
Definition: hdecay.h:120
ct_integers_list type
Definition: Utilities.h:62
result_type operator()(const argument_type &t) const
Definition: Utilities.h:88
static void print(std::ostream &out, const Type &value)
Definition: Utilities.h:24
double a
Definition: hdecay.h:121
result_type operator()(const argument_type &t) const
Definition: Utilities.h:121
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
long double T
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
ct_integers_list< n..., m > type
Definition: Utilities.h:51