63using std::ostream, std::list, std::vector, std::min;
74inline Point getPoint(
TGraph const &
gr,
int i)
102 const RooArgSet *normVars,
double prec,
double resolution,
bool shiftToZero,
WingMode wmode,
103 Int_t nEvalError,
Int_t doEEVal,
double eeVal,
bool showProg)
104 : _showProgress(showProg)
112 if(0 != strlen(
f.getUnit()) || 0 != strlen(
x.getUnit())) {
114 if(0 != strlen(
f.getUnit())) {
118 if(0 != strlen(
x.getUnit())) {
128 std::unique_ptr<RooAbsFunc> funcPtr{scaledFunc.
bindVars(
x, normVars,
true)};
133 std::unique_ptr<std::list<double>> hint{
f.plotSamplingHint(
x,xlo,xhi)};
134 addPoints(*funcPtr,xlo,xhi,xbins+1,prec,resolution,wmode,nEvalError,doEEVal,eeVal,hint.get());
136 ccoutP(Plotting) << std::endl ;
141 int nBinsX =
x.numBins();
142 for(
int i=0; i<nBinsX; ++i){
143 double xval =
x.getBinning().binCenter(i);
152 for (
int i=0 ; i<
GetN() ; i++) {
168 double xlo,
double xhi,
UInt_t minPoints,
double prec,
double resolution,
173 addPoints(func,xlo,xhi,minPoints+1,prec,resolution,wmode,nEvalError,doEEVal,eeVal);
178 for (
int i=0 ; i<
GetN() ; i++) {
206 std::deque<double> pointList ;
210 for (
int i1=0 ; i1<n1 ; i1++) {
211 pointList.push_back(
c1.GetPointX(i1));
216 for (
int i2=0 ; i2<n2 ; i2++) {
217 pointList.push_back(
c2.GetPointX(i2));
221 std::sort(pointList.begin(),pointList.end()) ;
225 for (
auto point : pointList) {
227 if ((point-last)>1
e-10) {
229 addPoint(point,scale1*
c1.interpolate(point)+scale2*
c2.interpolate(point)) ;
260 double minVal = std::numeric_limits<double>::infinity();
261 double maxVal = -std::numeric_limits<double>::infinity();
264 for (
int i = 1; i <
GetN() - 1; i++) {
266 minVal = std::min(
y, minVal);
267 maxVal = std::max(
y, maxVal);
271 for (
int i = 1; i <
GetN() - 1; i++) {
272 Point point = getPoint(*
this, i);
273 SetPoint(i, point.x, point.y - minVal);
288 Int_t minPoints,
double prec,
double resolution,
WingMode wmode,
289 Int_t numee,
bool doEEVal,
double eeVal, list<double>* samplingHint)
293 coutE(InputArguments) <<
fName <<
"::addPoints: input function is not valid" << std::endl;
296 if(minPoints <= 0 || xhi <= xlo) {
297 coutE(InputArguments) <<
fName <<
"::addPoints: bad input (nothing added)" << std::endl;
306 minPoints = samplingHint->
size() ;
309 double dx= (xhi-xlo)/(minPoints-1.);
311 std::vector<double> yval(minPoints);
315 std::vector<double> xval;
317 for(
int step= 0; step < minPoints; step++) {
318 xval.push_back(xlo + step*dx) ;
321 std::copy(samplingHint->begin(), samplingHint->end(), std::back_inserter(xval));
324 for (
unsigned int step=0; step < xval.size(); ++step) {
325 double xx = xval[step];
326 if (step ==
static_cast<unsigned int>(minPoints-1))
329 yval[step]= func(&xx);
337 coutW(Plotting) <<
"At observable [x]=" << xx <<
" " ;
347 const double ymax = *std::max_element(yval.begin(), yval.end());
348 const double ymin = *std::min_element(yval.begin(), yval.end());
352 double minDx= resolution*(xhi-xlo);
356 if (wmode==Extended) {
368 auto iter2 = xval.begin() ;
374 if (iter2==xval.end()) {
382 addRange(func,
x1,
x2,yval[step-1],yval[step],prec*yrangeEst,minDx,numee,doEEVal,eeVal,epsilon);
388 if (wmode==Extended) {
391 addPoint(xhi+dx,yval[minPoints-1]) ;
406 double y1,
double y2,
double minDy,
double minDx,
407 int numee,
bool doEEVal,
double eeVal,
double epsilon)
410 if (std::abs(
x2-
x1) <= epsilon) {
415 double xmid= 0.5*(
x1+
x2);
416 double ymid= func(&xmid);
424 coutW(Plotting) <<
"At observable [x]=" << xmid <<
" " ;
434 double dy= ymid - 0.5*(
y1+
y2);
435 if((xmid -
x1 >= minDx) && std::abs(dy)>0 && std::abs(dy) >= minDy) {
437 addRange(func,
x1,xmid,
y1,ymid,minDy,minDx,numee,doEEVal,eeVal,epsilon);
438 addRange(func,xmid,
x2,ymid,
y2,minDy,minDx,numee,doEEVal,eeVal,epsilon);
522 os <<
indent <<
"--- RooCurve ---" << std::endl ;
524 os <<
indent <<
" Contains " <<
n <<
" points" << std::endl;
525 os <<
indent <<
" Graph points:" << std::endl;
526 for(
Int_t i= 0; i <
n; i++) {
527 os <<
indent << std::setw(3) << i <<
") x = " <<
fX[i] <<
" , y = " <<
fY[i] << std::endl;
549 for (
int i=0 ; i<
np ; i++) {
552 Point point = getPoint(hist, i);
555 if (point.x<xstart || point.x>xstop) continue ;
563 double avg =
average(point.x-exl,point.x+exh) ;
567 double pull = (point.y>avg) ? ((point.y-avg)/eyl) : ((point.y-avg)/eyh) ;
574 return chisq.Sum() / (nbin-nFitParam) ;
588 coutE(InputArguments) <<
"RooCurve::average(" <<
GetName()
589 <<
") invalid range (" << xFirst <<
"," << xLast <<
")" << std::endl ;
592 else if (xFirst == xLast) {
601 Int_t ifirst =
findPoint(xFirst, std::numeric_limits<double>::infinity());
602 Int_t ilast =
findPoint(xLast, std::numeric_limits<double>::infinity());
613 if (ilast < ifirst) {
614 return 0.5*(yFirst+yLast) ;
617 Point firstPt = getPoint(*
this, ifirst);
618 Point lastPt = getPoint(*
this, ilast);
621 double sum = 0.5 * (firstPt.x-xFirst)*(yFirst+firstPt.y);
624 for (
int i=ifirst ; i<ilast ; i++) {
625 Point p1 = getPoint(*
this, i) ;
626 Point p2 = getPoint(*
this, i+1) ;
627 sum += 0.5 * (p2.x-p1.x)*(p1.y+p2.y);
631 sum += 0.5 * (xLast-lastPt.x)*(lastPt.y+yLast);
632 return sum/(xLast-xFirst) ;
643 double delta(std::numeric_limits<double>::max());
646 for (
int i=0 ; i<
n ; i++) {
648 if (std::abs(xvalue-
x)<delta) {
649 delta = std::abs(xvalue-
x) ;
654 return (delta<tolerance)?ibest:-1 ;
670 Point pbest = getPoint(*
this, ibest);
673 if (std::abs(pbest.x-xvalue)<tolerance) {
679 if (pbest.x<xvalue) {
684 Point pother = getPoint(*
this, ibest+1);
685 if (pother.x==pbest.x)
return pbest.y ;
686 retVal = pbest.y + (pother.y-pbest.y)*(xvalue-pbest.x)/(pother.x-pbest.x) ;
693 Point pother = getPoint(*
this, ibest-1);
694 if (pother.x==pbest.x)
return pbest.y ;
695 retVal = pother.y + (pbest.y-pother.y)*(xvalue-pother.x)/(pbest.x-pother.x) ;
713 band->SetLineWidth(1) ;
714 band->SetFillColor(
kCyan) ;
715 band->SetLineColor(
kCyan) ;
717 vector<double> bandLo(
GetN()) ;
718 vector<double> bandHi(
GetN()) ;
719 for (
int i=0 ; i<
GetN() ; i++) {
723 for (
int i=0 ; i<
GetN() ; i++) {
724 band->addPoint(
GetX()[i],bandLo[i]) ;
726 for (
int i=
GetN()-1 ; i>=0 ; i--) {
727 band->addPoint(
GetX()[i],bandHi[i]) ;
753 band->SetLineWidth(1) ;
754 band->SetFillColor(
kCyan) ;
755 band->SetLineColor(
kCyan) ;
757 vector<double> bandLo(
GetN()) ;
758 vector<double> bandHi(
GetN()) ;
759 for (
int i=0 ; i<
GetN() ; i++) {
763 for (
int i=0 ; i<
GetN() ; i++) {
764 band->addPoint(
GetX()[i],bandLo[i]) ;
766 for (
int i=
GetN()-1 ; i>=0 ; i--) {
767 band->addPoint(
GetX()[i],bandHi[i]) ;
790 vector<double> y_plus(plusVar.size());
791 vector<double> y_minus(minusVar.size());
793 for (vector<RooCurve*>::const_iterator iter=plusVar.begin() ; iter!=plusVar.end() ; ++iter) {
794 y_plus[j++] = (*iter)->interpolate(
GetX()[i]) ;
797 for (vector<RooCurve*>::const_iterator iter=minusVar.begin() ; iter!=minusVar.end() ; ++iter) {
798 y_minus[j++] = (*iter)->interpolate(
GetX()[i]) ;
800 double y_cen =
GetY()[i] ;
805 for (j=0 ; j<
n ; j++) {
806 F[j] = (y_plus[j]-y_minus[j])/2 ;
810 double sum = F*(C*F) ;
812 lo= y_cen + sqrt(
sum) ;
813 hi= y_cen - sqrt(
sum) ;
822 vector<double>
y(variations.size()) ;
824 for (vector<RooCurve*>::const_iterator iter=variations.begin() ; iter!=variations.end() ; ++iter) {
825 y[j++] = (*iter)->interpolate(
GetX()[i]) ;
832 sort(
y.begin(),
y.end()) ;
834 hi =
y[
y.size()-delta] ;
839 for (
unsigned int k=0 ; k<
y.size() ; k++) {
841 sum_ysq +=
y[k]*
y[k] ;
844 sum_ysq /=
y.size() ;
846 double rms = sqrt(sum_ysq - (sum_y*sum_y)) ;
847 lo =
GetY()[i] - Z*rms ;
867 for(
Int_t i= 0; i <
n; i++) {
876 for(
Int_t i= 2; i <
n-2; i++) {
878 double rdy = std::abs(yTest-other.fY[i])/Yrange ;
881 if(!verbose)
continue;
882 std::cout <<
"RooCurve::isIdentical[" << std::setw(3) << i <<
"] Y tolerance exceeded (" << std::setprecision(5) << std::setw(10) << rdy <<
">" << tol <<
"),";
883 std::cout <<
" x,y=(" << std::right << std::setw(10) <<
fX[i] <<
"," << std::setw(10) <<
fY[i] <<
")\tref: y="
884 << std::setw(10) << other.interpolate(
fX[i], 1.E-15) <<
". [Nearest point from ref: ";
885 auto j = other.findPoint(
fX[i], 1.E10);
886 std::cout <<
"j=" << j <<
"\tx,y=(" << std::setw(10) << other.fX[j] <<
"," << std::setw(10) << other.fY[j] <<
") ]" <<
"\trange=" << Yrange << std::endl;
903 auto hint =
new std::list<double>;
912 hint->push_back(xlo + delta);
913 hint->push_back(xhi - delta);
917 for (
const double x : boundaries) {
918 if (
x - xlo > delta && xhi -
x > delta) {
919 hint->push_back(
x - delta);
920 hint->push_back(
x + delta);
int Int_t
Signed integer 4 bytes (int)
static void indent(ostringstream &buf, int indent_level)
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t SetLineWidth
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 np
Option_t Option_t SetLineColor
Option_t Option_t TPoint TPoint const char x2
Option_t Option_t TPoint TPoint const char x1
Option_t Option_t TPoint TPoint const char y2
Option_t Option_t TPoint TPoint const char y1
The Kahan summation is a compensated summation algorithm, which significantly reduces numerical error...
Abstract interface for evaluating a real-valued function of one real variable and performing numerica...
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
Abstract base class for objects that represent a real value and implements functionality common to al...
RooFit::OwningPtr< RooAbsFunc > bindVars(const RooArgSet &vars, const RooArgSet *nset=nullptr, bool clipInvalid=false) const
Create an interface adaptor f(vars) that binds us to the specified variables (in arbitrary order).
static Int_t numEvalErrors()
Return the number of logged evaluation errors since the last clearing.
static void printEvalErrors(std::ostream &os=std::cout, Int_t maxPerNode=10000000)
Print all outstanding logged evaluation error on the given ostream.
static void clearEvalErrorLog()
Clear the stack of evaluation error messages.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
One-dimensional graphical representation of a real-valued function.
void addPoints(const RooAbsFunc &func, double xlo, double xhi, Int_t minPoints, double prec, double resolution, WingMode wmode, Int_t numee=0, bool doEEVal=false, double eeVal=0.0, std::list< double > *samplingHint=nullptr)
Add points calculated with the specified function, over the range (xlo,xhi).
void printTitle(std::ostream &os) const override
Print the title of this curve.
void initialize()
Perform initialization that is common to all curves.
double getFitRangeBinW() const override
Get the bin width associated with this plotable object.
static constexpr double relativeXEpsilon()
The distance between two points x1 and x2 relative to the full plot range below which two points are ...
void addRange(const RooAbsFunc &func, double x1, double x2, double y1, double y2, double minDy, double minDx, int numee, bool doEEVal, double eeVal, double epsilon)
Fill the range (x1,x2) with points calculated using func(&x).
void printName(std::ostream &os) const override
Print name of object.
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Print the details of this curve.
double interpolate(double x, double tolerance=1e-10) const
Return linearly interpolated value of curve at xvalue.
static std::list< double > * plotSamplingHintForBinBoundaries(std::span< const double > boundaries, double xlo, double xhi)
Returns sampling hints for a histogram with given boundaries.
void printClassName(std::ostream &os) const override
Print the class name of this curve.
RooCurve()
Default constructor.
bool _showProgress
! Show progress indication when adding points
RooCurve * makeErrorBand(const std::vector< RooCurve * > &variations, double Z=1) const
Construct filled RooCurve represented error band that captures alpha% of the variations of the curves...
double chiSquare(const RooHist &hist, int nFitParam) const
Calculate the chi^2/NDOF of this curve with respect to the histogram 'hist' accounting nFitParam floa...
void calcBandInterval(const std::vector< RooCurve * > &variations, Int_t i, double Z, double &lo, double &hi, bool approxGauss) const
double getFitRangeNEvt() const override
Return the number of events associated with the plotable object, it is always 1 for curves.
void shiftCurveToZero()
Find lowest point in curve and move all points in curve so that lowest point will go exactly through ...
void addPoint(double x, double y)
Add a point with the specified coordinates. Update our y-axis limits.
bool isIdentical(const RooCurve &other, double tol=1e-6, bool verbose=true) const
Return true if curve is identical to other curve allowing for given absolute tolerance on each point ...
Int_t findPoint(double value, double tolerance=1e-10) const
Find the nearest point to xvalue.
double average(double lo, double hi) const
Return average curve value in [xFirst,xLast] by integrating curve between points and dividing by xLas...
Graphical representation of binned data based on the TGraphAsymmErrors class.
static constexpr double infinity()
Return internal infinity representation.
void updateYAxisLimits(double y)
void setYAxisLimits(double ymin, double ymax)
void setYAxisLabel(const char *label)
Represents the product of a given set of RooAbsReal objects.
Bool_t IsAlphanumeric() const
const char * GetBinLabel(Int_t bin) const
Return label for bin.
virtual void Set(Int_t nbins, Double_t xmin, Double_t xmax)
Initialize axis with fix bins.
Double_t * GetEXlow() const override
Double_t * GetEYhigh() const override
Double_t * GetEXhigh() const override
Double_t * GetEYlow() const override
A TGraph is an object made of two arrays X and Y with npoints each.
virtual Double_t GetPointX(Int_t i) const
Get x value for point i.
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Double_t * fY
[fNpoints] array of Y points
virtual void Sort(Bool_t(*greater)(const TGraph *, Int_t, Int_t)=&TGraph::CompareX, Bool_t ascending=kTRUE, Int_t low=0, Int_t high=-1111)
Sorts the points of this TGraph using in-place quicksort (see e.g.
void SetName(const char *name="") override
Set graph name.
TAxis * GetXaxis() const
Get x axis of the graph.
Double_t * fX
[fNpoints] array of X points
virtual Double_t GetPointY(Int_t i) const
Get y value for point i.
void SetTitle(const char *title="") override
Change (i.e.
virtual Int_t GetPoint(Int_t i, Double_t &x, Double_t &y) const
Get x and y values for point number i.
const char * GetName() const override
Returns name of object.
const char * GetTitle() const override
Returns title of object.
virtual const char * ClassName() const
Returns name of class to which the object belongs.
const char * Data() const
TString & Append(const char *cs)
RooConstVar & RooConst(double val)
Double_t Erfc(Double_t x)
Computes the complementary error function erfc(x).
static uint64_t sum(uint64_t i)