AmpGen 2.1
Loading...
Searching...
No Matches
Generator.h
Go to the documentation of this file.
1#ifndef AMPGEN_GENERATOR_H
2#define AMPGEN_GENERATOR_H
3
4#include "AmpGen/EventList.h"
5#if ENABLE_AVX
7#endif
8#include "AmpGen/simd/utils.h"
9#include "AmpGen/EventType.h"
10#include "AmpGen/PhaseSpace.h"
12#include "AmpGen/Utilities.h"
13#include "AmpGen/ProfileClock.h"
14#include "AmpGen/ProgressBar.h"
15#include "AmpGen/MetaUtils.h"
16
17namespace AmpGen {
18 template <typename phaseSpace_t = PhaseSpace> class Generator {
19#if ENABLE_AVX
20 using eventlist_t = EventListSIMD;
21#else
22 using eventlist_t = EventList;
23#endif
24
25 private:
26 EventType m_eventType;
27 phaseSpace_t m_gps;
28 size_t m_generatorBlock = {5000000};
29 TRandom *m_rnd = {gRandom};
30 bool m_normalise = {true};
31
32 public:
33 template <typename... ARGS> explicit Generator(const ARGS &...args) : m_gps(args...) {
34 m_eventType = m_gps.eventType();
35 if(m_rnd != gRandom) setRandom(m_rnd);
36 }
37
38 phaseSpace_t phsp() { return m_gps; }
39
40 void setRandom(TRandom *rand) {
41 m_rnd = rand;
42 m_gps.setRandom(m_rnd);
43 }
44 void setBlockSize(const size_t &blockSize) { m_generatorBlock = blockSize; }
45 void setNormFlag(const bool &normSetting) { m_normalise = normSetting; }
46
47 void fillEventListPhaseSpace(eventlist_t &events, const size_t &N) {
48 if constexpr(std::is_same<phaseSpace_t, PhaseSpace>::value) {
49 constexpr auto w = utils::size<real_v>::value;
50 for(unsigned i = 0; i != N; ++i) {
51 double *addr = reinterpret_cast<double *>(events.block(i / w)) + i % w;
52 m_gps.fill(addr, w);
53 }
54 } else {
55 auto it = events.begin();
56 while(it != events.end()) {
57 *it = m_gps.makeEvent();
58 ++it;
59 }
60 }
61 }
62 template <typename pdf_t> double getMax(const eventlist_t &events, pdf_t &pdf) const {
63 double max = 0.;
64 for(const auto &evt : events) {
65 auto value = evt.genPdf();
66 if(std::isnan(value)) {
67 ERROR("PDF for event is nan: " << value);
68 evt.print();
69 pdf.debug(evt);
70 } else if(value > max)
71 max = value;
72 }
73 DEBUG("Returning normalisation constant = " << max);
74 return max;
75 }
76
77 template <typename eventList_t, typename pdf_t> void fillEventList(pdf_t &pdf, eventList_t &list, const size_t &N) {
78 if(m_rnd == nullptr) {
79 ERROR("Random generator not set!");
80 return;
81 }
82 double maxProb = m_normalise ? 0 : 1;
83 auto size0 = list.size();
84 double totalGenerated = 0;
85 pdf.reset(true);
86 ProgressBar pb(60, detail::trimmedString(__PRETTY_FUNCTION__));
87 ProfileClock t_phsp, t_eval, t_acceptReject, t_total;
88 std::vector<bool> efficiencyReport(m_generatorBlock, false);
89
90 while(list.size() - size0 < N) {
91 eventlist_t mc(m_eventType);
92 mc.resize(m_generatorBlock);
93 t_phsp.start();
94 fillEventListPhaseSpace(mc, m_generatorBlock);
95 t_phsp.stop();
96 t_eval.start();
97 pdf.setEvents(mc);
98 pdf.prepare();
99 auto previousSize = list.size();
100#ifdef _OPENMP
101#pragma omp parallel for
102#endif
103 for(size_t block = 0; block < mc.nBlocks(); ++block) { mc.setGenPDF(block, pdf(mc.block(block), block) / mc.genPDF(block)); }
104 maxProb = maxProb == 0 ? 1.5 * getMax(mc, pdf) : maxProb;
105 DEBUG("Norm: " << maxProb);
106 // if constexpr ( std::is_same<phaseSpace_t, TreePhaseSpace>::value ) m_gps.recalculate_weights(mc);
107
108 t_eval.stop();
109 t_acceptReject.start();
110 totalGenerated += mc.size();
111 for(const auto &event : mc) {
112 if(event.genPdf() > maxProb) {
113 std::cout << std::endl;
114 WARNING("PDF value exceeds norm value: " << event.genPdf() << " > " << maxProb);
115 event.print();
116 }
117 if(event.genPdf() > maxProb * m_rnd->Rndm()) {
118 list.push_back(event);
119 list.rbegin()->setGenPdf(pdf(event));
120 efficiencyReport[event.index()] = true;
121 } else
122 efficiencyReport[event.index()] = false;
123 if(list.size() - size0 == N) break;
124 }
126 t_acceptReject.stop();
127 double efficiency = 100. * (list.size() - previousSize) / (double)m_generatorBlock;
128 pb.print(double(list.size()) / double(N),
129 " ε[gen] = " + mysprintf("%.4f", efficiency) + "% , " + std::to_string(int(t_total.count() / 1000.)) + " seconds");
130 if(list.size() == previousSize) {
131 ERROR("No events generated, PDF: " << type_string<pdf_t>() << " is likely to be malformed");
132 break;
133 }
134 }
135 pb.finish();
136 t_total.stop();
137 INFO("Generated " << N << " events in " << t_total << " ms");
138 INFO("Generating phase space : " << t_phsp << " ms");
139 INFO("Evaluating PDF : " << t_eval << " ms");
140 INFO("Accept/reject : " << t_acceptReject << " ms");
141 INFO("Efficiency = " << double(N) * 100. / totalGenerated << " %");
142 }
143 template <typename pdf_t, typename = typename std::enable_if<!std::is_integral<pdf_t>::value>::type> EventList generate(pdf_t &pdf, const size_t &nEvents) {
144 eventlist_t evts(m_eventType);
145 fillEventList(pdf, evts, nEvents);
146 EventList output(m_eventType);
147 for(const auto &event : evts) output.emplace_back(event);
148 return output;
149 }
150 EventList generate(const size_t &nEvents) {
151 eventlist_t evts(m_eventType);
152 evts.resize(nEvents);
153 fillEventListPhaseSpace(evts, nEvents);
154 EventList output(m_eventType);
155 for(const auto &event : evts) output.emplace_back(event);
156 return output;
157 }
158 };
159
160 template <class FCN> class PDFWrapper {
161 public:
162 void prepare() {};
163 void setEvents(AmpGen::EventList & /*evts*/) {};
164 double prob_unnormalised(const AmpGen::Event &evt) const { return m_fcn(evt); }
165 explicit PDFWrapper(const FCN &fcn) : m_fcn(fcn) {}
166 size_t size() const { return 0; }
167 void reset(const bool & /*flag*/ = false) {};
168
169 private:
170 FCN m_fcn;
171 };
172
173 template <class FCN> PDFWrapper<FCN> make_pdf(const FCN &fcn) { return PDFWrapper<FCN>(fcn); }
174
179 extern "C" void python__generate(const char *eventType, double *out, const unsigned int size);
180} // namespace AmpGen
181#endif
Encapsulates the final state particles of a single event.
Definition Event.h:19
double * block(const unsigned pos)
Definition EventList.h:69
std::vector< Event >::iterator begin()
Definition EventList.h:55
void setGenPDF(const unsigned int &pos, const double &g)
Definition EventList.h:92
void emplace_back(const Event &evt)
std::vector< Event >::iterator end()
Definition EventList.h:56
size_t nBlocks() const
Definition EventList.h:67
void resize(const size_t &size)
size_t size() const
Definition EventList.h:65
real_t genPDF(const size_t &pos) const
Definition EventList.h:71
Deals with final state configuration of events, specifically dealing with the ordering of particles i...
Definition EventType.h:22
void fillEventList(pdf_t &pdf, eventList_t &list, const size_t &N)
Definition Generator.h:77
EventList generate(const size_t &nEvents)
Definition Generator.h:150
EventList generate(pdf_t &pdf, const size_t &nEvents)
Definition Generator.h:143
void setBlockSize(const size_t &blockSize)
Definition Generator.h:44
void setRandom(TRandom *rand)
Definition Generator.h:40
void fillEventListPhaseSpace(eventlist_t &events, const size_t &N)
Definition Generator.h:47
Generator(const ARGS &...args)
Definition Generator.h:33
phaseSpace_t phsp()
Definition Generator.h:38
double getMax(const eventlist_t &events, pdf_t &pdf) const
Definition Generator.h:62
void setNormFlag(const bool &normSetting)
Definition Generator.h:45
void setEvents(AmpGen::EventList &)
Definition Generator.h:163
PDFWrapper(const FCN &fcn)
Definition Generator.h:165
double prob_unnormalised(const AmpGen::Event &evt) const
Definition Generator.h:164
void reset(const bool &=false)
Definition Generator.h:167
size_t size() const
Definition Generator.h:166
void print(const double &percentage, const std::string &message="")
#define ERROR(X)
Used for printing errors messages, and will always be printed.
Definition MsgService.h:85
#define INFO(X)
Used for printing information messages, and will always be printed.
Definition MsgService.h:81
#define WARNING(X)
Used for printing warning messages, can be switched off using WARNINGLEVEL.
Definition MsgService.h:103
#define DEBUG(X)
Used for printing verbose debugging messages, only if DEBUGLEVEL is defined.
Definition MsgService.h:69
std::string trimmedString(std::string thing, const unsigned int &length=FCNNAMELENGTH)
Definition MsgService.h:25
void python__generate(const char *eventType, double *out, const unsigned int size)
@function PyGenerate
std::string type_string()
Utility classes for compile-time metaprogramming, such as identifying the types of arguments for gene...
Definition MetaUtils.h:17
std::string mysprintf(const std::string &format, ARGS &&...args)
Definition Utilities.h:91
PDFWrapper< FCN > make_pdf(const FCN &fcn)
Definition Generator.h:173
double count() const
static constexpr unsigned value
Definition utils.h:52