laura is hosted by Hepforge, IPPP Durham
Laura++  3.6.0
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauAbsFitModel.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 "LauAbsFitModel.hh"
30 
31 #include "LauAbsFitter.hh"
32 #include "LauAbsPdf.hh"
33 #include "LauComplex.hh"
34 #include "LauFitDataTree.hh"
35 #include "LauFitter.hh"
36 #include "LauGenNtuple.hh"
37 #include "LauParamFixed.hh"
38 #include "LauParameter.hh"
39 #include "LauPrint.hh"
40 #include "LauSPlot.hh"
41 
42 #include "TMessage.h"
43 #include "TMonitor.h"
44 #include "TSystem.h"
45 #include "TVirtualFitter.h"
46 
47 #include <iostream>
48 #include <limits>
49 #include <vector>
50 
52  fixParams_( kFALSE ),
53  compareFitData_( kFALSE ),
54  savePDF_( kFALSE ),
55  writeLatexTable_( kFALSE ),
56  writeSPlotData_( kFALSE ),
57  storeDPEff_( kFALSE ),
58  randomFit_( kFALSE ),
59  emlFit_( kFALSE ),
60  poissonSmear_( kFALSE ),
61  enableEmbedding_( kFALSE ),
62  usingDP_( kTRUE ),
63  pdfsDependOnDP_( kFALSE ),
64  inputFitData_( 0 ),
65  genNtuple_( 0 ),
66  sPlotNtuple_( 0 ),
67  nullString_( "" ),
68  doSFit_( kFALSE ),
69  sWeightBranchName_( "" ),
70  sWeightScaleFactor_( 1.0 ),
71  outputTableName_( "" ),
72  fitToyMCFileName_( "fitToyMC.root" ),
73  fitToyMCTableName_( "fitToyMCTable" ),
74  fitToyMCScale_( 10 ),
75  fitToyMCPoissonSmear_( kFALSE ),
76  sPlotFileName_( "" ),
77  sPlotTreeName_( "" ),
78  sPlotVerbosity_( "" )
79 {
80 }
81 
83 {
84  delete inputFitData_;
85  inputFitData_ = 0;
86  delete genNtuple_;
87  genNtuple_ = 0;
88  delete sPlotNtuple_;
89  sPlotNtuple_ = 0;
90 }
91 
92 void LauAbsFitModel::run( const TString& applicationCode,
93  const TString& dataFileName,
94  const TString& dataTreeName,
95  const TString& histFileName,
96  const TString& tableFileName )
97 {
98  // Chose whether you want to generate or fit events in the Dalitz plot.
99  // To generate events choose applicationCode = "gen", to fit events choose
100  // applicationCode = "fit".
101 
102  TString runCode( applicationCode );
103  runCode.ToLower();
104 
105  TString histFileNameCopy( histFileName );
106  TString tableFileNameCopy( tableFileName );
107  TString dataFileNameCopy( dataFileName );
108  TString dataTreeNameCopy( dataTreeName );
109 
110  // Initialise the fit par vectors. Each class that inherits from this one
111  // must implement this sensibly for all vectors specified in clearFitParVectors,
112  // i.e. specify parameter names, initial, min, max and fixed values
113  this->initialise();
114 
115  // Add variables to Gaussian constrain to a list
116  this->addConParameters();
117 
118  if ( dataFileNameCopy == "" ) {
119  dataFileNameCopy = "data.root";
120  }
121  if ( dataTreeNameCopy == "" ) {
122  dataTreeNameCopy = "genResults";
123  }
124 
125  if ( runCode.Contains( "gen" ) ) {
126 
127  if ( histFileNameCopy == "" ) {
128  histFileNameCopy = "parInfo.root";
129  }
130  if ( tableFileNameCopy == "" ) {
131  tableFileNameCopy = "genResults";
132  }
133 
134  this->setGenValues();
135  this->generate( dataFileNameCopy, dataTreeNameCopy, histFileNameCopy, tableFileNameCopy );
136 
137  } else if ( runCode.Contains( "fit" ) ) {
138 
139  if ( histFileNameCopy == "" ) {
140  histFileNameCopy = "parInfo.root";
141  }
142  if ( tableFileNameCopy == "" ) {
143  tableFileNameCopy = "fitResults";
144  }
145 
146  this->fit( dataFileNameCopy, dataTreeNameCopy, histFileNameCopy, tableFileNameCopy );
147 
148  } else if ( runCode.Contains( "plot" ) ) {
149 
150  this->savePDFPlots( "plot" );
151 
152  } else if ( runCode.Contains( "weight" ) ) {
153 
154  this->weightEvents( dataFileNameCopy, dataTreeNameCopy );
155  }
156 }
157 
158 void LauAbsFitModel::doSFit( const TString& sWeightBranchName, Double_t scaleFactor )
159 {
160  if ( sWeightBranchName == "" ) {
161  std::cerr << "WARNING in LauAbsFitModel::doSFit : sWeight branch name is empty string, not setting-up sFit."
162  << std::endl;
163  return;
164  }
165 
166  doSFit_ = kTRUE;
167  sWeightBranchName_ = sWeightBranchName;
168  sWeightScaleFactor_ = scaleFactor;
169 }
170 
171 void LauAbsFitModel::setBkgndClassNames( const std::vector<TString>& names )
172 {
173  if ( ! bkgndClassNames_.empty() ) {
174  std::cerr << "WARNING in LauAbsFitModel::setBkgndClassNames : Names already stored, not changing them."
175  << std::endl;
176  return;
177  }
178 
179  UInt_t nBkgnds = names.size();
180  for ( UInt_t i( 0 ); i < nBkgnds; ++i ) {
181  bkgndClassNames_.insert( std::make_pair( i, names[i] ) );
182  }
183 
184  this->setupBkgndVectors();
185 }
186 
187 Bool_t LauAbsFitModel::validBkgndClass( const TString& className ) const
188 {
189  if ( bkgndClassNames_.empty() ) {
190  return kFALSE;
191  }
192 
193  Bool_t found( kFALSE );
194  for ( LauBkgndClassMap::const_iterator iter = bkgndClassNames_.begin();
195  iter != bkgndClassNames_.end();
196  ++iter ) {
197  if ( iter->second == className ) {
198  found = kTRUE;
199  break;
200  }
201  }
202 
203  return found;
204 }
205 
206 UInt_t LauAbsFitModel::bkgndClassID( const TString& className ) const
207 {
208  if ( ! this->validBkgndClass( className ) ) {
209  std::cerr << "ERROR in LauAbsFitModel::bkgndClassID : Request for ID for invalid background class \""
210  << className << "\"." << std::endl;
211  return ( bkgndClassNames_.size() + 1 );
212  }
213 
214  UInt_t bgID( 0 );
215  for ( LauBkgndClassMap::const_iterator iter = bkgndClassNames_.begin();
216  iter != bkgndClassNames_.end();
217  ++iter ) {
218  if ( iter->second == className ) {
219  bgID = iter->first;
220  break;
221  }
222  }
223 
224  return bgID;
225 }
226 
227 const TString& LauAbsFitModel::bkgndClassName( UInt_t classID ) const
228 {
229  LauBkgndClassMap::const_iterator iter = bkgndClassNames_.find( classID );
230 
231  if ( iter == bkgndClassNames_.end() ) {
232  std::cerr << "ERROR in LauAbsFitModel::bkgndClassName : Request for name of invalid background class ID "
233  << classID << "." << std::endl;
234  return nullString_;
235  }
236 
237  return iter->second;
238 }
239 
241 {
242  std::cout << "INFO in LauAbsFitModel::clearFitParVectors : Clearing fit variable vectors"
243  << std::endl;
244 
245  conVars_.clear();
246  resVars_.clear();
247  fitVars_.clear();
248 }
249 
251 {
252  std::cout << "INFO in LauAbsFitModel::clearExtraVarVectors : Clearing extra ntuple variable vectors"
253  << std::endl;
254  extraVars_.clear();
255 }
256 
258 {
259  // makes sure each parameter holds its genValue as its current value
260  for ( LauParameterPList::iterator iter = fitVars_.begin(); iter != fitVars_.end(); ++iter ) {
261  ( *iter )->value( ( *iter )->genValue() );
262  }
263  this->propagateParUpdates();
264 }
265 
266 void LauAbsFitModel::writeSPlotData( const TString& fileName,
267  const TString& treeName,
268  Bool_t storeDPEfficiency,
269  const TString& verbosity )
270 {
271  if ( this->writeSPlotData() ) {
272  std::cerr << "ERROR in LauAbsFitModel::writeSPlotData : Already have an sPlot ntuple setup, not doing it again."
273  << std::endl;
274  return;
275  }
276  writeSPlotData_ = kTRUE;
277  sPlotFileName_ = fileName;
278  sPlotTreeName_ = treeName;
279  sPlotVerbosity_ = verbosity;
280  storeDPEff_ = storeDPEfficiency;
281 }
282 
283 // TODO : histFileName isn't used here at the moment but could be used for
284 // storing the values of the parameters used in the generation.
285 // These could then be read and used for setting the "true" values
286 // in a subsequent fit.
287 void LauAbsFitModel::generate( const TString& dataFileName,
288  const TString& dataTreeName,
289  const TString& /*histFileName*/,
290  const TString& tableFileNameBase )
291 {
292  // Create the ntuple for storing the results
293  std::cout << "INFO in LauAbsFitModel::generate : Creating generation ntuple." << std::endl;
294  if ( genNtuple_ != 0 ) {
295  delete genNtuple_;
296  genNtuple_ = 0;
297  }
298  genNtuple_ = new LauGenNtuple( dataFileName, dataTreeName );
299 
300  // add branches for storing the experiment number and the number of
301  // the event within the current experiment
302  this->addGenNtupleIntegerBranch( "iExpt" );
303  this->addGenNtupleIntegerBranch( "iEvtWithinExpt" );
304  this->setupGenNtupleBranches();
305 
306  // Start the cumulative timer
307  cumulTimer_.Start();
308 
309  const UInt_t firstExp = this->firstExpt();
310  const UInt_t nExp = this->nExpt();
311 
312  Bool_t genOK( kTRUE );
313  do {
314  // Loop over the number of experiments
315  for ( UInt_t iExp = firstExp; iExp < ( firstExp + nExp ); ++iExp ) {
316 
317  // Start the timer to see how long each experiment takes to generate
318  timer_.Start();
319 
320  // Store the experiment number in the ntuple
321  this->setGenNtupleIntegerBranchValue( "iExpt", iExp );
322 
323  // Do the generation for this experiment
324  std::cout << "INFO in LauAbsFitModel::generate : Generating experiment number " << iExp
325  << std::endl;
326  genOK = this->genExpt();
327 
328  // Stop the timer and see how long the program took so far
329  timer_.Stop();
330  timer_.Print();
331 
332  if ( ! genOK ) {
333  // delete and recreate an empty tree
335 
336  // then break out of the experiment loop
337  std::cerr << "WARNING in LauAbsFitModel::generate : Problem in toy MC generation. Starting again with updated parameters..."
338  << std::endl;
339  break;
340  }
341 
342  if ( this->writeLatexTable() ) {
343  TString tableFileName( tableFileNameBase );
344  tableFileName += "_";
345  tableFileName += iExp;
346  tableFileName += ".tex";
347  this->writeOutTable( tableFileName );
348  }
349 
350  } // Loop over number of experiments
351  } while ( ! genOK );
352 
353  // Print out total timing info.
354  cumulTimer_.Stop();
355  std::cout << "INFO in LauAbsFitModel::generate : Finished generating all experiments."
356  << std::endl;
357  std::cout << "INFO in LauAbsFitModel::generate : Cumulative timing:" << std::endl;
358  cumulTimer_.Print();
359 
360  // Build the event index
361  std::cout << "INFO in LauAbsFitModel::generate : Building experiment:event index." << std::endl;
362  // TODO - can test this return value?
363  //Int_t nIndexEntries =
364  genNtuple_->buildIndex( "iExpt", "iEvtWithinExpt" );
365 
366  // Write out toy MC ntuple
367  std::cout << "INFO in LauAbsFitModel::generate : Writing data to file " << dataFileName << "."
368  << std::endl;
370 }
371 
373 {
375 }
376 
378 {
380 }
381 
383 {
385 }
386 
388 {
390 }
391 
393 {
395 }
396 
397 Double_t LauAbsFitModel::getGenNtupleDoubleBranchValue( const TString& name ) const
398 {
400 }
401 
403 {
405 }
406 
408 {
410 }
411 
413 {
415 }
416 
418 {
420 }
421 
423 {
425 }
426 
428 {
430 }
431 
432 void LauAbsFitModel::fit( const TString& dataFileName,
433  const TString& dataTreeName,
434  const TString& histFileName,
435  const TString& tableFileNameBase )
436 {
437  // Routine to perform the total fit.
438 
439  const UInt_t firstExp = this->firstExpt();
440  const UInt_t nExp = this->nExpt();
441 
442  std::cout << "INFO in LauAbsFitModel::fit : First experiment = " << firstExp << std::endl;
443  std::cout << "INFO in LauAbsFitModel::fit : Number of experiments = " << nExp << std::endl;
444 
445  // Start the cumulative timer
446  cumulTimer_.Start();
447 
448  this->resetFitCounters();
449 
450  // Create and setup the fit results ntuple
451  this->setupResultsOutputs( histFileName, tableFileNameBase );
452 
453  // Create and setup the sPlot ntuple
454  if ( this->writeSPlotData() ) {
455  std::cout << "INFO in LauAbsFitModel::fit : Creating sPlot ntuple." << std::endl;
456  if ( sPlotNtuple_ != 0 ) {
457  delete sPlotNtuple_;
458  sPlotNtuple_ = 0;
459  }
461  this->setupSPlotNtupleBranches();
462  }
463 
464  // This reads in the given dataFile and creates an input
465  // fit data tree that stores them for all events and experiments.
466  Bool_t dataOK = this->verifyFitData( dataFileName, dataTreeName );
467  if ( ! dataOK ) {
468  std::cerr << "ERROR in LauAbsFitModel::fit : Problem caching the fit data." << std::endl;
469  gSystem->Exit( EXIT_FAILURE );
470  }
471 
472  // Loop over the number of experiments
473  for ( UInt_t iExp = firstExp; iExp < ( firstExp + nExp ); ++iExp ) {
474 
475  // Start the timer to see how long each fit takes
476  timer_.Start();
477 
478  this->setCurrentExperiment( iExp );
479 
480  UInt_t nEvents = this->readExperimentData();
481  if ( nEvents < 1 ) {
482  std::cerr << "WARNING in LauAbsFitModel::fit : Zero events in experiment " << iExp
483  << ", skipping..." << std::endl;
484  timer_.Stop();
485  continue;
486  }
487 
488  // Now the sub-classes must implement whatever they need to do
489  // to cache any more input fit data they need in order to
490  // calculate the likelihoods during the fit.
491  // They need to use the inputFitData_ tree as input. For example,
492  // inputFitData_ contains m13Sq and m23Sq. The appropriate fit model
493  // then caches the resonance dynamics for the signal model, as
494  // well as the background likelihood values in the Dalitz plot
495  this->cacheInputFitVars();
496  if ( this->doSFit() ) {
497  this->cacheInputSWeights();
498  }
499 
500  // If we're fitting toy experiments then re-generate the means of any constraints
502 
503  // Do the fit for this experiment
504  this->fitExpt();
505 
506  // Write the results into the ntuple
508 
509  // Stop the timer and see how long the program took so far
510  timer_.Stop();
511  timer_.Print();
512 
513  // Store the per-event likelihood values
514  if ( this->writeSPlotData() ) {
515  this->storePerEvtLlhds();
516  }
517 
518  // Create a toy MC sample using the fitted parameters so that
519  // the user can compare the fit to the data.
520  if ( compareFitData_ == kTRUE && this->statusCode() == 3 ) {
522  }
523 
524  } // Loop over number of experiments
525 
526  // Print out total timing info.
527  cumulTimer_.Stop();
528  std::cout << "INFO in LauAbsFitModel::fit : Cumulative timing:" << std::endl;
529  cumulTimer_.Print();
530 
531  // Print out stats on OK fits.
532  const UInt_t nOKFits = this->numberOKFits();
533  const UInt_t nBadFits = this->numberBadFits();
534  std::cout << "INFO in LauAbsFitModel::fit : Number of OK Fits = " << nOKFits << std::endl;
535  std::cout << "INFO in LauAbsFitModel::fit : Number of Failed Fits = " << nBadFits << std::endl;
536  Double_t fitEff( 0.0 );
537  if ( nExp != 0 ) {
538  fitEff = nOKFits / ( 1.0 * nExp );
539  }
540  std::cout << "INFO in LauAbsFitModel::fit : Fit efficiency = " << fitEff * 100.0 << "%."
541  << std::endl;
542 
543  // Write out any fit results (ntuples etc...).
544  this->writeOutAllFitResults();
545  if ( this->writeSPlotData() ) {
546  this->calculateSPlotData();
547  }
548 }
549 
550 void LauAbsFitModel::setupResultsOutputs( const TString& histFileName, const TString& tableFileName )
551 {
552  this->LauSimFitTask::setupResultsOutputs( histFileName, tableFileName );
553 
554  outputTableName_ = tableFileName;
555 }
556 
557 Bool_t LauAbsFitModel::verifyFitData( const TString& dataFileName, const TString& dataTreeName )
558 {
559  // From the input data stream, store the variables into the
560  // internal tree inputFitData_ that can be used by the sub-classes
561  // in calculating their likelihood functions for the fit
562  delete inputFitData_;
563  inputFitData_ = new LauFitDataTree( dataFileName, dataTreeName );
564  Bool_t dataOK = inputFitData_->findBranches();
565 
566  if ( ! dataOK ) {
567  delete inputFitData_;
568  inputFitData_ = 0;
569  }
570 
571  return dataOK;
572 }
573 
575 {
576  Bool_t hasBranch = inputFitData_->haveBranch( sWeightBranchName_ );
577  if ( ! hasBranch ) {
578  std::cerr << "ERROR in LauAbsFitModel::cacheInputSWeights : Input data does not contain variable \""
579  << sWeightBranchName_ << "\".\n";
580  std::cerr << " : Turning off sFit!" << std::endl;
581  doSFit_ = kFALSE;
582  return;
583  }
584 
585  UInt_t nEvents = this->eventsPerExpt();
586  sWeights_.clear();
587  sWeights_.reserve( nEvents );
588 
589  for ( UInt_t iEvt = 0; iEvt < nEvents; ++iEvt ) {
590 
591  const LauFitData& dataValues = inputFitData_->getData( iEvt );
592 
593  LauFitData::const_iterator iter = dataValues.find( sWeightBranchName_ );
594 
595  sWeights_.push_back( iter->second * sWeightScaleFactor_ );
596  }
597 }
598 
600 {
601  // Routine to perform the actual fit for the given experiment
602 
603  // Update initial fit parameters if required (e.g. if using random numbers).
604  this->checkInitFitParams();
605 
606  // Initialise the fitter
610 
611  this->startNewFit( LauFitter::fitter().nParameters(), LauFitter::fitter().nFreeParameters() );
612 
613  // Now ready for minimisation step
614  std::cout << "\nINFO in LauAbsFitModel::fitExpt : Start minimisation...\n";
616 
617  // If we're doing a two stage fit we can now release (i.e. float)
618  // the 2nd stage parameters and re-fit
619  if ( this->twoStageFit() ) {
620  if ( fitResult.status != 3 ) {
621  std::cerr << "WARNING in LauAbsFitModel:fitExpt : Not running second stage fit since first stage failed."
622  << std::endl;
624  } else {
626  this->startNewFit( LauFitter::fitter().nParameters(),
627  LauFitter::fitter().nFreeParameters() );
628  fitResult = LauFitter::fitter().minimise();
629  }
630  }
631 
632  const TMatrixD& covMat = LauFitter::fitter().covarianceMatrix();
633  this->storeFitStatus( fitResult, covMat );
634 
635  // Store the final fit results and errors into protected internal vectors that
636  // all sub-classes can use within their own finalFitResults implementation
637  // used below (e.g. putting them into an ntuple in a root file)
639 }
640 
642 {
643  if ( sPlotNtuple_ != 0 ) {
646  LauSPlot splot( sPlotNtuple_->fileName(),
648  this->firstExpt(),
649  this->nExpt(),
650  this->variableNames(),
651  this->freeSpeciesNames(),
652  this->fixdSpeciesNames(),
653  this->twodimPDFs(),
654  this->splitSignal(),
655  this->scfDPSmear() );
657  splot.writeOutResults();
658  }
659 }
660 
661 void LauAbsFitModel::compareFitData( UInt_t toyMCScale,
662  const TString& mcFileName,
663  const TString& tableFileName,
664  Bool_t poissonSmearing )
665 {
666  compareFitData_ = kTRUE;
667  fitToyMCScale_ = toyMCScale;
668  fitToyMCFileName_ = mcFileName;
669  fitToyMCTableName_ = tableFileName;
670  fitToyMCPoissonSmear_ = poissonSmearing;
671 }
672 
673 void LauAbsFitModel::createFitToyMC( const TString& mcFileName, const TString& tableFileName )
674 {
675  // Create a toy MC sample so that the user can compare the fitted
676  // result with the data.
677  // Generate more toy MC to reduce statistical fluctuations:
678  // - use the rescaling value fitToyMCScale_
679 
680  // Store the info on the number of experiments, first expt and current expt
681  const UInt_t oldNExpt( this->nExpt() );
682  const UInt_t oldFirstExpt( this->firstExpt() );
683  const UInt_t oldIExpt( this->iExpt() );
684  const Bool_t oldToyExpt( this->toyExpts() );
685 
686  // Turn off Poisson smearing if required
687  const Bool_t poissonSmearing( this->doPoissonSmearing() );
689 
690  // Turn off embedding, since we need toy MC, not reco'ed events
691  const Bool_t enableEmbeddingOrig( this->enableEmbedding() );
692  this->enableEmbedding( kFALSE );
693 
694  // Need to make sure that the generation of the DP co-ordinates is
695  // switched on if any of our PDFs depend on it
696  const Bool_t origUseDP = this->useDP();
697  if ( ! origUseDP && this->pdfsDependOnDP() ) {
698  this->useDP( kTRUE );
699  this->initialiseDPModels();
700  }
701 
702  // Construct a unique filename for this experiment
703  TString exptString( "_expt" );
704  exptString += oldIExpt;
705  TString fileName( mcFileName );
706  fileName.Insert( fileName.Last( '.' ), exptString );
707 
708  // Generate the toy MC
709  std::cout << "INFO in LauAbsFitModel::createFitToyMC : Generating toy MC in " << fileName
710  << " to compare fit with data..." << std::endl;
711  std::cout << " : Number of experiments to generate = "
712  << fitToyMCScale_ << "." << std::endl;
713  std::cout << " : This is to allow the toy MC to be made with reduced statistical fluctuations."
714  << std::endl;
715 
716  // Set the genValue of each parameter to its current (fitted) value
717  // but first store the original genValues for restoring later
718  std::vector<Double_t> origGenValues;
719  origGenValues.reserve( this->nTotParams() );
720  Bool_t blind( kFALSE );
721  for ( LauParameterPList::iterator iter = fitVars_.begin(); iter != fitVars_.end(); ++iter ) {
722  origGenValues.push_back( ( *iter )->genValue() );
723  ( *iter )->genValue( ( *iter )->unblindValue() );
724  if ( ( *iter )->blind() ) {
725  blind = kTRUE;
726  }
727  }
728  if ( blind ) {
729  std::cerr << "WARNING in LauAbsFitModel::createFitToyMC : One or more parameters are blind but the toy will be created using the unblind values - use with caution!!"
730  << std::endl;
731  }
732 
733  // If we're asked to generate more than 100 experiments then split it
734  // up into multiple files since otherwise can run into memory issues
735  // when building the index
736  // TODO - this obviously depends on the number of events per experiment as well, so should do this properly
737 
738  UInt_t totalExpts = fitToyMCScale_;
739  if ( totalExpts > 100 ) {
740  UInt_t nFiles = totalExpts / 100;
741  if ( totalExpts % 100 ) {
742  nFiles += 1;
743  }
744  TString fileNameBase { fileName };
745  for ( UInt_t iFile( 0 ); iFile < nFiles; ++iFile ) {
746 
747  UInt_t firstExp( iFile * 100 );
748 
749  // Set number of experiments and first experiment to generate
750  UInt_t nExp = ( ( firstExp + 100 ) > totalExpts ) ? totalExpts - firstExp : 100;
751  this->setNExpts( nExp, firstExp, kTRUE );
752 
753  // Create a unique filename and generate the events
754  fileName = fileNameBase;
755  TString extraname = "_file";
756  extraname += iFile;
757  fileName.Insert( fileName.Last( '.' ), extraname );
758  this->generate( fileName, "genResults", "dummy.root", tableFileName );
759  }
760  } else {
761  // Set number of experiments to new value
762  this->setNExpts( fitToyMCScale_, 0, kTRUE );
763  // Generate the toy
764  this->generate( fileName, "genResults", "dummy.root", tableFileName );
765  }
766 
767  // Reset number of experiments to original value
768  this->setNExpts( oldNExpt, oldFirstExpt, oldToyExpt );
769  this->setCurrentExperiment( oldIExpt );
770 
771  // Restore the Poisson smearing to its former value
772  this->doPoissonSmearing( poissonSmearing );
773 
774  // Restore the embedding status
775  this->enableEmbedding( enableEmbeddingOrig );
776 
777  // Restore "useDP" to its former status
778  this->useDP( origUseDP );
779 
780  // Restore the original genValue to each parameter
781  for ( UInt_t i( 0 ); i < this->nTotParams(); ++i ) {
782  fitVars_[i]->genValue( origGenValues[i] );
783  }
784 
785  std::cout << "INFO in LauAbsFitModel::createFitToyMC : Finished in createFitToyMC." << std::endl;
786 }
787 
789 {
790  // Calculate the total negative log-likelihood over all events.
791  // This function assumes that the fit parameters and data tree have
792  // already been set-up correctly.
793 
794  // Loop over the data points to calculate the log likelihood
795  Double_t logLike = this->getLogLikelihood( 0, this->eventsPerExpt() );
796 
797  // Include the Poisson term in the extended likelihood if required
798  if ( this->doEMLFit() ) {
799  logLike -= this->getEventSum();
800  }
801 
802  // Calculate any penalty terms from Gaussian constrained variables
803  const auto& multiDimCons = this->multiDimConstraints();
804  if ( ! conVars_.empty() || ! multiDimCons.empty() ) {
805  logLike -= this->getLogLikelihoodPenalty();
806  }
807 
808  Double_t totNegLogLike = -logLike;
809  return totNegLogLike;
810 }
811 
813 {
814  Double_t penalty { 0.0 };
815 
816  for ( LauAbsRValue* par : conVars_ ) {
817  penalty += par->constraintPenalty();
818  }
819 
820  auto& multiDimCons = this->multiDimConstraints();
821  for ( auto& constraint : multiDimCons ) {
822  penalty += constraint.constraintPenalty();
823  }
824 
825  return penalty;
826 }
827 
828 Double_t LauAbsFitModel::getLogLikelihood( UInt_t iStart, UInt_t iEnd )
829 {
830  // Calculate the total negative log-likelihood over all events.
831  // This function assumes that the fit parameters and data tree have
832  // already been set-up correctly.
833 
834  // Loop over the data points to calculate the log likelihood
835  Double_t logLike( 0.0 );
836  const Double_t worstLL = this->worstLogLike();
837 
838  // Loop over the number of events in this experiment
839  Bool_t ok( kTRUE );
840  for ( UInt_t iEvt = iStart; iEvt < iEnd; ++iEvt ) {
841 
842  Double_t likelihood = this->getTotEvtLikelihood( iEvt );
843 
844  if ( likelihood > std::numeric_limits<Double_t>::min() ) { // Is the likelihood zero?
845  Double_t evtLogLike = TMath::Log( likelihood );
846  if ( doSFit_ ) {
847  evtLogLike *= sWeights_[iEvt];
848  }
849  logLike += evtLogLike;
850  } else {
851  ok = kFALSE;
852  std::cerr << "WARNING in LauAbsFitModel::getLogLikelihood : Strange likelihood value for event "
853  << iEvt << ": " << likelihood << "\n";
854  this->printEventInfo( iEvt );
855  this->printVarsInfo(); //Write the values of the floated variables for which the likelihood is zero
856  break;
857  }
858  }
859 
860  if ( ! ok ) {
861  std::cerr << " : Returning worst NLL found so far to force MINUIT out of this region."
862  << std::endl;
863  logLike = worstLL;
864  } else if ( logLike < worstLL ) {
865  this->worstLogLike( logLike );
866  }
867 
868  return logLike;
869 }
870 
871 void LauAbsFitModel::setParsFromMinuit( Double_t* par, Int_t npar )
872 {
873  // This function sets the internal parameters based on the values
874  // that Minuit is using when trying to minimise the total likelihood function.
875 
876  // MINOS reports different numbers of free parameters depending on the
877  // situation, so disable this check
878  if ( ! this->withinAsymErrorCalc() ) {
879  const UInt_t nFreePars = this->nFreeParams();
880  if ( static_cast<UInt_t>( npar ) != nFreePars ) {
881  std::cerr << "ERROR in LauAbsFitModel::setParsFromMinuit : Unexpected number of free parameters: "
882  << npar << ".\n";
883  std::cerr << " Expected: " << nFreePars
884  << ".\n"
885  << std::endl;
886  gSystem->Exit( EXIT_FAILURE );
887  }
888  }
889 
890  // Despite npar being the number of free parameters
891  // the par array actually contains all the parameters,
892  // free and floating...
893 
894  // Update all the floating ones with their new values
895  // Also check if we have any parameters on which the DP integrals depend
896  // and whether they have changed since the last iteration
897  Bool_t recalcNorm( kFALSE );
898  const LauParameterPSet::const_iterator resVarsEnd = resVars_.end();
899  for ( UInt_t i( 0 ); i < this->nTotParams(); ++i ) {
900  if ( ! fitVars_[i]->fixed() ) {
901  if ( resVars_.find( fitVars_[i] ) != resVarsEnd ) {
902  if ( fitVars_[i]->value() != par[i] ) {
903  recalcNorm = kTRUE;
904  }
905  }
906  fitVars_[i]->value( par[i] );
907  }
908  }
909 
910  // If so, then recalculate the normalisation
911  if ( recalcNorm ) {
912  this->recalculateNormalisation();
913  }
914 
915  this->propagateParUpdates();
916 }
917 
918 UInt_t LauAbsFitModel::addFitParameters( LauParameter* param, const Bool_t addFixed )
919 {
920  UInt_t nParsAdded { 0 };
921 
922  // if we're dealing with a clone,
923  // we should instead deal with its parent
924  if ( param->clone() ) {
925  param = param->parent();
926  }
927 
928  // we need to include the parameter if it is either:
929  // - floating
930  // - currently fixed but will float in the second stage of a two-stage fit
931  if ( addFixed || ! param->fixed() || ( this->twoStageFit() && param->secondStage() ) ) {
932  // check whether we already have this parameter stored
933  auto [_, addedOK] { fitVarsSet_.insert( param ) };
934  if ( addedOK ) {
935  // if not, add it to the list
936  fitVars_.push_back( param );
937  ++nParsAdded;
938  }
939  }
940 
941  return nParsAdded;
942 }
943 
944 UInt_t LauAbsFitModel::addFitParameters( LauParameterPList& paramList, const Bool_t addFixed )
945 {
946  UInt_t nParsAdded { 0 };
947 
948  for ( auto param : paramList ) {
949  nParsAdded += this->addFitParameters( param, addFixed );
950  }
951 
952  return nParsAdded;
953 }
954 
955 UInt_t LauAbsFitModel::addFitParameters( LauAbsRValue* param, const Bool_t addFixed )
956 {
957  UInt_t nParsAdded { 0 };
958 
959  LauParameterPList pars { param->getPars() };
960  for ( auto par : pars ) {
961  nParsAdded += this->addFitParameters( par, addFixed );
962  }
963 
964  return nParsAdded;
965 }
966 
967 UInt_t LauAbsFitModel::addFitParameters( LauAbsRValuePList& paramList, const Bool_t addFixed )
968 {
969  UInt_t nParsAdded { 0 };
970 
971  for ( auto param : paramList ) {
972  nParsAdded += this->addFitParameters( param, addFixed );
973  }
974 
975  return nParsAdded;
976 }
977 
978 UInt_t LauAbsFitModel::addFitParameters( LauPdfPList& pdfList, const Bool_t addFixed )
979 {
980  UInt_t nParsAdded { 0 };
981 
982  for ( auto pdf : pdfList ) {
983  if ( pdf->isDPDependent() ) {
984  this->pdfsDependOnDP( kTRUE );
985  }
986 
987  LauAbsRValuePList& pars = pdf->getParameters();
988  nParsAdded += this->addFitParameters( pars, addFixed );
989  }
990 
991  return nParsAdded;
992 }
993 
995 {
996  UInt_t nParsAdded { 0 };
997 
998  // first check if we have this parameter in the set of resonance parameters
999  auto [_, addedOK] { resVars_.insert( param ) };
1000 
1001  if ( addedOK ) {
1002  nParsAdded += this->addFitParameters( param );
1003  }
1004 
1005  return nParsAdded;
1006 }
1007 
1009 {
1010  UInt_t nParsAdded { 0 };
1011 
1012  for ( auto param : paramList ) {
1013  nParsAdded += this->addResonanceParameters( param );
1014  }
1015 
1016  return nParsAdded;
1017 }
1018 
1020 {
1021  // Add penalties from the constraints to fit parameters
1022 
1023  // First, constraints on the fit parameters themselves
1024  for ( LauParameter* param : fitVars_ ) {
1025  if ( param->gaussConstraint() ) {
1026  conVars_.push_back( param );
1027  std::cout << "INFO in LauAbsFitModel::addConParameters : Added Gaussian constraint to parameter "
1028  << param->name() << std::endl;
1029  }
1030  }
1031 
1032  // Second, constraints on arbitrary combinations
1033  auto& conStore = this->formulaConstraints();
1034  for ( auto& constraint : conStore ) {
1035  std::vector<LauParameter*> params;
1036  for ( const auto& name : constraint.conPars_ ) {
1037  for ( LauParameter* par : fitVars_ ) {
1038  if ( par->name() == name ) {
1039  params.push_back( par );
1040  }
1041  }
1042  }
1043 
1044  // If the parameters are not found, skip it
1045  if ( params.size() != constraint.conPars_.size() ) {
1046  std::cerr << "WARNING in LauAbsFitModel::addConParameters: Could not find parameters to constrain in the formula... skipping"
1047  << std::endl;
1048  continue;
1049  }
1050 
1051  constraint.formulaPar_ =
1052  std::make_unique<LauFormulaPar>( constraint.formula_, constraint.formula_, params );
1053  constraint.formulaPar_->addGaussianConstraint( constraint.mean_, constraint.width_ );
1054 
1055  conVars_.push_back( constraint.formulaPar_.get() );
1056 
1057  std::cout << "INFO in LauAbsFitModel::addConParameters : Added Gaussian constraint to formula\n";
1058  std::cout << " : Formula: " << constraint.formula_
1059  << std::endl;
1060  for ( LauParameter* param : params ) {
1061  std::cout << " : Parameter: " << param->name()
1062  << std::endl;
1063  }
1064  }
1065 
1066  // Add n-dimensional constraints
1067  auto& multiDimCons = this->multiDimConstraints();
1068  for ( auto& constraint : multiDimCons ) {
1069  for ( auto& parname : constraint.conPars_ ) {
1070  for ( auto& fitPar : fitVars_ ) {
1071  if ( parname == fitPar->name() ) {
1072  // Check parameters do not have a 1D Gaussian constraint applied
1073  if ( fitPar->gaussConstraint() ) {
1074  std::cerr << "ERROR in LauAbsFitModel::addConParameters: parameter in n-dimensional constraint already has a 1d constraint applied"
1075  << std::endl;
1076  gSystem->Exit( EXIT_FAILURE );
1077  }
1078  constraint.conLauPars_.push_back( fitPar );
1079  }
1080  }
1081  }
1082  if ( constraint.conLauPars_.size() != constraint.conPars_.size() ) {
1083  std::cerr << "Error in LauAbsFitModel::addConParameters : Could not match parameter names for n-dimensional constraint"
1084  << std::endl;
1085  gSystem->Exit( EXIT_FAILURE );
1086  }
1087  }
1088 }
1089 
1091 {
1092  for ( LauPdfPList::iterator pdf_iter = pdfList.begin(); pdf_iter != pdfList.end(); ++pdf_iter ) {
1093  ( *pdf_iter )->updatePulls();
1094  }
1095 }
1096 
1097 void LauAbsFitModel::printFitParameters( const LauPdfPList& pdfList, std::ostream& fout ) const
1098 {
1099  LauPrint print;
1100  for ( LauPdfPList::const_iterator pdf_iter = pdfList.begin(); pdf_iter != pdfList.end();
1101  ++pdf_iter ) {
1102  const LauAbsRValuePList& pars = ( *pdf_iter )->getParameters();
1103  for ( LauAbsRValuePList::const_iterator pars_iter = pars.begin(); pars_iter != pars.end();
1104  ++pars_iter ) {
1105  LauParameterPList params = ( *pars_iter )->getPars();
1106  for ( LauParameterPList::iterator params_iter = params.begin();
1107  params_iter != params.end();
1108  ++params_iter ) {
1109  if ( ! ( *params_iter )->clone() ) {
1110  fout << ( *params_iter )->name() << " & $";
1111  print.printFormat( fout, ( *params_iter )->value() );
1112  if ( ( *params_iter )->fixed() == kTRUE ) {
1113  fout << "$ (fixed) \\\\";
1114  } else {
1115  fout << " \\pm ";
1116  print.printFormat( fout, ( *params_iter )->error() );
1117  fout << "$ \\\\" << std::endl;
1118  }
1119  }
1120  }
1121  }
1122  }
1123 }
1124 
1125 void LauAbsFitModel::cacheInfo( LauPdfPList& pdfList, const LauFitDataTree& theData )
1126 {
1127  for ( LauPdfPList::iterator pdf_iter = pdfList.begin(); pdf_iter != pdfList.end(); ++pdf_iter ) {
1128  ( *pdf_iter )->cacheInfo( theData );
1129  }
1130 }
1131 
1132 Double_t LauAbsFitModel::prodPdfValue( LauPdfPList& pdfList, UInt_t iEvt )
1133 {
1134  Double_t pdfVal = 1.0;
1135  for ( LauPdfPList::iterator pdf_iter = pdfList.begin(); pdf_iter != pdfList.end(); ++pdf_iter ) {
1136  ( *pdf_iter )->calcLikelihoodInfo( iEvt );
1137  pdfVal *= ( *pdf_iter )->getLikelihood();
1138  }
1139  return pdfVal;
1140 }
1141 
1142 void LauAbsFitModel::printEventInfo( UInt_t iEvt ) const
1143 {
1144  const LauFitData& data = inputFitData_->getData( iEvt );
1145  std::cerr << " : Input data values for this event:"
1146  << std::endl;
1147  for ( LauFitData::const_iterator iter = data.begin(); iter != data.end(); ++iter ) {
1148  std::cerr << " " << iter->first << " = " << iter->second << std::endl;
1149  }
1150 }
1151 
1153 {
1154  std::cerr << " : Current values of fit parameters:"
1155  << std::endl;
1156  for ( UInt_t i( 0 ); i < this->nTotParams(); ++i ) {
1157  std::cerr << " " << ( fitVars_[i]->name() ).Data() << " = " << fitVars_[i]->value()
1158  << std::endl;
1159  }
1160 }
1161 
1163 {
1164  // Update initial fit parameters if required (e.g. if using random numbers).
1165  this->checkInitFitParams();
1166 
1167  // Store the total number of parameters and the number of free parameters
1168  UInt_t nPars = fitVars_.size();
1169  UInt_t nFreePars = 0;
1170 
1171  // Send the fit parameters
1172  for ( LauParameterPList::iterator iter = fitVars_.begin(); iter != fitVars_.end(); ++iter ) {
1173  if ( ! ( *iter )->fixed() ) {
1174  ++nFreePars;
1175  }
1176  array.Add( *iter );
1177  }
1178 
1179  this->startNewFit( nPars, nFreePars );
1180 }
1181 
1183  const TObjArray* parsFromCoordinator,
1184  const TMatrixD* covMat,
1185  TObjArray& parsToCoordinator )
1186 {
1187  // Copy the fit status information
1188  this->storeFitStatus( fitStat, *covMat );
1189 
1190  // Now process the parameters
1191  const UInt_t nPars = this->nTotParams();
1192  UInt_t nParsFromCoordinator = parsFromCoordinator->GetEntries();
1193  if ( nParsFromCoordinator != nPars ) {
1194  std::cerr << "ERROR in LauAbsFitModel::finaliseExperiment : Unexpected number of parameters received from coordinator"
1195  << std::endl;
1196  std::cerr << " : Received "
1197  << nParsFromCoordinator << " when expecting " << nPars << std::endl;
1198  gSystem->Exit( EXIT_FAILURE );
1199  }
1200 
1201  for ( UInt_t iPar( 0 ); iPar < nParsFromCoordinator; ++iPar ) {
1202  LauParameter* parameter = dynamic_cast<LauParameter*>( ( *parsFromCoordinator )[iPar] );
1203  if ( ! parameter ) {
1204  std::cerr << "ERROR in LauAbsFitModel::finaliseExperiment : Error reading parameter from coordinator"
1205  << std::endl;
1206  gSystem->Exit( EXIT_FAILURE );
1207  }
1208 
1209  if ( parameter->name() != fitVars_[iPar]->name() ) {
1210  std::cerr << "ERROR in LauAbsFitModel::finaliseExperiment : Error reading parameter from coordinator"
1211  << std::endl;
1212  gSystem->Exit( EXIT_FAILURE );
1213  }
1214 
1215  *( fitVars_[iPar] ) = *parameter;
1216  }
1217 
1218  // Write the results into the ntuple
1220 
1221  // Store the per-event likelihood values
1222  if ( this->writeSPlotData() ) {
1223  this->storePerEvtLlhds();
1224  }
1225 
1226  // Create a toy MC sample using the fitted parameters so that
1227  // the user can compare the fit to the data.
1228  if ( compareFitData_ == kTRUE && fitStat.status == 3 ) {
1230  }
1231 
1232  // Send the finalised fit parameters
1233  for ( LauParameterPList::iterator iter = fitVars_.begin(); iter != fitVars_.end(); ++iter ) {
1234  parsToCoordinator.Add( *iter );
1235  }
1236 }
1237 
1239 {
1240  // retrieve the data and find out how many events have been read
1241  const UInt_t exptIndex = this->iExpt();
1242  inputFitData_->readExperimentData( exptIndex );
1243  const UInt_t nEvent = inputFitData_->nEvents();
1244  this->eventsPerExpt( nEvent );
1245  return nEvent;
1246 }
1247 
1248 void LauAbsFitModel::setParametersFromFile( const TString& fileName,
1249  const TString& treeName,
1250  const Bool_t fix )
1251 {
1252  fixParamFileName_ = fileName;
1253  fixParamTreeName_ = treeName;
1254  fixParams_ = fix;
1255 }
1256 
1257 void LauAbsFitModel::setParametersFromMap( const std::map<TString, Double_t>& parameters,
1258  const Bool_t fix )
1259 {
1260  fixParamMap_ = parameters;
1261  fixParams_ = fix;
1262 }
1263 
1264 void LauAbsFitModel::setNamedParameters( const TString& fileName,
1265  const TString& treeName,
1266  const std::set<TString>& parameters,
1267  const Bool_t fix )
1268 {
1269  fixParamFileName_ = fileName;
1270  fixParamTreeName_ = treeName;
1271  fixParamNames_ = parameters;
1272  fixParams_ = fix;
1273 }
1274 
1275 void LauAbsFitModel::setParametersFileFallback( const TString& fileName,
1276  const TString& treeName,
1277  const std::map<TString, Double_t>& parameters,
1278  const Bool_t fix )
1279 {
1280  fixParamFileName_ = fileName;
1281  fixParamTreeName_ = treeName;
1282  fixParamMap_ = parameters;
1283  fixParams_ = fix;
1284 }
File containing declaration of LauAbsPdf class.
File containing declaration of LauAbsFitModel class.
LauFitDataTree * inputFitData_
The input data.
virtual UInt_t readExperimentData()
Read in the data for the current experiment.
Bool_t doEMLFit() const
Determine whether an extended maximum likelihood fit it being performed.
const TString & fileName() const
Ntuple file name.
Definition: LauGenNtuple.hh:62
void setDoubleBranchValue(const TString &name, Double_t value)
Set value of a double branch.
virtual void initialiseDPModels()=0
Initialise the DP models.
virtual Int_t getGenNtupleIntegerBranchValue(const TString &name) const
Get the value of an integer branch in the gen tree.
UInt_t numberOKFits() const
Access the number of successful fits.
UInt_t addResonanceParameters(LauParameter *param)
Add the given parameter to the list of resonance parameters and the list of all fit parameters.
const TString nullString_
An empty string.
File containing declaration of LauFitter class.
Int_t getIntegerBranchValue(const TString &name) const
Get value of an integer branch.
Class for defining the fit parameter objects.
Definition: LauParameter.hh:49
virtual void writeOutTable(const TString &outputFile)=0
Write the latex table.
Bool_t writeSPlotData_
Option to write sPlot data.
Struct to store fit status information.
Definition: LauAbsFitter.hh:54
Bool_t doPoissonSmearing() const
Determine whether Poisson smearing is enabled for the toy MC generation.
Bool_t doSFit() const
Return the flag to store the status of using an sFit or not.
virtual Double_t getTotEvtLikelihood(UInt_t iEvt)=0
Calculates the likelihood for a given event.
TString sPlotFileName_
The name of the sPlot file.
void readExperimentData(UInt_t iExpt)
Read events only for the given experiment.
virtual Double_t getGenNtupleDoubleBranchValue(const TString &name) const
Get the value of a double branch in the gen tree.
Double_t value() const
The value of the parameter.
virtual void setGenNtupleIntegerBranchValue(const TString &name, Int_t value)
Set the value of an integer branch in the gen tree.
virtual void savePDFPlots(const TString &label)=0
Save the pdf Plots for all the resonances of experiment number fitExp.
void setParametersFromMap(const std::map< TString, Double_t > &parameters, const Bool_t fix)
Set model parameters from a given std::map.
Bool_t writeSPlotData() const
Determine whether the sPlot data is to be written out.
File containing declaration of LauAbsFitter class.
LauParameterPSet fitVarsSet_
Internal set of the same fit parameters (used to check uniqueness)
virtual Bool_t verifyFitData(const TString &dataFileName, const TString &dataTreeName)
Open the input file and verify that all required variables are present.
const LauFitData & getData(UInt_t iEvt) const
Retrieve the data for a given event.
TString fitToyMCTableName_
The output table name for Toy MC.
UInt_t firstExpt() const
Obtain the number of the first experiment.
LauBkgndClassMap bkgndClassNames_
The background class names.
virtual void printEventInfo(UInt_t iEvt) const
Prints the values of all the fit variables for the specified event - useful for diagnostics.
virtual Double_t getEventSum() const =0
Returns the sum of the expected events over all hypotheses; used in the EML fit scenario.
Bool_t toyExpts() const
Obtain whether this is toy.
void addDoubleBranch(const TString &name)
Add double branch to tree.
Definition: LauGenNtuple.cc:98
virtual void initialise()=0
Initialise the fit par vectors.
File containing declaration of LauParamFixed class.
void runCalculations(const TString &option="q")
Method to calculate the sWeights and cN coeffs.
Definition: LauSPlot.cc:703
File containing declaration of LauSPlot class.
File containing declaration of LauParameter class.
virtual void propagateParUpdates()=0
This function (specific to each model) calculates anything that depends on the fit parameter values.
virtual ~LauAbsFitModel()
Destructor.
void writeOutGenResults()
Write out the results from the generation.
void cacheInfo(LauPdfPList &pdfList, const LauFitDataTree &theData)
Have all PDFs in the list cache the data.
void setParametersFileFallback(const TString &fileName, const TString &treeName, const std::map< TString, Double_t > &parameters, const Bool_t fix)
Set named model parameters from a given std::map, with fallback to those from a file.
Bool_t enableEmbedding() const
Determine whether embedding of events is enabled in the generation.
virtual void generate(const TString &dataFileName, const TString &dataTreeName, const TString &histFileName, const TString &tableFileNameBase)
Generate toy MC.
Bool_t findBranches()
Find all of the branches in the tree.
virtual Bool_t genExpt()=0
The method that actually generates the toy MC events for the given experiment.
Bool_t useAsymmFitErrors() const
Report whether or not calculation of asymmetric errors is enabled.
Definition: LauFitObject.hh:60
virtual void addGenNtupleDoubleBranch(const TString &name)
Add a branch to the gen tree for storing a double.
File containing declaration of LauFitDataTree class.
virtual void printVarsInfo() const
Same as printEventInfo, but printing out the values of the variables in the fit.
const TString & treeName() const
Retrieve the tree name.
TString fixParamTreeName_
Imported parameters tree name.
TString fitToyMCFileName_
The output file name for Toy MC.
const TString & bkgndClassName(UInt_t classID) const
Get the name of a background class from the number.
static LauAbsFitter & fitter()
Method that provides access to the singleton fitter.
Definition: LauFitter.cc:75
void storeFitStatus(const LauAbsFitter::FitStatus &status, const TMatrixD &covMatrix)
Store fit status information.
Definition: LauFitObject.cc:93
UInt_t numberBadFits() const
Access the number of failed fits.
virtual void finaliseExperiment(const LauAbsFitter::FitStatus &fitStat, const TObjArray *parsFromCoordinator, const TMatrixD *covMat, TObjArray &parsToCoordinator)
Perform all finalisation actions.
UInt_t bkgndClassID(const TString &className) const
The number assigned to a background class.
virtual std::vector< LauParameter * > getPars()=0
Return the list of LauParameters on which the LauAbsRValue depends.
void resetFitCounters()
Reset the good/bad fit counters.
Definition: LauFitObject.cc:76
std::vector< LauParameter * > LauParameterPList
List of parameter pointers.
virtual Double_t getTotNegLogLikelihood()
Calculates the total negative log-likelihood.
virtual void weightEvents(const TString &dataFileName, const TString &dataTreeName)=0
Weighting - allows e.g. MC events to be weighted by the DP model.
LauParameterList extraVars_
Extra variables that aren't in the fit but are stored in the ntuple.
virtual Bool_t useAsymmFitErrors() const =0
Determine whether calculation of asymmetric errors is enabled.
Bool_t haveBranch(const TString &name) const
Check if the named branch is stored.
const TString & treeName() const
Ntuple tree name.
Definition: LauGenNtuple.hh:68
virtual void cacheInputSWeights()
Cache the value of the sWeights to be used in the sFit.
Bool_t doSFit_
Option to perfom the sFit.
const std::vector< MultiDimConstraint > & multiDimConstraints() const
Const access to the ND constraints store.
Class to store the input fit variables.
TString fixParamFileName_
Imported parameters file name.
Bool_t secondStage() const
Check whether the parameter should be floated only in the second stage of a two stage fit.
Bool_t storeDPEff_
Option to store DP efficiencies in the sPlot ntuple.
virtual Bool_t twoStageFit() const =0
Determine whether the two-stage fit is enabled.
LauParameter * parent() const
The parent parameter.
void generateConstraintMeans(std::vector< LauAbsRValue * > &conVars)
Generate per-experiment mean for each Gaussian constraint.
void addConParameters()
Add parameters to the list of Gaussian constrained parameters.
void setIntegerBranchValue(const TString &name, Int_t value)
Set value of an integer branch.
virtual void setupSPlotNtupleBranches()=0
Setup the branches of the sPlot tuple.
Bool_t blind() const
The blinding state.
void fillBranches()
Fill branches in the ntuple.
UInt_t addFitParameters(LauParameter *param, const Bool_t addFixed=kFALSE)
Add the given parameter to the list of all fit parameters.
virtual void cacheInputFitVars()=0
Cache the input data values to calculate the likelihood during the fit.
void createFitToyMC(const TString &mcFileName, const TString &tableFileName)
Create a toy MC sample from the fitted parameters.
virtual const FitStatus & minimise()=0
Perform the minimisation of the fit function.
const std::vector< FormulaConstraint > & formulaConstraints() const
Const access to the formula constraints store.
Double_t sWeightScaleFactor_
The sWeight scaling factor.
Bool_t clone() const
Check whether is a clone or not.
TString sPlotTreeName_
The name of the sPlot tree.
virtual const TMatrixD & covarianceMatrix() const =0
Retrieve the fit covariance matrix.
void addFriendTree(const TString &rootFileName, const TString &rootTreeName)
Add a friend tree.
std::vector< LauAbsRValue * > LauAbsRValuePList
List of parameter pointers.
Bool_t withinAsymErrorCalc() const
Query whether the fit is calculating the asymmetric errors.
Definition: LauFitObject.hh:94
virtual void setSPlotNtupleDoubleBranchValue(const TString &name, Double_t value)
Set the value of a double branch in the sPlot tree.
File containing declaration of LauComplex class.
virtual void setupGenNtupleBranches()=0
Setup the generation ntuple branches.
UInt_t iExpt() const
Obtain the number of the current experiment.
virtual void fillSPlotNtupleBranches()
Fill the sPlot tuple.
Double_t prodPdfValue(LauPdfPList &pdfList, UInt_t iEvt)
Calculate the product of the per-event likelihoods of the PDFs in the list.
Class for defining the SPlot technique.
Definition: LauSPlot.hh:68
void setParametersFromFile(const TString &fileName, const TString &treeName, const Bool_t fix)
Set model parameters from a file.
File containing declaration of LauGenNtuple class.
virtual void addSPlotNtupleIntegerBranch(const TString &name)
Add a branch to the sPlot tree for storing an integer.
virtual void prepareInitialParArray(TObjArray &array)
Package the initial fit parameters for transmission to the coordinator.
Int_t statusCode() const
Access the fit status code.
const TString & fileName() const
Retrieve the file name.
LauGenNtuple * genNtuple_
The generated ntuple.
virtual void setBkgndClassNames(const std::vector< TString > &names)
Setup the background class names.
virtual void setGenNtupleDoubleBranchValue(const TString &name, Double_t value)
Set the value of a double branch in the gen tree.
LauAbsFitModel()
Constructor.
void fit(const TString &dataFileName, const TString &dataTreeName, const TString &histFileName, const TString &tableFileNameBase)
Perform the total fit.
Double_t getDoubleBranchValue(const TString &name) const
Get value of a double branch.
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.
void setGenValues()
Make sure all parameters hold their genValue as the current value.
Bool_t fixed() const
Check whether the parameter is fixed or floated.
virtual void calculateSPlotData()
Calculate the sPlot data.
Bool_t pdfsDependOnDP() const
Do any of the PDFs have a dependence on the DP?
Bool_t writeLatexTable() const
Determine whether writing out of the latex table is enabled.
void run(const TString &applicationCode, const TString &dataFileName, const TString &dataTreeName, const TString &histFileName, const TString &tableFileName="")
Start the toy generation / fitting.
Int_t buildIndex(const TString &majorName, const TString &minorName="0")
Create an index table using leaves of the tree.
Pure abstract base class for defining a parameter containing an R value.
Definition: LauAbsRValue.hh:45
std::map< TString, Double_t > fixParamMap_
Map from imported parameter name to value.
const TString & name() const
The parameter name.
virtual void setupResultsOutputs(const TString &histFileName, const TString &tableFileName)
Setup saving of fit results to ntuple/LaTeX table etc.
virtual void addSPlotNtupleDoubleBranch(const TString &name)
Add a branch to the sPlot tree for storing a double.
void addIntegerBranch(const TString &name)
Add integer branch to tree.
Definition: LauGenNtuple.cc:88
void clearFitParVectors()
Clear the vectors containing fit parameters.
virtual void storePerEvtLlhds()=0
Store the per-event likelihood values.
void startNewFit(const UInt_t nPars, const UInt_t nFreePars)
Indicate the start of a new fit.
Definition: LauFitObject.cc:83
virtual void writeOutAllFitResults()
Write out any fit results.
std::map< TString, Double_t > LauFitData
Type for holding event data.
LauAbsRValuePList conVars_
Internal vectors of Gaussian parameters.
virtual void addGenNtupleIntegerBranch(const TString &name)
Add a branch to the gen tree for storing an integer.
File containing declaration of LauPrint class and LauOutputLevel enum.
Class to define various output print commands.
Definition: LauPrint.hh:54
Bool_t useDP() const
Is the Dalitz plot term in the likelihood.
virtual void setupResultsOutputs(const TString &histFileName, const TString &tableFileName)
Setup saving of fit results to ntuple/LaTeX table etc.
virtual void setSPlotNtupleIntegerBranchValue(const TString &name, Int_t value)
Set the value of an integer branch in the sPlot tree.
void clearExtraVarVectors()
Clear the vectors containing extra ntuple variables.
UInt_t fitToyMCScale_
The scaling factor (toy vs data statistics)
Bool_t fixParams_
Whether to fix the loaded parameters (kTRUE) or leave them floating (kFALSE)
void writeOutResults()
Save the sWeight results as a friend tree to the input tree (in the same file)
Definition: LauSPlot.cc:1359
Bool_t fitToyMCPoissonSmear_
Option to perform Poisson smearing.
UInt_t nExpt() const
Obtain the number of experiments.
void printFitParameters(const LauPdfPList &pdfList, std::ostream &fout) const
Print the fit parameters for all PDFs in the list.
TString sWeightBranchName_
The name of the sWeight branch.
UInt_t eventsPerExpt() const
Obtain the total number of events in the current experiment.
void printFormat(std::ostream &stream, Double_t value) const
Method to choose the printing format to a specified level of precision.
Definition: LauPrint.cc:43
virtual void finaliseFitResults(const TString &tableFileName)=0
Write the results of the fit into the ntuple.
void setNamedParameters(const TString &fileName, const TString &treeName, const std::set< TString > &parameters, const Bool_t fix)
Set named model parameters from a file.
virtual void initialise(LauFitObject *fitObj, const std::vector< LauParameter * > &parameters)=0
Initialise the fitter, setting the information on the parameters.
virtual void checkInitFitParams()=0
Update initial fit parameters if required.
Double_t getLogLikelihoodPenalty()
Calculate the penalty terms to the log likelihood from Gaussian constraints.
UInt_t nTotParams() const
Access the total number of fit parameters.
TStopwatch timer_
The fit timer.
Bool_t twoStageFit() const
Report whether the two-stage fit is enabled.
Definition: LauFitObject.hh:76
virtual void fillGenNtupleBranches()
Fill the gen tuple branches.
Int_t status
The status code of the fit.
Definition: LauAbsFitter.hh:56
TString sPlotVerbosity_
Control the verbosity of the sFit.
Double_t getLogLikelihood(UInt_t iStart, UInt_t iEnd)
Calculate the sum of the log-likelihood over the specified events.
TString outputTableName_
The output table name.
void updateFitParameters(LauPdfPList &pdfList)
Update the fit parameters for all PDFs in the list.
LauParameterPList fitVars_
Internal vector of fit parameters.
TStopwatch cumulTimer_
The total fit timer.
UInt_t nEvents() const
Retrieve the number of events.
void fitExpt()
Routine to perform the actual fit for a given experiment.
std::set< TString > fixParamNames_
Imported parameter names.
Bool_t validBkgndClass(const TString &className) const
Check if the given background class is in the list.
void deleteAndRecreateTree()
Delete and recreate tree.
LauGenNtuple * sPlotNtuple_
The sPlot ntuple.
void setCurrentExperiment(const UInt_t curExpt)
Set the ID of the current experiment.
Bool_t compareFitData_
Option to make toy from 1st successful experiment.
virtual void setParsFromMinuit(Double_t *par, Int_t npar)
This function sets the parameter values from Minuit.
virtual void releaseSecondStageParameters()=0
Release parameters marked as "second stage".
Class to store the results from the toy MC generation into an ntuple.
Definition: LauGenNtuple.hh:45
virtual void updateParameters()=0
Update the values and errors of the parameters based on the fit minimum.
LauParameterPSet resVars_
Internal set of fit parameters upon which the DP normalisation depends.
Double_t worstLogLike() const
Access the worst log likelihood found so far.
std::vector< Double_t > sWeights_
The vector of sWeights.
std::vector< LauAbsPdf * > LauPdfPList
List of Pdfs.
UInt_t nFreeParams() const
Access the total number of fit parameters.
virtual void recalculateNormalisation()=0
Recalculate normalisation the signal DP model(s)
void setNExpts(UInt_t nExperiments, UInt_t firstExperiment, Bool_t toyExpts)
Set the number of experiments, the first experiment, and whether this is toy.
Definition: LauFitObject.cc:61
virtual void setupBkgndVectors()=0
Method to set up the storage for background-related quantities called by setBkgndClassNames.