cepgen is hosted by Hepforge, IPPP Durham
CepGen 1.2.5
Central exclusive processes event generator
Loading...
Searching...
No Matches
FoamIntegrator.cpp
Go to the documentation of this file.
1/*
2 * CepGen: a central exclusive processes event generator
3 * Copyright (C) 2020-2024 Laurent Forthomme
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <TFoam.h>
20#include <TFoamIntegrand.h>
21
29
30namespace cepgen {
33 class FoamIntegrator final : public Integrator, public TFoamIntegrand {
34 public:
35 explicit FoamIntegrator(const ParametersList& params) : Integrator(params) {}
36
38 auto desc = Integrator::description();
39 desc.setDescription("FOAM general purpose MC integrator");
40 desc.add("randomGenerator", RandomGeneratorFactory::get().describeParameters("root"));
41 desc.add<int>("nCalls", 100'000).setDescription("number of calls for the cell evaluation");
42 desc.add<int>("nCells", 1000);
43 desc.add<int>("nSampl", 200);
44 desc.add<int>("nBin", 8);
45 desc.add<int>("EvPerBin", 25);
46 desc.add<int>("verbose", 0).setDescription("Verbosity level");
47 return desc;
48 }
49
50 Value integrate(Integrand& integrand) override {
51 integrand_ = &integrand;
52 std::unique_ptr<TFoam> foam(new TFoam("Foam"));
53 CG_DEBUG("Integrator:integrate") << "FOAM integrator built\n\t"
54 << "Version: " << foam->GetVersion() << ".";
55 foam->SetPseRan(rnd_gen_->engine<TRandom>());
56 foam->SetnCells(steer<int>("nCells"));
57 foam->SetnSampl(steer<int>("nSampl"));
58 foam->SetnBin(steer<int>("nBin"));
59 foam->SetEvPerBin(steer<int>("EvPerBin"));
60 foam->SetChat(std::max(verbosity_, 0));
61 foam->SetRho(this);
62 foam->SetkDim(integrand_->size());
63 Integrator::checkLimits(*integrand_);
64 coord_.resize(integrand_->size());
65 foam->Initialize();
66 std::unique_ptr<utils::ProcessVariablesAnalyser> analyser;
67 if (integrand.hasProcess())
68 analyser.reset(new utils::ProcessVariablesAnalyser(dynamic_cast<ProcessIntegrand&>(integrand).process(),
70 const auto num_calls = steer<int>("nCalls");
71 for (int i = 0; i < num_calls; ++i) {
72 foam->MakeEvent();
73 if (analyser)
74 analyser->feed(foam->GetMCwt() / num_calls);
75 }
76 if (analyser)
77 analyser->analyse();
78 //--- launch integration
79 double norm, err;
80 foam->Finalize(norm, err);
81
82 double result, abs_error;
83 foam->GetIntegMC(result, abs_error);
84 for (const auto& lim : limits_) {
85 result *= lim.range();
86 abs_error *= lim.range();
87 }
88 const auto res = Value{result, abs_error};
89
90 CG_DEBUG("FoamIntegrator").log([&](auto& log) {
91 double eps = 5.e-4, avewt, wtmax, sigma;
92 foam->GetWtParams(eps, avewt, wtmax, sigma);
93 const double ncalls = foam->GetnCalls();
94 const double effic = wtmax > 0 ? avewt / wtmax : 0.;
95 log << "Result: " << res << "\n\t"
96 << "Relative error: " << res.relativeUncertainty() * 100. << "%\n\t"
97 << "Dispersion/<wt> = " << sigma << ", <wt> = " << avewt << ", <wt>/wtmax = " << effic << ",\n\t"
98 << " for epsilon = " << eps << "\n\t"
99 << " nCalls (initialisation only)= " << ncalls << ".";
100 });
101 return res;
102 }
103
105 inline double Density(int ndim, double* x) override {
106 if (!integrand_)
107 throw CG_FATAL("FoamDensity") << "Integrand object not yet initialised!";
108 for (int i = 0; i < ndim; ++i)
109 coord_[i] = limits_.at(i).x(x[i]);
110 return integrand_->eval(coord_);
111 }
112
113 private:
114 Integrand* integrand_{nullptr};
115 std::vector<double> coord_;
116 };
117} // namespace cepgen
118REGISTER_INTEGRATOR("Foam", FoamIntegrator);
#define CG_FATAL(mod)
Definition Exception.h:61
#define REGISTER_INTEGRATOR(name, obj)
Add a generic process definition to the list of handled processes.
#define CG_DEBUG(mod)
Definition Message.h:220
Foam general-purpose integration algorithm as developed by S. Jadach (Institute of Nuclear Physics,...
FoamIntegrator(const ParametersList &params)
Value integrate(Integrand &integrand) override
Perform the multidimensional Monte Carlo integration.
static ParametersDescription description()
double Density(int ndim, double *x) override
Compute the weight for a given phase space point.
An integrand wrapper placeholder.
Definition Integrand.h:27
virtual bool hasProcess() const
Does this integrand also contain a process object?
Definition Integrand.h:37
virtual double eval(const std::vector< double > &)=0
Compute the integrand for a given coordinates set.
virtual size_t size() const =0
Phase space dimension.
Monte-Carlo integration algorithm.
Definition Integrator.h:28
void checkLimits(const Integrand &)
Ensure the integration bounds are properly set.
int verbosity_
Integrator verbosity.
Definition Integrator.h:57
std::vector< Limits > limits_
List of per-variable integration limits.
Definition Integrator.h:58
const std::unique_ptr< utils::RandomGenerator > rnd_gen_
Definition Integrator.h:56
static ParametersDescription description()
A description object for parameters collection.
Wrapper to the function to be integrated.
A scalar value with its uncertainty.
Definition Value.h:26
Common namespace for this Monte Carlo generator.