/*****************************************************************************
 * Project: RooFit                                                           *
 * Package: RooFitModels                                                     *
 * @(#)root/roofit:$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
// Class RooGExpModel is a RooResolutionModel implementation that models
// a resolution function that is the convolution of a Gaussian with
// a one-sided exponential. Object of class RooGExpModel can be used
// for analytical convolutions with classes inheriting from RooAbsAnaConvPdf
// END_HTML
//

#include "RooFit.h"

#include "Riostream.h"
#include "Riostream.h"
#include "RooGExpModel.h"
#include "RooMath.h"
#include "RooRealConstant.h"
#include "RooRandom.h"
#include "RooMath.h"
#include "TMath.h"

#include "TError.h"

using namespace std;

ClassImp(RooGExpModel) 
;



//_____________________________________________________________________________
RooGExpModel::RooGExpModel(const char *name, const char *title, RooRealVar& xIn, 
			   RooAbsReal& _sigma, RooAbsReal& _rlife, 
			   Bool_t nlo, Type type) : 
  RooResolutionModel(name,title,xIn), 
  sigma("sigma","Width",this,_sigma),
  rlife("rlife","Life time",this,_rlife),
  ssf("ssf","Sigma Scale Factor",this,(RooRealVar&)RooRealConstant::value(1)),
  rsf("rsf","RLife Scale Factor",this,(RooRealVar&)RooRealConstant::value(1)),
  _flip(type==Flipped),_nlo(nlo), _flatSFInt(kFALSE), _asympInt(kFALSE)
{  
}



//_____________________________________________________________________________
RooGExpModel::RooGExpModel(const char *name, const char *title, RooRealVar& xIn, 
			   RooAbsReal& _sigma, RooAbsReal& _rlife, 
			   RooAbsReal& _rsSF,
			   Bool_t nlo, Type type) : 
  RooResolutionModel(name,title,xIn), 
  sigma("sigma","Width",this,_sigma),
  rlife("rlife","Life time",this,_rlife),
  ssf("ssf","Sigma Scale Factor",this,_rsSF),
  rsf("rsf","RLife Scale Factor",this,_rsSF),
  _flip(type==Flipped),
  _nlo(nlo), 
  _flatSFInt(kFALSE),
  _asympInt(kFALSE)
{  
}



//_____________________________________________________________________________
RooGExpModel::RooGExpModel(const char *name, const char *title, RooRealVar& xIn, 
			   RooAbsReal& _sigma, RooAbsReal& _rlife, 
			   RooAbsReal& _sigmaSF, RooAbsReal& _rlifeSF,
			   Bool_t nlo, Type type) : 
  RooResolutionModel(name,title,xIn), 
  sigma("sigma","Width",this,_sigma),
  rlife("rlife","Life time",this,_rlife),
  ssf("ssf","Sigma Scale Factor",this,_sigmaSF),
  rsf("rsf","RLife Scale Factor",this,_rlifeSF),
  _flip(type==Flipped),
  _nlo(nlo), 
  _flatSFInt(kFALSE),
  _asympInt(kFALSE)
{  
}



//_____________________________________________________________________________
RooGExpModel::RooGExpModel(const RooGExpModel& other, const char* name) : 
  RooResolutionModel(other,name),
  sigma("sigma",this,other.sigma),
  rlife("rlife",this,other.rlife),
  ssf("ssf",this,other.ssf),
  rsf("rsf",this,other.rsf),
  _flip(other._flip),
  _nlo(other._nlo),
  _flatSFInt(other._flatSFInt),
  _asympInt(other._asympInt)
{
}



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



//_____________________________________________________________________________
Int_t RooGExpModel::basisCode(const char* name) const 
{
  if (!TString("exp(-@0/@1)").CompareTo(name)) return expBasisPlus ;
  if (!TString("exp(@0/@1)").CompareTo(name)) return expBasisMinus ;
  if (!TString("exp(-abs(@0)/@1)").CompareTo(name)) return expBasisSum ;
  if (!TString("exp(-@0/@1)*sin(@0*@2)").CompareTo(name)) return sinBasisPlus ;
  if (!TString("exp(@0/@1)*sin(@0*@2)").CompareTo(name)) return sinBasisMinus ;
  if (!TString("exp(-abs(@0)/@1)*sin(@0*@2)").CompareTo(name)) return sinBasisSum ;
  if (!TString("exp(-@0/@1)*cos(@0*@2)").CompareTo(name)) return cosBasisPlus ;
  if (!TString("exp(@0/@1)*cos(@0*@2)").CompareTo(name)) return cosBasisMinus ;
  if (!TString("exp(-abs(@0)/@1)*cos(@0*@2)").CompareTo(name)) return cosBasisSum ;
  if (!TString("exp(-@0/@1)*sinh(@0*@2/2)").CompareTo(name)) return sinhBasisPlus;
  if (!TString("exp(@0/@1)*sinh(@0*@2/2)").CompareTo(name)) return sinhBasisMinus;
  if (!TString("exp(-abs(@0)/@1)*sinh(@0*@2/2)").CompareTo(name)) return sinhBasisSum;
  if (!TString("exp(-@0/@1)*cosh(@0*@2/2)").CompareTo(name)) return coshBasisPlus;
  if (!TString("exp(@0/@1)*cosh(@0*@2/2)").CompareTo(name)) return coshBasisMinus;
  if (!TString("exp(-abs(@0)/@1)*cosh(@0*@2/2)").CompareTo(name)) return coshBasisSum;
  return 0 ;
} 



//_____________________________________________________________________________
Double_t RooGExpModel::evaluate() const 
{  
  static Double_t root2(sqrt(2.)) ;
//   static Double_t root2pi(sqrt(2*atan2(0.,-1.))) ;
//   static Double_t rootpi(sqrt(atan2(0.,-1.)));

  BasisType basisType = (BasisType)( (_basisCode == 0) ? 0 : (_basisCode/10) + 1 );
  BasisSign basisSign = (BasisSign)( _basisCode - 10*(basisType-1) - 2 ) ;

  Double_t fsign = _flip?-1:1 ;

  Double_t sig = sigma*ssf ;
  Double_t rtau = rlife*rsf ;
 
  Double_t tau = (_basisCode!=noBasis)?((RooAbsReal*)basis().getParameter(1))->getVal():0. ;
  // added, FMV 07/27/03
  if (basisType == coshBasis && _basisCode!=noBasis ) {
     Double_t dGamma = ((RooAbsReal*)basis().getParameter(2))->getVal();
     if (dGamma==0) basisType = expBasis;
  }

  // *** 1st form: Straight GExp, used for unconvoluted PDF or expBasis with 0 lifetime ***
  if (basisType==none || ((basisType==expBasis || basisType==cosBasis) && tau==0.)) {
    if (verboseEval()>2) cout << "RooGExpModel::evaluate(" << GetName() << ") 1st form" << endl ;    

    Double_t expArg = sig*sig/(2*rtau*rtau) + fsign*x/rtau ;

    Double_t result ;
    if (expArg<300) {
      result = 1/(2*rtau) * exp(expArg) * RooMath::erfc(sig/(root2*rtau) + fsign*x/(root2*sig));
    } else {
      // If exponent argument is very large, bring canceling RooMath::erfc() term inside exponent
      // to avoid floating point over/underflows of intermediate calculations
      result = 1/(2*rtau) * exp(expArg + logErfC(sig/(root2*rtau) + fsign*x/(root2*sig))) ;
    }

//     Double_t result = 1/(2*rtau)
//                     * exp(sig*sig/(2*rtau*rtau) + fsign*x/rtau)
//                     * RooMath::erfc(sig/(root2*rtau) + fsign*x/(root2*sig));

    // equivalent form, added FMV, 07/24/03
    //Double_t xprime = x/rtau ;
    //Double_t c = sig/(root2*rtau) ;
    //Double_t u = xprime/(2*c) ;
    //Double_t result = 0.5*evalCerf(fsign*u,c).real() ;  // sign=-1 ! 

    if (_basisCode!=0 && basisSign==Both) result *= 2 ;
    //cout << "1st form " << "x= " << x << " result= " << result << endl;
    return result ;    
  }
  
  // *** 2nd form: 0, used for sinBasis and cosBasis with tau=0 ***
  if (tau==0) {
    if (verboseEval()>2) cout << "RooGExpModel::evaluate(" << GetName() << ") 2nd form" << endl ;
    return 0. ;
  }

  Double_t omega = (basisType!=expBasis)?((RooAbsReal*)basis().getParameter(2))->getVal():0. ;

  // *** 3nd form: Convolution with exp(-t/tau), used for expBasis and cosBasis(omega=0) ***
  if (basisType==expBasis || (basisType==cosBasis && omega==0.)) {
    if (verboseEval()>2) cout << "RooGExpModel::evaluate(" << GetName() << ") 3d form tau=" << tau << endl ;
    Double_t result(0) ;
    if (basisSign!=Minus) result += calcDecayConv(+1,tau,sig,rtau,fsign) ;  // modified FMV,08/13/03
    if (basisSign!=Plus)  result += calcDecayConv(-1,tau,sig,rtau,fsign) ;  // modified FMV,08/13/03
    //cout << "3rd form " << "x= " << x << " result= " << result << endl;
    return result ;
  }
  
  // *** 4th form: Convolution with exp(-t/tau)*sin(omega*t), used for sinBasis(omega<>0,tau<>0) ***
  Double_t wt = omega *tau ;
  if (basisType==sinBasis) {
    if (verboseEval()>2) cout << "RooGExpModel::evaluate(" << GetName() << ") 4th form omega = " 
			     << omega << ", tau = " << tau << endl ;
    Double_t result(0) ;
    if (wt==0.) return result ;
    if (basisSign!=Minus) result += -1*calcSinConv(+1,sig,tau,omega,rtau,fsign).imag() ;
    if (basisSign!=Plus) result += -1*calcSinConv(-1,sig,tau,omega,rtau,fsign).imag() ;
    //cout << "4th form " << "x= " << x << " result= " << result << endl;
    return result ;
  }

  // *** 5th form: Convolution with exp(-t/tau)*cos(omega*t), used for cosBasis(omega<>0) ***
  if (basisType==cosBasis) {
    if (verboseEval()>2) cout << "RooGExpModel::evaluate(" << GetName() 
			     << ") 5th form omega = " << omega << ", tau = " << tau << endl ;
    Double_t result(0) ;
    if (basisSign!=Minus) result += calcSinConv(+1,sig,tau,omega,rtau,fsign).real() ;
    if (basisSign!=Plus) result += calcSinConv(-1,sig,tau,omega,rtau,fsign).real() ;
    //cout << "5th form " << "x= " << x << " result= " << result << endl;
    return result ;  
  }


  // *** 6th form: Convolution with exp(-t/tau)*sinh(dgamma*t/2), used for sinhBasis ***
  if (basisType==sinhBasis) {
    Double_t dgamma = ((RooAbsReal*)basis().getParameter(2))->getVal();
   
    if (verboseEval()>2) cout << "RooGExpModel::evaluate(" << GetName()
			     << ") 6th form = " << dgamma << ", tau = " << tau << endl;
    Double_t result(0);
    //if (basisSign!=Minus) result += calcSinhConv(+1,+1,-1,tau,dgamma,sig,rtau,fsign);
    //if (basisSign!=Plus) result += calcSinhConv(-1,-1,+1,tau,dgamma,sig,rtau,fsign);
    // better form, since it also accounts for the numerical divergence region, added FMV, 07/24/03
    Double_t tau1 = 1/(1/tau-dgamma/2) ; 
    Double_t tau2 = 1/(1/tau+dgamma/2) ;
    if (basisSign!=Minus) result += 0.5*(calcDecayConv(+1,tau1,sig,rtau,fsign)-calcDecayConv(+1,tau2,sig,rtau,fsign));  
          // modified FMV,08/13/03
    if (basisSign!=Plus) result += 0.5*(calcDecayConv(-1,tau2,sig,rtau,fsign)-calcDecayConv(-1,tau1,sig,rtau,fsign));
          // modified FMV,08/13/03
    //cout << "6th form " << "x= " << x << " result= " << result << endl;
    return result;
  }

  // *** 7th form: Convolution with exp(-t/tau)*cosh(dgamma*t/2), used for coshBasis ***
  if (basisType==coshBasis) {
    Double_t dgamma = ((RooAbsReal*)basis().getParameter(2))->getVal();
    
    if (verboseEval()>2) cout << "RooGExpModel::evaluate(" << GetName()
		         << ") 7th form = " << dgamma << ", tau = " << tau << endl;
    Double_t result(0);
    //if (basisSign!=Minus) result += calcCoshConv(+1,tau,dgamma,sig,rtau,fsign);
    //if (basisSign!=Plus) result += calcCoshConv(-1,tau,dgamma,sig,rtau,fsign);
    // better form, since it also accounts for the numerical divergence region, added FMV, 07/24/03
    Double_t tau1 = 1/(1/tau-dgamma/2) ; 
    Double_t tau2 = 1/(1/tau+dgamma/2) ;
    if (basisSign!=Minus) result += 0.5*(calcDecayConv(+1,tau1,sig,rtau,fsign)+calcDecayConv(+1,tau2,sig,rtau,fsign));
          // modified FMV,08/13/03
    if (basisSign!=Plus) result += 0.5*(calcDecayConv(-1,tau1,sig,rtau,fsign)+calcDecayConv(-1,tau2,sig,rtau,fsign));
          // modified FMV,08/13/03
    //cout << "7th form " << "x= " << x << " result= " << result << endl;
    return result;
  }
  R__ASSERT(0) ;
  return 0 ;
  }



//_____________________________________________________________________________
Double_t RooGExpModel::logErfC(Double_t xx) const
{
  // Approximation of the log of the complex error function
  Double_t t,z,ans;
  z=fabs(xx);
  t=1.0/(1.0+0.5*z);
  
  if(xx >= 0.0)
    ans=log(t)+(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+t*(-0.18628806+
	t*(0.27886807+t*(-1.13520398+t*(1.48851587+t*(-0.82215223+t*0.17087277)))))))));
  else
    ans=log(2.0-t*exp(-z*z-1.26551223+t*(1.00002368+t*(0.37409196+t*(0.09678418+t*(-0.18628806+
        t*(0.27886807+t*(-1.13520398+t*(1.48851587+t*(-0.82215223+t*0.17087277))))))))));
  
  return ans;
}



//_____________________________________________________________________________
std::complex<Double_t> RooGExpModel::calcSinConv(Double_t sign, Double_t sig, Double_t tau, Double_t omega, Double_t rtau, Double_t fsign) const
{
  static Double_t root2(sqrt(2.)) ;

  Double_t s1= -sign*x/tau;
  //Double_t s1= x/tau;
  Double_t c1= sig/(root2*tau);
  Double_t u1= s1/(2*c1);  
  Double_t s2= x/rtau;
  Double_t c2= sig/(root2*rtau);
  Double_t u2= fsign*s2/(2*c2) ;
  //Double_t u2= s2/(2*c2) ;

  std::complex<Double_t> eins(1,0);
  std::complex<Double_t> k(1/tau,sign*omega);  
  //return (evalCerf(-sign*omega*tau,u1,c1)+evalCerf(0,u2,c2)*fsign*sign) / (eins + k*fsign*sign*rtau) ;

  return (evalCerf(-sign*omega*tau,u1,c1)+std::complex<Double_t>(evalCerfRe(u2,c2),0)*fsign*sign) / (eins + k*fsign*sign*rtau) ;
  // equivalent form, added FMV, 07/24/03
  //return (evalCerf(-sign*omega*tau,-sign*u1,c1)+evalCerf(0,fsign*u2,c2)*fsign*sign) / (eins + k*fsign*sign*rtau) ;
}


// added FMV,08/18/03

//_____________________________________________________________________________
Double_t RooGExpModel::calcSinConv(Double_t sign, Double_t sig, Double_t tau, Double_t rtau, Double_t fsign) const
{
  static Double_t root2(sqrt(2.)) ;

  Double_t s1= -sign*x/tau;
  //Double_t s1= x/tau;
  Double_t c1= sig/(root2*tau);
  Double_t u1= s1/(2*c1);  
  Double_t s2= x/rtau;
  Double_t c2= sig/(root2*rtau);
  Double_t u2= fsign*s2/(2*c2) ;
  //Double_t u2= s2/(2*c2) ;

  Double_t eins(1);
  Double_t k(1/tau);  
  return (evalCerfRe(u1,c1)+evalCerfRe(u2,c2)*fsign*sign) / (eins + k*fsign*sign*rtau) ;
  // equivalent form, added FMV, 07/24/03
  //return (evalCerf(-sign*u1,c1).real()+evalCerf(fsign*u2,c2).real()*fsign*sign) / (eins + k*fsign*sign*rtau) ;
}



//_____________________________________________________________________________
Double_t RooGExpModel::calcDecayConv(Double_t sign, Double_t tau, Double_t sig, Double_t rtau, Double_t fsign) const
// modified FMV,08/13/03
{
  static Double_t root2(sqrt(2.)) ;
  static Double_t root2pi(sqrt(2*atan2(0.,-1.))) ;
  static Double_t rootpi(sqrt(atan2(0.,-1.)));

  // Process flip status
  Double_t xp(x) ;
  //if (_flip) {
  //  xp   *= -1 ;
  //  sign *= -1 ;
  //}
  xp *= fsign ;    // modified FMV,08/13/03
  sign *= fsign ;  // modified FMV,08/13/03

  Double_t cFly;
  if ((sign<0)&&(fabs(tau-rtau)<tau/260)) {

    Double_t MeanTau=0.5*(tau+rtau);
    if (fabs(xp/MeanTau)>300) {
      return 0 ;
    }

    cFly=1./(MeanTau*MeanTau*root2pi) *
      exp(-(-xp/MeanTau-sig*sig/(2*MeanTau*MeanTau)))
      *(sig*exp(-1/(2*sig*sig)*TMath::Power((sig*sig/MeanTau+xp),2)) 
	-(sig*sig/MeanTau+xp)*(rootpi/root2)*RooMath::erfc(sig/(root2*MeanTau)+xp/(root2*sig)));
    
    if(_nlo) {
      Double_t epsilon=0.5*(tau-rtau);
      Double_t a=sig/(root2*MeanTau)+xp/(root2*sig);
      cFly += 1./(MeanTau*MeanTau)
	*exp(-(-xp/MeanTau-sig*sig/(2*MeanTau*MeanTau)))
	*0.5/MeanTau*epsilon*epsilon*
	(exp(-a*a)*(sig/MeanTau*root2/rootpi
		    -(4*a*sig*sig)/(2*rootpi*MeanTau*MeanTau)
		    +(-4/rootpi+8*a*a/rootpi)/6
		    *TMath::Power(sig/(root2*MeanTau),3)
		    +2/rootpi*(sig*sig/(MeanTau*MeanTau)+xp/MeanTau)*
		    (sig/(root2*MeanTau)-a*(sig*sig)/(2*MeanTau*MeanTau))
		    +2/rootpi*((3*sig*sig)/(2*MeanTau*MeanTau)+xp/MeanTau+
			       0.5*TMath::Power(sig*sig/(MeanTau*MeanTau)+xp/MeanTau,2))*sig/(root2*MeanTau))
	 -(2*sig*sig/(MeanTau*MeanTau)+xp/MeanTau+(sig*sig/(MeanTau*MeanTau)+xp/MeanTau)*
	   (3*sig*sig/(2*MeanTau*MeanTau)+xp/MeanTau)
	   +TMath::Power(sig*sig/(MeanTau*MeanTau)+xp/MeanTau,3)/6)*RooMath::erfc(a));
    }
    
  } else {

    Double_t expArg1 = sig*sig/(2*tau*tau)-sign*xp/tau ;
    Double_t expArg2 = sig*sig/(2*rtau*rtau)+xp/rtau ;

    Double_t term1, term2 ;
    if (expArg1<300) {
      term1 = exp(expArg1) *RooMath::erfc(sig/(root2*tau)-sign*xp/(root2*sig)) ;
    } else {
      term1 = exp(expArg1+logErfC(sig/(root2*tau)-sign*xp/(root2*sig))) ; ;
    }
    if (expArg2<300) {
      term2 = exp(expArg2) *RooMath::erfc(sig/(root2*rtau)+xp/(root2*sig)) ;
    } else {
      term2 = exp(expArg2+logErfC(sig/(root2*rtau)+xp/(root2*sig))) ; ;
    }

    cFly=(term1+sign*term2)/(2*(tau+sign*rtau));
    
    // WVE prevent numeric underflows 
    if (cFly<1e-100) {
      cFly = 0 ;
    }

    // equivalent form, added FMV, 07/24/03 
    //cFly = calcSinConv(sign, sig, tau, rtau, fsign)/(2*tau) ;
  }

  return cFly*2*tau ;    
}

/* commented FMV, 07/24/03

//_____________________________________________________________________________
Double_t RooGExpModel::calcCoshConv(Double_t sign, Double_t tau, Double_t dgamma, Double_t sig, Double_t rtau, Double_t fsign) const
{
  
  
  
  static Double_t root2(sqrt(2.)) ;
  static Double_t root2pi(sqrt(2*atan2(0.,-1.))) ;
  static Double_t rootpi(sqrt(atan2(0.,-1.)));
  Double_t tau1 = 1/(1/tau-dgamma/2);
  Double_t tau2 = 1/(1/tau+dgamma/2);
  Double_t cFly;
  Double_t xp(x);

  //if (_flip) {
  //  xp   *= -1 ;
  //  sign *= -1 ;
  //}
  xp *= fsign ;    // modified FMV,08/13/03
  sign *= fsign ;  // modified FMV,08/13/03

  cFly=tau1*(exp(sig*sig/(2*tau1*tau1)-sign*xp/tau1)
	  *RooMath::erfc(sig/(root2*tau1)-sign*xp/(root2*sig))
	  +sign*exp(sig*sig/(2*rtau*rtau)+xp/rtau)
	  *RooMath::erfc(sig/(root2*rtau)+xp/(root2*sig)))/(2*(tau1+sign*rtau))
    +tau2*(exp(sig*sig/(2*tau2*tau2)-sign*xp/tau2)
	  *RooMath::erfc(sig/(root2*tau2)-sign*xp/(root2*sig))
	  +sign*exp(sig*sig/(2*rtau*rtau)+xp/rtau)
	  *RooMath::erfc(sig/(root2*rtau)+xp/(root2*sig)))/(2*(tau2+sign*rtau));;
  return cFly;
}
*/

/* commented FMV, 07/24/03

//_____________________________________________________________________________
Double_t RooGExpModel::calcSinhConv(Double_t sign, Double_t sign1, Double_t sign2, Double_t tau, Double_t dgamma, Double_t sig, Double_t rtau, Double_t fsign) const
{
  static Double_t root2(sqrt(2.)) ;
  static Double_t root2pi(sqrt(2*atan2(0.,-1.))) ;
  static Double_t rootpi(sqrt(atan2(0.,-1.)));
  Double_t tau1 = 1/(1/tau-dgamma/2);
  Double_t tau2 = 1/(1/tau+dgamma/2);
  Double_t cFly;
  Double_t xp(x);
  
  //if (_flip) {
  //  xp   *= -1 ;
  //  sign1 *= -1 ;
  //  sign2 *= -1 ;
  //}
  xp *= fsign ;    // modified FMV,08/13/03
  sign1 *= fsign ;  // modified FMV,08/13/03
  sign2 *= fsign ;  // modified FMV,08/13/03

  cFly=sign1*tau1*(exp(sig*sig/(2*tau1*tau1)-sign*xp/tau1)
	  *RooMath::erfc(sig/(root2*tau1)-sign*xp/(root2*sig))
	  +sign*exp(sig*sig/(2*rtau*rtau)+xp/rtau)
	  *RooMath::erfc(sig/(root2*rtau)+xp/(root2*sig)))/(2*(tau1+sign*rtau))
    +sign2*tau2*(exp(sig*sig/(2*tau2*tau2)-sign*xp/tau2)
	  *RooMath::erfc(sig/(root2*tau2)-sign*xp/(root2*sig))
	  +sign*exp(sig*sig/(2*rtau*rtau)+xp/rtau)
	  *RooMath::erfc(sig/(root2*rtau)+xp/(root2*sig)))/(2*(tau2+sign*rtau));;
  return cFly;
}
*/


//_____________________________________________________________________________
Int_t RooGExpModel::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* /*rangeName*/) const 
{
  switch(_basisCode) {

  // Analytical integration capability of raw PDF
  case noBasis:
    if (matchArgs(allVars,analVars,convVar())) return 1 ;
    break ;

  // Analytical integration capability of convoluted PDF
  case expBasisPlus:
  case expBasisMinus:
  case expBasisSum:
  case sinBasisPlus:
  case sinBasisMinus:
  case sinBasisSum:
  case cosBasisPlus:
  case cosBasisMinus:
  case cosBasisSum:
  case sinhBasisPlus:
  case sinhBasisMinus:
  case sinhBasisSum:
  case coshBasisPlus:
  case coshBasisMinus:
  case coshBasisSum:
    
    // Optionally advertise flat integral over sigma scale factor
    if (_flatSFInt) {
      if (matchArgs(allVars,analVars,RooArgSet(convVar(),ssf.arg()))) {
	return 2 ;
      }
    }

    if (matchArgs(allVars,analVars,convVar())) return 1 ;
    break ;
  }
  
  return 0 ;
}



//_____________________________________________________________________________
Double_t RooGExpModel::analyticalIntegral(Int_t code, const char* rangeName) const 
{
  static Double_t root2 = sqrt(2.) ;
//   static Double_t rootPiBy2 = sqrt(atan2(0.0,-1.0)/2.0);
  Double_t ssfInt(1.0) ;

  // Code must be 1 or 2
  R__ASSERT(code==1||code==2) ;
  if (code==2) {
    ssfInt = (ssf.max(rangeName)-ssf.min(rangeName)) ;
  }

  BasisType basisType = (BasisType)( (_basisCode == 0) ? 0 : (_basisCode/10) + 1 );
  BasisSign basisSign = (BasisSign)( _basisCode - 10*(basisType-1) - 2 ) ;
   
  Double_t tau = (_basisCode!=noBasis)?((RooAbsReal*)basis().getParameter(1))->getVal():0 ;

  // added FMV, 07/24/03
  if (basisType == coshBasis && _basisCode!=noBasis ) {
     Double_t dGamma = ((RooAbsReal*)basis().getParameter(2))->getVal();
     if (dGamma==0) basisType = expBasis;
  }
  Double_t fsign = _flip?-1:1 ;
  Double_t sig = sigma*ssf ;
  Double_t rtau = rlife*rsf ;

  // *** 1st form????
  if (basisType==none || ((basisType==expBasis || basisType==cosBasis) && tau==0.)) {
    if (verboseEval()>0) cout << "RooGExpModel::analyticalIntegral(" << GetName() << ") 1st form" << endl ;

    //Double_t result = 1.0 ; // WVE inferred from limit(tau->0) of cosBasisNorm
    // finite+asymtotic normalization, added FMV, 07/24/03
    Double_t xpmin = x.min(rangeName)/rtau ;
    Double_t xpmax = x.max(rangeName)/rtau ;
    Double_t c = sig/(root2*rtau) ;
    Double_t umin = xpmin/(2*c) ;
    Double_t umax = xpmax/(2*c) ;
    Double_t result ;
    if (_asympInt) {
      result = 1.0 ;
    } else {
      result = 0.5*evalCerfInt(-fsign,rtau,fsign*umin,fsign*umax,c)/rtau ;  //WVEFIX add 1/rtau
    }

    if (_basisCode!=0 && basisSign==Both) result *= 2 ;    
    //cout << "Integral 1st form " << " result= " << result*ssfInt << endl;
    return result*ssfInt ;    
  }

  Double_t omega = (basisType!=expBasis) ?((RooAbsReal*)basis().getParameter(2))->getVal() : 0 ;

  // *** 2nd form: unity, used for sinBasis and cosBasis with tau=0 (PDF is zero) ***
  //if (tau==0&&omega!=0) {
  if (tau==0) {  // modified, FMV 07/24/03
    if (verboseEval()>0) cout << "RooGExpModel::analyticalIntegral(" << GetName() << ") 2nd form" << endl ;
    return 0. ;
  }

  // *** 3rd form: Convolution with exp(-t/tau), used for expBasis and cosBasis(omega=0) ***
  if (basisType==expBasis || (basisType==cosBasis && omega==0.)) {
    //Double_t result = 2*tau ;
    //if (basisSign==Both) result *= 2 ;
    // finite+asymtotic normalization, added FMV, 07/24/03
    Double_t result(0.);
    if (basisSign!=Minus) result += calcSinConvNorm(+1,tau,sig,rtau,fsign,rangeName); 
    if (basisSign!=Plus) result += calcSinConvNorm(-1,tau,sig,rtau,fsign,rangeName);  
    //cout << "Integral 3rd form " << " result= " << result*ssfInt << endl;
    return result*ssfInt ;
  }
  
  // *** 4th form: Convolution with exp(-t/tau)*sin(omega*t), used for sinBasis(omega<>0,tau<>0) ***
  Double_t wt = omega * tau ;    
  if (basisType==sinBasis) {    
    if (verboseEval()>0) cout << "RooGExpModel::analyticalIntegral(" << GetName() << ") 4th form omega = " 
			     << omega << ", tau = " << tau << endl ;
    //cout << "sin integral" << endl;
    Double_t result(0) ;
    if (wt==0) return result ;
    //if (basisSign!=Minus) result += calcSinConvNorm(+1,tau,omega).imag() ;
    //if (basisSign!=Plus) result += calcSinConvNorm(-1,tau,omega).imag() ;
    // finite+asymtotic normalization, added FMV, 07/24/03
    if (basisSign!=Minus) result += -1*calcSinConvNorm(+1,tau,omega,sig,rtau,fsign,rangeName).imag();
    if (basisSign!=Plus) result += -1*calcSinConvNorm(-1,tau,omega,sig,rtau,fsign,rangeName).imag();
    //cout << "Integral 4th form " << " result= " << result*ssfInt << endl;
    return result*ssfInt ;
  }
 
  // *** 5th form: Convolution with exp(-t/tau)*cos(omega*t), used for cosBasis(omega<>0) ***
  if (basisType==cosBasis) {
    if (verboseEval()>0) cout << "RooGExpModel::analyticalIntegral(" << GetName() 
			     << ") 5th form omega = " << omega << ", tau = " << tau << endl ;
    //cout << "cos integral" << endl;
    Double_t result(0) ;
    //if (basisSign!=Minus) result += calcSinConvNorm(+1,tau,omega).real() ;
    //if (basisSign!=Plus) result += calcSinConvNorm(-1,tau,omega).real() ;
    // finite+asymtotic normalization, added FMV, 07/24/03
    if (basisSign!=Minus) result += calcSinConvNorm(+1,tau,omega,sig,rtau,fsign,rangeName).real();
    if (basisSign!=Plus) result += calcSinConvNorm(-1,tau,omega,sig,rtau,fsign,rangeName).real();
    //cout << "Integral 5th form " << " result= " << result*ssfInt << endl;
    return result*ssfInt ;
  }
  
  Double_t dgamma = ((basisType==coshBasis)||(basisType==sinhBasis))?((RooAbsReal*)basis().getParameter(2))->getVal():0 ;  
 
  // *** 6th form: Convolution with exp(-t/tau)*sinh(dgamma*t/2), used for sinhBasis ***
  if (basisType==sinhBasis) {
    if (verboseEval()>0) cout << "RooGExpModel::analyticalIntegral(" << GetName() 
			     << ") 6th form dgamma = " << dgamma << ", tau = " << tau << endl ;
    Double_t tau1 = 1/(1/tau-dgamma/2);
    Double_t tau2 = 1/(1/tau+dgamma/2);
    //cout << "sinh integral" << endl;
    Double_t result(0) ;
    //if (basisSign!=Minus) result += tau1-tau2 ;
    //if (basisSign!=Plus) result += tau2-tau1 ;
    // finite+asymtotic normalization, added FMV, 07/24/03
    if (basisSign!=Minus) result += 0.5*(calcSinConvNorm(+1,tau1,sig,rtau,fsign,rangeName)-
					 calcSinConvNorm(+1,tau2,sig,rtau,fsign,rangeName));
    if (basisSign!=Plus) result += 0.5*(calcSinConvNorm(-1,tau2,sig,rtau,fsign,rangeName)-
					calcSinConvNorm(-1,tau1,sig,rtau,fsign,rangeName));
    //cout << "Integral 6th form " << " result= " << result*ssfInt << endl;
    return result;
    }

  // ** 7th form: Convolution with exp(-t/tau)*cosh(dgamma*t/2), used for coshBasis ***
  if (basisType==coshBasis) {
    if (verboseEval()>0) cout << "RooGExpModel::analyticalIntegral(" << GetName() 
			     << ") 6th form dgamma = " << dgamma << ", tau = " << tau << endl ;
    //cout << "cosh integral" << endl;
    Double_t tau1 = 1/(1/tau-dgamma/2);
    Double_t tau2 = 1/(1/tau+dgamma/2);
    //Double_t result = (tau1+tau2) ;
    //if (basisSign==Both) result *= 2 ;
    // finite+asymtotic normalization, added FMV, 07/24/03
    Double_t result(0);
    if (basisSign!=Minus) result += 0.5*(calcSinConvNorm(+1,tau1,sig,rtau,fsign,rangeName)+
					 calcSinConvNorm(+1,tau2,sig,rtau,fsign,rangeName));
    if (basisSign!=Plus) result += 0.5*(calcSinConvNorm(-1,tau1,sig,rtau,fsign,rangeName)+
					calcSinConvNorm(-1,tau2,sig,rtau,fsign,rangeName));
    //cout << "Integral 7th form " << " result= " << result*ssfInt << endl;
    return result;
  
    }

  R__ASSERT(0) ;
  return 1 ;
}


// modified FMV, 07/24/03. Finite+asymtotic normalization

//_____________________________________________________________________________
std::complex<Double_t> RooGExpModel::calcSinConvNorm(Double_t sign, Double_t tau, Double_t omega, 
					 Double_t sig, Double_t rtau, Double_t fsign, const char* rangeName) const
{
  //  old code (asymptotic normalization only)
  //  std::complex<Double_t> z(1/tau,sign*omega);
  //  return z*2/(omega*omega+1/(tau*tau));

  static Double_t root2(sqrt(2.)) ;

  Double_t smin1= x.min(rangeName)/tau;
  Double_t smax1= x.max(rangeName)/tau;
  Double_t c1= sig/(root2*tau);
  Double_t umin1= smin1/(2*c1);  
  Double_t umax1= smax1/(2*c1);  
  Double_t smin2= x.min(rangeName)/rtau;
  Double_t smax2= x.max(rangeName)/rtau;
  Double_t c2= sig/(root2*rtau);
  Double_t umin2= smin2/(2*c2) ;
  Double_t umax2= smax2/(2*c2) ;

  std::complex<Double_t> eins(1,0);
  std::complex<Double_t> k(1/tau,sign*omega);
  std::complex<Double_t> term1 = evalCerfInt(sign,-sign*omega*tau, tau, -sign*umin1, -sign*umax1, c1);
  //std::complex<Double_t> term2 = evalCerfInt(-fsign,0., rtau, fsign*umin2, fsign*umax2, c2)*std::complex<Double_t>(fsign*sign,0);
  std::complex<Double_t> term2 = std::complex<Double_t>(evalCerfInt(-fsign, rtau, fsign*umin2, fsign*umax2, c2)*fsign*sign,0);
  return (term1+term2)/(eins + k*fsign*sign*rtau) ;
}


// added FMV, 08/17/03

//_____________________________________________________________________________
Double_t RooGExpModel::calcSinConvNorm(Double_t sign, Double_t tau, Double_t sig, Double_t rtau, Double_t fsign, const char* rangeName) const
{
  static Double_t root2(sqrt(2.)) ;

  Double_t smin1= x.min(rangeName)/tau;
  Double_t smax1= x.max(rangeName)/tau;
  Double_t c1= sig/(root2*tau);
  Double_t umin1= smin1/(2*c1);  
  Double_t umax1= smax1/(2*c1);  
  Double_t smin2= x.min(rangeName)/rtau;
  Double_t smax2= x.max(rangeName)/rtau;
  Double_t c2= sig/(root2*rtau);
  Double_t umin2= smin2/(2*c2) ;
  Double_t umax2= smax2/(2*c2) ;

  Double_t eins(1);
  Double_t k(1/tau);
  Double_t term1 = evalCerfInt(sign, tau, -sign*umin1, -sign*umax1, c1);
  Double_t term2 = evalCerfInt(-fsign, rtau, fsign*umin2, fsign*umax2, c2)*fsign*sign;

  // WVE Handle 0/0 numeric divergence 
  if (fabs(tau-rtau)<1e-10 && fabs(term1+term2)<1e-10) {
    cout << "epsilon method" << endl ;
    static Double_t epsilon = 1e-4 ;
    return calcSinConvNorm(sign,tau+epsilon,sig,rtau-epsilon,fsign,rangeName) ;
  }
  return (term1+term2)/(eins + k*fsign*sign*rtau) ;
}



// added FMV, 07/24/03
//_____________________________________________________________________________
std::complex<Double_t> RooGExpModel::evalCerfInt(Double_t sign, Double_t wt, Double_t tau, Double_t umin, Double_t umax, Double_t c) const
{
  std::complex<Double_t> diff;
  if (_asympInt) {
    diff = std::complex<Double_t>(2,0) ;
  } else {
    diff = std::complex<Double_t>(sign,0.)*(evalCerf(wt,umin,c) - evalCerf(wt,umax,c) + RooMath::erf(umin) - RooMath::erf(umax));
  }
  return std::complex<Double_t>(tau/(1.+wt*wt),0)*std::complex<Double_t>(1,wt)*diff;
}
// added FMV, 08/17/03. Modified FMV, 08/30/03

//_____________________________________________________________________________
Double_t RooGExpModel::evalCerfInt(Double_t sign, Double_t tau, Double_t umin, Double_t umax, Double_t c) const
{
  Double_t diff;
  if (_asympInt) {
    diff = 2. ;
  } else {
    if ((umin<-8 && umax>8)||(umax<-8 && umin>8)) {
      // If integral is over >8 sigma, approximate with full integral
      diff = 2. ;
    } else {
      diff = sign*(evalCerfRe(umin,c) - evalCerfRe(umax,c) + RooMath::erf(umin) - RooMath::erf(umax));
    }
  }
  return tau*diff;
}



//_____________________________________________________________________________
std::complex<Double_t> RooGExpModel::evalCerfApprox(Double_t swt, Double_t u, Double_t c)
{
  // use the approximation: erf(z) = exp(-z*z)/(sqrt(pi)*z)
  // to explicitly cancel the divergent exp(y*y) behaviour of
  // CWERF for z = x + i y with large negative y

  static Double_t rootpi= sqrt(atan2(0.,-1.));
  std::complex<Double_t> z(swt*c,u+c);  
  std::complex<Double_t> zc(u+c,-swt*c);
  std::complex<Double_t> zsq= z*z;
  std::complex<Double_t> v= -zsq - u*u;

  return std::exp(v)*(-std::exp(zsq)/(zc*rootpi) + 1.)*2.;
}



//_____________________________________________________________________________
Int_t RooGExpModel::getGenerator(const RooArgSet& directVars, RooArgSet &generateVars, Bool_t /*staticInitOK*/) const
{
  if (matchArgs(directVars,generateVars,x)) return 1 ; 
  return 0 ;
}



//_____________________________________________________________________________
void RooGExpModel::generateEvent(Int_t code)
{
  R__ASSERT(code==1) ;
  Double_t xgen ;
  while(1) {
    Double_t xgau = RooRandom::randomGenerator()->Gaus(0,(sigma*ssf));
    Double_t xexp = RooRandom::uniform();
    if (!_flip) xgen= xgau + (rlife*rsf)*log(xexp);  // modified, FMV 08/13/03
    else xgen= xgau - (rlife*rsf)*log(xexp);
    if (xgen<x.max() && xgen>x.min()) {
      x = xgen ;
      return ;
    }
  }
}


























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