Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooAbsRealLValue.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 RooAbsRealLValue.cxx
19\class RooAbsRealLValue
20\ingroup Roofitcore
21
22Abstract base class for objects that represent a
23real value that may appear on the left hand side of an equation ('lvalue').
24Each implementation must provide a setVal() member to allow direct modification
25of the value. RooAbsRealLValue may be derived, but its functional relation
26to other RooAbsArg must be invertible
27
28This class has methods that export the defined range of the lvalue,
29but doesn't hold its values because these limits may be derived
30from limits of client object. The range serve as integration
31range when interpreted as a observable and a boundaries when
32interpreted as a parameter.
33**/
34
35#include "RooAbsRealLValue.h"
36
37#include "RooStreamParser.h"
38#include "RooRandom.h"
39#include "RooPlot.h"
40#include "RooArgList.h"
41#include "RooAbsBinning.h"
42#include "RooBinning.h"
43#include "RooNumber.h"
44#include "RooUniformBinning.h"
45#include "RooCmdConfig.h"
46#include "RooAbsData.h"
47#include "RooRealVar.h"
48#include "RooMsgService.h"
49
50#include "ROOT/StringUtils.hxx"
51
52#include "TH1.h"
53#include "TH2.h"
54#include "TH3.h"
55
56#include <cmath>
57
58using std::endl, std::istream, std::ostream;
59
60
61////////////////////////////////////////////////////////////////////////////////
62/// Constructor
63
64RooAbsRealLValue::RooAbsRealLValue(const char *name, const char *title, const char *unit) :
65 RooAbsReal(name, title, 0, 0, unit)
66{
67}
68
69
70
71////////////////////////////////////////////////////////////////////////////////
72/// Copy constructor
73
78
79////////////////////////////////////////////////////////////////////////////////
80/// Return true if the input value is within our fit range. Otherwise, return
81/// false and write a clipped value into clippedValPtr if it is non-zero.
82bool RooAbsRealLValue::inRange(double value, const char* rangeName, double* clippedValPtr) const
83{
84 // double range = getMax() - getMin() ; // ok for +/-INFINITY
85 double clippedValue(value);
86 bool isInRange(true) ;
87
88 const RooAbsBinning& binning = getBinning(rangeName) ;
89 double min = binning.lowBound() ;
90 double max = binning.highBound() ;
91
92 // test this value against our upper fit limit
93 if(!RooNumber::isInfinite(max) && value > max) {
94 clippedValue = max;
95 isInRange = false ;
96 }
97 // test this value against our lower fit limit
98 if(!RooNumber::isInfinite(min) && value < min) {
99 clippedValue = min ;
100 isInRange = false ;
101 }
102
104
105 return isInRange ;
106}
107
108
109////////////////////////////////////////////////////////////////////////////////
110/// Vectorized version of RooAbsRealLValue::inRange(double, const char*, double*).
111void RooAbsRealLValue::inRange(std::span<const double> values, std::string const& rangeName, std::vector<bool>& out) const {
112 if(rangeName.empty()) {
113 return;
114 }
115
116 const RooAbsBinning& binning = getBinning(rangeName.c_str()) ;
117 const double min = binning.lowBound() ;
118 const double max = binning.highBound() ;
119
120 const bool infiniteMin = RooNumber::isInfinite(min);
121 const bool infiniteMax = RooNumber::isInfinite(max);
122
123 for(std::size_t i = 0; i < values.size(); ++i) {
124 out[i] = out[i] && ((infiniteMax | (values[i] <= max)) && (infiniteMin | (values[i] >= min)));
125 }
126
127}
128
129
130////////////////////////////////////////////////////////////////////////////////
131/// Check if given value is valid
132
133bool RooAbsRealLValue::isValidReal(double value, bool verbose) const
134{
135 if (!inRange(value,nullptr)) {
136 if (verbose) {
137 coutI(InputArguments) << "RooRealVar::isValid(" << GetName() << "): value " << value << " out of range ("
138 << getMin() << " - " << getMax() << ")" << std::endl;
139 }
140 return false ;
141 }
142 return true ;
143}
144
145
146
147////////////////////////////////////////////////////////////////////////////////
148/// Read object contents from given stream
149
150bool RooAbsRealLValue::readFromStream(istream& /*is*/, bool /*compact*/, bool /*verbose*/)
151{
152 return true ;
153}
154
155
156
157////////////////////////////////////////////////////////////////////////////////
158/// Write object contents to given stream
159
160void RooAbsRealLValue::writeToStream(ostream& /*os*/, bool /*compact*/) const
161{
162}
163
164
165
166////////////////////////////////////////////////////////////////////////////////
167/// Assignment operator from a double
168
170{
171 double clipValue ;
172 // Clip
173 inRange(newValue,nullptr,&clipValue) ;
175
176 return *this ;
177}
178
179
180////////////////////////////////////////////////////////////////////////////////
181/// Create a new RooPlot on the heap with a drawing frame initialized for this
182/// object, but no plot contents. Use x.frame() as the first argument to a
183/// y.plotOn(...) method, for example. The caller is responsible for deleting
184/// the returned object.
185///
186/// <table>
187/// <tr><th> Optional arguments <th>
188/// <tr><td> Range(double lo, double hi) <td> Make plot frame for the specified range
189/// <tr><td> Range(const char* name) <td> Make plot frame for range with the specified name
190/// <tr><td> Bins(Int_t nbins) <td> Set default binning for datasets to specified number of bins
191/// <tr><td> AutoRange(const RooAbsData& data, double margin) <td> Specifies range so that all points in given data set fit
192/// inside the range with given margin.
193/// <tr><td> AutoSymRange(const RooAbsData& data, double margin) <td> Specifies range so that all points in given data set fit
194/// inside the range and center of range coincides with mean of distribution in given dataset.
195/// <tr><td> Name(const char* name) <td> Give specified name to RooPlot object
196/// <tr><td> Title(const char* title) <td> Give specified title to RooPlot object
197/// </table>
198///
200 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) const
201{
203 cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
204 cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
205 cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
206 cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
207
208 return frame(cmdList) ;
209}
210
211
212
213////////////////////////////////////////////////////////////////////////////////
214/// Back-end function for named argument frame() method
215
217{
218 // Define configuration for this method
219 RooCmdConfig pc("RooAbsRealLValue::frame(" + std::string(GetName()) + ")");
220 pc.defineDouble("min","Range",0,getMin()) ;
221 pc.defineDouble("max","Range",1,getMax()) ;
222 pc.defineInt("nbins","Bins",0, getBins()!=0 ? getBins() : DefaultNBins) ;
223 pc.defineString("rangeName","RangeWithName",0,"") ;
224 pc.defineString("name","Name",0,"") ;
225 pc.defineString("title","Title",0,"") ;
226 pc.defineMutex("Range","RangeWithName","AutoRange") ;
227 pc.defineObject("rangeData","AutoRange",0,nullptr) ;
228 pc.defineDouble("rangeMargin","AutoRange",0,0.1) ;
229 pc.defineInt("rangeSym","AutoRange",0,0) ;
230
231 // Process & check varargs
232 pc.process(cmdList) ;
233 if (!pc.ok(true)) {
234 return nullptr ;
235 }
236
237 // Extract values from named arguments
238 double xmin(getMin());
239 double xmax(getMax());
240 if (pc.hasProcessed("Range")) {
241 xmin = pc.getDouble("min") ;
242 xmax = pc.getDouble("max") ;
243 if (xmin==xmax) {
244 xmin = getMin() ;
245 xmax = getMax() ;
246 }
247 } else if (pc.hasProcessed("RangeWithName")) {
248 const char* rangeName=pc.getString("rangeName",nullptr,true) ;
251 } else if (pc.hasProcessed("AutoRange")) {
252 auto rangeData = static_cast<RooAbsData*>(pc.getObject("rangeData")) ;
253 const bool error = rangeData->getRange(*this,xmin,xmax);
254 if (error) {
255 xmin = getMin();
256 xmax = getMax();
257 }
258 if (pc.getInt("rangeSym")==0) {
259 // Regular mode: range is from xmin to xmax with given extra margin
260 double margin = pc.getDouble("rangeMargin")*(xmax-xmin) ;
261 xmin -= margin ;
262 xmax += margin ;
263 if (xmin<getMin()) xmin = getMin() ;
264 if (xmin>getMax()) xmax = getMax() ;
265 } else {
266 // Symmetric mode: range is centered at mean of distribution with enough width to include
267 // both lowest and highest point with margin
268 double dmean = rangeData->moment(const_cast<RooRealVar &>(static_cast<RooRealVar const&>(*this)),1) ;
269 double ddelta = ((xmax-dmean)>(dmean-xmin)?(xmax-dmean):(dmean-xmin))*(1+pc.getDouble("rangeMargin")) ;
270 xmin = dmean-ddelta ;
271 xmax = dmean+ddelta ;
272 if (xmin<getMin()) xmin = getMin() ;
273 if (xmin>getMax()) xmax = getMax() ;
274 }
275 } else {
276 xmin = getMin() ;
277 xmax = getMax() ;
278 }
279
280 Int_t nbins = pc.getInt("nbins") ;
281 const char* name = pc.getString("name",nullptr,true) ;
282 const char* title = pc.getString("title",nullptr,true) ;
283
284 RooPlot* theFrame = new RooPlot(*this,xmin,xmax,nbins) ;
285
286 if (name) {
287 theFrame->SetName(name) ;
288 }
289 if (title) {
290 theFrame->SetTitle(title) ;
291 }
292
293 return theFrame ;
294}
295
296
297
298////////////////////////////////////////////////////////////////////////////////
299/// Create a new RooPlot on the heap with a drawing frame initialized for this
300/// object, but no plot contents. Use x.frame() as the first argument to a
301/// y.plotOn(...) method, for example. The caller is responsible for deleting
302/// the returned object.
303
304RooPlot *RooAbsRealLValue::frame(double xlo, double xhi, Int_t nbins) const
305{
306 return new RooPlot(*this,xlo,xhi,nbins);
307}
308
309
310
311////////////////////////////////////////////////////////////////////////////////
312/// Create a new RooPlot on the heap with a drawing frame initialized for this
313/// object, but no plot contents. Use x.frame() as the first argument to a
314/// y.plotOn(...) method, for example. The caller is responsible for deleting
315/// the returned object.
316
317RooPlot *RooAbsRealLValue::frame(double xlo, double xhi) const
318{
319 return new RooPlot(*this,xlo,xhi, getBins()!=0 ? getBins() : DefaultNBins);
320}
321
322
323
324////////////////////////////////////////////////////////////////////////////////
325/// Create a new RooPlot on the heap with a drawing frame initialized for this
326/// object, but no plot contents. Use x.frame() as the first argument to a
327/// y.plotOn(...) method, for example. The caller is responsible for deleting
328/// the returned object.
329///
330/// The current fit range may not be open ended or empty.
331
333{
334 // Plot range of variable may not be infinite or empty
335 if (getMin()==getMax()) {
336 coutE(InputArguments) << "RooAbsRealLValue::frame(" << GetName() << ") ERROR: empty fit range, must specify plot range" << std::endl ;
337 return nullptr ;
338 }
340 coutE(InputArguments) << "RooAbsRealLValue::frame(" << GetName() << ") ERROR: open ended fit range, must specify plot range" << std::endl ;
341 return nullptr ;
342 }
343
344 return new RooPlot(*this,getMin(),getMax(),nbins);
345}
346
347
348
349////////////////////////////////////////////////////////////////////////////////
350/// Create a new RooPlot on the heap with a drawing frame initialized for this
351/// object, but no plot contents. Use x.frame() as the first argument to a
352/// y.plotOn(...) method, for example. The caller is responsible for deleting
353/// the returned object.
354///
355/// The current fit range may not be open ended or empty.
356
358{
359 // Plot range of variable may not be infinite or empty
360 if (getMin()==getMax()) {
361 coutE(InputArguments) << "RooAbsRealLValue::frame(" << GetName() << ") ERROR: empty fit range, must specify plot range" << std::endl ;
362 return nullptr ;
363 }
365 coutE(InputArguments) << "RooAbsRealLValue::frame(" << GetName() << ") ERROR: open ended fit range, must specify plot range" << std::endl ;
366 return nullptr ;
367 }
368
369 return new RooPlot(*this,getMin(),getMax(), getBins()!=0 ? getBins() : DefaultNBins);
370}
371
372
373
374////////////////////////////////////////////////////////////////////////////////
375/// Copy cache of another RooAbsArg to our cache
376
378{
380 setVal(_value) ; // force back-propagation
381}
382
383
384////////////////////////////////////////////////////////////////////////////////
385/// Structure printing
386
387void RooAbsRealLValue::printMultiline(ostream& os, Int_t contents, bool verbose, TString indent) const
388{
389 RooAbsReal::printMultiline(os,contents,verbose,indent);
390 os << indent << "--- RooAbsRealLValue ---" << std::endl;
391 TString unit(_unit);
392 if(!unit.IsNull()) unit.Prepend(' ');
393 os << indent << " Fit range is [ ";
394 if(hasMin()) {
395 os << getMin() << unit << " , ";
396 }
397 else {
398 os << "-INF , ";
399 }
400 if(hasMax()) {
401 os << getMax() << unit << " ]" << std::endl;
402 }
403 else {
404 os << "+INF ]" << std::endl;
405 }
406}
407
408
409
410////////////////////////////////////////////////////////////////////////////////
411/// Set a new value sampled from a uniform distribution over the fit range.
412/// Prints a warning and does nothing if the fit range is not finite.
413
415{
417 double min = binning.lowBound() ;
418 double max = binning.highBound() ;
419
421 setValFast(min + RooRandom::uniform()*(max-min));
422 }
423 else {
424 coutE(Generation) << fName << "::" << ClassName() << ":randomize: fails with unbounded fit range" << std::endl;
425 }
426}
427
428
429
430////////////////////////////////////////////////////////////////////////////////
431/// Set value to center of bin 'ibin' of binning 'rangeName' (or of
432/// default binning if no range is specified)
433
435{
436 // Check range of plot bin index
438 coutE(InputArguments) << "RooAbsRealLValue::setBin(" << GetName() << ") ERROR: bin index " << ibin
439 << " is out of range (0," << getBins(rangeName)-1 << ")" << std::endl ;
440 return ;
441 }
442
443 // Set value to center of requested bin
444 setValFast(getBinning(rangeName).binCenter(ibin)) ;
445}
446
447
448
449////////////////////////////////////////////////////////////////////////////////
450/// Set value to center of bin 'ibin' of binning 'binning'
451
453{
454 // Set value to center of requested bin
455 setValFast(binning.binCenter(ibin)) ;
456}
457
458
459
460////////////////////////////////////////////////////////////////////////////////
461/// Set a new value sampled from a uniform distribution over the fit range.
462/// Prints a warning and does nothing if the fit range is not finite.
463
465{
466 double range= binning.highBound() - binning.lowBound() ;
468}
469
470
471
472////////////////////////////////////////////////////////////////////////////////
473/// Check if fit range is usable as plot range, i.e. it is neither
474/// open ended, nor empty
475
477{
478 return (hasMin() && hasMax() && (getMin()!=getMax())) ;
479}
480
481
482
483////////////////////////////////////////////////////////////////////////////////
484/// Check if current value is inside range with given name. Multiple comma-separated
485/// ranges can be passed. In this case, it will be checked if the value is in any of
486/// these ranges.
487bool RooAbsRealLValue::inRange(const char* name) const
488{
489 const double val = getVal() ;
490 if (!name || name[0] == '\0') {
491 const auto minMax = getRange(nullptr);
492 return minMax.first <= val && val <= minMax.second;
493 }
494
495 const auto& ranges = ROOT::Split(name, ",");
496 return std::any_of(ranges.begin(), ranges.end(), [val,this](const std::string& range){
497 const auto minMax = this->getRange(range.c_str());
498 return minMax.first <= val && val <= minMax.second;
499 });
500}
501
502
503
504////////////////////////////////////////////////////////////////////////////////
505
507 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
508 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) const
509
510 // Create an empty ROOT histogram TH1,TH2 or TH3 suitabe to store information represent by the RooAbsRealLValue
511 //
512 // This function accepts the following arguments
513 //
514 // name -- Name of the ROOT histogram
515 //
516 // Binning(const char* name) -- Apply binning with given name to x axis of histogram
517 // Binning(RooAbsBinning& binning) -- Apply specified binning to x axis of histogram
518 // Binning(int_t nbins) -- Apply specified binning to x axis of histogram
519 // Binning(int_t nbins, double lo, double hi) -- Apply specified binning to x axis of histogram
520 // ConditionalObservables(const RooArgSet& set) -- Do not normalized PDF over following observables when projecting PDF into histogram
521 //
522 // YVar(const RooAbsRealLValue& var,...) -- Observable to be mapped on y axis of ROOT histogram
523 // ZVar(const RooAbsRealLValue& var,...) -- Observable to be mapped on z axis of ROOT histogram
524 //
525 // The YVar() and ZVar() arguments can be supplied with optional Binning() arguments to control the binning of the Y and Z axes, e.g.
526 // createHistogram("histo",x,Binning(-1,1,20), YVar(y,Binning(-1,1,30)), ZVar(z,Binning("zbinning")))
527 //
528 // The caller takes ownership of the returned histogram
529{
531 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
532 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
533 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
534 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
535
536 return createHistogram(name,l) ;
537}
538
539
540
541////////////////////////////////////////////////////////////////////////////////
542/// Create empty 1,2 or 3D histogram
543/// Arguments recognized
544///
545/// YVar() -- RooRealVar defining Y dimension with optional range/binning
546/// ZVar() -- RooRealVar defining Z dimension with optional range/binning
547/// AxisLabel() -- Vertical axis label
548/// Binning() -- Range/Binning specification of X axis
549
551{
552 // Define configuration for this method
553 RooCmdConfig pc("RooAbsRealLValue::createHistogram(" + std::string(GetName()) + ")");
554
555 pc.defineObject("xbinning","Binning",0,nullptr) ;
556 pc.defineString("xbinningName","BinningName",0,"") ;
557 pc.defineInt("nxbins","BinningSpec",0) ;
558 pc.defineDouble("xlo","BinningSpec",0,0) ;
559 pc.defineDouble("xhi","BinningSpec",1,0) ;
560
561 pc.defineObject("yvar","YVar",0,nullptr) ;
562 pc.defineObject("ybinning","YVar::Binning",0,nullptr) ;
563 pc.defineString("ybinningName","YVar::BinningName",0,"") ;
564 pc.defineInt("nybins","YVar::BinningSpec",0) ;
565 pc.defineDouble("ylo","YVar::BinningSpec",0,0) ;
566 pc.defineDouble("yhi","YVar::BinningSpec",1,0) ;
567
568 pc.defineObject("zvar","ZVar",0,nullptr) ;
569 pc.defineObject("zbinning","ZVar::Binning",0,nullptr) ;
570 pc.defineString("zbinningName","ZVar::BinningName",0,"") ;
571 pc.defineInt("nzbins","ZVar::BinningSpec",0) ;
572 pc.defineDouble("zlo","ZVar::BinningSpec",0,0) ;
573 pc.defineDouble("zhi","ZVar::BinningSpec",1,0) ;
574
575 pc.defineString("axisLabel","AxisLabel",0,"Events") ;
576
577 pc.defineDependency("ZVar","YVar") ;
578
579 // Process & check varargs
580 pc.process(cmdList) ;
581 if (!pc.ok(true)) {
582 return nullptr ;
583 }
584
585 // Initialize arrays for call to implementation version of createHistogram
586 const char* axisLabel = pc.getString("axisLabel") ;
587 const RooAbsBinning* binning[3] ;
588 bool ownBinning[3] = { false, false, false } ;
589 RooArgList vars ;
590
591 // Prepare X dimension
592 vars.add(*this) ;
593 if (pc.hasProcessed("Binning")) {
594 binning[0] = static_cast<RooAbsBinning*>(pc.getObject("xbinning")) ;
595 } else if (pc.hasProcessed("BinningName")) {
596 binning[0] = &getBinning(pc.getString("xbinningName",nullptr,true)) ;
597 } else if (pc.hasProcessed("BinningSpec")) {
598 double xlo = pc.getDouble("xlo") ;
599 double xhi = pc.getDouble("xhi") ;
600 binning[0] = new RooUniformBinning((xlo==xhi)?getMin():xlo,(xlo==xhi)?getMax():xhi,pc.getInt("nxbins")) ;
601 ownBinning[0] = true ;
602 } else {
603 binning[0] = &getBinning() ;
604 if (binning[0]->numBins() == 0) {
605 binning[0] = new RooUniformBinning(getMin(), getMax(), DefaultNBins) ;
606 ownBinning[0] = true ;
607 }
608 }
609
610 if (pc.hasProcessed("YVar")) {
611 RooAbsRealLValue& yvar = *static_cast<RooAbsRealLValue*>(pc.getObject("yvar")) ;
612 vars.add(yvar) ;
613 if (pc.hasProcessed("YVar::Binning")) {
614 binning[1] = static_cast<RooAbsBinning*>(pc.getObject("ybinning")) ;
615 } else if (pc.hasProcessed("YVar::BinningName")) {
616 binning[1] = &yvar.getBinning(pc.getString("ybinningName",nullptr,true)) ;
617 } else if (pc.hasProcessed("YVar::BinningSpec")) {
618 double ylo = pc.getDouble("ylo") ;
619 double yhi = pc.getDouble("yhi") ;
620 binning[1] = new RooUniformBinning((ylo==yhi)?yvar.getMin():ylo,(ylo==yhi)?yvar.getMax():yhi,pc.getInt("nybins")) ;
621 ownBinning[1] = true ;
622 } else {
623 binning[1] = &yvar.getBinning() ;
624 if (binning[1]->numBins() == 0) {
625 binning[1] = new RooUniformBinning(yvar.getMin(), yvar.getMax(), DefaultNBins) ;
626 ownBinning[1] = true ;
627 }
628 }
629 }
630
631 if (pc.hasProcessed("ZVar")) {
632 RooAbsRealLValue& zvar = *static_cast<RooAbsRealLValue*>(pc.getObject("zvar")) ;
633 vars.add(zvar) ;
634 if (pc.hasProcessed("ZVar::Binning")) {
635 binning[2] = static_cast<RooAbsBinning*>(pc.getObject("zbinning")) ;
636 } else if (pc.hasProcessed("ZVar::BinningName")) {
637 binning[2] = &zvar.getBinning(pc.getString("zbinningName",nullptr,true)) ;
638 } else if (pc.hasProcessed("ZVar::BinningSpec")) {
639 double zlo = pc.getDouble("zlo") ;
640 double zhi = pc.getDouble("zhi") ;
641 binning[2] = new RooUniformBinning((zlo==zhi)?zvar.getMin():zlo,(zlo==zhi)?zvar.getMax():zhi,pc.getInt("nzbins")) ;
642 ownBinning[2] = true ;
643 } else {
644 binning[2] = &zvar.getBinning() ;
645 if (binning[2]->numBins() == 0) {
646 binning[2] = new RooUniformBinning(zvar.getMin(), zvar.getMax(), DefaultNBins) ;
647 ownBinning[2] = true ;
648 }
649 }
650 }
651
652
653 TH1* ret = createHistogram(name, vars, axisLabel, binning) ;
654
655 if (ownBinning[0]) delete binning[0] ;
656 if (ownBinning[1]) delete binning[1] ;
657 if (ownBinning[2]) delete binning[2] ;
658
659 return ret ;
660}
661
662
663
664////////////////////////////////////////////////////////////////////////////////
665/// Create an empty 1D-histogram with appropriate scale and labels for this variable.
666/// This method uses the default plot range which can be changed using the
667/// setPlotMin(),setPlotMax() methods, and the default binning which can be
668/// changed with setPlotBins(). The caller takes ownership of the returned
669/// object and is responsible for deleting it.
670
672{
673 // Check if the fit range is usable as plot range
674 if (!fitRangeOKForPlotting()) {
675 coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName()
676 << ") ERROR: fit range empty or open ended, must explicitly specify range" << std::endl ;
677 return nullptr ;
678 }
679
680 RooArgList list(*this) ;
681 double xlo = getMin() ;
682 double xhi = getMax() ;
683 Int_t nbins = getBins()!=0 ? getBins() : DefaultNBins ;
684
685 // coverity[ARRAY_VS_SINGLETON]
686 return static_cast<TH1F*>(createHistogram(name, list, yAxisLabel, &xlo, &xhi, &nbins));
687}
688
689
690
691////////////////////////////////////////////////////////////////////////////////
692/// Create an empty 1D-histogram with appropriate scale and labels for this variable.
693/// This method uses the default plot range which can be changed using the
694/// setPlotMin(),setPlotMax() methods, and the default binning which can be
695/// changed with setPlotBins(). The caller takes ownership of the returned
696/// object and is responsible for deleting it.
697
698TH1F *RooAbsRealLValue::createHistogram(const char *name, const char *yAxisLabel, double xlo, double xhi, Int_t nBins) const
699{
700 RooArgList list(*this) ;
701
702 // coverity[ARRAY_VS_SINGLETON]
703 return static_cast<TH1F*>(createHistogram(name, list, yAxisLabel, &xlo, &xhi, &nBins));
704}
705
706
707
708////////////////////////////////////////////////////////////////////////////////
709/// Create an empty 1D-histogram with appropriate scale and labels for this variable.
710
711TH1F *RooAbsRealLValue::createHistogram(const char *name, const char *yAxisLabel, const RooAbsBinning& bins) const
712{
713 RooArgList list(*this) ;
714 const RooAbsBinning* pbins = &bins ;
715
716 // coverity[ARRAY_VS_SINGLETON]
717 return static_cast<TH1F*>(createHistogram(name, list, yAxisLabel, &pbins));
718}
719
720
721
722////////////////////////////////////////////////////////////////////////////////
723/// Create an empty 2D-histogram with appropriate scale and labels for this variable (x)
724/// and the specified y variable. This method uses the default plot ranges for x and y which
725/// can be changed using the setPlotMin(),setPlotMax() methods, and the default binning which
726/// can be changed with setPlotBins(). The caller takes ownership of the returned object
727/// and is responsible for deleting it.
728
730 double* xlo, double* xhi, Int_t* nBins) const
731{
732 if ((!xlo && xhi) || (xlo && !xhi)) {
733 coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName()
734 << ") ERROR must specify either no range, or both limits" << std::endl ;
735 return nullptr ;
736 }
737
738 double xlo_fit[2] ;
739 double xhi_fit[2] ;
740 Int_t nbins_fit[2] ;
741
742 double *xlo2 = xlo;
743 double *xhi2 = xhi;
744 Int_t *nBins2 = nBins;
745
746 if (!xlo2) {
747
748 if (!fitRangeOKForPlotting()) {
749 coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName()
750 << ") ERROR: fit range empty or open ended, must explicitly specify range" << std::endl ;
751 return nullptr ;
752 }
753 if (!yvar.fitRangeOKForPlotting()) {
754 coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName()
755 << ") ERROR: fit range of " << yvar.GetName() << " empty or open ended, must explicitly specify range" << std::endl ;
756 return nullptr ;
757 }
758
759 xlo_fit[0] = getMin() ;
760 xhi_fit[0] = getMax() ;
761
762 xlo_fit[1] = yvar.getMin() ;
763 xhi_fit[1] = yvar.getMax() ;
764
765 xlo2 = xlo_fit ;
766 xhi2 = xhi_fit ;
767 }
768
769 if (!nBins2) {
770 nbins_fit[0] = getBins()!=0 ? getBins() : DefaultNBins ;
771 nbins_fit[1] = yvar.getBins()!=0 ? yvar.getBins() : DefaultNBins ;
772 nBins2 = nbins_fit ;
773 }
774
775
776 RooArgList list(*this,yvar) ;
777 // coverity[OVERRUN_STATIC]
778 return static_cast<TH2F*>(createHistogram(name, list, zAxisLabel, xlo2, xhi2, nBins2));
779}
780
781
782
783////////////////////////////////////////////////////////////////////////////////
784/// Create an empty 2D-histogram with appropriate scale and labels for this variable (x)
785/// and the specified y variable.
786
788 const char *zAxisLabel, const RooAbsBinning** bins) const
789{
790 RooArgList list(*this,yvar) ;
791 return static_cast<TH2F*>(createHistogram(name, list, zAxisLabel, bins));
792}
793
794
795
796////////////////////////////////////////////////////////////////////////////////
797/// Create an empty 3D-histogram with appropriate scale and labels for this variable (x)
798/// and the specified y,z variables. This method uses the default plot ranges for x,y,z which
799/// can be changed using the setPlotMin(),setPlotMax() methods, and the default binning which
800/// can be changed with setPlotBins(). The caller takes ownership of the returned object
801/// and is responsible for deleting it.
802
804 const char *tAxisLabel, double* xlo, double* xhi, Int_t* nBins) const
805{
806 if ((!xlo && xhi) || (xlo && !xhi)) {
807 coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName()
808 << ") ERROR must specify either no range, or both limits" << std::endl ;
809 return nullptr ;
810 }
811
812 double xlo_fit[3] ;
813 double xhi_fit[3] ;
814 Int_t nbins_fit[3] ;
815
816 double *xlo2 = xlo;
817 double *xhi2 = xhi;
818 Int_t* nBins2 = nBins;
819 if (!xlo2) {
820
821 if (!fitRangeOKForPlotting()) {
822 coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName()
823 << ") ERROR: fit range empty or open ended, must explicitly specify range" << std::endl ;
824 return nullptr ;
825 }
826 if (!yvar.fitRangeOKForPlotting()) {
827 coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName()
828 << ") ERROR: fit range of " << yvar.GetName() << " empty or open ended, must explicitly specify range" << std::endl ;
829 return nullptr ;
830 }
831 if (!zvar.fitRangeOKForPlotting()) {
832 coutE(InputArguments) << "RooAbsRealLValue::createHistogram(" << GetName()
833 << ") ERROR: fit range of " << zvar.GetName() << " empty or open ended, must explicitly specify range" << std::endl ;
834 return nullptr ;
835 }
836
837 xlo_fit[0] = getMin() ;
838 xhi_fit[0] = getMax() ;
839
840 xlo_fit[1] = yvar.getMin() ;
841 xhi_fit[1] = yvar.getMax() ;
842
843 xlo_fit[2] = zvar.getMin() ;
844 xhi_fit[2] = zvar.getMax() ;
845
846 xlo2 = xlo_fit ;
847 xhi2 = xhi_fit ;
848 }
849
850 if (!nBins2) {
851 nbins_fit[0] = getBins()!=0 ? getBins() : DefaultNBins ;
852 nbins_fit[1] = yvar.getBins()!=0 ? yvar.getBins() : DefaultNBins ;
853 nbins_fit[2] = zvar.getBins()!=0 ? zvar.getBins() : DefaultNBins ;
854 nBins2 = nbins_fit ;
855 }
856
857 RooArgList list(*this,yvar,zvar) ;
858 return static_cast<TH3F*>(createHistogram(name, list, tAxisLabel, xlo2, xhi2, nBins2));
859}
860
861
863 const char* tAxisLabel, const RooAbsBinning** bins) const
864{
865 // Create an empty 3D-histogram with appropriate scale and labels for this variable (x)
866 // and the specified y,z variables.
867
868 RooArgList list(*this,yvar,zvar) ;
869 return static_cast<TH3F*>(createHistogram(name, list, tAxisLabel, bins));
870}
871
872
873
874
875////////////////////////////////////////////////////////////////////////////////
876/// Create 1-, 2- or 3-d ROOT histogram with labels taken
877/// from the variables in 'vars' and the with range and binning
878/// specified in xlo,xhi and nBins. The dimensions of the arrays xlo,xhi,
879/// nBins should match the number of objects in vars.
880
882 double* xlo, double* xhi, Int_t* nBins)
883{
884 const RooAbsBinning* bin[3] ;
885 Int_t ndim = vars.size() ;
886 bin[0] = new RooUniformBinning(xlo[0],xhi[0],nBins[0]) ;
887 bin[1] = (ndim>1) ? new RooUniformBinning(xlo[1],xhi[1],nBins[1]) : nullptr ;
888 bin[2] = (ndim>2) ? new RooUniformBinning(xlo[2],xhi[2],nBins[2]) : nullptr ;
889
891
892 if (bin[0]) delete bin[0] ;
893 if (bin[1]) delete bin[1] ;
894 if (bin[2]) delete bin[2] ;
895 return ret ;
896}
897
898
899
900////////////////////////////////////////////////////////////////////////////////
901/// Create a 1,2, or 3D-histogram with appropriate scale and labels.
902/// Binning and ranges are taken from the variables themselves and can be changed by
903/// calling their setPlotMin/Max() and setPlotBins() methods. A histogram can be filled
904/// using RooAbsReal::fillHistogram() or RooTreeData::fillHistogram().
905/// The caller takes ownership of the returned object and is responsible for deleting it.
906
907TH1 *RooAbsRealLValue::createHistogram(const char *name, RooArgList &vars, const char *tAxisLabel, const RooAbsBinning** bins)
908{
909 // Check that we have 1-3 vars
910 Int_t dim= vars.size();
911 if(dim < 1 || dim > 3) {
912 oocoutE(nullptr,InputArguments) << "RooAbsReal::createHistogram: dimension not supported: " << dim << std::endl;
913 return nullptr;
914 }
915
916 // Check that all variables are AbsReals and prepare a name of the form <name>_<var1>_...
917 TString histName(name);
918 histName.Append("_");
919 const RooAbsRealLValue *xyz[3];
920
921 Int_t index;
922 for(index= 0; index < dim; index++) {
923 const RooAbsArg *arg= vars.at(index);
924 xyz[index]= dynamic_cast<const RooAbsRealLValue*>(arg);
925 if(!xyz[index]) {
926 oocoutE(nullptr,InputArguments) << "RooAbsRealLValue::createHistogram: variable is not real lvalue: " << arg->GetName() << std::endl;
927 return nullptr;
928 }
929 histName.Append("_");
930 histName.Append(arg->GetName());
931 }
932 TString histTitle(histName);
933 histTitle.Prepend("Histogram of ");
934
935 // Create the histogram
936 TH1 *histogram = nullptr;
937 switch(dim) {
938 case 1:
939 if (bins[0]->isUniform()) {
940 histogram= new TH1F(histName.Data(), histTitle.Data(),
941 bins[0]->numBins(),bins[0]->lowBound(),bins[0]->highBound());
942 } else {
943 histogram= new TH1F(histName.Data(), histTitle.Data(),
944 bins[0]->numBins(),bins[0]->array());
945 }
946 break;
947 case 2:
948 if (bins[0]->isUniform() && bins[1]->isUniform()) {
949 histogram= new TH2F(histName.Data(), histTitle.Data(),
950 bins[0]->numBins(),bins[0]->lowBound(),bins[0]->highBound(),
951 bins[1]->numBins(),bins[1]->lowBound(),bins[1]->highBound());
952 } else {
953 histogram= new TH2F(histName.Data(), histTitle.Data(),
954 bins[0]->numBins(),bins[0]->array(),
955 bins[1]->numBins(),bins[1]->array());
956 }
957 break;
958 case 3:
959 if (bins[0]->isUniform() && bins[1]->isUniform() && bins[2]->isUniform()) {
960 histogram= new TH3F(histName.Data(), histTitle.Data(),
961 bins[0]->numBins(),bins[0]->lowBound(),bins[0]->highBound(),
962 bins[1]->numBins(),bins[1]->lowBound(),bins[1]->highBound(),
963 bins[2]->numBins(),bins[2]->lowBound(),bins[2]->highBound()) ;
964 } else {
965 histogram= new TH3F(histName.Data(), histTitle.Data(),
966 bins[0]->numBins(),bins[0]->array(),
967 bins[1]->numBins(),bins[1]->array(),
968 bins[2]->numBins(),bins[2]->array()) ;
969 }
970 break;
971 }
972 if(!histogram) {
973 oocoutE(nullptr,InputArguments) << "RooAbsReal::createHistogram: unable to create a new histogram" << std::endl;
974 return nullptr;
975 }
976
977 // Set the histogram coordinate axis labels from the titles of each variable, adding units if necessary.
978 for(index= 0; index < dim; index++) {
979 TString axisTitle(xyz[index]->getTitle(true));
980 switch(index) {
981 case 0:
982 histogram->SetXTitle(axisTitle.Data());
983 break;
984 case 1:
985 histogram->SetYTitle(axisTitle.Data());
986 break;
987 case 2:
988 histogram->SetZTitle(axisTitle.Data());
989 break;
990 default:
991 assert(0);
992 break;
993 }
994 }
995
996 // Set the t-axis title if given one
997 if((nullptr != tAxisLabel) && (0 != strlen(tAxisLabel))) {
999 axisTitle.Append(" / ( ");
1000 for(Int_t index2= 0; index2 < dim; index2++) {
1001 double delta= bins[index2]->averageBinWidth() ; // xyz[index2]->getBins();
1002 if(index2 > 0) axisTitle.Append(" x ");
1003 axisTitle.Append(Form("%g",delta));
1004 if(strlen(xyz[index2]->getUnit())) {
1005 axisTitle.Append(" ");
1006 axisTitle.Append(xyz[index2]->getUnit());
1007 }
1008 }
1009 axisTitle.Append(" )");
1010 switch(dim) {
1011 case 1:
1012 histogram->SetYTitle(axisTitle.Data());
1013 break;
1014 case 2:
1015 histogram->SetZTitle(axisTitle.Data());
1016 break;
1017 case 3:
1018 // not supported in TH1
1019 break;
1020 default:
1021 assert(0);
1022 break;
1023 }
1024 }
1025
1026 return histogram;
1027}
1028
1029
1031{
1032 // Interface function to indicate that this lvalue
1033 // has a unit or constant jacobian terms with respect to
1034 // the observable passed as argument. This default implementation
1035 // always returns true (i.e. jacobian is constant)
1036 return true ;
1037}
1038
1039
1041{
1042 std::stringstream errStream;
1043 errStream << "Attempting to integrate the " << ClassName() << " \"" << GetName()
1044 << "\", but integrating a RooAbsRealLValue is not allowed!";
1045 const std::string errString = errStream.str();
1046 coutE(InputArguments) << errString << std::endl;
1047 throw std::runtime_error(errString);
1048}
#define coutI(a)
#define oocoutE(o, a)
#define coutE(a)
static void indent(ostringstream &buf, int indent_level)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
char name[80]
Definition TGX11.cxx:148
float xmin
float xmax
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2570
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:76
Abstract base class for RooRealVar binning definitions.
virtual double binCenter(Int_t bin) const =0
Int_t numBins() const
Return number of bins.
virtual double averageBinWidth() const =0
virtual double highBound() const =0
virtual double lowBound() const =0
virtual double * array() const =0
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t::size_type size() const
Abstract base class for binned and unbinned datasets.
Definition RooAbsData.h:56
Abstract base class for objects that are lvalues, i.e.
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
Int_t numBins(const char *rangeName=nullptr) const override
virtual Int_t getBins(const char *name=nullptr) const
Get number of bins of currently defined range.
RooFit::OwningPtr< RooAbsReal > createIntegral(const RooArgSet &iset, const RooArgSet *nset=nullptr, const RooNumIntConfig *cfg=nullptr, const char *rangeName=nullptr) const override
Create an object that represents the integral of the function over one or more observables listed in ...
virtual void setValFast(double value)
RooPlot * frame(const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
Create a new RooPlot on the heap with a drawing frame initialized for this object,...
bool isValidReal(double value, bool printError=false) const override
Check if given value is valid.
TH1 * createHistogram(const char *name, const RooCmdArg &arg1={}, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
virtual bool isJacobianOK(const RooArgSet &depList) const
static constexpr int DefaultNBins
Historical default number of bins, injected by routines that need a concrete bin count when a variabl...
virtual double getMax(const char *name=nullptr) const
Get maximum of currently defined range.
RooPlot * frame() const
Create a new RooPlot on the heap with a drawing frame initialized for this object,...
bool hasMax(const char *name=nullptr) const
Check if variable has an upper bound.
void copyCache(const RooAbsArg *source, bool valueOnly=false, bool setValDirty=true) override
Copy cache of another RooAbsArg to our cache.
bool fitRangeOKForPlotting() const
Check if fit range is usable as plot range, i.e.
void setBin(Int_t ibin, const char *rangeName=nullptr) override
Set value to center of bin 'ibin' of binning 'rangeName' (or of default binning if no range is specif...
void writeToStream(std::ostream &os, bool compact) const override
Write object contents to given stream.
void randomize(const char *rangeName=nullptr) override
Set a new value sampled from a uniform distribution over the fit range.
virtual void setVal(double value)=0
Set the current value of the object. Needs to be overridden by implementations.
virtual double getMin(const char *name=nullptr) const
Get minimum of currently defined range.
bool readFromStream(std::istream &is, bool compact, bool verbose=false) override
Read object contents from given stream.
virtual const RooAbsBinning & getBinning(const char *name=nullptr, bool verbose=true, bool createOnTheFly=false, bool shared=true) const =0
Retrieve binning configuration with given name or default binning.
bool inRange(const char *name) const override
Check if current value is inside range with given name.
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Structure printing.
std::pair< double, double > getRange(const char *name=nullptr) const
Get low and high bound of the variable.
virtual RooAbsArg & operator=(double newValue)
Assignment operator from a double.
bool hasMin(const char *name=nullptr) const
Check if variable has a lower bound.
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:63
double getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:107
TString _unit
Unit for objects value.
Definition RooAbsReal.h:540
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Structure printing.
void copyCache(const RooAbsArg *source, bool valueOnly=false, bool setValDirty=true) override
Copy the cached value of another RooAbsArg to our cache.
double _value
Cache for current value of object.
Definition RooAbsReal.h:539
TString getTitle(bool appendUnit=false) const
Return this variable's title string.
const Text_t * getUnit() const
Definition RooAbsReal.h:149
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
RooAbsArg * at(Int_t idx) const
Return object at given index, or nullptr if index is out of range.
Definition RooArgList.h:110
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
Named container for two doubles, two integers two object points and three string pointers that can be...
Definition RooCmdArg.h:26
Configurable parser for RooCmdArg named arguments.
void defineMutex(const char *head, Args_t &&... tail)
Define arguments where any pair is mutually exclusive.
bool process(const RooCmdArg &arg)
Process given RooCmdArg.
bool hasProcessed(const char *cmdName) const
Return true if RooCmdArg with name 'cmdName' has been processed.
double getDouble(const char *name, double defaultValue=0.0) const
Return double property registered with name 'name'.
void defineDependency(const char *refArgName, const char *neededArgName)
Define that processing argument name refArgName requires processing of argument named neededArgName t...
bool defineDouble(const char *name, const char *argName, int doubleNum, double defValue=0.0)
Define double property name 'name' mapped to double in slot 'doubleNum' in RooCmdArg with name argNam...
bool ok(bool verbose) const
Return true of parsing was successful.
bool defineObject(const char *name, const char *argName, int setNum, const TObject *obj=nullptr, bool isArray=false)
Define TObject property name 'name' mapped to object in slot 'setNum' in RooCmdArg with name argName ...
const char * getString(const char *name, const char *defaultValue="", bool convEmptyToNull=false) const
Return string property registered with name 'name'.
bool defineString(const char *name, const char *argName, int stringNum, const char *defValue="", bool appendMode=false)
Define double property name 'name' mapped to double in slot 'stringNum' in RooCmdArg with name argNam...
bool defineInt(const char *name, const char *argName, int intNum, int defValue=0)
Define integer property name 'name' mapped to integer in slot 'intNum' in RooCmdArg with name argName...
int getInt(const char *name, int defaultValue=0) const
Return integer property registered with name 'name'.
TObject * getObject(const char *name, TObject *obj=nullptr) const
Return TObject property registered with name 'name'.
Collection class for internal use, storing a collection of RooAbsArg pointers in a doubly linked list...
Holds the configuration parameters of the various numeric integrators used by RooRealIntegral.
static constexpr int isInfinite(double x)
Return true if x is infinite by RooNumber internal specification.
Definition RooNumber.h:27
Plot frame and a container for graphics objects within that frame.
Definition RooPlot.h:43
static double uniform(TRandom *generator=randomGenerator())
Return a number uniformly distributed from (0,1)
Definition RooRandom.cxx:77
Variable that can be changed from the outside.
Definition RooRealVar.h:37
Implementation of RooAbsBinning that provides a uniform binning in 'n' bins between the range end poi...
1-D histogram with a float per channel (see TH1 documentation)
Definition TH1.h:878
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
2-D histogram with a float per channel (see TH1 documentation)
Definition TH2.h:345
3-D histogram with a float per channel (see TH1 documentation)
Definition TH3.h:369
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
TString fName
Definition TNamed.h:32
Mother of all ROOT objects.
Definition TObject.h:42
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:227
Basic string class.
Definition TString.h:138
const char * Data() const
Definition TString.h:386
TString & Prepend(const char *cs)
Definition TString.h:684
Bool_t IsNull() const
Definition TString.h:424
TString & Append(const char *cs)
Definition TString.h:583
std::vector< std::string > Split(std::string_view str, std::string_view delims, bool skipEmpty=false)
Splits a string at each character in delims.
T * OwningPtr
An alias for raw pointers for indicating that the return type of a RooFit function is an owning point...
Definition Config.h:35
TLine l
Definition textangle.C:4