59using std::ostream, std::list, std::vector, std::min;
70inline Point getPoint(
TGraph const &
gr,
int i)
73 gr.GetPoint(i, p.x, p.y);
98 const RooArgSet *normVars,
double prec,
double resolution,
bool shiftToZero,
WingMode wmode,
99 Int_t nEvalError,
Int_t doEEVal,
double eeVal,
bool showProg)
108 if(0 != strlen(
f.getUnit()) || 0 != strlen(
x.getUnit())) {
110 if(0 != strlen(
f.getUnit())) {
111 title.Append(
f.getUnit());
114 if(0 != strlen(
x.getUnit())) {
116 title.Append(
x.getUnit());
124 std::unique_ptr<RooAbsFunc> funcPtr{scaledFunc.
bindVars(
x, normVars,
true)};
129 std::unique_ptr<std::list<double>> hint{
f.plotSamplingHint(
x,xlo,xhi)};
130 addPoints(*funcPtr,xlo,xhi,xbins+1,prec,resolution,wmode,nEvalError,doEEVal,eeVal,hint.get());
132 ccoutP(Plotting) << std::endl ;
137 int nBinsX =
x.numBins();
138 for(
int i=0; i<nBinsX; ++i){
139 double xval =
x.getBinning().binCenter(i);
148 for (
int i=0 ; i<
GetN() ; i++) {
164 double xlo,
double xhi,
UInt_t minPoints,
double prec,
double resolution,
169 addPoints(func,xlo,xhi,minPoints+1,prec,resolution,wmode,nEvalError,doEEVal,eeVal);
174 for (
int i=0 ; i<
GetN() ; i++) {
202 std::deque<double> pointList ;
206 for (
int i1=0 ; i1<n1 ; i1++) {
207 pointList.push_back(
c1.GetPointX(i1));
212 for (
int i2=0 ; i2<n2 ; i2++) {
213 pointList.push_back(
c2.GetPointX(i2));
217 std::sort(pointList.begin(),pointList.end()) ;
221 for (
auto point : pointList) {
223 if ((point-last)>1
e-10) {
225 addPoint(point,scale1*
c1.interpolate(point)+scale2*
c2.interpolate(point)) ;
256 double minVal = std::numeric_limits<double>::infinity();
257 double maxVal = -std::numeric_limits<double>::infinity();
260 for (
int i = 1; i <
GetN() - 1; i++) {
262 minVal = std::min(
y, minVal);
263 maxVal = std::max(
y, maxVal);
267 for (
int i = 1; i <
GetN() - 1; i++) {
268 Point point = getPoint(*
this, i);
269 SetPoint(i, point.x, point.y - minVal);
284 Int_t minPoints,
double prec,
double resolution,
WingMode wmode,
285 Int_t numee,
bool doEEVal,
double eeVal, list<double>* samplingHint)
289 coutE(InputArguments) <<
fName <<
"::addPoints: input function is not valid" << std::endl;
292 if(minPoints <= 0 || xhi <= xlo) {
293 coutE(InputArguments) <<
fName <<
"::addPoints: bad input (nothing added)" << std::endl;
302 minPoints = samplingHint->size() ;
305 double dx= (xhi-xlo)/(minPoints-1.);
307 std::vector<double> yval(minPoints);
311 std::vector<double> xval;
313 for(
int step= 0; step < minPoints; step++) {
314 xval.push_back(xlo + step*dx) ;
317 std::copy(samplingHint->begin(), samplingHint->end(), std::back_inserter(xval));
320 for (
unsigned int step=0; step < xval.size(); ++step) {
321 double xx = xval[step];
322 if (step ==
static_cast<unsigned int>(minPoints-1))
325 yval[step]= func(&xx);
333 coutW(Plotting) <<
"At observable [x]=" << xx <<
" " ;
343 const double ymax = *std::max_element(yval.begin(), yval.end());
344 const double ymin = *std::min_element(yval.begin(), yval.end());
348 double minDx= resolution*(xhi-xlo);
364 auto iter2 = xval.begin() ;
370 if (iter2==xval.end()) {
378 addRange(func,x1,x2,yval[step-1],yval[step],prec*yrangeEst,minDx,numee,doEEVal,eeVal,epsilon);
387 addPoint(xhi+dx,yval[minPoints-1]) ;
402 double y1,
double y2,
double minDy,
double minDx,
403 int numee,
bool doEEVal,
double eeVal,
double epsilon)
406 if (std::abs(x2-x1) <= epsilon) {
411 double xmid= 0.5*(x1+x2);
412 double ymid= func(&xmid);
420 coutW(Plotting) <<
"At observable [x]=" << xmid <<
" " ;
430 double dy= ymid - 0.5*(y1+y2);
431 if((xmid - x1 >= minDx) && std::abs(dy)>0 && std::abs(dy) >= minDy) {
433 addRange(func,x1,xmid,y1,ymid,minDy,minDx,numee,doEEVal,eeVal,epsilon);
434 addRange(func,xmid,x2,ymid,y2,minDy,minDx,numee,doEEVal,eeVal,epsilon);
518 os <<
indent <<
"--- RooCurve ---" << std::endl ;
520 os <<
indent <<
" Contains " <<
n <<
" points" << std::endl;
521 os <<
indent <<
" Graph points:" << std::endl;
522 for(
Int_t i= 0; i <
n; i++) {
523 os <<
indent << std::setw(3) << i <<
") x = " <<
fX[i] <<
" , y = " <<
fY[i] << std::endl;
545 for (
int i=0 ; i<np ; i++) {
548 Point point = getPoint(hist, i);
551 if (point.x<xstart || point.x>xstop) continue ;
559 double avg =
average(point.x-exl,point.x+exh) ;
563 double pull = (point.y>avg) ? ((point.y-avg)/eyl) : ((point.y-avg)/eyh) ;
570 return chisq.
Sum() / (nbin-nFitParam) ;
584 coutE(InputArguments) <<
"RooCurve::average(" <<
GetName()
585 <<
") invalid range (" << xFirst <<
"," << xLast <<
")" << std::endl ;
588 else if (xFirst == xLast) {
597 Int_t ifirst =
findPoint(xFirst, std::numeric_limits<double>::infinity());
598 Int_t ilast =
findPoint(xLast, std::numeric_limits<double>::infinity());
609 if (ilast < ifirst) {
610 return 0.5*(yFirst+yLast) ;
613 Point firstPt = getPoint(*
this, ifirst);
614 Point lastPt = getPoint(*
this, ilast);
617 double sum = 0.5 * (firstPt.x-xFirst)*(yFirst+firstPt.y);
620 for (
int i=ifirst ; i<ilast ; i++) {
621 Point p1 = getPoint(*
this, i) ;
622 Point p2 = getPoint(*
this, i+1) ;
623 sum += 0.5 * (p2.x-p1.x)*(p1.y+p2.y);
627 sum += 0.5 * (xLast-lastPt.x)*(lastPt.y+yLast);
628 return sum/(xLast-xFirst) ;
639 double delta(std::numeric_limits<double>::max());
642 for (
int i=0 ; i<
n ; i++) {
644 if (std::abs(xvalue-
x)<delta) {
645 delta = std::abs(xvalue-
x) ;
650 return (delta<tolerance)?ibest:-1 ;
666 Point pbest = getPoint(*
this, ibest);
669 if (std::abs(pbest.x-xvalue)<tolerance) {
675 if (pbest.x<xvalue) {
680 Point pother = getPoint(*
this, ibest+1);
681 if (pother.x==pbest.x)
return pbest.y ;
682 retVal = pbest.y + (pother.y-pbest.y)*(xvalue-pbest.x)/(pother.x-pbest.x) ;
689 Point pother = getPoint(*
this, ibest-1);
690 if (pother.x==pbest.x)
return pbest.y ;
691 retVal = pother.y + (pbest.y-pother.y)*(xvalue-pother.x)/(pbest.x-pother.x) ;
713 vector<double> bandLo(
GetN()) ;
714 vector<double> bandHi(
GetN()) ;
715 for (
int i=0 ; i<
GetN() ; i++) {
719 for (
int i=0 ; i<
GetN() ; i++) {
722 for (
int i=
GetN()-1 ; i>=0 ; i--) {
753 vector<double> bandLo(
GetN()) ;
754 vector<double> bandHi(
GetN()) ;
755 for (
int i=0 ; i<
GetN() ; i++) {
759 for (
int i=0 ; i<
GetN() ; i++) {
762 for (
int i=
GetN()-1 ; i>=0 ; i--) {
786 vector<double> y_plus(plusVar.size());
787 vector<double> y_minus(minusVar.size());
789 for (vector<RooCurve*>::const_iterator iter=plusVar.begin() ; iter!=plusVar.end() ; ++iter) {
790 y_plus[j++] = (*iter)->interpolate(
GetX()[i]) ;
793 for (vector<RooCurve*>::const_iterator iter=minusVar.begin() ; iter!=minusVar.end() ; ++iter) {
794 y_minus[j++] = (*iter)->interpolate(
GetX()[i]) ;
796 double y_cen =
GetY()[i] ;
801 for (j=0 ; j<
n ; j++) {
802 F[j] = (y_plus[j]-y_minus[j])/2 ;
806 double sum =
F*(C*
F) ;
808 lo= y_cen + sqrt(
sum) ;
809 hi= y_cen - sqrt(
sum) ;
818 vector<double>
y(variations.size()) ;
820 for (vector<RooCurve*>::const_iterator iter=variations.begin() ; iter!=variations.end() ; ++iter) {
821 y[j++] = (*iter)->interpolate(
GetX()[i]) ;
828 sort(
y.begin(),
y.end()) ;
830 hi =
y[
y.size()-delta] ;
835 for (
unsigned int k=0 ; k<
y.size() ; k++) {
837 sum_ysq +=
y[k]*
y[k] ;
840 sum_ysq /=
y.size() ;
842 double rms = sqrt(sum_ysq - (sum_y*sum_y)) ;
843 lo =
GetY()[i] - Z*rms ;
863 for(
Int_t i= 0; i <
n; i++) {
872 for(
Int_t i= 2; i <
n-2; i++) {
874 double rdy = std::abs(yTest-other.
fY[i])/Yrange ;
877 if(!verbose)
continue;
878 std::cout <<
"RooCurve::isIdentical[" << std::setw(3) << i <<
"] Y tolerance exceeded (" << std::setprecision(5) << std::setw(10) << rdy <<
">" << tol <<
"),";
879 std::cout <<
" x,y=(" << std::right << std::setw(10) <<
fX[i] <<
"," << std::setw(10) <<
fY[i] <<
")\tref: y="
880 << std::setw(10) << other.
interpolate(
fX[i], 1.E-15) <<
". [Nearest point from ref: ";
882 std::cout <<
"j=" << j <<
"\tx,y=(" << std::setw(10) << other.
fX[j] <<
"," << std::setw(10) << other.
fY[j] <<
") ]" <<
"\trange=" << Yrange << std::endl;
899 auto hint =
new std::list<double>;
908 hint->push_back(xlo + delta);
909 hint->push_back(xhi - delta);
913 for (
const double x : boundaries) {
914 if (
x - xlo > delta && xhi -
x > delta) {
915 hint->push_back(
x - delta);
916 hint->push_back(
x + delta);
int Int_t
Signed integer 4 bytes (int).
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int).
static void indent(ostringstream &buf, int indent_level)
TMatrixT< Double_t > TMatrixD
TVectorT< Double_t > TVectorD
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.
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.
virtual void SetFillColor(Color_t fcolor)
Set the fill area color.
virtual void SetLineWidth(Width_t lwidth)
Set the line width.
virtual void SetLineColor(Color_t lcolor)
Set the line color.
virtual void SetBinLabel(Int_t bin, const char *label)
Set 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
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Double_t * fY
[fNpoints] array of Y points
void SetName(const char *name="") override
Set the name of the TNamed.
virtual Double_t GetPointY(Int_t i) const
Double_t * fX
[fNpoints] array of X points
void SetTitle(const char *title="") override
Set the title of the TNamed.
virtual Double_t GetPointX(Int_t i) const
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)
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.
RooConstVar & RooConst(double val)
Double_t Erfc(Double_t x)
Computes the complementary error function erfc(x).
static uint64_t sum(uint64_t i)