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