MINT2
FastAmplitudeIntegrator.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 #include "Mint/FitAmpSum.h"
5 #include "Mint/IDalitzEvent.h"
6 #include "Mint/Minimiser.h"
7 
8 #include "TRandom.h"
9 #include "TRandom3.h"
10 
11 #include <iostream>
12 #include <sstream>
13 
14 #include <ctime>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 
18 using namespace std;
19 using namespace MINT;
20 
24  //, counted_ptr<IGetDalitzEvent> weight
25  , IEventGenerator<IDalitzEvent> * generator
26  , TRandom* rnd
27  , double precision
28  )
29  : _db(false)
30 {
31  // initialise(pattern, amps, weight, generator, rnd, precision);
32  initialise(pattern, amps, generator, rnd, precision);
33 }
37  , const std::string& fname
38  )
39  : _db(false)
40 {
41  // initialise(pattern, amps, weight, generator, rnd, precision);
42  initialiseFromFile(pattern, amps, fname);
43 }
44 
46  : _initialised(0), _db(false)
47 {
48 }
49 
50 
54  //, counted_ptr<IGetDalitzEvent> weight
55  , IEventGenerator<IDalitzEvent> * generator
56  , TRandom* rnd
57  , double precision
58  ){
59  bool sc=true;
60  sc &= setValues(pattern, amps, generator, rnd, precision);
61  sc &= generateEnoughEvents();
62  return sc;
63 }
64 
68  , const std::string& commaSeparatedList
69  ){
70  bool sc = setValues(pattern, amps, 0, 0, 1.e-10);
71  if(! sc) return false;
72  sc &= _integCalc->retrieve(commaSeparatedList);
73  return sc;
74 }
75 
76 /* the idea: if the integrator hasn't got
77  enough events in it, I generate some more
78  the risk: if I run the programme several times,
79  I could be topping up the list each time with
80  the same events from fromFileIntegrator.
81  Therefore the "_generator->ensureFreshEvents()"
82 */
84 ::initialise(const std::string& commaSeparatedList
85  , const DalitzEventPattern& pattern
87  , IEventGenerator<IDalitzEvent> * generator
88  , TRandom* rnd
89  , double precision
90  ){
91  // with file and top up
92  bool sc=true;
93  sc &= setValues(pattern, amps, generator, rnd, precision);
94  if(! sc) return false;
95  std::string firstDir;
96  std::stringstream is(commaSeparatedList);
97  getline(is, firstDir, ',');
98 
99  struct stat buf;
100  // if(firstDir != "" && access(firstDir.c_str(), 0) == 0){
101  if(firstDir != "" && stat(firstDir.c_str(), &buf) == 0){
102  // it exists, we can retrieve it
103  sc &= _integCalc->retrieve(commaSeparatedList);
104  // if we add events to this, we need to avoid
105  // duplication. The below will refuse to re-use
106  // events read from a file, and will randomise
107  // the random seed:
108  this->ensureFreshEvents();
109  }
110  sc &= generateEnoughEvents();
111  return sc;
112 }
113 
115  int totalEvents = _numEvents + other._numEvents;
116  if(totalEvents > 0){
117  _mean = (_numEvents * _mean + other._numEvents * other._mean)/totalEvents;
118  }
119  _numEvents = totalEvents;
120  _Ncalls += other._Ncalls;
121  if(0 != this->_integCalc){
122  _integCalc->add(other._integCalc);
123  }else{
124  if(0 != other._integCalc){
126  _integCalc = nL;
127  }
128  }
129  if(0 != this->_integCalc_copyForDebug){
131  }else{
132  if(0 != other._integCalc_copyForDebug){
134  nLc(new IntegCalculator(*(other._integCalc_copyForDebug)));
136  }
137  }
138  _initialised |= other._initialised;
139  _db |= other._db;
140 
141  // other quantities we take over if they aren't defined, here:
142  if(0 == _amps) _amps = other._amps;
143  if(0 == _rnd) _rnd = other._rnd;
144  if(0 == _localRnd) _localRnd = other._localRnd;
145  if(_precision <= 0.0) _precision = other._precision;
146 
147  return true;
148 }
149 
151  _rnd = makeNewRnd(time(0));
152  if(0 != _generator){
154  }
155  return true;
156 }
157 
159  if(seed < -9998) seed = time(0);
160  cout << "FastAmplitudeIntegrator::makeNewRnd with seed " << seed << endl;
161  counted_ptr<TRandom> lr(new TRandom3(seed));
162  _localRnd = lr;
163  _rnd = lr.get();
164  return _rnd;
165 }
169  //, counted_ptr<IGetDalitzEvent> weight
170  , IEventGenerator<IDalitzEvent> * generator
171  , TRandom* rnd
172  , double precision
173  ){
174  bool dbThis=false;
175  _pat = pattern;
176  _amps = amps;
177  //_weight = weight;
178  if(0 != rnd){
179  _rnd = rnd;
180  }else{
181  _rnd = makeNewRnd(time(0));
182  }
183  _precision = precision;
184 
185  _generator = generator;
186 
187  _integCalc = amps->makeIntegCalculator();
188  if(dbThis){
189  cout << "FastAmplitudeIntegrator::setValues: Have _integCalc ptr " << _integCalc
190  << ", now printing it." << endl;
191  _integCalc->print();
192  }
193 
194  if(_db) _integCalc_copyForDebug = amps->makeIntegCalculator();
195 
196  if(0 == _integCalc){
197  cout << "ERROR in FastAmplitudeIntegrator::initialise"
198  << " amps->makeIntegCalculator()"
199  << " return NULL pointer!" << endl;
200  cout << "\t This will go wrong." << endl;
201  }
202  _Ncalls=0;
203 
204  _initialised = true;
205  return _initialised;
206 }
207 
209  if(! _initialised){
210  cout << " FastAmplitudeIntegrator::updateEventSet "
211  << " need to know pattern first." << endl;
212  return 0;
213  }
214  int missingEvents = Nevents - _integCalc->numEvents();
215 
216  if(missingEvents > 0){
217  cout << "missing events: " << missingEvents
218  << " = " << Nevents
219  << " - " << _integCalc->numEvents()
220  << endl;
221  addEvents(missingEvents);
222  }else{
223  cout << "want " << Nevents
224  << ", have " << _integCalc->numEvents()
225  << ", so no more events missing." << endl;
226  }
227  return _integCalc->numEvents();
228 }
229 
231  return 1;
232  // (not in use, but left as a hook should the need arise)
233  /*
234  if(0 == _weight) return 1;
235 
236  _weight->setEvent(evtPtr);
237  double wght = _weight->RealVal();
238  _weight->resetEventRecord();
239  return wght;
240  */
241 }
243  bool dbThis=false;
244  if(! _initialised){
245  cout << " FastAmplitudeIntegrator::addEvents "
246  << " need to get initialised first." << endl;
247  return 0;
248  }
249  if(dbThis) cout << "FastAmplitudeIntegrator::addEvents "
250  << " got called " << endl;
251  if(Nevents <= 0) return _integCalc->numEvents();
252 
253  if(0 == _generator){
254  cout << "FastAmplitudeIntegrator::addEvents "
255  << " adding flat events. " << endl;
256  for(int i=0; i < Nevents; i++){
257  DalitzEvent evt(_pat, _rnd);
258  _integCalc->addEvent(&evt, weight(&evt));
259  }
260  }else{
261  int N_success = 0;
262  unsigned long int maxTries = (unsigned long int) Nevents * 1000;
263  // dealing with possible overflow:
264  if(maxTries < (unsigned long int) Nevents) maxTries = Nevents * 100;
265  if(maxTries < (unsigned long int) Nevents) maxTries = Nevents * 10;
266  if(maxTries < (unsigned long int) Nevents) maxTries = Nevents;
267 
268  time_t startTime = time(0);
269  for(unsigned long int i=0; i < maxTries && N_success < Nevents; i++){
271  if(dbThis) cout << "got event with ptr: " << ptr << endl;
272  if(0 == ptr){
273  if(_generator->exhausted()){
274  cout << "ERROR in FastAmplitudeIntegrator::addEvents"
275  << "\n\t Generator exhausted, cannot generate more events."
276  << endl;
277  break;
278  }
279  }else{
280  _integCalc->addEvent(ptr, weight(ptr.get()));
281  N_success++;
282  int printEvery = 1000;
283  if(N_success > 1000) printEvery = 50000;
284  if(N_success > 100000) printEvery = 100000;
285  bool printout = (N_success%printEvery == 0);
286  if(dbThis) printout |= (N_success < 20);
287 
288  if(printout){
289  cout << " FastAmplitudeIntegrator::addEvents: added " << N_success
290  << " th event";
291  evaluateSum();
292  double v= variance();
293  double sigma = -9999;
294  if(v > 0) sigma = sqrt(v);
295  cout << "\t integ= " << _mean << " +/- " << sigma;
296  cout << "\t("
297  << MINT::stringtime(difftime(time(0), startTime))
298  << ")";
299  cout << endl;
300  }
301  }
302  }
303  }
304  if(_integCalc->numEvents() < Nevents){
305  cout << "ERROR in FastAmplitudeIntegrator::addEvents"
306  << "\n\t> I was supposed to add " << Nevents << " events,"
307  << "\n\t> but now the total list size is only "
308  << _integCalc->numEvents()
309  << endl;
310  }else{
311  cout << " added " << Nevents << " _integCalc->numEvents "
312  << _integCalc->numEvents() << endl;
313 
314  }
315  return _integCalc->numEvents();
316 }
317 
319  if(! _initialised){
320  cout << " FastAmplitudeIntegrator::variance "
321  << " need to get initialised first." << endl;
322  return 0;
323  }
324  return _integCalc->variance();
325 }
327  if(! _initialised){
328  cout << " FastAmplitudeIntegrator::evaluateSum "
329  << " need to get initialised first." << endl;
330  return 0;
331  }
332 
333  time_t tstart = time(0);
334  _Ncalls++;
335 
337  double v = variance();
338  double sigma = -9999;
339  if(v >= 0) sigma = sqrt(v);
340  double actualPrecision = -9999;
341  if(_mean != 0 && sigma > 0) actualPrecision = sigma/_mean;
342 
343  double delT = difftime(time(0), tstart);
344 
345  int printEvery = 100;
346  if(_Ncalls > 1000) printEvery = 1000;
347  if(_Ncalls > 10000) printEvery = 10000;
348  if(_Ncalls > 100000) printEvery = 100000;
349  bool printout = _Ncalls < 3 || (0 == _Ncalls%printEvery);
350 
351  if(printout || _db){
352  cout << " FastAmplitudeIntegrator::evaluateSum() for "
353  << _integCalc->numEvents() << " events, "
354  << _Ncalls << " th call:"
355  << "\n\t> getting: " << _mean << " +/- " << sigma
356  << "\n\t> precision: requested: " << _precision*100
357  << "%, actual: " << actualPrecision*100 << "%"
358  << "\n\t> This took " << delT << " s."
359  << endl;
360  if(_db){
361  cout << "checking save and read-back:" << endl;
362  _integCalc->save("checkSaveAndReadBack");
363  _integCalc_copyForDebug->retrieve("checkSaveAndReadBack");
364  cout << " copy values:"
365  << "\n\t mean: " << _integCalc_copyForDebug->integral()
366  << "\n\t variance: " << _integCalc_copyForDebug->variance()
367  << endl;
368  }
369  }
370  return _mean;
371 }
372 
374  if(! _initialised){
375  cout << " FastAmplitudeIntegrator::determineNumEvents "
376  << " need to get initialised first." << endl;
377  return 0;
378  }
379 
381  evaluateSum();
382  double v = variance();
383  double safetyFactor = 1.15;
384  double maxVariance = _precision*_precision * _mean*_mean;
386  (v*safetyFactor/maxVariance);
387  // round to the nearest 100:
388  _numEvents = (_numEvents/100 + 1)*100;
389 
390  cout << " FastAmplitudeIntegrator::determineNumEvents():"
391  << "\n\t> mean: " << _mean << ", rms " << sqrt(v)
392  << "\n\t> currently, our relative precision is "
393  << sqrt(v)/_mean
394  << "\n\t> to achieve the requested pecision of " << _precision << ","
395  << "\n\t> (with a safety factor) I think we'll need "
396  << (v*safetyFactor/maxVariance)
397  << " times that, i.e. " << _numEvents << " events" << endl;
398 
399  return _numEvents;
400 }
401 
403  if(! _initialised){
404  cout << " FastAmplitudeIntegrator::generateEnoughEvents "
405  << " need to get initialised first." << endl;
406  return 0;
407  }
408 
410  int counter(0);
411  while(determineNumEvents() > _integCalc->numEvents() &&
412  counter < 10 && _numEvents > 0){
414  counter++;
415  }
416  return _integCalc->numEvents();
417 }
418 
420  evaluateSum();
421  return _mean;
422 }
423 
425  if(! _initialised){
426  cout << " FastAmplitudeIntegrator::histoSet "
427  << " need to get initialised first." << endl;
428  throw "bummer";
429  }
430 
431  return _integCalc->histoSet();
432 }
433 void FastAmplitudeIntegrator::saveEachAmpsHistograms(const std::string& prefix) const{
434  if(! _initialised){
435  cout << " FastAmplitudeIntegrator::saveEachAmpsHistograms "
436  << " need to get initialised first." << endl;
437  cout << "So I won't do anything" << endl;
438  return;
439  }
440  return _integCalc->saveEachAmpsHistograms(prefix);
441 }
443  if(! _initialised){
444  cout << " FastAmplitudeIntegrator::GetEachAmpsHistograms "
445  << " need to get initialised first." << endl;
446  std::vector<DalitzHistoSet> dummy;
447  return dummy;
448  }
450 }
451 
453  if(! _initialised){
454  cout << " FastAmplitudeIntegrator::interferenceHistoSet "
455  << " need to get initialised first." << endl;
456  DalitzHistoSet dummy;
457  return dummy;
458  }
460 }
461 void FastAmplitudeIntegrator::saveInterferenceHistograms(const std::string& prefix) const{
462  if(! _initialised){
463  cout << " FastAmplitudeIntegrator::saveInterferenceAmpsHistograms "
464  << " need to get initialised first." << endl;
465  cout << "So I won't do anything" << endl;
466  return;
467  }
468  return _integCalc->saveInterferenceHistograms(prefix);
469 }
471  if(! _initialised){
472  cout << " FastAmplitudeIntegrator::GetInterferenceHistograms "
473  << " need to get initialised first." << endl;
474  std::vector<DalitzHistoSet> dummy;
475  return dummy;
476  }
477 
479 }
480 
482  bool dbThis=true;
483  if(dbThis){
484  cout << "FastAmplitudeIntegrator::doFinalStats() called" << endl;
485  cout << "Am I initialised? " << _initialised << endl;
486  cout << "Got called with these pointers: mini " << mini
487  << " and my own _integCalc " << _integCalc << endl;
488  }
489  if(! _initialised){
490  cout << " FastAmplitudeIntegrator::doFinalStats "
491  << " need to get initialised first." << endl;
492  cout << " So I won't do anything." << endl;
493  return;
494  }
495 
496  _integCalc->doFinalStats(mini);
497 }
499  if(! _initialised){
500  cout << " FastAmplitudeIntegrator::getFractionChi2() "
501  << " need to get initialised first." << endl;
502  return -9999;
503  }
504  return _integCalc->getFractionChi2();
505 }
506 
507 bool FastAmplitudeIntegrator::save(const std::string& fname)const{
508  if(! _initialised){
509  cout << " FastAmplitudeIntegrator::save( " << fname << " ):"
510  << " need to get initialised first." << endl;
511  cout << " So I won't do anything." << endl;
512  return false;
513  }
514  return _integCalc->save(fname);
515 }
516 
517 //
std::vector< DalitzHistoSet > GetInterferenceHistograms()
virtual bool retrieve(const std::string &commaSeparatedList)
virtual DalitzHistoSet interferenceHistoSet() const
void saveEachAmpsHistograms(const std::string &prefix) const
virtual void saveInterferenceHistograms(const std::string &prefix) const
virtual bool exhausted() const =0
MINT::IEventGenerator< IDalitzEvent > * _generator
MINT::counted_ptr< IntegCalculator > _integCalc_copyForDebug
virtual DalitzHistoSet histoSet() const
virtual double integral() const
virtual bool save(const std::string &dirname) const
bool initialise(const DalitzEventPattern &pattern, IFastAmplitudeIntegrable *amps=0, MINT::IEventGenerator< IDalitzEvent > *eventGenerator=0, TRandom *rnd=0, double precision=1.e-2)
bool initialiseFromFile(const DalitzEventPattern &pattern, IFastAmplitudeIntegrable *amps, const std::string &commaSeparatedList)
virtual void print(std::ostream &os=std::cout) const
virtual std::vector< DalitzHistoSet > GetInterferenceHistograms()
virtual bool add(const FastAmplitudeIntegrator &other)
bool setValues(const DalitzEventPattern &pattern, IFastAmplitudeIntegrable *amps=0, MINT::IEventGenerator< IDalitzEvent > *eventGenerator=0, TRandom *rnd=0, double precision=1.e-2)
DalitzHistoSet histoSet() const
MINT::counted_ptr< TRandom > _localRnd
IFastAmplitudeIntegrable * _amps
virtual std::vector< DalitzHistoSet > GetEachAmpsHistograms()
bool save(const std::string &fname) const
virtual bool add(const IntegCalculator &other)
virtual counted_ptr< RETURN_TYPE > newEvent()=0
virtual void doFinalStats(MINT::Minimiser *mini=0)
virtual bool ensureFreshEvents()=0
virtual int numEvents() const
TRandom * makeNewRnd(int seed=-9999)
virtual double variance() const
virtual void doFinalStats(MINT::Minimiser *mini=0)
virtual void addEvent(IDalitzEvent *evtPtr, double weight=1)
virtual void saveEachAmpsHistograms(const std::string &prefix) const
std::vector< DalitzHistoSet > GetEachAmpsHistograms()
virtual double getFractionChi2() const
static const long int _minEvents
int updateEventSet(long int Nevents)
std::string stringtime(double dt)
Definition: Utils.cpp:14
MINT::counted_ptr< IntegCalculator > _integCalc
virtual MINT::counted_ptr< IntegCalculator > makeIntegCalculator()=0
double weight(IDalitzEvent *evtPtr)
DalitzHistoSet interferenceHistoSet() const
X * get() const
Definition: counted_ptr.h:123
void saveInterferenceHistograms(const std::string &prefix) const