00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <iostream>
00017
00018 #include "RooPoisson.h"
00019 #include "RooAbsReal.h"
00020 #include "RooAbsCategory.h"
00021
00022 #include "RooRandom.h"
00023 #include "RooMath.h"
00024 #include "TMath.h"
00025 #include "Math/ProbFuncMathCore.h"
00026
00027 ClassImp(RooPoisson)
00028
00029
00030
00031
00032 RooPoisson::RooPoisson(const char *name, const char *title,
00033 RooAbsReal& _x,
00034 RooAbsReal& _mean,
00035 Bool_t noRounding) :
00036 RooAbsPdf(name,title),
00037 x("x","x",this,_x),
00038 mean("mean","mean",this,_mean),
00039 _noRounding(noRounding),
00040 _protectNegative(false)
00041 {
00042
00043 }
00044
00045
00046
00047
00048 RooPoisson::RooPoisson(const RooPoisson& other, const char* name) :
00049 RooAbsPdf(other,name),
00050 x("x",this,other.x),
00051 mean("mean",this,other.mean),
00052 _noRounding(other._noRounding),
00053 _protectNegative(other._protectNegative)
00054 {
00055
00056 }
00057
00058
00059
00060
00061
00062 Double_t RooPoisson::evaluate() const
00063 {
00064
00065
00066 Double_t k = _noRounding ? x : floor(x);
00067 if(_protectNegative && mean<0)
00068 return 1e-3;
00069 return TMath::Poisson(k,mean) ;
00070 }
00071
00072
00073
00074
00075
00076
00077 Int_t RooPoisson::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* ) const
00078 {
00079 if (matchArgs(allVars,analVars,x)) return 1 ;
00080 return 0 ;
00081 }
00082
00083
00084
00085
00086 Double_t RooPoisson::analyticalIntegral(Int_t code, const char* rangeName) const
00087 {
00088 assert(code==1) ;
00089
00090 if(_protectNegative && mean<0)
00091 return exp(-2*mean);
00092
00093
00094
00095 Double_t xmin = x.min(rangeName) ;
00096 Double_t xmax = x.max(rangeName) ;
00097
00098
00099 if (xmin<0) xmin=0 ;
00100
00101 Int_t ixmin = Int_t (xmin) ;
00102 Int_t ixmax = Int_t (xmax)+1 ;
00103
00104 Double_t fracLoBin = 1-(xmin-ixmin) ;
00105 Double_t fracHiBin = 1-(ixmax-xmax) ;
00106
00107 if (!x.hasMax()) {
00108 if (xmin<1e-6) {
00109 return 1 ;
00110 } else {
00111
00112
00113
00114 if(ixmin == 0){
00115 return TMath::Poisson(0, mean)*(xmin-0);
00116 }
00117 Double_t sum(0) ;
00118 sum += TMath::Poisson(0,mean)*fracLoBin ;
00119 sum+= ROOT::Math::poisson_cdf(ixmin-2, mean) - ROOT::Math::poisson_cdf(0,mean) ;
00120 sum += TMath::Poisson(ixmin-1,mean)*fracHiBin ;
00121 return 1-sum ;
00122 }
00123 }
00124
00125 if(ixmin == ixmax-1){
00126 return TMath::Poisson(ixmin, mean)*(xmax-xmin);
00127 }
00128
00129 Double_t sum(0) ;
00130 sum += TMath::Poisson(ixmin,mean)*fracLoBin ;
00131 if (RooNumber::isInfinite(xmax)){
00132 sum+= 1.-ROOT::Math::poisson_cdf(ixmin,mean) ;
00133 } else {
00134 sum+= ROOT::Math::poisson_cdf(ixmax-2, mean) - ROOT::Math::poisson_cdf(ixmin,mean) ;
00135 sum += TMath::Poisson(ixmax-1,mean)*fracHiBin ;
00136 }
00137
00138 return sum ;
00139
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149 Int_t RooPoisson::getGenerator(const RooArgSet& directVars, RooArgSet &generateVars, Bool_t ) const
00150 {
00151
00152
00153 if (matchArgs(directVars,generateVars,x)) return 1 ;
00154 return 0 ;
00155 }
00156
00157
00158
00159
00160 void RooPoisson::generateEvent(Int_t code)
00161 {
00162
00163
00164 assert(code==1) ;
00165 Double_t xgen ;
00166 while(1) {
00167 xgen = RooRandom::randomGenerator()->Poisson(mean);
00168 if (xgen<=x.max() && xgen>=x.min()) {
00169 x = xgen ;
00170 break;
00171 }
00172 }
00173 return;
00174 }
00175
00176