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
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() {
86 RooSentinel::activate();
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 guarantee 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
154{
156}
157
158
159////////////////////////////////////////////////////////////////////////////////
160/// Constructor from a RooArgList. If the list contains multiple
161/// objects with the same name, only the first is store in the set.
162/// Warning messages will be printed for dropped items.
164 RooAbsCollection(coll.GetName())
165{
166 add(coll,true) ; // verbose to catch duplicate errors
168}
169
170
171////////////////////////////////////////////////////////////////////////////////
172/// Constructor from a RooArgSet / RooArgList and a pointer to another RooFit object.
173///
174/// \param[in] collection Collection of RooFit objects to be added. If a list contains multiple
175/// objects with the same name, only the first is stored in the set.
176/// Warning messages will be printed for dropped items.
177/// \param[in] var1 Further object to be added. If it is already in `collection`,
178/// nothing happens, and the warning message is suppressed.
179RooArgSet::RooArgSet(const RooAbsCollection& collection, const RooAbsArg* var1) :
180 RooAbsCollection(collection.GetName())
181{
182 if (var1 && !collection.contains(*var1)) {
183 add(*var1,true) ;
184 }
185 add(collection,true) ; // verbose to catch duplicate errors
187}
188
189
190////////////////////////////////////////////////////////////////////////////////
191/// Empty set constructor.
194{
196}
197
198
199////////////////////////////////////////////////////////////////////////////////
200/// Construct a set from two existing sets. The new set will not own its
201/// contents.
202RooArgSet::RooArgSet(const RooArgSet& set1, const RooArgSet& set2, const char *name) : RooAbsCollection(name)
203{
204 add(set1) ;
205 add(set2) ;
207}
208
209
210////////////////////////////////////////////////////////////////////////////////
211/// Constructor from a root TCollection. Elements in the collection that
212/// do not inherit from RooAbsArg will be skipped. A warning message
213/// will be printed for every skipped item.
214
215RooArgSet::RooArgSet(const TCollection& tcoll, const char* name) :
217{
218 for(TObject* obj : tcoll) {
219 if (!dynamic_cast<RooAbsArg*>(obj)) {
220 coutW(InputArguments) << "RooArgSet::RooArgSet(TCollection) element " << obj->GetName()
221 << " is not a RooAbsArg, ignored" << endl ;
222 continue ;
223 }
224 add(*static_cast<RooAbsArg*>(obj)) ;
225 }
227}
228
229
230////////////////////////////////////////////////////////////////////////////////
231/// Copy constructor. Note that a copy of a set is always non-owning,
232/// even if the source set owns its contents. To create an owning copy of
233/// a set (owning or not), use the snapshot() method.
234RooArgSet::RooArgSet(const RooArgSet& other, const char *name)
235 : RooAbsCollection(other,name)
236{
238}
239
240
241////////////////////////////////////////////////////////////////////////////////
242/// Destructor
243
245{
247}
248
249
250////////////////////////////////////////////////////////////////////////////////
251
252////////////////////////////////////////////////////////////////////////////////
253/// Get reference to an element using its name. Named element must exist in set.
254/// \throws invalid_argument if an element with the given name is not in the set.
255///
256/// Note that since most RooFit objects use an assignment operator that copies
257/// values, an expression like
258/// ```
259/// mySet["x"] = y;
260/// ```
261/// will not replace the element "x", it just assigns the values of y.
263{
264 RooAbsArg* arg = find(name) ;
265 if (!arg) {
266 coutE(InputArguments) << "RooArgSet::operator[](" << GetName() << ") ERROR: no element named " << name << " in set" << endl ;
267 throw std::invalid_argument((TString("No element named '") + name + "' in set " + GetName()).Data());
268 }
269 return *arg ;
270}
271
272
273
274////////////////////////////////////////////////////////////////////////////////
275/// Check if element with var's name is already in set
276
277bool RooArgSet::checkForDup(const RooAbsArg& var, bool silent) const
278{
279 RooAbsArg *other = find(var);
280 if (other) {
281 if (other != &var) {
282 if (!silent) {
283 // print a warning if this variable is not the same one we
284 // already have
285 coutE(InputArguments) << "RooArgSet::checkForDup: ERROR argument with name " << var.GetName() << " is already in this set" << endl;
286 }
287 }
288 // don't add duplicates
289 return true;
290 }
291 return false ;
292}
293
294
295
296
297
298
299
300////////////////////////////////////////////////////////////////////////////////
301/// Write contents of the argset to specified file.
302/// See writeToStream() for details
303
304void RooArgSet::writeToFile(const char* fileName) const
305{
306 ofstream ofs(fileName) ;
307 if (ofs.fail()) {
308 coutE(InputArguments) << "RooArgSet::writeToFile(" << GetName() << ") error opening file " << fileName << endl ;
309 return ;
310 }
311 writeToStream(ofs,false) ;
312}
313
314
315
316////////////////////////////////////////////////////////////////////////////////
317/// Read contents of the argset from specified file.
318/// See readFromStream() for details
319
320bool RooArgSet::readFromFile(const char* fileName, const char* flagReadAtt, const char* section, bool verbose)
321{
322 ifstream ifs(fileName) ;
323 if (ifs.fail()) {
324 coutE(InputArguments) << "RooArgSet::readFromFile(" << GetName() << ") error opening file " << fileName << endl ;
325 return true ;
326 }
327 return readFromStream(ifs,false,flagReadAtt,section,verbose) ;
328}
329
330
331
332
333////////////////////////////////////////////////////////////////////////////////
334/// Write the contents of the argset in ASCII form to given stream.
335///
336/// A line is written for each element contained in the form
337/// `<argName> = <argValue>`
338///
339/// The `<argValue>` part of each element is written by the arguments'
340/// writeToStream() function.
341/// \param os The stream to write to.
342/// \param compact Write only the bare values, separated by ' '.
343/// \note In compact mode, the stream cannot be read back into a RooArgSet,
344/// but only into a RooArgList, because the variable names are lost.
345/// \param section If non-null, add a section header like `[<section>]`.
346void RooArgSet::writeToStream(ostream& os, bool compact, const char* section) const
347{
348 if (section && section[0] != '\0')
349 os << '[' << section << ']' << '\n';
350
351 if (compact) {
352 for (const auto next : _list) {
353 next->writeToStream(os, true);
354 os << " ";
355 }
356 os << endl;
357 } else {
358 for (const auto next : _list) {
359 os << next->GetName() << " = " ;
360 next->writeToStream(os,false) ;
361 os << endl ;
362 }
363 }
364}
365
366
367
368
369////////////////////////////////////////////////////////////////////////////////
370/// Read the contents of the argset in ASCII form from given stream.
371///
372/// The stream is read to end-of-file and each line is assumed to be
373/// of the form
374/// \code
375/// <argName> = <argValue>
376/// \endcode
377/// Lines starting with argNames not matching any element in the list
378/// will be ignored with a warning message. In addition limited C++ style
379/// preprocessing and flow control is provided. The following constructions
380/// are recognized:
381/// \code
382/// include "include.file"
383/// \endcode
384/// Include given file, recursive inclusion OK
385/// \code
386/// if (<boolean_expression>)
387/// <name> = <value>
388/// ....
389/// else if (<boolean_expression>)
390/// ....
391/// else
392/// ....
393/// endif
394/// \endcode
395///
396/// All expressions are evaluated by RooFormula, and may involve any of
397/// the sets variables.
398/// \code
399/// echo <Message>
400/// \endcode
401/// Print console message while reading from stream
402/// \code
403/// abort
404/// \endcode
405/// Force termination of read sequence with error status
406///
407/// The value of each argument is read by the arguments readFromStream
408/// function.
409
410bool RooArgSet::readFromStream(istream& is, bool compact, const char* flagReadAtt, const char* section, bool verbose)
411{
412 if (compact) {
413 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << ") compact mode not supported" << endl ;
414 return true ;
415 }
416
417 RooStreamParser parser(is) ;
418 parser.setPunctuation("=") ;
419 TString token ;
420 bool retVal(false) ;
421
422 // Conditional stack and related state variables
423 // coverity[UNINIT]
424 bool anyCondTrue[100] ;
425 bool condStack[100] ;
426 bool lastLineWasElse=false ;
427 Int_t condStackLevel=0 ;
428 condStack[0]=true ;
429
430 // Prepare section processing
431 TString sectionHdr("[") ;
432 if (section) sectionHdr.Append(section) ;
433 sectionHdr.Append("]") ;
434 bool inSection(section?false:true) ;
435
436 bool reprocessToken = false ;
437 while (true) {
438
439 if (is.eof() || is.fail() || parser.atEOF()) {
440 break ;
441 }
442
443 // Read next token until memEnd of file
444 if (!reprocessToken) {
445 token = parser.readToken() ;
446 }
447 reprocessToken = false ;
448
449 // Skip empty lines
450 if (token.IsNull()) {
451 continue ;
452 }
453
454 // Process include directives
455 if (!token.CompareTo("include")) {
456 if (parser.atEOL()) {
457 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName()
458 << "): no filename found after include statement" << endl ;
459 return true ;
460 }
461 TString filename = parser.readLine() ;
462 ifstream incfs(filename) ;
463 if (!incfs.good()) {
464 coutE(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): cannot open include file " << filename << endl ;
465 return true ;
466 }
467 coutI(InputArguments) << "RooArgSet::readFromStream(" << GetName() << "): processing include file "
468 << filename << endl ;
469 if (readFromStream(incfs,compact,flagReadAtt,inSection?nullptr:section,verbose)) return true ;
470 continue ;
471 }
472
473 // Process section headers if requested
474 if (*token.Data()=='[') {
475 TString hdr(token) ;
476 const char* last = token.Data() + token.Length() -1 ;
477 if (*last != ']') {
478 hdr.Append(" ") ;
479 hdr.Append(parser.readLine()) ;
480 }
481 // parser.putBackToken(token) ;
482 // token = parser.readLine() ;
483 if (section) {
484 inSection = !sectionHdr.CompareTo(hdr) ;
485 }
486 continue ;
487 }
488
489 // If section is specified, ignore all data outside specified section
490 if (!inSection) {
491 parser.zapToEnd(true) ;
492 continue ;
493 }
494
495 // Conditional statement evaluation
496 if (!token.CompareTo("if")) {
497
498 // Extract conditional expressions and check validity
499 TString expr = parser.readLine() ;
500 RooFormula form(expr,expr,*this) ;
501 if (!form.ok()) return true ;
502
503 // Evaluate expression
504 bool status = form.eval()?true:false ;
505 if (lastLineWasElse) {
506 anyCondTrue[condStackLevel] |= status ;
507 lastLineWasElse=false ;
508 } else {
509 condStackLevel++ ;
510 anyCondTrue[condStackLevel] = status ;
511 }
512 condStack[condStackLevel] = status ;
513
514 if (verbose) {
515 cxcoutD(Eval) << "RooArgSet::readFromStream(" << GetName() << "): conditional expression " << expr << " = "
516 << (condStack[condStackLevel] ? "true" : "false") << endl;
517 }
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(nullptr,",") ;
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:1541
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: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.
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)