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