/***************************************************************************** 
  * Project: RooFit                                                           * 
  *                                                                           * 
  * 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)             * 
  *****************************************************************************/ 

//////////////////////////////////////////////////////////////////////////////
//
// Class RooIntegralMorph is an implementation of the histogram interpolation
// technique described by Alex Read in 'NIM A 425 (1999) 357-369 'Linear interpolation of histograms'
// for continuous functions rather than histograms. The interpolation method, in short,
// works as follows. 
//
//   - Given a p.d.f f1(x) with c.d.f F1(x) and p.d.f f2(x) with c.d.f F2(x)
// 
//   - One finds takes a value 'y' of both c.d.fs and determines the corresponding x
//     values x(1,2) at which F(1,2)(x)==y. 
//
//   - The value of the interpolated p.d.f fbar(x) is then calculated as 
//     fbar(alpha*x1+(1-alpha)*x2) = f1(x1)*f2(x2) / ( alpha*f2(x2) + (1-alpha)*f1(x1) ) ;
// 
// From a technical point of view class RooIntegralMorph is a p.d.f that takes
// two input p.d.fs f1(x,p) an f2(x,q) and an interpolation parameter to
// make a p.d.f fbar(x,p,q,alpha). The shapes f1 and f2 are always taken
// to be end the end-points of the parameter alpha, regardless of what
// the those numeric values are. 
//
// Since the value of fbar(x) cannot be easily calculated for a given value
// of x, class RooIntegralMorph is an implementation of RooAbsCachedPdf and
// calculates the shape of the interpolated p.d.f. fbar(x) for all values
// of x for a given value of alpha,p,q and caches these values in a histogram
// (as implemented by RooAbsCachedPdf). The binning granularity of the cache
// can be controlled by the binning named "cache" on the RooRealVar representing
// the observable x. The fbar sampling algorithm is based on a recursive division
// mechanism with a built-in precision cutoff: First an initial sampling in
// 64 equally spaced bins is made. Then the value of fbar is calculated in
// the center of each gap. If the calculated value deviates too much from
// the value obtained by linear interpolation from the edge bins, gap
// is recursively divided. This strategy makes it possible to define a very
// fine cache sampling (e.g. 1000 or 10000) bins without incurring a
// corresponding CPU penalty.
//
// Note on numeric stability of the algorithm. Since the algorithm relies
// on a numeric inversion of cumulative distributions functions, some precision
// may be lost at the 'edges' of the same (i.e. at regions in x where the
// c.d.f. value is close to zero or one). The general sampling strategy is
// to start with 64 equally spaces samples in the range y=(0.01-0.99).
// Then the y ranges are pushed outward by reducing y (or the distance of y to 1.0)
// by a factor of sqrt(10) iteratively up to the point where the corresponding
// x value no longer changes significantly. For p.d.f.s with very flat tails
// such as Gaussians some part of the tail may be lost due to limitations
// in numeric precision in the CDF inversion step. 
//
// An effect related to the above limitation in numeric precision should
// be anticipated when floating the alpha parameter in a fit. If a p.d.f
// with such flat tails is fitted, it is likely that the dataset contains
// events in the flat tail region. If the alpha parameter is varied, the
// likelihood contribution from such events may exhibit discontinuities
// in alpha, causing discontinuities in the summed likelihood as well
// that will cause convergence problems in MINUIT. To mitigate this effect
// one can use the setCacheAlpha() method to instruct RooIntegralMorph
// to construct a two-dimensional cache for its output values in both
// x and alpha. If linear interpolation is requested on the resulting
// output histogram, the resulting interpolation of the p.d.f in the
// alpha dimension will smooth out the discontinities in the tail regions
// result in a continuous likelihood distribution that can be fitted.
// An added advantage of the cacheAlpha option is that if parameters
// p,q of f1,f2 are fixed, the cached values in RooIntegralMorph are
// valid for the entire fit session and do not need to be recalculated
// for each change in alpha, which may result an considerable increase
// in calculation speed.
// 
//

#include "Riostream.h" 

#include "RooIntegralMorph.h" 
#include "RooAbsReal.h" 
#include "RooAbsCategory.h" 
#include "RooBrentRootFinder.h"
#include "RooAbsFunc.h"
#include "RooRealVar.h"
#include "RooDataHist.h"
#include "TH1.h"

using namespace std;

ClassImp(RooIntegralMorph) 


//_____________________________________________________________________________
RooIntegralMorph::RooIntegralMorph(const char *name, const char *title, 
			       RooAbsReal& _pdf1,
			       RooAbsReal& _pdf2,
			       RooAbsReal& _x,
			       RooAbsReal& _alpha,
			       Bool_t doCacheAlpha) :
  RooAbsCachedPdf(name,title,2), 
  pdf1("pdf1","pdf1",this,_pdf1),
  pdf2("pdf2","pdf2",this,_pdf2),
  x("x","x",this,_x),
  alpha("alpha","alpha",this,_alpha),
  _cacheAlpha(doCacheAlpha),
  _cache(0)
{ 
  // Constructor with observables x, pdf shapes pdf1 and pdf2 which represent
  // the shapes at the end points of the interpolation parameter alpha
  // If doCacheAlpha is true, a two-dimensional cache is constructed in
  // both alpha and x
} 



//_____________________________________________________________________________
RooIntegralMorph::RooIntegralMorph(const RooIntegralMorph& other, const char* name) :  
  RooAbsCachedPdf(other,name), 
  pdf1("pdf1",this,other.pdf1),
  pdf2("pdf2",this,other.pdf2),
  x("x",this,other.x),
  alpha("alpha",this,other.alpha),
  _cacheAlpha(other._cacheAlpha),
  _cache(0)
{ 
  // Copy constructor
} 



//_____________________________________________________________________________
RooArgSet* RooIntegralMorph::actualObservables(const RooArgSet& /*nset*/) const 
{
  // Observable to be cached for given choice of normalization.
  // Returns the 'x' observable unless doCacheAlpha is set in which
  // case a set with both x and alpha

  RooArgSet* obs = new RooArgSet ;
  if (_cacheAlpha) {
    obs->add(alpha.arg()) ;
  }
  obs->add(x.arg()) ;
  return obs ;
}



//_____________________________________________________________________________
RooArgSet* RooIntegralMorph::actualParameters(const RooArgSet& /*nset*/) const 
{  
  // Parameters of the cache. Returns parameters of both pdf1 and pdf2
  // and parameter cache, in case doCacheAlpha is not set.

  RooArgSet* par1 = pdf1.arg().getParameters(RooArgSet()) ;
  RooArgSet* par2 = pdf2.arg().getParameters(RooArgSet()) ;
  par1->add(*par2,kTRUE) ;
  par1->remove(x.arg(),kTRUE,kTRUE) ;
  if (!_cacheAlpha) {
    par1->add(alpha.arg()) ;
  }
  delete par2 ;
  return par1 ;
}



//_____________________________________________________________________________
const char* RooIntegralMorph::inputBaseName() const 
{
  // Return base name component for cache components in this case
  // a string encoding the names of both end point p.d.f.s

  static TString name ;

  name = pdf1.arg().GetName() ;
  name.Append("_MORPH_") ;
  name.Append(pdf2.arg().GetName()) ;
  return name.Data() ;
}

  

//_____________________________________________________________________________
void RooIntegralMorph::fillCacheObject(PdfCacheElem& cache) const 
{
  // Fill the cache with the interpolated shape. 

  MorphCacheElem& mcache = static_cast<MorphCacheElem&>(cache) ;
  
  // If cacheAlpha is true employ slice iterator here to fill all slices

  if (!_cacheAlpha) {

    TIterator* dIter = cache.hist()->sliceIterator((RooAbsArg&)x.arg(),RooArgSet()) ;
    mcache.calculate(dIter) ; 
    delete dIter ;

  } else {
    TIterator* slIter = cache.hist()->sliceIterator((RooAbsArg&)alpha.arg(),RooArgSet()) ;

    Double_t alphaSave = alpha ;
    RooArgSet alphaSet(alpha.arg()) ;
    coutP(Eval) << "RooIntegralMorph::fillCacheObject(" << GetName() << ") filling multi-dimensional cache" ;
    while(slIter->Next()) {
      alphaSet = (*cache.hist()->get()) ;
      TIterator* dIter = cache.hist()->sliceIterator((RooAbsArg&)x.arg(),RooArgSet(alpha.arg())) ;
      mcache.calculate(dIter) ;     
      ccoutP(Eval) << "." << flush;
      delete dIter ;
    }
    ccoutP(Eval) << endl ;

    delete slIter ;
    const_cast<RooIntegralMorph*>(this)->alpha = alphaSave ;
  }
}



//_____________________________________________________________________________
RooAbsCachedPdf::PdfCacheElem* RooIntegralMorph::createCache(const RooArgSet* nset) const 
{
  // Create and return a derived MorphCacheElem.

  return new MorphCacheElem(const_cast<RooIntegralMorph&>(*this),nset) ;
}



//_____________________________________________________________________________
RooArgList RooIntegralMorph::MorphCacheElem::containedArgs(Action action) 
{
  // Return all RooAbsArg components contained in this cache

  RooArgList ret ;
  ret.add(PdfCacheElem::containedArgs(action)) ;
  ret.add(*_self) ;
  ret.add(*_pdf1) ;
  ret.add(*_pdf2) ;
  ret.add(*_x  ) ; 
  ret.add(*_alpha) ;
  ret.add(*_c1) ; 
  ret.add(*_c2) ; 

  return ret ;
}



//_____________________________________________________________________________
RooIntegralMorph::MorphCacheElem::MorphCacheElem(RooIntegralMorph& self, const RooArgSet* nsetIn) : PdfCacheElem(self,nsetIn)
{
  // Construct of cache element, copy relevant input from RooIntegralMorph,
  // create the cdfs from the input p.d.fs and instantiate the root finders
  // on the cdfs to perform the inversion.

  // Mark in base class that normalization of cached pdf is invariant under pdf parameters
  _x = (RooRealVar*)self.x.absArg() ;
  _nset = new RooArgSet(*_x) ;

  _alpha = (RooAbsReal*)self.alpha.absArg() ;
  _pdf1 = (RooAbsPdf*)(self.pdf1.absArg()) ;
  _pdf2 = (RooAbsPdf*)(self.pdf2.absArg()) ;
  _c1 = _pdf1->createCdf(*_x);
  _c2 = _pdf2->createCdf(*_x) ;  
  _cb1 = _c1->bindVars(*_x,_nset) ;
  _cb2 = _c2->bindVars(*_x,_nset) ;  
  _self = &self ;

  _rf1 = new RooBrentRootFinder(*_cb1) ;
  _rf2 = new RooBrentRootFinder(*_cb2) ;
  _ccounter = 0 ;

  _rf1->setTol(1e-12) ;
  _rf2->setTol(1e-12) ;
  _ycutoff = 1e-7 ;
  
  _yatX = 0 ;
  _calcX = 0 ;

  // Must do this here too: fillCache() may not be called if cache contents is retrieved from EOcache
  pdf()->setUnitNorm(kTRUE) ;

  _yatXmax = 0 ;
  _yatXmin = 0 ;
}


//_____________________________________________________________________________
RooIntegralMorph::MorphCacheElem::~MorphCacheElem() 
{
  // Destructor

  delete _rf1 ;
  delete _rf2 ;
  delete[] _yatX ;
  delete[] _calcX ;
}



//_____________________________________________________________________________
Double_t RooIntegralMorph::MorphCacheElem::calcX(Double_t y, Bool_t& ok)
{
  // Calculate the x value of the output p.d.f at the given cdf value y.
  // The ok boolean is filled with the success status of the operation.

  if (y<0 || y>1) {
    oocoutW(_self,Eval) << "RooIntegralMorph::MorphCacheElem::calcX() WARNING: requested root finding for unphysical CDF value " << y << endl ; 
  }
  Double_t x1,x2 ;    

  Double_t xmax = _x->getMax("cache") ;
  Double_t xmin = _x->getMin("cache") ;

  ok=kTRUE ;
  ok &= _rf1->findRoot(x1,xmin,xmax,y) ;
  ok &= _rf2->findRoot(x2,xmin,xmax,y) ;
  if (!ok) return 0 ;
  _ccounter++ ;

  return _alpha->getVal()*x1 + (1-_alpha->getVal())*x2 ;  
}


//_____________________________________________________________________________
Int_t RooIntegralMorph::MorphCacheElem::binX(Double_t X) 
{
  // Return the bin number enclosing the given x value

  Double_t xmax = _x->getMax("cache") ;
  Double_t xmin = _x->getMin("cache") ;
  return (Int_t)(_x->numBins("cache")*(X-xmin)/(xmax-xmin)) ;
}



//_____________________________________________________________________________
void RooIntegralMorph::MorphCacheElem::calculate(TIterator* dIter)
{
  // Calculate shape of p.d.f for x,alpha values 
  // defined by dIter iterator over cache histogram

  Double_t xsave = _self->x ;

  if (!_yatX) {
    _yatX = new Double_t[_x->numBins("cache")+1] ;
    _calcX = new Double_t[_x->numBins("cache")+1] ;
  }

  RooArgSet nsetTmp(*_x) ;
  _ccounter = 0 ;
  
  // Get number of bins from PdfCacheElem histogram
  Int_t nbins = _x->numBins("cache") ;

  // Initialize yatX array to 'uncalculated values (-1)'
  for (int i=0 ; i<nbins ; i++) {
    _yatX[i] = -1 ;
    _calcX[i] = 0 ;
  }

  // Find low and high point
  findRange() ;

  // Perform initial scan of 100 points
  for (int i=0 ; i<10 ; i++) {    

    // Take a point in y
    Double_t offset = _yatX[_yatXmin] ;
    Double_t delta = (_yatX[_yatXmax] - _yatX[_yatXmin])/10 ;
    Double_t y = offset + i*delta ;

    // Calculate corresponding X
    Bool_t ok ;
    Double_t X = calcX(y,ok) ;
    if (ok) {
      Int_t iX = binX(X) ;
      _yatX[iX] = y ;           
      _calcX[iX] =  X ;
    }
  }

  // Now take an iteration filling the 'gaps'
  Int_t igapLow = _yatXmin+1 ;
  while(true) {
    // Find next gap
    Int_t igapHigh = igapLow+1 ;
    while(_yatX[igapHigh]<0 && igapHigh<(_yatXmax)) igapHigh++ ;

    // Fill the gap (iteratively and/or using interpolation)
    fillGap(igapLow-1,igapHigh) ;
    
    // Terminate after processing of last gap
    if (igapHigh>=_yatXmax-1) break ;
    igapLow = igapHigh+1 ;
  }

  // Make one more iteration to recalculate Y value at bin centers  
  Double_t xmax = _x->getMax("cache") ;
  Double_t xmin = _x->getMin("cache") ;
  Double_t binw = (xmax-xmin)/_x->numBins("cache") ;
  for (int i=_yatXmin+1 ; i<_yatXmax-1 ; i++) {

    // Calculate additional offset to apply if bin ixlo does not have X value calculated at bin center
    Double_t xBinC = xmin + (i+0.5)*binw ;
    Double_t xOffset = xBinC-_calcX[i] ;
    if (fabs(xOffset/binw)>1e-3) {
      Double_t slope = (_yatX[i+1]-_yatX[i-1])/(_calcX[i+1]-_calcX[i-1]) ;
      Double_t newY = _yatX[i] + slope*xOffset ;
      //cout << "bin " << i << " needs to be recentered " << xOffset/binw << " slope = " << slope << " origY = " << _yatX[i] << " newY = " << newY << endl ;      
      _yatX[i] = newY ;
    } 
  }

  // Zero output histogram below lowest calculable X value
  for (int i=0; i<_yatXmin ; i++) {
    dIter->Next() ;
    //_hist->get(i) ; 
    hist()->set(0) ;
  }
  // Transfer calculated values to histogram
  for (int i=_yatXmin ; i<_yatXmax ; i++) {
    
    Double_t y = _yatX[i] ;
    
    Double_t x1,x2 ;    

    Double_t xMin = _x->getMin("cache") ;
    Double_t xMax = _x->getMax("cache") ;
    _rf1->findRoot(x1,xMin,xMax,y) ;
    _rf2->findRoot(x2,xMin,xMax,y) ;
    
    _x->setVal(x1) ; Double_t f1x1 = _pdf1->getVal(&nsetTmp) ;
    _x->setVal(x2) ; Double_t f2x2 = _pdf2->getVal(&nsetTmp) ;
    Double_t fbarX = f1x1*f2x2 / ( _alpha->getVal()*f2x2 + (1-_alpha->getVal())*f1x1 ) ;

    dIter->Next() ;
    //_hist->get(i) ; 
    hist()->set(fbarX) ;
  }
  // Zero output histogram above highest calculable X value
  for (int i=_yatXmax+1 ; i<nbins ; i++) {
    dIter->Next() ;
    //_hist->get(i) ; 
    hist()->set(0) ;
  }

  pdf()->setUnitNorm(kTRUE) ;
  _self->x = xsave ;

  oocxcoutD(_self,Eval) << "RooIntegralMorph::MorphCacheElem::calculate(" << _self->GetName() << ") calculation required " << _ccounter << " samplings of cdfs" << endl ;
}


//_____________________________________________________________________________
void RooIntegralMorph::MorphCacheElem::fillGap(Int_t ixlo, Int_t ixhi, Double_t splitPoint) 
{
  // Fill all empty histogram bins between bins ixlo and ixhi. The value of 'splitPoint'
  // defines the split point for the recursive division strategy to fill the gaps
  // If the midpoint value of y is very close to the midpoint in x, use interpolation
  // to fill the gaps, otherwise the intervals again.

  // CONVENTION: _yatX[ixlo] is filled, _yatX[ixhi] is filled, elements in between are empty
  //   cout << "fillGap: gap from _yatX[" << ixlo << "]=" << _yatX[ixlo] << " to _yatX[" << ixhi << "]=" << _yatX[ixhi] << ", size = " << ixhi-ixlo << endl ;
  
  if (_yatX[ixlo]<0) {
    oocoutE(_self,Eval) << "RooIntegralMorph::MorphCacheElme::fillGap(" << _self->GetName() << "): ERROR in fillgap " << ixlo << " = " << ixhi 
			<< " splitPoint= " << splitPoint << " _yatX[ixlo] = " << _yatX[ixlo] << endl ;
  }
  if (_yatX[ixhi]<0) {
    oocoutE(_self,Eval) << "RooIntegralMorph::MorphCacheElme::fillGap(" << _self->GetName() << "): ERROR in fillgap " << ixlo << " = " << ixhi 
			<< " splitPoint " << splitPoint << " _yatX[ixhi] = " << _yatX[ixhi] << endl ;
  }

  // Determine where half-way Y value lands
  Double_t ymid = _yatX[ixlo]*splitPoint + _yatX[ixhi]*(1-splitPoint) ;
  Bool_t ok ;
  Double_t Xmid = calcX(ymid,ok) ;
  if (!ok) {
    oocoutW(_self,Eval) << "RooIntegralMorph::MorphCacheElem::fillGap(" << _self->GetName() << ") unable to calculate midpoint in gap [" 
			<< ixlo << "," << ixhi << "], resorting to interpolation" << endl ;
    interpolateGap(ixlo,ixhi) ;
  }

  Int_t iX = binX(Xmid) ;  
  Double_t cq = (Xmid-_calcX[ixlo])/(_calcX[ixhi]-_calcX[ixlo])-0.5 ;

  // Store midway point
  _yatX[iX] = ymid ;
  _calcX[iX] = Xmid ;


  // Policy: If centration quality is better than 1% OR better than 1/10 of a bin, fill interval with linear interpolation
  if (fabs(cq)<0.01 || fabs(cq*(ixhi-ixlo))<0.1 || ymid<_ycutoff ) {
        
    // Fill remaining gaps on either side with linear interpolation
    if (iX-ixlo>1) {      
      interpolateGap(ixlo,iX) ;
    }
    if (ixhi-iX>1) {
      interpolateGap(iX,ixhi) ;
    }
        
  } else {

    if (iX==ixlo) {

      if (splitPoint<0.95) {
	// Midway value lands on lowest bin, retry split with higher split point
	Double_t newSplit = splitPoint + 0.5*(1-splitPoint) ;
	fillGap(ixlo,ixhi,newSplit) ;
      } else {
	// Give up and resort to interpolation
	interpolateGap(ixlo,ixhi) ;
      }

    } else if (iX==ixhi) {

      // Midway value lands on highest bin, retry split with lower split point      
      if (splitPoint>0.05) {
	Double_t newSplit = splitPoint/2 ;
	fillGap(ixlo,ixhi,newSplit) ;
      } else {
	// Give up and resort to interpolation
	interpolateGap(ixlo,ixhi) ;
      }

    } else {

      // Midway point reasonable, iterate on interval on both sides
      if (iX-ixlo>1) {
	fillGap(ixlo,iX) ;
      }
      if (ixhi-iX>1) {
	fillGap(iX,ixhi) ;
      }    
    }
  }  
}


//_____________________________________________________________________________
void RooIntegralMorph::MorphCacheElem::interpolateGap(Int_t ixlo, Int_t ixhi)
{
  // Fill empty histogram bins between ixlo and ixhi with values obtained
  // from linear interpolation of ixlo,ixhi elements. 

  //cout << "filling gap with linear interpolation ixlo=" << ixlo << " ixhi=" << ixhi << endl ;

  Double_t xmax = _x->getMax("cache") ;
  Double_t xmin = _x->getMin("cache") ;
  Double_t binw = (xmax-xmin)/_x->numBins("cache") ;

  // Calculate deltaY in terms of actuall X difference calculate, not based on nominal bin width
  Double_t deltaY = (_yatX[ixhi]-_yatX[ixlo])/((_calcX[ixhi]-_calcX[ixlo])/binw) ;

  // Calculate additional offset to apply if bin ixlo does not have X value calculated at bin center
  Double_t xBinC = xmin + (ixlo+0.5)*binw ;
  Double_t xOffset = xBinC-_calcX[ixlo] ;
  
  for (int j=ixlo+1 ; j<ixhi ; j++) {
    _yatX[j] = _yatX[ixlo]+(xOffset+(j-ixlo))*deltaY ;
    _calcX[j] = xmin + (j+0.5)*binw ;
  } 

}



//_____________________________________________________________________________
void RooIntegralMorph::MorphCacheElem::findRange()
{
  // Determine which range of y values can be mapped to x values
  // from the numeric inversion of the input c.d.fs.
  // Start with a y rannge of [0.1-0.9] and push boundaries
  // outward with a factor of 1/sqrt(10). Stop iteration if
  // inverted x values no longer change
  
  Double_t xmin = _x->getMin("cache") ;
  Double_t xmax = _x->getMax("cache") ;
  Int_t nbins = _x->numBins("cache") ;

  Double_t x1,x2 ;      
  Bool_t ok = kTRUE ;
  Double_t ymin=0.1,yminSave(-1) ;
  Double_t Xsave(-1),Xlast=xmax ;

  // Find lowest Y value that can be measured
  // Start at 0.1 and iteratively lower limit by sqrt(10)
  while(true) {
    ok &= _rf1->findRoot(x1,xmin,xmax,ymin) ;
    ok &= _rf2->findRoot(x2,xmin,xmax,ymin) ;
    oocxcoutD(_self,Eval) << "RooIntegralMorph::MorphCacheElem::findRange(" << _self->GetName() << ") findMin: x1 = " << x1 << " x2 = " << x2 << " ok = " << (ok?"T":"F") << endl ;

    // Terminate in case of non-convergence
    if (!ok) break ;

    // Terminate if value of X no longer moves by >0.1 bin size
    Double_t X = _alpha->getVal()*x1 + (1-_alpha->getVal())*x2 ;
    if (fabs(X-Xlast)/(xmax-xmin)<0.0001) {
      break ;
    } 
    Xlast=X ;

    // Store new Y value
    _yatXmin = (Int_t)(nbins*(X-xmin)/(xmax-xmin)) ;
    _yatX[_yatXmin] = ymin ;
    _calcX[_yatXmin] = X ;
    yminSave = ymin ;
    Xsave=X ;

    // Reduce ymin by half an order of magnitude
    ymin /=sqrt(10.) ;

    // Emergency break
    if (ymin<_ycutoff) break ;
  }
  _yatX[_yatXmin] = yminSave ;
  _calcX[_yatXmin] = Xsave ;

  // Find highst Y value that can be measured
  // Start at 1 - 0.1 and iteratively lower delta by sqrt(10)
  ok = kTRUE ;
  Double_t deltaymax=0.1, deltaymaxSave(-1) ;
  Xlast=xmin ;
  while(true) {
    ok &= _rf1->findRoot(x1,xmin,xmax,1-deltaymax) ;
    ok &= _rf2->findRoot(x2,xmin,xmax,1-deltaymax) ;

    oocxcoutD(_self,Eval) << "RooIntegralMorph::MorphCacheElem::findRange(" << _self->GetName() << ") findMax: x1 = " << x1 << " x2 = " << x2 << " ok = " << (ok?"T":"F") << endl ;

    // Terminate in case of non-convergence
    if (!ok) break ;

    // Terminate if value of X no longer moves by >0.1 bin size
    Double_t X = _alpha->getVal()*x1 + (1-_alpha->getVal())*x2 ;
    if (fabs(X-Xlast)/(xmax-xmin)<0.0001) {
      break ;
    } 
    Xlast=X ;

    // Store new Y value
    _yatXmax = (Int_t)(nbins*(X-xmin)/(xmax-xmin)) ;    
    _yatX[_yatXmax] = 1-deltaymax ;
    _calcX[_yatXmax] = X ;
    deltaymaxSave = deltaymax ;
    Xsave=X ;

    // Reduce ymin by half an order of magnitude
    deltaymax /=sqrt(10.) ;

    // Emergency break
    if (deltaymax<_ycutoff) break ;
  }

  _yatX[_yatXmax] = 1-deltaymaxSave ;
  _calcX[_yatXmax] = Xsave ;

   
  // Initialize values out of range to 'out-of-range' (-2)
  for (int i=0 ; i<_yatXmin ; i++)  _yatX[i] = -2 ;
  for (int i=_yatXmax+1 ; i<nbins; i++) _yatX[i] = -2 ;
  oocxcoutD(_self,Eval) << "RooIntegralMorph::findRange(" << _self->GetName() << "): ymin = " << _yatX[_yatXmin] << " ymax = " << _yatX[_yatXmax] << endl; 
  oocxcoutD(_self,Eval) << "RooIntegralMorph::findRange(" << _self->GetName() << "): xmin = " << _calcX[_yatXmin] << " xmax = " << _calcX[_yatXmax] << endl; 
}



//_____________________________________________________________________________
Double_t RooIntegralMorph::evaluate() const 
{ 
  // Dummy
  return 0 ;
} 



//_____________________________________________________________________________
void RooIntegralMorph::preferredObservableScanOrder(const RooArgSet& obs, RooArgSet& orderedObs) const
{
  // Indicate to the RooAbsCachedPdf base class that for the filling of the
  // cache the traversal of the x should be in the innermost loop, to minimize
  // recalculation of the one-dimensional internal cache for a fixed value of alpha

  // Put x last to minimize cache faulting
  orderedObs.removeAll() ;

  orderedObs.add(obs) ;
  RooAbsArg* obsX = obs.find(x.arg().GetName()) ;
  if (obsX) {
    orderedObs.remove(*obsX) ;
    orderedObs.add(*obsX) ;
  }  
}



 RooIntegralMorph.cxx:1
 RooIntegralMorph.cxx:2
 RooIntegralMorph.cxx:3
 RooIntegralMorph.cxx:4
 RooIntegralMorph.cxx:5
 RooIntegralMorph.cxx:6
 RooIntegralMorph.cxx:7
 RooIntegralMorph.cxx:8
 RooIntegralMorph.cxx:9
 RooIntegralMorph.cxx:10
 RooIntegralMorph.cxx:11
 RooIntegralMorph.cxx:12
 RooIntegralMorph.cxx:13
 RooIntegralMorph.cxx:14
 RooIntegralMorph.cxx:15
 RooIntegralMorph.cxx:16
 RooIntegralMorph.cxx:17
 RooIntegralMorph.cxx:18
 RooIntegralMorph.cxx:19
 RooIntegralMorph.cxx:20
 RooIntegralMorph.cxx:21
 RooIntegralMorph.cxx:22
 RooIntegralMorph.cxx:23
 RooIntegralMorph.cxx:24
 RooIntegralMorph.cxx:25
 RooIntegralMorph.cxx:26
 RooIntegralMorph.cxx:27
 RooIntegralMorph.cxx:28
 RooIntegralMorph.cxx:29
 RooIntegralMorph.cxx:30
 RooIntegralMorph.cxx:31
 RooIntegralMorph.cxx:32
 RooIntegralMorph.cxx:33
 RooIntegralMorph.cxx:34
 RooIntegralMorph.cxx:35
 RooIntegralMorph.cxx:36
 RooIntegralMorph.cxx:37
 RooIntegralMorph.cxx:38
 RooIntegralMorph.cxx:39
 RooIntegralMorph.cxx:40
 RooIntegralMorph.cxx:41
 RooIntegralMorph.cxx:42
 RooIntegralMorph.cxx:43
 RooIntegralMorph.cxx:44
 RooIntegralMorph.cxx:45
 RooIntegralMorph.cxx:46
 RooIntegralMorph.cxx:47
 RooIntegralMorph.cxx:48
 RooIntegralMorph.cxx:49
 RooIntegralMorph.cxx:50
 RooIntegralMorph.cxx:51
 RooIntegralMorph.cxx:52
 RooIntegralMorph.cxx:53
 RooIntegralMorph.cxx:54
 RooIntegralMorph.cxx:55
 RooIntegralMorph.cxx:56
 RooIntegralMorph.cxx:57
 RooIntegralMorph.cxx:58
 RooIntegralMorph.cxx:59
 RooIntegralMorph.cxx:60
 RooIntegralMorph.cxx:61
 RooIntegralMorph.cxx:62
 RooIntegralMorph.cxx:63
 RooIntegralMorph.cxx:64
 RooIntegralMorph.cxx:65
 RooIntegralMorph.cxx:66
 RooIntegralMorph.cxx:67
 RooIntegralMorph.cxx:68
 RooIntegralMorph.cxx:69
 RooIntegralMorph.cxx:70
 RooIntegralMorph.cxx:71
 RooIntegralMorph.cxx:72
 RooIntegralMorph.cxx:73
 RooIntegralMorph.cxx:74
 RooIntegralMorph.cxx:75
 RooIntegralMorph.cxx:76
 RooIntegralMorph.cxx:77
 RooIntegralMorph.cxx:78
 RooIntegralMorph.cxx:79
 RooIntegralMorph.cxx:80
 RooIntegralMorph.cxx:81
 RooIntegralMorph.cxx:82
 RooIntegralMorph.cxx:83
 RooIntegralMorph.cxx:84
 RooIntegralMorph.cxx:85
 RooIntegralMorph.cxx:86
 RooIntegralMorph.cxx:87
 RooIntegralMorph.cxx:88
 RooIntegralMorph.cxx:89
 RooIntegralMorph.cxx:90
 RooIntegralMorph.cxx:91
 RooIntegralMorph.cxx:92
 RooIntegralMorph.cxx:93
 RooIntegralMorph.cxx:94
 RooIntegralMorph.cxx:95
 RooIntegralMorph.cxx:96
 RooIntegralMorph.cxx:97
 RooIntegralMorph.cxx:98
 RooIntegralMorph.cxx:99
 RooIntegralMorph.cxx:100
 RooIntegralMorph.cxx:101
 RooIntegralMorph.cxx:102
 RooIntegralMorph.cxx:103
 RooIntegralMorph.cxx:104
 RooIntegralMorph.cxx:105
 RooIntegralMorph.cxx:106
 RooIntegralMorph.cxx:107
 RooIntegralMorph.cxx:108
 RooIntegralMorph.cxx:109
 RooIntegralMorph.cxx:110
 RooIntegralMorph.cxx:111
 RooIntegralMorph.cxx:112
 RooIntegralMorph.cxx:113
 RooIntegralMorph.cxx:114
 RooIntegralMorph.cxx:115
 RooIntegralMorph.cxx:116
 RooIntegralMorph.cxx:117
 RooIntegralMorph.cxx:118
 RooIntegralMorph.cxx:119
 RooIntegralMorph.cxx:120
 RooIntegralMorph.cxx:121
 RooIntegralMorph.cxx:122
 RooIntegralMorph.cxx:123
 RooIntegralMorph.cxx:124
 RooIntegralMorph.cxx:125
 RooIntegralMorph.cxx:126
 RooIntegralMorph.cxx:127
 RooIntegralMorph.cxx:128
 RooIntegralMorph.cxx:129
 RooIntegralMorph.cxx:130
 RooIntegralMorph.cxx:131
 RooIntegralMorph.cxx:132
 RooIntegralMorph.cxx:133
 RooIntegralMorph.cxx:134
 RooIntegralMorph.cxx:135
 RooIntegralMorph.cxx:136
 RooIntegralMorph.cxx:137
 RooIntegralMorph.cxx:138
 RooIntegralMorph.cxx:139
 RooIntegralMorph.cxx:140
 RooIntegralMorph.cxx:141
 RooIntegralMorph.cxx:142
 RooIntegralMorph.cxx:143
 RooIntegralMorph.cxx:144
 RooIntegralMorph.cxx:145
 RooIntegralMorph.cxx:146
 RooIntegralMorph.cxx:147
 RooIntegralMorph.cxx:148
 RooIntegralMorph.cxx:149
 RooIntegralMorph.cxx:150
 RooIntegralMorph.cxx:151
 RooIntegralMorph.cxx:152
 RooIntegralMorph.cxx:153
 RooIntegralMorph.cxx:154
 RooIntegralMorph.cxx:155
 RooIntegralMorph.cxx:156
 RooIntegralMorph.cxx:157
 RooIntegralMorph.cxx:158
 RooIntegralMorph.cxx:159
 RooIntegralMorph.cxx:160
 RooIntegralMorph.cxx:161
 RooIntegralMorph.cxx:162
 RooIntegralMorph.cxx:163
 RooIntegralMorph.cxx:164
 RooIntegralMorph.cxx:165
 RooIntegralMorph.cxx:166
 RooIntegralMorph.cxx:167
 RooIntegralMorph.cxx:168
 RooIntegralMorph.cxx:169
 RooIntegralMorph.cxx:170
 RooIntegralMorph.cxx:171
 RooIntegralMorph.cxx:172
 RooIntegralMorph.cxx:173
 RooIntegralMorph.cxx:174
 RooIntegralMorph.cxx:175
 RooIntegralMorph.cxx:176
 RooIntegralMorph.cxx:177
 RooIntegralMorph.cxx:178
 RooIntegralMorph.cxx:179
 RooIntegralMorph.cxx:180
 RooIntegralMorph.cxx:181
 RooIntegralMorph.cxx:182
 RooIntegralMorph.cxx:183
 RooIntegralMorph.cxx:184
 RooIntegralMorph.cxx:185
 RooIntegralMorph.cxx:186
 RooIntegralMorph.cxx:187
 RooIntegralMorph.cxx:188
 RooIntegralMorph.cxx:189
 RooIntegralMorph.cxx:190
 RooIntegralMorph.cxx:191
 RooIntegralMorph.cxx:192
 RooIntegralMorph.cxx:193
 RooIntegralMorph.cxx:194
 RooIntegralMorph.cxx:195
 RooIntegralMorph.cxx:196
 RooIntegralMorph.cxx:197
 RooIntegralMorph.cxx:198
 RooIntegralMorph.cxx:199
 RooIntegralMorph.cxx:200
 RooIntegralMorph.cxx:201
 RooIntegralMorph.cxx:202
 RooIntegralMorph.cxx:203
 RooIntegralMorph.cxx:204
 RooIntegralMorph.cxx:205
 RooIntegralMorph.cxx:206
 RooIntegralMorph.cxx:207
 RooIntegralMorph.cxx:208
 RooIntegralMorph.cxx:209
 RooIntegralMorph.cxx:210
 RooIntegralMorph.cxx:211
 RooIntegralMorph.cxx:212
 RooIntegralMorph.cxx:213
 RooIntegralMorph.cxx:214
 RooIntegralMorph.cxx:215
 RooIntegralMorph.cxx:216
 RooIntegralMorph.cxx:217
 RooIntegralMorph.cxx:218
 RooIntegralMorph.cxx:219
 RooIntegralMorph.cxx:220
 RooIntegralMorph.cxx:221
 RooIntegralMorph.cxx:222
 RooIntegralMorph.cxx:223
 RooIntegralMorph.cxx:224
 RooIntegralMorph.cxx:225
 RooIntegralMorph.cxx:226
 RooIntegralMorph.cxx:227
 RooIntegralMorph.cxx:228
 RooIntegralMorph.cxx:229
 RooIntegralMorph.cxx:230
 RooIntegralMorph.cxx:231
 RooIntegralMorph.cxx:232
 RooIntegralMorph.cxx:233
 RooIntegralMorph.cxx:234
 RooIntegralMorph.cxx:235
 RooIntegralMorph.cxx:236
 RooIntegralMorph.cxx:237
 RooIntegralMorph.cxx:238
 RooIntegralMorph.cxx:239
 RooIntegralMorph.cxx:240
 RooIntegralMorph.cxx:241
 RooIntegralMorph.cxx:242
 RooIntegralMorph.cxx:243
 RooIntegralMorph.cxx:244
 RooIntegralMorph.cxx:245
 RooIntegralMorph.cxx:246
 RooIntegralMorph.cxx:247
 RooIntegralMorph.cxx:248
 RooIntegralMorph.cxx:249
 RooIntegralMorph.cxx:250
 RooIntegralMorph.cxx:251
 RooIntegralMorph.cxx:252
 RooIntegralMorph.cxx:253
 RooIntegralMorph.cxx:254
 RooIntegralMorph.cxx:255
 RooIntegralMorph.cxx:256
 RooIntegralMorph.cxx:257
 RooIntegralMorph.cxx:258
 RooIntegralMorph.cxx:259
 RooIntegralMorph.cxx:260
 RooIntegralMorph.cxx:261
 RooIntegralMorph.cxx:262
 RooIntegralMorph.cxx:263
 RooIntegralMorph.cxx:264
 RooIntegralMorph.cxx:265
 RooIntegralMorph.cxx:266
 RooIntegralMorph.cxx:267
 RooIntegralMorph.cxx:268
 RooIntegralMorph.cxx:269
 RooIntegralMorph.cxx:270
 RooIntegralMorph.cxx:271
 RooIntegralMorph.cxx:272
 RooIntegralMorph.cxx:273
 RooIntegralMorph.cxx:274
 RooIntegralMorph.cxx:275
 RooIntegralMorph.cxx:276
 RooIntegralMorph.cxx:277
 RooIntegralMorph.cxx:278
 RooIntegralMorph.cxx:279
 RooIntegralMorph.cxx:280
 RooIntegralMorph.cxx:281
 RooIntegralMorph.cxx:282
 RooIntegralMorph.cxx:283
 RooIntegralMorph.cxx:284
 RooIntegralMorph.cxx:285
 RooIntegralMorph.cxx:286
 RooIntegralMorph.cxx:287
 RooIntegralMorph.cxx:288
 RooIntegralMorph.cxx:289
 RooIntegralMorph.cxx:290
 RooIntegralMorph.cxx:291
 RooIntegralMorph.cxx:292
 RooIntegralMorph.cxx:293
 RooIntegralMorph.cxx:294
 RooIntegralMorph.cxx:295
 RooIntegralMorph.cxx:296
 RooIntegralMorph.cxx:297
 RooIntegralMorph.cxx:298
 RooIntegralMorph.cxx:299
 RooIntegralMorph.cxx:300
 RooIntegralMorph.cxx:301
 RooIntegralMorph.cxx:302
 RooIntegralMorph.cxx:303
 RooIntegralMorph.cxx:304
 RooIntegralMorph.cxx:305
 RooIntegralMorph.cxx:306
 RooIntegralMorph.cxx:307
 RooIntegralMorph.cxx:308
 RooIntegralMorph.cxx:309
 RooIntegralMorph.cxx:310
 RooIntegralMorph.cxx:311
 RooIntegralMorph.cxx:312
 RooIntegralMorph.cxx:313
 RooIntegralMorph.cxx:314
 RooIntegralMorph.cxx:315
 RooIntegralMorph.cxx:316
 RooIntegralMorph.cxx:317
 RooIntegralMorph.cxx:318
 RooIntegralMorph.cxx:319
 RooIntegralMorph.cxx:320
 RooIntegralMorph.cxx:321
 RooIntegralMorph.cxx:322
 RooIntegralMorph.cxx:323
 RooIntegralMorph.cxx:324
 RooIntegralMorph.cxx:325
 RooIntegralMorph.cxx:326
 RooIntegralMorph.cxx:327
 RooIntegralMorph.cxx:328
 RooIntegralMorph.cxx:329
 RooIntegralMorph.cxx:330
 RooIntegralMorph.cxx:331
 RooIntegralMorph.cxx:332
 RooIntegralMorph.cxx:333
 RooIntegralMorph.cxx:334
 RooIntegralMorph.cxx:335
 RooIntegralMorph.cxx:336
 RooIntegralMorph.cxx:337
 RooIntegralMorph.cxx:338
 RooIntegralMorph.cxx:339
 RooIntegralMorph.cxx:340
 RooIntegralMorph.cxx:341
 RooIntegralMorph.cxx:342
 RooIntegralMorph.cxx:343
 RooIntegralMorph.cxx:344
 RooIntegralMorph.cxx:345
 RooIntegralMorph.cxx:346
 RooIntegralMorph.cxx:347
 RooIntegralMorph.cxx:348
 RooIntegralMorph.cxx:349
 RooIntegralMorph.cxx:350
 RooIntegralMorph.cxx:351
 RooIntegralMorph.cxx:352
 RooIntegralMorph.cxx:353
 RooIntegralMorph.cxx:354
 RooIntegralMorph.cxx:355
 RooIntegralMorph.cxx:356
 RooIntegralMorph.cxx:357
 RooIntegralMorph.cxx:358
 RooIntegralMorph.cxx:359
 RooIntegralMorph.cxx:360
 RooIntegralMorph.cxx:361
 RooIntegralMorph.cxx:362
 RooIntegralMorph.cxx:363
 RooIntegralMorph.cxx:364
 RooIntegralMorph.cxx:365
 RooIntegralMorph.cxx:366
 RooIntegralMorph.cxx:367
 RooIntegralMorph.cxx:368
 RooIntegralMorph.cxx:369
 RooIntegralMorph.cxx:370
 RooIntegralMorph.cxx:371
 RooIntegralMorph.cxx:372
 RooIntegralMorph.cxx:373
 RooIntegralMorph.cxx:374
 RooIntegralMorph.cxx:375
 RooIntegralMorph.cxx:376
 RooIntegralMorph.cxx:377
 RooIntegralMorph.cxx:378
 RooIntegralMorph.cxx:379
 RooIntegralMorph.cxx:380
 RooIntegralMorph.cxx:381
 RooIntegralMorph.cxx:382
 RooIntegralMorph.cxx:383
 RooIntegralMorph.cxx:384
 RooIntegralMorph.cxx:385
 RooIntegralMorph.cxx:386
 RooIntegralMorph.cxx:387
 RooIntegralMorph.cxx:388
 RooIntegralMorph.cxx:389
 RooIntegralMorph.cxx:390
 RooIntegralMorph.cxx:391
 RooIntegralMorph.cxx:392
 RooIntegralMorph.cxx:393
 RooIntegralMorph.cxx:394
 RooIntegralMorph.cxx:395
 RooIntegralMorph.cxx:396
 RooIntegralMorph.cxx:397
 RooIntegralMorph.cxx:398
 RooIntegralMorph.cxx:399
 RooIntegralMorph.cxx:400
 RooIntegralMorph.cxx:401
 RooIntegralMorph.cxx:402
 RooIntegralMorph.cxx:403
 RooIntegralMorph.cxx:404
 RooIntegralMorph.cxx:405
 RooIntegralMorph.cxx:406
 RooIntegralMorph.cxx:407
 RooIntegralMorph.cxx:408
 RooIntegralMorph.cxx:409
 RooIntegralMorph.cxx:410
 RooIntegralMorph.cxx:411
 RooIntegralMorph.cxx:412
 RooIntegralMorph.cxx:413
 RooIntegralMorph.cxx:414
 RooIntegralMorph.cxx:415
 RooIntegralMorph.cxx:416
 RooIntegralMorph.cxx:417
 RooIntegralMorph.cxx:418
 RooIntegralMorph.cxx:419
 RooIntegralMorph.cxx:420
 RooIntegralMorph.cxx:421
 RooIntegralMorph.cxx:422
 RooIntegralMorph.cxx:423
 RooIntegralMorph.cxx:424
 RooIntegralMorph.cxx:425
 RooIntegralMorph.cxx:426
 RooIntegralMorph.cxx:427
 RooIntegralMorph.cxx:428
 RooIntegralMorph.cxx:429
 RooIntegralMorph.cxx:430
 RooIntegralMorph.cxx:431
 RooIntegralMorph.cxx:432
 RooIntegralMorph.cxx:433
 RooIntegralMorph.cxx:434
 RooIntegralMorph.cxx:435
 RooIntegralMorph.cxx:436
 RooIntegralMorph.cxx:437
 RooIntegralMorph.cxx:438
 RooIntegralMorph.cxx:439
 RooIntegralMorph.cxx:440
 RooIntegralMorph.cxx:441
 RooIntegralMorph.cxx:442
 RooIntegralMorph.cxx:443
 RooIntegralMorph.cxx:444
 RooIntegralMorph.cxx:445
 RooIntegralMorph.cxx:446
 RooIntegralMorph.cxx:447
 RooIntegralMorph.cxx:448
 RooIntegralMorph.cxx:449
 RooIntegralMorph.cxx:450
 RooIntegralMorph.cxx:451
 RooIntegralMorph.cxx:452
 RooIntegralMorph.cxx:453
 RooIntegralMorph.cxx:454
 RooIntegralMorph.cxx:455
 RooIntegralMorph.cxx:456
 RooIntegralMorph.cxx:457
 RooIntegralMorph.cxx:458
 RooIntegralMorph.cxx:459
 RooIntegralMorph.cxx:460
 RooIntegralMorph.cxx:461
 RooIntegralMorph.cxx:462
 RooIntegralMorph.cxx:463
 RooIntegralMorph.cxx:464
 RooIntegralMorph.cxx:465
 RooIntegralMorph.cxx:466
 RooIntegralMorph.cxx:467
 RooIntegralMorph.cxx:468
 RooIntegralMorph.cxx:469
 RooIntegralMorph.cxx:470
 RooIntegralMorph.cxx:471
 RooIntegralMorph.cxx:472
 RooIntegralMorph.cxx:473
 RooIntegralMorph.cxx:474
 RooIntegralMorph.cxx:475
 RooIntegralMorph.cxx:476
 RooIntegralMorph.cxx:477
 RooIntegralMorph.cxx:478
 RooIntegralMorph.cxx:479
 RooIntegralMorph.cxx:480
 RooIntegralMorph.cxx:481
 RooIntegralMorph.cxx:482
 RooIntegralMorph.cxx:483
 RooIntegralMorph.cxx:484
 RooIntegralMorph.cxx:485
 RooIntegralMorph.cxx:486
 RooIntegralMorph.cxx:487
 RooIntegralMorph.cxx:488
 RooIntegralMorph.cxx:489
 RooIntegralMorph.cxx:490
 RooIntegralMorph.cxx:491
 RooIntegralMorph.cxx:492
 RooIntegralMorph.cxx:493
 RooIntegralMorph.cxx:494
 RooIntegralMorph.cxx:495
 RooIntegralMorph.cxx:496
 RooIntegralMorph.cxx:497
 RooIntegralMorph.cxx:498
 RooIntegralMorph.cxx:499
 RooIntegralMorph.cxx:500
 RooIntegralMorph.cxx:501
 RooIntegralMorph.cxx:502
 RooIntegralMorph.cxx:503
 RooIntegralMorph.cxx:504
 RooIntegralMorph.cxx:505
 RooIntegralMorph.cxx:506
 RooIntegralMorph.cxx:507
 RooIntegralMorph.cxx:508
 RooIntegralMorph.cxx:509
 RooIntegralMorph.cxx:510
 RooIntegralMorph.cxx:511
 RooIntegralMorph.cxx:512
 RooIntegralMorph.cxx:513
 RooIntegralMorph.cxx:514
 RooIntegralMorph.cxx:515
 RooIntegralMorph.cxx:516
 RooIntegralMorph.cxx:517
 RooIntegralMorph.cxx:518
 RooIntegralMorph.cxx:519
 RooIntegralMorph.cxx:520
 RooIntegralMorph.cxx:521
 RooIntegralMorph.cxx:522
 RooIntegralMorph.cxx:523
 RooIntegralMorph.cxx:524
 RooIntegralMorph.cxx:525
 RooIntegralMorph.cxx:526
 RooIntegralMorph.cxx:527
 RooIntegralMorph.cxx:528
 RooIntegralMorph.cxx:529
 RooIntegralMorph.cxx:530
 RooIntegralMorph.cxx:531
 RooIntegralMorph.cxx:532
 RooIntegralMorph.cxx:533
 RooIntegralMorph.cxx:534
 RooIntegralMorph.cxx:535
 RooIntegralMorph.cxx:536
 RooIntegralMorph.cxx:537
 RooIntegralMorph.cxx:538
 RooIntegralMorph.cxx:539
 RooIntegralMorph.cxx:540
 RooIntegralMorph.cxx:541
 RooIntegralMorph.cxx:542
 RooIntegralMorph.cxx:543
 RooIntegralMorph.cxx:544
 RooIntegralMorph.cxx:545
 RooIntegralMorph.cxx:546
 RooIntegralMorph.cxx:547
 RooIntegralMorph.cxx:548
 RooIntegralMorph.cxx:549
 RooIntegralMorph.cxx:550
 RooIntegralMorph.cxx:551
 RooIntegralMorph.cxx:552
 RooIntegralMorph.cxx:553
 RooIntegralMorph.cxx:554
 RooIntegralMorph.cxx:555
 RooIntegralMorph.cxx:556
 RooIntegralMorph.cxx:557
 RooIntegralMorph.cxx:558
 RooIntegralMorph.cxx:559
 RooIntegralMorph.cxx:560
 RooIntegralMorph.cxx:561
 RooIntegralMorph.cxx:562
 RooIntegralMorph.cxx:563
 RooIntegralMorph.cxx:564
 RooIntegralMorph.cxx:565
 RooIntegralMorph.cxx:566
 RooIntegralMorph.cxx:567
 RooIntegralMorph.cxx:568
 RooIntegralMorph.cxx:569
 RooIntegralMorph.cxx:570
 RooIntegralMorph.cxx:571
 RooIntegralMorph.cxx:572
 RooIntegralMorph.cxx:573
 RooIntegralMorph.cxx:574
 RooIntegralMorph.cxx:575
 RooIntegralMorph.cxx:576
 RooIntegralMorph.cxx:577
 RooIntegralMorph.cxx:578
 RooIntegralMorph.cxx:579
 RooIntegralMorph.cxx:580
 RooIntegralMorph.cxx:581
 RooIntegralMorph.cxx:582
 RooIntegralMorph.cxx:583
 RooIntegralMorph.cxx:584
 RooIntegralMorph.cxx:585
 RooIntegralMorph.cxx:586
 RooIntegralMorph.cxx:587
 RooIntegralMorph.cxx:588
 RooIntegralMorph.cxx:589
 RooIntegralMorph.cxx:590
 RooIntegralMorph.cxx:591
 RooIntegralMorph.cxx:592
 RooIntegralMorph.cxx:593
 RooIntegralMorph.cxx:594
 RooIntegralMorph.cxx:595
 RooIntegralMorph.cxx:596
 RooIntegralMorph.cxx:597
 RooIntegralMorph.cxx:598
 RooIntegralMorph.cxx:599
 RooIntegralMorph.cxx:600
 RooIntegralMorph.cxx:601
 RooIntegralMorph.cxx:602
 RooIntegralMorph.cxx:603
 RooIntegralMorph.cxx:604
 RooIntegralMorph.cxx:605
 RooIntegralMorph.cxx:606
 RooIntegralMorph.cxx:607
 RooIntegralMorph.cxx:608
 RooIntegralMorph.cxx:609
 RooIntegralMorph.cxx:610
 RooIntegralMorph.cxx:611
 RooIntegralMorph.cxx:612
 RooIntegralMorph.cxx:613
 RooIntegralMorph.cxx:614
 RooIntegralMorph.cxx:615
 RooIntegralMorph.cxx:616
 RooIntegralMorph.cxx:617
 RooIntegralMorph.cxx:618
 RooIntegralMorph.cxx:619
 RooIntegralMorph.cxx:620
 RooIntegralMorph.cxx:621
 RooIntegralMorph.cxx:622
 RooIntegralMorph.cxx:623
 RooIntegralMorph.cxx:624
 RooIntegralMorph.cxx:625
 RooIntegralMorph.cxx:626
 RooIntegralMorph.cxx:627
 RooIntegralMorph.cxx:628
 RooIntegralMorph.cxx:629
 RooIntegralMorph.cxx:630
 RooIntegralMorph.cxx:631
 RooIntegralMorph.cxx:632
 RooIntegralMorph.cxx:633
 RooIntegralMorph.cxx:634
 RooIntegralMorph.cxx:635
 RooIntegralMorph.cxx:636
 RooIntegralMorph.cxx:637
 RooIntegralMorph.cxx:638
 RooIntegralMorph.cxx:639
 RooIntegralMorph.cxx:640
 RooIntegralMorph.cxx:641
 RooIntegralMorph.cxx:642
 RooIntegralMorph.cxx:643
 RooIntegralMorph.cxx:644
 RooIntegralMorph.cxx:645
 RooIntegralMorph.cxx:646
 RooIntegralMorph.cxx:647
 RooIntegralMorph.cxx:648
 RooIntegralMorph.cxx:649
 RooIntegralMorph.cxx:650
 RooIntegralMorph.cxx:651
 RooIntegralMorph.cxx:652
 RooIntegralMorph.cxx:653
 RooIntegralMorph.cxx:654
 RooIntegralMorph.cxx:655
 RooIntegralMorph.cxx:656
 RooIntegralMorph.cxx:657
 RooIntegralMorph.cxx:658
 RooIntegralMorph.cxx:659
 RooIntegralMorph.cxx:660
 RooIntegralMorph.cxx:661
 RooIntegralMorph.cxx:662
 RooIntegralMorph.cxx:663
 RooIntegralMorph.cxx:664
 RooIntegralMorph.cxx:665
 RooIntegralMorph.cxx:666
 RooIntegralMorph.cxx:667
 RooIntegralMorph.cxx:668
 RooIntegralMorph.cxx:669
 RooIntegralMorph.cxx:670
 RooIntegralMorph.cxx:671
 RooIntegralMorph.cxx:672
 RooIntegralMorph.cxx:673
 RooIntegralMorph.cxx:674
 RooIntegralMorph.cxx:675
 RooIntegralMorph.cxx:676
 RooIntegralMorph.cxx:677
 RooIntegralMorph.cxx:678
 RooIntegralMorph.cxx:679
 RooIntegralMorph.cxx:680
 RooIntegralMorph.cxx:681
 RooIntegralMorph.cxx:682
 RooIntegralMorph.cxx:683
 RooIntegralMorph.cxx:684
 RooIntegralMorph.cxx:685
 RooIntegralMorph.cxx:686
 RooIntegralMorph.cxx:687
 RooIntegralMorph.cxx:688
 RooIntegralMorph.cxx:689
 RooIntegralMorph.cxx:690
 RooIntegralMorph.cxx:691
 RooIntegralMorph.cxx:692
 RooIntegralMorph.cxx:693
 RooIntegralMorph.cxx:694
 RooIntegralMorph.cxx:695
 RooIntegralMorph.cxx:696
 RooIntegralMorph.cxx:697
 RooIntegralMorph.cxx:698
 RooIntegralMorph.cxx:699
 RooIntegralMorph.cxx:700
 RooIntegralMorph.cxx:701