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 <RooDataHist.h>
21#include <RooDataSet.h>
22#include <RooProdPdf.h>
23#include <RooRealSumPdf.h>
24#include <RooSimultaneous.h>
25
26#include <ROOT/StringUtils.hxx>
27#include <TClass.h>
28
29#include <unordered_map>
30
31namespace RooHelpers {
32
33LocalChangeMsgLevel::LocalChangeMsgLevel(RooFit::MsgLevel lvl, unsigned int extraTopics, unsigned int removeTopics,
34 bool overrideExternalLevel)
35{
36 auto &msg = RooMsgService::instance();
37 fOldKillBelow = msg.globalKillBelow();
38 if (overrideExternalLevel)
39 msg.setGlobalKillBelow(lvl);
40
41 for (int i = 0; i < msg.numStreams(); ++i) {
42 fOldConf.push_back(msg.getStream(i));
43 if (overrideExternalLevel)
44 msg.getStream(i).minLevel = lvl;
45 msg.getStream(i).removeTopic(static_cast<RooFit::MsgTopic>(removeTopics));
46 msg.setStreamStatus(i, true);
47 }
48
49 if (extraTopics != 0) {
50 fExtraStream = msg.addStream(lvl);
51 msg.getStream(fExtraStream).addTopic(static_cast<RooFit::MsgTopic>(extraTopics));
52 }
53}
54
56{
57 auto &msg = RooMsgService::instance();
58 msg.setGlobalKillBelow(fOldKillBelow);
59 for (int i = 0; i < msg.numStreams(); ++i) {
60 if (i < static_cast<int>(fOldConf.size()))
61 msg.getStream(i) = fOldConf[i];
62 }
63
64 if (fExtraStream > 0)
65 msg.deleteStream(fExtraStream);
66}
67
68/// Hijack all messages with given level and topics while this object is alive.
69/// \param[in] level Minimum level to hijack. Higher levels also get captured.
70/// \param[in] topics Topics to hijack. Use `|` to combine different topics, and cast to `RooFit::MsgTopic` if
71/// necessary. \param[in] objectName Only hijack messages from an object with the given name. Defaults to any object.
73{
74 auto &msg = RooMsgService::instance();
75 _oldKillBelow = msg.globalKillBelow();
76 if (_oldKillBelow > level)
77 msg.setGlobalKillBelow(level);
78
79 std::vector<RooMsgService::StreamConfig> tmpStreams;
80 for (int i = 0; i < msg.numStreams(); ++i) {
81 _oldConf.push_back(msg.getStream(i));
82 if (msg.getStream(i).match(level, topics, static_cast<RooAbsArg *>(nullptr))) {
83 tmpStreams.push_back(msg.getStream(i));
84 msg.setStreamStatus(i, false);
85 }
86 }
87
88 _thisStream = msg.addStream(level, RooFit::Topic(topics), RooFit::OutputStream(_str),
89 objectName ? RooFit::ObjectName(objectName) : RooCmdArg());
90
91 for (RooMsgService::StreamConfig &st : tmpStreams) {
92 msg.addStream(st.minLevel, RooFit::Topic(st.topic), RooFit::OutputStream(*st.os),
93 RooFit::ObjectName(st.objectName.c_str()), RooFit::ClassName(st.className.c_str()),
94 RooFit::BaseClassName(st.baseClassName.c_str()), RooFit::TagName(st.tagName.c_str()));
95 }
96}
97
98/// Deregister the hijacked stream and restore the stream state of all previous streams.
100{
101 auto &msg = RooMsgService::instance();
102 msg.setGlobalKillBelow(_oldKillBelow);
103 for (unsigned int i = 0; i < _oldConf.size(); ++i) {
104 msg.getStream(i) = _oldConf[i];
105 }
106
107 while (_thisStream < msg.numStreams()) {
108 msg.deleteStream(_thisStream);
109 }
110}
111
112/// \param[in] callingClass Class that's calling. Needed to include name and type name of the class in error message.
113/// \param[in] pars List of all parameters to be checked.
114/// \param[in] min Minimum of allowed range. `min` itself counts as disallowed.
115/// \param[in] max Maximum of allowed range. `max` itself counts as disallowed.
116/// \param[in] limitsInAllowedRange If true, the limits passed as parameters are part of the allowed range.
117/// \param[in] extraMessage Message that should be appended to the warning.
118void checkRangeOfParameters(const RooAbsReal *callingClass, std::initializer_list<const RooAbsReal *> pars, double min,
119 double max, bool limitsInAllowedRange, std::string const &extraMessage)
120{
121 const char openBr = limitsInAllowedRange ? '[' : '(';
122 const char closeBr = limitsInAllowedRange ? ']' : ')';
123
124 for (auto parameter : pars) {
125 auto par = dynamic_cast<const RooAbsRealLValue *>(parameter);
126 if (par && ((par->getMin() < min || par->getMax() > max) ||
127 (!limitsInAllowedRange && (par->getMin() == min || par->getMax() == max)))) {
128 std::stringstream rangeMsg;
129 rangeMsg << openBr;
130 if (min > -std::numeric_limits<double>::max()) {
131 rangeMsg << min << ", ";
132 } else {
133 rangeMsg << "-inf, ";
134 }
135
136 if (max < std::numeric_limits<double>::max()) {
137 rangeMsg << max << closeBr;
138 } else {
139 rangeMsg << "inf" << closeBr;
140 }
141
142 oocoutW(callingClass, InputArguments)
143 << "The parameter '" << par->GetName() << "' with range [" << par->getMin("") << ", " << par->getMax()
144 << "] of the " << callingClass->ClassName() << " '" << callingClass->GetName()
145 << "' exceeds the safe range of " << rangeMsg.str() << ". Advise to limit its range."
146 << (!extraMessage.empty() ? "\n" : "") << extraMessage << std::endl;
147 }
148 }
149}
150
151} // namespace RooHelpers
#define oocoutW(o, a)
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:77
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:59
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:80
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:81
~HijackMessageStream()
Deregister the hijacked stream and restore the stream state of all previous streams.
RooFit::MsgLevel fOldKillBelow
Definition RooHelpers.h:50
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:51
static RooMsgService & instance()
Return reference to singleton instance.
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:207
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.