Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooMsgService.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
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-2005, 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/**
18\file RooMsgService.cxx
19\class RooMsgService
20\ingroup Roofitcore
21
22
23The class RooMsgService is a singleton that organizes messages generated in RooFit.
24Each message has a message level RooFit::MsgLevel (DEBUG,INFO,PROGRESS,WARNING,ERROR or FATAL),
25an source object, and a RooFit::MsgTopic.
26RooMsgService allows to filter and redirect messages into streams
27according to message level, topic, (base) class of originating object, name of originating
28object and based on attribute labels attached to individual objects.
29The current default configuration creates streams for all messages at WARNING level
30or higher (e.g. ERROR and FATAL) and for all INFO message on topics Generation,Plotting,
31Integration and Minimization and redirects them to stdout. Users can create additional streams
32for logging of e.g. DEBUG messages on particular topics or objects and/or redirect streams to
33C++ streams or files.
34
35The singleton instance is accessible through RooMsgService::instance().
36
37### Temporarily change the message level
38There is a helper, RooHelpers::LocalChangeMsgLevel, that overrides the default message levels as
39long as it is alive. To suppress everything below WARNING:
40~~~{.cpp}
41RooHelpers::LocalChangeMessageLevel changeMsgLvl(RooFit::WARNING);
42[ statements that normally generate a lot of output ]
43~~~
44
45#### Temporarily capture a message stream
46RooHelpers::HijackMessageStream allows to fully capture a message stream in a std::stringstream. With this,
47RooFit messages can be evaluated or suppressed.
48**/
49
50
51#include "RooMsgService.h"
52
53#include <sys/types.h>
54#include "RooAbsArg.h"
55#include "RooCmdArg.h"
56#include "RooCmdConfig.h"
57#include "RooGlobalFunc.h"
58#include "RooWorkspace.h"
59#include "RooHelpers.h"
60
61#include "TClass.h"
62#include "TSystem.h"
63
64#include <fstream>
65#include <iomanip>
66
67using namespace std;
68using namespace RooFit;
69
71
73
74
75////////////////////////////////////////////////////////////////////////////////
76/// Constructor. Defines names of message levels
77/// and mapping of topic codes to topic names
78/// Install default message streams.
79
81{
82 _devnull = std::make_unique<ofstream>("/dev/null") ;
83
84 _levelNames[DEBUG]="DEBUG" ;
85 _levelNames[INFO]="INFO" ;
86 _levelNames[PROGRESS]="PROGRESS" ;
87 _levelNames[WARNING]="WARNING" ;
88 _levelNames[ERROR]="ERROR" ;
89 _levelNames[FATAL]="FATAL" ;
90
91 _topicNames[Generation]="Generation" ;
92 _topicNames[Minimization]="Minimization" ;
93 _topicNames[Plotting]="Plotting" ;
94 _topicNames[Fitting]="Fitting" ;
95 _topicNames[Integration]="Integration" ;
96 _topicNames[LinkStateMgmt]="LinkStateMgmt" ;
97 _topicNames[Eval]="Eval" ;
98 _topicNames[Caching]="Caching" ;
99 _topicNames[Optimization]="Optimization" ;
100 _topicNames[ObjectHandling]="ObjectHandling" ;
101 _topicNames[InputArguments]="InputArguments" ;
102 _topicNames[Tracing]="Tracing" ;
103 _topicNames[Contents]="Contents" ;
104 _topicNames[DataHandling]="DataHandling" ;
105 _topicNames[NumIntegration]="NumericIntegration" ;
106 _topicNames[FastEvaluations] = "FastEvaluations";
107 _topicNames[HistFactory]="HistFactory";
108
109 reset();
110}
111
112
114 _silentMode = false ;
115 _showPid = false ;
118
119 _debugWorkspace = nullptr;
120 _debugCode = 0 ;
121
122 _files.clear();
123
124 // Old-style streams
125 _streams.clear();
126 addStream(RooFit::PROGRESS, Topic(RooFit::HistFactory - 1));//All before HistFactory
129}
130
131
133
134
135////////////////////////////////////////////////////////////////////////////////
136/// Returns true if any debug level stream is active
137
139{
140 return instance()._debugCount>0 ;
141}
142
143
144
145////////////////////////////////////////////////////////////////////////////////
146
148{
149 if (!_debugWorkspace) {
150 _debugWorkspace = std::make_unique<RooWorkspace>("wdebug") ;
151 }
152 return _debugWorkspace.get();
153}
154
155
156
157////////////////////////////////////////////////////////////////////////////////
158/// Add a message logging stream for message with given RooFit::MsgLevel or higher.
159/// Higher means that messages with higher priority/severity are issued.
160///
161/// This method accepts the following arguments to configure the stream:
162/// <table>
163/// <tr><th> Output Style options <th>
164/// <tr><td> Prefix(bool flag=true) <td> Prefix all messages in this stream with Topic/Originator information
165/// <tr><th> Filtering options <th>
166/// <tr><td> Topic() <td> Restrict stream to messages on given topic
167/// <tr><td> ObjectName(const char*) <td> Restrict stream to messages from object with given name
168/// <tr><td> ClassName(const char*) <td> Restrict stream to messages from objects with given class name
169/// <tr><td> BaseClassName(const char*)<td> Restrict stream to messages from objects with given base class name
170/// <tr><td> LabelName(const chat*) <td> Restrict stream to messages from objects setAtrribute(const char*) tag with given name
171/// <tr><th> Output redirection options <th>
172/// <tr><td> OutputFile(const char*) <td> Send output to file with given name. Multiple streams can write to same file.
173/// <tr><td> OutputStream(ostream&) <td> Send output to given C++ stream. Multiple message streams can write to same c++ stream
174/// </table>
175/// The return value is the unique ID of the defined stream.
176
177Int_t RooMsgService::addStream(RooFit::MsgLevel level, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3,
178 const RooCmdArg& arg4, const RooCmdArg& arg5, const RooCmdArg& arg6)
179{
180
181 // Aggregate all arguments in a list
183 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
184 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
185 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
186
187 // Define configuration for this method
188 RooCmdConfig pc(Form("RooMsgService::addReportingStream(%s)",GetName())) ;
189 pc.defineInt("prefix","Prefix",0,true) ;
190 pc.defineInt("color","Color",0,static_cast<Int_t>(kBlack)) ;
191 pc.defineInt("topic","Topic",0,0xFFFFF) ;
192 pc.defineString("objName","ObjectName",0,"") ;
193 pc.defineString("className","ClassName",0,"") ;
194 pc.defineString("baseClassName","BaseClassName",0,"") ;
195 pc.defineString("tagName","LabelName",0,"") ;
196 pc.defineString("outFile","OutputFile",0,"") ;
197 pc.defineObject("outStream","OutputStream",0,0) ;
198 pc.defineMutex("OutputFile","OutputStream") ;
199
200 // Process & check varargs
201 pc.process(l) ;
202 if (!pc.ok(true)) {
203 return -1 ;
204 }
205
206 // Extract values from named arguments
207 RooFit::MsgTopic topic = (RooFit::MsgTopic) pc.getInt("topic") ;
208 const char* objName = pc.getString("objName") ;
209 const char* className = pc.getString("className") ;
210 const char* baseClassName = pc.getString("baseClassName") ;
211 const char* tagName = pc.getString("tagName") ;
212 const char* outFile = pc.getString("outFile") ;
213 bool prefix = pc.getInt("prefix") ;
214 Color_t color = static_cast<Color_t>(pc.getInt("color")) ;
215 auto wrapper = static_cast<RooHelpers::WrapIntoTObject<ostream>*>(pc.getObject("outStream"));
216 ostream* os = nullptr;
217 if (wrapper) {
218 os = wrapper->_payload;
219 delete wrapper;
220 wrapper = nullptr;
221 }
222
223 // Create new stream object
224 StreamConfig newStream ;
225
226 // Store configuration info
227 newStream.active = true ;
228 newStream.minLevel = level ;
229 newStream.topic = topic ;
230 newStream.objectName = (objName ? objName : "" ) ;
231 newStream.className = (className ? className : "" ) ;
232 newStream.baseClassName = (baseClassName ? baseClassName : "" ) ;
233 newStream.tagName = (tagName ? tagName : "" ) ;
234 newStream.color = color ;
235 newStream.prefix = prefix ;
236 newStream.universal = (newStream.objectName=="" && newStream.className=="" && newStream.baseClassName=="" && newStream.tagName=="") ;
237
238 // Update debug stream count
239 if (level==DEBUG) {
240 _debugCount++ ;
241 }
242
243 // Configure output
244 if (os) {
245
246 // To given non-owned stream
247 newStream.os = os ;
248
249 } else if (string(outFile).size()>0) {
250
251 // See if we already opened the file
252 ostream* os2 = _files["outFile"].get();
253
254 if (!os2) {
255
256 // To given file name, create owned stream for it
257 os2 = new ofstream(outFile) ;
258
259 if (!*os2) {
260 cout << "RooMsgService::addReportingStream ERROR: cannot open output log file " << outFile << " reverting stream to stdout" << endl ;
261 delete os2 ;
262 newStream.os = &cout ;
263 } else {
264 newStream.os = os2 ;
265 }
266
267 } else {
268 newStream.os = os2 ;
269 _files["outFile"] = std::unique_ptr<std::ostream>{os2};
270 }
271
272
273 } else {
274
275 // To stdout
276 newStream.os = &cout ;
277
278 }
279
280
281 // Add it to list of active streams ;
282 _streams.push_back(newStream) ;
283
284 // Return stream identifier
285 return _streams.size()-1 ;
286}
287
288
289
290////////////////////////////////////////////////////////////////////////////////
291/// Delete stream with given unique ID code
292
294{
295 vector<StreamConfig>::iterator iter = _streams.begin() ;
296 iter += id ;
297
298 // Update debug stream count
299 if (iter->minLevel==DEBUG) {
300 _debugCount-- ;
301 }
302
303 _streams.erase(iter) ;
304}
305
306
307
308////////////////////////////////////////////////////////////////////////////////
309/// (De)Activate stream with given unique ID
310
312{
313 if (id<0 || id>=static_cast<Int_t>(_streams.size())) {
314 cout << "RooMsgService::setStreamStatus() ERROR: invalid stream ID " << id << endl ;
315 return ;
316 }
317
318 // Update debug stream count
319 if (_streams[id].minLevel==DEBUG) {
320 _debugCount += flag ? 1 : -1 ;
321 }
322
323 _streams[id].active = flag ;
324}
325
326
327
328////////////////////////////////////////////////////////////////////////////////
329/// Get activation status of stream with given unique ID
330
332{
333 if (id<0 || id>= static_cast<Int_t>(_streams.size())) {
334 cout << "RooMsgService::getStreamStatus() ERROR: invalid stream ID " << id << endl ;
335 return false ;
336 }
337 return _streams[id].active ;
338}
339
340
341
342////////////////////////////////////////////////////////////////////////////////
343/// Return reference to singleton instance
344
346{
347 static RooMsgService instance;
348 return instance;
349}
350
351
352
353////////////////////////////////////////////////////////////////////////////////
354/// Save current state of message service
355
357{
358 _streamsSaved.push(_streams) ;
359}
360
361
362
363////////////////////////////////////////////////////////////////////////////////
364/// Restore last saved state of message service
365
367{
368 _streams = _streamsSaved.top() ;
369 _streamsSaved.pop() ;
370}
371
372
373
374////////////////////////////////////////////////////////////////////////////////
375/// Check if logging is active for given object/topic/RooFit::%MsgLevel combination
376
378{
379 return (activeStream(self,topic,level)>=0) ;
380}
381
382
383////////////////////////////////////////////////////////////////////////////////
384/// Check if logging is active for given object/topic/RooFit::%MsgLevel combination
385
387{
388 return (activeStream(self,topic,level)>=0) ;
389}
390
391
392////////////////////////////////////////////////////////////////////////////////
393/// Find appropriate logging stream for message from given object with given topic and message level
394
396{
397 if (level<_globMinLevel) return -1 ;
398 for (UInt_t i=0 ; i<_streams.size() ; i++) {
399 if (_streams[i].match(level,topic,self)) {
400 return i ;
401 }
402 }
403 return -1 ;
404}
405
406
407////////////////////////////////////////////////////////////////////////////////
408/// Find appropriate logging stream for message from given object with given topic and message level
409
411{
412 if (level<_globMinLevel) return -1 ;
413 for (UInt_t i=0 ; i<_streams.size() ; i++) {
414 if (_streams[i].match(level,topic,self)) {
415 return i ;
416 }
417 }
418 return -1 ;
419}
420
421
422////////////////////////////////////////////////////////////////////////////////
423/// Determine if message from given object at given level on given topic is logged
424
426{
427 if (!active) return false ;
428 if (level<minLevel) return false ;
429 if (!(topic&top)) return false ;
430
431 if (universal) return true ;
432
433 if (!obj) return false;
434 if (objectName.size()>0 && objectName != obj->GetName()) return false ;
435 if (className.size()>0 && className != obj->ClassName()) return false ;
436 if (baseClassName.size()>0 && !obj->IsA()->InheritsFrom(baseClassName.c_str())) return false ;
437 if (tagName.size()>0 && !obj->getAttribute(tagName.c_str())) return false ;
438
439 return true ;
440}
441
442
443////////////////////////////////////////////////////////////////////////////////
444/// Determine if message from given object at given level on given topic is logged
445
447{
448 if (!active) return false ;
449 if (level<minLevel) return false ;
450 if (!(topic&top)) return false ;
451
452 if (universal) return true ;
453
454 if (!obj) return false;
455 if (objectName.size()>0 && objectName != obj->GetName()) return false ;
456 if (className.size()>0 && className != obj->ClassName()) return false ;
457 if (baseClassName.size()>0 && !obj->IsA()->InheritsFrom(baseClassName.c_str())) return false ;
458
459 return true ;
460}
461
462
463
464////////////////////////////////////////////////////////////////////////////////
465/// Log error message associated with RooAbsArg object self at given level and topic. If skipPrefix
466/// is true the standard RooMsgService prefix is not added.
467
468ostream& RooMsgService::log(const RooAbsArg* self, RooFit::MsgLevel level, RooFit::MsgTopic topic, bool skipPrefix)
469{
470 if (level>=ERROR) {
471 _errorCount++ ;
472 }
473
474 // Return C++ ostream associated with given message configuration
475 Int_t as = activeStream(self,topic,level) ;
476
477 if (as==-1) {
478 return *_devnull ;
479 }
480
481 // Flush any previous messages
482 (*_streams[as].os).flush() ;
483
484 // Insert an endl if we switch from progress to another level
485 if (_lastMsgLevel==PROGRESS && level!=PROGRESS) {
486 (*_streams[as].os) << endl ;
487 }
488 _lastMsgLevel=level ;
489
490 if (_streams[as].prefix && !skipPrefix) {
491 if (_showPid) {
492 (*_streams[as].os) << "pid" << gSystem->GetPid() << " " ;
493 }
494 (*_streams[as].os) << "[#" << as << "] " << _levelNames[level] << ":" << _topicNames[topic] << " -- " ;
495 }
496 return (*_streams[as].os) ;
497}
498
499
500
501////////////////////////////////////////////////////////////////////////////////
502/// Log error message associated with TObject object self at given level and topic. If skipPrefix
503/// is true the standard RooMsgService prefix is not added.
504
505ostream& RooMsgService::log(const TObject* self, RooFit::MsgLevel level, RooFit::MsgTopic topic, bool skipPrefix)
506{
507 if (level>=ERROR) {
508 _errorCount++ ;
509 }
510
511 // Return C++ ostream associated with given message configuration
512 Int_t as = activeStream(self,topic,level) ;
513 if (as==-1) {
514 return *_devnull ;
515 }
516
517 // Flush any previous messages
518 (*_streams[as].os).flush() ;
519
520 if (_streams[as].prefix && !skipPrefix) {
521 if (_showPid) {
522 (*_streams[as].os) << "pid" << gSystem->GetPid() << " " ;
523 }
524 (*_streams[as].os) << "[#" << as << "] " << _levelNames[level] << ":" << _topicNames[topic] << " -- " ;
525 }
526 return (*_streams[as].os) ;
527}
528
529
530
531////////////////////////////////////////////////////////////////////////////////
532/// Print configuration of message service. If "v" option is given also
533/// inactive streams are listed
534
535void RooMsgService::Print(Option_t *options) const
536{
537 bool activeOnly = true ;
538 if (TString(options).Contains("V") || TString(options).Contains("v")) {
539 activeOnly = false ;
540 }
541
542 cout << (activeOnly?"Active Message streams":"All Message streams") << endl ;
543 for (UInt_t i=0 ; i<_streams.size() ; i++) {
544
545 // Skip passive streams in active only mode
546 if (activeOnly && !_streams[i].active) {
547 continue ;
548 }
549
550
551 map<int,string>::const_iterator is = _levelNames.find(_streams[i].minLevel) ;
552 cout << "[" << i << "] MinLevel = " << is->second ;
553
554 cout << " Topic = " ;
555 if (_streams[i].topic != 0xFFFFF) {
556 map<int,string>::const_iterator iter = _topicNames.begin() ;
557 while(iter!=_topicNames.end()) {
558 if (iter->first & _streams[i].topic) {
559 cout << iter->second << " " ;
560 }
561 ++iter ;
562 }
563 } else {
564 cout << " Any " ;
565 }
566
567
568 if (_streams[i].objectName.size()>0) {
569 cout << " ObjectName = " << _streams[i].objectName ;
570 }
571 if (_streams[i].className.size()>0) {
572 cout << " ClassName = " << _streams[i].className ;
573 }
574 if (_streams[i].baseClassName.size()>0) {
575 cout << " BaseClassName = " << _streams[i].baseClassName ;
576 }
577 if (_streams[i].tagName.size()>0) {
578 cout << " TagLabel = " << _streams[i].tagName ;
579 }
580
581 // Postfix status when printing all
582 if (!activeOnly && !_streams[i].active) {
583 cout << " (NOT ACTIVE)" ;
584 }
585
586 cout << endl ;
587 }
588
589}
#define DEBUG
int Int_t
Definition RtypesCore.h:45
short Color_t
Definition RtypesCore.h:92
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:377
@ kBlack
Definition Rtypes.h:65
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2467
R__EXTERN TSystem * gSystem
Definition TSystem.h:560
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition RooAbsArg.h:74
bool getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
RooCmdArg is a named container for two doubles, two integers two object points and three string point...
Definition RooCmdArg.h:26
Class RooCmdConfig is a configurable parser for RooCmdArg named arguments.
bool defineObject(const char *name, const char *argName, Int_t setNum, const TObject *obj=nullptr, bool isArray=false)
Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName ...
void defineMutex(const char *head, Args_t &&... tail)
Define arguments where any pair is mutually exclusive.
bool process(const RooCmdArg &arg)
Process given RooCmdArg.
Int_t getInt(const char *name, Int_t defaultValue=0)
Return integer property registered with name 'name'.
bool defineInt(const char *name, const char *argName, Int_t intNum, Int_t defValue=0)
Define integer property name 'name' mapped to integer in slot 'intNum' in RooCmdArg with name argName...
bool defineString(const char *name, const char *argName, Int_t stringNum, const char *defValue="", bool appendMode=false)
Define double property name 'name' mapped to double in slot 'stringNum' in RooCmdArg with name argNam...
bool ok(bool verbose) const
Return true of parsing was successful.
TObject * getObject(const char *name, TObject *obj=nullptr)
Return TObject property registered with name 'name'.
const char * getString(const char *name, const char *defaultValue="", bool convEmptyToNull=false)
Return string property registered with name 'name'.
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
The class RooMsgService is a singleton that organizes messages generated in RooFit.
std::vector< StreamConfig > _streams
void restoreState()
Restore last saved state of message service.
std::ostream & log(const RooAbsArg *self, RooFit::MsgLevel level, RooFit::MsgTopic facility, bool forceSkipPrefix=false)
Log error message associated with RooAbsArg object self at given level and topic.
static RooMsgService & instance()
Return reference to singleton instance.
static Int_t _debugCount
std::unique_ptr< RooWorkspace > _debugWorkspace
static bool anyDebug()
Returns true if any debug level stream is active.
RooFit::MsgLevel _globMinLevel
std::stack< std::vector< StreamConfig > > _streamsSaved
RooMsgService()
Constructor.
RooWorkspace * debugWorkspace()
void Print(Option_t *options=nullptr) const override
Print configuration of message service.
void setStreamStatus(Int_t id, bool active)
(De)Activate stream with given unique ID
void saveState()
Save current state of message service.
std::map< int, std::string > _topicNames
~RooMsgService() override
std::map< std::string, std::unique_ptr< std::ostream > > _files
bool isActive(const RooAbsArg *self, RooFit::MsgTopic facility, RooFit::MsgLevel level)
Check if logging is active for given object/topic/RooFit::MsgLevel combination.
Int_t activeStream(const RooAbsArg *self, RooFit::MsgTopic facility, RooFit::MsgLevel level)
Find appropriate logging stream for message from given object with given topic and message level.
bool getStreamStatus(Int_t id) const
Get activation status of stream with given unique ID.
void deleteStream(Int_t id)
Delete stream with given unique ID code.
std::unique_ptr< std::ofstream > _devnull
std::map< int, std::string > _levelNames
Int_t addStream(RooFit::MsgLevel level, const RooCmdArg &arg1=RooCmdArg(), const RooCmdArg &arg2=RooCmdArg(), const RooCmdArg &arg3=RooCmdArg(), const RooCmdArg &arg4=RooCmdArg(), const RooCmdArg &arg5=RooCmdArg(), const RooCmdArg &arg6=RooCmdArg())
Add a message logging stream for message with given RooFit::MsgLevel or higher.
RooFit::MsgLevel _lastMsgLevel
The RooWorkspace is a persistable container for RooFit projects.
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
Definition TClass.cxx:4874
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
TClass * IsA() const override
Definition TNamed.h:58
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:439
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:207
virtual TClass * IsA() const
Definition TObject.h:245
Basic string class.
Definition TString.h:139
virtual int GetPid()
Get process id.
Definition TSystem.cxx:710
RooCmdArg Topic(Int_t topic)
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
Definition Common.h:18
MsgLevel
Verbosity level for RooMsgService::StreamConfig in RooMsgService.
MsgTopic
Topics for a RooMsgService::StreamConfig in RooMsgService.
@ FastEvaluations
@ NumIntegration
@ InputArguments
@ ObjectHandling
@ LinkStateMgmt
Wrap an object into a TObject. Sometimes needed to avoid reinterpret_cast or enable RTTI.
Definition RooHelpers.h:65
bool match(RooFit::MsgLevel level, RooFit::MsgTopic facility, const RooAbsArg *obj)
Determine if message from given object at given level on given topic is logged.
TLine l
Definition textangle.C:4