MINT2
DalitzMCIntegrator.cpp
Go to the documentation of this file.
1 // author: Jonas Rademacker (Jonas.Rademacker@bristol.ac.uk)
2 // status: Mon 9 Feb 2009 19:18:02 GMT
4 
5 #include "TRandom.h"
6 #include "Mint/IWeightedEvent.h"
7 
8 #include <iostream>
9 #include <ctime>
10 
11 using namespace std;
12 using namespace MINT;
13 
14 
15 /*
16  Warning: This piece of code is much slower and less accurate than
17  "FastAmplitudeIntegrator", as used by DalitzPdfBaseFastInteg.
18  Still, the code here is good for x-checks.
19  */
21  , IReturnRealForEvent<IDalitzEvent>* weightFunction
22  , IEventGenerator<IDalitzEvent> * generator
23  , TRandom* rnd
24  , double precision
25  )
26  : _Ncalls(0)
27  , _sumT(0)
28  , _mean(0)
29  , _variance(0)
30  , _numEvents(0)
31  , _weightSum(0)
32  , _initialised(0)
33  , _iw(weightFunction)
34 {
35  initialise(pattern, weightFunction, generator, rnd, precision);
36 }
38  : _Ncalls(0)
39  , _sumT(0)
40  , _mean(0)
41  , _variance(0)
42  , _numEvents(0)
43  , _weightSum(0)
44  , _initialised(0)
45  , _iw(0)
46 {
47 }
48 
50  , IReturnRealForEvent<IDalitzEvent>* weightFunction
51  , IEventGenerator<IDalitzEvent> * generator
52  , TRandom* rnd
53  , double precision
54  ){
55  _Ncalls = 0;
56  _sumT = 0.0;
57  _pat = pattern;
58  _w = weightFunction;
59  _rnd = rnd;
60  _precision = precision;
61 
62  _generator = generator;
63 
64  _iw.setWeight(weightFunction);
65 
66  _initialised = true;
67 
68 
69  generateEnoughEvents();// must come last.
70 
71  return _initialised;
72 }
74  weightFunction
75  ){
76  _w = weightFunction;
77  _iw.setWeight(weightFunction);
78  return true;
79 }
80 
82  if(! _initialised){
83  cout << " DalitzMCIntegrator::updateEventSet "
84  << " need to know pattern first." << endl;
85  return 0;
86 
87  }
88  int missingEvents = Nevents - _eventPtrList.size();
89  cout << "missing events: " << missingEvents
90  << " = " << Nevents
91  << " - " << _eventPtrList.size()
92  << endl;
93  if(missingEvents > 0){
94  addEvents(missingEvents);
95  }
96  return _eventPtrList.size();
97 }
98 
100  bool dbThis=false;
101  if(Nevents <= 0) return _eventPtrList.size();
102 
103  if(0 == _generator){
105  return _eventPtrList.size();
106  }
107 
108  int N_success = 0;
109  for(int i=0; i < Nevents*1000 && N_success < Nevents; i++){
110  //counted_ptr<IDalitzEvent> ptr(_generator->newEvent());
112  if(dbThis) cout << "got event with ptr: " << ptr << endl;
113  if(0 != ptr){
114  _eventPtrList.push_back(ptr); // change event list to list of counted ptrs
115  N_success++;
116  int printEvery = 1000;
117  if(N_success > 10000) printEvery=10000;
118  bool printout = (N_success%printEvery == 0);
119  if(printout){
120  cout << " DalitzMCIntegrator::addEvents: added " << N_success
121  << " th event" << endl;
122  }
123  }
124  }
125  cout << " added " << Nevents << " _eventList.size() "
126  << _eventPtrList.size() << endl;
127  return _eventPtrList.size();
128 }
129 
131  /*
132  if(! _initialised){
133  cout << " DalitzMCIntegrator::evaluateSum "
134  << " need to know pattern first." << endl;
135  return 0;
136  }
137 
138  if(_eventPtrList.empty()){
139  cout << "WARNING in DalitzMCIntegrator::evaluateSum()"
140  << " no events!" << endl;
141  _mean = _variance = 0;
142  return 0;
143  }
144  */
145 
146  double sum = 0;
147  double sumsq = 0;
148  double ws =0;
149  _weightSum = 0;
150  //int printEveryNEvents = (_eventPtrList.size()/4);
151  //if(printEveryNEvents < 1) printEveryNEvents = 1;
152 
153  //time_t tstart = time(0);
154 
155  //#pragma omp parallel for reduction(+:sum, sumsq, ws);
156  for(unsigned int N=0; N < _eventPtrList.size(); N++){
157  //DalitzEvent thisEvt(_eventPtrList[N]);
158  /*
159  double ps = thisEvt.phaseSpace();
160  if(ps <= 0.0){
161  cout << "WARNING in DalitzMCIntegrator::evaluateSum()"
162  << " event with phase space = " << ps << endl;
163  continue; // should not happen.
164  }
165  */
167  double val = _iw.RealVal(_eventPtrList.getEventRef(N)); // _w->RealVal() * weight;
168 
169  sum += val;
170  sumsq += val*val;
171 
172  ws += weight;// /ps;
173 
174  /*
175  if(N%printEveryNEvents == 0){
176  cout << "DalitzMCIntegrator::evaluateSum() N = " << N
177  << " val = " << val
178  << " _w->RealVal(thisEvt)*weight " << _w->RealVal(thisEvt)*weight
179  << endl;
180  }
181  */
182  }
183 
184  _weightSum = ws;
185 
186  double fN = (double) _eventPtrList.size();
187  _mean = sum / fN;
188  double meanOfSq = sumsq / fN;
189  _variance = (meanOfSq - _mean * _mean)/fN;
190 
191  if(_weightSum > 0){
192  double sf = fN/_weightSum;
193  _mean *= sf;
194  _variance *= sf*sf;
195  }
196 
197  /*
198  double delT = difftime(time(0), tstart);
199  double sigma = -9999;
200  if(_variance >= 0) sigma = sqrt(_variance);
201  double actualPrecision = -9999;
202  if(_mean != 0 && sigma > 0) actualPrecision = sigma/_mean;
203  cout << " DalitzMCIntegrator::evaluateSum() for " << N << " events:"
204  << "\n > getting: " << _mean << " +/- " << sigma
205  << "\n > precision: requested: " << _precision*100
206  << "%, actual: " << actualPrecision*100 << "%"
207  << "\n > This took " << delT << " s."
208  << endl;
209  */
210  return _mean;
211 }
212 
215  evaluateSum();
216 
217  double safetyFactor = 1.15;
218  double maxVariance = _precision*_precision * _mean*_mean;
219  _numEvents = _eventPtrList.size() * ( ((int)(_variance*safetyFactor/maxVariance)) + 1);
220  cout << " DalitzMCIntegrator::determineNumEvents():"
221  << "\n > mean: " << _mean << ", rms " << sqrt(_variance)
222  << "\n > currently, our precision is " << sqrt(_variance)/_mean
223  << "\n > to achieve requested pecision of " << _precision << ","
224  << "\n > I think we'll need " << (_variance*safetyFactor/maxVariance)
225  << " times that, i.e. " << _numEvents << " events" << endl;
226 
227  return _numEvents;
228 }
229 
231  addEvents(300000);
232  //updateEventSet(_minEvents);
233  //determineNumEvents();
234  //updateEventSet(_numEvents);
235  return _eventPtrList.size();
236 }
237 
239  _Ncalls++;
240 
241  int printEvery = 10;
242  if(_Ncalls > 100) printEvery = 100;
243  if(_Ncalls > 1000) printEvery = 1000;
244  if(_Ncalls > 10000) printEvery = 10000;
245  if(_Ncalls > 100000) printEvery = 100000;
246  bool printout = _Ncalls < 10 || (0 == _Ncalls%printEvery);
247 
248  time_t tstart = time(0);
249  evaluateSum();
250  double delT = difftime(time(0), tstart);
251 
252  _sumT += delT;
253 
254  if(_Ncalls > 0 && printout){
255  cout << "DalitzMCIntegrator::getVal, " << _Ncalls << "th call: Returning " << _mean
256  << " this call took " << delT << " s,"
257  << " average call " << _sumT/_Ncalls << " s, "
258  << " for " << _eventPtrList.size() << " events."
259  << endl;
260  }
261 
262  return _mean;
263 }
264 
266 
269  : _externalPdf(externalPdf)
270 {
271  cout << "after construction, externalPdf = " << _externalPdf << endl;
272 }
273 
276  double den = evt.getGeneratorPdfRelativeToPhaseSpace();
277  double weight = evt.getWeight();
278  if(0 != den) weight /= den;
279  double val = _externalPdf->RealVal(evt) * weight;
280 
281  return val;
282 }
283 
286  _externalPdf = pdf;
287 }
288 
289 //
MINT::IEventGenerator< IDalitzEvent > * _generator
virtual const EVENT_TYPE & getEventRef(unsigned int i) const
Definition: EventPtrList.h:49
static const int _minEvents
virtual double getWeight() const =0
void push_back(const T &c)
integrationWeight(MINT::IReturnRealForEvent< IDalitzEvent > *externalPdf)
int generatePhaseSpaceEvents(int NumEvents, const DalitzEventPattern &pat, TRandom *rnd=0)
bool initialise(const DalitzEventPattern &pattern, MINT::IReturnRealForEvent< IDalitzEvent > *weightFunction=0, MINT::IEventGenerator< IDalitzEvent > *eventGenerator=0, TRandom *rnd=gRandom, double precision=1.e-2)
MINT::IReturnRealForEvent< IDalitzEvent > * _w
virtual unsigned int size() const
Definition: EventPtrList.h:76
virtual double getWeight() const
virtual counted_ptr< RETURN_TYPE > newEvent()=0
virtual double getGeneratorPdfRelativeToPhaseSpace() const
MINT::IReturnRealForEvent< IDalitzEvent > * _externalPdf
virtual double getGeneratorPdfRelativeToPhaseSpace() const =0
integrationWeight _iw
int addEvents(int Nevents)
DalitzEventPattern _pat
DalitzEventPtrList _eventPtrList
int updateEventSet(int Nevents)
void setWeight(MINT::IReturnRealForEvent< IDalitzEvent > *pdf)
virtual void doFinalStats(MINT::Minimiser *mini=0)
bool resetIntegrand(MINT::IReturnRealForEvent< IDalitzEvent > *weightFunction=0)