Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RooHelpers.cxx
Go to the documentation of this file.
1 // Author: Stephan Hageboeck, CERN 01/2019
2 
3 /*****************************************************************************
4  * RooFit
5  * Authors: *
6  * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7  * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8  * *
9  * Copyright (c) 2000-2019, Regents of the University of California *
10  * and Stanford University. All rights reserved. *
11  * *
12  * Redistribution and use in source and binary forms, *
13  * with or without modification, are permitted according to the terms *
14  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15  *****************************************************************************/
16 
17 #include "RooHelpers.h"
18 #include "RooAbsRealLValue.h"
19 
20 namespace RooHelpers {
21 
22 /// Tokenise the string by splitting at the characters in delims.
23 /// Consecutive delimiters are collapsed, so that no delimiters will appear in the
24 /// tokenised strings, and no emtpy strings are returned.
25 std::vector<std::string> tokenise(const std::string &str, const std::string &delims) {
26  std::vector<std::string> tokens;
27 
28  auto beg = str.find_first_not_of(delims, 0);
29  auto end = str.find_first_of(delims, beg);
30  do {
31  tokens.emplace_back(str.substr(beg, end-beg));
32  beg = str.find_first_not_of(delims, end);
33  end = str.find_first_of(delims, beg);
34  } while (beg != std::string::npos);
35 
36  return tokens;
37 }
38 
39 
40 
41 HijackMessageStream::HijackMessageStream(RooFit::MsgLevel level, RooFit::MsgTopic topics, const char* objectName) :
42  std::ostringstream()
43 {
44  auto& msg = RooMsgService::instance();
45  _oldKillBelow = msg.globalKillBelow();
46  msg.setGlobalKillBelow(level);
47  for (int i = 0; i < msg.numStreams(); ++i) {
48  _oldConf.push_back(msg.getStream(i));
49  msg.getStream(i).removeTopic(topics);
50  msg.setStreamStatus(i, true);
51  }
52 
53  _thisStream = msg.addStream(level,
54  RooFit::Topic(topics),
55  RooFit::OutputStream(*this),
56  objectName ? RooFit::ObjectName(objectName) : RooCmdArg());
57 }
58 
59 HijackMessageStream::~HijackMessageStream() {
60  auto& msg = RooMsgService::instance();
61  msg.setGlobalKillBelow(_oldKillBelow);
62  for (unsigned int i = 0; i < _oldConf.size(); ++i) {
63  msg.getStream(i) = _oldConf[i];
64  }
65  msg.deleteStream(_thisStream);
66 }
67 
68 
69 /// \param[in] callingClass Class that's calling. Needed to include name and type name of the class in error message.
70 /// \param[in] pars List of all parameters to be checked.
71 /// \param[in] min Minimum of allowed range. `min` itself counts as disallowed.
72 /// \param[in] max Maximum of allowed range. `max` itself counts as disallowed.
73 /// \param[in] limitsInAllowedRange If true, the limits passed as parameters are part of the allowed range.
74 /// \param[in] extraMessage Message that should be appended to the warning.
75 void checkRangeOfParameters(const RooAbsReal* callingClass, std::initializer_list<const RooAbsReal*> pars,
76  double min, double max, bool limitsInAllowedRange, std::string extraMessage) {
77  const char openBr = limitsInAllowedRange ? '[' : '(';
78  const char closeBr = limitsInAllowedRange ? ']' : ')';
79 
80  for (auto parameter : pars) {
81  auto par = dynamic_cast<const RooAbsRealLValue*>(parameter);
82  if (par && (
83  (par->getMin() < min || par->getMax() > max)
84  || (!limitsInAllowedRange && (par->getMin() == min || par->getMax() == max)) )) {
85  std::stringstream rangeMsg;
86  rangeMsg << openBr;
87  if (min > -std::numeric_limits<double>::max())
88  rangeMsg << min << ", ";
89  else
90  rangeMsg << "-inf, ";
91 
92  if (max < std::numeric_limits<double>::max())
93  rangeMsg << max << closeBr;
94  else
95  rangeMsg << "inf" << closeBr;
96 
97  oocoutW(callingClass, InputArguments) << "The parameter '" << par->GetName() << "' with range [" << par->getMin("") << ", "
98  << par->getMax() << "] of the " << callingClass->IsA()->GetName() << " '" << callingClass->GetName()
99  << "' exceeds the safe range of " << rangeMsg.str() << ". Advise to limit its range."
100  << (!extraMessage.empty() ? "\n" : "") << extraMessage << std::endl;
101  }
102  }
103 }
104 
105 }