29 class FoamDistribution :
public TFoamIntegrand {
33 FoamDistribution(
const ROOT::Math::IMultiGenFunction & f,
const ROOT::Fit::DataRange & range) :
35 fX(std::vector<double>(f.NDim() ) ),
36 fMinX(std::vector<double>(f.NDim() ) ),
37 fDeltaX(std::vector<double>(f.NDim() ) )
39 assert(f.NDim() == range.NDim() );
40 std::vector<double> xmax(f.NDim() );
41 for (
unsigned int i = 0; i < range.NDim(); ++i) {
42 if (range.Size(i) == 0)
43 Error(
"FoamDistribution",
"Range is not set for coordinate dim %d",i);
44 else if (range.Size(i)>1)
45 Warning(
"FoamDistribution",
"Using only first range in coordinate dim %d",i);
47 std::pair<double,double> r = range(i);
49 fDeltaX[i] = r.second - r.first;
54 virtual double Density(
int ndim,
double * x) {
55 assert(ndim == (
int) fFunc.NDim() );
56 for (
int i = 0; i < ndim; ++i)
57 fX[i] = fMinX[i] + x[i] * fDeltaX[i];
59 return (fFunc)(&fX[0]);
62 double MinX(
unsigned int i) {
return fMinX[i]; }
63 double DeltaX(
unsigned int i) {
return fDeltaX[i]; }
67 const ROOT::Math::IMultiGenFunction & fFunc;
68 std::vector<double> fX;
69 std::vector<double> fMinX;
70 std::vector<double> fDeltaX;
79 ClassImp(TFoamSampler);
82 TFoamSampler::TFoamSampler() : ROOT::Math::DistSampler(),
88 fFoam(new TFoam(
"FOAM") ),
92 TFoamSampler::~TFoamSampler() {
95 if (fFoamDist)
delete fFoamDist;
98 bool TFoamSampler::Init(
const char *) {
101 ROOT::Math::DistSamplerOptions opt(0);
102 ROOT::Math::IOptions * foamOpt = ROOT::Math::DistSamplerOptions::FindDefault(
"Foam");
103 if (foamOpt) opt.SetExtraOptions(*foamOpt);
107 bool TFoamSampler::Init(
const ROOT::Math::DistSamplerOptions & opt) {
109 assert (fFoam != 0 );
111 Error(
"TFoamSampler::Init",
"Distribution function has not been set ! Need to call SetFunction first.");
116 fFoam->SetkDim(NDim() );
119 if (!GetRandom()) SetRandom(gRandom);
122 if (fFoamDist)
delete fFoamDist;
123 fFoamDist =
new FoamDistribution(ParentPdf(),PdfRange());
125 fFoam->SetRho(fFoamDist);
127 fFoam->SetChat(opt.PrintLevel());
130 ROOT::Math::IOptions * fopt = opt.ExtraOptions();
134 if (fopt->GetIntValue(
"nCells", nval) ) fFoam->SetnCells(nval);
135 if (fopt->GetIntValue(
"nCell1D", nval) && NDim() ==1) fFoam->SetnCells(nval);
136 if (fopt->GetIntValue(
"nCellND", nval) && NDim() >1) fFoam->SetnCells(nval);
137 if (fopt->GetIntValue(
"nCell2D", nval) && NDim() ==2) fFoam->SetnCells(nval);
138 if (fopt->GetIntValue(
"nCell3D", nval) && NDim() ==3) fFoam->SetnCells(nval);
140 if (fopt->GetIntValue(
"nSample", nval) ) fFoam->SetnSampl(nval);
141 if (fopt->GetIntValue(
"nBin", nval) ) fFoam->SetnBin(nval);
142 if (fopt->GetIntValue(
"OptDrive",nval) ) fFoam->SetOptDrive(nval);
143 if (fopt->GetIntValue(
"OptRej",nval) ) fFoam->SetOptRej(nval);
144 if (fopt->GetRealValue(
"MaxWtRej",fval) ) fFoam->SetMaxWtRej(fval);
147 if (fopt->GetIntValue(
"chatLevel", nval) ) fFoam->SetChat(nval);
156 void TFoamSampler::SetFunction(TF1 * pdf) {
158 SetFunction<TF1>(*pdf, pdf->GetNdim());
161 void TFoamSampler::SetRandom(TRandom * r) {
166 void TFoamSampler::SetSeed(
unsigned int seed) {
168 TRandom * r = fFoam->GetPseRan();
169 if (r) r->SetSeed(seed);
172 TRandom * TFoamSampler::GetRandom() {
174 return fFoam->GetPseRan();
182 bool TFoamSampler::Sample(
double * x) {
188 for (
unsigned int i = 0; i < NDim(); ++i)
189 x[i] = ( (FoamDistribution*)fFoamDist)->MinX(i) + ( ( (FoamDistribution*) fFoamDist)->DeltaX(i))*x[i];
195 bool TFoamSampler::SampleBin(
double prob,
double & value,
double *error) {
198 TRandom * r = GetRandom();
199 if (!r)
return false;
200 value = r->Poisson(prob);
201 if (error) *error = std::sqrt(value);