laura is hosted by Hepforge, IPPP Durham
Laura++  v2r0
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauAbsFitModel.cc
Go to the documentation of this file.
1 
2 // Copyright University of Warwick 2004 - 2013.
3 // Distributed under the Boost Software License, Version 1.0.
4 // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 // Authors:
7 // Thomas Latham
8 // John Back
9 // Paul Harrison
10 
15 #include <iostream>
16 #include <limits>
17 #include <vector>
18 
19 #include "TMessage.h"
20 #include "TMonitor.h"
21 #include "TServerSocket.h"
22 #include "TSocket.h"
23 #include "TSystem.h"
24 #include "TVectorD.h"
25 #include "TVirtualFitter.h"
26 
27 #include "LauAbsFitModel.hh"
28 #include "LauAbsFitter.hh"
29 #include "LauAbsPdf.hh"
30 #include "LauComplex.hh"
31 #include "LauFitter.hh"
32 #include "LauFitDataTree.hh"
33 #include "LauFitNtuple.hh"
34 #include "LauGenNtuple.hh"
35 #include "LauParameter.hh"
36 #include "LauParamFixed.hh"
37 #include "LauPrint.hh"
38 #include "LauSPlot.hh"
39 
40 ClassImp(LauAbsFitModel)
41 
42 
44  twoStageFit_(kFALSE),
45  useAsymmFitErrors_(kFALSE),
46  compareFitData_(kFALSE),
47  writeLatexTable_(kFALSE),
48  writeSPlotData_(kFALSE),
49  storeDPEff_(kFALSE),
50  randomFit_(kFALSE),
51  emlFit_(kFALSE),
52  poissonSmear_(kFALSE),
53  enableEmbedding_(kFALSE),
54  usingDP_(kTRUE),
55  pdfsDependOnDP_(kFALSE),
56  firstExpt_(0),
57  nExpt_(0),
58  evtsPerExpt_(0),
59  iExpt_(0),
60  inputFitData_(0),
61  fitNtuple_(0),
62  genNtuple_(0),
63  sPlotNtuple_(0),
64  fitStatus_(0),
65  NLL_(0),
66  numberOKFits_(0),
67  numberBadFits_(0),
68  nParams_(0),
69  nFreeParams_(0),
70  worstLogLike_(std::numeric_limits<Double_t>::max()),
71  withinAsymErrorCalc_(kFALSE),
72  nullString_(""),
73  doSFit_(kFALSE),
74  sWeightBranchName_(""),
75  sWeightScaleFactor_(1.0),
76  fitToyMCFileName_("fitToyMC.root"),
77  fitToyMCTableName_("fitToyMCTable"),
78  fitToyMCScale_(10),
79  fitToyMCPoissonSmear_(kFALSE),
80  sPlotFileName_(""),
81  sPlotTreeName_(""),
82  sPlotVerbosity_(""),
83  sMaster_(0),
84  messageFromMaster_(0),
85  slaveId_(-1),
86  nSlaves_(0),
87  parValues_(0)
88 {
89 }
90 
91 
93 {
94  delete inputFitData_; inputFitData_ = 0;
95  delete fitNtuple_; fitNtuple_ = 0;
96  delete genNtuple_; genNtuple_ = 0;
97  delete sPlotNtuple_; sPlotNtuple_ = 0;
98  delete sMaster_; sMaster_ = 0;
99  delete[] parValues_; parValues_ = 0;
100 }
101 
102 void LauAbsFitModel::run(const TString& applicationCode, const TString& dataFileName, const TString& dataTreeName,
103  const TString& histFileName, const TString& tableFileName)
104 {
105  // Chose whether you want to generate or fit events in the Dalitz plot.
106  // To generate events choose applicationCode = "gen", to fit events choose
107  // applicationCode = "fit".
108 
109  TString runCode(applicationCode);
110  runCode.ToLower();
111 
112  TString histFileNameCopy(histFileName);
113  TString tableFileNameCopy(tableFileName);
114  TString dataFileNameCopy(dataFileName);
115  TString dataTreeNameCopy(dataTreeName);
116 
117  // Initialise the fit par vectors. Each class that inherits from this one
118  // must implement this sensibly for all vectors specified in clearFitParVectors,
119  // i.e. specify parameter names, initial, min, max and fixed values
120  this->initialise();
121 
122  // Add variables to Gaussian constrain to a list
123  this->addConParameters();
124 
125  if (dataFileNameCopy == "") {dataFileNameCopy = "data.root";}
126  if (dataTreeNameCopy == "") {dataTreeNameCopy = "genResults";}
127 
128  if (runCode.Contains("gen")) {
129 
130  if (histFileNameCopy == "") {histFileNameCopy = "parInfo.root";}
131  if (tableFileNameCopy == "") {tableFileNameCopy = "genResults";}
132 
133  this->setGenValues();
134  this->generate(dataFileNameCopy, dataTreeNameCopy, histFileNameCopy, tableFileNameCopy);
135 
136  } else if (runCode.Contains("fit")) {
137 
138  if (histFileNameCopy == "") {histFileNameCopy = "parInfo.root";}
139  if (tableFileNameCopy == "") {tableFileNameCopy = "fitResults";}
140 
141  this->fit(dataFileNameCopy, dataTreeNameCopy, histFileNameCopy, tableFileNameCopy);
142 
143  } else if (runCode.Contains("reweight")) {
144 
145  this->weightEvents(dataFileNameCopy, dataTreeNameCopy);
146  }
147 }
148 
149 void LauAbsFitModel::runSlave(const TString& dataFileName, const TString& dataTreeName,
150  const TString& histFileName, const TString& tableFileName,
151  const TString& addressMaster, const UInt_t portMaster)
152 {
153  if ( sMaster_ != 0 ) {
154  std::cerr << "ERROR in LauAbsFitModel::runSlave : master socket already present" << std::endl;
155  return;
156  }
157 
158  // Open connection to master
159  sMaster_ = new TSocket(addressMaster, portMaster);
160  sMaster_->Recv( messageFromMaster_ );
161  messageFromMaster_->ReadUInt( slaveId_ );
162  messageFromMaster_->ReadUInt( nSlaves_ );
163 
164  delete messageFromMaster_;
165  messageFromMaster_ = 0;
166 
167  std::cout << "INFO in LauAbsFitModel::runSlave : Established connection to master on port " << portMaster << std::endl;
168  std::cout << " : We are slave " << slaveId_ << " of " << nSlaves_ << std::endl;
169 
170  // Initialise the fit par vectors. Each class that inherits from this one
171  // must implement this sensibly for all vectors specified in clearFitParVectors,
172  // i.e. specify parameter names, initial, min, max and fixed values
173  this->initialise();
174 
175  nParams_ = fitVars_.size();
176  parValues_ = new Double_t[nParams_];
177  for ( UInt_t iPar(0); iPar < nParams_; ++iPar ) {
178  parValues_[iPar] = fitVars_[iPar]->initValue();
179  }
180 
181  TString dataFileNameCopy(dataFileName);
182  TString dataTreeNameCopy(dataTreeName);
183  TString histFileNameCopy(histFileName);
184  TString tableFileNameCopy(tableFileName);
185 
186  if (dataFileNameCopy == "") {dataFileNameCopy = "data.root";}
187  if (dataTreeNameCopy == "") {dataTreeNameCopy = "genResults";}
188  if (histFileNameCopy == "") {histFileNameCopy = "parInfo.root";}
189  if (tableFileNameCopy == "") {tableFileNameCopy = "fitResults";}
190 
191  this->fitSlave(dataFileNameCopy, dataTreeNameCopy, histFileNameCopy, tableFileNameCopy);
192 
193  std::cout << "INFO in LauAbsFitModel::runSlave : Fit slave " << slaveId_ << " has finished successfully" << std::endl;
194 }
195 
196 void LauAbsFitModel::doSFit( const TString& sWeightBranchName, Double_t scaleFactor )
197 {
198  if ( sWeightBranchName == "" ) {
199  std::cerr << "WARNING in LauAbsFitModel::doSFit : sWeight branch name is empty string, not setting-up sFit." << std::endl;
200  return;
201  }
202 
203  doSFit_ = kTRUE;
204  sWeightBranchName_ = sWeightBranchName;
205  sWeightScaleFactor_ = scaleFactor;
206 }
207 
208 void LauAbsFitModel::setBkgndClassNames( const std::vector<TString>& names )
209 {
210  if ( !bkgndClassNames_.empty() ) {
211  std::cerr << "WARNING in LauAbsFitModel::setBkgndClassNames : Names already stored, not changing them." << std::endl;
212  return;
213  }
214 
215  UInt_t nBkgnds = names.size();
216  for ( UInt_t i(0); i < nBkgnds; ++i ) {
217  bkgndClassNames_.insert( std::make_pair( i, names[i] ) );
218  }
219 
220  this->setupBkgndVectors();
221 }
222 
223 Bool_t LauAbsFitModel::validBkgndClass( const TString& className ) const
224 {
225  if ( bkgndClassNames_.empty() ) {
226  return kFALSE;
227  }
228 
229  Bool_t found(kFALSE);
230  for ( LauBkgndClassMap::const_iterator iter = bkgndClassNames_.begin(); iter != bkgndClassNames_.end(); ++iter ) {
231  if ( iter->second == className ) {
232  found = kTRUE;
233  break;
234  }
235  }
236 
237  return found;
238 }
239 
240 UInt_t LauAbsFitModel::bkgndClassID( const TString& className ) const
241 {
242  if ( ! this->validBkgndClass( className ) ) {
243  std::cerr << "ERROR in LauAbsFitModel::bkgndClassID : Request for ID for invalid background class \"" << className << "\"." << std::endl;
244  return (bkgndClassNames_.size() + 1);
245  }
246 
247  UInt_t bgID(0);
248  for ( LauBkgndClassMap::const_iterator iter = bkgndClassNames_.begin(); iter != bkgndClassNames_.end(); ++iter ) {
249  if ( iter->second == className ) {
250  bgID = iter->first;
251  break;
252  }
253  }
254 
255  return bgID;
256 }
257 
258 const TString& LauAbsFitModel::bkgndClassName( UInt_t classID ) const
259 {
260  LauBkgndClassMap::const_iterator iter = bkgndClassNames_.find( classID );
261 
262  if ( iter == bkgndClassNames_.end() ) {
263  std::cerr << "ERROR in LauAbsFitModel::bkgndClassName : Request for name of invalid background class ID " << classID << "." << std::endl;
264  return nullString_;
265  }
266 
267  return iter->second;
268 }
269 
271 {
272  std::cout << "INFO in LauAbsFitModel::clearFitParVectors : Clearing fit variable vectors" << std::endl;
273  fitVars_.clear();
274  conVars_.clear();
275 }
276 
278 {
279  std::cout << "INFO in LauAbsFitModel::clearExtraVarVectors : Clearing extra ntuple variable vectors" << std::endl;
280  extraVars_.clear();
281 }
282 
284 {
285  // makes sure each parameter holds its genValue as its current value
286  for (LauParameterPList::iterator iter = fitVars_.begin(); iter != fitVars_.end(); ++iter) {
287  (*iter)->value((*iter)->genValue());
288  }
289  this->propagateParUpdates();
290 }
291 
292 void LauAbsFitModel::writeSPlotData(const TString& fileName, const TString& treeName, Bool_t storeDPEfficiency, const TString& verbosity)
293 {
294  if (this->writeSPlotData()) {
295  std::cerr << "ERROR in LauAbsFitModel::writeSPlotData : Already have an sPlot ntuple setup, not doing it again." << std::endl;
296  return;
297  }
298  writeSPlotData_ = kTRUE;
299  sPlotFileName_ = fileName;
300  sPlotTreeName_ = treeName;
301  sPlotVerbosity_ = verbosity;
302  storeDPEff_ = storeDPEfficiency;
303 }
304 
305 // TODO : histFileName isn't used here at the moment but could be used for
306 // storing the values of the parameters used in the generation.
307 // These could then be read and used for setting the "true" values
308 // in a subsequent fit.
309 void LauAbsFitModel::generate(const TString& dataFileName, const TString& dataTreeName, const TString& /*histFileName*/, const TString& tableFileNameBase)
310 {
311  // Create the ntuple for storing the results
312  std::cout << "INFO in LauAbsFitModel::generate : Creating generation ntuple." << std::endl;
313  if (genNtuple_ != 0) {delete genNtuple_; genNtuple_ = 0;}
314  genNtuple_ = new LauGenNtuple(dataFileName,dataTreeName);
315 
316  // add branches for storing the experiment number and the number of
317  // the event within the current experiment
318  this->addGenNtupleIntegerBranch("iExpt");
319  this->addGenNtupleIntegerBranch("iEvtWithinExpt");
320  this->setupGenNtupleBranches();
321 
322  // Start the cumulative timer
323  cumulTimer_.Start();
324 
325  Bool_t genOK(kTRUE);
326  do {
327  // Loop over the number of experiments
328  for (iExpt_ = firstExpt_; iExpt_ < (firstExpt_+nExpt_); ++iExpt_) {
329 
330  // Start the timer to see how long each experiment takes to generate
331  timer_.Start();
332 
333  // Store the experiment number in the ntuple
334  this->setGenNtupleIntegerBranchValue("iExpt",iExpt_);
335 
336  // Do the generation for this experiment
337  std::cout << "INFO in LauAbsFitModel::generate : Generating experiment number " << iExpt_ << std::endl;
338  genOK = this->genExpt();
339 
340  // Stop the timer and see how long the program took so far
341  timer_.Stop();
342  timer_.Print();
343 
344  if (!genOK) {
345  // delete and recreate an empty tree
347 
348  // then break out of the experiment loop
349  std::cerr << "ERROR in LauAbsFitModel::generate : Problem in toy MC generation. Starting again with updated parameters..." << std::endl;
350  break;
351  }
352 
353  if (this->writeLatexTable()) {
354  TString tableFileName(tableFileNameBase);
355  tableFileName += "_";
356  tableFileName += iExpt_;
357  tableFileName += ".tex";
358  this->writeOutTable(tableFileName);
359  }
360 
361  } // Loop over number of experiments
362  } while (!genOK);
363 
364  // Print out total timing info.
365  cumulTimer_.Stop();
366  std::cout << "INFO in LauAbsFitModel::generate : Finished generating all experiments." << std::endl;
367  std::cout << "INFO in LauAbsFitModel::generate : Cumulative timing:" << std::endl;
368  cumulTimer_.Print();
369 
370  // Build the event index
371  std::cout << "INFO in LauAbsFitModel::generate : Building experiment:event index." << std::endl;
372  // TODO - can test this return value?
373  //Int_t nIndexEntries =
374  genNtuple_->buildIndex("iExpt","iEvtWithinExpt");
375 
376  // Write out toy MC ntuple
377  std::cout << "INFO in LauAbsFitModel::generate : Writing data to file " << dataFileName << "." << std::endl;
379 }
380 
382 {
384 }
385 
387 {
389 }
390 
392 {
393  genNtuple_->setIntegerBranchValue(name,value);
394 }
395 
397 {
398  genNtuple_->setDoubleBranchValue(name,value);
399 }
400 
402 {
403  return genNtuple_->getIntegerBranchValue(name);
404 }
405 
407 {
408  return genNtuple_->getDoubleBranchValue(name);
409 }
410 
412 {
414 }
415 
417 {
419 }
420 
422 {
424 }
425 
427 {
428  sPlotNtuple_->setIntegerBranchValue(name,value);
429 }
430 
432 {
433  sPlotNtuple_->setDoubleBranchValue(name,value);
434 }
435 
437 {
439 }
440 
441 void LauAbsFitModel::fit(const TString& dataFileName, const TString& dataTreeName, const TString& histFileName, const TString& tableFileNameBase)
442 {
443  // Routine to perform the total fit.
444 
445  std::cout << "INFO in LauAbsFitModel::fit : First experiment = " << firstExpt_ << std::endl;
446  std::cout << "INFO in LauAbsFitModel::fit : Number of experiments = " << nExpt_ << std::endl;
447 
448  // Start the cumulative timer
449  cumulTimer_.Start();
450 
451  numberOKFits_ = 0, numberBadFits_ = 0;
452  fitStatus_ = -1;
453 
454  // Create and setup the fit results ntuple
455  std::cout << "INFO in LauAbsFitModel::fit : Creating fit ntuple." << std::endl;
456  if (fitNtuple_ != 0) {delete fitNtuple_; fitNtuple_ = 0;}
457  fitNtuple_ = new LauFitNtuple(histFileName, this->useAsymmFitErrors());
458 
459  // Create and setup the sPlot ntuple
460  if (this->writeSPlotData()) {
461  std::cout << "INFO in LauAbsFitModel::fit : Creating sPlot ntuple." << std::endl;
462  if (sPlotNtuple_ != 0) {delete sPlotNtuple_; sPlotNtuple_ = 0;}
464  this->setupSPlotNtupleBranches();
465  }
466 
467  // This reads in the given dataFile and creates an input
468  // fit data tree that stores them for all events and experiments.
469  Bool_t dataOK = this->cacheFitData(dataFileName,dataTreeName);
470  if (!dataOK) {
471  std::cerr << "ERROR in LauAbsFitModel::fit : Problem caching the fit data." << std::endl;
472  gSystem->Exit(EXIT_FAILURE);
473  }
474 
475  // Loop over the number of experiments
476  for (iExpt_ = firstExpt_; iExpt_ < (firstExpt_+nExpt_); ++iExpt_) {
477 
478  // Start the timer to see how long each fit takes
479  timer_.Start();
480 
483 
484  if (this->eventsPerExpt() < 1) {
485  std::cerr << "ERROR in LauAbsFitModel::fit : Zero events in experiment " << iExpt_ << ", skipping..." << std::endl;
486  timer_.Stop();
487  continue;
488  }
489 
490  // Now the sub-classes must implement whatever they need to do
491  // to cache any more input fit data they need in order to
492  // calculate the likelihoods during the fit.
493  // They need to use the inputFitData_ tree as input. For example,
494  // inputFitData_ contains m13Sq and m23Sq. The appropriate fit model
495  // then caches the resonance dynamics for the signal model, as
496  // well as the background likelihood values in the Dalitz plot
497  this->cacheInputFitVars();
498  if ( this->doSFit() ) {
499  this->cacheInputSWeights();
500  }
501 
502  // Do the fit for this experiment
503  this->fitExpt();
504 
505  // Write the results into the ntuple
506  this->finaliseFitResults(tableFileNameBase);
507 
508  // Stop the timer and see how long the program took so far
509  timer_.Stop();
510  timer_.Print();
511 
512  // Store the per-event likelihood values
513  if ( this->writeSPlotData() ) {
514  this->storePerEvtLlhds();
515  }
516 
517  // Create a toy MC sample for the 1st successful experiment
518  // using the fitted parameters so that the user can compare
519  // the fit to the actual data. The toy MC stats are a
520  // factor of 10 higher than the number of events specified
521  // via setNEvGen. This is to reduce the statistical
522  // fluctuations for the toy MC data.
523  if (compareFitData_ == kTRUE && fitStatus_ == 3) {
525  compareFitData_ = kFALSE; // only do this for the first successful experiment
526  }
527 
528  // Keep track of how many fits worked or failed
529  // NB values of fitStatus_ now indicate the status of the error matrix:
530  // 0= not calculated at all
531  // 1= approximation only, not accurate
532  // 2= full matrix, but forced positive-definite
533  // 3= full accurate covariance matrix
534  if (fitStatus_ == 3) {
535  numberOKFits_++;
536  } else {
537  numberBadFits_++;
538  }
539 
540  } // Loop over number of experiments
541 
542  // Print out total timing info.
543  cumulTimer_.Stop();
544  std::cout << "INFO in LauAbsFitModel::fit : Cumulative timing:" << std::endl;
545  cumulTimer_.Print();
546 
547  // Print out stats on OK fits.
548  std::cout << "INFO in LauAbsFitModel::fit : Number of OK Fits = " << numberOKFits_ << std::endl;
549  std::cout << "INFO in LauAbsFitModel::fit : Number of Failed Fits = " << numberBadFits_ << std::endl;
550  Double_t fitEff(0.0);
551  if (nExpt_ != 0) {fitEff = numberOKFits_/(1.0*nExpt_);}
552  std::cout << "INFO in LauAbsFitModel::fit : Fit efficiency = " << fitEff*100.0 << "%." << std::endl;
553 
554  // Write out any fit results (ntuples etc...).
555  this->writeOutAllFitResults();
556  if ( this->writeSPlotData() ) {
557  this->calculateSPlotData();
558  }
559 }
560 
561 void LauAbsFitModel::fitSlave(const TString& dataFileName, const TString& dataTreeName, const TString& histFileName, const TString& tableFileNameBase)
562 {
563  // Create and setup the fit results ntuple
564  std::cout << "INFO in LauAbsFitModel::fitSlave : Creating fit ntuple." << std::endl;
565  if (fitNtuple_ != 0) {delete fitNtuple_; fitNtuple_ = 0;}
566  fitNtuple_ = new LauFitNtuple(histFileName, this->useAsymmFitErrors());
567 
568  // This reads in the given dataFile and creates an input
569  // fit data tree that stores them for all events and experiments.
570  Bool_t dataOK = this->cacheFitData(dataFileName,dataTreeName);
571  if (!dataOK) {
572  std::cerr << "ERROR in LauAbsFitModel::fitSlave : Problem caching the fit data." << std::endl;
573  gSystem->Exit(EXIT_FAILURE);
574  }
575 
576  // Now process the various requests from the master
577 
578  TMessage messageToMaster(kMESS_ANY);
579 
580  while ( kTRUE ) {
581 
582  sMaster_->Recv( messageFromMaster_ );
583 
584  if ( messageFromMaster_->What() == kMESS_STRING ) {
585 
586  TString msgStr;
587  messageFromMaster_->ReadTString( msgStr );
588 
589  std::cout << "INFO in LauAbsFitModel::fitSlave : Received message from master: " << msgStr << std::endl;
590 
591  if ( msgStr == "Send Parameters" ) {
592 
593  // Update initial fit parameters if required (e.g. if using random numbers).
594  this->checkInitFitParams();
595 
596  // Send the fit parameters
597  TObjArray array;
598  for ( LauParameterPList::iterator iter = fitVars_.begin(); iter != fitVars_.end(); ++iter ) {
599  array.Add( *iter );
600  }
601 
602  messageToMaster.Reset( kMESS_OBJECT );
603  messageToMaster.WriteObject( &array );
604  sMaster_->Send( messageToMaster );
605 
606  } else if ( msgStr == "Read Expt" ) {
607 
608  // Read the data for this experiment
609  messageFromMaster_->ReadUInt( iExpt_ );
610 
612  UInt_t nEvent = inputFitData_->nEvents();
613  this->eventsPerExpt( nEvent );
614 
615  if ( nEvent < 1 ) {
616  std::cerr << "ERROR in LauAbsFitModel::fitSlave : Zero events in experiment " << firstExpt_ << ", the master should skip this experiment..." << std::endl;
617  }
618 
619  messageToMaster.Reset( kMESS_ANY );
620  messageToMaster.WriteUInt( slaveId_ );
621  messageToMaster.WriteUInt( nEvent );
622  sMaster_->Send( messageToMaster );
623 
624  } else if ( msgStr == "Cache" ) {
625 
626  // Perform the caching
627 
628  this->cacheInputFitVars();
629 
630  messageToMaster.Reset( kMESS_ANY );
631  messageToMaster.WriteUInt( slaveId_ );
632  messageToMaster.WriteBool( kTRUE );
633  sMaster_->Send( messageToMaster );
634 
635  } else if ( msgStr == "Write Results" ) {
636 
637  this->writeOutAllFitResults();
638 
639  messageToMaster.Reset( kMESS_ANY );
640  messageToMaster.WriteUInt( slaveId_ );
641  messageToMaster.WriteBool( kTRUE );
642  sMaster_->Send( messageToMaster );
643 
644  } else if ( msgStr == "Finish" ) {
645 
646  std::cout << "INFO in LauAbsFitModel::fitSlave : Message from master to finish" << std::endl;
647  break;
648  } else {
649  std::cerr << "ERROR in LauAbsFitModel::fitSlave : Unexpected message from master" << std::endl;
650  gSystem->Exit( EXIT_FAILURE );
651  }
652 
653  } else if ( messageFromMaster_->What() == kMESS_OBJECT ) {
654 
655  std::cout << "INFO in LauAbsFitModel::fitSlave : Received message from master: Finalise" << std::endl;
656 
657  messageFromMaster_->ReadInt( fitStatus_ );
658  messageFromMaster_->ReadDouble( NLL_ );
659 
660  TObjArray * objarray = dynamic_cast<TObjArray*>( messageFromMaster_->ReadObject( messageFromMaster_->GetClass() ) );
661  if ( ! objarray ) {
662  std::cerr << "ERROR in LauAbsFitModel::fitSlave : Error reading parameters from master" << std::endl;
663  gSystem->Exit( EXIT_FAILURE );
664  }
665 
666  TMatrixD * covMat = dynamic_cast<TMatrixD*>( messageFromMaster_->ReadObject( messageFromMaster_->GetClass() ) );
667  if ( ! covMat ) {
668  std::cerr << "ERROR in LauAbsFitModel::fitSlave : Error reading covariance matrix from master" << std::endl;
669  gSystem->Exit( EXIT_FAILURE );
670  }
671  covMatrix_.Clear();
672  covMatrix_.ResizeTo( covMat->GetNrows(), covMat->GetNcols() );
673  covMatrix_.SetMatrixArray( covMat->GetMatrixArray() );
674  delete covMat; covMat = 0;
675 
676 
677  UInt_t nPars = objarray->GetEntries();
678 
679  if ( nPars != nParams_ ) {
680  std::cerr << "ERROR in LauAbsFitModel::fitSlave : Unexpected number of parameters received from master" << std::endl;
681  std::cerr << " ::fitSlave : Received " << nPars << " when expecting " << nParams_ << std::endl;
682  gSystem->Exit( EXIT_FAILURE );
683  }
684 
685  for ( UInt_t iPar(0); iPar < nPars; ++iPar ) {
686  LauParameter* parameter = dynamic_cast<LauParameter*>( (*objarray)[iPar] );
687  if ( ! parameter ) {
688  std::cerr << "ERROR in LauAbsFitModel::fitSlave : Error reading parameter from master" << std::endl;
689  gSystem->Exit( EXIT_FAILURE );
690  }
691 
692  if ( parameter->name() != fitVars_[iPar]->name() ) {
693  std::cerr << "ERROR in LauAbsFitModel::fitSlave : Error reading parameter from master" << std::endl;
694  gSystem->Exit( EXIT_FAILURE );
695  }
696 
697  *(fitVars_[iPar]) = *parameter;
698  }
699 
700  this->finaliseFitResults( tableFileNameBase );
701 
702  // Send the finalised parameters
703  TObjArray array;
704  for ( LauParameterPList::iterator iter = fitVars_.begin(); iter != fitVars_.end(); ++iter ) {
705  array.Add( *iter );
706  }
707 
708  messageToMaster.Reset( kMESS_ANY );
709  messageToMaster.WriteUInt( slaveId_ );
710  messageToMaster.WriteBool( kTRUE );
711  messageToMaster.WriteObject( &array );
712  sMaster_->Send( messageToMaster );
713 
714  } else if ( messageFromMaster_->What() == kMESS_ANY ) {
715 
716  UInt_t nPars(0);
717  messageFromMaster_->ReadUInt( nPars );
718 
719  if ( nPars != nParams_ ) {
720  std::cerr << "ERROR in LauAbsFitModel::fitSlave : Unexpected number of parameters received from master" << std::endl;
721  std::cerr << " ::fitSlave : Received " << nPars << " when expecting " << nParams_ << std::endl;
722  gSystem->Exit( EXIT_FAILURE );
723  }
724 
725  messageFromMaster_->ReadFastArray( parValues_, nPars );
726 
727  for ( UInt_t iPar(0); iPar < nPars; ++iPar ) {
728  if ( ! fitVars_[iPar]->fixed() ) {
729  fitVars_[iPar]->value( parValues_[iPar] );
730  }
731  }
732  this->propagateParUpdates();
733 
734  Double_t negLogLike = this->getTotNegLogLikelihood();
735 
736  messageToMaster.Reset( kMESS_ANY );
737  messageToMaster.WriteDouble( negLogLike );
738  sMaster_->Send( messageToMaster );
739 
740  } else {
741  std::cerr << "ERROR in LauAbsFitModel::fitSlave : Unexpected message type" << std::endl;
742  gSystem->Exit( EXIT_FAILURE );
743  }
744 
745  delete messageFromMaster_;
746  messageFromMaster_ = 0;
747  }
748 }
749 
750 Bool_t LauAbsFitModel::cacheFitData(const TString& dataFileName, const TString& dataTreeName)
751 {
752  // From the input data stream, store the variables into the
753  // internal tree inputFitData_ that can be used by the sub-classes
754  // in calculating their likelihood functions for the fit
755  delete inputFitData_;
756  inputFitData_ = new LauFitDataTree(dataFileName,dataTreeName);
757  Bool_t dataOK = inputFitData_->findBranches();
758 
759  if (!dataOK) {
760  delete inputFitData_; inputFitData_ = 0;
761  }
762 
763  return dataOK;
764 }
765 
767 {
768  Bool_t hasBranch = inputFitData_->haveBranch( sWeightBranchName_ );
769  if ( ! hasBranch ) {
770  std::cerr << "ERROR in LauAbsFitModel::cacheInputSWeights : Input data does not contain variable \"" << sWeightBranchName_ << "\".\n";
771  std::cerr << " : Turning off sFit!" << std::endl;
772  doSFit_ = kFALSE;
773  return;
774  }
775 
776  UInt_t nEvents = this->eventsPerExpt();
777  sWeights_.clear();
778  sWeights_.reserve( nEvents );
779 
780  for (UInt_t iEvt = 0; iEvt < nEvents; ++iEvt) {
781 
782  const LauFitData& dataValues = inputFitData_->getData(iEvt);
783 
784  LauFitData::const_iterator iter = dataValues.find( sWeightBranchName_ );
785 
786  sWeights_.push_back( iter->second * sWeightScaleFactor_ );
787  }
788 }
789 
791 {
792  // Routine to perform the actual fit for the given experiment
793 
794  // Reset the worst likelihood found to its catch-all value
795  worstLogLike_ = std::numeric_limits<Double_t>::max();
796 
797  // Update initial fit parameters if required (e.g. if using random numbers).
798  this->checkInitFitParams();
799 
800  // Initialise the fitter
804 
807 
808  // Now ready for minimisation step
809  std::cout << "\nINFO in LauAbsFitModel::fitExpt : Start minimisation...\n";
810  std::pair<Int_t,Double_t> fitResult = LauFitter::fitter()->minimise();
811 
812  fitStatus_ = fitResult.first;
813  NLL_ = fitResult.second;
814 
815  // If we're doing a two stage fit we can now release (i.e. float)
816  // the 2nd stage parameters and re-fit
817  if (this->twoStageFit()) {
818 
819  if ( fitStatus_ != 3 ) {
820  std::cerr << "ERROR in LauAbsFitModel:fitExpt : Not running second stage fit since first stage failed." << std::endl;
822  } else {
827  fitResult = LauFitter::fitter()->minimise();
828  }
829  }
830 
831  fitStatus_ = fitResult.first;
832  NLL_ = fitResult.second;
833  const TMatrixD& covMat = LauFitter::fitter()->covarianceMatrix();
834  covMatrix_.Clear();
835  covMatrix_.ResizeTo( covMat.GetNrows(), covMat.GetNcols() );
836  covMatrix_.SetMatrixArray( covMat.GetMatrixArray() );
837 
838  // Store the final fit results and errors into protected internal vectors that
839  // all sub-classes can use within their own finalFitResults implementation
840  // used below (e.g. putting them into an ntuple in a root file)
843 }
844 
846 {
847  // Write out histograms at end
848  if (fitNtuple_ != 0) {
850  }
851 }
852 
854 {
855  if (sPlotNtuple_ != 0) {
858  LauSPlot splot(sPlotNtuple_->fileName(), sPlotNtuple_->treeName(), this->firstExpt(), this->nExpt(),
859  this->variableNames(), this->freeSpeciesNames(), this->fixdSpeciesNames(), this->twodimPDFs(),
860  this->splitSignal(), this->scfDPSmear());
862  splot.writeOutResults();
863  }
864 }
865 
866 void LauAbsFitModel::compareFitData(UInt_t toyMCScale, const TString& mcFileName, const TString& tableFileName, Bool_t poissonSmearing)
867 {
868  compareFitData_ = kTRUE;
869  fitToyMCScale_ = toyMCScale;
870  fitToyMCFileName_ = mcFileName;
871  fitToyMCTableName_ = tableFileName;
872  fitToyMCPoissonSmear_ = poissonSmearing;
873 }
874 
875 void LauAbsFitModel::createFitToyMC(const TString& mcFileName, const TString& tableFileName)
876 {
877  // Create a toy MC sample so that the user can eventually
878  // compare the "fitted" result with the data
879  // Generate more toy MC to reduce statistical fluctuations. Use the
880  // rescaling value fitToyMCScale_.
881 
882  // Store the info on the number of experiments, first expt and current expt
883  UInt_t oldNExpt(this->nExpt());
884  UInt_t oldFirstExpt(this->firstExpt());
885  UInt_t oldIExpt(iExpt_);
886 
887  // Turn off Poisson smearing if required
888  Bool_t poissonSmearing(this->doPoissonSmearing());
890 
891  // Turn off embedding, since we need toy MC, not reco'ed events
892  Bool_t enableEmbeddingOrig(this->enableEmbedding());
893  this->enableEmbedding(kFALSE);
894 
895  // Need to make sure that the generation of the DP co-ordinates is
896  // switched on if any of our PDFs depend on it
897  Bool_t origUseDP = this->useDP();
898  if ( this->pdfsDependOnDP() && !origUseDP ) {
899  this->useDP( kTRUE );
900  this->initialiseDPModels();
901  }
902 
903  // Generate the toy MC
904  std::cout << "INFO in LauAbsFitModel::createFitToyMC : Generating toy MC in " << mcFileName << " to compare fit with data..." << std::endl;
905  std::cout << " : Number of experiments to generate = " << this->nExpt() << ", which is a factor of " <<fitToyMCScale_ << " higher than that originally specified." << std::endl;
906  std::cout <<" : This is to allow the toy MC to be made with reduced statistical fluctuations." << std::endl;
907 
908  // Set the genValue of each parameter to its current (fitted) value
909  // but first store the original genValues for restoring later
910  std::vector<Double_t> origGenValues; origGenValues.reserve(nParams_);
911  for (LauParameterPList::iterator iter = fitVars_.begin(); iter != fitVars_.end(); ++iter) {
912  origGenValues.push_back((*iter)->genValue());
913  (*iter)->genValue((*iter)->value());
914  }
915 
916  // If we're asked to generate more than 100 experiments then split it
917  // up into multiple files since otherwise can run into memory issues
918  // when building the index
919 
920  UInt_t totalExpts = oldNExpt * fitToyMCScale_;
921  if ( totalExpts > 100 ) {
922  UInt_t nFiles = totalExpts/100;
923  if ( totalExpts%100 ) {
924  nFiles += 1;
925  }
926  for ( UInt_t iFile(0); iFile < nFiles; ++iFile ) {
927 
928  UInt_t firstExp( iFile*100 );
929 
930  // Set number of experiments and first experiment to generate
931  UInt_t nExp = ((firstExp + 100)>totalExpts) ? totalExpts-firstExp : 100;
932  this->setNExpts(nExp, firstExp);
933 
934  // Create a unique filename and generate the events
935  TString extraname = "_file";
936  extraname += iFile;
937  TString filename(mcFileName);
938  filename.Insert( filename.Index("."), extraname );
939  this->generate(filename, "genResults", "dummy.root", tableFileName);
940  }
941  } else {
942  // Set number of experiments to new value
943  this->setNExpts(oldNExpt*fitToyMCScale_, 0);
944  // Generate the toy
945  this->generate(mcFileName, "genResults", "dummy.root", tableFileName);
946  }
947 
948  // Reset number of experiments to original value
949  iExpt_ = oldIExpt;
950  this->setNExpts(oldNExpt, oldFirstExpt);
951 
952  // Restore the Poisson smearing to its former value
953  this->doPoissonSmearing(poissonSmearing);
954 
955  // Restore the embedding status
956  this->enableEmbedding(enableEmbeddingOrig);
957 
958  // Restore "useDP" to its former status
959  this->useDP( origUseDP );
960 
961  // Restore the original genValue to each parameter
962  for (UInt_t i(0); i<nParams_; ++i) {
963  fitVars_[i]->genValue(origGenValues[i]);
964  }
965 
966  std::cout << "INFO in LauAbsFitModel::createFitToyMC : Finished in createFitToyMC." << std::endl;
967 }
968 
970 {
971  // Calculate the total negative log-likelihood over all events.
972  // This function assumes that the fit parameters and data tree have
973  // already been set-up correctly.
974 
975  // Loop over the data points to calculate the log likelihood
976  Double_t logLike = this->getLogLikelihood( 0, this->eventsPerExpt() );
977 
978  // Include the Poisson term in the extended likelihood if required
979  if (this->doEMLFit()) {
980  logLike -= this->getEventSum();
981  }
982 
983  // Calculate any penalty terms from Gaussian constrained variables
984  if ( ! conVars_.empty() ){
985  logLike -= this->getLogLikelihoodPenalty();
986  }
987 
988  Double_t totNegLogLike = -logLike;
989  return totNegLogLike;
990 }
991 
993 {
994  Double_t penalty(0.0);
995 
996  for ( LauParameterPList::const_iterator iter = conVars_.begin(); iter != conVars_.end(); ++iter ) {
997  Double_t val = (*iter)->value();
998  Double_t mean = (*iter)->constraintMean();
999  Double_t width = (*iter)->constraintWidth();
1000 
1001  Double_t term = ( val - mean ) / width;
1002  penalty += term*term;
1003  }
1004 
1005  return penalty;
1006 }
1007 
1008 Double_t LauAbsFitModel::getLogLikelihood( UInt_t iStart, UInt_t iEnd )
1009 {
1010  // Calculate the total negative log-likelihood over all events.
1011  // This function assumes that the fit parameters and data tree have
1012  // already been set-up correctly.
1013 
1014  // Loop over the data points to calculate the log likelihood
1015  Double_t logLike(0.0);
1016 
1017  // Loop over the number of events in this experiment
1018  Bool_t ok(kTRUE);
1019  for (UInt_t iEvt = iStart; iEvt < iEnd; ++iEvt) {
1020 
1021  Double_t likelihood = this->getTotEvtLikelihood(iEvt);
1022 
1023  if (likelihood > DBL_MIN) { // Is the likelihood zero?
1024  Double_t evtLogLike = TMath::Log(likelihood);
1025  if ( doSFit_ ) {
1026  evtLogLike *= sWeights_[iEvt];
1027  }
1028  logLike += evtLogLike;
1029  } else {
1030  ok = kFALSE;
1031  std::cerr << "WARNING in LauAbsFitModel::getLogLikelihood : Strange likelihood value for event " << iEvt << ": " << likelihood << "\n";
1032  this->printEventInfo(iEvt);
1033  this->printVarsInfo(); //Write the values of the floated variables for which the likelihood is zero
1034  break;
1035  }
1036  }
1037 
1038  if (!ok) {
1039  std::cerr << " : Returning worst NLL found so far to force MINUIT out of this region." << std::endl;
1040  logLike = worstLogLike_;
1041  } else if (logLike < worstLogLike_) {
1042  worstLogLike_ = logLike;
1043  }
1044 
1045  return logLike;
1046 }
1047 
1048 void LauAbsFitModel::setParsFromMinuit(Double_t* par, Int_t npar)
1049 {
1050  // This function sets the internal parameters based on the values
1051  // that Minuit is using when trying to minimise the total likelihood function.
1052 
1053  // MINOS reports different numbers of free parameters depending on the
1054  // situation, so disable this check
1055  if ( ! withinAsymErrorCalc_ ) {
1056  if (static_cast<UInt_t>(npar) != nFreeParams_) {
1057  std::cerr << "ERROR in LauAbsFitModel::setParsFromMinuit : Unexpected number of free parameters: " << npar << ".\n";
1058  std::cerr << " Expected: " << nFreeParams_ << ".\n" << std::endl;
1059  gSystem->Exit(EXIT_FAILURE);
1060  }
1061  }
1062 
1063  // Despite npar being the number of free parameters
1064  // the par array actually contains all the parameters,
1065  // free and floating...
1066  // Update all the floating ones with their new values.
1067  for (UInt_t i(0); i<nParams_; ++i) {
1068  if (!fitVars_[i]->fixed()) {
1069  fitVars_[i]->value(par[i]);
1070  }
1071  }
1072 
1073  this->propagateParUpdates();
1074 }
1075 
1077 {
1078  UInt_t nParsAdded(0);
1079  for (LauPdfList::iterator pdf_iter = pdfList.begin(); pdf_iter != pdfList.end(); ++pdf_iter) {
1080  LauAbsPdf* pdf = (*pdf_iter);
1081  if ( pdf->isDPDependent() ) {
1082  this->pdfsDependOnDP( kTRUE );
1083  }
1084  LauParameterPList& pars = pdf->getParameters();
1085  for (LauParameterPList::iterator pars_iter = pars.begin(); pars_iter != pars.end(); ++pars_iter) {
1086  if ( !(*pars_iter)->clone() && ( !(*pars_iter)->fixed() ||
1087  (this->twoStageFit() && ( (*pars_iter)->secondStage() || (*pars_iter)->firstStage())) ) ) {
1088  fitVars_.push_back(*pars_iter);
1089  ++nParsAdded;
1090  }
1091  }
1092  }
1093  return nParsAdded;
1094 }
1095 
1097 {
1098  for ( LauParameterPList::const_iterator iter = fitVars_.begin(); iter != fitVars_.end(); ++iter ) {
1099  if ( (*iter)->gaussConstraint() ) {
1100  conVars_.push_back( *iter );
1101  std::cout << "INFO in LauAbsFitModel::addConParameters: Added Gaussian constraint to parameter "<< (*iter)->name() << std::endl;
1102  }
1103  }
1104 
1105 }
1106 
1108 {
1109  for (LauPdfList::iterator pdf_iter = pdfList.begin(); pdf_iter != pdfList.end(); ++pdf_iter) {
1110  (*pdf_iter)->updatePulls();
1111  }
1112 }
1113 
1114 void LauAbsFitModel::printFitParameters(const LauPdfList& pdfList, std::ostream& fout) const
1115 {
1116  LauPrint print;
1117  for (LauPdfList::const_iterator pdf_iter = pdfList.begin(); pdf_iter != pdfList.end(); ++pdf_iter) {
1118  const LauParameterPList& pars = (*pdf_iter)->getParameters();
1119  for (LauParameterPList::const_iterator pars_iter = pars.begin(); pars_iter != pars.end(); ++pars_iter) {
1120  if (!(*pars_iter)->clone()) {
1121  fout << (*pars_iter)->name() << " & $";
1122  print.printFormat(fout, (*pars_iter)->value());
1123  if ((*pars_iter)->fixed() == kTRUE) {
1124  fout << "$ (fixed) \\\\";
1125  } else {
1126  fout << " \\pm ";
1127  print.printFormat(fout, (*pars_iter)->error());
1128  fout << "$ \\\\" << std::endl;
1129  }
1130  }
1131  }
1132  }
1133 }
1134 
1136 {
1137  for (LauPdfList::iterator pdf_iter = pdfList.begin(); pdf_iter != pdfList.end(); ++pdf_iter) {
1138  (*pdf_iter)->cacheInfo(theData);
1139  }
1140 }
1141 
1142 Double_t LauAbsFitModel::prodPdfValue(LauPdfList& pdfList, UInt_t iEvt)
1143 {
1144  Double_t pdfVal = 1.0;
1145  for (LauPdfList::iterator pdf_iter = pdfList.begin(); pdf_iter != pdfList.end(); ++pdf_iter) {
1146  (*pdf_iter)->calcLikelihoodInfo(iEvt);
1147  pdfVal *= (*pdf_iter)->getLikelihood();
1148  }
1149  return pdfVal;
1150 }
1151 
1152 void LauAbsFitModel::printEventInfo(UInt_t iEvt) const
1153 {
1154  const LauFitData& data = inputFitData_->getData(iEvt);
1155  std::cerr << " : Input data values for this event:" << std::endl;
1156  for (LauFitData::const_iterator iter = data.begin(); iter != data.end(); ++iter) {
1157  std::cerr << " " << iter->first << " = " << iter->second << std::endl;
1158  }
1159 }
1160 
1162 {
1163  std::cerr << " : Current values of fit parameters:" << std::endl;
1164  for (UInt_t i(0); i<nParams_; ++i) {
1165  std::cerr << " " << (fitVars_[i]->name()).Data() << " = " << fitVars_[i]->value() << std::endl;
1166  }
1167 }
1168 
Class for defining the SPlot technique.
Definition: LauSPlot.hh:55
TString fitToyMCTableName_
The output table name for Toy MC.
virtual void addSPlotNtupleIntegerBranch(const TString &name)
Add a branch to the sPlot tree for storing an integer.
Bool_t findBranches()
Find all of the branches in the tree.
virtual Bool_t twoStageFit() const
Determine whether the two-stage fit is enabled.
virtual Bool_t genExpt()=0
The method that actually generates the toy MC events for the given experiment.
void createFitToyMC(const TString &mcFileName, const TString &tableFileName)
Create a toy MC sample from the fitted parameters.
UInt_t firstExpt() const
Obtain the number of the first experiment.
File containing declaration of LauFitDataTree class.
virtual Double_t getEventSum() const =0
Returns the sum of the expected events over all hypotheses; used in the EML fit scenario.
Bool_t fixed() const
Check whether the parameter is fixed or floated.
virtual void updateParameters()=0
Update the values and errors of the parameters based on the fit minimum.
UInt_t eventsPerExpt() const
Obtain the total number of events in the current experiment.
void setGenValues()
Make sure all parameters hold their genValue as the current value.
TString sPlotFileName_
The name of the sPlot file.
Double_t * parValues_
Parameter values array (for reading from the master)
virtual void writeOutTable(const TString &outputFile)=0
Write the latex table.
Bool_t writeLatexTable() const
Determine whether writing out of the latex table is enabled.
Bool_t doSFit_
Option to perfom the sFit.
Bool_t writeSPlotData() const
Determine whether the sPlot data is to be written out.
TStopwatch timer_
The fit timer.
UInt_t nParams_
The number of fit parameters.
File containing declaration of LauParamFixed class.
Double_t getTotNegLogLikelihood()
Calculates the total negative log-likelihood.
Bool_t storeDPEff_
Option to store DP efficiencies in the sPlot ntuple.
void cacheInfo(LauPdfList &pdfList, const LauFitDataTree &theData)
Have all PDFs in the list cache the data.
void runCalculations(const TString &option="q")
Method to calculate the sWeights and cN coeffs.
Definition: LauSPlot.cc:626
virtual void setGenNtupleIntegerBranchValue(const TString &name, Int_t value)
Set the value of an integer branch in the gen tree.
virtual void setupBkgndVectors()=0
Method to set up the storage for background-related quantities called by setBkgndClassNames.
LauGenNtuple * genNtuple_
The generated ntuple.
File containing declaration of LauAbsFitModel class.
Bool_t withinAsymErrorCalc_
Flag to indicate if the asymmetric error calculation (e.g. MINOS) is currently running.
Bool_t useAsymmFitErrors() const
Determine whether calculation of asymmetric errors is enabled.
const TString & name() const
The parameter name.
virtual void setupGenNtupleBranches()=0
Setup the generation ntuple branches.
UInt_t addFitParameters(LauPdfList &pdfList)
Add parameters of the PDFs in the list to the list of all fit parameters.
virtual void generate(const TString &dataFileName, const TString &dataTreeName, const TString &histFileName, const TString &tableFileNameBase)
Generate toy MC.
virtual void setBkgndClassNames(const std::vector< TString > &names)
Setup the background class names.
Bool_t useDP() const
Is the Dalitz plot term in the likelihood.
Int_t buildIndex(const TString &majorName, const TString &minorName="0")
Create an index table using leaves of the tree.
void compareFitData(UInt_t toyMCScale=10, const TString &mcFileName="fitToyMC.root", const TString &tableFileName="fitToyMCTable.tex", Bool_t poissonSmearing=kTRUE)
Specify that a toy MC sample should be created for a successful fit to an experiment.
const TString & treeName() const
Ntuple tree name.
Definition: LauGenNtuple.hh:56
Int_t getIntegerBranchValue(const TString &name) const
Get value of an integer branch.
virtual void cacheInputSWeights()
Cache the value of the sWeights to be used in the sFit.
virtual Bool_t twoStageFit() const =0
Determine whether the two-stage fit is enabled.
virtual void setGenNtupleDoubleBranchValue(const TString &name, Double_t value)
Set the value of a double branch in the gen tree.
void deleteAndRecreateTree()
Delete and recreate tree.
File containing declaration of LauAbsFitter class.
TSocket * sMaster_
A socket to enable parallel setup.
virtual const std::vector< LauParameter * > & getParameters() const
Retrieve the parameters of the PDF, e.g. so that they can be loaded into a fit.
Definition: LauAbsPdf.hh:321
void addFriendTree(const TString &rootFileName, const TString &rootTreeName)
Add a friend tree.
virtual void storePerEvtLlhds()=0
Store the per-event likelihood values.
virtual void printEventInfo(UInt_t iEvt) const
Prints the values of all the fit variables for the specified event - useful for diagnostics.
Bool_t pdfsDependOnDP() const
Do any of the PDFs have a dependence on the DP?
virtual ~LauAbsFitModel()
Destructor.
Bool_t compareFitData_
Option to make toy from 1st successful experiment.
File containing declaration of LauPrint class.
Double_t prodPdfValue(LauPdfList &pdfList, UInt_t iEvt)
Calculate the product of the per-event likelihoods of the PDFs in the list.
Double_t getDoubleBranchValue(const TString &name) const
Get value of a double branch.
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.
virtual Int_t getGenNtupleIntegerBranchValue(const TString &name) const
Get the value of an integer branch in the gen tree.
UInt_t nSlaves_
The total number of slaves.
virtual LauSPlot::NumbMap fixdSpeciesNames() const =0
Returns the names and yields of species that are fixed in the fit.
LauBkgndClassMap bkgndClassNames_
The background class names.
TMessage * messageFromMaster_
Message from master to the slaves.
Class to define various output print commands.
Definition: LauPrint.hh:29
virtual void setupSPlotNtupleBranches()=0
Setup the branches of the sPlot tuple.
virtual void fillGenNtupleBranches()
Fill the gen tuple branches.
void fitSlave(const TString &dataFileName, const TString &dataTreeName, const TString &histFileName, const TString &tableFileNameBase)
Slaves required when performing a simultaneous fit.
virtual void setSPlotNtupleDoubleBranchValue(const TString &name, Double_t value)
Set the value of a double branch in the sPlot tree.
void printFitParameters(const LauPdfList &pdfList, std::ostream &fout) const
Print the fit parameters for all PDFs in the list.
virtual void initialise(LauFitObject *fitObj, const std::vector< LauParameter * > &parameters)=0
Initialise the fitter, setting the information on the parameters.
void readExperimentData(UInt_t iExpt)
Read events only for the given experiment.
virtual std::pair< Int_t, Double_t > minimise()=0
Perform the minimisation of the fit function.
UInt_t slaveId_
Slave id number.
virtual Double_t getTotEvtLikelihood(UInt_t iEvt)=0
Calculates the likelihood for a given event.
TStopwatch cumulTimer_
The total fit timer.
File containing LauFitter namespace.
virtual void propagateParUpdates()=0
This function (specific to each model) calculates anything that depends on the fit parameter values...
void addConParameters()
Add parameters to the list of Gaussian constrained parameters.
LauFitDataTree * inputFitData_
The input data.
Bool_t doSFit() const
Return the flag to store the status of using an sFit or not.
void run(const TString &applicationCode, const TString &dataFileName, const TString &dataTreeName, const TString &histFileName, const TString &tableFileName="")
Start the toy generation / fitting.
std::vector< LauParameter * > LauParameterPList
List of parameter pointers.
const TString & treeName() const
Retrieve the tree name.
LauParameterList extraVars_
Extra variables that aren&#39;t in the fit but are stored in the ntuple.
TMatrixD covMatrix_
The fit covariance matrix.
void writeOutFitResults()
Write out fit results.
void addIntegerBranch(const TString &name)
Add integer branch to tree.
Definition: LauGenNtuple.cc:73
const TString & fileName() const
Ntuple file name.
Definition: LauGenNtuple.hh:50
Abstract interface to the fitting and toy MC model.
UInt_t numberBadFits_
The number of bad fits.
virtual void addGenNtupleIntegerBranch(const TString &name)
Add a branch to the gen tree for storing an integer.
UInt_t nExpt() const
Obtain the number of experiments.
File containing declaration of LauParameter class.
Bool_t doPoissonSmearing() const
Determine whether Poisson smearing is enabled for the toy MC generation.
virtual Double_t getGenNtupleDoubleBranchValue(const TString &name) const
Get the value of a double branch in the gen tree.
void setNExpts(UInt_t nExperiments, UInt_t firstExperiment=0)
Set the number of experiments and the first experiment.
virtual void weightEvents(const TString &dataFileName, const TString &dataTreeName)=0
Reweighting - allows e.g. MC events to be weighted by the DP model.
Bool_t doEMLFit() const
Determine whether an extended maximum likelihood fit it being performed.
virtual void fixFirstStageParameters()=0
Fix parameters marked as &quot;first stage&quot;.
File containing declaration of LauComplex class.
UInt_t numberOKFits_
The number of good fits.
const TString & fileName() const
Retrieve the file name.
virtual Bool_t isDPDependent() const
Specifies whether or not the PDF is DP dependent.
Definition: LauAbsPdf.hh:110
virtual UInt_t nParameters() const =0
Get the total number of fit parameters.
virtual LauSPlot::NumbMap freeSpeciesNames() const =0
Returns the names and yields of species that are free in the fit.
Class to store the results from the toy MC generation into an ntuple.
Definition: LauGenNtuple.hh:32
File containing declaration of LauSPlot class.
virtual Bool_t splitSignal() const =0
Check if the signal is split into well-reconstructed and mis-reconstructed types. ...
Double_t worstLogLike_
The worst LL value found so far.
virtual void releaseSecondStageParameters()=0
Release parameters marked as &quot;second stage&quot;.
TString sPlotTreeName_
The name of the sPlot tree.
virtual void initialiseDPModels()=0
Initialise the DP models.
LauGenNtuple * sPlotNtuple_
The sPlot ntuple.
TString sPlotVerbosity_
Control the verbosity of the sFit.
const TString nullString_
An empty string.
void clearFitParVectors()
Clear the vectors containing fit parameters.
Class for defining the fit parameter objects.
Definition: LauParameter.hh:32
virtual void addSPlotNtupleDoubleBranch(const TString &name)
Add a branch to the sPlot tree for storing a double.
void clearExtraVarVectors()
Clear the vectors containing extra ntuple variables.
virtual void cacheInputFitVars()=0
Cache the input data values to calculate the likelihood during the fit.
void fitExpt()
Routine to perform the actual fit for a given experiment.
Double_t sWeightScaleFactor_
The sWeight scaling factor.
File containing declaration of LauAbsPdf class.
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.
virtual void writeOutAllFitResults()
Write out any fit results.
virtual void finaliseFitResults(const TString &tableFileName)=0
Write the results of the fit into the ntuple.
UInt_t firstExpt_
The number of the first experiment to consider.
static LauAbsFitter * fitter()
Method that provides access to the singleton fitter.
Definition: LauFitter.cc:34
void setIntegerBranchValue(const TString &name, Int_t value)
Set value of an integer branch.
Definition: LauGenNtuple.cc:91
virtual void checkInitFitParams()=0
Update initial fit parameters if required.
virtual void printVarsInfo() const
Same as printEventInfo, but printing out the values of the variables in the fit.
Bool_t writeSPlotData_
Option to write sPlot data.
Bool_t validBkgndClass(const TString &className) const
Check if the given background class is in the list.
Bool_t fitToyMCPoissonSmear_
Option to perform Poisson smearing.
TString sWeightBranchName_
The name of the sWeight branch.
virtual UInt_t nFreeParameters() const =0
Get the number of floating fit parameters.
UInt_t iExpt_
The number of the current experiment.
LauParameterPList fitVars_
Internal vectors of fit parameters.
virtual Bool_t scfDPSmear() const =0
Check if the mis-reconstructed signal is to be smeared in the DP.
Bool_t cacheFitData(const TString &dataFileName, const TString &dataTreeName)
Store variables from the input file into the internal data storage.
void fit(const TString &dataFileName, const TString &dataTreeName, const TString &histFileName, const TString &tableFileNameBase)
Perform the total fit.
virtual void setSPlotNtupleIntegerBranchValue(const TString &name, Int_t value)
Set the value of an integer branch in the sPlot tree.
UInt_t fitToyMCScale_
The scaling factor (toy vs data statistics)
virtual void fillSPlotNtupleBranches()
Fill the sPlot tuple.
TString fitToyMCFileName_
The output file name for Toy MC.
void writeOutGenResults()
Write out the results from the generation.
void printFormat(std::ostream &stream, Double_t value) const
Method to choose the printing format to a specified level of precision.
Definition: LauPrint.cc:32
void runSlave(const TString &dataFileName, const TString &dataTreeName, const TString &histFileName, const TString &tableFileName="", const TString &addressMaster="localhost", const UInt_t portMaster=9090)
Start the slave process for simultaneous fitting.
virtual LauSPlot::TwoDMap twodimPDFs() const =0
Returns the species and variables for all 2D PDFs in the fit.
Double_t getLogLikelihoodPenalty()
Calculate the penalty terms to the log likelihood from Gaussian constraints.
Bool_t haveBranch(const TString &name) const
Check if the named branch is stored.
const TString & bkgndClassName(UInt_t classID) const
Get the name of a background class from the number.
virtual Bool_t useAsymmFitErrors() const =0
Determine whether calculation of asymmetric errors is enabled.
Bool_t enableEmbedding() const
Determine whether embedding of events is enabled in the generation.
Double_t NLL_
The negative log-likelihood.
Class for defining the abstract interface for PDF classes.
Definition: LauAbsPdf.hh:40
Double_t getLogLikelihood(UInt_t iStart, UInt_t iEnd)
Calculate the sum of the log-likelihood over the specified events.
UInt_t nExpt_
The number of experiments to consider.
LauFitNtuple * fitNtuple_
The fit ntuple.
virtual LauSPlot::NameSet variableNames() const =0
Returns the names of all variables in the fit.
Double_t value() const
The value of the parameter.
UInt_t nEvents() const
Retrieve the number of events.
virtual void addGenNtupleDoubleBranch(const TString &name)
Add a branch to the gen tree for storing a double.
friend class LauFitNtuple
LauFitNtuple is a friend class.
void updateFitParameters(LauPdfList &pdfList)
Update the fit parameters for all PDFs in the list.
LauParameterPList conVars_
Internal vectors of Gaussian parameters.
void addDoubleBranch(const TString &name)
Add double branch to tree.
Definition: LauGenNtuple.cc:82
virtual void setParsFromMinuit(Double_t *par, Int_t npar)
This function sets the parameter values from Minuit.
virtual void releaseFirstStageParameters()=0
Release parameters marked as &quot;first stage&quot;.
Int_t fitStatus_
The status of the fit.
virtual void initialise()=0
Initialise the fit par vectors.
Class to store the input fit variables.
File containing declaration of LauFitNtuple class.
virtual const TMatrixD & covarianceMatrix() const =0
Retrieve the fit covariance matrix.
virtual void calculateSPlotData()
Calculate the sPlot data.
File containing declaration of LauGenNtuple class.
void setDoubleBranchValue(const TString &name, Double_t value)
Set value of a double branch.
Definition: LauGenNtuple.cc:96
std::vector< Double_t > sWeights_
The vector of sWeights.
UInt_t nFreeParams_
The number of free fit parameters.