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 namespace std ;
70
71#if (__GNUC__==3&&__GNUC_MINOR__==2&&__GNUC_PATCHLEVEL__==3)
72char* operator+( streampos&, char* );
73#endif
74
76
77
78
79#ifndef USEMEMPOOLFORARGSET
81#else
82
83#include "MemPoolForRooSets.h"
84
85RooArgSet::MemPool* RooArgSet::memPool() {
87 static auto * memPool = new RooArgSet::MemPool();
88 return memPool;
89}
90
91////////////////////////////////////////////////////////////////////////////////
92/// Clear memory pool on exit to avoid reported memory leaks
93
95{
96 auto pool = memPool();
97 memPool()->teardown();
98
99 //Here, the pool might have to leak if RooArgSets are still alive.
100 if (pool->empty())
101 delete pool;
102}
103
104
105////////////////////////////////////////////////////////////////////////////////
106/// Overloaded new operator guarantees that all RooArgSets allocated with new
107/// have a unique address, a property that is exploited in several places
108/// in roofit to quickly index contents on normalization set pointers.
109/// The memory pool only allocates space for the class itself. The elements
110/// stored in the set are stored outside the pool.
111
112void* RooArgSet::operator new (size_t bytes)
113{
114 // To make sure that derived classes don't use this operator
115 if (bytes != sizeof(RooArgSet)) {
116 return ::operator new(bytes);
117 }
118
119 return memPool()->allocate(bytes);
120}
121
122
123////////////////////////////////////////////////////////////////////////////////
124/// Overloaded new operator with placement does not guarante that all
125/// RooArgSets allocated with new have a unique address, but uses the global
126/// operator.
127
128void* RooArgSet::operator new (size_t bytes, void* ptr) noexcept
129{
130 return ::operator new (bytes, ptr);
131}
132
133
134////////////////////////////////////////////////////////////////////////////////
135/// Memory is owned by pool, we need to do nothing to release it
136
137void RooArgSet::operator delete (void* ptr)
138{
139 // Decrease use count in pool that ptr is on
140 if (memPool()->deallocate(ptr))
141 return;
142
143 // Not part of any pool; use global op delete:
144 ::operator delete(ptr);
145}
146
147#endif
148
149
150////////////////////////////////////////////////////////////////////////////////
151/// Default constructor
152
155{
157}
158
159
160////////////////////////////////////////////////////////////////////////////////
161/// Constructor from a RooArgList. If the list contains multiple
162/// objects with the same name, only the first is store in the set.
163/// Warning messages will be printed for dropped items.
165 RooAbsCollection(coll.GetName())
166{
167 add(coll,true) ; // verbose to catch duplicate errors
169}
170
171
172////////////////////////////////////////////////////////////////////////////////
173/// Constructor from a RooArgSet / RooArgList and a pointer to another RooFit object.
174///
175/// \param[in] collection Collection of RooFit objects to be added. If a list contains multiple
176/// objects with the same name, only the first is stored in the set.
177/// Warning messages will be printed for dropped items.
178/// \param[in] var1 Further object to be added. If it is already in `collection`,
179/// nothing happens, and the warning message is suppressed.
180RooArgSet::RooArgSet(const RooAbsCollection& collection, const RooAbsArg* var1) :
181 RooAbsCollection(collection.GetName())
182{
183 if (var1 && !collection.contains(*var1)) {
184 add(*var1,true) ;
185 }
186 add(collection,true) ; // verbose to catch duplicate errors
188}
189
190
191////////////////////////////////////////////////////////////////////////////////
192/// Empty set constructor.
195{
197}
198
199
200////////////////////////////////////////////////////////////////////////////////
201/// Construct a set from two existing sets. The new set will not own its
202/// contents.
203RooArgSet::RooArgSet(const RooArgSet& set1, const RooArgSet& set2, const char *name) : RooAbsCollection(name)
204{
205 add(set1) ;
206 add(set2) ;
208}
209
210
211////////////////////////////////////////////////////////////////////////////////
212/// Constructor from a root TCollection. Elements in the collection that
213/// do not inherit from RooAbsArg will be skipped. A warning message
214/// will be printed for every skipped item.
215
216RooArgSet::RooArgSet(const TCollection& tcoll, const char* name) :
218{
219 for(TObject* obj : tcoll) {
220 if (!dynamic_cast<RooAbsArg*>(obj)) {
221 coutW(InputArguments) << "RooArgSet::RooArgSet(TCollection) element " << obj->GetName()
222 << " is not a RooAbsArg, ignored" << endl ;
223 continue ;
224 }
225 add(*(RooAbsArg*)obj) ;
226 }
228}
229
230
231////////////////////////////////////////////////////////////////////////////////
232/// Copy constructor. Note that a copy of a set is always non-owning,
233/// even if the source set owns its contents. To create an owning copy of
234/// a set (owning or not), use the snapshot() method.
235RooArgSet::RooArgSet(const RooArgSet& other, const char *name)
236 : RooAbsCollection(other,name)
237{
239}
240
241
242////////////////////////////////////////////////////////////////////////////////
243/// Destructor
244
246{
248}
249
250
251////////////////////////////////////////////////////////////////////////////////
252
253////////////////////////////////////////////////////////////////////////////////
254/// Get reference to an element using its name. Named element must exist in set.
255/// \throws invalid_argument if an element with the given name is not in the set.
256///
257/// Note that since most RooFit objects use an assignment operator that copies
258/// values, an expression like
259/// ```
260/// mySet["x"] = y;
261/// ```
262/// will not replace the element "x", it just assigns the values of y.
264{
265 RooAbsArg* arg = find(name) ;
266 if (!arg) {
267 coutE(InputArguments) << "RooArgSet::operator[](" << GetName() << ") ERROR: no element named " << name << " in set" << endl ;
268 throw std::invalid_argument((TString("No element named '") + name + "' in set " + GetName()).Data());
269 }
270 return *arg ;
271}
272
273
274
275////////////////////////////////////////////////////////////////////////////////
276/// Check if element with var's name is already in set
277
278bool RooArgSet::checkForDup(const RooAbsArg& var, bool silent) const
279{
280 RooAbsArg *other = find(var);
281 if (other) {
282 if (other != &var) {
283 if (!silent) {
284 // print a warning if this variable is not the same one we
285 // already have
286 coutE(InputArguments) << "RooArgSet::checkForDup: ERROR argument with name " << var.GetName() << " is already in this set" << endl;
287 }
288 }
289 // don't add duplicates
290 return true;
291 }
292 return false ;
293}
294
295
296
297
298
299
300
301////////////////////////////////////////////////////////////////////////////////
302/// Write contents of the argset to specified file.
303/// See writeToStream() for details
304
305void RooArgSet::writeToFile(const char* fileName) const
306{
307 ofstream ofs(fileName) ;
308 if (ofs.fail()) {
309 coutE(InputArguments) << "RooArgSet::writeToFile(" << GetName() << ") error opening file " << fileName << endl ;
310 return ;
311 }
312 writeToStream(ofs,false) ;
313}
314
315
316
317////////////////////////////////////////////////////////////////////////////////
318/// Read contents of the argset from specified file.
319/// See readFromStream() for details
320
321bool RooArgSet::readFromFile(const char* fileName, const char* flagReadAtt, const char* section, bool verbose)
322{
323 ifstream ifs(fileName) ;
324 if (ifs.fail()) {
325 coutE(InputArguments) << "RooArgSet::readFromFile(" << GetName() << ") error opening file " << fileName << endl ;
326 return true ;
327 }
328 return readFromStream(ifs,false,flagReadAtt,section,verbose) ;
329}
330
331
332
333
334////////////////////////////////////////////////////////////////////////////////
335/// Write the contents of the argset in ASCII form to given stream.
336///
337/// A line is written for each element contained in the form
338/// `<argName> = <argValue>`
339///
340/// The `<argValue>` part of each element is written by the arguments'
341/// writeToStream() function.
342/// \param os The stream to write to.
343/// \param compact Write only the bare values, separated by ' '.
344/// \note In compact mode, the stream cannot be read back into a RooArgSet,
345/// but only into a RooArgList, because the variable names are lost.
346/// \param section If non-null, add a section header like `[<section>]`.
347void RooArgSet::writeToStream(ostream& os, bool compact, const char* section) const
348{
349 if (section && section[0] != '\0')
350 os << '[' << section << ']' << '\n';
351
352 if (compact) {
353 for (const auto next : _list) {
354 next->writeToStream(os, true);
355 os << " ";
356 }
357 os << endl;
358 } else {
359 for (const auto next : _list) {
360 os << next->GetName() << " = " ;
361 next->writeToStream(os,false) ;
362 os << endl ;
363 }
364 }
365}
366
367
368
369
370////////////////////////////////////////////////////////////////////////////////
371/// Read the contents of the argset in ASCII form from given stream.
372///
373/// The stream is read to end-of-file and each line is assumed to be
374/// of the form
375/// \code
376/// <argName> = <argValue>
377/// \endcode
378/// Lines starting with argNames not matching any element in the list
379/// will be ignored with a warning message. In addition limited C++ style
380/// preprocessing and flow control is provided. The following constructions
381/// are recognized:
382/// \code
383/// include "include.file"
384/// \endcode
385/// Include given file, recursive inclusion OK
386/// \code
387/// if (<boolean_expression>)
388/// <name> = <value>
389/// ....
390/// else if (<boolean_expression>)
391/// ....
392/// else
393/// ....
394/// endif
395/// \endcode
396///
397/// All expressions are evaluated by RooFormula, and may involve any of
398/// the sets variables.
399/// \code
400/// echo <Message>
401/// \endcode
402/// Print console message while reading from stream
403/// \code
404/// abort
405/// \endcode
406/// Force termination of read sequence with error status
407///
408/// The value of each argument is read by the arguments readFromStream
409/// function.
410
411bool RooArgSet::readFromStream(istream& is, bool compact, const char* flagReadAtt, const char* section, bool verbose)
412{
413 if (compact) {
414 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << ") compact mode not supported" << endl ;
415 return true ;
416 }
417
418 RooStreamParser parser(is) ;
419 parser.setPunctuation("=") ;
420 TString token ;
421 bool retVal(false) ;
422
423 // Conditional stack and related state variables
424 // coverity[UNINIT]
425 bool anyCondTrue[100] ;
426 bool condStack[100] ;
427 bool lastLineWasElse=false ;
428 Int_t condStackLevel=0 ;
429 condStack[0]=true ;
430
431 // Prepare section processing
432 TString sectionHdr("[") ;
433 if (section) sectionHdr.Append(section) ;
434 sectionHdr.Append("]") ;
435 bool inSection(section?false:true) ;
436
437 bool reprocessToken = false ;
438 while (1) {
439
440 if (is.eof() || is.fail() || parser.atEOF()) {
441 break ;
442 }
443
444 // Read next token until memEnd of file
445 if (!reprocessToken) {
446 token = parser.readToken() ;
447 }
448 reprocessToken = false ;
449
450 // Skip empty lines
451 if (token.IsNull()) {
452 continue ;
453 }
454
455 // Process include directives
456 if (!token.CompareTo("include")) {
457 if (parser.atEOL()) {
458 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName()
459 << "): no filename found after include statement" << endl ;
460 return true ;
461 }
462 TString filename = parser.readLine() ;
463 ifstream incfs(filename) ;
464 if (!incfs.good()) {
465 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): cannot open include file " << filename << endl ;
466 return true ;
467 }
468 coutI(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): processing include file "
469 << filename << endl ;
470 if (readFromStream(incfs,compact,flagReadAtt,inSection?0:section,verbose)) return true ;
471 continue ;
472 }
473
474 // Process section headers if requested
475 if (*token.Data()=='[') {
476 TString hdr(token) ;
477 const char* last = token.Data() + token.Length() -1 ;
478 if (*last != ']') {
479 hdr.Append(" ") ;
480 hdr.Append(parser.readLine()) ;
481 }
482 // parser.putBackToken(token) ;
483 // token = parser.readLine() ;
484 if (section) {
485 inSection = !sectionHdr.CompareTo(hdr) ;
486 }
487 continue ;
488 }
489
490 // If section is specified, ignore all data outside specified section
491 if (!inSection) {
492 parser.zapToEnd(true) ;
493 continue ;
494 }
495
496 // Conditional statement evaluation
497 if (!token.CompareTo("if")) {
498
499 // Extract conditional expressions and check validity
500 TString expr = parser.readLine() ;
501 RooFormula form(expr,expr,*this) ;
502 if (!form.ok()) return true ;
503
504 // Evaluate expression
505 bool status = form.eval()?true:false ;
506 if (lastLineWasElse) {
507 anyCondTrue[condStackLevel] |= status ;
508 lastLineWasElse=false ;
509 } else {
510 condStackLevel++ ;
511 anyCondTrue[condStackLevel] = status ;
512 }
513 condStack[condStackLevel] = status ;
514
515 if (verbose) cxcoutD(Eval) << "RooArgSet::readFromStream(" << GetName()
516 << "): conditional expression " << expr << " = "
517 << (condStack[condStackLevel]?"true":"false") << endl ;
518 continue ; // go to next line
519 }
520
521 if (!token.CompareTo("else")) {
522 // Must have seen an if statement before
523 if (condStackLevel==0) {
524 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): unmatched 'else'" << endl ;
525 }
526
527 if (parser.atEOL()) {
528 // simple else: process if nothing else was true
529 condStack[condStackLevel] = !anyCondTrue[condStackLevel] ;
530 parser.zapToEnd(false) ;
531 continue ;
532 } else {
533 // if anything follows it should be 'if'
534 token = parser.readToken() ;
535 if (token.CompareTo("if")) {
536 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): syntax error: 'else " << token << "'" << endl ;
537 return true ;
538 } else {
539 if (anyCondTrue[condStackLevel]) {
540 // No need for further checking, true conditional already processed
541 condStack[condStackLevel] = false ;
542 parser.zapToEnd(false) ;
543 continue ;
544 } else {
545 // Process as normal 'if' no true conditional was encountered
546 reprocessToken = true ;
547 lastLineWasElse=true ;
548 continue ;
549 }
550 }
551 }
552 }
553
554 if (!token.CompareTo("endif")) {
555 // Must have seen an if statement before
556 if (condStackLevel==0) {
557 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): unmatched 'endif'" << endl ;
558 return true ;
559 }
560
561 // Decrease stack by one
562 condStackLevel-- ;
563 continue ;
564 }
565
566 // If current conditional is true
567 if (condStack[condStackLevel]) {
568
569 // Process echo statements
570 if (!token.CompareTo("echo")) {
571 TString message = parser.readLine() ;
572 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): >> " << message << endl ;
573 continue ;
574 }
575
576 // Process abort statements
577 if (!token.CompareTo("abort")) {
578 TString message = parser.readLine() ;
579 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): USER ABORT" << endl ;
580 return true ;
581 }
582
583 // Interpret the rest as <arg> = <value_expr>
584 RooAbsArg *arg ;
585
586 if ((arg = find(token)) && !arg->getAttribute("Dynamic")) {
587 if (parser.expectToken("=",true)) {
588 parser.zapToEnd(true) ;
589 retVal=true ;
590 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName()
591 << "): missing '=' sign: " << arg << endl ;
592 continue ;
593 }
594 bool argRet = arg->readFromStream(is,false,verbose) ;
595 if (!argRet && flagReadAtt) arg->setAttribute(flagReadAtt,true) ;
596 retVal |= argRet ;
597 } else {
598 if (verbose) {
599 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): argument "
600 << token << " not in list, ignored" << endl ;
601 }
602 parser.zapToEnd(true) ;
603 }
604 } else {
605 parser.readLine() ;
606 }
607 }
608
609 // Did we fully unwind the conditional stack?
610 if (condStackLevel!=0) {
611 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): missing 'endif'" << endl ;
612 return true ;
613 }
614
615 return retVal ;
616}
617
618
619bool RooArgSet::isInRange(const char* rangeSpec)
620{
621 char buf[1024] ;
622 strlcpy(buf,rangeSpec,1024) ;
623 char* token = strtok(buf,",") ;
624
625 while(token) {
626
627 bool accept=true ;
628 for (auto * lvarg : dynamic_range_cast<RooAbsRealLValue*>(*this)) {
629 if (lvarg) {
630 if (!lvarg->inRange(token)) {
631 accept=false ;
632 break ;
633 }
634 }
635 // WVE MUST HANDLE RooAbsCategoryLValue ranges as well
636 }
637 if (accept) {
638 return true ;
639 }
640
641 token = strtok(0,",") ;
642 }
643
644 return false ;
645}
646
647
#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
TString operator+(const TString &s1, const TString &s2)
Use the special concatenation constructor.
Definition TString.cxx:1519
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition RooAbsArg.h:74
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.
RooAbsCollection is an 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:80
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:201
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.
RooFormula internally uses ROOT's TFormula to compute user-defined expressions of RooAbsArgs.
Definition RooFormula.h:33
bool ok() const
Definition RooFormula.h:58
double eval(const RooArgSet *nset=nullptr) const
Evalute all parameters/observables, and then evaluate formula.
static void activate()
Install atexit handler that calls CleanupRooFitAtExit() on program termination.
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:421
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition TString.cxx:450
const char * Data() const
Definition TString.h:380
Bool_t IsNull() const
Definition TString.h:418
TString & Append(const char *cs)
Definition TString.h:576
RooConstVar & RooConst(double val)