MINT2
HadronicParameters.cpp
Go to the documentation of this file.
2 #include <TMath.h>
3 #include <Mint/NamedParameter.h>
4 #include <fstream>
5 
6 using namespace std ;
8 
10  return binNumber > 0 ? 1 : -1 ;
11 }
12 
14  return binNumber > 0 ;
15 }
16 
18  nBins(nBins)
19 {}
20 
22  return binInfo(evt).binNumber ;
23 }
24 
26  return other.nBins == nBins && other.type() == type() ;
27 }
28 
30  return !(operator==(other)) ;
31 }
32 
35  unsigned nBins) :
36  PhaseBinningBase(nBins),
37  m_model(model),
38  m_cpmodel(cpmodel)
39 {}
40 
42  return "model" ;
43 }
44 
45 bool HadronicParameters::ModelPhaseBinning::isFavoured(const double F, const double Fbar, IDalitzEvent&) const {
46  return F > Fbar ;
47 }
48 
50  EventBinInfo binNo ;
51  binNo.evt = &evt ;
52  binNo.amp = m_model->ComplexVal(evt) ;
53  binNo.ampBar = m_cpmodel->ComplexVal(evt) ;
54  binNo.F = norm(binNo.amp) ;
55  binNo.Fbar = norm(binNo.ampBar) ;
56  double phasediff = arg(binNo.amp/binNo.ampBar) ;
57  // Invert the phase difference in the suppressed region, effectively using the phase difference
58  // from the favoured CP-conjugate point to determine the bin. This assumes no direct CPV, ie, that
59  // arg(Fminus/Fbarplus) = -arg(Fplus/Fbarminus). Could use the CP-conjugate event to determine
60  // the phase difference if we need to allow for direct CPV.
61  if(!isFavoured(binNo.F, binNo.Fbar, evt))
62  phasediff *= -1 ;
63  if(phasediff < 0.)
64  phasediff += 2. * TMath::Pi() ;
65  binNo.binNumber = (int(phasediff * nBins/2./TMath::Pi() + 0.5) % nBins + 1) ;
66  // Possible issue if F == Fbar ?
67  if(binNo.Fbar > binNo.F)
68  binNo.binNumber *= -1 ;
69  return binNo ;
70 }
71 
72 void HadronicParameters::ModelPhaseBinning::Print(const std::string& _name, std::ostream& os) const {
73  string name = _name + "_binning_" ;
74  os << name << "type\t" << type() << endl ;
75  os << name << "nBins\t" << nBins << endl ;
76  os << name << "eventPattern" ;
77  for(const auto& ipat : m_model->getAmpPtr(0)->getTreePattern().getVectorOfInts())
78  os << "\t" << ipat ;
79  os << endl ;
80  os << name << "cpEventPattern" ;
81  for(const auto& ipat : m_cpmodel->getAmpPtr(0)->getTreePattern().getVectorOfInts())
82  os << "\t" << ipat ;
83  os << endl ;
84 }
85 
87  const string& fname) {
88  string name = _name + "_binning_" ;
89  if(string(NamedParameter<string>(name + "type", fname.c_str())) != "model")
90  return BinningPtr(0) ;
91  NamedParameter<int> nBins(name + "nBins", fname.c_str()) ;
92  NamedParameter<int> pat(name + "eventPattern", fname.c_str()) ;
93  NamedParameter<int> cpPat(name + "cpEventPattern", fname.c_str()) ;
94  ModelPtr model(new FitAmpSum(DalitzEventPattern(pat), fname.c_str())) ;
95  ModelPtr cpModel(new FitAmpSum(DalitzEventPattern(cpPat), fname.c_str())) ;
96  return BinningPtr(new ModelPhaseBinning(model, cpModel, nBins)) ;
97 }
98 
99 /*bool HadronicParameters::ModelPhaseBinning::operator==(const PhaseBinningBase& other) const {
100  if(!PhaseBiningBase::operator==(other))
101  return false ;
102  const ModelPhaseBinning* ptr = (ModelPhaseBinning*)(&other) ;
103  }
104 */
105 
108  unsigned nBins) :
109  ModelPhaseBinning(model, cpmodel, nBins)
110 {}
111 
113  return "model3body" ;
114 }
115 
116 bool HadronicParameters::ModelBinning3Body::isFavoured(const double, const double, IDalitzEvent& evt) const {
117  const DalitzEventPattern& pat = evt.eventPattern() ;
118  int i1(1), i2(2), i3(3) ;
119  // Assuming we have a decay of the form P->h+h-h0 (in some order).
120  for(unsigned i = 1 ; i < pat.size() ; ++i){
121  if(pat[i].charge() > 0)
122  i1 = i ;
123  else if(pat[i].charge() < 0)
124  i2 = i ;
125  else
126  i3 = i ;
127  }
128  double s13 = evt.s(i1, i3) ;
129  double s23 = evt.s(i2, i3) ;
130  return s13 > s23 ;
131 }
132 
134  const string& fname) {
135  string name = _name + "_binning_" ;
136  if(string(NamedParameter<string>(name + "type", fname.c_str())) != "model3body")
137  return BinningPtr(0) ;
138  NamedParameter<int> nBins(name + "nBins", fname.c_str()) ;
139  NamedParameter<int> pat(name + "eventPattern", fname.c_str()) ;
140  NamedParameter<int> cpPat(name + "cpEventPattern", fname.c_str()) ;
141  ModelPtr model(new FitAmpSum(DalitzEventPattern(pat), fname.c_str())) ;
142  ModelPtr cpModel(new FitAmpSum(DalitzEventPattern(cpPat), fname.c_str())) ;
143  return BinningPtr(new ModelBinning3Body(model, cpModel, nBins)) ;
144 }
145 
146 
147 HadronicParameters::Bin::Bin(double _Fplus, double _Fminus, const complex<double>& X,
148  double _Fbarplus, double _Fbarminus, const complex<double>& Xbar,
149  double norm, double normBar, double sumw, double sumw2) :
150  m_Fplus(_Fplus * sumw * norm),
151  m_Fminus(_Fminus * sumw * norm),
152  m_X(X),
153  m_Fbarplus(_Fbarplus * sumw * normBar),
154  m_Fbarminus(_Fbarminus * sumw * normBar),
155  m_Xbar(Xbar),
156  m_sumw(sumw),
157  m_sumw2(sumw2),
158  m_norm(norm),
159  m_normBar(normBar)
160 {
161  m_X *= sqrt(Fplus() * Fminus()) * sumw * norm ;
162  m_Xbar *= sqrt(Fbarplus() * Fbarminus()) * sumw * normBar ;
163 }
164 
166  m_Fplus(0.),
167  m_Fminus(0.),
168  m_X(0., 0.),
169  m_Fbarplus(0.),
170  m_Fbarminus(0.),
171  m_Xbar(0., 0.),
172  m_sumw(0.),
173  m_sumw2(0.),
174  m_norm(1.),
175  m_normBar(1.)
176 {}
177 
178 HadronicParameters::Bin::Bin(const string& _name, unsigned number, const string& fname) :
179  m_Fplus(0.),
180  m_Fminus(0.),
181  m_X(0., 0.),
182  m_Fbarplus(0.),
183  m_Fbarminus(0.),
184  m_Xbar(0., 0.),
185  m_sumw(0.),
186  m_sumw2(0.),
187  m_norm(0.),
188  m_normBar(1.)
189 {
190  string name = getName(_name, number) ;
191  NamedParameter<double> _Fplus(name + "_Fplus", fname.c_str()) ;
192  NamedParameter<double> _Fminus(name + "_Fminus", fname.c_str()) ;
193  NamedParameter<double> Xplus_Re(name + "_Xplus_Re", fname.c_str()) ;
194  NamedParameter<double> Xplus_Im(name + "_Xplus_Im", fname.c_str()) ;
195 
196  NamedParameter<double> _Fbarplus(name + "_Fbarplus", fname.c_str()) ;
197  NamedParameter<double> _Fbarminus(name + "_Fbarminus", fname.c_str()) ;
198  NamedParameter<double> Xbarplus_Re(name + "_Xbarplus_Re", fname.c_str()) ;
199  NamedParameter<double> Xbarplus_Im(name + "_Xbarplus_Im", fname.c_str()) ;
200 
201  NamedParameter<double> sumw(name + "_sumw", fname.c_str()) ;
202  NamedParameter<double> sumw2(name + "_sumw2", fname.c_str()) ;
203  NamedParameter<double> norm(name + "_norm", fname.c_str()) ;
204  NamedParameter<double> normBar(name + "_normBar", fname.c_str()) ;
205 
206  m_norm = norm ;
207  m_normBar = normBar ;
208  m_sumw = sumw ;
209  m_sumw2 = sumw2 ;
210 
211  m_Fplus = _Fplus * m_sumw * m_norm ;
212  m_Fminus = _Fminus * m_sumw * m_norm ;
213  m_X = complex<double>(Xplus_Re, Xplus_Im) * sqrt(Fplus() * Fminus()) * m_sumw * m_norm ;
214 
215  m_Fbarplus = _Fbarplus * m_sumw * m_normBar ;
216  m_Fbarminus = _Fbarminus * m_sumw * m_normBar ;
217  m_Xbar = complex<double>(Xbarplus_Re, Xbarplus_Im) * sqrt(Fbarplus() * Fbarminus()) * m_sumw * m_normBar ;
218 }
219 
220 
222  const HadronicParameters::EventBinInfo& evtMinus,
223  double weight) {
224  m_Fplus += evtPlus.F * weight ;
225  m_Fminus += evtMinus.F * weight ;
226  m_Fbarplus += evtMinus.Fbar * weight ;
227  m_Fbarminus += evtPlus.Fbar * weight ;
228  m_X += conj(evtPlus.amp) * evtPlus.ampBar * weight ;
229  m_Xbar += conj(evtMinus.ampBar) * evtMinus.amp * weight ;
230  m_sumw += weight ;
231  m_sumw2 += weight*weight ;
232 }
233 
235  return m_Fplus / m_sumw / m_norm ;
236 }
237 
239  return m_Fminus / m_sumw / m_norm ;
240 }
241 
242 complex<double> HadronicParameters::Bin::Xplus() const {
243  return m_X / m_sumw / sqrt(Fplus() * Fbarminus()) / m_norm ;
244 }
245 
246 complex<double> HadronicParameters::Bin::Xminus() const {
247  return conj(Xplus()) ;
248 }
249 
251  return m_Fbarplus / m_sumw / m_normBar ;
252 }
253 
255  return m_Fbarminus / m_sumw / m_normBar ;
256 }
257 
258 complex<double> HadronicParameters::Bin::Xbarplus() const {
259  return m_Xbar / m_sumw / sqrt(Fbarplus() * Fminus()) / m_normBar ;
260 }
261 
262 complex<double> HadronicParameters::Bin::Xbarminus() const {
263  return conj(Xbarplus()) ;
264 }
265 
267  return m_norm ;
268 }
269 
271  m_norm = norm ;
272 }
273 
275  return m_normBar ;
276 }
277 
279  m_normBar = norm ;
280 }
281 
282 void HadronicParameters::Bin::Print(const string& _name, unsigned number, ostream& os) const {
283  string name = getName(_name, number) ;
284  complex<double> Xp = Xplus() ;
285  complex<double> Xbarp = Xbarplus() ;
286  os.precision(16) ;
287  os << name << "_Fplus\t" << Fplus() << endl ;
288  os << name << "_Fminus\t" << Fminus() << endl ;
289  os << name << "_Xplus_Re\t" << Xp.real() << endl ;
290  os << name << "_Xplus_Im\t" << Xp.imag() << endl ;
291  os << name << "_Fbarplus\t" << Fbarplus() << endl ;
292  os << name << "_Fbarminus\t" << Fbarminus() << endl ;
293  os << name << "_Xbarplus_Re\t" << Xbarp.real() << endl ;
294  os << name << "_Xbarplus_Im\t" << Xbarp.imag() << endl ;
295  os << name << "_sumw\t" << m_sumw << endl ;
296  os << name << "_sumw2\t" << m_sumw2 << endl ;
297  os << name << "_norm\t" << m_norm << endl ;
298  os << name << "_normBar\t" << m_normBar << endl ;
299 }
300 
301 string HadronicParameters::Bin::getName(const string& name, unsigned number) {
302  ostringstream sstr ;
303  sstr << name << "_bin_" << number ;
304  return sstr.str() ;
305 }
306 
307 double HadronicParameters::Bin::R(double t, double t2, double lifetime,
308  const complex<double>& zcp, const complex<double>& dz) const {
309  complex<double> sumz(zcp + dz) ;
310  return _R(t, t2, lifetime, zcp, dz, Fplus(), Fminus(), Xplus(), sumz) ;
311 }
312 
313 double HadronicParameters::Bin::Rbar(double t, double t2, double lifetime,
314  const complex<double>& zcp, const complex<double>& dz) const {
315  complex<double> sumz(zcp - dz) ;
316  return _R(t, t2, lifetime, zcp, dz, Fbarplus(), Fbarminus(), Xbarplus(), sumz) ;
317 }
318 
319 double HadronicParameters::Bin::_R(double t, double t2, double lifetime,
320  const complex<double>& zcp, const complex<double>& dz,
321  double _Fplus, double _Fminus,
322  const complex<double>& X, const complex<double>& sumz) const {
323  t /= lifetime ;
324  t2 /= lifetime * lifetime ;
325  double r = _Fminus/_Fplus ;
326  double term1 = (1 + 0.25 * t2 * (zcp*zcp - dz*dz).real()) ;
327  double term2 = 0.25 * t2 * norm(sumz) ;
328  double term3 = sqrt(r) * t * (conj(X) * sumz).real() ;
329  double numerator = r * term1 + term2 + term3 ;
330  double term4 = sqrt(r) * t * (X * sumz).real() ;
331  double denominator = term1 + r * term2 + term4 ;
332  return numerator/denominator ;
333 }
334 
336  BinningPtr phaseBinning) :
337  m_bins(bins),
338  m_phaseBinning(phaseBinning)
339 {}
340 
342  m_bins(phaseBinning->nBins, HadronicParameters::Bin()),
343  m_phaseBinning(phaseBinning)
344 {}
345 
346 HadronicParameters::HadronicParameters(const string& name, const string& fname) :
347  m_bins(),
348  m_phaseBinning(HadronicParameters::getPhaseBinning(name, fname))
349 {
350  for(unsigned i = 1 ; i < m_phaseBinning->nBins + 1 ; ++i)
351  m_bins.push_back(Bin(name, i, fname)) ;
352 }
353 
355  int binNo = abs(m_phaseBinning->binNumber(evt)) ;
356  return m_bins.at(binNo-1) ;
357 }
358 
360  return m_bins.at(i-1) ;
361 }
362 
363 void HadronicParameters::add(IDalitzEvent& evt, double weight) {
364  EventBinInfo binNo = m_phaseBinning->binInfo(evt) ;
365  DalitzEvent cpEvt(evt) ;
366  cpEvt.CP_conjugateYourself() ;
367  EventBinInfo cpBinNo = m_phaseBinning->binInfo(cpEvt) ;
368  if(binNo.isPlus())
369  m_bins.at(binNo.binNumber-1).add(binNo, cpBinNo, weight) ;
370  else
371  m_bins.at(cpBinNo.binNumber-1).add(cpBinNo, binNo, weight) ;
372 }
373 
374 void HadronicParameters::add(const DalitzEventPattern& pat, TRandom3& rndm, unsigned nevt) {
375  for(unsigned i = 0 ; i < nevt ; ++i)
376  add(pat, rndm) ;
377 }
378 
379 void HadronicParameters::add(const DalitzEventPattern& pat, TRandom3& rndm) {
380  DalitzEvent evt(pat, (TRandom*)&rndm) ;
381  add(evt) ;
382 }
383 
384 pair<double, double> HadronicParameters::integral() const {
385  double norm = 0. ;
386  double normBar = 0. ;
387  for(const auto& bin : m_bins){
388  norm += bin.Fplus() + bin.Fminus() ;
389  normBar += bin.Fbarplus() + bin.Fbarminus() ;
390  }
391  return pair<double, double>(norm, normBar) ;
392 }
393 
394 pair<double, double> HadronicParameters::normalise(double _norm, double _normBar) {
395  for(auto& bin : m_bins){
396  bin.setNorm(1.) ;
397  bin.setNormBar(1.) ;
398  }
399  pair<double, double> norm = integral() ;
400  norm.first /= _norm ;
401  norm.second /= _normBar ;
402  for(auto& bin : m_bins){
403  bin.setNorm(norm.first) ;
404  bin.setNormBar(norm.second) ;
405  }
406  return norm ;
407 }
408 
409 void HadronicParameters::Print(const string& name, ostream& os) const {
410  m_phaseBinning->Print(name, os) ;
411  unsigned i = 1 ;
412  for(const auto& bin : m_bins){
413  bin.Print(name, i, os) ;
414  i += 1 ;
415  }
416 }
417 
418 void HadronicParameters::write(const string& name, const string& fname) const {
419  ofstream fout ;
420  fout.open(fname) ;
421  Print(name, fout) ;
422  fout.close() ;
423 }
424 
426 HadronicParameters::getPhaseBinning(const string& name, const string& fname) {
427  NamedParameter<string> type(name + "_binning_type", fname.c_str()) ;
428  string strtype(type) ;
429  if(strtype == string("model"))
430  return BinningPtr(ModelPhaseBinning::fromConfig(name, fname)) ;
431  if(strtype == string("model3body"))
432  return BinningPtr(ModelBinning3Body::fromConfig(name, fname)) ;
433  throw invalid_argument("Unknown binning type: " + strtype) ;
434 }
435 
437  return *m_phaseBinning ;
438 }
439 
441  return m_phaseBinning ;
442 }
double getNorm() const
Get the normalisation.
double Fminus() const
Get the magnitude sq in the suppressed region.
std::complex< double > Xbarplus() const
Get the cross term for the favoured region, for the CP-conjugate decay.
void Print(const std::string &name, unsigned, std::ostream &os=std::cout) const
Print the parameters.
std::complex< double > m_Xbar
Cross term, for the CP-conjugate decay.
void Print(const std::string &, std::ostream &os=std::cout) const
Print the parameters.
std::complex< double > Xbarminus() const
Get the cross term for the suppressed region, for the CP-conjugate decay.
static BinningPtr getPhaseBinning(const std::string &, const std::string &fname="")
Get the PhaseBinning type.
double Fplus() const
Get the magnitude sq in the favoured region.
virtual void CP_conjugateYourself()
std::complex< double > Xplus() const
Get the cross term for the favoured region.
std::complex< double > m_X
Cross term.
virtual std::string type() const override
void setNormBar(double)
Set the normalisation, for the CP-conjugate decay.
static std::string getName(const std::string &, unsigned)
Get the name string.
virtual void Print(const std::string &, std::ostream &os=std::cout) const =0
HadronicParameters::BinningPtr binningPtr() const
Get a pointer to the binning scheme.
double m_Fbarminus
Magnitude sq. in the suppressed region, for the CP-conjugate decay.
const PhaseBinningBase & binning() const
Get the binning scheme.
ModelBinning3Body(ModelPtr, ModelPtr, unsigned)
Bin()
Initialise an empty bin.
double m_normBar
The normalisation scale for the CP-conjugate decay.
double m_Fminus
Magnitude sq. in the suppressed region.
Hadronic parameters in a bin of phase space.
static MINT::counted_ptr< PhaseBinningBase > fromConfig(const std::string &, const std::string &fname="")
double m_norm
The normalisation scale. - Are there potentially issues with having different normalisation for D0 an...
double m_sumw
Sum of weights.
virtual std::string type() const =0
Class for determining if an event lives in a +ve or -ve bin.
Phase binning class for 3-body decays using the line s13=s23 to determine favoured/suppressed.
Info on the bin of an Event - output of IPhaseBin::binInfo. Caches as much as possible for efficiency...
double m_sumw2
Sum of weights sq.
std::pair< double, double > normalise(double norm=1., double normBar=1.)
Normalise the parameters.
void add(const EventBinInfo &, const EventBinInfo &, double weight=1.)
Add a DalitzEvent and its conjugate.
double m_Fbarplus
Magnitude sq. in the favoured region, for the CP-conjugate decay.
void setNorm(double)
Set the normalisation.
virtual void Print(const std::string &, std::ostream &os=std::cout) const override
HadronicParameters(const Bins &, BinningPtr)
Initialise from a predetermined set of bins.
ModelPhaseBinning(ModelPtr, ModelPtr, unsigned)
std::complex< double > Xminus() const
Get the cross term for the suppressed region.
Interface class for determining which bin an event lives in.
virtual bool isFavoured(const double, const double, IDalitzEvent &) const
void add(IDalitzEvent &, double weight=1.)
Add a DalitzEvent.
int binSign() const
Get the bin sign, +1 or -1.
virtual bool isFavoured(const double, const double, IDalitzEvent &) const override
double m_Fplus
Magnitude sq. in the favoured region.
void write(const std::string &, const std::string &) const
Write to a file.
std::pair< double, double > integral() const
Get the integral over phase space.
virtual const DalitzEventPattern & eventPattern() const =0
bool operator!=(const PhaseBinningBase &) const
double Fbarminus() const
Get the magnitude sq in the suppressed region, for the CP-conjugate decay.
unsigned int size() const
virtual EventBinInfo binInfo(IDalitzEvent &) const override
const Bin & bin(IDalitzEvent &) const
Get the bin for a DalitzEvent.
MINT::counted_ptr< PhaseBinningBase > BinningPtr
Pointer to the binning scheme.
virtual std::string type() const override
virtual double s(unsigned int i, unsigned int j) const =0
virtual EventBinInfo binInfo(IDalitzEvent &) const =0
std::deque< Bin > Bins
A set of bins.
bool isPlus() const
Check if the event is in a +ve bin.
double Fbarplus() const
Get the magnitude sq in the favoured region, for the CP-conjugate decay.
double Rbar(double, double, double, const std::complex< double > &, const std::complex< double > &) const
static MINT::counted_ptr< PhaseBinningBase > fromConfig(const std::string &, const std::string &fname="")
double _R(double, double, double, const std::complex< double > &, const std::complex< double > &, double, double, const std::complex< double > &, const std::complex< double > &) const
Get the expected ratio of events (suppressed)/(favoured) at the given time for the given mixing param...
virtual bool operator==(const PhaseBinningBase &) const
double getNormBar() const
Get the normalisation, for the CP-conjugate decay.
double R(double, double, double, const std::complex< double > &, const std::complex< double > &) const
Get expected ratio of events (suppressed)/(favoured) at the given time for the given mixing parameter...