#include "RooFit.h"
#include "Riostream.h"
#include "Riostream.h"
#include <math.h>
#include "RooGamma.h"
#include "RooAbsReal.h"
#include "RooRealVar.h"
#include "RooRandom.h"
#include "RooMath.h"
#include <iostream>
#include "TMath.h"
#include <Math/SpecFuncMathCore.h>
#include <Math/PdfFuncMathCore.h>
#include <Math/ProbFuncMathCore.h>
#include "TError.h"
using namespace std;
ClassImp(RooGamma)
RooGamma::RooGamma(const char *name, const char *title,
RooAbsReal& _x, RooAbsReal& _gamma,
RooAbsReal& _beta, RooAbsReal& _mu) :
RooAbsPdf(name,title),
x("x","Observable",this,_x),
gamma("gamma","Mean",this,_gamma),
beta("beta","Width",this,_beta),
mu("mu","Para",this,_mu)
{
}
RooGamma::RooGamma(const RooGamma& other, const char* name) :
RooAbsPdf(other,name), x("x",this,other.x), gamma("mean",this,other.gamma),
beta("beta",this,other.beta), mu("mu",this,other.mu)
{
}
Double_t RooGamma::evaluate() const
{
Double_t arg= x ;
Double_t ret = TMath::GammaDist(arg, gamma, mu, beta) ;
return ret ;
}
Int_t RooGamma::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* ) const
{
if (matchArgs(allVars,analVars,x)) return 1 ;
return 0 ;
}
Double_t RooGamma::analyticalIntegral(Int_t code, const char* rangeName) const
{
R__ASSERT(code==1) ;
Double_t integral = ROOT::Math::gamma_cdf(x.max(rangeName), gamma, beta, mu) - ROOT::Math::gamma_cdf(x.min(rangeName), gamma, beta, mu);
return integral ;
}
Int_t RooGamma::getGenerator(const RooArgSet& directVars, RooArgSet &generateVars, Bool_t ) const
{
if (matchArgs(directVars,generateVars,x)) return 1 ;
return 0 ;
}
void RooGamma::generateEvent(Int_t code)
{
R__ASSERT(code==1) ;
while(1) {
double d = 0;
double c = 0;
double xgen = 0;
double v = 0;
double u = 0;
d = gamma -1./3.; c = 1./TMath::Sqrt(9.*d);
while(v <= 0.){
xgen = RooRandom::randomGenerator()->Gaus(); v = 1. + c*xgen;
}
v = v*v*v; u = RooRandom::randomGenerator()->Uniform();
if( u < 1.-.0331*(xgen*xgen)*(xgen*xgen) ) {
if ( (((d*v)* beta + mu ) < x.max()) && (((d*v)* beta + mu) > x.min()) ) {
x = ((d*v)* beta + mu) ;
break;
}
}
if( TMath::Log(u) < 0.5*xgen*xgen + d*(1.-v + TMath::Log(v)) ) {
if ( (((d*v)* beta + mu ) < x.max()) && (((d*v)* beta + mu) > x.min()) ) {
x = ((d*v)* beta + mu) ;
break;
}
}
}
return;
}