Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooArgSet.cxx
Go to the documentation of this file.
1/***************************************************************************** * Project: RooFit *
2 * Package: RooFitCore *
3 * @(#)root/roofitcore:$Id$
4 * Authors: *
5 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
6 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
7 * *
8 * Copyright (c) 2000-2005, Regents of the University of California *
9 * and Stanford University. All rights reserved. *
10 * *
11 * Redistribution and use in source and binary forms, *
12 * with or without modification, are permitted according to the terms *
13 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
14 *****************************************************************************/
15
16//////////////////////////////////////////////////////////////////////////////
17/// \class RooArgSet
18/// RooArgSet is a container object that can hold multiple RooAbsArg objects.
19/// The container has set semantics which means that:
20///
21/// - Every object it contains must have a unique name returned by GetName().
22///
23/// - Contained objects are not ordered, although the set can be traversed
24/// using an iterator returned by createIterator(). The iterator does not
25/// necessarily follow the object insertion order.
26///
27/// - Objects can be retrieved by name only, and not by index.
28///
29///
30/// Ownership of contents
31/// -------------------------
32/// Unowned objects are inserted with the add() method. Owned objects
33/// are added with addOwned() or addClone(). A RooArgSet either owns all
34/// of it contents, or none, which is determined by the first `add`
35/// call. Once an ownership status is selected, inappropriate `add` calls
36/// will return error status. Clearing the list via removeAll() resets the
37/// ownership status. Arguments supplied in the constructor are always added
38/// as unowned elements.
39///
40///
41/// Uniquely identifying RooArgSet objects
42/// ---------------------------------------
43///
44/// \warning Before v6.28, it was ensured that no RooArgSet objects on the heap
45/// were located at an address that had already been used for a RooArgSet before.
46/// With v6.28, this is not guaranteed anymore. Hence, if your code uses pointer
47/// comparisons to uniquely identify RooArgSet instances, please consider using
48/// the new `RooArgSet::uniqueId()`.
49
50#include "RooArgSet.h"
51
52#include "RooStreamParser.h"
53#include "RooFormula.h"
54#include "RooAbsRealLValue.h"
56#include "RooStringVar.h"
57#include "RooTrace.h"
58#include "RooArgList.h"
59#include "RooSentinel.h"
60#include "RooMsgService.h"
61#include "RooConstVar.h"
62#include "strlcpy.h"
63
64#include <iostream>
65#include <fstream>
66#include <iomanip>
67#include <stdexcept>
68
69using std::istream, std::ostream, std::ifstream, std::ofstream, std::endl;
70
72
73
74
75#ifndef USEMEMPOOLFORARGSET
77#else
78
79#include "MemPoolForRooSets.h"
80
81RooArgSet::MemPool* RooArgSet::memPool() {
82 RooSentinel::activate();
83 static auto * memPool = new RooArgSet::MemPool();
84 return memPool;
85}
86
87////////////////////////////////////////////////////////////////////////////////
88/// Clear memory pool on exit to avoid reported memory leaks
89
91{
92 auto pool = memPool();
93 memPool()->teardown();
94
95 //Here, the pool might have to leak if RooArgSets are still alive.
96 if (pool->empty())
97 delete pool;
98}
99
100
101////////////////////////////////////////////////////////////////////////////////
102/// Overloaded new operator guarantees that all RooArgSets allocated with new
103/// have a unique address, a property that is exploited in several places
104/// in roofit to quickly index contents on normalization set pointers.
105/// The memory pool only allocates space for the class itself. The elements
106/// stored in the set are stored outside the pool.
107
108void* RooArgSet::operator new (size_t bytes)
109{
110 // To make sure that derived classes don't use this operator
111 if (bytes != sizeof(RooArgSet)) {
112 return ::operator new(bytes);
113 }
114
115 return memPool()->allocate(bytes);
116}
117
118
119////////////////////////////////////////////////////////////////////////////////
120/// Overloaded new operator with placement does not guarantee that all
121/// RooArgSets allocated with new have a unique address, but uses the global
122/// operator.
123
124void* RooArgSet::operator new (size_t bytes, void* ptr) noexcept
125{
126 return ::operator new (bytes, ptr);
127}
128
129
130////////////////////////////////////////////////////////////////////////////////
131/// Memory is owned by pool, we need to do nothing to release it
132
133void RooArgSet::operator delete (void* ptr)
134{
135 // Decrease use count in pool that ptr is on
136 if (memPool()->deallocate(ptr))
137 return;
138
139 // Not part of any pool; use global op delete:
140 ::operator delete(ptr);
141}
142
143#endif
144
145
146////////////////////////////////////////////////////////////////////////////////
147/// Default constructor
148
150{
152}
153
154
155////////////////////////////////////////////////////////////////////////////////
156/// Constructor from a RooArgList. If the list contains multiple
157/// objects with the same name, only the first is store in the set.
158/// Warning messages will be printed for dropped items.
160 RooAbsCollection(coll.GetName())
161{
162 add(coll,true) ; // verbose to catch duplicate errors
164}
165
166
167////////////////////////////////////////////////////////////////////////////////
168/// Constructor from a RooArgSet / RooArgList and a pointer to another RooFit object.
169///
170/// \param[in] collection Collection of RooFit objects to be added. If a list contains multiple
171/// objects with the same name, only the first is stored in the set.
172/// Warning messages will be printed for dropped items.
173/// \param[in] var1 Further object to be added. If it is already in `collection`,
174/// nothing happens, and the warning message is suppressed.
175RooArgSet::RooArgSet(const RooAbsCollection& collection, const RooAbsArg* var1) :
176 RooAbsCollection(collection.GetName())
177{
178 if (var1 && !collection.contains(*var1)) {
179 add(*var1,true) ;
180 }
181 add(collection,true) ; // verbose to catch duplicate errors
183}
184
185
186////////////////////////////////////////////////////////////////////////////////
187/// Empty set constructor.
190{
192}
193
194
195////////////////////////////////////////////////////////////////////////////////
196/// Construct a set from two existing sets. The new set will not own its
197/// contents.
198RooArgSet::RooArgSet(const RooArgSet& set1, const RooArgSet& set2, const char *name) : RooAbsCollection(name)
199{
200 add(set1) ;
201 add(set2) ;
203}
204
205
206////////////////////////////////////////////////////////////////////////////////
207/// Constructor from a root TCollection. Elements in the collection that
208/// do not inherit from RooAbsArg will be skipped. A warning message
209/// will be printed for every skipped item.
210
211RooArgSet::RooArgSet(const TCollection& tcoll, const char* name) :
213{
214 for(TObject* obj : tcoll) {
215 if (!dynamic_cast<RooAbsArg*>(obj)) {
216 coutW(InputArguments) << "RooArgSet::RooArgSet(TCollection) element " << obj->GetName()
217 << " is not a RooAbsArg, ignored" << endl ;
218 continue ;
219 }
220 add(*static_cast<RooAbsArg*>(obj)) ;
221 }
223}
224
225
226////////////////////////////////////////////////////////////////////////////////
227/// Copy constructor. Note that a copy of a set is always non-owning,
228/// even if the source set owns its contents. To create an owning copy of
229/// a set (owning or not), use the snapshot() method.
230RooArgSet::RooArgSet(const RooArgSet& other, const char *name)
231 : RooAbsCollection(other,name)
232{
234}
235
236
237////////////////////////////////////////////////////////////////////////////////
238/// Destructor
239
241{
243}
244
245
246////////////////////////////////////////////////////////////////////////////////
247
248////////////////////////////////////////////////////////////////////////////////
249/// Get reference to an element using its name. Named element must exist in set.
250/// \throws invalid_argument if an element with the given name is not in the set.
251///
252/// Note that since most RooFit objects use an assignment operator that copies
253/// values, an expression like
254/// ```
255/// mySet["x"] = y;
256/// ```
257/// will not replace the element "x", it just assigns the values of y.
259{
260 RooAbsArg* arg = find(name) ;
261 if (!arg) {
262 coutE(InputArguments) << "RooArgSet::operator[](" << GetName() << ") ERROR: no element named " << name << " in set" << endl ;
263 throw std::invalid_argument((TString("No element named '") + name + "' in set " + GetName()).Data());
264 }
265 return *arg ;
266}
267
268
269
270////////////////////////////////////////////////////////////////////////////////
271/// Check if element with var's name is already in set
272
273bool RooArgSet::checkForDup(const RooAbsArg& var, bool silent) const
274{
275 RooAbsArg *other = find(var);
276 if (other) {
277 if (other != &var) {
278 if (!silent) {
279 // print a warning if this variable is not the same one we
280 // already have
281 coutE(InputArguments) << "RooArgSet::checkForDup: ERROR argument with name " << var.GetName() << " is already in this set" << endl;
282 }
283 }
284 // don't add duplicates
285 return true;
286 }
287 return false ;
288}
289
290
291
292
293
294
295
296////////////////////////////////////////////////////////////////////////////////
297/// Write contents of the argset to specified file.
298/// See writeToStream() for details
299
300void RooArgSet::writeToFile(const char* fileName) const
301{
302 ofstream ofs(fileName) ;
303 if (ofs.fail()) {
304 coutE(InputArguments) << "RooArgSet::writeToFile(" << GetName() << ") error opening file " << fileName << endl ;
305 return ;
306 }
307 writeToStream(ofs,false) ;
308}
309
310
311
312////////////////////////////////////////////////////////////////////////////////
313/// Read contents of the argset from specified file.
314/// See readFromStream() for details
315
316bool RooArgSet::readFromFile(const char* fileName, const char* flagReadAtt, const char* section, bool verbose)
317{
318 ifstream ifs(fileName) ;
319 if (ifs.fail()) {
320 coutE(InputArguments) << "RooArgSet::readFromFile(" << GetName() << ") error opening file " << fileName << endl ;
321 return true ;
322 }
323 return readFromStream(ifs,false,flagReadAtt,section,verbose) ;
324}
325
326
327
328
329////////////////////////////////////////////////////////////////////////////////
330/// Write the contents of the argset in ASCII form to given stream.
331///
332/// A line is written for each element contained in the form
333/// `<argName> = <argValue>`
334///
335/// The `<argValue>` part of each element is written by the arguments'
336/// writeToStream() function.
337/// \param os The stream to write to.
338/// \param compact Write only the bare values, separated by ' '.
339/// \note In compact mode, the stream cannot be read back into a RooArgSet,
340/// but only into a RooArgList, because the variable names are lost.
341/// \param section If non-null, add a section header like `[<section>]`.
342void RooArgSet::writeToStream(ostream& os, bool compact, const char* section) const
343{
344 if (section && section[0] != '\0')
345 os << '[' << section << ']' << '\n';
346
347 if (compact) {
348 for (const auto next : _list) {
349 next->writeToStream(os, true);
350 os << " ";
351 }
352 os << endl;
353 } else {
354 for (const auto next : _list) {
355 os << next->GetName() << " = " ;
356 next->writeToStream(os,false) ;
357 os << endl ;
358 }
359 }
360}
361
362
363
364
365////////////////////////////////////////////////////////////////////////////////
366/// Read the contents of the argset in ASCII form from given stream.
367///
368/// The stream is read to end-of-file and each line is assumed to be
369/// of the form
370/// \code
371/// <argName> = <argValue>
372/// \endcode
373/// Lines starting with argNames not matching any element in the list
374/// will be ignored with a warning message. In addition limited C++ style
375/// preprocessing and flow control is provided. The following constructions
376/// are recognized:
377/// \code
378/// include "include.file"
379/// \endcode
380/// Include given file, recursive inclusion OK
381/// \code
382/// if (<boolean_expression>)
383/// <name> = <value>
384/// ....
385/// else if (<boolean_expression>)
386/// ....
387/// else
388/// ....
389/// endif
390/// \endcode
391///
392/// All expressions are evaluated by RooFormula, and may involve any of
393/// the sets variables.
394/// \code
395/// echo <Message>
396/// \endcode
397/// Print console message while reading from stream
398/// \code
399/// abort
400/// \endcode
401/// Force termination of read sequence with error status
402///
403/// The value of each argument is read by the arguments readFromStream
404/// function.
405
406bool RooArgSet::readFromStream(istream& is, bool compact, const char* flagReadAtt, const char* section, bool verbose)
407{
408 if (compact) {
409 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << ") compact mode not supported" << endl ;
410 return true ;
411 }
412
413 RooStreamParser parser(is) ;
414 parser.setPunctuation("=") ;
415 TString token ;
416 bool retVal(false) ;
417
418 // Conditional stack and related state variables
419 // coverity[UNINIT]
420 bool anyCondTrue[100] ;
421 bool condStack[100] ;
422 bool lastLineWasElse=false ;
423 Int_t condStackLevel=0 ;
424 condStack[0]=true ;
425
426 // Prepare section processing
427 TString sectionHdr("[") ;
428 if (section) sectionHdr.Append(section) ;
429 sectionHdr.Append("]") ;
430 bool inSection(section?false:true) ;
431
432 bool reprocessToken = false ;
433 while (true) {
434
435 if (is.eof() || is.fail() || parser.atEOF()) {
436 break ;
437 }
438
439 // Read next token until memEnd of file
440 if (!reprocessToken) {
441 token = parser.readToken() ;
442 }
443 reprocessToken = false ;
444
445 // Skip empty lines
446 if (token.IsNull()) {
447 continue ;
448 }
449
450 // Process include directives
451 if (!token.CompareTo("include")) {
452 if (parser.atEOL()) {
453 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName()
454 << "): no filename found after include statement" << endl ;
455 return true ;
456 }
457 TString filename = parser.readLine() ;
458 ifstream incfs(filename) ;
459 if (!incfs.good()) {
460 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): cannot open include file " << filename << endl ;
461 return true ;
462 }
463 coutI(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): processing include file "
464 << filename << endl ;
465 if (readFromStream(incfs,compact,flagReadAtt,inSection?nullptr:section,verbose)) return true ;
466 continue ;
467 }
468
469 // Process section headers if requested
470 if (*token.Data()=='[') {
471 TString hdr(token) ;
472 const char* last = token.Data() + token.Length() -1 ;
473 if (*last != ']') {
474 hdr.Append(" ") ;
475 hdr.Append(parser.readLine()) ;
476 }
477 // parser.putBackToken(token) ;
478 // token = parser.readLine() ;
479 if (section) {
480 inSection = !sectionHdr.CompareTo(hdr) ;
481 }
482 continue ;
483 }
484
485 // If section is specified, ignore all data outside specified section
486 if (!inSection) {
487 parser.zapToEnd(true) ;
488 continue ;
489 }
490
491 // Conditional statement evaluation
492 if (!token.CompareTo("if")) {
493
494 // Extract conditional expressions and check validity
495 TString expr = parser.readLine() ;
496 RooFormula form(expr,expr,*this) ;
497 if (!form.ok()) return true ;
498
499 // Evaluate expression
500 bool status = form.eval()?true:false ;
501 if (lastLineWasElse) {
502 anyCondTrue[condStackLevel] |= status ;
503 lastLineWasElse=false ;
504 } else {
505 condStackLevel++ ;
506 anyCondTrue[condStackLevel] = status ;
507 }
508 condStack[condStackLevel] = status ;
509
510 if (verbose) {
511 cxcoutD(Eval) << "RooArgSet::readFromStream(" << GetName() << "): conditional expression " << expr << " = "
512 << (condStack[condStackLevel] ? "true" : "false") << endl;
513 }
514 continue ; // go to next line
515 }
516
517 if (!token.CompareTo("else")) {
518 // Must have seen an if statement before
519 if (condStackLevel==0) {
520 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): unmatched 'else'" << endl ;
521 }
522
523 if (parser.atEOL()) {
524 // simple else: process if nothing else was true
525 condStack[condStackLevel] = !anyCondTrue[condStackLevel] ;
526 parser.zapToEnd(false) ;
527 continue ;
528 } else {
529 // if anything follows it should be 'if'
530 token = parser.readToken() ;
531 if (token.CompareTo("if")) {
532 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): syntax error: 'else " << token << "'" << endl ;
533 return true ;
534 } else {
535 if (anyCondTrue[condStackLevel]) {
536 // No need for further checking, true conditional already processed
537 condStack[condStackLevel] = false ;
538 parser.zapToEnd(false) ;
539 continue ;
540 } else {
541 // Process as normal 'if' no true conditional was encountered
542 reprocessToken = true ;
543 lastLineWasElse=true ;
544 continue ;
545 }
546 }
547 }
548 }
549
550 if (!token.CompareTo("endif")) {
551 // Must have seen an if statement before
552 if (condStackLevel==0) {
553 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): unmatched 'endif'" << endl ;
554 return true ;
555 }
556
557 // Decrease stack by one
558 condStackLevel-- ;
559 continue ;
560 }
561
562 // If current conditional is true
563 if (condStack[condStackLevel]) {
564
565 // Process echo statements
566 if (!token.CompareTo("echo")) {
567 TString message = parser.readLine() ;
568 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): >> " << message << endl ;
569 continue ;
570 }
571
572 // Process abort statements
573 if (!token.CompareTo("abort")) {
574 TString message = parser.readLine() ;
575 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): USER ABORT" << endl ;
576 return true ;
577 }
578
579 // Interpret the rest as <arg> = <value_expr>
580 RooAbsArg *arg ;
581
582 if ((arg = find(token)) && !arg->getAttribute("Dynamic")) {
583 if (parser.expectToken("=",true)) {
584 parser.zapToEnd(true) ;
585 retVal=true ;
586 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName()
587 << "): missing '=' sign: " << arg << endl ;
588 continue ;
589 }
590 bool argRet = arg->readFromStream(is,false,verbose) ;
591 if (!argRet && flagReadAtt) arg->setAttribute(flagReadAtt,true) ;
592 retVal |= argRet ;
593 } else {
594 if (verbose) {
595 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): argument "
596 << token << " not in list, ignored" << endl ;
597 }
598 parser.zapToEnd(true) ;
599 }
600 } else {
601 parser.readLine() ;
602 }
603 }
604
605 // Did we fully unwind the conditional stack?
606 if (condStackLevel!=0) {
607 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): missing 'endif'" << endl ;
608 return true ;
609 }
610
611 return retVal ;
612}
613
614
615bool RooArgSet::isInRange(const char* rangeSpec)
616{
617 char buf[1024] ;
618 strlcpy(buf,rangeSpec,1024) ;
619 char* token = strtok(buf,",") ;
620
621 while(token) {
622
623 bool accept=true ;
624 for (auto * lvarg : dynamic_range_cast<RooAbsRealLValue*>(*this)) {
625 if (lvarg) {
626 if (!lvarg->inRange(token)) {
627 accept=false ;
628 break ;
629 }
630 }
631 // WVE MUST HANDLE RooAbsCategoryLValue ranges as well
632 }
633 if (accept) {
634 return true ;
635 }
636
637 token = strtok(nullptr,",") ;
638 }
639
640 return false ;
641}
642
643
#define coutI(a)
#define cxcoutD(a)
#define coutW(a)
#define coutE(a)
#define TRACE_DESTROY
Definition RooTrace.h:24
#define TRACE_CREATE
Definition RooTrace.h:23
#define ClassImp(name)
Definition Rtypes.h:377
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t bytes
char name[80]
Definition TGX11.cxx:110
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:77
virtual bool readFromStream(std::istream &is, bool compact, bool verbose=false)=0
bool getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
void setAttribute(const Text_t *name, bool value=true)
Set (default) or clear a named boolean attribute of this object.
Abstract container object that can hold multiple RooAbsArg objects.
bool contains(const RooAbsArg &var) const
Check if collection contains an argument with the same name as var.
const char * GetName() const override
Returns name of object.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t _list
Actual object storage.
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
bool isInRange(const char *rangeSpec)
bool checkForDup(const RooAbsArg &arg, bool silent) const
Check if element with var's name is already in set.
RooArgSet()
Default constructor.
~RooArgSet() override
Destructor.
void writeToFile(const char *fileName) const
Write contents of the argset to specified file.
bool readFromFile(const char *fileName, const char *flagReadAtt=nullptr, const char *section=nullptr, bool verbose=false)
Read contents of the argset from specified file.
static void cleanup()
Definition RooArgSet.cxx:76
virtual bool readFromStream(std::istream &is, bool compact, bool verbose=false)
Shortcut for readFromStream(std::istream&, bool, const char*, const char*, bool), setting flagReadAtt...
Definition RooArgSet.h:158
void processArg(const RooAbsArg &arg)
Definition RooArgSet.h:209
RooAbsArg & operator[](const TString &str) const
Get reference to an element using its name.
virtual void writeToStream(std::ostream &os, bool compact, const char *section=nullptr) const
Write the contents of the argset in ASCII form to given stream.
Internally uses ROOT's TFormula to compute user-defined expressions of RooAbsArgs.
Definition RooFormula.h:27
bool ok() const
Definition RooFormula.h:50
double eval(const RooArgSet *nset=nullptr) const
Evaluate all parameters/observables, and then evaluate formula.
void setPunctuation(const TString &punct)
Change list of characters interpreted as punctuation.
bool expectToken(const TString &expected, bool zapOnError=false)
Read the next token and return true if it is identical to the given 'expected' token.
bool atEOL()
If true, parser is at end of line in stream.
TString readLine()
Read an entire line from the stream and return as TString This method recognizes the use of '\' in th...
TString readToken()
Read one token separated by any of the know punctuation characters This function recognizes and handl...
void zapToEnd(bool inclContLines=false)
Eat all characters up to and including then end of the current line.
Collection abstract base class.
Definition TCollection.h:65
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
Mother of all ROOT objects.
Definition TObject.h:41
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition TString.cxx:457
const char * Data() const
Definition TString.h:376
Bool_t IsNull() const
Definition TString.h:414
TString & Append(const char *cs)
Definition TString.h:572
RooConstVar & RooConst(double val)