Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooHelpers.cxx
Go to the documentation of this file.
1/*
2 * Project: RooFit
3 * Author:
4 * Stephan Hageboeck, CERN 2019
5 *
6 * Copyright (c) 2023, CERN
7 *
8 * Redistribution and use in source and binary forms,
9 * with or without modification, are permitted according to the terms
10 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
11 */
12
13#include <RooHelpers.h>
14
15#include <RooAbsCategory.h>
16#include <RooAbsData.h>
17#include <RooAbsPdf.h>
18#include <RooAbsRealLValue.h>
19#include <RooArgList.h>
20#include <RooCategory.h>
21#include <RooDataHist.h>
22#include <RooDataSet.h>
23#include <RooMultiPdf.h>
24#include <RooProdPdf.h>
25#include <RooRealSumPdf.h>
26#include <RooRealVar.h>
27#include <RooSimultaneous.h>
28
29#include <ROOT/StringUtils.hxx>
30#include <TClass.h>
31
32#include <algorithm>
33#include <cmath>
34#include <unordered_map>
35
36namespace RooHelpers {
37
40{
42 fOldKillBelow = msg.globalKillBelow();
44 msg.setGlobalKillBelow(lvl);
45
46 for (int i = 0; i < msg.numStreams(); ++i) {
47 fOldConf.push_back(msg.getStream(i));
49 msg.getStream(i).minLevel = lvl;
50 msg.getStream(i).removeTopic(static_cast<RooFit::MsgTopic>(removeTopics));
51 msg.setStreamStatus(i, true);
52 }
53
54 if (extraTopics != 0) {
55 fExtraStream = msg.addStream(lvl);
56 msg.getStream(fExtraStream).addTopic(static_cast<RooFit::MsgTopic>(extraTopics));
57 }
58}
59
61{
63 msg.setGlobalKillBelow(fOldKillBelow);
64 for (int i = 0; i < msg.numStreams(); ++i) {
65 if (i < static_cast<int>(fOldConf.size()))
66 msg.getStream(i) = fOldConf[i];
67 }
68
69 if (fExtraStream > 0)
70 msg.deleteStream(fExtraStream);
71}
72
73/// Hijack all messages with given level and topics while this object is alive.
74/// \param[in] level Minimum level to hijack. Higher levels also get captured.
75/// \param[in] topics Topics to hijack. Use `|` to combine different topics, and cast to `RooFit::MsgTopic` if
76/// necessary. \param[in] objectName Only hijack messages from an object with the given name. Defaults to any object.
78{
80 _oldKillBelow = msg.globalKillBelow();
81 if (_oldKillBelow > level)
82 msg.setGlobalKillBelow(level);
83
84 std::vector<RooMsgService::StreamConfig> tmpStreams;
85 for (int i = 0; i < msg.numStreams(); ++i) {
86 _oldConf.push_back(msg.getStream(i));
87 if (msg.getStream(i).match(level, topics, static_cast<RooAbsArg *>(nullptr))) {
88 tmpStreams.push_back(msg.getStream(i));
89 msg.setStreamStatus(i, false);
90 }
91 }
92
94 objectName ? RooFit::ObjectName(objectName) : RooCmdArg());
95
97 msg.addStream(st.minLevel, RooFit::Topic(st.topic), RooFit::OutputStream(*st.os),
98 RooFit::ObjectName(st.objectName.c_str()), RooFit::ClassName(st.className.c_str()),
99 RooFit::BaseClassName(st.baseClassName.c_str()), RooFit::TagName(st.tagName.c_str()));
100 }
101}
102
103/// Deregister the hijacked stream and restore the stream state of all previous streams.
105{
107 msg.setGlobalKillBelow(_oldKillBelow);
108 for (unsigned int i = 0; i < _oldConf.size(); ++i) {
109 msg.getStream(i) = _oldConf[i];
110 }
111
112 while (_thisStream < msg.numStreams()) {
113 msg.deleteStream(_thisStream);
114 }
115}
116
117/// \param[in] callingClass Class that's calling. Needed to include name and type name of the class in error message.
118/// \param[in] pars List of all parameters to be checked.
119/// \param[in] min Minimum of allowed range. `min` itself counts as disallowed.
120/// \param[in] max Maximum of allowed range. `max` itself counts as disallowed.
121/// \param[in] limitsInAllowedRange If true, the limits passed as parameters are part of the allowed range.
122/// \param[in] extraMessage Message that should be appended to the warning.
123void checkRangeOfParameters(const RooAbsReal *callingClass, std::initializer_list<const RooAbsReal *> pars, double min,
124 double max, bool limitsInAllowedRange, std::string const &extraMessage)
125{
126 const char openBr = limitsInAllowedRange ? '[' : '(';
127 const char closeBr = limitsInAllowedRange ? ']' : ')';
128
129 for (auto parameter : pars) {
130 auto par = dynamic_cast<const RooAbsRealLValue *>(parameter);
131 if (par && ((par->getMin() < min || par->getMax() > max) ||
132 (!limitsInAllowedRange && (par->getMin() == min || par->getMax() == max)))) {
133 std::stringstream rangeMsg;
134 rangeMsg << openBr;
135 if (min > -std::numeric_limits<double>::max()) {
136 rangeMsg << min << ", ";
137 } else {
138 rangeMsg << "-inf, ";
139 }
140
141 if (max < std::numeric_limits<double>::max()) {
142 rangeMsg << max << closeBr;
143 } else {
144 rangeMsg << "inf" << closeBr;
145 }
146
147 oocoutW(callingClass, InputArguments)
148 << "The parameter '" << par->GetName() << "' with range [" << par->getMin("") << ", " << par->getMax()
149 << "] of the " << callingClass->ClassName() << " '" << callingClass->GetName()
150 << "' exceeds the safe range of " << rangeMsg.str() << ". Advise to limit its range."
151 << (!extraMessage.empty() ? "\n" : "") << extraMessage << std::endl;
152 }
153 }
154}
155
157{
158 bool changed = false;
159 for (RooAbsArg *a : coll) {
160 RooRealVar *v = dynamic_cast<RooRealVar *>(a);
161 RooCategory *cv = dynamic_cast<RooCategory *>(a);
162 if (v && (v->isConstant() != constant)) {
163 changed = true;
164 v->setConstant(constant);
165 } else if (cv && (cv->isConstant() != constant)) {
166 changed = true;
167 cv->setConstant(constant);
168 }
169 }
170 return changed;
171}
172
173bool isFunctionFlatInBins(const RooAbsReal &function, RooAbsRealLValue &obs, std::span<const double> boundaries,
174 double relTol)
175{
176 // Fractions of the bin width at which the function is sampled. They are kept
177 // strictly inside the bin (away from the boundaries) so that the evaluation
178 // is not affected by which side of a boundary a step function jumps.
179 const double fractions[] = {0.04, 0.27, 0.5, 0.73, 0.96};
180
181 const double savedVal = obs.getVal();
182
183 bool isFlat = true;
184 for (std::size_t i = 0; i + 1 < boundaries.size() && isFlat; ++i) {
185 const double lo = boundaries[i];
186 const double hi = boundaries[i + 1];
187 double reference = 0.0;
188 bool first = true;
189 for (double frac : fractions) {
190 obs.setVal(lo + frac * (hi - lo));
191 const double val = function.getVal();
192 if (first) {
193 reference = val;
194 first = false;
195 continue;
196 }
197 const double scale = std::max(std::abs(reference), 1e-12);
198 if (std::abs(val - reference) > relTol * scale) {
199 isFlat = false;
200 break;
201 }
202 }
203 }
204
205 obs.setVal(savedVal);
206 return isFlat;
207}
208
209std::list<double> *binBoundariesInRange(std::span<const double> boundaries, double xlo, double xhi)
210{
211 auto out = new std::list<double>;
212
213 // Small tolerance so that boundaries numerically coinciding with the range
214 // limits are not duplicated by the explicit xlo/xhi endpoints below.
215 const double delta = (xhi - xlo) * 1e-8;
216
217 for (double boundary : boundaries) {
218 if (boundary > xlo + delta && boundary < xhi - delta) {
219 out->push_back(boundary);
220 }
221 }
222
223 out->push_front(xlo);
224 out->push_back(xhi);
225
226 return out;
227}
228
229} // namespace RooHelpers
#define a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
#define oocoutW(o, a)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define hi
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:76
Abstract container object that can hold multiple RooAbsArg objects.
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
virtual void setVal(double value)=0
Set the current value of the object. Needs to be overridden by implementations.
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:63
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:107
Object to represent discrete states.
Definition RooCategory.h:28
Named container for two doubles, two integers two object points and three string pointers that can be...
Definition RooCmdArg.h:26
RooFit::MsgLevel _oldKillBelow
Definition RooHelpers.h:84
HijackMessageStream(RooFit::MsgLevel level, RooFit::MsgTopic topics, const char *objectName=nullptr)
Hijack all messages with given level and topics while this object is alive.
std::vector< RooMsgService::StreamConfig > _oldConf
Definition RooHelpers.h:85
~HijackMessageStream()
Deregister the hijacked stream and restore the stream state of all previous streams.
RooFit::MsgLevel fOldKillBelow
Definition RooHelpers.h:54
LocalChangeMsgLevel(RooFit::MsgLevel lvl=RooFit::DEBUG, unsigned int extraTopics=0u, unsigned int removeTopics=0u, bool overrideExternalLevel=true)
Change message level (and topics) while this object is alive, reset when it goes out of scope.
std::vector< RooMsgService::StreamConfig > fOldConf
Definition RooHelpers.h:55
static RooMsgService & instance()
Return reference to singleton instance.
Variable that can be changed from the outside.
Definition RooRealVar.h:37
TCanvas * fractions()
Definition fractions.C:1
RooCmdArg ClassName(const char *name)
RooCmdArg OutputStream(std::ostream &os)
RooCmdArg Topic(Int_t topic)
RooCmdArg TagName(const char *name)
RooCmdArg BaseClassName(const char *name)
RooCmdArg ObjectName(const char *name)
MsgLevel
Verbosity level for RooMsgService::StreamConfig in RooMsgService.
MsgTopic
Topics for a RooMsgService::StreamConfig in RooMsgService.
void checkRangeOfParameters(const RooAbsReal *callingClass, std::initializer_list< const RooAbsReal * > pars, double min=-std::numeric_limits< double >::max(), double max=std::numeric_limits< double >::max(), bool limitsInAllowedRange=false, std::string const &extraMessage="")
Check if the parameters have a range, and warn if the range extends below / above the set limits.
bool isFunctionFlatInBins(const RooAbsReal &function, RooAbsRealLValue &obs, std::span< const double > boundaries, double relTol=1e-9)
Check that function is constant (flat) inside each bin defined by the sorted boundaries when scanning...
std::list< double > * binBoundariesInRange(std::span< const double > boundaries, double xlo, double xhi)
Return a newly allocated list with the subset of boundaries that lies strictly inside [xlo,...
bool setAllConstant(const RooAbsCollection &coll, bool constant=true)
set all RooRealVars to constants. return true if at least one changed status