rivet is hosted by Hepforge, IPPP Durham
Rivet 3.1.6
Utils.hh
1// -*- C++ -*-
2#ifndef RIVET_Utils_HH
3#define RIVET_Utils_HH
4
5#include "Rivet/Tools/RivetSTL.hh"
6#include "Rivet/Tools/PrettyPrint.hh"
7#include "Rivet/Tools/Exceptions.hh"
8#include <ostream>
9#include <cctype>
10#include <cerrno>
11#include <stdexcept>
12#include <numeric>
13#include <limits>
14#include <climits>
15#include <cfloat>
16#include <cmath>
17#include <sstream>
18#include <functional>
19
21
22
24#ifndef DEPRECATED
25#if __GNUC__ && __cplusplus && RIVET_NO_DEPRECATION_WARNINGS == 0
26#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
27#if GCC_VERSION >= 40500
28 #if __cplusplus > 201103L
29 #define DEPRECATED(x) [[deprecated(x)]]
30 #else
31 #define DEPRECATED(x) __attribute__((deprecated(x)))
32 #endif
33#else
34 #define DEPRECATED(x) __attribute__((deprecated))
35#endif
36#else
37 #define DEPRECATED(x)
38#endif
39#endif
40
41
42namespace Rivet {
43
44
46 static constexpr double DBL_NAN = std::numeric_limits<double>::quiet_NaN();
47
48
51
53 struct bad_lexical_cast : public std::runtime_error {
54 bad_lexical_cast(const std::string& what) : std::runtime_error(what) {}
55 };
56
58 template<typename T, typename U>
59 T lexical_cast(const U& in) {
60 try {
61 std::stringstream ss;
62 ss << in;
63 T out;
64 ss >> out;
65 return out;
66 } catch (const std::exception& e) {
67 throw bad_lexical_cast(e.what());
68 }
69 }
70
74 template <typename T>
75 inline string to_str(const T& x) {
76 return lexical_cast<string>(x);
77 }
78
82 template <typename T>
83 inline string toString(const T& x) {
84 return lexical_cast<string>(x);
85 }
86
88 inline string& replace_first(string& str, const string& patt, const string& repl) {
89 if (!contains(str, patt)) return str; //< contains from RivetSTL
90 str.replace(str.find(patt), patt.size(), repl);
91 return str;
92 }
93
99 inline string& replace_all(string& str, const string& patt, const string& repl) {
100 if (!contains(str, patt)) return str; //< contains from RivetSTL
101 while (true) {
102 string::size_type it = str.find(patt);
103 if (it == string::npos) break;
104 str.replace(it, patt.size(), repl);
105 }
106 return str;
107 }
108
109
111 inline int nocase_cmp(const string& s1, const string& s2) {
112 string::const_iterator it1 = s1.begin();
113 string::const_iterator it2 = s2.begin();
114 while ( (it1 != s1.end()) && (it2 != s2.end()) ) {
115 if(::toupper(*it1) != ::toupper(*it2)) { // < Letters differ?
116 // Return -1 to indicate smaller than, 1 otherwise
117 return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1;
118 }
119 // Proceed to the next character in each string
120 ++it1;
121 ++it2;
122 }
123 size_t size1 = s1.size(), size2 = s2.size(); // Cache lengths
124 // Return -1,0 or 1 according to strings' lengths
125 if (size1 == size2) return 0;
126 return (size1 < size2) ? -1 : 1;
127 }
128
129
131 inline bool nocase_equals(const string& s1, const string& s2) {
132 return nocase_cmp(s1, s2) == 0;
133 }
134
135
137 inline string toLower(const string& s) {
138 string out = s;
139 std::transform(out.begin(), out.end(), out.begin(), (int(*)(int)) std::tolower);
140 return out;
141 }
142
143
145 inline string toUpper(const string& s) {
146 string out = s;
147 std::transform(out.begin(), out.end(), out.begin(), (int(*)(int)) std::toupper);
148 return out;
149 }
150
151
153 inline bool startsWith(const string& s, const string& start) {
154 if (s.length() < start.length()) return false;
155 return s.substr(0, start.length()) == start;
156 }
157
158
160 inline bool endsWith(const string& s, const string& end) {
161 if (s.length() < end.length()) return false;
162 return s.substr(s.length() - end.length()) == end;
163 }
164
165
166 // Terminating version of strjoin, for empty fargs list
167 inline string strcat() { return ""; }
169 template<typename T, typename... Ts>
170 inline string strcat(T value, Ts... fargs) {
171 const string strthis = lexical_cast<string>(value);
172 const string strnext = strcat(fargs...);
173 return strnext.empty() ? strthis : strthis + strnext;
174 }
175
176
178 template <typename T>
179 inline string join(const vector<T>& v, const string& sep=" ") {
180 string rtn;
181 for (size_t i = 0; i < v.size(); ++i) {
182 if (i != 0) rtn += sep;
183 rtn += to_str(v[i]);
184 }
185 return rtn;
186 }
187
189 template <>
190 inline string join(const vector<string>& v, const string& sep) {
191 string rtn;
192 for (size_t i = 0; i < v.size(); ++i) {
193 if (i != 0) rtn += sep;
194 rtn += v[i];
195 }
196 return rtn;
197 }
198
200 template <typename T>
201 inline string join(const set<T>& s, const string& sep=" ") {
202 string rtn;
203 for (const T& x : s) {
204 if (rtn.size() > 0) rtn += sep;
205 rtn += to_str(x);
206 }
207 return rtn;
208 }
209
211 template <>
212 inline string join(const set<string>& s, const string& sep) {
213 string rtn;
214 for (const string & x : s) {
215 if (rtn.size() > 0) rtn += sep;
216 rtn += x;
217 }
218 return rtn;
219 }
220
222 inline vector<string> split(const string& s, const string& sep) {
223 vector<string> dirs;
224 string tmp = s;
225 while (true) {
226 const size_t delim_pos = tmp.find(sep);
227 if (delim_pos == string::npos) break;
228 const string dir = tmp.substr(0, delim_pos);
229 if (dir.length()) dirs.push_back(dir); // Don't insert "empties"
230 tmp.replace(0, delim_pos+1, "");
231 }
232 if (tmp.length()) dirs.push_back(tmp); // Don't forget the trailing component!
233 return dirs;
234 }
235
237 inline string lpad(const string& s, size_t width, const string& padchar=" ") {
238 if (s.size() >= width) return s;
239 return string(width - s.size(), padchar[0]) + s;
240 }
241
243 inline string rpad(const string& s, size_t width, const string& padchar=" ") {
244 if (s.size() >= width) return s;
245 return s + string(width - s.size(), padchar[0]);
246 }
247
249
250
251
254
258 inline vector<string> pathsplit(const string& path) {
259 return split(path, ":");
260 }
261
266 inline string pathjoin(const vector<string>& paths) {
267 return join(paths, ":");
268 }
269
271 inline string operator / (const string& a, const string& b) {
272 // Ensure that a doesn't end with a slash, and b doesn't start with one, to avoid "//"
273 const string anorm = (a.find("/") != string::npos) ? a.substr(0, a.find_last_not_of("/")+1) : a;
274 const string bnorm = (b.find("/") != string::npos) ? b.substr(b.find_first_not_of("/")) : b;
275 return anorm + "/" + bnorm;
276 }
277
279 inline string basename(const string& p) {
280 if (!contains(p, "/")) return p;
281 return p.substr(p.rfind("/")+1);
282 }
283
285 inline string dirname(const string& p) {
286 if (!contains(p, "/")) return "";
287 return p.substr(0, p.rfind("/"));
288 }
289
291 inline string file_stem(const string& f) {
292 if (!contains(f, ".")) return f;
293 return f.substr(0, f.rfind("."));
294 }
295
297 inline string file_extn(const string& f) {
298 if (!contains(f, ".")) return "";
299 return f.substr(f.rfind(".")+1);
300 }
301
303
304
305
308
310 template <typename CONTAINER>
311 inline unsigned int count(const CONTAINER& c) {
312 // return std::count_if(std::begin(c), std::end(c), [](const typename CONTAINER::value_type& x){return bool(x);});
313 unsigned int rtn = 0;
314 for (const auto& x : c) if (bool(x)) rtn += 1;
315 return rtn;
316 }
317
318 // /// Return number of elements in the container @a c for which @c f(x) is true.
319 // template <typename CONTAINER>
320 // inline unsigned int count(const CONTAINER& c, const std::function<bool(typename CONTAINER::value_type)>& f) {
321 // return std::count_if(std::begin(c), std::end(c), f);
322 // }
323
325 template <typename CONTAINER, typename FN>
326 inline unsigned int count(const CONTAINER& c, const FN& f) {
327 return std::count_if(std::begin(c), std::end(c), f);
328 }
329
330
331
333 template <typename CONTAINER>
334 inline bool any(const CONTAINER& c) {
335 // return std::any_of(std::begin(c), std::end(c), [](const auto& x){return bool(x);});
336 for (const auto& x : c) if (bool(x)) return true;
337 return false;
338 }
339
340 // /// Return true if f(x) is true for any x in container c, otherwise false.
341 // template <typename CONTAINER>
342 // inline bool any(const CONTAINER& c, const std::function<bool(typename CONTAINER::value_type)>& f) {
343 // return std::any_of(std::begin(c), std::end(c), f);
344 // }
345
347 template <typename CONTAINER, typename FN>
348 inline bool any(const CONTAINER& c, const FN& f) {
349 return std::any_of(std::begin(c), std::end(c), f);
350 }
351
352
353
355 template <typename CONTAINER>
356 inline bool all(const CONTAINER& c) {
357 // return std::all_of(std::begin(c), std::end(c), [](const auto& x){return bool(x);});
358 for (const auto& x : c) if (!bool(x)) return false;
359 return true;
360 }
361
362 // /// Return true if @a f(x) is true for all @c x in container @a c, otherwise false.
363 // template <typename CONTAINER>
364 // inline bool all(const CONTAINER& c, const std::function<bool(typename CONTAINER::value_type)>& f) {
365 // return std::all_of(std::begin(c), std::end(c), f);
366 // }
367
369 template <typename CONTAINER, typename FN>
370 inline bool all(const CONTAINER& c, const FN& f) {
371 return std::all_of(std::begin(c), std::end(c), f);
372 }
373
374
375
377 template <typename CONTAINER>
378 inline bool none(const CONTAINER& c) {
379 // return std::none_of(std::begin(c), std::end(c), [](){});
380 for (const auto& x : c) if (bool(x)) return false;
381 return true;
382 }
383
384 // /// Return true if @a f(x) is false for all @c x in container @a c, otherwise false.
385 // template <typename C>
386 // inline bool none(const C& c, const std::function<bool(typename C::value_type)>& f) {
387 // return std::none_of(std::begin(c), std::end(c), f);
388 // }
389
391 template <typename CONTAINER, typename FN>
392 inline bool none(const CONTAINER& c, const FN& f) {
393 return std::none_of(std::begin(c), std::end(c), f);
394 }
395
396
397 // /// A single-container-arg version of std::transform, aka @c map
398 // template <typename CONTAINER1, typename CONTAINER2>
399 // inline const CONTAINER2& transform(const CONTAINER1& in, CONTAINER2& out,
400 // const std::function<typename CONTAINER2::value_type(typename CONTAINER1::value_type)>& f) {
401 // out.clear(); out.resize(in.size());
402 // std::transform(in.begin(), in.end(), out.begin(), f);
403 // return out;
404 // }
405
407 template <typename CONTAINER1, typename CONTAINER2, typename FN>
408 inline const CONTAINER2& transform(const CONTAINER1& in, CONTAINER2& out, const FN& f) {
409 out.clear(); out.resize(in.size());
410 std::transform(in.begin(), in.end(), out.begin(), f);
411 return out;
412 }
413
416 template <typename CONTAINER1, typename T2>
417 inline std::vector<T2> transform(const CONTAINER1& in, const std::function<T2(typename CONTAINER1::value_type)>& f) {
418 std::vector<T2> out(in.size());
419 transform(in, out, f);
420 return out;
421 }
422
423
424
425 // /// A single-container-arg version of std::accumulate, aka @c reduce
426 // template <typename CONTAINER1, typename T>
427 // inline T accumulate(const CONTAINER1& in, const T& init, const std::function<T(typename CONTAINER1::value_type)>& f) {
428 // const T rtn = std::accumulate(in.begin(), in.end(), init, f);
429 // return rtn;
430 // }
431
433 template <typename CONTAINER1, typename T, typename FN>
434 inline T accumulate(const CONTAINER1& in, const T& init, const FN& f) {
435 const T rtn = std::accumulate(in.begin(), in.end(), init, f);
436 return rtn;
437 }
438
439
440
444 template <typename CONTAINER>
445 inline typename CONTAINER::value_type sum(const CONTAINER& c) {
446 typename CONTAINER::value_type rtn; //< default construct return type
447 for (const auto& x : c) rtn += x;
448 return rtn;
449 }
450
454 template <typename CONTAINER, typename T>
455 inline T sum(const CONTAINER& c, const T& start) {
456 T rtn = start;
457 for (const auto& x : c) rtn += x;
458 return rtn;
459 }
460
462 template <typename CONTAINER, typename FN, typename T>
463 inline T sum(const CONTAINER& c, const FN& f, const T& start=T()) {
464 T rtn = start;
465 for (const auto& x : c) rtn += f(x);
466 return rtn;
467 }
468
469
470
474 template <typename CONTAINER, typename T>
475 inline T& isum(const CONTAINER& c, T& out) {
476 for (const auto& x : c) out += x;
477 return out;
478 }
479
483 template <typename CONTAINER, typename FN, typename T>
484 inline T& isum(const CONTAINER& c, const FN& f, T& out) {
485 for (const auto& x : c) out += f(x);
486 return out;
487 }
488
489
490
493 template <typename CONTAINER, typename FN>
494 inline CONTAINER& ifilter_discard(CONTAINER& c, const FN& f) {
495 const auto newend = std::remove_if(std::begin(c), std::end(c), f);
496 c.erase(newend, c.end());
497 return c;
498 }
500 template <typename CONTAINER, typename FN>
501 inline CONTAINER& idiscard(CONTAINER& c, const FN& f) {
502 return ifilter_discard(c, f);
503 }
504
505
508 template <typename CONTAINER, typename FN>
509 inline CONTAINER filter_discard(const CONTAINER& c, const FN& f) {
510 CONTAINER rtn = c;
511 return ifilter_discard(rtn, f);
512 }
514 template <typename CONTAINER, typename FN>
515 inline CONTAINER& discard(CONTAINER& c, const FN& f) {
516 return filter_discard(c, f);
517 }
518
522 template <typename CONTAINER, typename FN>
523 inline CONTAINER& filter_discard(const CONTAINER& c, const FN& f, CONTAINER& out) {
524 out = filter_discard(c, f);
525 return out;
526 }
528 template <typename CONTAINER, typename FN>
529 inline CONTAINER& discard(CONTAINER& c, const FN& f, CONTAINER& out) {
530 return filter_discard(c, f, out);
531 }
532
533
534
537 template <typename CONTAINER, typename FN>
538 inline CONTAINER& ifilter_select(CONTAINER& c, const FN& f) {
539 //using value_type = typename std::remove_reference<decltype(*std::begin(std::declval<typename std::add_lvalue_reference<CONTAINER>::type>()))>::type;
540 auto invf = [&](const typename CONTAINER::value_type& x){ return !f(x); };
541 return ifilter_discard(c, invf);
542 }
544 template <typename CONTAINER, typename FN>
545 inline CONTAINER& iselect(CONTAINER& c, const FN& f) {
546 return ifilter_select(c, f);
547 }
548
551 template <typename CONTAINER, typename FN>
552 inline CONTAINER filter_select(const CONTAINER& c, const FN& f) {
553 CONTAINER rtn = c;
554 return ifilter_select(rtn, f);
555 }
557 template <typename CONTAINER, typename FN>
558 inline CONTAINER select(const CONTAINER& c, const FN& f) {
559 return filter_select(c, f);
560 }
561
565 template <typename CONTAINER, typename FN>
566 inline CONTAINER& filter_select(const CONTAINER& c, const FN& f, CONTAINER& out) {
567 out = filter_select(c, f);
568 return out;
569 }
571 template <typename CONTAINER, typename FN>
572 inline CONTAINER& select(CONTAINER& c, const FN& f, CONTAINER& out) {
573 return filter_select(c, f, out);
574 }
575
576
577
582 template <typename CONTAINER>
583 inline CONTAINER slice(const CONTAINER& c, int i, int j) {
584 CONTAINER rtn;
585 const size_t off1 = (i >= 0) ? i : c.size() + i;
586 const size_t off2 = (j >= 0) ? j : c.size() + j;
587 if (off1 > c.size() || off2 > c.size()) throw RangeError("Attempting to slice beyond requested offsets");
588 if (off2 < off1) throw RangeError("Requested offsets in invalid order");
589 rtn.resize(off2 - off1);
590 std::copy(c.begin()+off1, c.begin()+off2, rtn.begin());
591 return rtn;
592 }
593
597 template <typename CONTAINER>
598 inline CONTAINER slice(const CONTAINER& c, int i) {
599 return slice(c, i, c.size());
600 }
601
605 template <typename CONTAINER>
606 inline CONTAINER head(const CONTAINER& c, int n) {
607 // if (n > c.size()) throw RangeError("Requested head longer than container");
608 if (n < 0) n = std::max(0, (int)c.size()+n);
609 n = std::min(n, (int)c.size());
610 return slice(c, 0, n);
611 }
612
616 template <typename CONTAINER>
617 inline CONTAINER tail(const CONTAINER& c, int n) {
618 // if (n > c.size()) throw RangeError("Requested tail longer than container");
619 if (n < 0) n = std::max(0, (int)c.size()+n);
620 n = std::min(n, (int)c.size());
621 return slice(c, c.size()-n);
622 }
623
624
625 using std::min;
626 using std::max;
627
629 inline double min(const vector<double>& in, double errval=DBL_NAN) {
630 const auto e = std::min_element(in.begin(), in.end());
631 return e != in.end() ? *e : errval;
632 }
633
635 inline double max(const vector<double>& in, double errval=DBL_NAN) {
636 const auto e = std::max_element(in.begin(), in.end());
637 return e != in.end() ? *e : errval;
638 }
639
641 inline pair<double,double> minmax(const vector<double>& in, double errval=DBL_NAN) {
642 const auto e = std::minmax_element(in.begin(), in.end());
643 const double rtnmin = e.first != in.end() ? *e.first : errval;
644 const double rtnmax = e.second != in.end() ? *e.first : errval;
645 return std::make_pair(rtnmin, rtnmax);
646 }
647
648
650 inline int min(const vector<int>& in, int errval=-1) {
651 const auto e = std::min_element(in.begin(), in.end());
652 return e != in.end() ? *e : errval;
653 }
654
656 inline int max(const vector<int>& in, int errval=-1) {
657 const auto e = std::max_element(in.begin(), in.end());
658 return e != in.end() ? *e : errval;
659 }
660
662 inline pair<int,int> minmax(const vector<int>& in, int errval=-1) {
663 const auto e = std::minmax_element(in.begin(), in.end());
664 const double rtnmin = e.first != in.end() ? *e.first : errval;
665 const double rtnmax = e.second != in.end() ? *e.first : errval;
666 return std::make_pair(rtnmin, rtnmax);
667 }
668
670
671
677 template <typename T>
678 T getEnvParam(const std::string name, const T& fallback) {
679 char* env = getenv(name.c_str());
680 return env ? lexical_cast<T>(env) : fallback;
681 }
682
683
684}
685
686#endif
int max(const vector< int > &in, int errval=-1)
Find the maximum value in the vector.
Definition: Utils.hh:656
bool all(const CONTAINER &c)
Return true if x is true for all x in container c, otherwise false.
Definition: Utils.hh:356
int min(const vector< int > &in, int errval=-1)
Find the minimum value in the vector.
Definition: Utils.hh:650
T & isum(const CONTAINER &c, T &out)
Definition: Utils.hh:475
pair< double, double > minmax(const vector< double > &in, double errval=DBL_NAN)
Find the minimum and maximum values in the vector.
Definition: Utils.hh:641
CONTAINER head(const CONTAINER &c, int n)
Head slice of the n first container elements.
Definition: Utils.hh:606
CONTAINER slice(const CONTAINER &c, int i, int j)
Slice of the container elements cf. Python's [i:j] syntax.
Definition: Utils.hh:583
CONTAINER::value_type sum(const CONTAINER &c)
Generic sum function, adding x for all x in container c.
Definition: Utils.hh:445
bool none(const CONTAINER &c)
Return true if x is false for all x in container c, otherwise false.
Definition: Utils.hh:378
std::vector< T2 > transform(const CONTAINER1 &in, const std::function< T2(typename CONTAINER1::value_type)> &f)
Definition: Utils.hh:417
CONTAINER tail(const CONTAINER &c, int n)
Tail slice of the n last container elements.
Definition: Utils.hh:617
unsigned int count(const CONTAINER &c)
Return number of true elements in the container c .
Definition: Utils.hh:311
T accumulate(const CONTAINER1 &in, const T &init, const FN &f)
A single-container-arg version of std::accumulate, aka reduce.
Definition: Utils.hh:434
bool any(const CONTAINER &c)
Return true if x is true for any x in container c, otherwise false.
Definition: Utils.hh:334
Jets & idiscard(Jets &jets, const Cut &c)
New alias for ifilter_discard.
Definition: JetUtils.hh:184
Jets select(const Jets &jets, const Cut &c)
New alias for filter_select.
Definition: JetUtils.hh:165
Jets & iselect(Jets &jets, const Cut &c)
New alias for ifilter_select.
Definition: JetUtils.hh:153
Jets filter_discard(const Jets &jets, const Cut &c)
Filter a jet collection in-place to the subset that fails the supplied Cut.
Definition: JetUtils.hh:188
Jets discard(const Jets &jets, const Cut &c)
New alias for filter_discard.
Definition: JetUtils.hh:193
Jets filter_select(const Jets &jets, const Cut &c)
Filter a jet collection in-place to the subset that passes the supplied Cut.
Definition: JetUtils.hh:157
Jets & ifilter_select(Jets &jets, const Cut &c)
Filter a jet collection in-place to the subset that passes the supplied Cut.
Jets & ifilter_discard(Jets &jets, const Cut &c)
Filter a jet collection in-place to the subset that fails the supplied Cut.
double p(const ParticleBase &p)
Unbound function access to p.
Definition: ParticleBaseUtils.hh:653
string dirname(const string &p)
Get the dirname (i.e. path to the penultimate directory) from a path p.
Definition: Utils.hh:285
string file_extn(const string &f)
Get the file extension from a filename f.
Definition: Utils.hh:297
string pathjoin(const vector< string > &paths)
Join several filesystem paths together with the standard ':' delimiter.
Definition: Utils.hh:266
vector< string > pathsplit(const string &path)
Split a path string with colon delimiters.
Definition: Utils.hh:258
string basename(const string &p)
Get the basename (i.e. terminal file name) from a path p.
Definition: Utils.hh:279
string file_stem(const string &f)
Get the stem (i.e. part without a file extension) from a filename f.
Definition: Utils.hh:291
bool endsWith(const string &s, const string &end)
Check whether a string end is found at the end of s.
Definition: Utils.hh:160
bool nocase_equals(const string &s1, const string &s2)
Case-insensitive string equality function.
Definition: Utils.hh:131
bool startsWith(const string &s, const string &start)
Check whether a string start is found at the start of s.
Definition: Utils.hh:153
string toUpper(const string &s)
Convert a string to upper-case.
Definition: Utils.hh:145
string rpad(const string &s, size_t width, const string &padchar=" ")
Right-pad the given string s to width width.
Definition: Utils.hh:243
string to_str(const T &x)
Convert any object to a string.
Definition: Utils.hh:75
string lpad(const string &s, size_t width, const string &padchar=" ")
Left-pad the given string s to width width.
Definition: Utils.hh:237
string toLower(const string &s)
Convert a string to lower-case.
Definition: Utils.hh:137
T lexical_cast(const U &in)
Convert between any types via stringstream.
Definition: Utils.hh:59
vector< string > split(const string &s, const string &sep)
Split a string on a specified separator string.
Definition: Utils.hh:222
string & replace_all(string &str, const string &patt, const string &repl)
Replace all instances of patt with repl.
Definition: Utils.hh:99
string join(const vector< T > &v, const string &sep=" ")
Make a string containing the string representations of each item in v, separated by sep.
Definition: Utils.hh:179
string & replace_first(string &str, const string &patt, const string &repl)
Replace the first instance of patt with repl.
Definition: Utils.hh:88
int nocase_cmp(const string &s1, const string &s2)
Case-insensitive string comparison function.
Definition: Utils.hh:111
T getEnvParam(const std::string name, const T &fallback)
Get a parameter from a named environment variable, with automatic type conversion.
Definition: Utils.hh:678
Definition: MC_Cent_pPb.hh:10
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value, typenamestd::common_type< N1, N2 >::type >::type max(N1 a, N2 b)
Get the maximum of two numbers.
Definition: MathUtils.hh:111
std::enable_if< std::is_arithmetic< N1 >::value &&std::is_arithmetic< N2 >::value, typenamestd::common_type< N1, N2 >::type >::type min(N1 a, N2 b)
Get the minimum of two numbers.
Definition: MathUtils.hh:102
static constexpr double DBL_NAN
Convenient const for getting the double NaN value.
Definition: Utils.hh:46
bool contains(const std::string &s, const std::string &sub)
Does s contain sub as a substring?
Definition: RivetSTL.hh:93
std::string toString(const AnalysisInfo &ai)
String representation.
Error for e.g. use of invalid bin ranges.
Definition: Exceptions.hh:22
Exception class for throwing from lexical_cast when a parse goes wrong.
Definition: Utils.hh:53