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
115 _showPid = kFALSE ;
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_t flag=kTRUE) <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,kTRUE) ;
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(kTRUE)) {
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_t 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 = kTRUE ;
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 kFALSE ;
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 kFALSE ;
449 if (level<minLevel) return kFALSE ;
450 if (!(topic&top)) return kFALSE ;
451
452 if (universal) return kTRUE ;
453
454 if (objectName.size()>0 && objectName != obj->GetName()) return kFALSE ;
455 if (className.size()>0 && className != obj->IsA()->GetName()) return kFALSE ;
456 if (baseClassName.size()>0 && !obj->IsA()->InheritsFrom(baseClassName.c_str())) return kFALSE ;
457 if (tagName.size()>0 && !obj->getAttribute(tagName.c_str())) return kFALSE ;
458
459 return kTRUE ;
460}
461
462
463////////////////////////////////////////////////////////////////////////////////
464/// Determine if message from given object at given level on given topic is logged
465
467{
468 if (!active) return kFALSE ;
469 if (level<minLevel) return kFALSE ;
470 if (!(topic&top)) return kFALSE ;
471
472 if (universal) return kTRUE ;
473
474 if (objectName.size()>0 && objectName != obj->GetName()) return kFALSE ;
475 if (className.size()>0 && className != obj->IsA()->GetName()) return kFALSE ;
476 if (baseClassName.size()>0 && !obj->IsA()->InheritsFrom(baseClassName.c_str())) return kFALSE ;
477
478 return kTRUE ;
479}
480
481
482
483////////////////////////////////////////////////////////////////////////////////
484/// Log error message associated with RooAbsArg object self at given level and topic. If skipPrefix
485/// is true the standard RooMsgService prefix is not added.
486
487ostream& RooMsgService::log(const RooAbsArg* self, RooFit::MsgLevel level, RooFit::MsgTopic topic, Bool_t skipPrefix)
488{
489 if (level>=ERROR) {
490 _errorCount++ ;
491 }
492
493 // Return C++ ostream associated with given message configuration
494 Int_t as = activeStream(self,topic,level) ;
495
496 if (as==-1) {
497 return *_devnull ;
498 }
499
500 // Flush any previous messages
501 (*_streams[as].os).flush() ;
502
503 // Insert an endl if we switch from progress to another level
504 if (_lastMsgLevel==PROGRESS && level!=PROGRESS) {
505 (*_streams[as].os) << endl ;
506 }
507 _lastMsgLevel=level ;
508
509 if (_streams[as].prefix && !skipPrefix) {
510 if (_showPid) {
511 (*_streams[as].os) << "pid" << gSystem->GetPid() << " " ;
512 }
513 (*_streams[as].os) << "[#" << as << "] " << _levelNames[level] << ":" << _topicNames[topic] << " -- " ;
514 }
515 return (*_streams[as].os) ;
516}
517
518
519
520////////////////////////////////////////////////////////////////////////////////
521/// Log error message associated with TObject object self at given level and topic. If skipPrefix
522/// is true the standard RooMsgService prefix is not added.
523
524ostream& RooMsgService::log(const TObject* self, RooFit::MsgLevel level, RooFit::MsgTopic topic, Bool_t skipPrefix)
525{
526 if (level>=ERROR) {
527 _errorCount++ ;
528 }
529
530 // Return C++ ostream associated with given message configuration
531 Int_t as = activeStream(self,topic,level) ;
532 if (as==-1) {
533 return *_devnull ;
534 }
535
536 // Flush any previous messages
537 (*_streams[as].os).flush() ;
538
539 if (_streams[as].prefix && !skipPrefix) {
540 if (_showPid) {
541 (*_streams[as].os) << "pid" << gSystem->GetPid() << " " ;
542 }
543 (*_streams[as].os) << "[#" << as << "] " << _levelNames[level] << ":" << _topicNames[topic] << " -- " ;
544 }
545 return (*_streams[as].os) ;
546}
547
548
549
550////////////////////////////////////////////////////////////////////////////////
551/// Print configuration of message service. If "v" option is given also
552/// inactive streams are listed
553
554void RooMsgService::Print(Option_t *options) const
555{
556 Bool_t activeOnly = kTRUE ;
557 if (TString(options).Contains("V") || TString(options).Contains("v")) {
558 activeOnly = kFALSE ;
559 }
560
561 cout << (activeOnly?"Active Message streams":"All Message streams") << endl ;
562 for (UInt_t i=0 ; i<_streams.size() ; i++) {
563
564 // Skip passive streams in active only mode
565 if (activeOnly && !_streams[i].active) {
566 continue ;
567 }
568
569
570 map<int,string>::const_iterator is = _levelNames.find(_streams[i].minLevel) ;
571 cout << "[" << i << "] MinLevel = " << is->second ;
572
573 cout << " Topic = " ;
574 if (_streams[i].topic != 0xFFFFF) {
575 map<int,string>::const_iterator iter = _topicNames.begin() ;
576 while(iter!=_topicNames.end()) {
577 if (iter->first & _streams[i].topic) {
578 cout << iter->second << " " ;
579 }
580 ++iter ;
581 }
582 } else {
583 cout << " Any " ;
584 }
585
586
587 if (_streams[i].objectName.size()>0) {
588 cout << " ObjectName = " << _streams[i].objectName ;
589 }
590 if (_streams[i].className.size()>0) {
591 cout << " ClassName = " << _streams[i].className ;
592 }
593 if (_streams[i].baseClassName.size()>0) {
594 cout << " BaseClassName = " << _streams[i].baseClassName ;
595 }
596 if (_streams[i].tagName.size()>0) {
597 cout << " TagLabel = " << _streams[i].tagName ;
598 }
599
600 // Postfix status when printing all
601 if (!activeOnly && !_streams[i].active) {
602 cout << " (NOT ACTIVE)" ;
603 }
604
605 cout << endl ;
606 }
607
608}
#define DEBUG
Definition: Polynomial.cxx:40
int Int_t
Definition: RtypesCore.h:45
const Bool_t kFALSE
Definition: RtypesCore.h:101
short Color_t
Definition: RtypesCore.h:92
const Bool_t kTRUE
Definition: RtypesCore.h:100
const char Option_t
Definition: RtypesCore.h:66
#define ClassImp(name)
Definition: Rtypes.h:364
@ kBlack
Definition: Rtypes.h:65
XFontStruct * id
Definition: TGX11.cxx:109
char * Form(const char *fmt,...)
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:75
Bool_t getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
Definition: RooAbsArg.cxx:307
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:28
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
void setStreamStatus(Int_t id, Bool_t active)
(De)Activate stream with given unique ID
Bool_t getStreamStatus(Int_t id) const
Get activation status of stream with given unique ID.
static RooMsgService & instance()
Return reference to singleton instance.
static Int_t _debugCount
RooFit::MsgLevel _globMinLevel
Bool_t isActive(const RooAbsArg *self, RooFit::MsgTopic facility, RooFit::MsgLevel level)
Check if logging is active for given object/topic/RooFit::MsgLevel combination.
std::stack< std::vector< StreamConfig > > _streamsSaved
RooMsgService()
Constructor.
Bool_t _silentMode
RooWorkspace * debugWorkspace()
void saveState()
Save current state of message service.
std::map< int, std::string > _topicNames
std::ostream & log(const RooAbsArg *self, RooFit::MsgLevel level, RooFit::MsgTopic facility, Bool_t forceSkipPrefix=kFALSE)
Log error message associated with RooAbsArg object self at given level and topic.
RooWorkspace * _debugWorkspace
static Bool_t anyDebug()
Returns true if any debug level stream is active.
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.
virtual ~RooMsgService()
Destructor.
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.
void Print(Option_t *options=0) const
Print configuration of message service.
RooFit::MsgLevel _lastMsgLevel
The RooWorkspace is a persistable container for RooFit projects.
Definition: RooWorkspace.h:43
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:445
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:68
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:58
MsgTopic
Topics for a RooMsgService::StreamConfig in RooMsgService.
Definition: RooGlobalFunc.h:60
@ Minimization
Definition: RooGlobalFunc.h:60
@ FastEvaluations
Definition: RooGlobalFunc.h:62
@ Generation
Definition: RooGlobalFunc.h:60
@ NumIntegration
Definition: RooGlobalFunc.h:62
@ Optimization
Definition: RooGlobalFunc.h:61
@ DataHandling
Definition: RooGlobalFunc.h:62
@ HistFactory
Definition: RooGlobalFunc.h:62
@ InputArguments
Definition: RooGlobalFunc.h:61
@ ObjectHandling
Definition: RooGlobalFunc.h:61
@ Integration
Definition: RooGlobalFunc.h:60
@ LinkStateMgmt
Definition: RooGlobalFunc.h:60
static constexpr double pc
Wrap an object into a TObject. Sometimes needed to avoid reinterpret_cast or enable RTTI.
Definition: RooHelpers.h:65
Bool_t match(RooFit::MsgLevel level, RooFit::MsgTopic facility, const RooAbsArg *obj)
Determine if message from given object at given level on given topic is logged.
auto * l
Definition: textangle.C:4