/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitCore                                                       *
 * @(#)root/roofitcore:$Id$
 * Authors:                                                                  *
 *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
 *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
 *                                                                           *
 * Copyright (c) 2000-2005, Regents of the University of California          *
 *                          and Stanford University. All rights reserved.    *
 *                                                                           *
 * Redistribution and use in source and binary forms,                        *
 * with or without modification, are permitted according to the terms        *
 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
 *****************************************************************************/

//////////////////////////////////////////////////////////////////////////////
// 
// BEGIN_HTML
// A RooCurve is a one-dimensional graphical representation of a real-valued function.
// A curve is approximated by straight line segments with endpoints chosen to give
// a "good" approximation to the true curve. The goodness of the approximation is
// controlled by a precision and a resolution parameter. To view the points where
// a function y(x) is actually evaluated to approximate a smooth curve, use:
// END_HTML
//
//  RooPlot *p= y.plotOn(x.frame());
//  p->getAttMarker("curve_y")->SetMarkerStyle(20);
//  p->setDrawOptions("curve_y","PL");
//  p->Draw();
//


#include "RooFit.h"

#include "RooCurve.h"
#include "RooHist.h"
#include "RooAbsReal.h"
#include "RooArgSet.h"
#include "RooRealVar.h"
#include "RooRealIntegral.h"
#include "RooRealBinding.h"
#include "RooScaledFunc.h"
#include "RooMsgService.h"

#include "Riostream.h"
#include "TClass.h"
#include "TMath.h"
#include "TMatrixD.h"
#include "TVectorD.h"
#include <iomanip>
#include <math.h>
#include <assert.h>
#include <deque>
#include <algorithm>
#include <limits>

using namespace std ;

ClassImp(RooCurve)


//_____________________________________________________________________________
RooCurve::RooCurve() : _showProgress(kFALSE)
{
  // Default constructor
  initialize();
}


//_____________________________________________________________________________
RooCurve::RooCurve(const RooAbsReal &f, RooAbsRealLValue &x, Double_t xlo, Double_t xhi, Int_t xbins,
		   Double_t scaleFactor, const RooArgSet *normVars, Double_t prec, Double_t resolution,
		   Bool_t shiftToZero, WingMode wmode, Int_t nEvalError, Int_t doEEVal, Double_t eeVal, 
		   Bool_t showProg) : _showProgress(showProg)
{
  // Create a 1-dim curve of the value of the specified real-valued expression
  // as a function of x. Use the optional precision parameter to control
  // how precisely the smooth curve is rasterized. Use the optional argument set
  // to specify how the expression should be normalized. Use the optional scale
  // factor to rescale the expression after normalization.
  // If shiftToZero is set, the entire curve is shift down to make the lowest
  // point in of the curve go through zero.
  

  // grab the function's name and title
  TString name(f.GetName());
  SetName(name.Data());
  TString title(f.GetTitle());
  SetTitle(title.Data());
  // append " ( [<funit> ][/ <xunit> ])" to our y-axis label if necessary
  if(0 != strlen(f.getUnit()) || 0 != strlen(x.getUnit())) {
    title.Append(" ( ");
    if(0 != strlen(f.getUnit())) {
      title.Append(f.getUnit());
      title.Append(" ");
    }
    if(0 != strlen(x.getUnit())) {
      title.Append("/ ");
      title.Append(x.getUnit());
      title.Append(" ");
    }
    title.Append(")");
  }
  setYAxisLabel(title.Data());

  RooAbsFunc *funcPtr = 0;
  RooAbsFunc *rawPtr  = 0;
  funcPtr= f.bindVars(x,normVars,kTRUE);

  // apply a scale factor if necessary
  if(scaleFactor != 1) {
    rawPtr= funcPtr;
    funcPtr= new RooScaledFunc(*rawPtr,scaleFactor);
  }
  assert(0 != funcPtr);

  // calculate the points to add to our curve
  Double_t prevYMax = getYAxisMax() ;
  list<Double_t>* hint = f.plotSamplingHint(x,xlo,xhi) ;
  addPoints(*funcPtr,xlo,xhi,xbins+1,prec,resolution,wmode,nEvalError,doEEVal,eeVal,hint);
  if (_showProgress) {
    ccoutP(Plotting) << endl ;
  }
  if (hint) {
    delete hint ;
  }
  initialize();

  // cleanup
  delete funcPtr;
  if(rawPtr) delete rawPtr;
  if (shiftToZero) shiftCurveToZero(prevYMax) ;

  // Adjust limits
  Int_t i ;
  for (i=0 ; i<GetN() ; i++) {    
    Double_t x2,y2 ;
    GetPoint(i,x2,y2) ;
    updateYAxisLimits(y2);
  }
}



//_____________________________________________________________________________
RooCurve::RooCurve(const char *name, const char *title, const RooAbsFunc &func,
		   Double_t xlo, Double_t xhi, UInt_t minPoints, Double_t prec, Double_t resolution,
		   Bool_t shiftToZero, WingMode wmode, Int_t nEvalError, Int_t doEEVal, Double_t eeVal) :
  _showProgress(kFALSE)
{
  // Create a 1-dim curve of the value of the specified real-valued
  // expression as a function of x. Use the optional precision
  // parameter to control how precisely the smooth curve is
  // rasterized.  If shiftToZero is set, the entire curve is shift
  // down to make the lowest point in of the curve go through zero.

  SetName(name);
  SetTitle(title);
  Double_t prevYMax = getYAxisMax() ;
  addPoints(func,xlo,xhi,minPoints+1,prec,resolution,wmode,nEvalError,doEEVal,eeVal);  
  initialize();
  if (shiftToZero) shiftCurveToZero(prevYMax) ;

  // Adjust limits
  Int_t i ;
  for (i=0 ; i<GetN() ; i++) {    
    Double_t x,y ;
    GetPoint(i,x,y) ;
    updateYAxisLimits(y);
  }
}



//_____________________________________________________________________________
RooCurve::RooCurve(const char* name, const char* title, const RooCurve& c1, const RooCurve& c2, Double_t scale1, Double_t scale2) :
  _showProgress(kFALSE)
{
  // Constructor of curve as sum of two other curves
  //
  // Csum = scale1*c1 + scale2*c2
  //
  
  initialize() ;
  SetName(name) ;
  SetTitle(title) ;

  // Make deque of points in X
  deque<Double_t> pointList ;
  Double_t x,y ;

  // Add X points of C1
  Int_t i1,n1 = c1.GetN() ;
  for (i1=0 ; i1<n1 ; i1++) {
    const_cast<RooCurve&>(c1).GetPoint(i1,x,y) ;
    pointList.push_back(x) ;
  }

  // Add X points of C2
  Int_t i2,n2 = c2.GetN() ;
  for (i2=0 ; i2<n2 ; i2++) {
    const_cast<RooCurve&>(c2).GetPoint(i2,x,y) ;
    pointList.push_back(x) ;
  }
  
  // Sort X points
  sort(pointList.begin(),pointList.end()) ;

  // Loop over X points
  deque<double>::iterator iter ;
  Double_t last(-RooNumber::infinity()) ;
  for (iter=pointList.begin() ; iter!=pointList.end() ; ++iter) {

    if ((*iter-last)>1e-10) {      
      // Add OR of points to new curve, skipping duplicate points within tolerance
      addPoint(*iter,scale1*c1.interpolate(*iter)+scale2*c2.interpolate(*iter)) ;
    }
    last = *iter ;
  }

}



//_____________________________________________________________________________
RooCurve::~RooCurve() 
{
  // Destructor
}



//_____________________________________________________________________________
void RooCurve::initialize() 
{
  // Perform initialization that is common to all curves

  // set default line width in pixels
  SetLineWidth(3);
  // set default line color
  SetLineColor(kBlue);
}



//_____________________________________________________________________________
void RooCurve::shiftCurveToZero(Double_t prevYMax) 
{
  // Find lowest point in curve and move all points in curve so that
  // lowest point will go exactly through zero

  Int_t i ;
  Double_t minVal(1e30) ;
  Double_t maxVal(-1e30) ;

  // First iteration, find current lowest point
  for (i=1 ; i<GetN()-1 ; i++) {
    Double_t x,y ;
    GetPoint(i,x,y) ;
    if (y<minVal) minVal=y ;
    if (y>maxVal) maxVal=y ;
  }

  // Second iteration, lower all points by minVal
  for (i=1 ; i<GetN()-1 ; i++) {
    Double_t x,y ;
    GetPoint(i,x,y) ;
    SetPoint(i,x,y-minVal) ;
  }

  // Check if y-axis range needs readjustment
  if (getYAxisMax()>prevYMax) {
    Double_t newMax = maxVal - minVal ;
    setYAxisLimits(getYAxisMin(), newMax<prevYMax ? prevYMax : newMax) ;
  }
}



//_____________________________________________________________________________
void RooCurve::addPoints(const RooAbsFunc &func, Double_t xlo, Double_t xhi,
			 Int_t minPoints, Double_t prec, Double_t resolution, WingMode wmode,
			 Int_t numee, Bool_t doEEVal, Double_t eeVal, list<Double_t>* samplingHint) 
{
  // Add points calculated with the specified function, over the range (xlo,xhi).
  // Add at least minPoints equally spaced points, and add sufficient points so that
  // the maximum deviation from the final straight-line segements is prec*(ymax-ymin),
  // down to a minimum horizontal spacing of resolution*(xhi-xlo).

  // check the inputs
  if(!func.isValid()) {
    coutE(InputArguments) << fName << "::addPoints: input function is not valid" << endl;
    return;
  }
  if(minPoints <= 0 || xhi <= xlo) {
    coutE(InputArguments) << fName << "::addPoints: bad input (nothing added)" << endl;
    return;
  }

  // Perform a coarse scan of the function to estimate its y range.
  // Save the results so we do not have to re-evaluate at the scan points.

  // Adjust minimum number of points to external sampling hint if used
  if (samplingHint) {
    minPoints = samplingHint->size() ;
  }

  Int_t step;
  Double_t dx= (xhi-xlo)/(minPoints-1.);
  Double_t *yval= new Double_t[minPoints];
  
  // Get list of initial x values. If function provides sampling hint use that,
  // otherwise use default binning of frame
  list<Double_t>* xval = samplingHint ;
  if (!xval) {
    xval = new list<Double_t> ;
    for(step= 0; step < minPoints; step++) {
      xval->push_back(xlo + step*dx) ;
    }    
  }
  

  Double_t ymax(-1e30), ymin(1e30) ;

  step=0 ;
  for(list<Double_t>::iterator iter = xval->begin() ; iter!=xval->end() ; ++iter,++step) {
    Double_t xx = *iter ;
    
    if (step==minPoints-1) xx-=1e-15 ;

    yval[step]= func(&xx);
    if (_showProgress) {
      ccoutP(Plotting) << "." ;
      cout.flush() ;
    }

    if (RooAbsReal::numEvalErrors()>0) {
      if (numee>=0) {
	coutW(Plotting) << "At observable [x]=" << xx <<  " " ;
	RooAbsReal::printEvalErrors(ccoutW(Plotting),numee) ;
      }
      if (doEEVal) {
	yval[step]=eeVal ;
      }
    }
    RooAbsReal::clearEvalErrorLog() ;


    if (yval[step]>ymax) ymax=yval[step] ;
    if (yval[step]<ymin) ymin=yval[step] ;
  }
  Double_t yrangeEst=(ymax-ymin) ;

  // store points of the coarse scan and calculate any refinements necessary
  Double_t minDx= resolution*(xhi-xlo);
  Double_t x1,x2= xlo;

  if (wmode==Extended) {
    addPoint(xlo-dx,0) ;
    addPoint(xlo-dx,yval[0]) ;
  } else if (wmode==Straight) {
    addPoint(xlo,0) ;
  }

  addPoint(xlo,yval[0]);

  list<Double_t>::iterator iter2 = xval->begin() ;
  x1 = *iter2 ;
  step=1 ;
  while(true) {
    x1= x2;
    iter2++ ;
    if (iter2==xval->end()) {
      break ;
    }
    x2= *iter2 ;
    if (prec<0) {
      // If precision is <0, no attempt at recursive interpolation is made
      addPoint(x2,yval[step]) ;
    } else {
      addRange(func,x1,x2,yval[step-1],yval[step],prec*yrangeEst,minDx,numee,doEEVal,eeVal);
    }
    step++ ;
  }
  addPoint(xhi,yval[minPoints-1]) ;

  if (wmode==Extended) {
    addPoint(xhi+dx,yval[minPoints-1]) ;
    addPoint(xhi+dx,0) ;
  } else if (wmode==Straight) {
    addPoint(xhi,0) ;
  }

  // cleanup
  delete [] yval;
  if (xval != samplingHint) {
    delete xval ;
  }

}


//_____________________________________________________________________________
void RooCurve::addRange(const RooAbsFunc& func, Double_t x1, Double_t x2,
			Double_t y1, Double_t y2, Double_t minDy, Double_t minDx,
			Int_t numee, Bool_t doEEVal, Double_t eeVal) 
{
  // Fill the range (x1,x2) with points calculated using func(&x). No point will
  // be added at x1, and a point will always be added at x2. The density of points
  // will be calculated so that the maximum deviation from a straight line
  // approximation is prec*(ymax-ymin) down to the specified minimum horizontal spacing.

  // Explicitly skip empty ranges to eliminate point duplication
  if (fabs(x2-x1)<1e-20) {
    return ;
  }

  // calculate our value at the midpoint of this range
  Double_t xmid= 0.5*(x1+x2);
  Double_t ymid= func(&xmid);
  if (_showProgress) {
    ccoutP(Plotting) << "." ;
    cout.flush() ;
  }

  if (RooAbsReal::numEvalErrors()>0) {
    if (numee>=0) {
      coutW(Plotting) << "At observable [x]=" << xmid <<  " " ;
      RooAbsReal::printEvalErrors(ccoutW(Plotting),numee) ;
    }
    if (doEEVal) {
      ymid=eeVal ;
    }
  }
  RooAbsReal::clearEvalErrorLog() ;

  // test if the midpoint is sufficiently close to a straight line across this interval
  Double_t dy= ymid - 0.5*(y1+y2);
  if((xmid - x1 >= minDx) && fabs(dy)>0 && fabs(dy) >= minDy) {
    // fill in each subrange
    addRange(func,x1,xmid,y1,ymid,minDy,minDx,numee,doEEVal,eeVal);
    addRange(func,xmid,x2,ymid,y2,minDy,minDx,numee,doEEVal,eeVal);
  }
  else {
    // add the endpoint
    addPoint(x2,y2);
  }
}


//_____________________________________________________________________________
void RooCurve::addPoint(Double_t x, Double_t y) 
{
  // Add a point with the specified coordinates. Update our y-axis limits.
  
//   cout << "RooCurve("<< GetName() << ") adding point at (" << x << "," << y << ")" << endl ;
  Int_t next= GetN();
  SetPoint(next, x, y);
  updateYAxisLimits(y) ;
}


//_____________________________________________________________________________
Double_t RooCurve::getFitRangeNEvt() const {
  // Return the number of events associated with the plotable object,
  // it is always 1 for curves
  return 1;
}


//_____________________________________________________________________________
Double_t RooCurve::getFitRangeNEvt(Double_t, Double_t) const 
{
  // Return the number of events associated with the plotable object,
  // in the given range. It is always 1 for curves
  return 1 ;
}


//_____________________________________________________________________________
Double_t RooCurve::getFitRangeBinW() const {
  // Get the bin width associated with this plotable object.
  // It is alwats zero for curves
  return 0 ;
}



//_____________________________________________________________________________
void RooCurve::printName(ostream& os) const 
// 
{
  // Print the name of this curve
  os << GetName() ;
}


//_____________________________________________________________________________
void RooCurve::printTitle(ostream& os) const 
{
  // Print the title of this curve
  os << GetTitle() ;
}


//_____________________________________________________________________________
void RooCurve::printClassName(ostream& os) const 
{
  // Print the class name of this curve
  os << IsA()->GetName() ;
}



//_____________________________________________________________________________
void RooCurve::printMultiline(ostream& os, Int_t /*contents*/, Bool_t /*verbose*/, TString indent) const
{
  // Print the details of this curve
  os << indent << "--- RooCurve ---" << endl ;
  Int_t n= GetN();
  os << indent << "  Contains " << n << " points" << endl;
  os << indent << "  Graph points:" << endl;
  for(Int_t i= 0; i < n; i++) {
    os << indent << setw(3) << i << ") x = " << fX[i] << " , y = " << fY[i] << endl;
  }
}



//_____________________________________________________________________________
Double_t RooCurve::chiSquare(const RooHist& hist, Int_t nFitParam) const 
{
  // Calculate the chi^2/NDOF of this curve with respect to the histogram
  // 'hist' accounting nFitParam floating parameters in case the curve
  // was the result of a fit

  Int_t i,np = hist.GetN() ;
  Double_t x,y,eyl,eyh,exl,exh ;

  // Find starting and ending bin of histogram based on range of RooCurve
  Double_t xstart,xstop ;

#if ROOT_VERSION_CODE >= ROOT_VERSION(4,0,1)
  GetPoint(0,xstart,y) ;
  GetPoint(GetN()-1,xstop,y) ;
#else
  const_cast<RooCurve*>(this)->GetPoint(0,xstart,y) ;
  const_cast<RooCurve*>(this)->GetPoint(GetN()-1,xstop,y) ;
#endif

  Int_t nbin(0) ;

  Double_t chisq(0) ;
  for (i=0 ; i<np ; i++) {   

    // Retrieve histogram contents
    ((RooHist&)hist).GetPoint(i,x,y) ;

    // Check if point is in range of curve
    if (x<xstart || x>xstop) continue ;

    eyl = hist.GetEYlow()[i] ;
    eyh = hist.GetEYhigh()[i] ;
    exl = hist.GetEXlow()[i] ;
    exh = hist.GetEXhigh()[i] ;

    // Integrate function over this bin
    Double_t avg = average(x-exl,x+exh) ;

    // Add pull^2 to chisq
    if (y!=0) {      
      Double_t pull = (y>avg) ? ((y-avg)/eyl) : ((y-avg)/eyh) ;
      chisq += pull*pull ;
      nbin++ ;
    }
  }

  // Return chisq/nDOF 
  return chisq / (nbin-nFitParam) ;
}



//_____________________________________________________________________________
Double_t RooCurve::average(Double_t xFirst, Double_t xLast) const
{
  // Return average curve value in [xFirst,xLast] by integrating curve between points
  // and dividing by xLast-xFirst

  if (xFirst>=xLast) {
    coutE(InputArguments) << "RooCurve::average(" << GetName() 
			  << ") invalid range (" << xFirst << "," << xLast << ")" << endl ;
    return 0 ;
  }

  // Find Y values and begin and end points
  Double_t yFirst = interpolate(xFirst,1e-10) ;
  Double_t yLast = interpolate(xLast,1e-10) ;

  // Find first and last mid points
  Int_t ifirst = findPoint(xFirst,1e10) ;
  Int_t ilast  = findPoint(xLast,1e10) ;
  Double_t xFirstPt,yFirstPt,xLastPt,yLastPt ;
  const_cast<RooCurve&>(*this).GetPoint(ifirst,xFirstPt,yFirstPt) ;
  const_cast<RooCurve&>(*this).GetPoint(ilast,xLastPt,yLastPt) ;

  Double_t tolerance=1e-3*(xLast-xFirst) ;

  // Handle trivial scenario -- no midway points, point only at or outside given range
  if (ilast-ifirst==1 &&(xFirstPt-xFirst)<-1*tolerance && (xLastPt-xLast)>tolerance) {
    return 0.5*(yFirst+yLast) ;
  }
 
  // If first point closest to xFirst is at xFirst or before xFirst take the next point
  // as the first midway point   
  if ((xFirstPt-xFirst)<-1*tolerance) {
    ifirst++ ;
    const_cast<RooCurve&>(*this).GetPoint(ifirst,xFirstPt,yFirstPt) ;
  }
  
  // If last point closest to yLast is at yLast or beyond yLast the the previous point
  // as the last midway point
  if ((xLastPt-xLast)>tolerance) {
    ilast-- ;
    const_cast<RooCurve&>(*this).GetPoint(ilast,xLastPt,yLastPt) ;
  }

  Double_t sum(0),x1,y1,x2,y2 ;

  // Trapezoid integration from lower edge to first midpoint
  sum += (xFirstPt-xFirst)*(yFirst+yFirstPt)/2 ;

  // Trapezoid integration between midpoints
  Int_t i ;
  for (i=ifirst ; i<ilast ; i++) {
    const_cast<RooCurve&>(*this).GetPoint(i,x1,y1) ;
    const_cast<RooCurve&>(*this).GetPoint(i+1,x2,y2) ;
    sum += (x2-x1)*(y1+y2)/2 ;
  }

  // Trapezoid integration from last midpoint to upper edge 
  sum += (xLast-xLastPt)*(yLastPt+yLast)/2 ;
  return sum/(xLast-xFirst) ;
}



//_____________________________________________________________________________
Int_t RooCurve::findPoint(Double_t xvalue, Double_t tolerance) const
{
  // Find the nearest point to xvalue. Return -1 if distance
  // exceeds tolerance

  Double_t delta(std::numeric_limits<double>::max()),x,y ;
  Int_t i,n = GetN() ;
  Int_t ibest(-1) ;
  for (i=0 ; i<n ; i++) {
    ((RooCurve&)*this).GetPoint(i,x,y) ;
    if (fabs(xvalue-x)<delta) {
      delta = fabs(xvalue-x) ;
      ibest = i ;
    }
  }

  return (delta<tolerance)?ibest:-1 ;
}


//_____________________________________________________________________________
Double_t RooCurve::interpolate(Double_t xvalue, Double_t tolerance) const
{
  // Return linearly interpolated value of curve at xvalue. If distance
  // to nearest point is less than tolerance, return nearest point value
  // instead

  // Find best point
  int n = GetN() ;
  int ibest = findPoint(xvalue,1e10) ;
  
  // Get position of best point
  Double_t xbest, ybest ;
  const_cast<RooCurve*>(this)->GetPoint(ibest,xbest,ybest) ;

  // Handle trivial case of being dead on
  if (fabs(xbest-xvalue)<tolerance) {
    return ybest ;
  }

  // Get nearest point on other side w.r.t. xvalue
  Double_t xother,yother, retVal(0) ;
  if (xbest<xvalue) {
    if (ibest==n-1) {
      // Value beyond end requested -- return value of last point
      return ybest ;
    }
    const_cast<RooCurve*>(this)->GetPoint(ibest+1,xother,yother) ;        
    if (xother==xbest) return ybest ;
    retVal = ybest + (yother-ybest)*(xvalue-xbest)/(xother-xbest) ; 

  } else {
    if (ibest==0) {
      // Value before 1st point requested -- return value of 1st point
      return ybest ;
    }
    const_cast<RooCurve*>(this)->GetPoint(ibest-1,xother,yother) ;    
    if (xother==xbest) return ybest ;
    retVal = yother + (ybest-yother)*(xvalue-xother)/(xbest-xother) ;
  }
 
  return retVal ;
}




//_____________________________________________________________________________
RooCurve* RooCurve::makeErrorBand(const vector<RooCurve*>& variations, Double_t Z) const
{
  // Construct filled RooCurve represented error band that captures alpha% of the variations
  // of the curves passed through argument variations, where the percentage alpha corresponds to
  // the central interval fraction of a significance Z
  
  RooCurve* band = new RooCurve ;
  band->SetName(Form("%s_errorband",GetName())) ;
  band->SetLineWidth(1) ;
  band->SetFillColor(kCyan) ;
  band->SetLineColor(kCyan) ;

  vector<double> bandLo(GetN()) ;
  vector<double> bandHi(GetN()) ;
  for (int i=0 ; i<GetN() ; i++) {
    calcBandInterval(variations,i,Z,bandLo[i],bandHi[i],kFALSE) ;
  }
  
  for (int i=0 ; i<GetN() ; i++) {
    band->addPoint(GetX()[i],bandLo[i]) ;
  }
  for (int i=GetN()-1 ; i>=0 ; i--) {
    band->addPoint(GetX()[i],bandHi[i]) ;
  }	   
  
  return band ;
}




//_____________________________________________________________________________
RooCurve* RooCurve::makeErrorBand(const vector<RooCurve*>& plusVar, const vector<RooCurve*>& minusVar, const TMatrixD& C, Double_t Z) const
{
  // Construct filled RooCurve represented error band represent the error added in quadrature defined by the curves arguments
  // plusVar and minusVar corresponding to one-sigma variations of each parameter. The resulting error band, combined used the correlation matrix C
  // is multiplied with the significance parameter Z to construct the equivalent of a Z sigma error band (in Gaussian approximation)
  
  RooCurve* band = new RooCurve ;
  band->SetName(Form("%s_errorband",GetName())) ;
  band->SetLineWidth(1) ;
  band->SetFillColor(kCyan) ;
  band->SetLineColor(kCyan) ;

  vector<double> bandLo(GetN()) ;
  vector<double> bandHi(GetN()) ;
  for (int i=0 ; i<GetN() ; i++) {
    calcBandInterval(plusVar,minusVar,i,C,Z,bandLo[i],bandHi[i]) ;
  }
  
  for (int i=0 ; i<GetN() ; i++) {
    band->addPoint(GetX()[i],bandLo[i]) ;
  }
  for (int i=GetN()-1 ; i>=0 ; i--) {
    band->addPoint(GetX()[i],bandHi[i]) ;
  }	   
  
  return band ;
}





//_____________________________________________________________________________
void RooCurve::calcBandInterval(const vector<RooCurve*>& plusVar, const vector<RooCurve*>& minusVar,Int_t i, const TMatrixD& C, Double_t /*Z*/, Double_t& lo, Double_t& hi) const
{
  // Retrieve variation points from curves
  vector<double> y_plus(plusVar.size()), y_minus(minusVar.size()) ;
  Int_t j(0) ;
  for (vector<RooCurve*>::const_iterator iter=plusVar.begin() ; iter!=plusVar.end() ; iter++) {
    y_plus[j++] = (*iter)->interpolate(GetX()[i]) ;    
  }
  j=0 ;
  for (vector<RooCurve*>::const_iterator iter=minusVar.begin() ; iter!=minusVar.end() ; iter++) {
    y_minus[j++] = (*iter)->interpolate(GetX()[i]) ;
  }
  Double_t y_cen = GetY()[i] ;
  Int_t n = j ;

  // Make vector of variations
  TVectorD F(plusVar.size()) ;
  for (j=0 ; j<n ; j++) {
    F[j] = (y_plus[j]-y_minus[j])/2 ;
  }

  // Calculate error in linear approximation from variations and correlation coefficient
  Double_t sum = F*(C*F) ;

  lo= y_cen + sqrt(sum) ;
  hi= y_cen - sqrt(sum) ;
}



//_____________________________________________________________________________
void RooCurve::calcBandInterval(const vector<RooCurve*>& variations,Int_t i,Double_t Z, Double_t& lo, Double_t& hi, Bool_t approxGauss) const
{
  vector<double> y(variations.size()) ;
  Int_t j(0) ;
  for (vector<RooCurve*>::const_iterator iter=variations.begin() ; iter!=variations.end() ; iter++) {
    y[j++] = (*iter)->interpolate(GetX()[i]) ;
}

  if (!approxGauss) {
    // Construct central 68% interval from variations collected at each point
    Double_t pvalue = TMath::Erfc(Z/sqrt(2.)) ;
    Int_t delta = Int_t( y.size()*(pvalue)/2 + 0.5) ;
    sort(y.begin(),y.end()) ;    
    lo = y[delta] ;
    hi = y[y.size()-delta] ;  
  } else {
    // Estimate R.M.S of variations at each point and use that as Gaussian sigma
    Double_t sum_y(0), sum_ysq(0) ;
    for (unsigned int k=0 ; k<y.size() ; k++) {
      sum_y   += y[k] ;
      sum_ysq += y[k]*y[k] ;
    }
    sum_y /= y.size() ;
    sum_ysq /= y.size() ;

    Double_t rms = sqrt(sum_ysq - (sum_y*sum_y)) ;
    lo = GetY()[i] - Z*rms ;
    hi = GetY()[i] + Z*rms ;    
  }
}




//_____________________________________________________________________________
Bool_t RooCurve::isIdentical(const RooCurve& other, Double_t tol) const 
{
  // Return true if curve is identical to other curve allowing for given
  // absolute tolerance on each point compared point.

  // Determine X range and Y range
  Int_t n= min(GetN(),other.GetN());
  Double_t xmin(1e30), xmax(-1e30), ymin(1e30), ymax(-1e30) ;
  for(Int_t i= 0; i < n; i++) {
    if (fX[i]<xmin) xmin=fX[i] ;
    if (fX[i]>xmax) xmax=fX[i] ;
    if (fY[i]<ymin) ymin=fY[i] ;
    if (fY[i]>ymax) ymax=fY[i] ;
  }
  Double_t Yrange=ymax-ymin ;

  Bool_t ret(kTRUE) ;
  for(Int_t i= 2; i < n-2; i++) {
    Double_t yTest = interpolate(other.fX[i],1e-10) ;
    Double_t rdy = fabs(yTest-other.fY[i])/Yrange ;
    if (rdy>tol) {

//       cout << "xref = " << other.fX[i] << " yref = " << other.fY[i] << " xtest = " << fX[i] << " ytest = " << fY[i] 
// 	   << " ytestInt[other.fX] = " << interpolate(other.fX[i],1e-10) << endl ;
      
      cout << "RooCurve::isIdentical[" << i << "] Y tolerance exceeded (" << rdy << ">" << tol 
	   << "), X=" << other.fX[i] << "(" << fX[i] << ")" << " Ytest=" << yTest << " Yref=" << other.fY[i] << " range = " << Yrange << endl ;
      ret=kFALSE ;
    }
  }
      
  return ret ;
}


 RooCurve.cxx:1
 RooCurve.cxx:2
 RooCurve.cxx:3
 RooCurve.cxx:4
 RooCurve.cxx:5
 RooCurve.cxx:6
 RooCurve.cxx:7
 RooCurve.cxx:8
 RooCurve.cxx:9
 RooCurve.cxx:10
 RooCurve.cxx:11
 RooCurve.cxx:12
 RooCurve.cxx:13
 RooCurve.cxx:14
 RooCurve.cxx:15
 RooCurve.cxx:16
 RooCurve.cxx:17
 RooCurve.cxx:18
 RooCurve.cxx:19
 RooCurve.cxx:20
 RooCurve.cxx:21
 RooCurve.cxx:22
 RooCurve.cxx:23
 RooCurve.cxx:24
 RooCurve.cxx:25
 RooCurve.cxx:26
 RooCurve.cxx:27
 RooCurve.cxx:28
 RooCurve.cxx:29
 RooCurve.cxx:30
 RooCurve.cxx:31
 RooCurve.cxx:32
 RooCurve.cxx:33
 RooCurve.cxx:34
 RooCurve.cxx:35
 RooCurve.cxx:36
 RooCurve.cxx:37
 RooCurve.cxx:38
 RooCurve.cxx:39
 RooCurve.cxx:40
 RooCurve.cxx:41
 RooCurve.cxx:42
 RooCurve.cxx:43
 RooCurve.cxx:44
 RooCurve.cxx:45
 RooCurve.cxx:46
 RooCurve.cxx:47
 RooCurve.cxx:48
 RooCurve.cxx:49
 RooCurve.cxx:50
 RooCurve.cxx:51
 RooCurve.cxx:52
 RooCurve.cxx:53
 RooCurve.cxx:54
 RooCurve.cxx:55
 RooCurve.cxx:56
 RooCurve.cxx:57
 RooCurve.cxx:58
 RooCurve.cxx:59
 RooCurve.cxx:60
 RooCurve.cxx:61
 RooCurve.cxx:62
 RooCurve.cxx:63
 RooCurve.cxx:64
 RooCurve.cxx:65
 RooCurve.cxx:66
 RooCurve.cxx:67
 RooCurve.cxx:68
 RooCurve.cxx:69
 RooCurve.cxx:70
 RooCurve.cxx:71
 RooCurve.cxx:72
 RooCurve.cxx:73
 RooCurve.cxx:74
 RooCurve.cxx:75
 RooCurve.cxx:76
 RooCurve.cxx:77
 RooCurve.cxx:78
 RooCurve.cxx:79
 RooCurve.cxx:80
 RooCurve.cxx:81
 RooCurve.cxx:82
 RooCurve.cxx:83
 RooCurve.cxx:84
 RooCurve.cxx:85
 RooCurve.cxx:86
 RooCurve.cxx:87
 RooCurve.cxx:88
 RooCurve.cxx:89
 RooCurve.cxx:90
 RooCurve.cxx:91
 RooCurve.cxx:92
 RooCurve.cxx:93
 RooCurve.cxx:94
 RooCurve.cxx:95
 RooCurve.cxx:96
 RooCurve.cxx:97
 RooCurve.cxx:98
 RooCurve.cxx:99
 RooCurve.cxx:100
 RooCurve.cxx:101
 RooCurve.cxx:102
 RooCurve.cxx:103
 RooCurve.cxx:104
 RooCurve.cxx:105
 RooCurve.cxx:106
 RooCurve.cxx:107
 RooCurve.cxx:108
 RooCurve.cxx:109
 RooCurve.cxx:110
 RooCurve.cxx:111
 RooCurve.cxx:112
 RooCurve.cxx:113
 RooCurve.cxx:114
 RooCurve.cxx:115
 RooCurve.cxx:116
 RooCurve.cxx:117
 RooCurve.cxx:118
 RooCurve.cxx:119
 RooCurve.cxx:120
 RooCurve.cxx:121
 RooCurve.cxx:122
 RooCurve.cxx:123
 RooCurve.cxx:124
 RooCurve.cxx:125
 RooCurve.cxx:126
 RooCurve.cxx:127
 RooCurve.cxx:128
 RooCurve.cxx:129
 RooCurve.cxx:130
 RooCurve.cxx:131
 RooCurve.cxx:132
 RooCurve.cxx:133
 RooCurve.cxx:134
 RooCurve.cxx:135
 RooCurve.cxx:136
 RooCurve.cxx:137
 RooCurve.cxx:138
 RooCurve.cxx:139
 RooCurve.cxx:140
 RooCurve.cxx:141
 RooCurve.cxx:142
 RooCurve.cxx:143
 RooCurve.cxx:144
 RooCurve.cxx:145
 RooCurve.cxx:146
 RooCurve.cxx:147
 RooCurve.cxx:148
 RooCurve.cxx:149
 RooCurve.cxx:150
 RooCurve.cxx:151
 RooCurve.cxx:152
 RooCurve.cxx:153
 RooCurve.cxx:154
 RooCurve.cxx:155
 RooCurve.cxx:156
 RooCurve.cxx:157
 RooCurve.cxx:158
 RooCurve.cxx:159
 RooCurve.cxx:160
 RooCurve.cxx:161
 RooCurve.cxx:162
 RooCurve.cxx:163
 RooCurve.cxx:164
 RooCurve.cxx:165
 RooCurve.cxx:166
 RooCurve.cxx:167
 RooCurve.cxx:168
 RooCurve.cxx:169
 RooCurve.cxx:170
 RooCurve.cxx:171
 RooCurve.cxx:172
 RooCurve.cxx:173
 RooCurve.cxx:174
 RooCurve.cxx:175
 RooCurve.cxx:176
 RooCurve.cxx:177
 RooCurve.cxx:178
 RooCurve.cxx:179
 RooCurve.cxx:180
 RooCurve.cxx:181
 RooCurve.cxx:182
 RooCurve.cxx:183
 RooCurve.cxx:184
 RooCurve.cxx:185
 RooCurve.cxx:186
 RooCurve.cxx:187
 RooCurve.cxx:188
 RooCurve.cxx:189
 RooCurve.cxx:190
 RooCurve.cxx:191
 RooCurve.cxx:192
 RooCurve.cxx:193
 RooCurve.cxx:194
 RooCurve.cxx:195
 RooCurve.cxx:196
 RooCurve.cxx:197
 RooCurve.cxx:198
 RooCurve.cxx:199
 RooCurve.cxx:200
 RooCurve.cxx:201
 RooCurve.cxx:202
 RooCurve.cxx:203
 RooCurve.cxx:204
 RooCurve.cxx:205
 RooCurve.cxx:206
 RooCurve.cxx:207
 RooCurve.cxx:208
 RooCurve.cxx:209
 RooCurve.cxx:210
 RooCurve.cxx:211
 RooCurve.cxx:212
 RooCurve.cxx:213
 RooCurve.cxx:214
 RooCurve.cxx:215
 RooCurve.cxx:216
 RooCurve.cxx:217
 RooCurve.cxx:218
 RooCurve.cxx:219
 RooCurve.cxx:220
 RooCurve.cxx:221
 RooCurve.cxx:222
 RooCurve.cxx:223
 RooCurve.cxx:224
 RooCurve.cxx:225
 RooCurve.cxx:226
 RooCurve.cxx:227
 RooCurve.cxx:228
 RooCurve.cxx:229
 RooCurve.cxx:230
 RooCurve.cxx:231
 RooCurve.cxx:232
 RooCurve.cxx:233
 RooCurve.cxx:234
 RooCurve.cxx:235
 RooCurve.cxx:236
 RooCurve.cxx:237
 RooCurve.cxx:238
 RooCurve.cxx:239
 RooCurve.cxx:240
 RooCurve.cxx:241
 RooCurve.cxx:242
 RooCurve.cxx:243
 RooCurve.cxx:244
 RooCurve.cxx:245
 RooCurve.cxx:246
 RooCurve.cxx:247
 RooCurve.cxx:248
 RooCurve.cxx:249
 RooCurve.cxx:250
 RooCurve.cxx:251
 RooCurve.cxx:252
 RooCurve.cxx:253
 RooCurve.cxx:254
 RooCurve.cxx:255
 RooCurve.cxx:256
 RooCurve.cxx:257
 RooCurve.cxx:258
 RooCurve.cxx:259
 RooCurve.cxx:260
 RooCurve.cxx:261
 RooCurve.cxx:262
 RooCurve.cxx:263
 RooCurve.cxx:264
 RooCurve.cxx:265
 RooCurve.cxx:266
 RooCurve.cxx:267
 RooCurve.cxx:268
 RooCurve.cxx:269
 RooCurve.cxx:270
 RooCurve.cxx:271
 RooCurve.cxx:272
 RooCurve.cxx:273
 RooCurve.cxx:274
 RooCurve.cxx:275
 RooCurve.cxx:276
 RooCurve.cxx:277
 RooCurve.cxx:278
 RooCurve.cxx:279
 RooCurve.cxx:280
 RooCurve.cxx:281
 RooCurve.cxx:282
 RooCurve.cxx:283
 RooCurve.cxx:284
 RooCurve.cxx:285
 RooCurve.cxx:286
 RooCurve.cxx:287
 RooCurve.cxx:288
 RooCurve.cxx:289
 RooCurve.cxx:290
 RooCurve.cxx:291
 RooCurve.cxx:292
 RooCurve.cxx:293
 RooCurve.cxx:294
 RooCurve.cxx:295
 RooCurve.cxx:296
 RooCurve.cxx:297
 RooCurve.cxx:298
 RooCurve.cxx:299
 RooCurve.cxx:300
 RooCurve.cxx:301
 RooCurve.cxx:302
 RooCurve.cxx:303
 RooCurve.cxx:304
 RooCurve.cxx:305
 RooCurve.cxx:306
 RooCurve.cxx:307
 RooCurve.cxx:308
 RooCurve.cxx:309
 RooCurve.cxx:310
 RooCurve.cxx:311
 RooCurve.cxx:312
 RooCurve.cxx:313
 RooCurve.cxx:314
 RooCurve.cxx:315
 RooCurve.cxx:316
 RooCurve.cxx:317
 RooCurve.cxx:318
 RooCurve.cxx:319
 RooCurve.cxx:320
 RooCurve.cxx:321
 RooCurve.cxx:322
 RooCurve.cxx:323
 RooCurve.cxx:324
 RooCurve.cxx:325
 RooCurve.cxx:326
 RooCurve.cxx:327
 RooCurve.cxx:328
 RooCurve.cxx:329
 RooCurve.cxx:330
 RooCurve.cxx:331
 RooCurve.cxx:332
 RooCurve.cxx:333
 RooCurve.cxx:334
 RooCurve.cxx:335
 RooCurve.cxx:336
 RooCurve.cxx:337
 RooCurve.cxx:338
 RooCurve.cxx:339
 RooCurve.cxx:340
 RooCurve.cxx:341
 RooCurve.cxx:342
 RooCurve.cxx:343
 RooCurve.cxx:344
 RooCurve.cxx:345
 RooCurve.cxx:346
 RooCurve.cxx:347
 RooCurve.cxx:348
 RooCurve.cxx:349
 RooCurve.cxx:350
 RooCurve.cxx:351
 RooCurve.cxx:352
 RooCurve.cxx:353
 RooCurve.cxx:354
 RooCurve.cxx:355
 RooCurve.cxx:356
 RooCurve.cxx:357
 RooCurve.cxx:358
 RooCurve.cxx:359
 RooCurve.cxx:360
 RooCurve.cxx:361
 RooCurve.cxx:362
 RooCurve.cxx:363
 RooCurve.cxx:364
 RooCurve.cxx:365
 RooCurve.cxx:366
 RooCurve.cxx:367
 RooCurve.cxx:368
 RooCurve.cxx:369
 RooCurve.cxx:370
 RooCurve.cxx:371
 RooCurve.cxx:372
 RooCurve.cxx:373
 RooCurve.cxx:374
 RooCurve.cxx:375
 RooCurve.cxx:376
 RooCurve.cxx:377
 RooCurve.cxx:378
 RooCurve.cxx:379
 RooCurve.cxx:380
 RooCurve.cxx:381
 RooCurve.cxx:382
 RooCurve.cxx:383
 RooCurve.cxx:384
 RooCurve.cxx:385
 RooCurve.cxx:386
 RooCurve.cxx:387
 RooCurve.cxx:388
 RooCurve.cxx:389
 RooCurve.cxx:390
 RooCurve.cxx:391
 RooCurve.cxx:392
 RooCurve.cxx:393
 RooCurve.cxx:394
 RooCurve.cxx:395
 RooCurve.cxx:396
 RooCurve.cxx:397
 RooCurve.cxx:398
 RooCurve.cxx:399
 RooCurve.cxx:400
 RooCurve.cxx:401
 RooCurve.cxx:402
 RooCurve.cxx:403
 RooCurve.cxx:404
 RooCurve.cxx:405
 RooCurve.cxx:406
 RooCurve.cxx:407
 RooCurve.cxx:408
 RooCurve.cxx:409
 RooCurve.cxx:410
 RooCurve.cxx:411
 RooCurve.cxx:412
 RooCurve.cxx:413
 RooCurve.cxx:414
 RooCurve.cxx:415
 RooCurve.cxx:416
 RooCurve.cxx:417
 RooCurve.cxx:418
 RooCurve.cxx:419
 RooCurve.cxx:420
 RooCurve.cxx:421
 RooCurve.cxx:422
 RooCurve.cxx:423
 RooCurve.cxx:424
 RooCurve.cxx:425
 RooCurve.cxx:426
 RooCurve.cxx:427
 RooCurve.cxx:428
 RooCurve.cxx:429
 RooCurve.cxx:430
 RooCurve.cxx:431
 RooCurve.cxx:432
 RooCurve.cxx:433
 RooCurve.cxx:434
 RooCurve.cxx:435
 RooCurve.cxx:436
 RooCurve.cxx:437
 RooCurve.cxx:438
 RooCurve.cxx:439
 RooCurve.cxx:440
 RooCurve.cxx:441
 RooCurve.cxx:442
 RooCurve.cxx:443
 RooCurve.cxx:444
 RooCurve.cxx:445
 RooCurve.cxx:446
 RooCurve.cxx:447
 RooCurve.cxx:448
 RooCurve.cxx:449
 RooCurve.cxx:450
 RooCurve.cxx:451
 RooCurve.cxx:452
 RooCurve.cxx:453
 RooCurve.cxx:454
 RooCurve.cxx:455
 RooCurve.cxx:456
 RooCurve.cxx:457
 RooCurve.cxx:458
 RooCurve.cxx:459
 RooCurve.cxx:460
 RooCurve.cxx:461
 RooCurve.cxx:462
 RooCurve.cxx:463
 RooCurve.cxx:464
 RooCurve.cxx:465
 RooCurve.cxx:466
 RooCurve.cxx:467
 RooCurve.cxx:468
 RooCurve.cxx:469
 RooCurve.cxx:470
 RooCurve.cxx:471
 RooCurve.cxx:472
 RooCurve.cxx:473
 RooCurve.cxx:474
 RooCurve.cxx:475
 RooCurve.cxx:476
 RooCurve.cxx:477
 RooCurve.cxx:478
 RooCurve.cxx:479
 RooCurve.cxx:480
 RooCurve.cxx:481
 RooCurve.cxx:482
 RooCurve.cxx:483
 RooCurve.cxx:484
 RooCurve.cxx:485
 RooCurve.cxx:486
 RooCurve.cxx:487
 RooCurve.cxx:488
 RooCurve.cxx:489
 RooCurve.cxx:490
 RooCurve.cxx:491
 RooCurve.cxx:492
 RooCurve.cxx:493
 RooCurve.cxx:494
 RooCurve.cxx:495
 RooCurve.cxx:496
 RooCurve.cxx:497
 RooCurve.cxx:498
 RooCurve.cxx:499
 RooCurve.cxx:500
 RooCurve.cxx:501
 RooCurve.cxx:502
 RooCurve.cxx:503
 RooCurve.cxx:504
 RooCurve.cxx:505
 RooCurve.cxx:506
 RooCurve.cxx:507
 RooCurve.cxx:508
 RooCurve.cxx:509
 RooCurve.cxx:510
 RooCurve.cxx:511
 RooCurve.cxx:512
 RooCurve.cxx:513
 RooCurve.cxx:514
 RooCurve.cxx:515
 RooCurve.cxx:516
 RooCurve.cxx:517
 RooCurve.cxx:518
 RooCurve.cxx:519
 RooCurve.cxx:520
 RooCurve.cxx:521
 RooCurve.cxx:522
 RooCurve.cxx:523
 RooCurve.cxx:524
 RooCurve.cxx:525
 RooCurve.cxx:526
 RooCurve.cxx:527
 RooCurve.cxx:528
 RooCurve.cxx:529
 RooCurve.cxx:530
 RooCurve.cxx:531
 RooCurve.cxx:532
 RooCurve.cxx:533
 RooCurve.cxx:534
 RooCurve.cxx:535
 RooCurve.cxx:536
 RooCurve.cxx:537
 RooCurve.cxx:538
 RooCurve.cxx:539
 RooCurve.cxx:540
 RooCurve.cxx:541
 RooCurve.cxx:542
 RooCurve.cxx:543
 RooCurve.cxx:544
 RooCurve.cxx:545
 RooCurve.cxx:546
 RooCurve.cxx:547
 RooCurve.cxx:548
 RooCurve.cxx:549
 RooCurve.cxx:550
 RooCurve.cxx:551
 RooCurve.cxx:552
 RooCurve.cxx:553
 RooCurve.cxx:554
 RooCurve.cxx:555
 RooCurve.cxx:556
 RooCurve.cxx:557
 RooCurve.cxx:558
 RooCurve.cxx:559
 RooCurve.cxx:560
 RooCurve.cxx:561
 RooCurve.cxx:562
 RooCurve.cxx:563
 RooCurve.cxx:564
 RooCurve.cxx:565
 RooCurve.cxx:566
 RooCurve.cxx:567
 RooCurve.cxx:568
 RooCurve.cxx:569
 RooCurve.cxx:570
 RooCurve.cxx:571
 RooCurve.cxx:572
 RooCurve.cxx:573
 RooCurve.cxx:574
 RooCurve.cxx:575
 RooCurve.cxx:576
 RooCurve.cxx:577
 RooCurve.cxx:578
 RooCurve.cxx:579
 RooCurve.cxx:580
 RooCurve.cxx:581
 RooCurve.cxx:582
 RooCurve.cxx:583
 RooCurve.cxx:584
 RooCurve.cxx:585
 RooCurve.cxx:586
 RooCurve.cxx:587
 RooCurve.cxx:588
 RooCurve.cxx:589
 RooCurve.cxx:590
 RooCurve.cxx:591
 RooCurve.cxx:592
 RooCurve.cxx:593
 RooCurve.cxx:594
 RooCurve.cxx:595
 RooCurve.cxx:596
 RooCurve.cxx:597
 RooCurve.cxx:598
 RooCurve.cxx:599
 RooCurve.cxx:600
 RooCurve.cxx:601
 RooCurve.cxx:602
 RooCurve.cxx:603
 RooCurve.cxx:604
 RooCurve.cxx:605
 RooCurve.cxx:606
 RooCurve.cxx:607
 RooCurve.cxx:608
 RooCurve.cxx:609
 RooCurve.cxx:610
 RooCurve.cxx:611
 RooCurve.cxx:612
 RooCurve.cxx:613
 RooCurve.cxx:614
 RooCurve.cxx:615
 RooCurve.cxx:616
 RooCurve.cxx:617
 RooCurve.cxx:618
 RooCurve.cxx:619
 RooCurve.cxx:620
 RooCurve.cxx:621
 RooCurve.cxx:622
 RooCurve.cxx:623
 RooCurve.cxx:624
 RooCurve.cxx:625
 RooCurve.cxx:626
 RooCurve.cxx:627
 RooCurve.cxx:628
 RooCurve.cxx:629
 RooCurve.cxx:630
 RooCurve.cxx:631
 RooCurve.cxx:632
 RooCurve.cxx:633
 RooCurve.cxx:634
 RooCurve.cxx:635
 RooCurve.cxx:636
 RooCurve.cxx:637
 RooCurve.cxx:638
 RooCurve.cxx:639
 RooCurve.cxx:640
 RooCurve.cxx:641
 RooCurve.cxx:642
 RooCurve.cxx:643
 RooCurve.cxx:644
 RooCurve.cxx:645
 RooCurve.cxx:646
 RooCurve.cxx:647
 RooCurve.cxx:648
 RooCurve.cxx:649
 RooCurve.cxx:650
 RooCurve.cxx:651
 RooCurve.cxx:652
 RooCurve.cxx:653
 RooCurve.cxx:654
 RooCurve.cxx:655
 RooCurve.cxx:656
 RooCurve.cxx:657
 RooCurve.cxx:658
 RooCurve.cxx:659
 RooCurve.cxx:660
 RooCurve.cxx:661
 RooCurve.cxx:662
 RooCurve.cxx:663
 RooCurve.cxx:664
 RooCurve.cxx:665
 RooCurve.cxx:666
 RooCurve.cxx:667
 RooCurve.cxx:668
 RooCurve.cxx:669
 RooCurve.cxx:670
 RooCurve.cxx:671
 RooCurve.cxx:672
 RooCurve.cxx:673
 RooCurve.cxx:674
 RooCurve.cxx:675
 RooCurve.cxx:676
 RooCurve.cxx:677
 RooCurve.cxx:678
 RooCurve.cxx:679
 RooCurve.cxx:680
 RooCurve.cxx:681
 RooCurve.cxx:682
 RooCurve.cxx:683
 RooCurve.cxx:684
 RooCurve.cxx:685
 RooCurve.cxx:686
 RooCurve.cxx:687
 RooCurve.cxx:688
 RooCurve.cxx:689
 RooCurve.cxx:690
 RooCurve.cxx:691
 RooCurve.cxx:692
 RooCurve.cxx:693
 RooCurve.cxx:694
 RooCurve.cxx:695
 RooCurve.cxx:696
 RooCurve.cxx:697
 RooCurve.cxx:698
 RooCurve.cxx:699
 RooCurve.cxx:700
 RooCurve.cxx:701
 RooCurve.cxx:702
 RooCurve.cxx:703
 RooCurve.cxx:704
 RooCurve.cxx:705
 RooCurve.cxx:706
 RooCurve.cxx:707
 RooCurve.cxx:708
 RooCurve.cxx:709
 RooCurve.cxx:710
 RooCurve.cxx:711
 RooCurve.cxx:712
 RooCurve.cxx:713
 RooCurve.cxx:714
 RooCurve.cxx:715
 RooCurve.cxx:716
 RooCurve.cxx:717
 RooCurve.cxx:718
 RooCurve.cxx:719
 RooCurve.cxx:720
 RooCurve.cxx:721
 RooCurve.cxx:722
 RooCurve.cxx:723
 RooCurve.cxx:724
 RooCurve.cxx:725
 RooCurve.cxx:726
 RooCurve.cxx:727
 RooCurve.cxx:728
 RooCurve.cxx:729
 RooCurve.cxx:730
 RooCurve.cxx:731
 RooCurve.cxx:732
 RooCurve.cxx:733
 RooCurve.cxx:734
 RooCurve.cxx:735
 RooCurve.cxx:736
 RooCurve.cxx:737
 RooCurve.cxx:738
 RooCurve.cxx:739
 RooCurve.cxx:740
 RooCurve.cxx:741
 RooCurve.cxx:742
 RooCurve.cxx:743
 RooCurve.cxx:744
 RooCurve.cxx:745
 RooCurve.cxx:746
 RooCurve.cxx:747
 RooCurve.cxx:748
 RooCurve.cxx:749
 RooCurve.cxx:750
 RooCurve.cxx:751
 RooCurve.cxx:752
 RooCurve.cxx:753
 RooCurve.cxx:754
 RooCurve.cxx:755
 RooCurve.cxx:756
 RooCurve.cxx:757
 RooCurve.cxx:758
 RooCurve.cxx:759
 RooCurve.cxx:760
 RooCurve.cxx:761
 RooCurve.cxx:762
 RooCurve.cxx:763
 RooCurve.cxx:764
 RooCurve.cxx:765
 RooCurve.cxx:766
 RooCurve.cxx:767
 RooCurve.cxx:768
 RooCurve.cxx:769
 RooCurve.cxx:770
 RooCurve.cxx:771
 RooCurve.cxx:772
 RooCurve.cxx:773
 RooCurve.cxx:774
 RooCurve.cxx:775
 RooCurve.cxx:776
 RooCurve.cxx:777
 RooCurve.cxx:778
 RooCurve.cxx:779
 RooCurve.cxx:780
 RooCurve.cxx:781
 RooCurve.cxx:782
 RooCurve.cxx:783
 RooCurve.cxx:784
 RooCurve.cxx:785
 RooCurve.cxx:786
 RooCurve.cxx:787
 RooCurve.cxx:788
 RooCurve.cxx:789
 RooCurve.cxx:790
 RooCurve.cxx:791
 RooCurve.cxx:792
 RooCurve.cxx:793
 RooCurve.cxx:794
 RooCurve.cxx:795
 RooCurve.cxx:796
 RooCurve.cxx:797
 RooCurve.cxx:798
 RooCurve.cxx:799
 RooCurve.cxx:800
 RooCurve.cxx:801
 RooCurve.cxx:802
 RooCurve.cxx:803
 RooCurve.cxx:804
 RooCurve.cxx:805
 RooCurve.cxx:806
 RooCurve.cxx:807
 RooCurve.cxx:808
 RooCurve.cxx:809
 RooCurve.cxx:810
 RooCurve.cxx:811
 RooCurve.cxx:812
 RooCurve.cxx:813
 RooCurve.cxx:814
 RooCurve.cxx:815
 RooCurve.cxx:816
 RooCurve.cxx:817
 RooCurve.cxx:818
 RooCurve.cxx:819
 RooCurve.cxx:820
 RooCurve.cxx:821
 RooCurve.cxx:822
 RooCurve.cxx:823
 RooCurve.cxx:824
 RooCurve.cxx:825
 RooCurve.cxx:826
 RooCurve.cxx:827
 RooCurve.cxx:828
 RooCurve.cxx:829
 RooCurve.cxx:830
 RooCurve.cxx:831
 RooCurve.cxx:832
 RooCurve.cxx:833
 RooCurve.cxx:834
 RooCurve.cxx:835
 RooCurve.cxx:836
 RooCurve.cxx:837
 RooCurve.cxx:838
 RooCurve.cxx:839
 RooCurve.cxx:840
 RooCurve.cxx:841
 RooCurve.cxx:842
 RooCurve.cxx:843
 RooCurve.cxx:844
 RooCurve.cxx:845
 RooCurve.cxx:846
 RooCurve.cxx:847
 RooCurve.cxx:848
 RooCurve.cxx:849
 RooCurve.cxx:850
 RooCurve.cxx:851
 RooCurve.cxx:852
 RooCurve.cxx:853
 RooCurve.cxx:854
 RooCurve.cxx:855
 RooCurve.cxx:856
 RooCurve.cxx:857
 RooCurve.cxx:858
 RooCurve.cxx:859
 RooCurve.cxx:860
 RooCurve.cxx:861
 RooCurve.cxx:862
 RooCurve.cxx:863
 RooCurve.cxx:864
 RooCurve.cxx:865
 RooCurve.cxx:866
 RooCurve.cxx:867
 RooCurve.cxx:868
 RooCurve.cxx:869
 RooCurve.cxx:870
 RooCurve.cxx:871
 RooCurve.cxx:872
 RooCurve.cxx:873
 RooCurve.cxx:874
 RooCurve.cxx:875
 RooCurve.cxx:876
 RooCurve.cxx:877
 RooCurve.cxx:878
 RooCurve.cxx:879
 RooCurve.cxx:880
 RooCurve.cxx:881
 RooCurve.cxx:882
 RooCurve.cxx:883