laura is hosted by Hepforge, IPPP Durham
Laura++  3.6.0
A maximum likelihood fitting package for performing Dalitz-plot analysis.
LauFitObject.cc
Go to the documentation of this file.
1 
2 /*
3 Copyright 2017 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 "LauFitObject.hh"
30 
31 #include "LauRandom.hh"
32 
33 #include "TDecompChol.h"
34 #include "TMatrixD.h"
35 #include "TRandom.h"
36 #include "TSystem.h"
37 #include "TVectorD.h"
38 
39 #include <iostream>
40 
42  TObject(),
43  twoStageFit_( kFALSE ),
44  useAsymmFitErrors_( kFALSE ),
45  nParams_( 0 ),
46  nFreeParams_( 0 ),
47  withinAsymErrorCalc_( kFALSE ),
48  toyExpts_( kFALSE ),
49  firstExpt_( 0 ),
50  nExpt_( 1 ),
51  iExpt_( 0 ),
52  evtsPerExpt_( 0 ),
53  fitStatus_( { -1, 0.0, 0.0 } ),
54  worstLogLike_( std::numeric_limits<Double_t>::max() ),
55  covMatrix_(),
56  numberOKFits_( 0 ),
57  numberBadFits_( 0 )
58 {
59 }
60 
61 void LauFitObject::setNExpts( UInt_t nExperiments, UInt_t firstExperiment, Bool_t toyExpts )
62 {
63  nExpt_ = nExperiments;
64  firstExpt_ = firstExperiment;
66 
67  if ( ! toyExpts && ( nExperiments > 1 || firstExperiment > 0 ) ) {
68  std::cerr << "WARNING in LauFitObject::setNExpts : toyExpts is set to kFALSE but the values of nExperiments and firstExperiment indicate otherwise, please check"
69  << std::endl;
70  } else if ( toyExpts && nExperiments == 1 && firstExperiment == 0 ) {
71  std::cerr << "WARNING in LauFitObject::setNExpts : toyExpts is set to kTRUE but the values of nExperiments and firstExperiment perhaps indicate otherwise, please check"
72  << std::endl;
73  }
74 }
75 
77 {
78  numberOKFits_ = 0;
79  numberBadFits_ = 0;
80  fitStatus_ = { -1, 0.0, 0.0 };
81 }
82 
83 void LauFitObject::startNewFit( const UInt_t nPars, const UInt_t nFreePars )
84 {
85  // Reset the worst likelihood found to its catch-all value
86  worstLogLike_ = std::numeric_limits<Double_t>::max();
87 
88  // Store the number of fit parameters (total and floating)
89  nParams_ = nPars;
90  nFreeParams_ = nFreePars;
91 }
92 
93 void LauFitObject::storeFitStatus( const LauAbsFitter::FitStatus& status, const TMatrixD& covMatrix )
94 {
95  fitStatus_ = status;
96 
97  covMatrix_.Clear();
98  covMatrix_.ResizeTo( covMatrix.GetNrows(), covMatrix.GetNcols() );
99  covMatrix_.SetMatrixArray( covMatrix.GetMatrixArray() );
100 
101  // Keep track of how many fits worked or failed
102  // NB values of fitStatus_ indicate the status of the error matrix:
103  // 0= not calculated at all
104  // 1= approximation only, not accurate
105  // 2= full matrix, but forced positive-definite
106  // 3= full accurate covariance matrix
107  if ( fitStatus_.status == 3 ) {
108  ++numberOKFits_;
109  } else {
110  ++numberBadFits_;
111  }
112 }
113 
114 void LauFitObject::addConstraint( const TString& formula,
115  const std::vector<TString>& pars,
116  const Double_t mean,
117  const Double_t width )
118 {
119  std::cerr << "WARNING in LauFitObject::addConstraint : This function is deprecated, please switch to addFormulaConstraint!"
120  << std::endl;
121  this->addFormulaConstraint( formula, pars, mean, width );
122 }
123 
124 void LauFitObject::addFormulaConstraint( const TString& formula,
125  const std::vector<TString>& pars,
126  const Double_t mean,
127  const Double_t width )
128 {
129  if ( ! this->checkRepetition( pars, ConstraintType::Formula ) ) {
130  std::cerr << "WARNING in LauFitObject::addFormulaConstraint : Parameter(s) added to multiple constraints!"
131  << std::endl;
132  }
133 
134  formulaConstraints_.emplace_back( FormulaConstraint { formula, pars, mean, width, nullptr } );
135 
136  std::cout << "INFO in LauFitObject::addFormulaConstraint : Added formula constraint" << std::endl;
137 }
138 
139 void LauFitObject::addMultiDimConstraint( const std::vector<TString>& pars,
140  const TVectorD& means,
141  const TMatrixD& covMat )
142 {
143  if ( ! this->checkRepetition( pars, ConstraintType::MultDim ) ) {
144  std::cerr << "WARNING in LauFitObject::addMultiDimConstraint : Parameter(s) added to multiple constraints!"
145  << std::endl;
146  }
147 
148  multiDimConstraints_.emplace_back( pars, means, covMat );
149 
150  std::cout << "INFO in LauFitObject::addMultiDimConstraint : Added multi-dimensional constraint"
151  << std::endl;
152 }
153 
154 void LauFitObject::generateConstraintMeans( std::vector<LauAbsRValue*>& conVars )
155 {
156  if ( ! this->toyExpts() ) {
157  return;
158  }
159 
160  // For reproducibility, set a seed based on the experiment number
161  // First, store the current seed, so that it can be restored afterwards
162  const UInt_t oldSeed { LauRandom::randomFun()->GetSeed() };
163  LauRandom::randomFun()->SetSeed( 827375 + this->iExpt() );
164 
165  for ( LauAbsRValue* par : conVars ) {
166  par->generateConstraintMean();
167  }
168 
169  for ( auto& constraint : multiDimConstraints_ ) {
170  constraint.generateConstraintMeans();
171  }
172 
173  // Restore the old random seed
174  LauRandom::randomFun()->SetSeed( oldSeed );
175 }
176 
177 Bool_t LauFitObject::checkRepetition( const std::vector<TString>& names, const ConstraintType conType )
178 {
179  Bool_t allOK { kTRUE };
180 
181  for ( auto& newname : names ) {
182  // Check in formula constraints
183  if ( formulaConstrainedPars_.find( newname ) != formulaConstrainedPars_.end() ) {
184  std::cerr << "WARNING in LauFitObject::checkRepetition: named parameter " << newname
185  << " already used in a formula constraint" << std::endl;
186  allOK = kFALSE;
187  }
188 
189  // Check in ND constraints
190  if ( multiDimConstrainedPars_.find( newname ) != multiDimConstrainedPars_.end() ) {
191  std::cerr << "WARNING in LauFitObject::checkRepetition: named parameter " << newname
192  << " already used in a multi-dimensional constraint" << std::endl;
193  allOK = kFALSE;
194  }
195 
196  // Add the new names to the appropriate set
197  switch ( conType ) {
199  formulaConstrainedPars_.insert( newname );
200  break;
202  multiDimConstrainedPars_.insert( newname );
203  break;
204  }
205  }
206 
207  return allOK;
208 }
209 
210 LauFitObject::MultiDimConstraint::MultiDimConstraint( const std::vector<TString>& parNames,
211  const TVectorD& means,
212  const TMatrixD& covMat ) :
213  conPars_ { parNames },
214  trueMeans_ { means },
215  means_ { means },
216  invCovMat_ { covMat.GetNrows(), covMat.GetNcols() },
217  sqrtCovMat_ { covMat.GetNrows(), covMat.GetNcols() }
218 {
219  if ( covMat.GetNcols() != covMat.GetNrows() ) {
220  std::cerr << "ERROR in LauFitObject::MultiDimConstraint : Covariance matrix is not square!"
221  << std::endl;
222  gSystem->Exit( EXIT_FAILURE );
223  }
224 
225  if ( ( parNames.size() != static_cast<std::size_t>( means.GetNrows() ) ) ||
226  ( parNames.size() != static_cast<std::size_t>( covMat.GetNrows() ) ) ) {
227  std::cerr << "ERROR in LauFitObject::MultiDimConstraint : Different number of elements in vectors/covariance matrix!"
228  << std::endl;
229  gSystem->Exit( EXIT_FAILURE );
230  }
231 
232  // Check invertion of the covariance matrix was successful
233  TMatrixD invCovMat { TMatrixD::kInverted, covMat };
234  if ( invCovMat == covMat ) {
235  std::cerr << "ERROR in LauFitObject::MultiDimConstraint : covariance matrix inversion failed, check your input!"
236  << std::endl;
237  gSystem->Exit( EXIT_FAILURE );
238  }
239  invCovMat_ = invCovMat;
240 
241  // Check invertion of the covariance matrix was successful
242  TDecompChol cholDecomp { covMat };
243  if ( ! cholDecomp.Decompose() ) {
244  std::cerr << "ERROR in LauFitObject::MultiDimConstraint : covariance matrix decomposition failed, check your input!"
245  << std::endl;
246  gSystem->Exit( EXIT_FAILURE );
247  }
248  sqrtCovMat_ = TMatrixD { TMatrixD::kTransposed, cholDecomp.GetU() };
249 }
250 
252 {
253  TVectorD diff { means_.GetNrows() };
254  for ( ULong_t j { 0 }; j < conLauPars_.size(); ++j ) {
255  LauParameter* param = conLauPars_[j];
256  diff[j] = param->unblindValue();
257  }
258  diff -= means_;
259  return 0.5 * invCovMat_.Similarity( diff );
260 }
261 
263 {
264  TRandom* random = LauRandom::randomFun();
265 
266  for ( Int_t j { 0 }; j < trueMeans_.GetNrows(); ++j ) {
267  means_[j] = random->Gaus( 0.0, 1.0 );
268  }
269 
270  means_ *= sqrtCovMat_;
271  means_ += trueMeans_;
272 
273  // Store the new mean in the parameter itself to enable writing it out to the results ntuple
274  // (this is safe because a parameter cannot have both a 1D constraint and an ND constraint on it at the same time)
275  for ( Int_t j { 0 }; j < trueMeans_.GetNrows(); ++j ) {
276  conLauPars_[j]->constraintMean_ = means_[j];
277  std::cout << "INFO in LauFitObject::MultiDimConstraint::generateConstraintMeans : set constraint mean for parameter \""
278  << conLauPars_[j]->name() << "\" to " << conLauPars_[j]->constraintMean_
279  << std::endl;
280  }
281 }
File containing LauRandom namespace.
Double_t worstLogLike_
The worst log likelihood value found so far.
std::vector< MultiDimConstraint > multiDimConstraints_
Store the ND constraints for fit parameters until initialisation is complete.
Class for defining the fit parameter objects.
Definition: LauParameter.hh:49
Double_t unblindValue() const
The unblinded value of the parameter.
Struct to store fit status information.
Definition: LauAbsFitter.hh:54
UInt_t numberBadFits_
The number of fit failures.
std::vector< FormulaConstraint > formulaConstraints_
Store the constraints for fit parameters until initialisation is complete.
UInt_t nFreeParams_
The number of free fit parameters.
@ Formula
Formula-based constraint on a combination of parameters.
std::set< TString > formulaConstrainedPars_
Store the names of all parameters used in all formula constraints.
std::set< TString > multiDimConstrainedPars_
Store the names of all parameters used in all multi-dimensional constraints.
void addMultiDimConstraint(const std::vector< TString > &pars, const TVectorD &means, const TMatrixD &covMat)
Store n-dimensional constraint information for fit parameters.
Bool_t toyExpts() const
Obtain whether this is toy.
UInt_t nParams_
The number of fit parameters.
ConstraintType
Enumeration of the different types of constraint.
Struct to store formula-based constraint information.
void storeFitStatus(const LauAbsFitter::FitStatus &status, const TMatrixD &covMatrix)
Store fit status information.
Definition: LauFitObject.cc:93
void resetFitCounters()
Reset the good/bad fit counters.
Definition: LauFitObject.cc:76
Double_t constraintPenalty() const
Get the penalty term.
void generateConstraintMeans(std::vector< LauAbsRValue * > &conVars)
Generate per-experiment mean for each Gaussian constraint.
UInt_t iExpt() const
Obtain the number of the current experiment.
MultiDimConstraint()=default
Default constructor.
TRandom * randomFun()
Access the singleton random number generator with a particular seed.
Definition: LauRandom.cc:33
@ MultDim
Multi-dimensional constraint on several parameters.
Pure abstract base class for defining a parameter containing an R value.
Definition: LauAbsRValue.hh:45
void startNewFit(const UInt_t nPars, const UInt_t nFreePars)
Indicate the start of a new fit.
Definition: LauFitObject.cc:83
void generateConstraintMeans()
Generate per-experiment constraint means.
void addConstraint(const TString &formula, const std::vector< TString > &pars, const Double_t mean, const Double_t width)
Store constraint information for fit parameters.
UInt_t nExpt_
The number of experiments to consider.
Bool_t checkRepetition(const std::vector< TString > &names, const ConstraintType conType)
Check if parameters names for constraints have already been used elsewhere.
LauFitObject()
Constructor.
Definition: LauFitObject.cc:41
TMatrixD covMatrix_
The fit covariance matrix.
File containing declaration of LauFitObject class.
Int_t status
The status code of the fit.
Definition: LauAbsFitter.hh:56
Bool_t toyExpts_
Flag to indicate whether this is toy.
LauAbsFitter::FitStatus fitStatus_
The status of the current fit.
UInt_t firstExpt_
The number of the first experiment to consider.
void addFormulaConstraint(const TString &formula, const std::vector< TString > &pars, const Double_t mean, const Double_t width)
Store constraint information for fit parameters.
UInt_t numberOKFits_
The number of successful fits.
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