laura is hosted by Hepforge, IPPP Durham
Laura++  v3r2
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauCPFitModel.cc
Go to the documentation of this file.
1 
2 // Copyright University of Warwick 2004 - 2014.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 // Authors:
7 // Thomas Latham
8 // John Back
9 // Paul Harrison
10 
15 #include <iostream>
16 #include <iomanip>
17 #include <fstream>
18 #include <vector>
19 
20 #include "TVirtualFitter.h"
21 #include "TSystem.h"
22 #include "TMinuit.h"
23 #include "TRandom.h"
24 #include "TFile.h"
25 #include "TMath.h"
26 #include "TH2.h"
27 
28 #include "LauAbsBkgndDPModel.hh"
29 #include "LauAbsCoeffSet.hh"
30 #include "LauIsobarDynamics.hh"
31 #include "LauAbsPdf.hh"
32 #include "LauAsymmCalc.hh"
33 #include "LauComplex.hh"
34 #include "LauConstants.hh"
35 #include "LauCPFitModel.hh"
36 #include "LauDaughters.hh"
37 #include "LauEffModel.hh"
38 #include "LauEmbeddedData.hh"
39 #include "LauFitNtuple.hh"
40 #include "LauGenNtuple.hh"
41 #include "LauKinematics.hh"
42 #include "LauPrint.hh"
43 #include "LauRandom.hh"
44 #include "LauScfMap.hh"
45 #include "TGraph2D.h"
46 #include "TGraph.h"
47 #include "TStyle.h"
48 #include "TCanvas.h"
49 #include "TGraph2D.h"
50 #include "TGraph.h"
51 #include "TStyle.h"
52 #include "TCanvas.h"
53 
55 
56 
57 LauCPFitModel::LauCPFitModel(LauIsobarDynamics* negModel, LauIsobarDynamics* posModel, Bool_t tagged, const TString& tagVarName) : LauAbsFitModel(),
58  negSigModel_(negModel), posSigModel_(posModel),
59  negKinematics_(negModel ? negModel->getKinematics() : 0),
60  posKinematics_(posModel ? posModel->getKinematics() : 0),
61  usingBkgnd_(kFALSE),
62  nSigComp_(0),
63  nSigDPPar_(0),
64  nExtraPdfPar_(0),
65  nNormPar_(0),
66  negMeanEff_("negMeanEff",0.0,0.0,1.0), posMeanEff_("posMeanEff",0.0,0.0,1.0),
67  negDPRate_("negDPRate",0.0,0.0,100.0), posDPRate_("posDPRate",0.0,0.0,100.0),
68  signalEvents_(0),
69  signalAsym_(0),
70  forceAsym_(kFALSE),
71  tagged_(tagged),
72  tagVarName_(tagVarName),
73  curEvtCharge_(0),
74  useSCF_(kFALSE),
75  useSCFHist_(kFALSE),
76  scfFrac_("scfFrac",0.0,0.0,1.0),
77  scfFracHist_(0),
78  scfMap_(0),
79  compareFitData_(kFALSE),
80  negParent_("B-"), posParent_("B+"),
81  negSignalTree_(0), posSignalTree_(0),
82  reuseSignal_(kFALSE),
83  useNegReweighting_(kFALSE), usePosReweighting_(kFALSE),
84  sigDPLike_(0.0),
85  scfDPLike_(0.0),
86  sigExtraLike_(0.0),
87  scfExtraLike_(0.0),
88  sigTotalLike_(0.0),
89  scfTotalLike_(0.0)
90 {
91  const LauDaughters* negDaug = negSigModel_->getDaughters();
92  if (negDaug != 0) {negParent_ = negDaug->getNameParent();}
93  const LauDaughters* posDaug = posSigModel_->getDaughters();
94  if (posDaug != 0) {posParent_ = posDaug->getNameParent();}
95 }
96 
98 {
99  delete negSignalTree_;
100  delete posSignalTree_;
101  for (LauBkgndEmbDataList::iterator iter = negBkgndTree_.begin(); iter != negBkgndTree_.end(); ++iter) {
102  delete (*iter);
103  }
104  for (LauBkgndEmbDataList::iterator iter = posBkgndTree_.begin(); iter != posBkgndTree_.end(); ++iter) {
105  delete (*iter);
106  }
107  delete scfFracHist_;
108 }
109 
111 {
112  UInt_t nBkgnds = this->nBkgndClasses();
113  negBkgndDPModels_.resize( nBkgnds );
114  posBkgndDPModels_.resize( nBkgnds );
115  negBkgndPdfs_.resize( nBkgnds );
116  posBkgndPdfs_.resize( nBkgnds );
117  bkgndEvents_.resize( nBkgnds );
118  bkgndAsym_.resize( nBkgnds );
119  negBkgndTree_.resize( nBkgnds );
120  posBkgndTree_.resize( nBkgnds );
121  reuseBkgnd_.resize( nBkgnds );
122  bkgndDPLike_.resize( nBkgnds );
123  bkgndExtraLike_.resize( nBkgnds );
124  bkgndTotalLike_.resize( nBkgnds );
125 }
126 
128 {
129  if ( nSigEvents == 0 ) {
130  std::cerr << "ERROR in LauCPFitModel::setNSigEvents : The LauParameter pointer is null." << std::endl;
131  gSystem->Exit(EXIT_FAILURE);
132  }
133  if ( signalEvents_ != 0 ) {
134  std::cerr << "ERROR in LauCPFitModel::setNSigEvents : You are trying to overwrite the signal yield." << std::endl;
135  return;
136  }
137  if ( signalAsym_ != 0 ) {
138  std::cerr << "ERROR in LauCPFitModel::setNSigEvents : You are trying to overwrite the signal asymmetry." << std::endl;
139  return;
140  }
141 
142  signalEvents_ = nSigEvents;
143  TString name = signalEvents_->name();
144  if ( ! name.Contains("signalEvents") && !( name.BeginsWith("signal") && name.EndsWith("Events") ) ) {
145  signalEvents_->name("signalEvents");
146  }
147  Double_t value = nSigEvents->value();
148  signalEvents_->range(-2.0*(TMath::Abs(value)+1.0), 2.0*(TMath::Abs(value)+1.0));
149 
150  signalAsym_ = new LauParameter("signalAsym",0.0,-1.0,1.0,kTRUE);
151 }
152 
153 void LauCPFitModel::setNSigEvents( LauParameter* nSigEvents, LauParameter* sigAsym, Bool_t forceAsym )
154 {
155  if ( nSigEvents == 0 ) {
156  std::cerr << "ERROR in LauCPFitModel::setNSigEvents : The event LauParameter pointer is null." << std::endl;
157  gSystem->Exit(EXIT_FAILURE);
158  }
159  if ( sigAsym == 0 ) {
160  std::cerr << "ERROR in LauCPFitModel::setNSigEvents : The asym LauParameter pointer is null." << std::endl;
161  gSystem->Exit(EXIT_FAILURE);
162  }
163 
164  if ( signalEvents_ != 0 ) {
165  std::cerr << "ERROR in LauCPFitModel::setNSigEvents : You are trying to overwrite the signal yield." << std::endl;
166  return;
167  }
168  if ( signalAsym_ != 0 ) {
169  std::cerr << "ERROR in LauCPFitModel::setNSigEvents : You are trying to overwrite the signal asymmetry." << std::endl;
170  return;
171  }
172 
173  signalEvents_ = nSigEvents;
174  signalEvents_->name("signalEvents");
175  Double_t value = nSigEvents->value();
176  signalEvents_->range(-2.0*(TMath::Abs(value)+1.0), 2.0*(TMath::Abs(value)+1.0));
177 
178  signalAsym_ = sigAsym;
179  signalAsym_->name("signalAsym");
180  signalAsym_->range(-1.0,1.0);
181 
182  forceAsym_ = forceAsym;
183 }
184 
186 {
187  if ( nBkgndEvents == 0 ) {
188  std::cerr << "ERROR in LauCPFitModel::setNBgkndEvents : The background yield LauParameter pointer is null." << std::endl;
189  gSystem->Exit(EXIT_FAILURE);
190  }
191 
192  if ( ! this->validBkgndClass( nBkgndEvents->name() ) ) {
193  std::cerr << "ERROR in LauCPFitModel::setNBkgndEvents : Invalid background class \"" << nBkgndEvents->name() << "\"." << std::endl;
194  std::cerr << " : Background class names must be provided in \"setBkgndClassNames\" before any other background-related actions can be performed." << std::endl;
195  gSystem->Exit(EXIT_FAILURE);
196  }
197 
198  UInt_t bkgndID = this->bkgndClassID( nBkgndEvents->name() );
199 
200  if ( bkgndEvents_[bkgndID] != 0 ) {
201  std::cerr << "ERROR in LauCPFitModel::setNBkgndEvents : You are trying to overwrite the background yield." << std::endl;
202  return;
203  }
204 
205  if ( bkgndAsym_[bkgndID] != 0 ) {
206  std::cerr << "ERROR in LauCPFitModel::setNBkgndEvents : You are trying to overwrite the background asymmetry." << std::endl;
207  return;
208  }
209 
210  bkgndEvents_[bkgndID] = nBkgndEvents;
211  bkgndEvents_[bkgndID]->name( nBkgndEvents->name()+"Events" );
212  Double_t value = nBkgndEvents->value();
213  bkgndEvents_[bkgndID]->range(-2.0*(TMath::Abs(value)+1.0), 2.0*(TMath::Abs(value)+1.0));
214 
215  bkgndAsym_[bkgndID] = new LauParameter(nBkgndEvents->name()+"Asym",0.0,-1.0,1.0,kTRUE);
216 }
217 
219 {
220  if ( nBkgndEvents == 0 ) {
221  std::cerr << "ERROR in LauCPFitModel::setNBkgndEvents : The background yield LauParameter pointer is null." << std::endl;
222  gSystem->Exit(EXIT_FAILURE);
223  }
224 
225  if ( bkgndAsym == 0 ) {
226  std::cerr << "ERROR in LauCPFitModel::setNBkgndEvents : The background asym LauParameter pointer is null." << std::endl;
227  gSystem->Exit(EXIT_FAILURE);
228  }
229 
230  if ( ! this->validBkgndClass( nBkgndEvents->name() ) ) {
231  std::cerr << "ERROR in LauCPFitModel::setNBkgndEvents : Invalid background class \"" << nBkgndEvents->name() << "\"." << std::endl;
232  std::cerr << " : Background class names must be provided in \"setBkgndClassNames\" before any other background-related actions can be performed." << std::endl;
233  gSystem->Exit(EXIT_FAILURE);
234  }
235 
236  UInt_t bkgndID = this->bkgndClassID( nBkgndEvents->name() );
237 
238  if ( bkgndEvents_[bkgndID] != 0 ) {
239  std::cerr << "ERROR in LauCPFitModel::setNBkgndEvents : You are trying to overwrite the background yield." << std::endl;
240  return;
241  }
242 
243  if ( bkgndAsym_[bkgndID] != 0 ) {
244  std::cerr << "ERROR in LauCPFitModel::setNBkgndEvents : You are trying to overwrite the background asymmetry." << std::endl;
245  return;
246  }
247 
248  bkgndEvents_[bkgndID] = nBkgndEvents;
249  bkgndEvents_[bkgndID]->name( nBkgndEvents->name()+"Events" );
250  Double_t value = nBkgndEvents->value();
251  bkgndEvents_[bkgndID]->range(-2.0*(TMath::Abs(value)+1.0), 2.0*(TMath::Abs(value)+1.0));
252 
253  bkgndAsym_[bkgndID] = bkgndAsym;
254  bkgndAsym_[bkgndID]->name( nBkgndEvents->name()+"Asym" );
255  bkgndAsym_[bkgndID]->range(-1.0,1.0);
256 }
257 
258 void LauCPFitModel::splitSignalComponent( const TH2* dpHisto, const Bool_t upperHalf, const Bool_t fluctuateBins, LauScfMap* scfMap )
259 {
260  if ( useSCF_ == kTRUE ) {
261  std::cerr << "ERROR in LauCPFitModel::splitSignalComponent : Have already setup SCF." << std::endl;
262  return;
263  }
264 
265  if ( dpHisto == 0 ) {
266  std::cerr << "ERROR in LauCPFitModel::splitSignalComponent : The histogram pointer is null." << std::endl;
267  return;
268  }
269 
270  const LauDaughters* daughters = negSigModel_->getDaughters();
271  scfFracHist_ = new LauEffModel( daughters, 0 );
272  scfFracHist_->setEffHisto( dpHisto, kTRUE, fluctuateBins, 0.0, 0.0, upperHalf, daughters->squareDP() );
273 
274  scfMap_ = scfMap;
275 
276  useSCF_ = kTRUE;
277  useSCFHist_ = kTRUE;
278 }
279 
280 void LauCPFitModel::splitSignalComponent( const Double_t scfFrac, const Bool_t fixed )
281 {
282  if ( useSCF_ == kTRUE ) {
283  std::cerr << "ERROR in LauCPFitModel::splitSignalComponent : Have already setup SCF." << std::endl;
284  return;
285  }
286 
287  scfFrac_.range( 0.0, 1.0 );
288  scfFrac_.value( scfFrac ); scfFrac_.initValue( scfFrac ); scfFrac_.genValue( scfFrac );
289  scfFrac_.fixed( fixed );
290 
291  useSCF_ = kTRUE;
292  useSCFHist_ = kFALSE;
293 }
294 
295 void LauCPFitModel::setBkgndDPModels(const TString& bkgndClass, LauAbsBkgndDPModel* negModel, LauAbsBkgndDPModel* posModel)
296 {
297  if ((negModel==0) || (posModel==0)) {
298  std::cerr << "ERROR in LauCPFitModel::setBkgndDPModels : One or both of the model pointers is null." << std::endl;
299  return;
300  }
301 
302  // check that this background name is valid
303  if ( ! this->validBkgndClass( bkgndClass) ) {
304  std::cerr << "ERROR in LauCPFitModel::setBkgndDPModel : Invalid background class \"" << bkgndClass << "\"." << std::endl;
305  std::cerr << " : Background class names must be provided in \"setBkgndClassNames\" before any other background-related actions can be performed." << std::endl;
306  return;
307  }
308 
309  UInt_t bkgndID = this->bkgndClassID( bkgndClass );
310  negBkgndDPModels_[bkgndID] = negModel;
311  posBkgndDPModels_[bkgndID] = posModel;
312 
313  usingBkgnd_ = kTRUE;
314 }
315 
317 {
318  if ( tagged_ ) {
319  if (negPdf==0 || posPdf==0) {
320  std::cerr << "ERROR in LauCPFitModel::setSignalPdfs : One or both of the PDF pointers is null." << std::endl;
321  return;
322  }
323  } else {
324  // if we're doing an untagged analysis we will only use the negative PDFs
325  if ( negPdf==0 ) {
326  std::cerr << "ERROR in LauCPFitModel::setSignalPdfs : The negative PDF pointer is null." << std::endl;
327  return;
328  }
329  if ( posPdf!=0 ) {
330  std::cerr << "WARNING in LauCPFitModel::setSignalPdfs : Doing an untagged fit so will not use the positive PDF." << std::endl;
331  }
332  }
333  negSignalPdfs_.push_back(negPdf);
334  posSignalPdfs_.push_back(posPdf);
335 }
336 
338 {
339  if ( tagged_ ) {
340  if (negPdf==0 || posPdf==0) {
341  std::cerr << "ERROR in LauCPFitModel::setSCFPdfs : One or both of the PDF pointers is null." << std::endl;
342  return;
343  }
344  } else {
345  // if we're doing an untagged analysis we will only use the negative PDFs
346  if ( negPdf==0 ) {
347  std::cerr << "ERROR in LauCPFitModel::setSCFPdfs : The negative PDF pointer is null." << std::endl;
348  return;
349  }
350  if ( posPdf!=0 ) {
351  std::cerr << "WARNING in LauCPFitModel::setSCFPdfs : Doing an untagged fit so will not use the positive PDF." << std::endl;
352  }
353  }
354  negScfPdfs_.push_back(negPdf);
355  posScfPdfs_.push_back(posPdf);
356 }
357 
358 void LauCPFitModel::setBkgndPdfs(const TString& bkgndClass, LauAbsPdf* negPdf, LauAbsPdf* posPdf)
359 {
360  if ( tagged_ ) {
361  if (negPdf==0 || posPdf==0) {
362  std::cerr << "ERROR in LauCPFitModel::setBkgndPdfs : One or both of the PDF pointers is null." << std::endl;
363  return;
364  }
365  } else {
366  // if we're doing an untagged analysis we will only use the negative PDFs
367  if ( negPdf==0 ) {
368  std::cerr << "ERROR in LauCPFitModel::setBkgndPdfs : The negative PDF pointer is null." << std::endl;
369  return;
370  }
371  if ( posPdf!=0 ) {
372  std::cerr << "WARNING in LauCPFitModel::setBkgndPdfs : Doing an untagged fit so will not use the positive PDF." << std::endl;
373  }
374  }
375 
376  // check that this background name is valid
377  if ( ! this->validBkgndClass( bkgndClass ) ) {
378  std::cerr << "ERROR in LauCPFitModel::setBkgndPdfs : Invalid background class \"" << bkgndClass << "\"." << std::endl;
379  std::cerr << " : Background class names must be provided in \"setBkgndClassNames\" before any other background-related actions can be performed." << std::endl;
380  return;
381  }
382 
383  UInt_t bkgndID = this->bkgndClassID( bkgndClass );
384  negBkgndPdfs_[bkgndID].push_back(negPdf);
385  posBkgndPdfs_[bkgndID].push_back(posPdf);
386 
387  usingBkgnd_ = kTRUE;
388 }
389 
391 {
392  // Resize the coeffPars vector if not already done
393  if ( coeffPars_.empty() ) {
394  const UInt_t nNegAmp = negSigModel_->getnTotAmp();
395  const UInt_t nPosAmp = posSigModel_->getnTotAmp();
396  if ( nNegAmp != nPosAmp ) {
397  std::cerr << "ERROR in LauCPFitModel::setAmpCoeffSet : Unequal number of signal DP components in the negative and positive models: " << nNegAmp << " != " << nPosAmp << std::endl;
398  gSystem->Exit(EXIT_FAILURE);
399  }
400  coeffPars_.resize( nNegAmp );
401  for (std::vector<LauAbsCoeffSet*>::iterator iter = coeffPars_.begin(); iter != coeffPars_.end(); ++iter) {
402  (*iter) = 0;
403  }
404  fitFracAsymm_.resize( nNegAmp );
405  acp_.resize( nNegAmp );
406  }
407 
408  // Is there a component called compName in the signal model?
409  TString compName(coeffSet->name());
410  TString conjName = negSigModel_->getConjResName(compName);
411  const Int_t negIndex = negSigModel_->resonanceIndex(compName);
412  const Int_t posIndex = posSigModel_->resonanceIndex(conjName);
413  if ( negIndex < 0 ) {
414  std::cerr << "ERROR in LauCPFitModel::setAmpCoeffSet : " << negParent_ << " signal DP model doesn't contain component \"" << compName << "\"." << std::endl;
415  return;
416  }
417  if ( posIndex < 0 ) {
418  std::cerr << "ERROR in LauCPFitModel::setAmpCoeffSet : " << posParent_ << " signal DP model doesn't contain component \"" << conjName << "\"." << std::endl;
419  return;
420  }
421  if ( posIndex != negIndex ) {
422  std::cerr << "ERROR in LauCPFitModel::setAmpCoeffSet : " << negParent_ << " signal DP model and " << posParent_ << " signal DP model have different indices for components \"" << compName << "\" and \"" << conjName << "\"." << std::endl;
423  return;
424  }
425 
426  // Do we already have it in our list of names?
427  if ( coeffPars_[negIndex] != 0 && coeffPars_[negIndex]->name() == compName) {
428  std::cerr << "ERROR in LauCPFitModel::setAmpCoeffSet : Have already set coefficients for \"" << compName << "\"." << std::endl;
429  return;
430  }
431 
432  coeffSet->index(negIndex);
433  coeffPars_[negIndex] = coeffSet;
434 
435  TString parName = coeffSet->baseName(); parName += "FitFracAsym";
436  fitFracAsymm_[negIndex] = LauParameter(parName, 0.0, -1.0, 1.0);
437 
438  acp_[negIndex] = coeffSet->acp();
439 
440  ++nSigComp_;
441 
442  std::cout << "INFO in LauCPFitModel::setAmpCoeffSet : Added coefficients for component \"" << compName << "\" to the fit model." << std::endl;
443  coeffSet->printParValues();
444 }
445 
447 {
448  // Initialisation
449  if (!this->useDP() && negSignalPdfs_.empty()) {
450  std::cerr << "ERROR in LauCPFitModel::initialise : Signal model doesn't exist for any variable." << std::endl;
451  gSystem->Exit(EXIT_FAILURE);
452  }
453 
454  if ( this->useDP() ) {
455  // Check that we have all the Dalitz-plot models
456  if ((negSigModel_ == 0) || (posSigModel_ == 0)) {
457  std::cerr << "ERROR in LauCPFitModel::initialise : the pointer to one (neg or pos) of the signal DP models is null.\n";
458  std::cerr << " : Removing the Dalitz Plot from the model." << std::endl;
459  this->useDP(kFALSE);
460  }
461  if ( usingBkgnd_ ) {
462  if ( negBkgndDPModels_.empty() || posBkgndDPModels_.empty() ) {
463  std::cerr << "ERROR in LauCPFitModel::initialise : No background DP models found.\n";
464  std::cerr << " : Removing the Dalitz plot from the model." << std::endl;
465  this->useDP(kFALSE);
466  }
467  for (LauBkgndDPModelList::const_iterator dpmodel_iter = negBkgndDPModels_.begin(); dpmodel_iter != negBkgndDPModels_.end(); ++dpmodel_iter ) {
468  if ( (*dpmodel_iter) == 0 ) {
469  std::cerr << "ERROR in LauCPFitModel::initialise : The pointer to one of the background DP models is null.\n";
470  std::cerr << " : Removing the Dalitz Plot from the model." << std::endl;
471  this->useDP(kFALSE);
472  break;
473  }
474  }
475  for (LauBkgndDPModelList::const_iterator dpmodel_iter = posBkgndDPModels_.begin(); dpmodel_iter != posBkgndDPModels_.end(); ++dpmodel_iter ) {
476  if ( (*dpmodel_iter) == 0 ) {
477  std::cerr << "ERROR in LauCPFitModel::initialise : The pointer to one of the background DP models is null.\n";
478  std::cerr << " : Removing the Dalitz Plot from the model." << std::endl;
479  this->useDP(kFALSE);
480  break;
481  }
482  }
483  }
484 
485  // Need to check that the number of components we have and that the dynamics has matches up
486  const UInt_t nNegAmp = negSigModel_->getnTotAmp();
487  const UInt_t nPosAmp = posSigModel_->getnTotAmp();
488  if ( nNegAmp != nPosAmp ) {
489  std::cerr << "ERROR in LauCPFitModel::initialise : Unequal number of signal DP components in the negative and positive models: " << nNegAmp << " != " << nPosAmp << std::endl;
490  gSystem->Exit(EXIT_FAILURE);
491  }
492  if ( nNegAmp != nSigComp_ ) {
493  std::cerr << "ERROR in LauCPFitModel::initialise : Number of signal DP components in the model (" << nNegAmp << ") not equal to number of coefficients supplied (" << nSigComp_ << ")." << std::endl;
494  gSystem->Exit(EXIT_FAILURE);
495  }
496 
497 
498  // From the initial parameter values calculate the coefficients
499  // so they can be passed to the signal model
500  this->updateCoeffs();
501 
502  // If all is well, go ahead and initialise them
503  this->initialiseDPModels();
504  }
505 
506  // Next check that, if a given component is being used we've got the
507  // right number of PDFs for all the variables involved
508  // TODO - should probably check variable names and so on as well
509 
510  UInt_t nsigpdfvars(0);
511  for ( LauPdfList::const_iterator pdf_iter = negSignalPdfs_.begin(); pdf_iter != negSignalPdfs_.end(); ++pdf_iter ) {
512  std::vector<TString> varNames = (*pdf_iter)->varNames();
513  for ( std::vector<TString>::const_iterator var_iter = varNames.begin(); var_iter != varNames.end(); ++var_iter ) {
514  if ( (*var_iter) != "m13Sq" && (*var_iter) != "m23Sq" ) {
515  ++nsigpdfvars;
516  }
517  }
518  }
519  if (useSCF_) {
520  UInt_t nscfpdfvars(0);
521  for ( LauPdfList::const_iterator pdf_iter = negScfPdfs_.begin(); pdf_iter != negScfPdfs_.end(); ++pdf_iter ) {
522  std::vector<TString> varNames = (*pdf_iter)->varNames();
523  for ( std::vector<TString>::const_iterator var_iter = varNames.begin(); var_iter != varNames.end(); ++var_iter ) {
524  if ( (*var_iter) != "m13Sq" && (*var_iter) != "m23Sq" ) {
525  ++nscfpdfvars;
526  }
527  }
528  }
529  if (nscfpdfvars != nsigpdfvars) {
530  std::cerr << "ERROR in LauCPFitModel::initialise : There are " << nsigpdfvars << " TM signal PDF variables but " << nscfpdfvars << " SCF signal PDF variables." << std::endl;
531  gSystem->Exit(EXIT_FAILURE);
532  }
533  }
534  if (usingBkgnd_) {
535  for (LauBkgndPdfsList::const_iterator bgclass_iter = negBkgndPdfs_.begin(); bgclass_iter != negBkgndPdfs_.end(); ++bgclass_iter) {
536  UInt_t nbkgndpdfvars(0);
537  const LauPdfList& pdfList = (*bgclass_iter);
538  for ( LauPdfList::const_iterator pdf_iter = pdfList.begin(); pdf_iter != pdfList.end(); ++pdf_iter ) {
539  std::vector<TString> varNames = (*pdf_iter)->varNames();
540  for ( std::vector<TString>::const_iterator var_iter = varNames.begin(); var_iter != varNames.end(); ++var_iter ) {
541  if ( (*var_iter) != "m13Sq" && (*var_iter) != "m23Sq" ) {
542  ++nbkgndpdfvars;
543  }
544  }
545  }
546  if (nbkgndpdfvars != nsigpdfvars) {
547  std::cerr << "ERROR in LauCPFitModel::initialise : There are " << nsigpdfvars << " signal PDF variables but " << nbkgndpdfvars << " bkgnd PDF variables." << std::endl;
548  gSystem->Exit(EXIT_FAILURE);
549  }
550  }
551  }
552 
553  // Clear the vectors of parameter information so we can start from scratch
554  this->clearFitParVectors();
555 
556  // Set the fit parameters for signal and background models
557  this->setSignalDPParameters();
558 
559  // Set the fit parameters for the various extra PDFs
560  this->setExtraPdfParameters();
561 
562  // Set the initial bg and signal events
563  this->setFitNEvents();
564 
565  // Check that we have the expected number of fit variables
566  const LauParameterPList& fitVars = this->fitPars();
567  if (fitVars.size() != (nSigDPPar_ + nExtraPdfPar_ + nNormPar_)) {
568  std::cerr << "ERROR in LauCPFitModel::initialise : Number of fit parameters not of expected size. Exiting" << std::endl;
569  gSystem->Exit(EXIT_FAILURE);
570  }
571 
572  this->setExtraNtupleVars();
573 }
574 
576 {
577  //std::cout << "INFO in LauCPFitModel::recalculateNormalizationInDPModels : Recalc Norm in DP model" << std::endl;
582 }
583 
585 {
586  std::cout << "INFO in LauCPFitModel::initialiseDPModels : Initialising signal DP model" << std::endl;
589 
590  if (usingBkgnd_ == kTRUE) {
591  for (LauBkgndDPModelList::iterator iter = negBkgndDPModels_.begin(); iter != negBkgndDPModels_.end(); ++iter) {
592  (*iter)->initialise();
593  }
594  for (LauBkgndDPModelList::iterator iter = posBkgndDPModels_.begin(); iter != posBkgndDPModels_.end(); ++iter) {
595  (*iter)->initialise();
596  }
597  }
598 }
599 
601 {
602  // Set the fit parameters for the signal model.
603 
604  nSigDPPar_ = 0;
605  if ( ! this->useDP() ) {
606  return;
607  }
608 
609  std::cout << "INFO in LauCPFitModel::setSignalDPParameters : Setting the initial fit parameters for the signal DP model." << std::endl;
610 
611  // Place isobar coefficient parameters in vector of fit variables
612  LauParameterPList& fitVars = this->fitPars();
613  for (UInt_t i = 0; i < nSigComp_; i++) {
614  LauParameterPList pars = coeffPars_[i]->getParameters();
615  for (LauParameterPList::iterator iter = pars.begin(); iter != pars.end(); ++iter) {
616  if ( !(*iter)->clone() ) {
617  fitVars.push_back(*iter);
618  ++nSigDPPar_;
619  }
620  }
621  }
622 
623  // Obtain the resonance parameters and place them in the vector of fit variables and in a separate vector
624  // Need to make sure that they are unique because some might appear in both DP models
625  LauParameterPSet& resVars = this->resPars();
626  resVars.clear();
627 
630 
631  for ( LauParameterPList::iterator iter = negSigDPPars.begin(); iter != negSigDPPars.end(); ++iter ) {
632  if ( resVars.insert(*iter).second ) {
633  fitVars.push_back(*iter);
634  ++nSigDPPar_;
635  }
636  }
637  for ( LauParameterPList::iterator iter = posSigDPPars.begin(); iter != posSigDPPars.end(); ++iter ) {
638  if ( resVars.insert(*iter).second ) {
639  fitVars.push_back(*iter);
640  ++nSigDPPar_;
641  }
642  }
643 }
644 
646 {
647  // Include all the parameters of the PDF in the fit
648  // NB all of them are passed to the fit, even though some have been fixed through parameter.fixed(kTRUE)
649  // With the new "cloned parameter" scheme only "original" parameters are passed to the fit.
650  // Their clones are updated automatically when the originals are updated.
651 
652  nExtraPdfPar_ = 0;
653 
655  if ( tagged_ ) {
657  }
658 
659  if (useSCF_ == kTRUE) {
661  if ( tagged_ ) {
663  }
664  }
665 
666  if (usingBkgnd_ == kTRUE) {
667  for (LauBkgndPdfsList::iterator iter = negBkgndPdfs_.begin(); iter != negBkgndPdfs_.end(); ++iter) {
668  nExtraPdfPar_ += this->addFitParameters(*iter);
669  }
670  if ( tagged_ ) {
671  for (LauBkgndPdfsList::iterator iter = posBkgndPdfs_.begin(); iter != posBkgndPdfs_.end(); ++iter) {
672  nExtraPdfPar_ += this->addFitParameters(*iter);
673  }
674  }
675  }
676 }
677 
679 {
680  if ( signalEvents_ == 0 ) {
681  std::cerr << "ERROR in LauCPFitModel::setFitNEvents : Signal yield not defined." << std::endl;
682  return;
683  }
684  nNormPar_ = 0;
685 
686  // initialise the total number of events to be the sum of all the hypotheses
687  Double_t nTotEvts = signalEvents_->value();
688  for (LauBkgndYieldList::const_iterator iter = bkgndEvents_.begin(); iter != bkgndEvents_.end(); ++iter) {
689  nTotEvts += (*iter)->value();
690  if ( (*iter) == 0 ) {
691  std::cerr << "ERROR in LauCPFitModel::setFitNEvents : Background yield not defined." << std::endl;
692  return;
693  }
694  }
695  this->eventsPerExpt(TMath::FloorNint(nTotEvts));
696 
697  LauParameterPList& fitVars = this->fitPars();
698 
699  // if doing an extended ML fit add the number of signal events into the fit parameters
700  if (this->doEMLFit()) {
701  std::cout << "INFO in LauCPFitModel::setFitNEvents : Initialising number of events for signal and background components..." << std::endl;
702  // add the signal fraction to the list of fit parameters
703  if(!signalEvents_->fixed()) {
704  fitVars.push_back(signalEvents_);
705  ++nNormPar_;
706  }
707  } else {
708  std::cout << "INFO in LauCPFitModel::setFitNEvents : Initialising number of events for background components (and hence signal)..." << std::endl;
709  }
710 
711  // if not using the DP in the model we need an explicit signal asymmetry parameter
712  if (this->useDP() == kFALSE) {
713  if(!signalAsym_->fixed()) {
714  fitVars.push_back(signalAsym_);
715  ++nNormPar_;
716  }
717  }
718 
719  if (useSCF_ && !useSCFHist_) {
720  if(!scfFrac_.fixed()) {
721  fitVars.push_back(&scfFrac_);
722  ++nNormPar_;
723  }
724  }
725 
726  if (usingBkgnd_ == kTRUE) {
727  for (LauBkgndYieldList::iterator iter = bkgndEvents_.begin(); iter != bkgndEvents_.end(); ++iter) {
728  LauParameter* parameter = (*iter);
729  if(!parameter->fixed()) {
730  fitVars.push_back(parameter);
731  ++nNormPar_;
732  }
733  }
734  for (LauBkgndYieldList::iterator iter = bkgndAsym_.begin(); iter != bkgndAsym_.end(); ++iter) {
735  LauParameter* parameter = (*iter);
736  if(!parameter->fixed()) {
737  fitVars.push_back(parameter);
738  ++nNormPar_;
739  }
740  }
741  }
742 }
743 
745 {
746  // Set-up other parameters derived from the fit results, e.g. fit fractions.
747 
748  if (this->useDP() != kTRUE) {
749  return;
750  }
751 
752  // First clear the vectors so we start from scratch
753  this->clearExtraVarVectors();
754 
755  LauParameterList& extraVars = this->extraPars();
756 
757  // Add the positive and negative fit fractions for each signal component
759  if (negFitFrac_.size() != nSigComp_) {
760  std::cerr << "ERROR in LauCPFitModel::setExtraNtupleVars : Initial Fit Fraction array of unexpected dimension: " << negFitFrac_.size() << std::endl;
761  gSystem->Exit(EXIT_FAILURE);
762  }
763  for (UInt_t i(0); i<nSigComp_; ++i) {
764  if (negFitFrac_[i].size() != nSigComp_) {
765  std::cerr << "ERROR in LauCPFitModel::setExtraNtupleVars : Initial Fit Fraction array of unexpected dimension: " << negFitFrac_[i].size() << std::endl;
766  gSystem->Exit(EXIT_FAILURE);
767  }
768  }
769 
771  if (posFitFrac_.size() != nSigComp_) {
772  std::cerr << "ERROR in LauCPFitModel::setExtraNtupleVars : Initial Fit Fraction array of unexpected dimension: " << posFitFrac_.size() << std::endl;
773  gSystem->Exit(EXIT_FAILURE);
774  }
775  for (UInt_t i(0); i<nSigComp_; ++i) {
776  if (posFitFrac_[i].size() != nSigComp_) {
777  std::cerr << "ERROR in LauCPFitModel::setExtraNtupleVars : Initial Fit Fraction array of unexpected dimension: " << posFitFrac_[i].size() << std::endl;
778  gSystem->Exit(EXIT_FAILURE);
779  }
780  }
781 
782  // Add the positive and negative fit fractions that have not been corrected for the efficiency for each signal component
784  if (negFitFracEffUnCorr_.size() != nSigComp_) {
785  std::cerr << "ERROR in LauCPFitModel::setExtraNtupleVars : Initial Fit Fraction array of unexpected dimension: " << negFitFracEffUnCorr_.size() << std::endl;
786  gSystem->Exit(EXIT_FAILURE);
787  }
788  for (UInt_t i(0); i<nSigComp_; ++i) {
789  if (negFitFracEffUnCorr_[i].size() != nSigComp_) {
790  std::cerr << "ERROR in LauCPFitModel::setExtraNtupleVars : Initial Fit Fraction array of unexpected dimension: " << negFitFracEffUnCorr_[i].size() << std::endl;
791  gSystem->Exit(EXIT_FAILURE);
792  }
793  }
794 
796  if (posFitFracEffUnCorr_.size() != nSigComp_) {
797  std::cerr << "ERROR in LauCPFitModel::setExtraNtupleVars : Initial Fit Fraction array of unexpected dimension: " << posFitFracEffUnCorr_.size() << std::endl;
798  gSystem->Exit(EXIT_FAILURE);
799  }
800  for (UInt_t i(0); i<nSigComp_; ++i) {
801  if (posFitFracEffUnCorr_[i].size() != nSigComp_) {
802  std::cerr << "ERROR in LauCPFitModel::setExtraNtupleVars : Initial Fit Fraction array of unexpected dimension: " << posFitFracEffUnCorr_[i].size() << std::endl;
803  gSystem->Exit(EXIT_FAILURE);
804  }
805  }
806 
807  for (UInt_t i(0); i<nSigComp_; ++i) {
808  for (UInt_t j(i); j<nSigComp_; ++j) {
809  TString name = negFitFrac_[i][j].name();
810  name.Insert( name.Index("FitFrac"), "Neg" );
811  negFitFrac_[i][j].name(name);
812  extraVars.push_back(negFitFrac_[i][j]);
813 
814  name = posFitFrac_[i][j].name();
815  name.Insert( name.Index("FitFrac"), "Pos" );
816  posFitFrac_[i][j].name(name);
817  extraVars.push_back(posFitFrac_[i][j]);
818 
819  name = negFitFracEffUnCorr_[i][j].name();
820  name.Insert( name.Index("FitFrac"), "Neg" );
821  negFitFracEffUnCorr_[i][j].name(name);
822  extraVars.push_back(negFitFracEffUnCorr_[i][j]);
823 
824  name = posFitFracEffUnCorr_[i][j].name();
825  name.Insert( name.Index("FitFrac"), "Pos" );
826  posFitFracEffUnCorr_[i][j].name(name);
827  extraVars.push_back(posFitFracEffUnCorr_[i][j]);
828  }
829  }
830 
831  // Store any extra parameters/quantities from the DP model (e.g. K-matrix total fit fractions)
832  std::vector<LauParameter> negExtraPars = negSigModel_->getExtraParameters();
833  std::vector<LauParameter>::iterator negExtraIter;
834  for (negExtraIter = negExtraPars.begin(); negExtraIter != negExtraPars.end(); ++negExtraIter) {
835  LauParameter negExtraParameter = (*negExtraIter);
836  extraVars.push_back(negExtraParameter);
837  }
838 
839  std::vector<LauParameter> posExtraPars = posSigModel_->getExtraParameters();
840  std::vector<LauParameter>::iterator posExtraIter;
841  for (posExtraIter = posExtraPars.begin(); posExtraIter != posExtraPars.end(); ++posExtraIter) {
842  LauParameter posExtraParameter = (*posExtraIter);
843  extraVars.push_back(posExtraParameter);
844  }
845 
846  // Now add in the DP efficiency value
847  Double_t initMeanEff = negSigModel_->getMeanEff().initValue();
848  negMeanEff_.value(initMeanEff);
849  negMeanEff_.genValue(initMeanEff);
850  negMeanEff_.initValue(initMeanEff);
851  extraVars.push_back(negMeanEff_);
852 
853  initMeanEff = posSigModel_->getMeanEff().initValue();
854  posMeanEff_.value(initMeanEff);
855  posMeanEff_.genValue(initMeanEff);
856  posMeanEff_.initValue(initMeanEff);
857  extraVars.push_back(posMeanEff_);
858 
859  // Also add in the DP rates
860  Double_t initDPRate = negSigModel_->getDPRate().initValue();
861  negDPRate_.value(initDPRate);
862  negDPRate_.genValue(initDPRate);
863  negDPRate_.initValue(initDPRate);
864  extraVars.push_back(negDPRate_);
865 
866  initDPRate = posSigModel_->getDPRate().initValue();
867  posDPRate_.value(initDPRate);
868  posDPRate_.genValue(initDPRate);
869  posDPRate_.initValue(initDPRate);
870  extraVars.push_back(posDPRate_);
871 
872  // Calculate the CPC and CPV Fit Fractions, ACPs and FitFrac asymmetries
873  this->calcExtraFractions(kTRUE);
874  this->calcAsymmetries(kTRUE);
875 
876  // Add the CP violating and CP conserving fit fractions for each signal component
877  for (UInt_t i = 0; i < nSigComp_; i++) {
878  for (UInt_t j = i; j < nSigComp_; j++) {
879  extraVars.push_back(CPVFitFrac_[i][j]);
880  }
881  }
882  for (UInt_t i = 0; i < nSigComp_; i++) {
883  for (UInt_t j = i; j < nSigComp_; j++) {
884  extraVars.push_back(CPCFitFrac_[i][j]);
885  }
886  }
887 
888  // Add the Fit Fraction asymmetry for each signal component
889  for (UInt_t i = 0; i < nSigComp_; i++) {
890  extraVars.push_back(fitFracAsymm_[i]);
891  }
892 
893  // Add the calculated CP asymmetry for each signal component
894  for (UInt_t i = 0; i < nSigComp_; i++) {
895  extraVars.push_back(acp_[i]);
896  }
897 }
898 
899 void LauCPFitModel::calcExtraFractions(Bool_t initValues)
900 {
901  // Calculate the CP-conserving and CP-violating fit fractions
902 
903  if (initValues) {
904  // create the structure
905  CPCFitFrac_.clear();
906  CPVFitFrac_.clear();
907  CPCFitFrac_.resize(nSigComp_);
908  CPVFitFrac_.resize(nSigComp_);
909  for (UInt_t i(0); i<nSigComp_; ++i) {
910  CPCFitFrac_[i].resize(nSigComp_);
911  CPVFitFrac_[i].resize(nSigComp_);
912 
913  for (UInt_t j(i); j<nSigComp_; ++j) {
914  TString name = negFitFrac_[i][j].name();
915  name.Replace( name.Index("Neg"), 3, "CPC" );
916  CPCFitFrac_[i][j].name( name );
917  CPCFitFrac_[i][j].valueAndRange( 0.0, -100.0, 100.0 );
918 
919  name = negFitFrac_[i][j].name();
920  name.Replace( name.Index("Neg"), 3, "CPV" );
921  CPVFitFrac_[i][j].name( name );
922  CPVFitFrac_[i][j].valueAndRange( 0.0, -100.0, 100.0 );
923  }
924  }
925  }
926 
927  Double_t denom = negDPRate_.value() + posDPRate_.value();
928 
929  for (UInt_t i(0); i<nSigComp_; ++i) {
930  for (UInt_t j(i); j<nSigComp_; ++j) {
931 
932  Double_t negTerm = negFitFrac_[i][j].value()*negDPRate_.value();
933  Double_t posTerm = posFitFrac_[i][j].value()*posDPRate_.value();
934 
935  Double_t cpcFitFrac = (negTerm + posTerm)/denom;
936  Double_t cpvFitFrac = (negTerm - posTerm)/denom;
937 
938  CPCFitFrac_[i][j].value(cpcFitFrac);
939  CPVFitFrac_[i][j].value(cpvFitFrac);
940 
941  if (initValues) {
942  CPCFitFrac_[i][j].genValue(cpcFitFrac);
943  CPCFitFrac_[i][j].initValue(cpcFitFrac);
944 
945  CPVFitFrac_[i][j].genValue(cpvFitFrac);
946  CPVFitFrac_[i][j].initValue(cpvFitFrac);
947  }
948  }
949  }
950 }
951 
952 void LauCPFitModel::calcAsymmetries(Bool_t initValues)
953 {
954  // Calculate the CP asymmetries
955  // Also calculate the fit fraction asymmetries
956 
957  for (UInt_t i = 0; i < nSigComp_; i++) {
958 
959  acp_[i] = coeffPars_[i]->acp();
960 
961  LauAsymmCalc asymmCalc(negFitFrac_[i][i].value(), posFitFrac_[i][i].value());
962  Double_t asym = asymmCalc.getAsymmetry();
963  fitFracAsymm_[i].value(asym);
964  if (initValues) {
965  fitFracAsymm_[i].genValue(asym);
966  fitFracAsymm_[i].initValue(asym);
967  }
968  }
969 }
970 
971 void LauCPFitModel::finaliseFitResults(const TString& tablePrefixName)
972 {
973  // Retrieve parameters from the fit results for calculations and toy generation
974  // and eventually store these in output root ntuples/text files
975 
976  // Now take the fit parameters and update them as necessary
977  // i.e. to make mag > 0.0, phase in the right range.
978  // This function will also calculate any other values, such as the
979  // fit fractions, using any errors provided by fitParErrors as appropriate.
980  // Also obtain the pull values: (measured - generated)/(average error)
981 
982  if (this->useDP() == kTRUE) {
983  for (UInt_t i = 0; i < nSigComp_; ++i) {
984  // Check whether we have "a/b > 0.0", and phases in the right range
985  coeffPars_[i]->finaliseValues();
986  }
987  }
988 
989  // update the pulls on the event fractions and asymmetries
990  if (this->doEMLFit()) {
992  }
993  if (this->useDP() == kFALSE) {
995  }
996  if (useSCF_ && !useSCFHist_) {
998  }
999  if (usingBkgnd_ == kTRUE) {
1000  for (LauBkgndYieldList::iterator iter = bkgndEvents_.begin(); iter != bkgndEvents_.end(); ++iter) {
1001  (*iter)->updatePull();
1002  }
1003  for (LauBkgndYieldList::iterator iter = bkgndAsym_.begin(); iter != bkgndAsym_.end(); ++iter) {
1004  (*iter)->updatePull();
1005  }
1006  }
1007 
1008  // Update the pulls on all the extra PDFs' parameters
1011  if (useSCF_ == kTRUE) {
1014  }
1015  if (usingBkgnd_ == kTRUE) {
1016  for (LauBkgndPdfsList::iterator iter = negBkgndPdfs_.begin(); iter != negBkgndPdfs_.end(); ++iter) {
1017  this->updateFitParameters(*iter);
1018  }
1019  for (LauBkgndPdfsList::iterator iter = posBkgndPdfs_.begin(); iter != posBkgndPdfs_.end(); ++iter) {
1020  this->updateFitParameters(*iter);
1021  }
1022  }
1023 
1024  // Fill the fit results to the ntuple
1025 
1026  // update the coefficients and then calculate the fit fractions and ACP's
1027  if (this->useDP() == kTRUE) {
1028  this->updateCoeffs();
1031 
1032  LauParArray negFitFrac = negSigModel_->getFitFractions();
1033  if (negFitFrac.size() != nSigComp_) {
1034  std::cerr << "ERROR in LauCPFitModel::finaliseFitResults : Fit Fraction array of unexpected dimension: " << negFitFrac.size() << std::endl;
1035  gSystem->Exit(EXIT_FAILURE);
1036  }
1037  for (UInt_t i(0); i<nSigComp_; ++i) {
1038  if (negFitFrac[i].size() != nSigComp_) {
1039  std::cerr << "ERROR in LauCPFitModel::finaliseFitResults : Fit Fraction array of unexpected dimension: " << negFitFrac[i].size() << std::endl;
1040  gSystem->Exit(EXIT_FAILURE);
1041  }
1042  }
1043 
1044  LauParArray posFitFrac = posSigModel_->getFitFractions();
1045  if (posFitFrac.size() != nSigComp_) {
1046  std::cerr << "ERROR in LauCPFitModel::finaliseFitResults : Fit Fraction array of unexpected dimension: " << posFitFrac.size() << std::endl;
1047  gSystem->Exit(EXIT_FAILURE);
1048  }
1049  for (UInt_t i(0); i<nSigComp_; ++i) {
1050  if (posFitFrac[i].size() != nSigComp_) {
1051  std::cerr << "ERROR in LauCPFitModel::finaliseFitResults : Fit Fraction array of unexpected dimension: " << posFitFrac[i].size() << std::endl;
1052  gSystem->Exit(EXIT_FAILURE);
1053  }
1054  }
1055 
1057  if (negFitFracEffUnCorr.size() != nSigComp_) {
1058  std::cerr << "ERROR in LauCPFitModel::finaliseFitResults : Fit Fraction array of unexpected dimension: " << negFitFracEffUnCorr.size() << std::endl;
1059  gSystem->Exit(EXIT_FAILURE);
1060  }
1061  for (UInt_t i(0); i<nSigComp_; ++i) {
1062  if (negFitFracEffUnCorr[i].size() != nSigComp_) {
1063  std::cerr << "ERROR in LauCPFitModel::finaliseFitResults : Fit Fraction array of unexpected dimension: " << negFitFracEffUnCorr[i].size() << std::endl;
1064  gSystem->Exit(EXIT_FAILURE);
1065  }
1066  }
1067 
1069  if (posFitFracEffUnCorr.size() != nSigComp_) {
1070  std::cerr << "ERROR in LauCPFitModel::finaliseFitResults : Fit Fraction array of unexpected dimension: " << posFitFracEffUnCorr.size() << std::endl;
1071  gSystem->Exit(EXIT_FAILURE);
1072  }
1073  for (UInt_t i(0); i<nSigComp_; ++i) {
1074  if (posFitFracEffUnCorr[i].size() != nSigComp_) {
1075  std::cerr << "ERROR in LauCPFitModel::finaliseFitResults : Fit Fraction array of unexpected dimension: " << posFitFracEffUnCorr[i].size() << std::endl;
1076  gSystem->Exit(EXIT_FAILURE);
1077  }
1078  }
1079 
1080  for (UInt_t i(0); i<nSigComp_; ++i) {
1081  for (UInt_t j(i); j<nSigComp_; ++j) {
1082  negFitFrac_[i][j].value(negFitFrac[i][j].value());
1083  posFitFrac_[i][j].value(posFitFrac[i][j].value());
1084  negFitFracEffUnCorr_[i][j].value(negFitFracEffUnCorr[i][j].value());
1085  posFitFracEffUnCorr_[i][j].value(posFitFracEffUnCorr[i][j].value());
1086  }
1087  }
1088 
1093 
1094  this->calcExtraFractions();
1095  this->calcAsymmetries();
1096 
1097  // Then store the final fit parameters, and any extra parameters for
1098  // the signal model (e.g. fit fractions, FF asymmetries, ACPs, mean efficiency and DP rate)
1099 
1100  this->clearExtraVarVectors();
1101  LauParameterList& extraVars = this->extraPars();
1102 
1103  // Add the positive and negative fit fractions for each signal component
1104  for (UInt_t i(0); i<nSigComp_; ++i) {
1105  for (UInt_t j(i); j<nSigComp_; ++j) {
1106  extraVars.push_back(negFitFrac_[i][j]);
1107  extraVars.push_back(posFitFrac_[i][j]);
1108  extraVars.push_back(negFitFracEffUnCorr_[i][j]);
1109  extraVars.push_back(posFitFracEffUnCorr_[i][j]);
1110  }
1111  }
1112 
1113  // Store any extra parameters/quantities from the DP model (e.g. K-matrix total fit fractions)
1114  std::vector<LauParameter> negExtraPars = negSigModel_->getExtraParameters();
1115  std::vector<LauParameter>::iterator negExtraIter;
1116  for (negExtraIter = negExtraPars.begin(); negExtraIter != negExtraPars.end(); ++negExtraIter) {
1117  LauParameter negExtraParameter = (*negExtraIter);
1118  extraVars.push_back(negExtraParameter);
1119  }
1120 
1121  std::vector<LauParameter> posExtraPars = posSigModel_->getExtraParameters();
1122  std::vector<LauParameter>::iterator posExtraIter;
1123  for (posExtraIter = posExtraPars.begin(); posExtraIter != posExtraPars.end(); ++posExtraIter) {
1124  LauParameter posExtraParameter = (*posExtraIter);
1125  extraVars.push_back(posExtraParameter);
1126  }
1127 
1128  extraVars.push_back(negMeanEff_);
1129  extraVars.push_back(posMeanEff_);
1130  extraVars.push_back(negDPRate_);
1131  extraVars.push_back(posDPRate_);
1132 
1133  for (UInt_t i = 0; i < nSigComp_; i++) {
1134  for (UInt_t j(i); j<nSigComp_; ++j) {
1135  extraVars.push_back(CPVFitFrac_[i][j]);
1136  }
1137  }
1138  for (UInt_t i = 0; i < nSigComp_; i++) {
1139  for (UInt_t j(i); j<nSigComp_; ++j) {
1140  extraVars.push_back(CPCFitFrac_[i][j]);
1141  }
1142  }
1143  for (UInt_t i(0); i<nSigComp_; ++i) {
1144  extraVars.push_back(fitFracAsymm_[i]);
1145  }
1146  for (UInt_t i(0); i<nSigComp_; ++i) {
1147  extraVars.push_back(acp_[i]);
1148  }
1149 
1150  this->printFitFractions(std::cout);
1151  this->printAsymmetries(std::cout);
1152  }
1153 
1154  const LauParameterPList& fitVars = this->fitPars();
1155  const LauParameterList& extraVars = this->extraPars();
1156  LauFitNtuple* ntuple = this->fitNtuple();
1157  ntuple->storeParsAndErrors(fitVars, extraVars);
1158 
1159  // find out the correlation matrix for the parameters
1160  ntuple->storeCorrMatrix(this->iExpt(), this->fitStatus(), this->covarianceMatrix());
1161 
1162  // Fill the data into ntuple
1163  ntuple->updateFitNtuple();
1164 
1165  // Print out the partial fit fractions, phases and the
1166  // averaged efficiency, reweighted by the dynamics (and anything else)
1167  if (this->writeLatexTable()) {
1168  TString sigOutFileName(tablePrefixName);
1169  sigOutFileName += "_"; sigOutFileName += this->iExpt(); sigOutFileName += "Expt.tex";
1170  this->writeOutTable(sigOutFileName);
1171  }
1172 }
1173 
1174 void LauCPFitModel::printFitFractions(std::ostream& output)
1175 {
1176  // Print out Fit Fractions, total DP rate and mean efficiency
1177  // First for the B- events
1178  for (UInt_t i = 0; i < nSigComp_; i++) {
1179  const TString compName(coeffPars_[i]->name());
1180  output << negParent_ << " FitFraction for component " << i << " (" << compName << ") = " << negFitFrac_[i][i] << std::endl;
1181  }
1182  output << negParent_ << " overall DP rate (integral of matrix element squared) = " << negDPRate_ << std::endl;
1183  output << negParent_ << " average efficiency weighted by whole DP dynamics = " << negMeanEff_ << std::endl;
1184 
1185  // Then for the positive sample
1186  for (UInt_t i = 0; i < nSigComp_; i++) {
1187  const TString compName(coeffPars_[i]->name());
1188  const TString conjName(negSigModel_->getConjResName(compName));
1189  output << posParent_ << " FitFraction for component " << i << " (" << conjName << ") = " << posFitFrac_[i][i] << std::endl;
1190  }
1191  output << posParent_ << " overall DP rate (integral of matrix element squared) = " << posDPRate_ << std::endl;
1192  output << posParent_ << " average efficiency weighted by whole DP dynamics = " << posMeanEff_ << std::endl;
1193 }
1194 
1195 void LauCPFitModel::printAsymmetries(std::ostream& output)
1196 {
1197  for (UInt_t i = 0; i < nSigComp_; i++) {
1198  const TString compName(coeffPars_[i]->name());
1199  output << "Fit Fraction asymmetry for component " << i << " (" << compName << ") = " << fitFracAsymm_[i] << std::endl;
1200  }
1201  for (UInt_t i = 0; i < nSigComp_; i++) {
1202  const TString compName(coeffPars_[i]->name());
1203  output << "ACP for component " << i << " (" << compName << ") = " << acp_[i] << std::endl;
1204  }
1205 }
1206 
1207 void LauCPFitModel::writeOutTable(const TString& outputFile)
1208 {
1209  // Write out the results of the fit to a tex-readable table
1210  // TODO - need to include the yields in this table
1211  std::ofstream fout(outputFile);
1212  LauPrint print;
1213 
1214  std::cout << "INFO in LauCPFitModel::writeOutTable : Writing out results of the fit to the tex file " << outputFile << std::endl;
1215 
1216  if (this->useDP() == kTRUE) {
1217  // print the fit coefficients in one table
1218  coeffPars_.front()->printTableHeading(fout);
1219  for (UInt_t i = 0; i < nSigComp_; i++) {
1220  coeffPars_[i]->printTableRow(fout);
1221  }
1222  fout << "\\hline" << std::endl;
1223  fout << "\\end{tabular}" << std::endl << std::endl;
1224 
1225  // print the fit fractions and asymmetries in another
1226  fout << "\\begin{tabular}{|l|c|c|c|c|}" << std::endl;
1227  fout << "\\hline" << std::endl;
1228  fout << "Component & " << negParent_ << " Fit Fraction & " << posParent_ << " Fit Fraction & Fit Fraction Asymmetry & ACP \\\\" << std::endl;
1229  fout << "\\hline" << std::endl;
1230 
1231  Double_t negFitFracSum(0.0);
1232  Double_t posFitFracSum(0.0);
1233 
1234  for (UInt_t i = 0; i < nSigComp_; i++) {
1235  TString resName = coeffPars_[i]->name();
1236  resName = resName.ReplaceAll("_", "\\_");
1237 
1238  Double_t negFitFrac = negFitFrac_[i][i].value();
1239  Double_t posFitFrac = posFitFrac_[i][i].value();
1240  negFitFracSum += negFitFrac;
1241  posFitFracSum += posFitFrac;
1242 
1243  Double_t fitFracAsymm = fitFracAsymm_[i].value();
1244 
1245  Double_t acp = acp_[i].value();
1246  Double_t acpErr = acp_[i].error();
1247 
1248  fout << resName << " & $";
1249 
1250  print.printFormat(fout, negFitFrac);
1251  fout << "$ & $";
1252  print.printFormat(fout, posFitFrac);
1253  fout << "$ & $";
1254 
1255  print.printFormat(fout, fitFracAsymm);
1256  fout << "$ & $";
1257 
1258  print.printFormat(fout, acp);
1259  fout << " \\pm ";
1260  print.printFormat(fout, acpErr);
1261  fout << "$ \\\\" << std::endl;
1262  }
1263  fout << "\\hline" << std::endl;
1264 
1265  // Also print out sum of fit fractions
1266  fout << "Fit Fraction Sum & $";
1267  print.printFormat(fout, negFitFracSum);
1268  fout << "$ & $";
1269  print.printFormat(fout, posFitFracSum);
1270  fout << "$ & & \\\\" << std::endl;
1271  fout << "\\hline" << std::endl;
1272 
1273  fout << "DP rate & $";
1274  print.printFormat(fout, negDPRate_.value());
1275  fout << "$ & $";
1276  print.printFormat(fout, posDPRate_.value());
1277  fout << "$ & & \\\\" << std::endl;
1278 
1279  fout << "$< \\varepsilon > $ & $";
1280  print.printFormat(fout, negMeanEff_.value());
1281  fout << "$ & $";
1282  print.printFormat(fout, posMeanEff_.value());
1283  fout << "$ & & \\\\" << std::endl;
1284  fout << "\\hline" << std::endl;
1285  fout << "\\end{tabular}" << std::endl << std::endl;
1286  }
1287 
1288  if (!negSignalPdfs_.empty()) {
1289  fout << "\\begin{tabular}{|l|c|}" << std::endl;
1290  fout << "\\hline" << std::endl;
1291  if (useSCF_ == kTRUE) {
1292  fout << "\\Extra TM Signal PDFs' Parameters: & \\\\" << std::endl;
1293  } else {
1294  fout << "\\Extra Signal PDFs' Parameters: & \\\\" << std::endl;
1295  }
1296  this->printFitParameters(negSignalPdfs_, fout);
1297  if ( tagged_ ) {
1298  this->printFitParameters(posSignalPdfs_, fout);
1299  }
1300  if (useSCF_ == kTRUE && !negScfPdfs_.empty()) {
1301  fout << "\\hline" << std::endl;
1302  fout << "\\Extra SCF Signal PDFs' Parameters: & \\\\" << std::endl;
1303  this->printFitParameters(negScfPdfs_, fout);
1304  if ( tagged_ ) {
1305  this->printFitParameters(posScfPdfs_, fout);
1306  }
1307  }
1308  if (usingBkgnd_ == kTRUE && !negBkgndPdfs_.empty()) {
1309  fout << "\\hline" << std::endl;
1310  fout << "\\Extra Background PDFs' Parameters: & \\\\" << std::endl;
1311  for (LauBkgndPdfsList::const_iterator iter = negBkgndPdfs_.begin(); iter != negBkgndPdfs_.end(); ++iter) {
1312  this->printFitParameters(*iter, fout);
1313  }
1314  if ( tagged_ ) {
1315  for (LauBkgndPdfsList::const_iterator iter = posBkgndPdfs_.begin(); iter != posBkgndPdfs_.end(); ++iter) {
1316  this->printFitParameters(*iter, fout);
1317  }
1318  }
1319  }
1320  fout << "\\hline \n\\end{tabular}" << std::endl << std::endl;
1321  }
1322 }
1323 
1325 {
1326  // Update the number of signal events to be total-sum(background events)
1327  this->updateSigEvents();
1328 
1329  // Check whether we want to have randomised initial fit parameters for the signal model
1330  if (this->useRandomInitFitPars() == kTRUE) {
1331  std::cout << "INFO in LauCPFitModel::checkInitFitParams : Setting random parameters for the signal model" << std::endl;
1332  this->randomiseInitFitPars();
1333  }
1334 }
1335 
1337 {
1338  // Only randomise those parameters that are not fixed!
1339  std::cout << "INFO in LauCPFitModel::randomiseInitFitPars : Randomising the initial fit magnitudes and phases of the components..." << std::endl;
1340 
1341  for (UInt_t i = 0; i < nSigComp_; i++) {
1342  coeffPars_[i]->randomiseInitValues();
1343  }
1344 }
1345 
1346 std::pair<LauCPFitModel::LauGenInfo,Bool_t> LauCPFitModel::eventsToGenerate()
1347 {
1348  // Determine the number of events to generate for each hypothesis
1349  // If we're smearing then smear each one individually
1350 
1351  LauGenInfo nEvtsGen;
1352 
1353  // Keep track of whether any yield or asymmetry parameters are blinded
1354  Bool_t blind = kFALSE;
1355 
1356  // Signal
1357  Double_t evtWeight(1.0);
1358  Double_t nEvts = signalEvents_->genValue();
1359  if ( nEvts < 0.0 ) {
1360  evtWeight = -1.0;
1361  nEvts = TMath::Abs( nEvts );
1362  }
1363  if ( signalEvents_->blind() ) {
1364  blind = kTRUE;
1365  }
1366  Double_t asym(0.0);
1367  Double_t sigAsym(0.0);
1368  // need to include this as an alternative in case the DP isn't in the model
1369  if ( !this->useDP() || forceAsym_ ) {
1370  sigAsym = signalAsym_->genValue();
1371  if ( signalAsym_->blind() ) {
1372  blind = kTRUE;
1373  }
1374  } else {
1375  Double_t negRate = negSigModel_->getDPNorm();
1376  Double_t posRate = posSigModel_->getDPNorm();
1377  if (negRate+posRate>1e-30) {
1378  sigAsym = (negRate-posRate)/(negRate+posRate);
1379  }
1380  }
1381  asym = sigAsym;
1382  Int_t nPosEvts = static_cast<Int_t>((nEvts/2.0 * (1.0 - asym)) + 0.5);
1383  Int_t nNegEvts = static_cast<Int_t>((nEvts/2.0 * (1.0 + asym)) + 0.5);
1384  if (this->doPoissonSmearing()) {
1385  nNegEvts = LauRandom::randomFun()->Poisson(nNegEvts);
1386  nPosEvts = LauRandom::randomFun()->Poisson(nPosEvts);
1387  }
1388  nEvtsGen[std::make_pair("signal",-1)] = std::make_pair(nNegEvts,evtWeight);
1389  nEvtsGen[std::make_pair("signal",+1)] = std::make_pair(nPosEvts,evtWeight);
1390 
1391  // backgrounds
1392  const UInt_t nBkgnds = this->nBkgndClasses();
1393  for ( UInt_t bkgndID(0); bkgndID < nBkgnds; ++bkgndID ) {
1394  const TString& bkgndClass = this->bkgndClassName(bkgndID);
1395  const LauParameter* evtsPar = bkgndEvents_[bkgndID];
1396  const LauParameter* asymPar = bkgndAsym_[bkgndID];
1397  if ( evtsPar->blind() || asymPar->blind() ) {
1398  blind = kTRUE;
1399  }
1400  evtWeight = 1.0;
1401  nEvts = TMath::FloorNint( evtsPar->genValue() );
1402  if ( nEvts < 0 ) {
1403  evtWeight = -1.0;
1404  nEvts = TMath::Abs( nEvts );
1405  }
1406  asym = asymPar->genValue();
1407  nPosEvts = static_cast<Int_t>((nEvts/2.0 * (1.0 - asym)) + 0.5);
1408  nNegEvts = static_cast<Int_t>((nEvts/2.0 * (1.0 + asym)) + 0.5);
1409  if (this->doPoissonSmearing()) {
1410  nNegEvts = LauRandom::randomFun()->Poisson(nNegEvts);
1411  nPosEvts = LauRandom::randomFun()->Poisson(nPosEvts);
1412  }
1413  nEvtsGen[std::make_pair(bkgndClass,-1)] = std::make_pair(nNegEvts,evtWeight);
1414  nEvtsGen[std::make_pair(bkgndClass,+1)] = std::make_pair(nPosEvts,evtWeight);
1415  }
1416 
1417  // Print out the information on what we're generating, but only if none of the parameters are blind (otherwise we risk unblinding them!)
1418  if ( !blind ) {
1419  std::cout << "INFO in LauCPFitModel::eventsToGenerate : Generating toy MC with:" << std::endl;
1420  std::cout << " : Signal asymmetry = " << sigAsym << " and number of signal events = " << signalEvents_->genValue() << std::endl;
1421  for ( UInt_t bkgndID(0); bkgndID < nBkgnds; ++bkgndID ) {
1422  const TString& bkgndClass = this->bkgndClassName(bkgndID);
1423  const LauParameter* evtsPar = bkgndEvents_[bkgndID];
1424  const LauParameter* asymPar = bkgndAsym_[bkgndID];
1425  std::cout << " : " << bkgndClass << " asymmetry = " << asymPar->genValue() << " and number of " << bkgndClass << " events = " << evtsPar->genValue() << std::endl;
1426  }
1427  }
1428 
1429  return std::make_pair( nEvtsGen, blind );
1430 }
1431 
1433 {
1434  // Routine to generate toy Monte Carlo events according to the various models we have defined.
1435 
1436  // Determine the number of events to generate for each hypothesis
1437  std::pair<LauGenInfo,Bool_t> info = this->eventsToGenerate();
1438  LauGenInfo nEvts = info.first;
1439  const Bool_t blind = info.second;
1440 
1441  Bool_t genOK(kTRUE);
1442  Int_t evtNum(0);
1443 
1444  const UInt_t nBkgnds = this->nBkgndClasses();
1445  std::vector<TString> bkgndClassNames(nBkgnds);
1446  std::vector<TString> bkgndClassNamesGen(nBkgnds);
1447  for ( UInt_t iBkgnd(0); iBkgnd < nBkgnds; ++iBkgnd ) {
1448  TString name( this->bkgndClassName(iBkgnd) );
1449  bkgndClassNames[iBkgnd] = name;
1450  bkgndClassNamesGen[iBkgnd] = "gen"+name;
1451  }
1452 
1453  const Bool_t storeSCFTruthInfo = ( useSCF_ || ( this->enableEmbedding() &&
1454  negSignalTree_ != 0 && negSignalTree_->haveBranch("mcMatch") &&
1455  posSignalTree_ != 0 && posSignalTree_->haveBranch("mcMatch") ) );
1456 
1457  // Loop over the hypotheses and generate the requested number of events for each one
1458  for (LauGenInfo::const_iterator iter = nEvts.begin(); iter != nEvts.end(); ++iter) {
1459 
1460  const TString& type(iter->first.first);
1461  curEvtCharge_ = iter->first.second;
1462  Double_t evtWeight( iter->second.second );
1463  Int_t nEvtsGen( iter->second.first );
1464 
1465  for (Int_t iEvt(0); iEvt<nEvtsGen; ++iEvt) {
1466 
1467  this->setGenNtupleDoubleBranchValue( "evtWeight", evtWeight );
1468  this->setGenNtupleDoubleBranchValue( "efficiency", 1.0 );
1469 
1470  if (type == "signal") {
1471  this->setGenNtupleIntegerBranchValue("genSig",1);
1472  for ( UInt_t iBkgnd(0); iBkgnd < nBkgnds; ++iBkgnd ) {
1473  this->setGenNtupleIntegerBranchValue( bkgndClassNamesGen[iBkgnd], 0 );
1474  }
1475  genOK = this->generateSignalEvent();
1476  if ( curEvtCharge_ > 0 ){
1477  this->setGenNtupleDoubleBranchValue( "efficiency", posSigModel_->getEvtEff() );
1478  } else {
1479  this->setGenNtupleDoubleBranchValue( "efficiency", negSigModel_->getEvtEff() );
1480  }
1481 
1482  } else {
1483  this->setGenNtupleIntegerBranchValue("genSig",0);
1484  if ( storeSCFTruthInfo ) {
1485  this->setGenNtupleIntegerBranchValue("genTMSig",0);
1486  this->setGenNtupleIntegerBranchValue("genSCFSig",0);
1487  }
1488  UInt_t bkgndID(0);
1489  for ( UInt_t iBkgnd(0); iBkgnd < nBkgnds; ++iBkgnd ) {
1490  Int_t gen(0);
1491  if ( bkgndClassNames[iBkgnd] == type ) {
1492  gen = 1;
1493  bkgndID = iBkgnd;
1494  }
1495  this->setGenNtupleIntegerBranchValue( bkgndClassNamesGen[iBkgnd], gen );
1496  }
1497  genOK = this->generateBkgndEvent(bkgndID);
1498  }
1499  if (!genOK) {
1500  // If there was a problem with the generation then break out and return.
1501  // The problem model will have adjusted itself so that all should be OK next time.
1502  break;
1503  }
1504  if (this->useDP() == kTRUE) {
1505  this->setDPBranchValues();
1506  }
1507 
1508  // Store the event charge
1510 
1511  // Store the event number (within this experiment)
1512  // and then increment it
1513  this->setGenNtupleIntegerBranchValue("iEvtWithinExpt",evtNum);
1514  ++evtNum;
1515 
1516  this->fillGenNtupleBranches();
1517  if ( !blind && (iEvt%500 == 0) ) {
1518  std::cout << "INFO in LauCPFitModel::genExpt : Generated event number " << iEvt << " out of " << nEvtsGen << " " << type << " events." << std::endl;
1519  }
1520  }
1521 
1522  if (!genOK) {
1523  break;
1524  }
1525  }
1526 
1527  if (this->useDP() && genOK) {
1528 
1529  negSigModel_->checkToyMC(kTRUE,kTRUE);
1530  posSigModel_->checkToyMC(kTRUE,kTRUE);
1531 
1532  // Get the fit fractions if they're to be written into the latex table
1533  if (this->writeLatexTable()) {
1534  LauParArray negFitFrac = negSigModel_->getFitFractions();
1535  if (negFitFrac.size() != nSigComp_) {
1536  std::cerr << "ERROR in LauCPFitModel::genExpt : Fit Fraction array of unexpected dimension: " << negFitFrac.size() << std::endl;
1537  gSystem->Exit(EXIT_FAILURE);
1538  }
1539  for (UInt_t i(0); i<nSigComp_; ++i) {
1540  if (negFitFrac[i].size() != nSigComp_) {
1541  std::cerr << "ERROR in LauCPFitModel::genExpt : Fit Fraction array of unexpected dimension: " << negFitFrac[i].size() << std::endl;
1542  gSystem->Exit(EXIT_FAILURE);
1543  }
1544  }
1545  LauParArray posFitFrac = posSigModel_->getFitFractions();
1546  if (posFitFrac.size() != nSigComp_) {
1547  std::cerr << "ERROR in LauCPFitModel::genExpt : Fit Fraction array of unexpected dimension: " << posFitFrac.size() << std::endl;
1548  gSystem->Exit(EXIT_FAILURE);
1549  }
1550  for (UInt_t i(0); i<nSigComp_; ++i) {
1551  if (posFitFrac[i].size() != nSigComp_) {
1552  std::cerr << "ERROR in LauCPFitModel::genExpt : Fit Fraction array of unexpected dimension: " << posFitFrac[i].size() << std::endl;
1553  gSystem->Exit(EXIT_FAILURE);
1554  }
1555  }
1556 
1557  for (UInt_t i(0); i<nSigComp_; ++i) {
1558  for (UInt_t j(i); j<nSigComp_; ++j) {
1559  negFitFrac_[i][j].value(negFitFrac[i][j].value());
1560  posFitFrac_[i][j].value(posFitFrac[i][j].value());
1561  }
1562  }
1567  }
1568  }
1569 
1570  // If we're reusing embedded events or if the generation is being
1571  // reset then clear the lists of used events
1572  if (reuseSignal_ || !genOK) {
1573  if (negSignalTree_) {
1575  }
1576  if (posSignalTree_) {
1578  }
1579  }
1580  for ( UInt_t bkgndID(0); bkgndID < nBkgnds; ++bkgndID ) {
1581  LauEmbeddedData* data = negBkgndTree_[bkgndID];
1582  if (reuseBkgnd_[bkgndID] || !genOK) {
1583  if (data) {
1584  data->clearUsedList();
1585  }
1586  }
1587  }
1588  for ( UInt_t bkgndID(0); bkgndID < nBkgnds; ++bkgndID ) {
1589  LauEmbeddedData* data = posBkgndTree_[bkgndID];
1590  if (reuseBkgnd_[bkgndID] || !genOK) {
1591  if (data) {
1592  data->clearUsedList();
1593  }
1594  }
1595  }
1596 
1597  return genOK;
1598 }
1599 
1601 {
1602  // Generate signal event
1603  Bool_t genOK(kTRUE);
1604  Bool_t genSCF(kFALSE);
1605 
1606  LauIsobarDynamics* model(0);
1607  LauKinematics* kinematics(0);
1608  LauEmbeddedData* embeddedData(0);
1609  LauPdfList* sigPdfs(0);
1610  LauPdfList* scfPdfs(0);
1611 
1612  Bool_t doReweighting(kFALSE);
1613 
1614  if (curEvtCharge_<0) {
1615  model = negSigModel_;
1616  kinematics = negKinematics_;
1617  sigPdfs = &negSignalPdfs_;
1618  scfPdfs = &negScfPdfs_;
1619  if (this->enableEmbedding()) {
1620  embeddedData = negSignalTree_;
1621  doReweighting = useNegReweighting_;
1622  }
1623  } else {
1624  model = posSigModel_;
1625  kinematics = posKinematics_;
1626  if ( tagged_ ) {
1627  sigPdfs = &posSignalPdfs_;
1628  scfPdfs = &posScfPdfs_;
1629  } else {
1630  sigPdfs = &negSignalPdfs_;
1631  scfPdfs = &negScfPdfs_;
1632  }
1633  if (this->enableEmbedding()) {
1634  embeddedData = posSignalTree_;
1635  doReweighting = usePosReweighting_;
1636  }
1637  }
1638 
1639  if (this->useDP()) {
1640  if (embeddedData) {
1641  if (doReweighting) {
1642  // Select a (random) event from the generated data. Then store the
1643  // reconstructed DP co-ords, together with other pdf information,
1644  // as the embedded data.
1645  genOK = embeddedData->getReweightedEvent(model);
1646  } else {
1647  // Just get the information of a (randomly) selected event in the
1648  // embedded data
1649  embeddedData->getEmbeddedEvent(kinematics);
1650  }
1651  genSCF = this->storeSignalMCMatch( embeddedData );
1652  } else {
1653  genOK = model->generate();
1654  if ( genOK && useSCF_ ) {
1655  Double_t frac(0.0);
1656  if ( useSCFHist_ ) {
1657  frac = scfFracHist_->calcEfficiency( kinematics );
1658  } else {
1659  frac = scfFrac_.genValue();
1660  }
1661  if ( frac < LauRandom::randomFun()->Rndm() ) {
1662  this->setGenNtupleIntegerBranchValue("genTMSig",1);
1663  this->setGenNtupleIntegerBranchValue("genSCFSig",0);
1664  genSCF = kFALSE;
1665  } else {
1666  this->setGenNtupleIntegerBranchValue("genTMSig",0);
1667  this->setGenNtupleIntegerBranchValue("genSCFSig",1);
1668  genSCF = kTRUE;
1669 
1670  // Optionally smear the DP position
1671  // of the SCF event
1672  if ( scfMap_ != 0 ) {
1673  Double_t xCoord(0.0), yCoord(0.0);
1674  if ( kinematics->squareDP() ) {
1675  xCoord = kinematics->getmPrime();
1676  yCoord = kinematics->getThetaPrime();
1677  } else {
1678  xCoord = kinematics->getm13Sq();
1679  yCoord = kinematics->getm23Sq();
1680  }
1681 
1682  // Find the bin number where this event is generated
1683  Int_t binNo = scfMap_->binNumber( xCoord, yCoord );
1684 
1685  // Retrieve the migration histogram
1686  TH2* histo = scfMap_->trueHist( binNo );
1687 
1688  const LauAbsEffModel * effModel = model->getEffModel();
1689  do {
1690  // Get a random point from the histogram
1691  histo->GetRandom2( xCoord, yCoord );
1692 
1693  // Update the kinematics
1694  if ( kinematics->squareDP() ) {
1695  kinematics->updateSqDPKinematics( xCoord, yCoord );
1696  } else {
1697  kinematics->updateKinematics( xCoord, yCoord );
1698  }
1699  } while ( ! effModel->passVeto( kinematics ) );
1700  }
1701  }
1702  }
1703  }
1704  } else {
1705  if (embeddedData) {
1706  embeddedData->getEmbeddedEvent(0);
1707  genSCF = this->storeSignalMCMatch( embeddedData );
1708  } else if ( useSCF_ ) {
1709  Double_t frac = scfFrac_.genValue();
1710  if ( frac < LauRandom::randomFun()->Rndm() ) {
1711  this->setGenNtupleIntegerBranchValue("genTMSig",1);
1712  this->setGenNtupleIntegerBranchValue("genSCFSig",0);
1713  genSCF = kFALSE;
1714  } else {
1715  this->setGenNtupleIntegerBranchValue("genTMSig",0);
1716  this->setGenNtupleIntegerBranchValue("genSCFSig",1);
1717  genSCF = kTRUE;
1718  }
1719  }
1720  }
1721  if (genOK) {
1722  if ( useSCF_ ) {
1723  if ( genSCF ) {
1724  this->generateExtraPdfValues(scfPdfs, embeddedData);
1725  } else {
1726  this->generateExtraPdfValues(sigPdfs, embeddedData);
1727  }
1728  } else {
1729  this->generateExtraPdfValues(sigPdfs, embeddedData);
1730  }
1731  }
1732  // Check for problems with the embedding
1733  if (embeddedData && (embeddedData->nEvents() == embeddedData->nUsedEvents())) {
1734  std::cerr << "WARNING in LauCPFitModel::generateSignalEvent : Source of embedded signal events used up, clearing the list of used events." << std::endl;
1735  embeddedData->clearUsedList();
1736  }
1737 
1738  return genOK;
1739 }
1740 
1742 {
1743  // Generate Bkgnd event
1744  Bool_t genOK(kTRUE);
1745 
1746  LauAbsBkgndDPModel* model(0);
1747  LauEmbeddedData* embeddedData(0);
1748  LauPdfList* extraPdfs(0);
1749  LauKinematics* kinematics(0);
1750 
1751  if (curEvtCharge_<0) {
1752  model = negBkgndDPModels_[bkgndID];
1753  if (this->enableEmbedding()) {
1754  embeddedData = negBkgndTree_[bkgndID];
1755  }
1756  extraPdfs = &negBkgndPdfs_[bkgndID];
1757  kinematics = negKinematics_;
1758  } else {
1759  model = posBkgndDPModels_[bkgndID];
1760  if (this->enableEmbedding()) {
1761  embeddedData = posBkgndTree_[bkgndID];
1762  }
1763  if ( tagged_ ) {
1764  extraPdfs = &posBkgndPdfs_[bkgndID];
1765  } else {
1766  extraPdfs = &negBkgndPdfs_[bkgndID];
1767  }
1768  kinematics = posKinematics_;
1769  }
1770 
1771  if (this->useDP()) {
1772  if (embeddedData) {
1773  embeddedData->getEmbeddedEvent(kinematics);
1774  } else {
1775  if (model == 0) {
1776  const TString& bkgndClass = this->bkgndClassName(bkgndID);
1777  std::cerr << "ERROR in LauCPFitModel::generateBkgndEvent : Can't find the DP model for background class \"" << bkgndClass << "\"." << std::endl;
1778  gSystem->Exit(EXIT_FAILURE);
1779  }
1780  genOK = model->generate();
1781  }
1782  } else {
1783  if (embeddedData) {
1784  embeddedData->getEmbeddedEvent(0);
1785  }
1786  }
1787  if (genOK) {
1788  this->generateExtraPdfValues(extraPdfs, embeddedData);
1789  }
1790 
1791  // Check for problems with the embedding
1792  if (embeddedData && (embeddedData->nEvents() == embeddedData->nUsedEvents())) {
1793  const TString& bkgndClass = this->bkgndClassName(bkgndID);
1794  std::cerr << "WARNING in LauCPFitModel::generateBkgndEvent : Source of embedded " << bkgndClass << " events used up, clearing the list of used events." << std::endl;
1795  embeddedData->clearUsedList();
1796  }
1797 
1798  return genOK;
1799 }
1800 
1802 {
1803  // Setup the required ntuple branches
1804  this->addGenNtupleDoubleBranch("evtWeight");
1805  this->addGenNtupleIntegerBranch("genSig");
1806  this->addGenNtupleDoubleBranch("efficiency");
1807  if ( useSCF_ || ( this->enableEmbedding() &&
1808  negSignalTree_ != 0 && negSignalTree_->haveBranch("mcMatch") &&
1809  posSignalTree_ != 0 && posSignalTree_->haveBranch("mcMatch") ) ) {
1810  this->addGenNtupleIntegerBranch("genTMSig");
1811  this->addGenNtupleIntegerBranch("genSCFSig");
1812  }
1813  const UInt_t nBkgnds = this->nBkgndClasses();
1814  for ( UInt_t iBkgnd(0); iBkgnd < nBkgnds; ++iBkgnd ) {
1815  TString name( this->bkgndClassName(iBkgnd) );
1816  name.Prepend("gen");
1817  this->addGenNtupleIntegerBranch(name);
1818  }
1819  this->addGenNtupleIntegerBranch("charge");
1820  if (this->useDP() == kTRUE) {
1821  this->addGenNtupleDoubleBranch("m12");
1822  this->addGenNtupleDoubleBranch("m23");
1823  this->addGenNtupleDoubleBranch("m13");
1824  this->addGenNtupleDoubleBranch("m12Sq");
1825  this->addGenNtupleDoubleBranch("m23Sq");
1826  this->addGenNtupleDoubleBranch("m13Sq");
1827  this->addGenNtupleDoubleBranch("cosHel12");
1828  this->addGenNtupleDoubleBranch("cosHel23");
1829  this->addGenNtupleDoubleBranch("cosHel13");
1831  this->addGenNtupleDoubleBranch("mPrime");
1832  this->addGenNtupleDoubleBranch("thPrime");
1833  }
1834  }
1835  for (LauPdfList::const_iterator pdf_iter = negSignalPdfs_.begin(); pdf_iter != negSignalPdfs_.end(); ++pdf_iter) {
1836  std::vector<TString> varNames = (*pdf_iter)->varNames();
1837  for ( std::vector<TString>::const_iterator var_iter = varNames.begin(); var_iter != varNames.end(); ++var_iter ) {
1838  if ( (*var_iter) != "m13Sq" && (*var_iter) != "m23Sq" ) {
1839  this->addGenNtupleDoubleBranch( (*var_iter) );
1840  }
1841  }
1842  }
1843 }
1844 
1846 {
1847  LauKinematics* kinematics(0);
1848  if (curEvtCharge_<0) {
1849  kinematics = negKinematics_;
1850  } else {
1851  kinematics = posKinematics_;
1852  }
1853 
1854  // Store all the DP information
1855  this->setGenNtupleDoubleBranchValue("m12", kinematics->getm12());
1856  this->setGenNtupleDoubleBranchValue("m23", kinematics->getm23());
1857  this->setGenNtupleDoubleBranchValue("m13", kinematics->getm13());
1858  this->setGenNtupleDoubleBranchValue("m12Sq", kinematics->getm12Sq());
1859  this->setGenNtupleDoubleBranchValue("m23Sq", kinematics->getm23Sq());
1860  this->setGenNtupleDoubleBranchValue("m13Sq", kinematics->getm13Sq());
1861  this->setGenNtupleDoubleBranchValue("cosHel12", kinematics->getc12());
1862  this->setGenNtupleDoubleBranchValue("cosHel23", kinematics->getc23());
1863  this->setGenNtupleDoubleBranchValue("cosHel13", kinematics->getc13());
1864  if (kinematics->squareDP()) {
1865  this->setGenNtupleDoubleBranchValue("mPrime", kinematics->getmPrime());
1866  this->setGenNtupleDoubleBranchValue("thPrime", kinematics->getThetaPrime());
1867  }
1868 }
1869 
1871 {
1872  LauKinematics* kinematics(0);
1873  if (curEvtCharge_<0) {
1874  kinematics = negKinematics_;
1875  } else {
1876  kinematics = posKinematics_;
1877  }
1878 
1879  if (!extraPdfs) {
1880  std::cerr << "ERROR in LauCPFitModel::generateExtraPdfValues : Null pointer to PDF list." << std::endl;
1881  gSystem->Exit(EXIT_FAILURE);
1882  }
1883 
1884  if (extraPdfs->empty()) {
1885  //std::cerr << "WARNING in LauCPFitModel::generateExtraPdfValues : PDF list is empty." << std::endl;
1886  return;
1887  }
1888 
1889  // Generate from the extra PDFs
1890  for (LauPdfList::iterator pdf_iter = extraPdfs->begin(); pdf_iter != extraPdfs->end(); ++pdf_iter) {
1891  LauFitData genValues;
1892  if (embeddedData) {
1893  genValues = embeddedData->getValues( (*pdf_iter)->varNames() );
1894  } else {
1895  genValues = (*pdf_iter)->generate(kinematics);
1896  }
1897  for ( LauFitData::const_iterator var_iter = genValues.begin(); var_iter != genValues.end(); ++var_iter ) {
1898  TString varName = var_iter->first;
1899  if ( varName != "m13Sq" && varName != "m23Sq" ) {
1900  Double_t value = var_iter->second;
1901  this->setGenNtupleDoubleBranchValue(varName,value);
1902  }
1903  }
1904  }
1905 }
1906 
1908 {
1909  // Default to TM
1910  Bool_t genSCF(kFALSE);
1911  Int_t match(1);
1912 
1913  // Check that we have a valid pointer and that embedded data has
1914  // the mcMatch branch. If so then get the match value.
1915  if ( embeddedData && embeddedData->haveBranch("mcMatch") ) {
1916  match = TMath::Nint( embeddedData->getValue("mcMatch") );
1917  }
1918 
1919  // Set the variables accordingly.
1920  if (match) {
1921  this->setGenNtupleIntegerBranchValue("genTMSig",1);
1922  this->setGenNtupleIntegerBranchValue("genSCFSig",0);
1923  genSCF = kFALSE;
1924  } else {
1925  this->setGenNtupleIntegerBranchValue("genTMSig",0);
1926  this->setGenNtupleIntegerBranchValue("genSCFSig",1);
1927  genSCF = kTRUE;
1928  }
1929 
1930  return genSCF;
1931 }
1932 
1934 {
1935  // Update the signal parameters and then the total normalisation for the signal likelihood
1936  if (this->useDP() == kTRUE) {
1937  this->updateCoeffs();
1940  }
1941 
1942  // Update the signal fraction from the background fractions if not doing an extended fit
1943  if ( !this->doEMLFit() && !signalEvents_->fixed() ) {
1944  this->updateSigEvents();
1945  }
1946 }
1947 
1949 {
1950  // The background parameters will have been set from Minuit.
1951  // We need to update the signal events using these.
1952  Double_t nTotEvts = this->eventsPerExpt();
1953 
1954  signalEvents_->range(-2.0*nTotEvts,2.0*nTotEvts);
1955  for (LauBkgndYieldList::iterator iter = bkgndEvents_.begin(); iter != bkgndEvents_.end(); ++iter) {
1956  (*iter)->range(-2.0*nTotEvts,2.0*nTotEvts);
1957  }
1958 
1959  if (signalEvents_->fixed()) {
1960  return;
1961  }
1962 
1963  // Subtract background events (if any) from signal.
1964  Double_t signalEvents = nTotEvts;
1965  if (usingBkgnd_ == kTRUE) {
1966  for (LauBkgndYieldList::const_iterator iter = bkgndEvents_.begin(); iter != bkgndEvents_.end(); ++iter) {
1967  signalEvents -= (*iter)->value();
1968  }
1969  }
1970  signalEvents_->value(signalEvents);
1971 }
1972 
1974 {
1975  // Fill the internal data trees of the signal and background models.
1976  // Note that we store the events of both charges in both the
1977  // negative and the positive models. It's only later, at the stage
1978  // when the likelihood is being calculated, that we separate them.
1979 
1980  LauFitDataTree* inputFitData = this->fitData();
1981 
1982  // First the Dalitz plot variables (m_ij^2)
1983  if (this->useDP() == kTRUE) {
1984 
1985  // need to append SCF smearing bins before caching DP amplitudes
1986  if ( scfMap_ != 0 ) {
1987  this->appendBinCentres( inputFitData );
1988  }
1989 
1990  negSigModel_->fillDataTree(*inputFitData);
1991  posSigModel_->fillDataTree(*inputFitData);
1992 
1993  if (usingBkgnd_ == kTRUE) {
1994  for (LauBkgndDPModelList::iterator iter = negBkgndDPModels_.begin(); iter != negBkgndDPModels_.end(); ++iter) {
1995  (*iter)->fillDataTree(*inputFitData);
1996  }
1997  for (LauBkgndDPModelList::iterator iter = posBkgndDPModels_.begin(); iter != posBkgndDPModels_.end(); ++iter) {
1998  (*iter)->fillDataTree(*inputFitData);
1999  }
2000  }
2001  }
2002 
2003  // ...and then the extra PDFs
2004  this->cacheInfo(negSignalPdfs_, *inputFitData);
2005  this->cacheInfo(negScfPdfs_, *inputFitData);
2006  for (LauBkgndPdfsList::iterator iter = negBkgndPdfs_.begin(); iter != negBkgndPdfs_.end(); ++iter) {
2007  this->cacheInfo((*iter), *inputFitData);
2008  }
2009  if ( tagged_ ) {
2010  this->cacheInfo(posSignalPdfs_, *inputFitData);
2011  this->cacheInfo(posScfPdfs_, *inputFitData);
2012  for (LauBkgndPdfsList::iterator iter = posBkgndPdfs_.begin(); iter != posBkgndPdfs_.end(); ++iter) {
2013  this->cacheInfo((*iter), *inputFitData);
2014  }
2015  }
2016 
2017  // the SCF fractions and jacobians
2018  if ( useSCF_ && useSCFHist_ ) {
2019  if ( !inputFitData->haveBranch( "m13Sq" ) || !inputFitData->haveBranch( "m23Sq" ) ) {
2020  std::cerr << "ERROR in LauCPFitModel::cacheInputFitVars : Input data does not contain DP branches and so can't cache the SCF fraction." << std::endl;
2021  gSystem->Exit(EXIT_FAILURE);
2022  }
2023 
2024  UInt_t nEvents = inputFitData->nEvents();
2025  recoSCFFracs_.clear();
2026  recoSCFFracs_.reserve( nEvents );
2027  if ( negKinematics_->squareDP() ) {
2028  recoJacobians_.clear();
2029  recoJacobians_.reserve( nEvents );
2030  }
2031  for (UInt_t iEvt = 0; iEvt < nEvents; iEvt++) {
2032  const LauFitData& dataValues = inputFitData->getData(iEvt);
2033  LauFitData::const_iterator m13_iter = dataValues.find("m13Sq");
2034  LauFitData::const_iterator m23_iter = dataValues.find("m23Sq");
2035  negKinematics_->updateKinematics( m13_iter->second, m23_iter->second );
2036  Double_t scfFrac = scfFracHist_->calcEfficiency( negKinematics_ );
2037  recoSCFFracs_.push_back( scfFrac );
2038  if ( negKinematics_->squareDP() ) {
2040  }
2041  }
2042  }
2043 
2044  // finally cache the event charge
2045  evtCharges_.clear();
2046  if ( tagged_ ) {
2047  if ( !inputFitData->haveBranch( tagVarName_ ) ) {
2048  std::cerr << "ERROR in LauCPFitModel::cacheInputFitVars : Input data does not contain branch \"" << tagVarName_ << "\"." << std::endl;
2049  gSystem->Exit(EXIT_FAILURE);
2050  }
2051  UInt_t nEvents = inputFitData->nEvents();
2052  evtCharges_.reserve( nEvents );
2053  for (UInt_t iEvt = 0; iEvt < nEvents; iEvt++) {
2054  const LauFitData& dataValues = inputFitData->getData(iEvt);
2055  LauFitData::const_iterator iter = dataValues.find( tagVarName_ );
2056  curEvtCharge_ = static_cast<Int_t>( iter->second );
2057  evtCharges_.push_back( curEvtCharge_ );
2058  }
2059  }
2060 }
2061 
2063 {
2064  // We'll be caching the DP amplitudes and efficiencies of the centres of the true bins.
2065  // To do so, we attach some fake points at the end of inputData, the number of the entry
2066  // minus the total number of events corresponding to the number of the histogram for that
2067  // given true bin in the LauScfMap object. (What this means is that when Laura is provided with
2068  // the LauScfMap object by the user, it's the latter who has to make sure that it contains the
2069  // right number of histograms and in exactly the right order!)
2070 
2071  // Get the x and y co-ordinates of the bin centres
2072  std::vector<Double_t> binCentresXCoords;
2073  std::vector<Double_t> binCentresYCoords;
2074  scfMap_->listBinCentres(binCentresXCoords, binCentresYCoords);
2075 
2076  // The SCF histograms could be in square Dalitz plot histograms.
2077  // The dynamics takes normal Dalitz plot coords, so we might have to convert them back.
2078  Bool_t sqDP = negKinematics_->squareDP();
2079  UInt_t nBins = binCentresXCoords.size();
2080  fakeSCFFracs_.clear();
2081  fakeSCFFracs_.reserve( nBins );
2082  if ( sqDP ) {
2083  fakeJacobians_.clear();
2084  fakeJacobians_.reserve( nBins );
2085  }
2086 
2087  for (UInt_t iBin = 0; iBin < nBins; ++iBin) {
2088 
2089  if ( sqDP ) {
2090  negKinematics_->updateSqDPKinematics(binCentresXCoords[iBin],binCentresYCoords[iBin]);
2091  binCentresXCoords[iBin] = negKinematics_->getm13Sq();
2092  binCentresYCoords[iBin] = negKinematics_->getm23Sq();
2094  } else {
2095  negKinematics_->updateKinematics(binCentresXCoords[iBin],binCentresYCoords[iBin]);
2096  }
2097 
2099  }
2100 
2101  // Set up inputFitVars_ object to hold the fake events
2102  inputData->appendFakePoints(binCentresXCoords,binCentresYCoords);
2103 }
2104 
2106 {
2107  // Find out whether we have B- or B+
2108  if ( tagged_ ) {
2109  curEvtCharge_ = evtCharges_[iEvt];
2110 
2111  // check that the charge is either +1 or -1
2112  if (TMath::Abs(curEvtCharge_)!=1) {
2113  std::cerr << "ERROR in LauCPFitModel::getTotEvtLikelihood : Charge/tag not accepted value: " << curEvtCharge_ << std::endl;
2114  if (curEvtCharge_>0) {
2115  curEvtCharge_ = +1;
2116  } else {
2117  curEvtCharge_ = -1;
2118  }
2119  std::cerr << " : Making it: " << curEvtCharge_ << "." << std::endl;
2120  }
2121  }
2122 
2123  // Get the DP likelihood for signal and backgrounds
2124  this->getEvtDPLikelihood(iEvt);
2125 
2126  // Get the combined extra PDFs likelihood for signal and backgrounds
2127  this->getEvtExtraLikelihoods(iEvt);
2128 
2129  // If appropriate, combine the TM and SCF likelihoods
2130  Double_t sigLike = sigDPLike_ * sigExtraLike_;
2131  if ( useSCF_ ) {
2132  Double_t scfFrac(0.0);
2133  if (useSCFHist_) {
2134  scfFrac = recoSCFFracs_[iEvt];
2135  } else {
2136  scfFrac = scfFrac_.unblindValue();
2137  }
2138  sigLike *= (1.0 - scfFrac);
2139  if ( (scfMap_ != 0) && (this->useDP() == kTRUE) ) {
2140  // if we're smearing the SCF DP PDF then the SCF frac
2141  // is already included in the SCF DP likelihood
2142  sigLike += (scfDPLike_ * scfExtraLike_);
2143  } else {
2144  sigLike += (scfFrac * scfDPLike_ * scfExtraLike_);
2145  }
2146  }
2147 
2148  // Get the correct event fractions depending on the charge
2149  // Signal asymmetry is built into the DP model... but when the DP
2150  // isn't in the fit we need an explicit parameter
2151  Double_t signalEvents = signalEvents_->unblindValue() * 0.5;
2152  if (this->useDP() == kFALSE) {
2153  signalEvents *= (1.0 - curEvtCharge_ * signalAsym_->unblindValue());
2154  }
2155 
2156  // Construct the total event likelihood
2157  Double_t likelihood(0.0);
2158  if (usingBkgnd_) {
2159  likelihood = sigLike*signalEvents;
2160  const UInt_t nBkgnds = this->nBkgndClasses();
2161  for ( UInt_t bkgndID(0); bkgndID < nBkgnds; ++bkgndID ) {
2162  Double_t bkgndEvents = bkgndEvents_[bkgndID]->unblindValue() * 0.5 * (1.0 - curEvtCharge_ * bkgndAsym_[bkgndID]->unblindValue());
2163  likelihood += bkgndEvents*bkgndDPLike_[bkgndID]*bkgndExtraLike_[bkgndID];
2164  }
2165  } else {
2166  likelihood = sigLike*0.5;
2167  }
2168  return likelihood;
2169 }
2170 
2172 {
2173  Double_t eventSum(0.0);
2174  eventSum += signalEvents_->unblindValue();
2175  if (usingBkgnd_) {
2176  for (LauBkgndYieldList::const_iterator iter = bkgndEvents_.begin(); iter != bkgndEvents_.end(); ++iter) {
2177  eventSum += (*iter)->unblindValue();
2178  }
2179  }
2180  return eventSum;
2181 }
2182 
2184 {
2185  // Function to return the signal and background likelihoods for the
2186  // Dalitz plot for the given event evtNo.
2187 
2188  if ( ! this->useDP() ) {
2189  // There's always going to be a term in the likelihood for the
2190  // signal, so we'd better not zero it.
2191  sigDPLike_ = 1.0;
2192  scfDPLike_ = 1.0;
2193 
2194  const UInt_t nBkgnds = this->nBkgndClasses();
2195  for ( UInt_t bkgndID(0); bkgndID < nBkgnds; ++bkgndID ) {
2196  if (usingBkgnd_ == kTRUE) {
2197  bkgndDPLike_[bkgndID] = 1.0;
2198  } else {
2199  bkgndDPLike_[bkgndID] = 0.0;
2200  }
2201  }
2202 
2203  return;
2204  }
2205 
2206  const UInt_t nBkgnds = this->nBkgndClasses();
2207  if ( tagged_ ) {
2208  if (curEvtCharge_==+1) {
2211 
2212  for ( UInt_t bkgndID(0); bkgndID < nBkgnds; ++bkgndID ) {
2213  if (usingBkgnd_ == kTRUE) {
2214  bkgndDPLike_[bkgndID] = posBkgndDPModels_[bkgndID]->getLikelihood(iEvt);
2215  } else {
2216  bkgndDPLike_[bkgndID] = 0.0;
2217  }
2218  }
2219  } else {
2222 
2223  for ( UInt_t bkgndID(0); bkgndID < nBkgnds; ++bkgndID ) {
2224  if (usingBkgnd_ == kTRUE) {
2225  bkgndDPLike_[bkgndID] = negBkgndDPModels_[bkgndID]->getLikelihood(iEvt);
2226  } else {
2227  bkgndDPLike_[bkgndID] = 0.0;
2228  }
2229  }
2230  }
2231  } else {
2234 
2236 
2237  for ( UInt_t bkgndID(0); bkgndID < nBkgnds; ++bkgndID ) {
2238  if (usingBkgnd_ == kTRUE) {
2239  bkgndDPLike_[bkgndID] = 0.5 * ( posBkgndDPModels_[bkgndID]->getLikelihood(iEvt) +
2240  negBkgndDPModels_[bkgndID]->getLikelihood(iEvt) );
2241  } else {
2242  bkgndDPLike_[bkgndID] = 0.0;
2243  }
2244  }
2245  }
2246 
2247  if ( useSCF_ == kTRUE ) {
2248  if ( scfMap_ == 0 ) {
2249  // we're not smearing the SCF DP position
2250  // so the likelihood is the same as the TM
2252  } else {
2253  // calculate the smeared SCF DP likelihood
2254  scfDPLike_ = this->getEvtSCFDPLikelihood(iEvt);
2255  }
2256  }
2257 
2258  // Calculate the signal normalisation
2259  // NB the 2.0 is there so that the 0.5 factor is applied to
2260  // signal and background in the same place otherwise you get
2261  // normalisation problems when you switch off the DP in the fit
2262  Double_t norm = negSigModel_->getDPNorm() + posSigModel_->getDPNorm();
2263  sigDPLike_ *= 2.0/norm;
2264  scfDPLike_ *= 2.0/norm;
2265 }
2266 
2268 {
2269  Double_t scfDPLike(0.0);
2270 
2271  Double_t recoJacobian(1.0);
2272  Double_t xCoord(0.0);
2273  Double_t yCoord(0.0);
2274 
2275  Bool_t squareDP = negKinematics_->squareDP();
2276  if ( squareDP ) {
2277  xCoord = negSigModel_->getEvtmPrime();
2278  yCoord = negSigModel_->getEvtthPrime();
2279  recoJacobian = recoJacobians_[iEvt];
2280  } else {
2281  xCoord = negSigModel_->getEvtm13Sq();
2282  yCoord = negSigModel_->getEvtm23Sq();
2283  }
2284 
2285  // Find the bin that our reco event falls in
2286  Int_t recoBin = scfMap_->binNumber( xCoord, yCoord );
2287 
2288  // Find out which true Bins contribute to the given reco bin
2289  const std::vector<Int_t>* trueBins = scfMap_->trueBins(recoBin);
2290 
2291  const Int_t nDataEvents = this->eventsPerExpt();
2292 
2293  // Loop over the true bins
2294  for (std::vector<Int_t>::const_iterator iter = trueBins->begin(); iter != trueBins->end(); ++iter)
2295  {
2296  Int_t trueBin = (*iter);
2297 
2298  // prob of a true event in the given true bin migrating to the reco bin
2299  Double_t pRecoGivenTrue = scfMap_->prob( recoBin, trueBin );
2300  Double_t pTrue(0.0);
2301 
2302  // We've cached the DP amplitudes and the efficiency for the
2303  // true bin centres, just after the data points
2304  if ( tagged_ ) {
2305  LauIsobarDynamics* sigModel(0);
2306  if (curEvtCharge_<0) {
2307  sigModel = negSigModel_;
2308  } else {
2309  sigModel = posSigModel_;
2310  }
2311 
2312  sigModel->calcLikelihoodInfo( nDataEvents + trueBin );
2313 
2314  pTrue = sigModel->getEvtIntensity();
2315  } else {
2316  posSigModel_->calcLikelihoodInfo( nDataEvents + trueBin );
2317  negSigModel_->calcLikelihoodInfo( nDataEvents + trueBin );
2318 
2319  pTrue = 0.5 * ( posSigModel_->getEvtIntensity() + negSigModel_->getEvtIntensity() );
2320  }
2321 
2322  // Get the cached SCF fraction (and jacobian if we're using the square DP)
2323  Double_t scfFraction = fakeSCFFracs_[ trueBin ];
2324  Double_t jacobian(1.0);
2325  if ( squareDP ) {
2326  jacobian = fakeJacobians_[ trueBin ];
2327  }
2328 
2329  scfDPLike += pTrue * jacobian * scfFraction * pRecoGivenTrue;
2330  }
2331 
2332  // Divide by the reco jacobian
2333  scfDPLike /= recoJacobian;
2334 
2335  return scfDPLike;
2336 }
2337 
2339 {
2340  // Function to return the signal and background likelihoods for the
2341  // extra variables for the given event evtNo.
2342 
2343  sigExtraLike_ = 1.0;
2344 
2345  const UInt_t nBkgnds = this->nBkgndClasses();
2346 
2347  if ( ! tagged_ || curEvtCharge_ < 0 ) {
2348  sigExtraLike_ = this->prodPdfValue( negSignalPdfs_, iEvt );
2349 
2350  if (useSCF_) {
2351  scfExtraLike_ = this->prodPdfValue( negScfPdfs_, iEvt );
2352  }
2353 
2354  for ( UInt_t bkgndID(0); bkgndID < nBkgnds; ++bkgndID ) {
2355  if (usingBkgnd_) {
2356  bkgndExtraLike_[bkgndID] = this->prodPdfValue( negBkgndPdfs_[bkgndID], iEvt );
2357  } else {
2358  bkgndExtraLike_[bkgndID] = 0.0;
2359  }
2360  }
2361  } else {
2362  sigExtraLike_ = this->prodPdfValue( posSignalPdfs_, iEvt );
2363 
2364  if (useSCF_) {
2365  scfExtraLike_ = this->prodPdfValue( posScfPdfs_, iEvt );
2366  }
2367 
2368  for ( UInt_t bkgndID(0); bkgndID < nBkgnds; ++bkgndID ) {
2369  if (usingBkgnd_) {
2370  bkgndExtraLike_[bkgndID] = this->prodPdfValue( posBkgndPdfs_[bkgndID], iEvt );
2371  } else {
2372  bkgndExtraLike_[bkgndID] = 0.0;
2373  }
2374  }
2375  }
2376 }
2377 
2379 {
2380  negCoeffs_.clear(); posCoeffs_.clear();
2381  negCoeffs_.reserve(nSigComp_); posCoeffs_.reserve(nSigComp_);
2382  for (UInt_t i = 0; i < nSigComp_; i++) {
2383  negCoeffs_.push_back(coeffPars_[i]->antiparticleCoeff());
2384  posCoeffs_.push_back(coeffPars_[i]->particleCoeff());
2385  }
2386 }
2387 
2389 {
2390  // add branches for storing the experiment number and the number of
2391  // the event within the current experiment
2392  this->addSPlotNtupleIntegerBranch("iExpt");
2393  this->addSPlotNtupleIntegerBranch("iEvtWithinExpt");
2394 
2395  // Store the efficiency of the event (for inclusive BF calculations).
2396  if (this->storeDPEff()) {
2397  this->addSPlotNtupleDoubleBranch("efficiency");
2399  this->addSPlotNtupleDoubleBranch("scffraction");
2400  }
2401  }
2402 
2403  // Store the total event likelihood for each species.
2404  if (useSCF_) {
2405  this->addSPlotNtupleDoubleBranch("sigTMTotalLike");
2406  this->addSPlotNtupleDoubleBranch("sigSCFTotalLike");
2407  this->addSPlotNtupleDoubleBranch("sigSCFFrac");
2408  } else {
2409  this->addSPlotNtupleDoubleBranch("sigTotalLike");
2410  }
2411  if (usingBkgnd_) {
2412  const UInt_t nBkgnds = this->nBkgndClasses();
2413  for ( UInt_t iBkgnd(0); iBkgnd < nBkgnds; ++iBkgnd ) {
2414  TString name( this->bkgndClassName(iBkgnd) );
2415  name += "TotalLike";
2416  this->addSPlotNtupleDoubleBranch(name);
2417  }
2418  }
2419 
2420  // Store the DP likelihoods
2421  if (this->useDP()) {
2422  if (useSCF_) {
2423  this->addSPlotNtupleDoubleBranch("sigTMDPLike");
2424  this->addSPlotNtupleDoubleBranch("sigSCFDPLike");
2425  } else {
2426  this->addSPlotNtupleDoubleBranch("sigDPLike");
2427  }
2428  if (usingBkgnd_) {
2429  const UInt_t nBkgnds = this->nBkgndClasses();
2430  for ( UInt_t iBkgnd(0); iBkgnd < nBkgnds; ++iBkgnd ) {
2431  TString name( this->bkgndClassName(iBkgnd) );
2432  name += "DPLike";
2433  this->addSPlotNtupleDoubleBranch(name);
2434  }
2435  }
2436  }
2437 
2438  // Store the likelihoods for each extra PDF
2439  if (useSCF_) {
2440  this->addSPlotNtupleBranches(&negSignalPdfs_, "sigTM");
2441  this->addSPlotNtupleBranches(&negScfPdfs_, "sigSCF");
2442  } else {
2443  this->addSPlotNtupleBranches(&negSignalPdfs_, "sig");
2444  }
2445  if (usingBkgnd_) {
2446  const UInt_t nBkgnds = this->nBkgndClasses();
2447  for ( UInt_t iBkgnd(0); iBkgnd < nBkgnds; ++iBkgnd ) {
2448  const TString& bkgndClass = this->bkgndClassName(iBkgnd);
2449  const LauPdfList* pdfList = &(negBkgndPdfs_[iBkgnd]);
2450  this->addSPlotNtupleBranches(pdfList, bkgndClass);
2451  }
2452  }
2453 }
2454 
2455 void LauCPFitModel::addSPlotNtupleBranches(const LauPdfList* extraPdfs, const TString& prefix)
2456 {
2457  if (extraPdfs) {
2458  // Loop through each of the PDFs
2459  for (LauPdfList::const_iterator pdf_iter = extraPdfs->begin(); pdf_iter != extraPdfs->end(); ++pdf_iter) {
2460 
2461  // Count the number of input variables that are not
2462  // DP variables (used in the case where there is DP
2463  // dependence for e.g. MVA)
2464  UInt_t nVars(0);
2465  std::vector<TString> varNames = (*pdf_iter)->varNames();
2466  for ( std::vector<TString>::const_iterator var_iter = varNames.begin(); var_iter != varNames.end(); ++var_iter ) {
2467  if ( (*var_iter) != "m13Sq" && (*var_iter) != "m23Sq" ) {
2468  ++nVars;
2469  }
2470  }
2471 
2472  if ( nVars == 1 ) {
2473  // If the PDF only has one variable then
2474  // simply add one branch for that variable
2475  TString varName = (*pdf_iter)->varName();
2476  TString name(prefix);
2477  name += varName;
2478  name += "Like";
2479  this->addSPlotNtupleDoubleBranch(name);
2480  } else if ( nVars == 2 ) {
2481  // If the PDF has two variables then we
2482  // need a branch for them both together and
2483  // branches for each
2484  TString allVars("");
2485  for ( std::vector<TString>::const_iterator var_iter = varNames.begin(); var_iter != varNames.end(); ++var_iter ) {
2486  allVars += (*var_iter);
2487  TString name(prefix);
2488  name += (*var_iter);
2489  name += "Like";
2490  this->addSPlotNtupleDoubleBranch(name);
2491  }
2492  TString name(prefix);
2493  name += allVars;
2494  name += "Like";
2495  this->addSPlotNtupleDoubleBranch(name);
2496  } else {
2497  std::cerr << "WARNING in LauCPFitModel::addSPlotNtupleBranches : Can't yet deal with 3D PDFs." << std::endl;
2498  }
2499  }
2500  }
2501 }
2502 
2503 Double_t LauCPFitModel::setSPlotNtupleBranchValues(LauPdfList* extraPdfs, const TString& prefix, UInt_t iEvt)
2504 {
2505  // Store the PDF value for each variable in the list
2506  Double_t totalLike(1.0);
2507  Double_t extraLike(0.0);
2508  if (extraPdfs) {
2509  for (LauPdfList::iterator pdf_iter = extraPdfs->begin(); pdf_iter != extraPdfs->end(); ++pdf_iter) {
2510 
2511  // calculate the likelihood for this event
2512  (*pdf_iter)->calcLikelihoodInfo(iEvt);
2513  extraLike = (*pdf_iter)->getLikelihood();
2514  totalLike *= extraLike;
2515 
2516  // Count the number of input variables that are not
2517  // DP variables (used in the case where there is DP
2518  // dependence for e.g. MVA)
2519  UInt_t nVars(0);
2520  std::vector<TString> varNames = (*pdf_iter)->varNames();
2521  for ( std::vector<TString>::const_iterator var_iter = varNames.begin(); var_iter != varNames.end(); ++var_iter ) {
2522  if ( (*var_iter) != "m13Sq" && (*var_iter) != "m23Sq" ) {
2523  ++nVars;
2524  }
2525  }
2526 
2527  if ( nVars == 1 ) {
2528  // If the PDF only has one variable then
2529  // simply store the value for that variable
2530  TString varName = (*pdf_iter)->varName();
2531  TString name(prefix);
2532  name += varName;
2533  name += "Like";
2534  this->setSPlotNtupleDoubleBranchValue(name, extraLike);
2535  } else if ( nVars == 2 ) {
2536  // If the PDF has two variables then we
2537  // store the value for them both together
2538  // and for each on their own
2539  TString allVars("");
2540  for ( std::vector<TString>::const_iterator var_iter = varNames.begin(); var_iter != varNames.end(); ++var_iter ) {
2541  allVars += (*var_iter);
2542  TString name(prefix);
2543  name += (*var_iter);
2544  name += "Like";
2545  Double_t indivLike = (*pdf_iter)->getLikelihood( (*var_iter) );
2546  this->setSPlotNtupleDoubleBranchValue(name, indivLike);
2547  }
2548  TString name(prefix);
2549  name += allVars;
2550  name += "Like";
2551  this->setSPlotNtupleDoubleBranchValue(name, extraLike);
2552  } else {
2553  std::cerr << "WARNING in LauCPFitModel::setSPlotNtupleBranchValues : Can't yet deal with 3D PDFs." << std::endl;
2554  }
2555  }
2556  }
2557  return totalLike;
2558 }
2559 
2561 {
2562  LauSPlot::NameSet nameSet;
2563  if (this->useDP()) {
2564  nameSet.insert("DP");
2565  }
2566  // Loop through all the signal PDFs
2567  for (LauPdfList::const_iterator pdf_iter = negSignalPdfs_.begin(); pdf_iter != negSignalPdfs_.end(); ++pdf_iter) {
2568  // Loop over the variables involved in each PDF
2569  std::vector<TString> varNames = (*pdf_iter)->varNames();
2570  for ( std::vector<TString>::const_iterator var_iter = varNames.begin(); var_iter != varNames.end(); ++var_iter ) {
2571  // If they are not DP coordinates then add them
2572  if ( (*var_iter) != "m13Sq" && (*var_iter) != "m23Sq" ) {
2573  nameSet.insert( (*var_iter) );
2574  }
2575  }
2576  }
2577  return nameSet;
2578 }
2579 
2581 {
2582  LauSPlot::NumbMap numbMap;
2583  if (!signalEvents_->fixed() && this->doEMLFit()) {
2584  numbMap["sig"] = signalEvents_->genValue();
2585  }
2586  if ( usingBkgnd_ ) {
2587  const UInt_t nBkgnds = this->nBkgndClasses();
2588  for ( UInt_t iBkgnd(0); iBkgnd < nBkgnds; ++iBkgnd ) {
2589  const TString& bkgndClass = this->bkgndClassName(iBkgnd);
2590  const LauParameter* par = bkgndEvents_[iBkgnd];
2591  if (!par->fixed()) {
2592  numbMap[bkgndClass] = par->genValue();
2593  }
2594  }
2595  }
2596  return numbMap;
2597 }
2598 
2600 {
2601  LauSPlot::NumbMap numbMap;
2602  if (signalEvents_->fixed() && this->doEMLFit()) {
2603  numbMap["sig"] = signalEvents_->genValue();
2604  }
2605  if ( usingBkgnd_ ) {
2606  const UInt_t nBkgnds = this->nBkgndClasses();
2607  for ( UInt_t iBkgnd(0); iBkgnd < nBkgnds; ++iBkgnd ) {
2608  const TString& bkgndClass = this->bkgndClassName(iBkgnd);
2609  const LauParameter* par = bkgndEvents_[iBkgnd];
2610  if (par->fixed()) {
2611  numbMap[bkgndClass] = par->genValue();
2612  }
2613  }
2614  }
2615  return numbMap;
2616 }
2617 
2619 {
2620  // This makes the assumption that the form of the positive and
2621  // negative PDFs are the same, which seems reasonable to me
2622 
2623  LauSPlot::TwoDMap twodimMap;
2624 
2625  for (LauPdfList::const_iterator pdf_iter = negSignalPdfs_.begin(); pdf_iter != negSignalPdfs_.end(); ++pdf_iter) {
2626  // Count the number of input variables that are not DP variables
2627  UInt_t nVars(0);
2628  std::vector<TString> varNames = (*pdf_iter)->varNames();
2629  for ( std::vector<TString>::const_iterator var_iter = varNames.begin(); var_iter != varNames.end(); ++var_iter ) {
2630  if ( (*var_iter) != "m13Sq" && (*var_iter) != "m23Sq" ) {
2631  ++nVars;
2632  }
2633  }
2634  if ( nVars == 2 ) {
2635  if (useSCF_) {
2636  twodimMap.insert( std::make_pair( "sigTM", std::make_pair( varNames[0], varNames[1] ) ) );
2637  } else {
2638  twodimMap.insert( std::make_pair( "sig", std::make_pair( varNames[0], varNames[1] ) ) );
2639  }
2640  }
2641  }
2642 
2643  if ( useSCF_ ) {
2644  for (LauPdfList::const_iterator pdf_iter = negScfPdfs_.begin(); pdf_iter != negScfPdfs_.end(); ++pdf_iter) {
2645  // Count the number of input variables that are not DP variables
2646  UInt_t nVars(0);
2647  std::vector<TString> varNames = (*pdf_iter)->varNames();
2648  for ( std::vector<TString>::const_iterator var_iter = varNames.begin(); var_iter != varNames.end(); ++var_iter ) {
2649  if ( (*var_iter) != "m13Sq" && (*var_iter) != "m23Sq" ) {
2650  ++nVars;
2651  }
2652  }
2653  if ( nVars == 2 ) {
2654  twodimMap.insert( std::make_pair( "sigSCF", std::make_pair( varNames[0], varNames[1] ) ) );
2655  }
2656  }
2657  }
2658 
2659  if (usingBkgnd_) {
2660  const UInt_t nBkgnds = this->nBkgndClasses();
2661  for ( UInt_t iBkgnd(0); iBkgnd < nBkgnds; ++iBkgnd ) {
2662  const TString& bkgndClass = this->bkgndClassName(iBkgnd);
2663  const LauPdfList& pdfList = negBkgndPdfs_[iBkgnd];
2664  for (LauPdfList::const_iterator pdf_iter = pdfList.begin(); pdf_iter != pdfList.end(); ++pdf_iter) {
2665  // Count the number of input variables that are not DP variables
2666  UInt_t nVars(0);
2667  std::vector<TString> varNames = (*pdf_iter)->varNames();
2668  for ( std::vector<TString>::const_iterator var_iter = varNames.begin(); var_iter != varNames.end(); ++var_iter ) {
2669  if ( (*var_iter) != "m13Sq" && (*var_iter) != "m23Sq" ) {
2670  ++nVars;
2671  }
2672  }
2673  if ( nVars == 2 ) {
2674  twodimMap.insert( std::make_pair( bkgndClass, std::make_pair( varNames[0], varNames[1] ) ) );
2675  }
2676  }
2677  }
2678  }
2679 
2680  return twodimMap;
2681 }
2682 
2684 {
2685  std::cout << "INFO in LauCPFitModel::storePerEvtLlhds : Storing per-event likelihood values..." << std::endl;
2686 
2687  // if we've not been using the DP model then we need to cache all
2688  // the info here so that we can get the efficiency from it
2689 
2690  LauFitDataTree* inputFitData = this->fitData();
2691 
2692  if (!this->useDP() && this->storeDPEff()) {
2695  negSigModel_->fillDataTree(*inputFitData);
2696  posSigModel_->fillDataTree(*inputFitData);
2697  }
2698 
2699  UInt_t evtsPerExpt(this->eventsPerExpt());
2700 
2701  LauIsobarDynamics* sigModel(0);
2702  LauPdfList* sigPdfs(0);
2703  LauPdfList* scfPdfs(0);
2704  LauBkgndPdfsList* bkgndPdfs(0);
2705 
2706  for (UInt_t iEvt = 0; iEvt < evtsPerExpt; ++iEvt) {
2707 
2708  this->setSPlotNtupleIntegerBranchValue("iExpt",this->iExpt());
2709  this->setSPlotNtupleIntegerBranchValue("iEvtWithinExpt",iEvt);
2710 
2711  // Find out whether we have B- or B+
2712  if ( tagged_ ) {
2713  const LauFitData& dataValues = inputFitData->getData(iEvt);
2714  LauFitData::const_iterator iter = dataValues.find("charge");
2715  curEvtCharge_ = static_cast<Int_t>(iter->second);
2716 
2717  if (curEvtCharge_==+1) {
2718  sigModel = posSigModel_;
2719  sigPdfs = &posSignalPdfs_;
2720  scfPdfs = &posScfPdfs_;
2721  bkgndPdfs = &posBkgndPdfs_;
2722  } else {
2723  sigModel = negSigModel_;
2724  sigPdfs = &negSignalPdfs_;
2725  scfPdfs = &negScfPdfs_;
2726  bkgndPdfs = &negBkgndPdfs_;
2727  }
2728  } else {
2729  sigPdfs = &negSignalPdfs_;
2730  scfPdfs = &negScfPdfs_;
2731  bkgndPdfs = &negBkgndPdfs_;
2732  }
2733 
2734  // the DP information
2735  this->getEvtDPLikelihood(iEvt);
2736  if (this->storeDPEff()) {
2737  if (!this->useDP()) {
2740  }
2741  if ( tagged_ ) {
2742  this->setSPlotNtupleDoubleBranchValue("efficiency",sigModel->getEvtEff());
2744  this->setSPlotNtupleDoubleBranchValue("scffraction",sigModel->getEvtScfFraction());
2745  }
2746  } else {
2750  }
2751  }
2752  }
2753  if (this->useDP()) {
2755  if (useSCF_) {
2757  this->setSPlotNtupleDoubleBranchValue("sigTMDPLike",sigDPLike_);
2758  this->setSPlotNtupleDoubleBranchValue("sigSCFDPLike",scfDPLike_);
2759  } else {
2760  this->setSPlotNtupleDoubleBranchValue("sigDPLike",sigDPLike_);
2761  }
2762  if (usingBkgnd_) {
2763  const UInt_t nBkgnds = this->nBkgndClasses();
2764  for ( UInt_t iBkgnd(0); iBkgnd < nBkgnds; ++iBkgnd ) {
2765  TString name = this->bkgndClassName(iBkgnd);
2766  name += "DPLike";
2767  this->setSPlotNtupleDoubleBranchValue(name,bkgndDPLike_[iBkgnd]);
2768  }
2769  }
2770  } else {
2771  sigTotalLike_ = 1.0;
2772  if (useSCF_) {
2773  scfTotalLike_ = 1.0;
2774  }
2775  if (usingBkgnd_) {
2776  const UInt_t nBkgnds = this->nBkgndClasses();
2777  for ( UInt_t iBkgnd(0); iBkgnd < nBkgnds; ++iBkgnd ) {
2778  bkgndTotalLike_[iBkgnd] = 1.0;
2779  }
2780  }
2781  }
2782 
2783  // the signal PDF values
2784  if ( useSCF_ ) {
2785  sigTotalLike_ *= this->setSPlotNtupleBranchValues(sigPdfs, "sigTM", iEvt);
2786  scfTotalLike_ *= this->setSPlotNtupleBranchValues(scfPdfs, "sigSCF", iEvt);
2787  } else {
2788  sigTotalLike_ *= this->setSPlotNtupleBranchValues(sigPdfs, "sig", iEvt);
2789  }
2790 
2791  // the background PDF values
2792  if (usingBkgnd_) {
2793  const UInt_t nBkgnds = this->nBkgndClasses();
2794  for ( UInt_t iBkgnd(0); iBkgnd < nBkgnds; ++iBkgnd ) {
2795  const TString& bkgndClass = this->bkgndClassName(iBkgnd);
2796  LauPdfList& pdfs = (*bkgndPdfs)[iBkgnd];
2797  bkgndTotalLike_[iBkgnd] *= this->setSPlotNtupleBranchValues(&(pdfs), bkgndClass, iEvt);
2798  }
2799  }
2800 
2801  // the total likelihoods
2802  if (useSCF_) {
2803  Double_t scfFrac(0.0);
2804  if ( useSCFHist_ ) {
2805  scfFrac = recoSCFFracs_[iEvt];
2806  } else {
2807  scfFrac = scfFrac_.unblindValue();
2808  }
2809  this->setSPlotNtupleDoubleBranchValue("sigSCFFrac",scfFrac);
2810  sigTotalLike_ *= ( 1.0 - scfFrac );
2811  if ( scfMap_ == 0 ) {
2812  scfTotalLike_ *= scfFrac;
2813  }
2814  this->setSPlotNtupleDoubleBranchValue("sigTMTotalLike",sigTotalLike_);
2815  this->setSPlotNtupleDoubleBranchValue("sigSCFTotalLike",scfTotalLike_);
2816  } else {
2817  this->setSPlotNtupleDoubleBranchValue("sigTotalLike",sigTotalLike_);
2818  }
2819  if (usingBkgnd_) {
2820  const UInt_t nBkgnds = this->nBkgndClasses();
2821  for ( UInt_t iBkgnd(0); iBkgnd < nBkgnds; ++iBkgnd ) {
2822  TString name = this->bkgndClassName(iBkgnd);
2823  name += "TotalLike";
2825  }
2826  }
2827  // fill the tree
2828  this->fillSPlotNtupleBranches();
2829  }
2830  std::cout << "INFO in LauCPFitModel::storePerEvtLlhds : Finished storing per-event likelihood values." << std::endl;
2831 }
2832 
2833 void LauCPFitModel::embedNegSignal(const TString& fileName, const TString& treeName,
2834  Bool_t reuseEventsWithinEnsemble, Bool_t reuseEventsWithinExperiment,
2835  Bool_t useReweighting)
2836 {
2837  if (negSignalTree_) {
2838  std::cerr << "ERROR in LauCPFitModel::embedNegSignal : Already embedding signal from a file." << std::endl;
2839  return;
2840  }
2841 
2842  negSignalTree_ = new LauEmbeddedData(fileName,treeName,reuseEventsWithinExperiment);
2843  Bool_t dataOK = negSignalTree_->findBranches();
2844  if (!dataOK) {
2845  delete negSignalTree_; negSignalTree_ = 0;
2846  std::cerr << "ERROR in LauCPFitModel::embedNegSignal : Problem creating data tree for embedding." << std::endl;
2847  return;
2848  }
2849  reuseSignal_ = reuseEventsWithinEnsemble;
2850  useNegReweighting_ = useReweighting;
2851  if (this->enableEmbedding() == kFALSE) {this->enableEmbedding(kTRUE);}
2852 }
2853 
2854 void LauCPFitModel::embedNegBkgnd(const TString& bkgndClass, const TString& fileName, const TString& treeName,
2855  Bool_t reuseEventsWithinEnsemble, Bool_t reuseEventsWithinExperiment)
2856 {
2857  if ( ! this->validBkgndClass( bkgndClass ) ) {
2858  std::cerr << "ERROR in LauCPFitModel::embedBkgnd : Invalid background class \"" << bkgndClass << "\"." << std::endl;
2859  std::cerr << " : Background class names must be provided in \"setBkgndClassNames\" before any other background-related actions can be performed." << std::endl;
2860  return;
2861  }
2862 
2863  UInt_t bkgndID = this->bkgndClassID( bkgndClass );
2864 
2865  if (negBkgndTree_[bkgndID]) {
2866  std::cerr << "ERROR in LauCPFitModel::embedNegBkgnd : Already embedding background from a file." << std::endl;
2867  return;
2868  }
2869 
2870  negBkgndTree_[bkgndID] = new LauEmbeddedData(fileName,treeName,reuseEventsWithinExperiment);
2871  Bool_t dataOK = negBkgndTree_[bkgndID]->findBranches();
2872  if (!dataOK) {
2873  delete negBkgndTree_[bkgndID]; negBkgndTree_[bkgndID] = 0;
2874  std::cerr << "ERROR in LauCPFitModel::embedNegBkgnd : Problem creating data tree for embedding." << std::endl;
2875  return;
2876  }
2877  reuseBkgnd_[bkgndID] = reuseEventsWithinEnsemble;
2878  if (this->enableEmbedding() == kFALSE) {this->enableEmbedding(kTRUE);}
2879 }
2880 
2881 void LauCPFitModel::embedPosSignal(const TString& fileName, const TString& treeName,
2882  Bool_t reuseEventsWithinEnsemble, Bool_t reuseEventsWithinExperiment,
2883  Bool_t useReweighting)
2884 {
2885  if (posSignalTree_) {
2886  std::cerr << "ERROR in LauCPFitModel::embedPosSignal : Already embedding signal from a file." << std::endl;
2887  return;
2888  }
2889 
2890  posSignalTree_ = new LauEmbeddedData(fileName,treeName,reuseEventsWithinExperiment);
2891  Bool_t dataOK = posSignalTree_->findBranches();
2892  if (!dataOK) {
2893  delete posSignalTree_; posSignalTree_ = 0;
2894  std::cerr << "ERROR in LauCPFitModel::embedPosSignal : Problem creating data tree for embedding." << std::endl;
2895  return;
2896  }
2897  reuseSignal_ = reuseEventsWithinEnsemble;
2898  usePosReweighting_ = useReweighting;
2899  if (this->enableEmbedding() == kFALSE) {this->enableEmbedding(kTRUE);}
2900 }
2901 
2902 void LauCPFitModel::embedPosBkgnd(const TString& bkgndClass, const TString& fileName, const TString& treeName,
2903  Bool_t reuseEventsWithinEnsemble, Bool_t reuseEventsWithinExperiment)
2904 {
2905  if ( ! this->validBkgndClass( bkgndClass ) ) {
2906  std::cerr << "ERROR in LauCPFitModel::embedBkgnd : Invalid background class \"" << bkgndClass << "\"." << std::endl;
2907  std::cerr << " : Background class names must be provided in \"setBkgndClassNames\" before any other background-related actions can be performed." << std::endl;
2908  return;
2909  }
2910 
2911  UInt_t bkgndID = this->bkgndClassID( bkgndClass );
2912 
2913  if (posBkgndTree_[bkgndID]) {
2914  std::cerr << "ERROR in LauCPFitModel::embedPosBkgnd : Already embedding background from a file." << std::endl;
2915  return;
2916  }
2917 
2918  posBkgndTree_[bkgndID] = new LauEmbeddedData(fileName,treeName,reuseEventsWithinExperiment);
2919  Bool_t dataOK = posBkgndTree_[bkgndID]->findBranches();
2920  if (!dataOK) {
2921  delete posBkgndTree_[bkgndID]; posBkgndTree_[bkgndID] = 0;
2922  std::cerr << "ERROR in LauCPFitModel::embedPosBkgnd : Problem creating data tree for embedding." << std::endl;
2923  return;
2924  }
2925  reuseBkgnd_[bkgndID] = reuseEventsWithinEnsemble;
2926  if (this->enableEmbedding() == kFALSE) {this->enableEmbedding(kTRUE);}
2927 }
2928 
2929 void LauCPFitModel::weightEvents( const TString& dataFileName, const TString& dataTreeName )
2930 {
2931  // Routine to provide weights for events that are uniformly distributed
2932  // in the DP (or square DP) so as to reproduce the given DP model
2933 
2934  if ( posKinematics_->squareDP() ) {
2935  std::cout << "INFO in LauSimpleFitModel::weightEvents : will create weights assuming events were generated flat in the square DP" << std::endl;
2936  } else {
2937  std::cout << "INFO in LauSimpleFitModel::weightEvents : will create weights assuming events were generated flat in phase space" << std::endl;
2938  }
2939 
2940  // This reads in the given dataFile and creates an input
2941  // fit data tree that stores them for all events and experiments.
2942  Bool_t dataOK = this->verifyFitData(dataFileName,dataTreeName);
2943  if (!dataOK) {
2944  std::cerr << "ERROR in LauSimpleFitModel::weightEvents : Problem caching the data." << std::endl;
2945  return;
2946  }
2947 
2948  LauFitDataTree* inputFitData = this->fitData();
2949 
2950  if ( ! inputFitData->haveBranch( "m13Sq_MC" ) || ! inputFitData->haveBranch( "m23Sq_MC" ) || ! inputFitData->haveBranch( "charge" )) {
2951  std::cerr << "WARNING in LauSimpleFitModel::weightEvents : Cannot find MC truth DP coordinate branches in supplied data, aborting." << std::endl;
2952  return;
2953  }
2954 
2955  // Create the ntuple to hold the DP weights
2956  TString weightsFileName( dataFileName );
2957  Ssiz_t index = weightsFileName.Last('.');
2958  weightsFileName.Insert( index, "_DPweights" );
2959  LauGenNtuple * weightsTuple = new LauGenNtuple( weightsFileName, dataTreeName );
2960  weightsTuple->addIntegerBranch("iExpt");
2961  weightsTuple->addIntegerBranch("iEvtWithinExpt");
2962  weightsTuple->addDoubleBranch("dpModelWeight");
2963 
2964  UInt_t iExpmt = this->iExpt();
2965  UInt_t nExpmt = this->nExpt();
2966  UInt_t firstExpmt = this->firstExpt();
2967  for (iExpmt = firstExpmt; iExpmt < (firstExpmt+nExpmt); ++iExpmt) {
2968 
2969  inputFitData->readExperimentData(iExpmt);
2970  UInt_t nEvents = inputFitData->nEvents();
2971 
2972  if (nEvents < 1) {
2973  std::cerr << "WARNING in LauSimpleFitModel::weightEvents : Zero events in experiment " << iExpmt << ", skipping..." << std::endl;
2974  continue;
2975  }
2976 
2977  weightsTuple->setIntegerBranchValue( "iExpt", iExpmt );
2978 
2979  // Calculate and store the weights for the events in this experiment
2980  for ( UInt_t iEvent(0); iEvent < nEvents; ++iEvent ) {
2981 
2982  weightsTuple->setIntegerBranchValue( "iEvtWithinExpt", iEvent );
2983 
2984  const LauFitData& evtData = inputFitData->getData( iEvent );
2985 
2986  Double_t m13Sq_MC = evtData.find("m13Sq_MC")->second;
2987  Double_t m23Sq_MC = evtData.find("m23Sq_MC")->second;
2988  Int_t charge = evtData.find("charge")->second;
2989 
2990  Double_t dpModelWeight(0.0);
2991 
2992  LauKinematics * kinematics;
2993  LauIsobarDynamics * dpModel;
2994 
2995  if (charge > 0) {
2996  kinematics = posKinematics_;
2997  dpModel = posSigModel_;
2998  } else {
2999  kinematics = negKinematics_;
3000  dpModel = negSigModel_;
3001  }
3002 
3003  if ( kinematics->withinDPLimits( m13Sq_MC, m23Sq_MC ) ) {
3004 
3005  kinematics->updateKinematics( m13Sq_MC, m23Sq_MC );
3006  dpModelWeight = dpModel->getEventWeight();
3007 
3008  if ( kinematics->squareDP() ) {
3009  dpModelWeight *= kinematics->calcSqDPJacobian();
3010  }
3011 
3012  Double_t norm = negSigModel_->getDPNorm() + posSigModel_->getDPNorm();
3013  dpModelWeight /= norm;
3014 
3015  if (LauIsobarDynamics::GenOK != dpModel->checkToyMC(kTRUE,kFALSE)) {
3016  std::cerr << "WARNING in LauSimpleFitModel::weightEvents : Problem in calculating the weight, aborting." << std::endl;
3017  delete weightsTuple;
3018  return;
3019  }
3020  }
3021 
3022  weightsTuple->setDoubleBranchValue( "dpModelWeight", dpModelWeight );
3023  weightsTuple->fillBranches();
3024  }
3025 
3026  }
3027 
3028  weightsTuple->buildIndex( "iExpt", "iEvtWithinExpt" );
3029  weightsTuple->addFriendTree(dataFileName, dataTreeName);
3030  weightsTuple->writeOutGenResults();
3031 
3032  delete weightsTuple;
3033 }
3034 
3035 
3036 void LauCPFitModel::savePDFPlots(const TString& label)
3037 {
3038  savePDFPlotsWave(label, 0);
3039  savePDFPlotsWave(label, 1);
3040  savePDFPlotsWave(label, 2);
3041 
3042  std::cout << "LauCPFitModel::plot" << std::endl;
3043 // ((LauIsobarDynamics*)negSigModel_)->plot();
3044 
3045 
3046 
3047  //Double_t minm13 = negSigModel_->getKinematics()->getm13Min();
3048  Double_t minm13 = 0.0;
3049  Double_t maxm13 = negSigModel_->getKinematics()->getm13Max();
3050  //Double_t minm23 = negSigModel_->getKinematics()->getm23Min();
3051  Double_t minm23 = 0.0;
3052  Double_t maxm23 = negSigModel_->getKinematics()->getm23Max();
3053 
3054  Double_t mins13 = minm13*minm13;
3055  Double_t maxs13 = maxm13*maxm13;
3056  Double_t mins23 = minm23*minm23;
3057  Double_t maxs23 = maxm23*maxm23;
3058 
3059  Double_t s13, s23, posChPdf, negChPdf;
3060 
3061  TString xLabel = "s13";
3062  TString yLabel = "s23";
3063 
3064  if (negSigModel_->getDaughters()->gotSymmetricalDP()) { xLabel = "sHigh"; yLabel = "sLow";}
3065 
3066  Int_t n13=200.00, n23=200.00;
3067  Double_t delta13, delta23;
3068  delta13 = (maxs13 - mins13)/n13;
3069  delta23 = (maxs23 - mins23)/n23;
3070  UInt_t nAmp = negSigModel_->getnCohAmp();
3071  for (UInt_t resID = 0; resID <= nAmp; ++resID)
3072  {
3073  TGraph2D *posDt = new TGraph2D();
3074  TGraph2D *negDt = new TGraph2D();
3075  TGraph2D *acpDt = new TGraph2D();
3076 
3077  TString resName = "TotalAmp";
3078  if (resID != nAmp){
3079  TString tStrResID = Form("%d", resID);
3080  const LauIsobarDynamics* model = negSigModel_;
3081  const LauAbsResonance* resonance = model->getResonance(resID);
3082  resName = resonance->getResonanceName();
3083  std::cout << "resName = " << resName << std::endl;
3084  }
3085 
3086 
3087  resName.ReplaceAll("(", "");
3088  resName.ReplaceAll(")", "");
3089  resName.ReplaceAll("*", "Star");
3090 
3091  posDt->SetName(resName+label);
3092  posDt->SetTitle(resName+" ("+label+") Positive");
3093  negDt->SetName(resName+label);
3094  negDt->SetTitle(resName+" ("+label+") Negative");
3095  acpDt->SetName(resName+label);
3096  acpDt->SetTitle(resName+" ("+label+") Asymmetry");
3097 
3098  Int_t count=0;
3099  for (Int_t i=0; i<n13; i++) {
3100  s13 = mins13 + i*delta13;
3101  for (Int_t j=0; j<n23; j++) {
3102  s23 = mins23 + j*delta23;
3103  if (negSigModel_->getKinematics()->withinDPLimits2(s23, s13))
3104  {
3105  if (negSigModel_->getDaughters()->gotSymmetricalDP() && (s13>s23) ) continue;
3106 
3107  negSigModel_->calcLikelihoodInfo(s13, s23);
3108  posSigModel_->calcLikelihoodInfo(s13, s23);
3109 
3110  LauComplex negChAmp = negSigModel_->getEvtDPAmp();
3111  LauComplex posChAmp = posSigModel_->getEvtDPAmp();
3112 
3113  if (resID != nAmp){
3114  negChAmp = negSigModel_->getFullAmplitude(resID);
3115  posChAmp = posSigModel_->getFullAmplitude(resID);
3116  }
3117  negChPdf = negChAmp.abs2();
3118  posChPdf = posChAmp.abs2();
3119  negDt->SetPoint(count,s23,s13,negChPdf); // s23=sHigh, s13 = sLow
3120  posDt->SetPoint(count,s23,s13,posChPdf); // s23=sHigh, s13 = sLow
3121  acpDt->SetPoint(count,s23,s13, negChPdf - posChPdf); // s23=sHigh, s13 = sLow
3122  count++;
3123  }
3124  }
3125  }
3126  gStyle->SetPalette(1);
3127  TCanvas *posC = new TCanvas("c"+resName+label + "Positive",resName+" ("+label+") Positive",0,0,600,400);
3128  posDt->GetXaxis()->SetTitle(xLabel);
3129  posDt->GetYaxis()->SetTitle(yLabel);
3130  posDt->Draw("SURF1");
3131  posDt->GetXaxis()->SetTitle(xLabel);
3132  posDt->GetYaxis()->SetTitle(yLabel);
3133  posC->SaveAs("plot_2D_"+resName + "_"+label+"Positive.C");
3134 
3135  TCanvas *negC = new TCanvas("c"+resName+label + "Negative",resName+" ("+label+") Negative",0,0,600,400);
3136  negDt->GetXaxis()->SetTitle(xLabel);
3137  negDt->GetYaxis()->SetTitle(yLabel);
3138  negDt->Draw("SURF1");
3139  negDt->GetXaxis()->SetTitle(xLabel);
3140  negDt->GetYaxis()->SetTitle(yLabel);
3141  negC->SaveAs("plot_2D_"+resName + "_"+label+"Negative.C");
3142 
3143  TCanvas *acpC = new TCanvas("c"+resName+label + "Asymmetry",resName+" ("+label+") Asymmetry",0,0,600,400);
3144  acpDt->GetXaxis()->SetTitle(xLabel);
3145  acpDt->GetYaxis()->SetTitle(yLabel);
3146  acpDt->Draw("SURF1");
3147  acpDt->GetXaxis()->SetTitle(xLabel);
3148  acpDt->GetYaxis()->SetTitle(yLabel);
3149  acpC->SaveAs("plot_2D_"+resName + "_"+label+"Asymmetry.C");
3150  }
3151 }
3152 
3153 void LauCPFitModel::savePDFPlotsWave(const TString& label, const Int_t& spin)
3154 {
3155 
3156  std::cout << "label = "<< label << ", spin = "<< spin << std::endl;
3157 
3158  TString tStrResID = "S_Wave";
3159  if (spin == 1) tStrResID = "P_Wave";
3160  if (spin == 2) tStrResID = "D_Wave";
3161 
3162  TString xLabel = "s13";
3163  TString yLabel = "s23";
3164 
3165  std::cout << "LauSimpleFitModel::savePDFPlotsWave: "<< tStrResID << std::endl;
3166 
3167  Double_t minm13 = 0.0;
3168  Double_t maxm13 = negSigModel_->getKinematics()->getm13Max();
3169  Double_t minm23 = 0.0;
3170  Double_t maxm23 = negSigModel_->getKinematics()->getm23Max();
3171 
3172  Double_t mins13 = minm13*minm13;
3173  Double_t maxs13 = maxm13*maxm13;
3174  Double_t mins23 = minm23*minm23;
3175  Double_t maxs23 = maxm23*maxm23;
3176 
3177  Double_t s13, s23, posChPdf, negChPdf;
3178  TGraph2D *posDt = new TGraph2D();
3179  TGraph2D *negDt = new TGraph2D();
3180  TGraph2D *acpDt = new TGraph2D();
3181 
3182 
3183  posDt->SetName(tStrResID+label);
3184  posDt->SetTitle(tStrResID+" ("+label+") Positive");
3185  negDt->SetName(tStrResID+label);
3186  negDt->SetTitle(tStrResID+" ("+label+") Negative");
3187  acpDt->SetName(tStrResID+label);
3188  acpDt->SetTitle(tStrResID+" ("+label+") Asymmetry");
3189 
3190  Int_t n13=200.00, n23=200.00;
3191  Double_t delta13, delta23;
3192  delta13 = (maxs13 - mins13)/n13;
3193  delta23 = (maxs23 - mins23)/n23;
3194  UInt_t nAmp = negSigModel_->getnCohAmp();
3195 
3196  Int_t count=0;
3197  for (Int_t i=0; i<n13; i++)
3198  {
3199  s13 = mins13 + i*delta13;
3200  for (Int_t j=0; j<n23; j++)
3201  {
3202  s23 = mins23 + j*delta23;
3203  if (negSigModel_->getKinematics()->withinDPLimits2(s23, s13))
3204  {
3205  if (negSigModel_->getDaughters()->gotSymmetricalDP() && (s13>s23) ) continue;
3206 
3207  LauComplex negChAmp(0,0);
3208  LauComplex posChAmp(0,0);
3209  Bool_t noWaveRes = kTRUE;
3210  negSigModel_->calcLikelihoodInfo(s13, s23);
3211  for (UInt_t resID = 0; resID < nAmp; ++resID)
3212  {
3213  const LauIsobarDynamics* model = negSigModel_;
3214  const LauAbsResonance* resonance = model->getResonance(resID);
3215  Int_t spin_res = resonance->getSpin();
3216  if (spin != spin_res) continue;
3217  noWaveRes = kFALSE;
3218  negChAmp += negSigModel_->getFullAmplitude(resID);
3219  posChAmp += posSigModel_->getFullAmplitude(resID);
3220  }
3221 
3222  if (noWaveRes) return;
3223 
3224  negChPdf = negChAmp.abs2();
3225  posChPdf = posChAmp.abs2();
3226 
3227  negDt->SetPoint(count,s23,s13,negChPdf); // s23=sHigh, s13 = sLow
3228  posDt->SetPoint(count,s23,s13,posChPdf); // s23=sHigh, s13 = sLow
3229  acpDt->SetPoint(count,s23,s13, negChPdf - posChPdf); // s23=sHigh, s13 = sLow
3230  count++;
3231 
3232  }
3233  }
3234  }
3235  gStyle->SetPalette(1);
3236  TCanvas *posC = new TCanvas("c"+tStrResID+label + "Positive",tStrResID+" ("+label+") Positive",0,0,600,400);
3237  posDt->GetXaxis()->SetTitle(xLabel);
3238  posDt->GetYaxis()->SetTitle(yLabel);
3239  posDt->Draw("SURF1");
3240  posDt->GetXaxis()->SetTitle(xLabel);
3241  posDt->GetYaxis()->SetTitle(yLabel);
3242  posC->SaveAs("plot_2D_"+tStrResID + "_"+label+"Positive.C");
3243 
3244  TCanvas *negC = new TCanvas("c"+tStrResID+label + "Negative",tStrResID+" ("+label+") Negative",0,0,600,400);
3245  negDt->GetXaxis()->SetTitle(xLabel);
3246  negDt->GetYaxis()->SetTitle(yLabel);
3247  negDt->Draw("SURF1");
3248  negDt->GetXaxis()->SetTitle(xLabel);
3249  negDt->GetYaxis()->SetTitle(yLabel);
3250  negC->SaveAs("plot_2D_"+tStrResID + "_"+label+"Negative.C");
3251 
3252  TCanvas *acpC = new TCanvas("c"+tStrResID+label + "Asymmetry",tStrResID+" ("+label+") Asymmetry",0,0,600,400);
3253  acpDt->GetXaxis()->SetTitle(xLabel);
3254  acpDt->GetYaxis()->SetTitle(yLabel);
3255  acpDt->Draw("SURF1");
3256  acpDt->GetXaxis()->SetTitle(xLabel);
3257  acpDt->GetYaxis()->SetTitle(yLabel);
3258  acpC->SaveAs("plot_2D_"+tStrResID + "_"+label+"Asymmetry.C");
3259 
3260 
3261 }
3262 
3263 
3264 
3265 
3266 
3267 
3268 
Double_t range() const
The range allowed for the parameter.
void generateExtraPdfValues(LauPdfList *extraPdfs, LauEmbeddedData *embeddedData)
Generate from the extra PDFs.
Bool_t withinDPLimits(const Double_t m13Sq, const Double_t m23Sq) const
Check whether a given (m13Sq,m23Sq) point is within the kinematic limits of the Dalitz plot...
void modifyDataTree()
Recache the amplitude values for those that have changed.
Bool_t generateSignalEvent()
Generate signal event.
virtual void addSPlotNtupleIntegerBranch(const TString &name)
Add a branch to the sPlot tree for storing an integer.
Double_t getm23Max() const
Get the m23 maximum defined as (mParent - m1)
The abstract interface for a background Dalitz plot model.
std::vector< LauParameter > acp_
A_CP parameter.
virtual LauSPlot::NameSet variableNames() const
Returns the names of all variables in the fit.
Double_t getc23() const
Get the cosine of the helicity angle theta23.
TRandom * randomFun()
Access the singleton random number generator with a particular seed.
Definition: LauRandom.cc:20
const LauParameter & getDPRate() const
Retrieve the overall Dalitz plot rate.
std::vector< LauParameter > LauParameterList
List of parameters.
Bool_t fixed() const
Check whether the parameter is fixed or floated.
LauKinematics * negKinematics_
The B- Dalitz plot kinematics object.
UInt_t nEvents() const
Retrieve the number of events.
virtual void printAsymmetries(std::ostream &output)
Print the asymmetries.
Bool_t writeLatexTable() const
Determine whether writing out of the latex table is enabled.
LauPdfList negSignalPdfs_
The B- signal PDFs.
void addSPlotNtupleBranches(const LauPdfList *extraPdfs, const TString &prefix)
Add sPlot branches for the extra PDFs.
const TString & getResonanceName() const
Get the name of the resonance.
Bool_t forceAsym_
Option to force an asymmetry.
Double_t scfTotalLike_
Total SCF likelihood.
void setExtraPdfParameters()
Set the fit parameters for the extra PDFs.
void updateCoeffs(const std::vector< LauComplex > &coeffs)
Update the complex coefficients for the resonances.
LauBkgndDPModelList posBkgndDPModels_
The B+ background Dalitz plot models.
void setEffHisto(const TH2 *effHisto, Bool_t useInterpolation=kTRUE, Bool_t fluctuateBins=kFALSE, Double_t avEff=-1.0, Double_t absError=-1.0, Bool_t useUpperHalfOnly=kFALSE, Bool_t squareDP=kFALSE)
Set the efficiency variation across the phase space using a predetermined 2D histogram.
Definition: LauEffModel.cc:54
void cacheInfo(LauPdfList &pdfList, const LauFitDataTree &theData)
Have all PDFs in the list cache the data.
virtual void setGenNtupleIntegerBranchValue(const TString &name, Int_t value)
Set the value of an integer branch in the gen tree.
File containing declaration of LauAsymmCalc class.
ClassImp(LauAbsCoeffSet)
UInt_t nNormPar_
Number of normalisation parameters (yields, asymmetries)
LauEmbeddedData * posSignalTree_
The B+ signal event tree.
void squareDP(const Bool_t calcSquareDPCoords)
Enable/disable the calculation of square Dalitz plot co-ordinates.
Bool_t getReweightedEvent(LauIsobarDynamics *dynamics)
Retrieve an event from the data sample, applying an accept/reject based on the given DP model...
LauParameter()
Default constructor.
Definition: LauParameter.cc:30
const LauParameter & getMeanEff() const
Retrieve the mean efficiency across the Dalitz plot.
Double_t getm23() const
Get the m23 invariant mass.
Int_t curEvtCharge_
Current event charge.
virtual Bool_t verifyFitData(const TString &dataFileName, const TString &dataTreeName)
Open the input file and verify that all required variables are present.
void calcExtraFractions(Bool_t initValues=kFALSE)
Calculate the CP-conserving and CP-violating fit fractions.
const TString & name() const
The parameter name.
virtual LauParameter acp()=0
Calculate the CP asymmetry.
const LauKinematics * getKinematics() const
Retrieve the Dalitz plot kinematics.
Double_t getmPrime() const
Get m&#39; value.
Class that defines the particular 3-body decay under study.
Definition: LauDaughters.hh:33
UInt_t addFitParameters(LauPdfList &pdfList)
Add parameters of the PDFs in the list to the list of all fit parameters.
Class for calculating the asymmetry between two variables.
Definition: LauAsymmCalc.hh:25
LauEmbeddedData * negSignalTree_
The B- signal event tree.
Double_t getDPNorm() const
Retrieve the normalisation factor for the log-likelihood function.
Bool_t useDP() const
Is the Dalitz plot term in the likelihood.
Double_t getc13() const
Get the cosine of the helicity angle theta13.
File containing declaration of LauAbsCoeffSet class.
void clearUsedList()
Clear the list of used events.
Bool_t useNegReweighting_
Boolean to use reweighting for B-.
void calcExtraInfo(const Bool_t init=kFALSE)
Calculate the fit fractions, mean efficiency and total DP rate.
TH2 * trueHist(Int_t trueBin)
Retrieve the migration histogram for trueBin.
Definition: LauScfMap.cc:176
std::vector< LauComplex > negCoeffs_
The complex coefficients for B-.
LauBkgndPdfsList posBkgndPdfs_
The B+ background PDFs.
std::multimap< TString, std::pair< TString, TString > > TwoDMap
Type to associate the name of the species that have 2D PDFs with the names of the two variables invol...
Definition: LauSPlot.hh:68
Int_t buildIndex(const TString &majorName, const TString &minorName="0")
Create an index table using leaves of the tree.
LauParArray negFitFrac_
The B- fit fractions.
void listBinCentres(std::vector< Double_t > &xCoords, std::vector< Double_t > &yCoords) const
Create lists of the co-ordinates of the centres of true bins.
Definition: LauScfMap.cc:114
virtual void getEvtExtraLikelihoods(UInt_t iEvt)
Determine the signal and background likelihood for the extra variables for a given event...
Double_t sigDPLike_
Signal DP likelihood value.
File containing declaration of LauDaughters class.
const std::vector< Int_t > * trueBins(Int_t recoBin) const
Find which true bins contribute to the given reco bin.
Definition: LauScfMap.cc:155
LauPdfList negScfPdfs_
The B- SCF PDFs.
Bool_t useSCF_
Is the signal split into TM and SCF.
virtual Bool_t genExpt()
Toy MC generation and fitting overloaded functions.
virtual void setGenNtupleDoubleBranchValue(const TString &name, Double_t value)
Set the value of a double branch in the gen tree.
const LauFitNtuple * fitNtuple() const
Const access to the fit ntuple.
TString negParent_
Name of the parent particle.
TString posParent_
Name of the parent particle.
void embedNegSignal(const TString &fileName, const TString &treeName, Bool_t reuseEventsWithinEnsemble, Bool_t reuseEventsWithinExperiment=kFALSE, Bool_t useReweighting=kFALSE)
Embed full simulation events for the B- signal, rather than generating toy from the PDFs...
void addFriendTree(const TString &rootFileName, const TString &rootTreeName)
Add a friend tree.
File containing declaration of LauScfMap class.
Double_t getEvtthPrime() const
Retrieve the square Dalitz plot coordinate, theta&#39;, for the current event.
std::pair< LauGenInfo, Bool_t > eventsToGenerate()
Determine the number of events to generate for each hypothesis.
std::vector< Double_t > fakeSCFFracs_
The cached values of the SCF fraction for each bin centre.
TString getConjResName(const TString &resName) const
Retrieve the name of the charge conjugate of a named resonance.
std::vector< std::vector< LauParameter > > LauParArray
Type to define an array of parameters.
virtual void printParValues() const =0
Print the current values of the parameters.
Bool_t storeSignalMCMatch(LauEmbeddedData *embeddedData)
Store the MC truth info on the TM/SCF nature of the embedded signal event.
Bool_t usingBkgnd_
Background boolean.
File containing declaration of LauPrint class.
void updateSqDPKinematics(const Double_t mPrime, const Double_t thetaPrime)
Update all kinematic quantities based on the square DP co-ordinates m&#39; and theta&#39;.
Pure abstract base class for defining the efficiency description across the signal Dalitz plot...
Double_t prodPdfValue(LauPdfList &pdfList, UInt_t iEvt)
Calculate the product of the per-event likelihoods of the PDFs in the list.
std::vector< LauAbsPdf * > LauPdfList
List of Pdfs.
std::map< TString, Double_t > LauFitData
Type for holding event data.
void fillBranches()
Fill branches in the ntuple.
LauBkgndYieldList bkgndAsym_
Background asymmetries(s)
LauComplex getFullAmplitude(const Int_t resID) const
Retrieve the Amplitude of resonance resID.
Double_t getm23Sq() const
Get the m23 invariant mass square.
LauIsobarDynamics * negSigModel_
The B- signal Dalitz plot model.
const LauParArray & getFitFractions() const
Retrieve the fit fractions for the amplitude components.
void recalculateNormalisation()
recalculate Normalization
Bool_t squareDP() const
Determine to use or not the square Dalitz plot.
Definition: LauDaughters.hh:84
LauParameter negDPRate_
The average DP rate for B-.
Double_t getEvtScfFraction() const
Retrieve the fraction of events that are poorly reconstructed (the self cross feed fraction) for the ...
Class to define various output print commands.
Definition: LauPrint.hh:29
Double_t getValue(const TString &name) const
Get the value of a specified branch.
std::vector< Double_t > bkgndTotalLike_
Total background likelihood(s)
void calcLikelihoodInfo(const UInt_t iEvt)
Calculate the likelihood (and all associated information) for the given event number.
virtual void fillGenNtupleBranches()
Fill the gen tuple branches.
std::vector< Double_t > recoSCFFracs_
The cached values of the SCF fraction for each event.
LauParameter posDPRate_
The average DP rate for B+.
void updateFitNtuple()
Update the fit ntuple.
std::set< LauParameter * > LauParameterPSet
Set of parameter pointers.
File containing declaration of LauKinematics class.
virtual void setSPlotNtupleDoubleBranchValue(const TString &name, Double_t value)
Set the value of a double branch in the sPlot tree.
File containing declaration of LauEmbeddedData class.
std::vector< Double_t > bkgndExtraLike_
Background likelihood value(s) from extra PDFs.
void setupGenNtupleBranches()
Setup the required ntuple branches.
void printFitParameters(const LauPdfList &pdfList, std::ostream &fout) const
Print the fit parameters for all PDFs in the list.
Double_t getm13Max() const
Get the m13 maximum defined as (mParent - m2)
Double_t scfExtraLike_
SCF likelihood from extra PDFs.
Bool_t haveBranch(const TString &name) const
Boolean to determine whether branch exists.
File containing declaration of LauCPFitModel class.
Bool_t reuseSignal_
Boolean to reuse signal events.
LauParArray posFitFrac_
The B+ fit fractions.
Bool_t usingScfModel() const
Check whether a self cross feed fraction model is being used.
const LauAbsResonance * getResonance(const UInt_t resIndex) const
Retrieve a resonance by its index.
virtual void cacheInputFitVars()
Read in the input fit data variables, e.g. m13Sq and m23Sq.
void setSignalDPParameters()
Set the fit parameters for the DP model.
Double_t getEvtmPrime() const
Retrieve the square Dalitz plot coordinate, m&#39;, for the current event.
void readExperimentData(UInt_t iExpt)
Read events only for the given experiment.
void randomiseInitFitPars()
Randomise the initial fit parameters.
void appendBinCentres(LauFitDataTree *inputData)
Append fake data points to the inputData for each bin in the SCF smearing matrix. ...
virtual void savePDFPlotsWave(const TString &label, const Int_t &spin)
Save the pdf Plots for the sum of resonances of a given spin.
File containing declaration of LauIsobarDynamics class.
virtual UInt_t index() const
Retrieve the index number of the coefficient set.
void fillDataTree(const LauFitDataTree &fitDataTree)
Fill the internal data structure that caches the resonance dynamics.
virtual void checkInitFitParams()
Check the initial fit parameters.
const LauParameterList & extraPars() const
Const access the extra variables.
Double_t calcSqDPJacobian(const Double_t mPrime, const Double_t thPrime) const
Calculate the Jacobian for the transformation m23^2, m13^2 -&gt; m&#39;, theta&#39; (square DP) at the given poin...
Double_t abs2() const
Obtain the square of the absolute value of the complex number.
Definition: LauComplex.hh:232
virtual void recalculateNormalisation()
Recalculate Normalization the signal DP models.
std::vector< LauParameter * > LauParameterPList
List of parameter pointers.
const Bool_t tagged_
IS the analysis tagged?
UInt_t nExtraPdfPar_
Number of extra PDF parameters.
Bool_t gotSymmetricalDP() const
Is Dalitz plot symmetric, i.e. 2 identical particles.
Definition: LauDaughters.hh:66
void storeCorrMatrix(const UInt_t iExpt, const LauAbsFitter::FitStatus &fitStatus, const TMatrixD &covMatrix)
Store the correlation matrix and other fit information.
Definition: LauFitNtuple.cc:60
virtual void finaliseFitResults(const TString &tablePrefixName)
Get the fit results and store them.
Double_t getEvtm23Sq() const
Retrieve the invariant mass squared of the second and third daughters in the current event...
Bool_t withinDPLimits2(const Double_t m13Sq, const Double_t m23Sq) const
Check whether a given (m13Sq,m23Sq) point is within the kinematic limits of the Dalitz plot (alternat...
Bool_t blind() const
The blinding state.
virtual void printFitFractions(std::ostream &output)
Print the fit fractions, total DP rate and mean efficiency.
Double_t calcEfficiency(const LauKinematics *kinematics) const
Determine the efficiency for a given point in the Dalitz plot.
Definition: LauEffModel.cc:254
LauParArray negFitFracEffUnCorr_
Fit B- fractions (uncorrected for the efficiency)
void addIntegerBranch(const TString &name)
Add integer branch to tree.
Definition: LauGenNtuple.cc:73
UInt_t eventsPerExpt() const
Obtain the total number of events in the current experiment.
Definition: LauFitObject.hh:87
Class for defining a CP fit model.
Abstract interface to the fitting and toy MC model.
std::vector< LauParameter * > & getFloatingParameters()
Retrieve the floating parameters of the resonance models.
const TString tagVarName_
Event charge.
LauParameter * signalEvents_
Signal yield.
LauParArray posFitFracEffUnCorr_
Fit B+ fractions (uncorrected for the efficiency)
virtual void addGenNtupleIntegerBranch(const TString &name)
Add a branch to the gen tree for storing an integer.
const LauComplex & getEvtDPAmp() const
Retrieve the total amplitude for the current event.
std::vector< Int_t > evtCharges_
Vector to store event charges.
Int_t binNumber(Double_t xCoord, Double_t yCoord) const
Find the global bin number for the given co-ordinates.
Definition: LauScfMap.cc:144
Bool_t doPoissonSmearing() const
Determine whether Poisson smearing is enabled for the toy MC generation.
Double_t getc12() const
Get the cosine of the helicity angle theta12.
Double_t getm13() const
Get the m13 invariant mass.
std::vector< LauPdfList > LauBkgndPdfsList
Typedef for a vector of background PDFs.
void calcAsymmetries(Bool_t initValues=kFALSE)
Calculate the CP asymmetries.
std::map< TString, Double_t > NumbMap
Type to associate a category name with a double precision number, e.g. a yield or PDF value for a giv...
Definition: LauSPlot.hh:62
Bool_t doEMLFit() const
Determine whether an extended maximum likelihood fit it being performed.
const LauDaughters * getDaughters() const
Retrieve the daughters.
LauScfMap * scfMap_
The smearing matrix for the SCF DP PDF.
File containing declaration of LauComplex class.
Double_t sigExtraLike_
Signal likelihood from extra PDFs.
LauFitData getValues(const std::vector< TString > &names) const
Get values of specified branches.
const LauParArray & getFitFractionsEfficiencyUncorrected() const
Retrieve the fit fractions for the amplitude components.
virtual void setNBkgndEvents(LauParameter *nBkgndEvents)
Set the background event yield(s)
Class to store the results from the toy MC generation into an ntuple.
Definition: LauGenNtuple.hh:32
virtual void initialise()
Initialise the fit.
virtual LauSPlot::NumbMap fixdSpeciesNames() const
Returns the names and yields of species that are fixed in the fit.
Class for defining the abstract interface for complex coefficient classes.
Double_t sigTotalLike_
Total signal likelihood.
UInt_t nExpt() const
Obtain the number of experiments.
Definition: LauFitObject.hh:90
const TMatrixD & covarianceMatrix() const
Access the fit covariance matrix.
void clearFitParVectors()
Clear the vectors containing fit parameters.
virtual void setAmpCoeffSet(LauAbsCoeffSet *coeffSet)
Set the DP amplitude coefficients.
Class for defining the fit parameter objects.
Definition: LauParameter.hh:35
Class to store the data for embedding in toy experiments.
UInt_t getnTotAmp() const
Retrieve the total number of amplitude components.
virtual void addSPlotNtupleDoubleBranch(const TString &name)
Add a branch to the sPlot tree for storing a double.
UInt_t nSigComp_
Number of signal components.
virtual void setupSPlotNtupleBranches()
Add branches to store experiment number and the event number within the experiment.
void clearExtraVarVectors()
Clear the vectors containing extra ntuple variables.
LauParameter * signalAsym_
Signal asymmetry.
void getEmbeddedEvent(LauKinematics *kinematics)
Retrieve an event from the data sample.
void splitSignalComponent(const TH2 *dpHisto, const Bool_t upperHalf=kFALSE, const Bool_t fluctuateBins=kFALSE, LauScfMap *scfMap=0)
Split the signal component into well-reconstructed and mis-reconstructed parts.
virtual void savePDFPlots(const TString &label)
Save the pdf Plots for all the resonances.
const LauAbsEffModel * getEffModel() const
Retrieve the model for the efficiency across the Dalitz plot.
void updateKinematics(const Double_t m13Sq, const Double_t m23Sq)
Update all kinematic quantities based on the DP co-ordinates m13Sq and m23Sq.
std::vector< Double_t > bkgndDPLike_
Background DP likelihood value(s)
void embedNegBkgnd(const TString &bgClass, const TString &fileName, const TString &treeName, Bool_t reuseEventsWithinEnsemble, Bool_t reuseEventsWithinExperiment=kFALSE)
Embed full simulation events for the given background class, rather than generating toy from the PDFs...
LauBkgndEmbDataList negBkgndTree_
The B- background event tree.
void appendFakePoints(const std::vector< Double_t > &xCoords, const std::vector< Double_t > &yCoords)
Add fake events to the data.
File containing declaration of LauAbsPdf class.
Bool_t storeDPEff() const
Determine whether the efficiency information should be stored in the sPlot ntuple.
LauBkgndReuseEventsList reuseBkgnd_
Vector of booleans to reuse background events.
Double_t getEvtIntensity() const
Retrieve the total intensity multiplied by the efficiency for the current event.
std::vector< LauAbsCoeffSet * > coeffPars_
Magnitudes and Phases.
LauParameter posMeanEff_
The mean efficiency for B+ model.
UInt_t bkgndClassID(const TString &className) const
The number assigned to a background class.
const LauFitData & getData(UInt_t iEvt) const
Retrieve the data for a given event.
File containing LauRandom namespace.
Bool_t generate()
Generate a toy MC signal event.
Bool_t useRandomInitFitPars() const
Determine whether the initial values of the fit parameters, in particular the isobar coefficient para...
File containing declaration of LauEffModel class.
const LauFitDataTree * fitData() const
Const access the data store.
void setIntegerBranchValue(const TString &name, Int_t value)
Set value of an integer branch.
Definition: LauGenNtuple.cc:91
LauParArray CPCFitFrac_
The CP conserving fit fraction.
virtual void setNSigEvents(LauParameter *nSigEvents)
Set the signal event yield.
virtual void weightEvents(const TString &dataFileName, const TString &dataTreeName)
Weight events based on the DP model.
Bool_t validBkgndClass(const TString &className) const
Check if the given background class is in the list.
Bool_t usePosReweighting_
Boolean to use reweighting for B+.
Bool_t generateBkgndEvent(UInt_t bgID)
Generate background event.
virtual void writeOutTable(const TString &outputFile)
Write the fit results in latex table format.
Double_t getm12Sq() const
Get the m12 invariant mass square.
Class that implements the efficiency description across the signal Dalitz plot.
Definition: LauEffModel.hh:37
Int_t resonanceIndex(const TString &resName) const
Retrieve the index for the given resonance.
Abstract class for defining type for resonance amplitude models (Breit-Wigner, Flatte etc...
TString getNameParent() const
Get name of the parent particle.
const LauParameterPSet & resPars() const
Const access the fit variables which affect the DP normalisation.
UInt_t nUsedEvents() const
Retrieve the number of events that have already been sampled.
Double_t getm13Sq() const
Get the m13 invariant mass square.
void storeParsAndErrors(const std::vector< LauParameter * > &fitVars, const std::vector< LauParameter > &extraVars)
Store parameters and their errors.
virtual void updateCoeffs()
Update the coefficients.
virtual void setSPlotNtupleIntegerBranchValue(const TString &name, Int_t value)
Set the value of an integer branch in the sPlot tree.
Double_t setSPlotNtupleBranchValues(LauPdfList *extraPdfs, const TString &prefix, UInt_t iEvt)
Set the branches for the sPlot ntuple with extra PDFs.
Double_t initValue() const
The initial value of the parameter.
virtual ~LauCPFitModel()
Destructor.
std::vector< LauComplex > posCoeffs_
The complex coefficients for B+.
virtual void initialiseDPModels()
Initialise the signal DP models.
void updateSigEvents()
Update the signal events after Minuit sets background parameters.
Class for defining signal dynamics using the isobar model.
Double_t getm12() const
Get the m12 invariant mass.
Double_t getEventWeight()
Calculate the acceptance rate, for events with the current kinematics, when generating events accordi...
virtual void fillSPlotNtupleBranches()
Fill the sPlot tuple.
virtual void setupBkgndVectors()
Define the length of the background vectors.
File containing LauConstants namespace.
void setSignalPdfs(LauAbsPdf *negPdf, LauAbsPdf *posPdf)
Set the signal PDFs.
void setFitNEvents()
Set the initial yields.
virtual LauSPlot::TwoDMap twodimPDFs() const
Returns the species and variables for all 2D PDFs in the fit.
virtual LauSPlot::NumbMap freeSpeciesNames() const
Returns the names and yields of species that are free in the fit.
void writeOutGenResults()
Write out the results from the generation.
LauEffModel * scfFracHist_
The histogram giving the DP-dependence of the SCF fraction.
void printFormat(std::ostream &stream, Double_t value) const
Method to choose the printing format to a specified level of precision.
Definition: LauPrint.cc:32
Double_t unblindValue() const
The unblinded value of the parameter.
ToyMCStatus checkToyMC(Bool_t printErrorMessages=kTRUE, Bool_t printInfoMessages=kFALSE)
Check the status of the toy MC generation.
Class to store the results from the fit into an ntuple.
Definition: LauFitNtuple.hh:44
UInt_t getnCohAmp() const
Retrieve the number of coherent amplitude components.
UInt_t nSigDPPar_
Number of signal DP parameters.
Bool_t haveBranch(const TString &name) const
Check if the named branch is stored.
virtual void propagateParUpdates()
Calculate things that depend on the fit parameters after they have been updated by Minuit...
Class for representing the 4D smearing matrix for mis-reconstructed signal (self cross feed) ...
Definition: LauScfMap.hh:29
virtual void storePerEvtLlhds()
Store the per event likelihood values.
Double_t scfDPLike_
SCF DP likelihood value.
Double_t getThetaPrime() const
Get theta&#39; value.
Class for defining a complex number.
Definition: LauComplex.hh:47
void updatePull()
Call to update the bias and pull values.
Double_t getEvtEff() const
Retrieve the efficiency for the current event.
UInt_t nBkgndClasses() const
Returns the number of background classes.
const TString & bkgndClassName(UInt_t classID) const
Get the name of a background class from the number.
std::vector< Double_t > recoJacobians_
The cached values of the sqDP jacobians for each event.
const LauAbsFitter::FitStatus & fitStatus() const
Access the fit status information.
Bool_t enableEmbedding() const
Determine whether embedding of events is enabled in the generation.
virtual Double_t getEventSum() const
Get the total number of events.
virtual TString name() const
Retrieve the name of the coefficient set.
Class for defining the abstract interface for PDF classes.
Definition: LauAbsPdf.hh:41
LauIsobarDynamics * posSigModel_
The B+ signal Dalitz plot model.
const LauParameterPList & fitPars() const
Const access the fit variables.
LauPdfList posScfPdfs_
The B+ SCF PDFs.
LauBkgndYieldList bkgndEvents_
Background yield(s)
Class for calculating 3-body kinematic quantities.
Double_t value() const
The value of the parameter.
LauBkgndDPModelList negBkgndDPModels_
The B- background Dalitz plot models.
UInt_t nEvents() const
Retrieve the number of events.
LauParArray CPVFitFrac_
The CP violating fit fraction.
virtual void addGenNtupleDoubleBranch(const TString &name)
Add a branch to the gen tree for storing a double.
LauPdfList posSignalPdfs_
The B+ signal PDFs.
void updateFitParameters(LauPdfList &pdfList)
Update the fit parameters for all PDFs in the list.
void embedPosBkgnd(const TString &bgClass, const TString &fileName, const TString &treeName, Bool_t reuseEventsWithinEnsemble, Bool_t reuseEventsWithinExperiment=kFALSE)
Embed full simulation events for the given background class, rather than generating toy from the PDFs...
std::vector< Double_t > fakeJacobians_
The cached values of the sqDP jacobians for each true bin.
virtual const TString & baseName() const
Retrieve the base name of the coefficient set.
Double_t getAsymmetry()
Retrieve the asymmetry.
Definition: LauAsymmCalc.hh:48
virtual Double_t getEvtSCFDPLikelihood(UInt_t iEvt)
Calculate the SCF likelihood for the DP for a given event.
void addDoubleBranch(const TString &name)
Add double branch to tree.
Definition: LauGenNtuple.cc:82
UInt_t iExpt() const
Obtain the number of the current experiment.
Definition: LauFitObject.hh:96
const std::vector< LauParameter > & getExtraParameters() const
Retrieve any extra parameters/quantities (e.g. K-matrix total fit fractions)
Bool_t findBranches()
Find and read the branches in data tree.
Int_t getSpin() const
Get the spin of the resonance.
File containing declaration of LauAbsBkgndDPModel class.
void setSCFPdfs(LauAbsPdf *negPdf, LauAbsPdf *posPdf)
Set the SCF PDF for a given variable.
std::map< std::pair< TString, Int_t >, std::pair< Int_t, Double_t > > LauGenInfo
Define a map to be used to store a category name and numbers.
Bool_t useSCFHist_
Is the SCF fraction DP-dependent.
LauParameter negMeanEff_
The mean efficiency for B- model.
void setBkgndPdfs(const TString &bkgndClass, LauAbsPdf *negPdf, LauAbsPdf *posPdf)
Set the background PDFs.
Double_t prob(Int_t recoBin, Int_t trueBin) const
Probability of a true event in the given true bin migrating to the reco bin.
Definition: LauScfMap.cc:165
void initialise(const std::vector< LauComplex > &coeffs)
Initialise the Dalitz plot dynamics.
virtual Double_t getTotEvtLikelihood(UInt_t iEvt)
Get the total likelihood for each event.
virtual void getEvtDPLikelihood(UInt_t iEvt)
Calculate the signal and background likelihoods for the DP for a given event.
Double_t getEvtm13Sq() const
Retrieve the invariant mass squared of the first and third daughters in the current event...
Double_t genValue() const
The value generated for the parameter.
LauBkgndEmbDataList posBkgndTree_
The B+ background event tree.
void setBkgndDPModels(const TString &bkgndClass, LauAbsBkgndDPModel *negModel, LauAbsBkgndDPModel *posModel)
Set the background DP models.
LauBkgndPdfsList negBkgndPdfs_
The B- background PDFs.
UInt_t firstExpt() const
Obtain the number of the first experiment.
Definition: LauFitObject.hh:93
Class to store the input fit variables.
LauParameter scfFrac_
The (global) SCF fraction parameter.
std::set< TString > NameSet
Type to store names, e.g. of the discriminating/control variables.
Definition: LauSPlot.hh:59
File containing declaration of LauFitNtuple class.
void setDPBranchValues()
Store all of the DP information.
File containing declaration of LauGenNtuple class.
LauKinematics * posKinematics_
The B+ Dalitz plot kinematics object.
void setDoubleBranchValue(const TString &name, Double_t value)
Set value of a double branch.
Definition: LauGenNtuple.cc:96
void embedPosSignal(const TString &fileName, const TString &treeName, Bool_t reuseEventsWithinEnsemble, Bool_t reuseEventsWithinExperiment=kFALSE, Bool_t useReweighting=kFALSE)
Embed full simulation events for the B+ signal, rather than generating toy from the PDFs...
std::vector< LauParameter > fitFracAsymm_
The fit fraction asymmetries.
virtual Bool_t generate()=0
Generate a toy MC event from the model.
void setExtraNtupleVars()
Set-up other parameters that are derived from the fit results, e.g. fit fractions.
virtual Bool_t passVeto(const LauKinematics *kinematics) const =0
Determine whether the given DP position is outside the vetoes.