Logo ROOT  
Reference Guide
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 = new 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 delete _debugWorkspace;
120 _debugWorkspace = nullptr;
121 _debugCode = 0 ;
122
123 for (auto &item : _files) {
124 delete item.second;
125 }
126 _files.clear();
127
128 // Old-style streams
129 _streams.clear();
130 addStream(RooFit::PROGRESS, Topic(RooFit::HistFactory - 1));//All before HistFactory
133}
134
135
136////////////////////////////////////////////////////////////////////////////////
137/// Destructor
138
140{
141 // Delete all ostreams we own ;
142 map<string,ostream*>::iterator iter = _files.begin() ;
143 for (; iter != _files.end() ; ++iter) {
144 delete iter->second ;
145 }
146
147 if (_debugWorkspace) {
148 delete _debugWorkspace ;
149 }
150
151 delete _devnull ;
152}
153
154
155
156////////////////////////////////////////////////////////////////////////////////
157/// Returns true if any debug level stream is active
158
160{
161 return instance()._debugCount>0 ;
162}
163
164
165
166////////////////////////////////////////////////////////////////////////////////
167
169{
170 if (!_debugWorkspace) {
171 _debugWorkspace = new RooWorkspace("wdebug") ;
172 }
173 return _debugWorkspace ;
174}
175
176
177
178////////////////////////////////////////////////////////////////////////////////
179/// Add a message logging stream for message with given RooFit::MsgLevel or higher.
180/// Higher means that messages with higher priority/severity are issued.
181///
182/// This method accepts the following arguments to configure the stream:
183/// <table>
184/// <tr><th> Output Style options <th>
185/// <tr><td> Prefix(bool flag=true) <td> Prefix all messages in this stream with Topic/Originator information
186/// <tr><th> Filtering options <th>
187/// <tr><td> Topic() <td> Restrict stream to messages on given topic
188/// <tr><td> ObjectName(const char*) <td> Restrict stream to messages from object with given name
189/// <tr><td> ClassName(const char*) <td> Restrict stream to messages from objects with given class name
190/// <tr><td> BaseClassName(const char*)<td> Restrict stream to messages from objects with given base class name
191/// <tr><td> LabelName(const chat*) <td> Restrict stream to messages from objects setAtrribute(const char*) tag with given name
192/// <tr><th> Output redirection options <th>
193/// <tr><td> OutputFile(const char*) <td> Send output to file with given name. Multiple streams can write to same file.
194/// <tr><td> OutputStream(ostream&) <td> Send output to given C++ stream. Multiple message streams can write to same c++ stream
195/// </table>
196/// The return value is the unique ID of the defined stream.
197
198Int_t RooMsgService::addStream(RooFit::MsgLevel level, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3,
199 const RooCmdArg& arg4, const RooCmdArg& arg5, const RooCmdArg& arg6)
200{
201
202 // Aggregate all arguments in a list
204 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
205 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
206 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
207
208 // Define configuration for this method
209 RooCmdConfig pc(Form("RooMsgService::addReportingStream(%s)",GetName())) ;
210 pc.defineInt("prefix","Prefix",0,true) ;
211 pc.defineInt("color","Color",0,static_cast<Int_t>(kBlack)) ;
212 pc.defineInt("topic","Topic",0,0xFFFFF) ;
213 pc.defineString("objName","ObjectName",0,"") ;
214 pc.defineString("className","ClassName",0,"") ;
215 pc.defineString("baseClassName","BaseClassName",0,"") ;
216 pc.defineString("tagName","LabelName",0,"") ;
217 pc.defineString("outFile","OutputFile",0,"") ;
218 pc.defineObject("outStream","OutputStream",0,0) ;
219 pc.defineMutex("OutputFile","OutputStream") ;
220
221 // Process & check varargs
222 pc.process(l) ;
223 if (!pc.ok(true)) {
224 return -1 ;
225 }
226
227 // Extract values from named arguments
228 RooFit::MsgTopic topic = (RooFit::MsgTopic) pc.getInt("topic") ;
229 const char* objName = pc.getString("objName") ;
230 const char* className = pc.getString("className") ;
231 const char* baseClassName = pc.getString("baseClassName") ;
232 const char* tagName = pc.getString("tagName") ;
233 const char* outFile = pc.getString("outFile") ;
234 bool prefix = pc.getInt("prefix") ;
235 Color_t color = static_cast<Color_t>(pc.getInt("color")) ;
236 auto wrapper = static_cast<RooHelpers::WrapIntoTObject<ostream>*>(pc.getObject("outStream"));
237 ostream* os = nullptr;
238 if (wrapper) {
239 os = wrapper->_payload;
240 delete wrapper;
241 wrapper = nullptr;
242 }
243
244 // Create new stream object
245 StreamConfig newStream ;
246
247 // Store configuration info
248 newStream.active = true ;
249 newStream.minLevel = level ;
250 newStream.topic = topic ;
251 newStream.objectName = (objName ? objName : "" ) ;
252 newStream.className = (className ? className : "" ) ;
253 newStream.baseClassName = (baseClassName ? baseClassName : "" ) ;
254 newStream.tagName = (tagName ? tagName : "" ) ;
255 newStream.color = color ;
256 newStream.prefix = prefix ;
257 newStream.universal = (newStream.objectName=="" && newStream.className=="" && newStream.baseClassName=="" && newStream.tagName=="") ;
258
259 // Update debug stream count
260 if (level==DEBUG) {
261 _debugCount++ ;
262 }
263
264 // Configure output
265 if (os) {
266
267 // To given non-owned stream
268 newStream.os = os ;
269
270 } else if (string(outFile).size()>0) {
271
272 // See if we already opened the file
273 ostream* os2 = _files["outFile"] ;
274
275 if (!os2) {
276
277 // To given file name, create owned stream for it
278 os2 = new ofstream(outFile) ;
279
280 if (!*os2) {
281 cout << "RooMsgService::addReportingStream ERROR: cannot open output log file " << outFile << " reverting stream to stdout" << endl ;
282 delete os2 ;
283 newStream.os = &cout ;
284 } else {
285 newStream.os = os2 ;
286 }
287
288 } else {
289 _files["outFile"] = os2 ;
290 newStream.os = os2 ;
291 }
292
293
294 } else {
295
296 // To stdout
297 newStream.os = &cout ;
298
299 }
300
301
302 // Add it to list of active streams ;
303 _streams.push_back(newStream) ;
304
305 // Return stream identifier
306 return _streams.size()-1 ;
307}
308
309
310
311////////////////////////////////////////////////////////////////////////////////
312/// Delete stream with given unique ID code
313
315{
316 vector<StreamConfig>::iterator iter = _streams.begin() ;
317 iter += id ;
318
319 // Update debug stream count
320 if (iter->minLevel==DEBUG) {
321 _debugCount-- ;
322 }
323
324 _streams.erase(iter) ;
325}
326
327
328
329////////////////////////////////////////////////////////////////////////////////
330/// (De)Activate stream with given unique ID
331
333{
334 if (id<0 || id>=static_cast<Int_t>(_streams.size())) {
335 cout << "RooMsgService::setStreamStatus() ERROR: invalid stream ID " << id << endl ;
336 return ;
337 }
338
339 // Update debug stream count
340 if (_streams[id].minLevel==DEBUG) {
341 _debugCount += flag ? 1 : -1 ;
342 }
343
344 _streams[id].active = flag ;
345}
346
347
348
349////////////////////////////////////////////////////////////////////////////////
350/// Get activation status of stream with given unique ID
351
353{
354 if (id<0 || id>= static_cast<Int_t>(_streams.size())) {
355 cout << "RooMsgService::getStreamStatus() ERROR: invalid stream ID " << id << endl ;
356 return false ;
357 }
358 return _streams[id].active ;
359}
360
361
362
363////////////////////////////////////////////////////////////////////////////////
364/// Return reference to singleton instance
365
367{
368 static RooMsgService instance;
369 return instance;
370}
371
372
373
374////////////////////////////////////////////////////////////////////////////////
375/// Save current state of message service
376
378{
379 _streamsSaved.push(_streams) ;
380}
381
382
383
384////////////////////////////////////////////////////////////////////////////////
385/// Restore last saved state of message service
386
388{
389 _streams = _streamsSaved.top() ;
390 _streamsSaved.pop() ;
391}
392
393
394
395////////////////////////////////////////////////////////////////////////////////
396/// Check if logging is active for given object/topic/RooFit::%MsgLevel combination
397
399{
400 return (activeStream(self,topic,level)>=0) ;
401}
402
403
404////////////////////////////////////////////////////////////////////////////////
405/// Check if logging is active for given object/topic/RooFit::%MsgLevel combination
406
408{
409 return (activeStream(self,topic,level)>=0) ;
410}
411
412
413////////////////////////////////////////////////////////////////////////////////
414/// Find appropriate logging stream for message from given object with given topic and message level
415
417{
418 if (level<_globMinLevel) return -1 ;
419 for (UInt_t i=0 ; i<_streams.size() ; i++) {
420 if (_streams[i].match(level,topic,self)) {
421 return i ;
422 }
423 }
424 return -1 ;
425}
426
427
428////////////////////////////////////////////////////////////////////////////////
429/// Find appropriate logging stream for message from given object with given topic and message level
430
432{
433 if (level<_globMinLevel) return -1 ;
434 for (UInt_t i=0 ; i<_streams.size() ; i++) {
435 if (_streams[i].match(level,topic,self)) {
436 return i ;
437 }
438 }
439 return -1 ;
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 if (tagName.size()>0 && !obj->getAttribute(tagName.c_str())) return false ;
459
460 return true ;
461}
462
463
464////////////////////////////////////////////////////////////////////////////////
465/// Determine if message from given object at given level on given topic is logged
466
468{
469 if (!active) return false ;
470 if (level<minLevel) return false ;
471 if (!(topic&top)) return false ;
472
473 if (universal) return true ;
474
475 if (!obj) return false;
476 if (objectName.size()>0 && objectName != obj->GetName()) return false ;
477 if (className.size()>0 && className != obj->ClassName()) return false ;
478 if (baseClassName.size()>0 && !obj->IsA()->InheritsFrom(baseClassName.c_str())) return false ;
479
480 return true ;
481}
482
483
484
485////////////////////////////////////////////////////////////////////////////////
486/// Log error message associated with RooAbsArg object self at given level and topic. If skipPrefix
487/// is true the standard RooMsgService prefix is not added.
488
489ostream& RooMsgService::log(const RooAbsArg* self, RooFit::MsgLevel level, RooFit::MsgTopic topic, bool skipPrefix)
490{
491 if (level>=ERROR) {
492 _errorCount++ ;
493 }
494
495 // Return C++ ostream associated with given message configuration
496 Int_t as = activeStream(self,topic,level) ;
497
498 if (as==-1) {
499 return *_devnull ;
500 }
501
502 // Flush any previous messages
503 (*_streams[as].os).flush() ;
504
505 // Insert an endl if we switch from progress to another level
506 if (_lastMsgLevel==PROGRESS && level!=PROGRESS) {
507 (*_streams[as].os) << endl ;
508 }
509 _lastMsgLevel=level ;
510
511 if (_streams[as].prefix && !skipPrefix) {
512 if (_showPid) {
513 (*_streams[as].os) << "pid" << gSystem->GetPid() << " " ;
514 }
515 (*_streams[as].os) << "[#" << as << "] " << _levelNames[level] << ":" << _topicNames[topic] << " -- " ;
516 }
517 return (*_streams[as].os) ;
518}
519
520
521
522////////////////////////////////////////////////////////////////////////////////
523/// Log error message associated with TObject object self at given level and topic. If skipPrefix
524/// is true the standard RooMsgService prefix is not added.
525
526ostream& RooMsgService::log(const TObject* self, RooFit::MsgLevel level, RooFit::MsgTopic topic, bool skipPrefix)
527{
528 if (level>=ERROR) {
529 _errorCount++ ;
530 }
531
532 // Return C++ ostream associated with given message configuration
533 Int_t as = activeStream(self,topic,level) ;
534 if (as==-1) {
535 return *_devnull ;
536 }
537
538 // Flush any previous messages
539 (*_streams[as].os).flush() ;
540
541 if (_streams[as].prefix && !skipPrefix) {
542 if (_showPid) {
543 (*_streams[as].os) << "pid" << gSystem->GetPid() << " " ;
544 }
545 (*_streams[as].os) << "[#" << as << "] " << _levelNames[level] << ":" << _topicNames[topic] << " -- " ;
546 }
547 return (*_streams[as].os) ;
548}
549
550
551
552////////////////////////////////////////////////////////////////////////////////
553/// Print configuration of message service. If "v" option is given also
554/// inactive streams are listed
555
556void RooMsgService::Print(Option_t *options) const
557{
558 bool activeOnly = true ;
559 if (TString(options).Contains("V") || TString(options).Contains("v")) {
560 activeOnly = false ;
561 }
562
563 cout << (activeOnly?"Active Message streams":"All Message streams") << endl ;
564 for (UInt_t i=0 ; i<_streams.size() ; i++) {
565
566 // Skip passive streams in active only mode
567 if (activeOnly && !_streams[i].active) {
568 continue ;
569 }
570
571
572 map<int,string>::const_iterator is = _levelNames.find(_streams[i].minLevel) ;
573 cout << "[" << i << "] MinLevel = " << is->second ;
574
575 cout << " Topic = " ;
576 if (_streams[i].topic != 0xFFFFF) {
577 map<int,string>::const_iterator iter = _topicNames.begin() ;
578 while(iter!=_topicNames.end()) {
579 if (iter->first & _streams[i].topic) {
580 cout << iter->second << " " ;
581 }
582 ++iter ;
583 }
584 } else {
585 cout << " Any " ;
586 }
587
588
589 if (_streams[i].objectName.size()>0) {
590 cout << " ObjectName = " << _streams[i].objectName ;
591 }
592 if (_streams[i].className.size()>0) {
593 cout << " ClassName = " << _streams[i].className ;
594 }
595 if (_streams[i].baseClassName.size()>0) {
596 cout << " BaseClassName = " << _streams[i].baseClassName ;
597 }
598 if (_streams[i].tagName.size()>0) {
599 cout << " TagLabel = " << _streams[i].tagName ;
600 }
601
602 // Postfix status when printing all
603 if (!activeOnly && !_streams[i].active) {
604 cout << " (NOT ACTIVE)" ;
605 }
606
607 cout << endl ;
608 }
609
610}
#define DEBUG
Definition: Polynomial.cxx:40
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:375
@ 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:2452
R__EXTERN TSystem * gSystem
Definition: TSystem.h:559
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition: RooAbsArg.h:71
bool getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
Definition: RooAbsArg.cxx:269
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.
Definition: RooCmdConfig.h:31
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
Definition: RooLinkedList.h:38
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 * _devnull
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
static bool anyDebug()
Returns true if any debug level stream is active.
void Print(Option_t *options=0) const override
Print configuration of message service.
RooFit::MsgLevel _globMinLevel
std::stack< std::vector< StreamConfig > > _streamsSaved
RooMsgService()
Constructor.
RooWorkspace * debugWorkspace()
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
Destructor.
RooWorkspace * _debugWorkspace
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::map< std::string, std::ostream * > _files
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.
Definition: RooWorkspace.h:43
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4863
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:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:363
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:130
virtual TClass * IsA() const
Definition: TObject.h:230
Basic string class.
Definition: TString.h:136
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:710
RooCmdArg Topic(Int_t topic)
TString as(SEXP s)
Definition: RExports.h:86
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.
Definition: RooGlobalFunc.h:61
MsgTopic
Topics for a RooMsgService::StreamConfig in RooMsgService.
Definition: RooGlobalFunc.h:63
@ Minimization
Definition: RooGlobalFunc.h:63
@ FastEvaluations
Definition: RooGlobalFunc.h:65
@ Generation
Definition: RooGlobalFunc.h:63
@ NumIntegration
Definition: RooGlobalFunc.h:65
@ Optimization
Definition: RooGlobalFunc.h:64
@ DataHandling
Definition: RooGlobalFunc.h:65
@ HistFactory
Definition: RooGlobalFunc.h:65
@ InputArguments
Definition: RooGlobalFunc.h:64
@ ObjectHandling
Definition: RooGlobalFunc.h:64
@ Integration
Definition: RooGlobalFunc.h:63
@ LinkStateMgmt
Definition: RooGlobalFunc.h:63
static constexpr double pc
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