MINT2
TimeBinning.cpp
Go to the documentation of this file.
1 #include <Mint/TimeBinning.h>
2 #include <Mint/NamedParameter.h>
3 #include <fstream>
4 #include <TFile.h>
5 #include <stdexcept>
6 
7 using namespace std ;
9 
11  m_t(0.),
12  m_t2(0.),
13  m_sumw(0.),
14  m_sumw2(0.),
15  m_sumwplus(0.),
16  m_sumw2plus(0.),
17  m_sumwminus(0.),
18  m_sumw2minus(0.)
19 {}
20 
21 TimeBinning::Bin::Bin(const string& _name, unsigned number, const string& fname) :
22  m_t(0.),
23  m_t2(0.),
24  m_sumw(0.),
25  m_sumw2(0.),
26  m_sumwplus(0.),
27  m_sumw2plus(0.),
28  m_sumwminus(0.),
29  m_sumw2minus(0.)
30 {
31  string name = getName(_name, number) ;
32  NamedParameter<double> sumw(name + "sumw", fname.c_str()) ;
33  m_sumw = sumw ;
34  NamedParameter<double> sumw2(name + "sumw2", fname.c_str()) ;
35  m_sumw2 = sumw2 ;
36 
37  NamedParameter<double> _t(name + "t", fname.c_str()) ;
38  m_t = _t * m_sumw ;
39  NamedParameter<double> _t2(name + "t2", fname.c_str()) ;
40  m_t2 = _t2 * m_sumw2 ;
41 
42  NamedParameter<double> sumwplus(name + "sumwplus", fname.c_str()) ;
43  m_sumwplus = sumwplus ;
44  NamedParameter<double> sumw2plus(name + "sumw2plus", fname.c_str()) ;
45  m_sumw2plus = sumw2plus ;
46 
47  NamedParameter<double> sumwminus(name + "sumwminus", fname.c_str()) ;
48  m_sumwminus = sumwminus ;
49  NamedParameter<double> sumw2minus(name + "sumw2minus", fname.c_str()) ;
50  m_sumw2minus = sumw2minus ;
51 }
52 
53 void TimeBinning::Bin::Print(const std::string& _name, unsigned number, ostream& os) const {
54  os.precision(16) ;
55  string name = getName(_name, number) ;
56  os << name << "t\t" << t() << endl ;
57  os << name << "t2\t" << t2() << endl ;
58  os << name << "sumw\t" << m_sumw << endl ;
59  os << name << "sumw2\t" << m_sumw2 << endl ;
60  os << name << "sumwplus\t" << m_sumwplus << endl ;
61  os << name << "sumw2plus\t" << m_sumw2plus << endl ;
62  os << name << "sumwminus\t" << m_sumwminus << endl ;
63  os << name << "sumw2minus\t" << m_sumw2minus << endl ;
64 }
65 
66 string TimeBinning::Bin::getName(const std::string& name, unsigned number) {
67  ostringstream sstr ;
68  sstr << name << "_bin_" << number << "_" ;
69  return sstr.str() ;
70 }
71 
72 void TimeBinning::Bin::add(double t, bool isplus, double weight) {
73  double weight2 = weight*weight ;
74  m_t += t ;
75  m_t2 += t*t ;
76  m_sumw += weight ;
77  m_sumw2 += weight2 ;
78  if(isplus){
79  m_sumwplus += weight ;
80  m_sumw2plus += weight2 ;
81  }
82  else {
83  m_sumwminus += weight ;
84  m_sumw2minus += weight2 ;
85  }
86 }
87 
88 double TimeBinning::Bin::t() const {
89  return m_sumw > 0 ? m_t/m_sumw : 0. ;
90 }
91 
92 double TimeBinning::Bin::t2() const {
93  return m_sumw > 0 ? m_t2/m_sumw : 0. ;
94 }
95 
96 double TimeBinning::Bin::nPlus() const {
97  return m_sumwplus ;
98 }
99 
101  return sqrt(m_sumw2plus) ;
102 }
103 
104 double TimeBinning::Bin::nMinus() const {
105  return m_sumwminus ;
106 }
107 
109  return sqrt(m_sumw2minus) ;
110 }
111 
113  return m_sumw == m_sumw2 ;
114 }
115 
116 double TimeBinning::Bin::chiSquared(double R) const {
117  if(nMinus() == 0. or nPlus() == 0.)
118  return 0. ;
119  double numerator = nMinus() - nPlus() * R ;
120  numerator *= numerator ;
121  double denominator = m_sumw2minus + m_sumw2plus * R*R ;
122  if(denominator == 0.)
123  return 0. ;
124  return numerator/denominator ;
125 }
126 
128  return other += *this;
129 }
130 
132  m_t += other.m_t;
133  m_t2 += other.m_t2;
134  m_sumw += other.m_sumw;
135  m_sumw2 += other.m_sumw2;
136  m_sumwplus += other.m_sumwplus;
137  m_sumw2plus += other.m_sumw2plus;
138  m_sumwminus += other.m_sumwminus;
139  m_sumw2minus += other.m_sumw2minus;
140  return *this;
141 }
142 
143 TimeBinning::TimeBinning(const vector<double>& timeBins, HadronicParameters::BinningPtr phaseBinning, double lifetime) :
144  m_timeBins(timeBins),
145  m_meant(nBinsTime(), 0.),
146  m_meant2(nBinsTime(), 0.),
147  m_lifetime(lifetime),
148  m_bins(nBinsTime(), Bins(phaseBinning->nBins)),
149  m_binsBar(nBinsTime(), Bins(phaseBinning->nBins)),
150  m_binsInt(nBinsTime()),
152 {
153  setLifetime(lifetime) ;
154 }
155 
156 TimeBinning::TimeBinning(const string& name, const string& fname) :
157  m_timeBins(),
158  m_meant(),
159  m_meant2(),
160  m_lifetime(),
161  m_bins(),
162  m_binsBar(),
163  m_binsInt(),
164  m_phaseBinning(0)
165 {
166  NamedParameter<double> timeBins(name + "_timeBins", fname.c_str()) ;
167  m_timeBins = timeBins.getVector() ;
168  m_meant = vector<double>(nBinsTime(), 0.) ;
169  m_meant2 = vector<double>(nBinsTime(), 0.) ;
170  NamedParameter<double> lifetime(name + "_lifetime", fname.c_str()) ;
171  setLifetime(lifetime) ;
173  string nameint = name + "_int" ;
174  string nameplus = name + "_plus" ;
175  string nameminus = name + "_minus" ;
176  for(unsigned iTimeBin = 0 ; iTimeBin < nBinsTime() ; ++iTimeBin){
177  m_binsInt.push_back(Bin(nameint, iTimeBin, fname)) ;
178  m_bins.push_back(Bins()) ;
179  m_binsBar.push_back(Bins()) ;
180  string nameplusbin = Bin::getName(nameplus + "_time", iTimeBin) + "phase" ;
181  string nameminusbin = Bin::getName(nameminus + "_time", iTimeBin) + "phase" ;
182  for(unsigned iPhaseBin = 1 ; iPhaseBin < m_phaseBinning->nBins + 1 ; ++iPhaseBin){
183  m_bins.back().push_back(Bin(nameplusbin, iPhaseBin, fname)) ;
184  m_binsBar.back().push_back(Bin(nameminusbin, iPhaseBin, fname)) ;
185  }
186  }
187 }
188 
189 void TimeBinning::Print(const string& name, ostream& os) const {
190  os.precision(16) ;
191  os << name << "_timeBins" ;
192  for(const auto& bin : m_timeBins)
193  os << "\t" << bin ;
194  os << endl ;
195  os << name << "_lifetime\t" << m_lifetime << endl ;
196  string nameint = name + "_int" ;
197  string nameplus = name + "_plus" ;
198  string nameminus = name + "_minus" ;
199  for(unsigned iTimeBin = 0 ; iTimeBin < nBinsTime() ; ++iTimeBin){
200  m_binsInt[iTimeBin].Print(nameint, iTimeBin, os) ;
201  string nameplusbin = Bin::getName(nameplus + "_time", iTimeBin) + "phase" ;
202  string nameminusbin = Bin::getName(nameminus + "_time", iTimeBin) + "phase" ;
203  for(unsigned iPhaseBin = 1 ; iPhaseBin < m_phaseBinning->nBins + 1; ++iPhaseBin){
204  bin(iTimeBin, iPhaseBin).Print(nameplusbin, iPhaseBin, os) ;
205  binBar(iTimeBin, iPhaseBin).Print(nameminusbin, iPhaseBin, os) ;
206  }
207  }
208  m_phaseBinning->Print(name, os) ;
209 }
210 
211 void TimeBinning::write(const string& name, const string& fname) const {
212  ofstream outfile ;
213  outfile.open(fname) ;
214  Print(name, outfile) ;
215  outfile.close() ;
216 }
217 
219  return m_phaseBinning ;
220 }
221 
222 int TimeBinning::timeBin(double t) const {
223  for(unsigned i = 0 ; i < nBinsTime() ; ++i)
224  if(m_timeBins[i] <= t && t < m_timeBins[i+1])
225  return i ;
226  return -1 ;
227 }
228 
229 void TimeBinning::add(IDalitzEvent& evt, int tag, double t, double weight) {
230  int timeBinNo = timeBin(t) ;
231  if(timeBinNo < 0)
232  return ;
233  int phaseBin = m_phaseBinning->binNumber(evt) ;
234  bool isPlus = phaseBin > 0 ;
235  if(tag > 0){
236  _bin(timeBinNo, abs(phaseBin)).add(t, isPlus, weight) ;
237  }
238  else{
239  isPlus = !isPlus ;
240  _binBar(timeBinNo, abs(phaseBin)).add(t, isPlus, weight) ;
241  }
242  _integratedBin(timeBinNo).add(t, isPlus, weight) ;
243 }
244 
245 double TimeBinning::chiSquared(unsigned iTimeBin, unsigned iPhaseBin, double Rplus, double Rminus) const {
246  return bin(iTimeBin, iPhaseBin).chiSquared(Rplus)
247  + binBar(iTimeBin, iPhaseBin).chiSquared(Rminus) ;
248 }
249 
250 unsigned TimeBinning::nBinsTime() const {
251  return m_timeBins.size()-1 ;
252 }
253 
254 unsigned TimeBinning::nBinsPhase() const {
255  return m_phaseBinning->nBins ;
256 }
257 
259  return m_binsInt.at(i) ;
260 }
261 
262 const TimeBinning::Bin& TimeBinning::bin(unsigned iTimeBin, unsigned iPhaseBin) const {
263  return m_bins.at(iTimeBin).at(iPhaseBin-1) ;
264 }
265 
266 const TimeBinning::Bin& TimeBinning::binBar(unsigned iTimeBin, unsigned iPhaseBin) const {
267  return m_binsBar.at(iTimeBin).at(iPhaseBin-1) ;
268 }
269 
271  return m_binsInt.at(i) ;
272 }
273 
274 TimeBinning::Bin& TimeBinning::_bin(unsigned iTimeBin, unsigned iPhaseBin) {
275  return m_bins.at(iTimeBin).at(iPhaseBin-1) ;
276 }
277 
278 TimeBinning::Bin& TimeBinning::_binBar(unsigned iTimeBin, unsigned iPhaseBin) {
279  return m_binsBar.at(iTimeBin).at(iPhaseBin-1) ;
280 }
281 
282 deque<TH1F> TimeBinning::plotVsTime(const string& _name, unsigned phaseBin, int tag) const {
283  ostringstream stag ;
284  stag << tag ;
285  string name = Bin::getName(_name + "_" + stag.str() + "_phase", phaseBin) ;
286 
287  TH1F hplus((name + "nPlus").c_str(), "", nBinsTime(), &m_timeBins[0]) ;
288  TH1F hminus((name + "nMinus").c_str(), "", nBinsTime(), &m_timeBins[0]) ;
289  TH1F hr((name + "ratio").c_str(), "", nBinsTime(), &m_timeBins[0]) ;
290  for(unsigned i = 1 ; i < nBinsTime()+1 ; ++i) {
291  const Bin& pbin = tag > 0 ? bin(i-1, phaseBin) : binBar(i-1, phaseBin) ;
292  hplus.SetBinContent(i, pbin.nPlus()) ;
293  hplus.SetBinError(i, pbin.nPlusErr()) ;
294  hminus.SetBinContent(i, pbin.nMinus()) ;
295  hminus.SetBinError(i, pbin.nMinusErr()) ;
296  double r = pbin.nPlus() > 0. ? pbin.nMinus()/pbin.nPlus() : 0. ;
297  double rerr = r > 0 && pbin.nMinus() > 0 ? r * sqrt(pow(pbin.nPlusErr()/pbin.nPlus(), 2) + pow(pbin.nMinusErr()/pbin.nMinus(), 2)) : 0. ;
298  hr.SetBinContent(i, r) ;
299  hr.SetBinError(i, rerr) ;
300  }
301  deque<TH1F> histos ;
302  histos.push_back(hplus) ;
303  histos.push_back(hminus) ;
304  histos.push_back(hr) ;
305  return histos ;
306 }
307 
308 deque<deque<TH1F> > TimeBinning::plotsVsTime(const string& name) const {
309  deque<deque<TH1F> > histos ;
310  for(unsigned iphase = 1 ; iphase < m_phaseBinning->nBins + 1 ; ++iphase){
311  histos.push_back(deque<TH1F>()) ;
312  deque<TH1F>& binhistos = histos.back() ;
313  for(int tag = -1 ; tag < 2 ; tag += 2){
314  deque<TH1F> taghistos = plotVsTime(name, iphase, tag) ;
315  binhistos.insert(binhistos.end(), taghistos.begin(), taghistos.end()) ;
316  }
317  TH1F rdiff(binhistos.back()) ;
318  string rdiffname(Bin::getName(name + "_phase", iphase) + "ratiodiff") ;
319  rdiff.SetName(rdiffname.c_str()) ;
320  rdiff.Add(&binhistos[2], -1.) ;
321  binhistos.push_back(rdiff) ;
322  }
323  return histos ;
324 }
325 
326 void TimeBinning::savePlotsVsTime(const string& name, TFile& outputfile) const {
327  outputfile.cd() ;
328  deque<deque<TH1F> > histos = plotsVsTime(name) ;
329  for(auto& binhistos : histos)
330  for(auto& histo : binhistos)
331  histo.Write() ;
332 }
333 
334 double TimeBinning::unmixedTimeMoment(unsigned ibin, double lifetime, int moment) const {
335  const double& tmin = m_timeBins.at(ibin) ;
336  const double& tmax = m_timeBins.at(ibin+1) ;
337  double norm = exp(-tmin/lifetime) - exp(-tmax/lifetime) ;
338  double timeMoment = (pow(tmin, moment) * exp(-tmin/lifetime) - pow(tmax, moment) * exp(-tmax/lifetime))/norm ;
339  if(moment == 0)
340  return timeMoment ;
341  timeMoment += moment * lifetime * unmixedTimeMoment(ibin, lifetime, moment-1) ;
342  return timeMoment ;
343 }
344 
345 void TimeBinning::setLifetime(double lifetime) {
346  m_lifetime = lifetime ;
347  for(unsigned ibin = 0 ; ibin < nBinsTime() ; ++ibin){
348  m_meant.at(ibin) = unmixedTimeMoment(ibin, lifetime, 1) ;
349  m_meant2.at(ibin) = unmixedTimeMoment(ibin, lifetime, 2) ;
350  }
351 }
352 
353 double TimeBinning::getLifetime() const {
354  return m_lifetime ;
355 }
356 
357 double TimeBinning::meanUnmixedTime(unsigned ibin) const {
358  return m_meant.at(ibin) ;
359 }
360 
361 double TimeBinning::meanUnmixedTime2(unsigned ibin) const {
362  return m_meant2.at(ibin) ;
363 }
364 
366 bool TimeBinning::isConsistent(const TimeBinning& other) const {
367  return m_timeBins == other.m_timeBins && m_meant == other.m_meant && m_meant2 == other.m_meant2 \
368  && m_lifetime == other.m_lifetime && *m_phaseBinning == *other.m_phaseBinning;
369 }
370 
372  return other += *this;
373 }
374 
375 /*
376 I feel like this should work, but it doesn't build, giving
377 error: need ‘typename’ before ‘std::deque<T>::const_iterator’ because ‘std::deque<T>’ is a dependent scope
378 
379 template <typename T>
380 std::deque<T>& operator+=(std::deque<T>& self, const std::deque<T>& other) {
381  if(self.size() != other.size())
382  throw std::invalid_argument("Attempt to add deques of different length!");
383  std::deque<T>::const_iterator iother = other.begin();
384  for(std::deque<T>::iterator iself = self.begin(); iself != self.end(); ++iself)
385  *iself += *iother++;
386  return self;
387 }
388 */
389 
391  if(!isConsistent(other))
392  throw std::invalid_argument("Attempt to combine incompatible TimeBinning instances!");
393  //m_bins += other.m_bins;
394  //m_binsBar += other.m_binsBar;
395  //m_binsInt += other.m_binsInt;
396  for(unsigned iTimeBin = 0; iTimeBin < nBinsTime(); ++iTimeBin){
397  m_binsInt.at(iTimeBin) += other.m_binsInt.at(iTimeBin);
398  for(unsigned iPhaseBin = 0; iPhaseBin < nBinsPhase(); ++iPhaseBin){
399  m_bins.at(iTimeBin).at(iPhaseBin) += other.m_bins.at(iTimeBin).at(iPhaseBin);
400  m_binsBar.at(iTimeBin).at(iPhaseBin) += other.m_binsBar.at(iTimeBin).at(iPhaseBin);
401  }
402  }
403  return *this;
404 }
unsigned nBinsPhase() const
Bins2D m_bins
Definition: TimeBinning.h:76
int timeBin(double) const
void setLifetime(double)
static BinningPtr getPhaseBinning(const std::string &, const std::string &fname="")
Get the PhaseBinning type.
bool usePoissonErrs() const
Bin & _binBar(unsigned, unsigned)
std::deque< TH1F > plotVsTime(const std::string &, unsigned, int) const
void add(IDalitzEvent &, int, double, double weight=1.)
static std::string getName(const std::string &, unsigned)
Definition: TimeBinning.cpp:66
const Bin & integratedBin(unsigned) const
const Bin & binBar(unsigned, unsigned) const
double t2() const
Definition: TimeBinning.cpp:92
double m_lifetime
Definition: TimeBinning.h:75
double nMinus() const
void Print(const std::string &, unsigned, std::ostream &os=std::cout) const
Definition: TimeBinning.cpp:53
Bin operator+(Bin) const
TimeBinning(const std::vector< double > &, HadronicParameters::BinningPtr, double)
double nPlusErr() const
void savePlotsVsTime(const std::string &, TFile &) const
TimeBinning & operator+=(const TimeBinning &)
HadronicParameters::BinningPtr m_phaseBinning
Definition: TimeBinning.h:79
std::vector< double > m_meant2
Definition: TimeBinning.h:74
Bin & _bin(unsigned, unsigned)
std::deque< Bin > Bins
Definition: TimeBinning.h:41
double m_sumwminus
Definition: TimeBinning.h:38
double m_sumw2minus
Definition: TimeBinning.h:39
Bin & _integratedBin(unsigned)
Bin & operator+=(const Bin &)
double nMinusErr() const
virtual double unmixedTimeMoment(unsigned, double, int) const
Bins m_binsInt
Definition: TimeBinning.h:78
void write(const std::string &, const std::string &) const
double meanUnmixedTime(unsigned) const
TimeBinning operator+(TimeBinning) const
void add(double, bool, double weight=1.)
Definition: TimeBinning.cpp:72
std::vector< double > m_meant
Definition: TimeBinning.h:73
bool isConsistent(const TimeBinning &) const
Check that two TimeBinnings use the same binning scheme.
double meanUnmixedTime2(unsigned) const
Bins2D m_binsBar
Definition: TimeBinning.h:77
HadronicParameters::BinningPtr phaseBinning() const
double m_sumw2plus
Definition: TimeBinning.h:37
double chiSquared(unsigned, unsigned, double, double) const
const Bin & bin(unsigned, unsigned) const
std::vector< double > m_timeBins
Definition: TimeBinning.h:72
double getLifetime() const
double chiSquared(double) const
double nPlus() const
Definition: TimeBinning.cpp:96
double t() const
Definition: TimeBinning.cpp:88
std::deque< std::deque< TH1F > > plotsVsTime(const std::string &) const
void Print(const std::string &, std::ostream &os=std::cout) const
unsigned nBinsTime() const