17#include "analysis/OrcaKinFit/BaseFitObject.h"
18#include <framework/logging/Logger.h>
28#include <gsl/gsl_matrix.h>
29#include <gsl/gsl_linalg.h>
36 namespace OrcaKinFit {
45 for (
int ilocal = 0; ilocal < BaseDefs::MAXPAR; ++ilocal) {
47 fixed[ilocal] =
false;
48 for (
int jlocal = 0; jlocal < BaseDefs::MAXPAR; ++jlocal)
49 cov[ilocal][jlocal] = 0;
55 : name(nullptr), par{}, mpar{}, measured{}, fixed{}, globalParNum{}, cov{}, covinv{}, covinvvalid(false), cachevalid(false)
70 if (&source !=
this) {
73 for (
int i = 0; i < BaseDefs::MAXPAR; ++i) {
74 par[i] = source.par[i];
75 mpar[i] = source.mpar[i];
77 fixed[i] = source.fixed[i];
79 for (
int j = 0; j < BaseDefs::MAXPAR; ++j) {
80 cov[i][j] = source.cov[i][j];
81 covinv[i][j] = source.covinv[i][j];
96 const double BaseFitObject::eps2 = 0.0001;
100 if (name_ ==
nullptr)
return;
101 size_t l = strlen(name_);
102 if (name)
delete[] name;
103 name =
new char[l + 1];
109 return name ? name :
"???";
140 for (
int i = 0; i <
getNPar(); ++i) {
141 if (i > 0) os <<
", ";
154 for (
int i = 0; i <
getNPar(); ++i) {
155 for (
int j = 0; j <
getNPar(); ++j) {
156 if (i > 0 && j == 0) os <<
",";
157 os <<
" " <<
getRho(i, j);
160 os <<
"}" << std::endl;
168 for (
int i = 0; i < BaseDefs::nMetaVars[metaSet]; ++i) {
169 for (
int j = 0; j <
getNPar(); ++j) {
170 if (i > 0 && j == 0) os <<
",";
171 os <<
" " << getFirstDerivative_Meta_Local(i, j, metaSet);
174 os <<
"#" << std::endl;
182 for (
int i = 0; i < BaseDefs::nMetaVars[metaSet]; ++i) {
183 if (i > 0) os << std::endl <<
" ";
184 for (
int j = 0; j <
getNPar(); ++j) {
185 for (
int k = 0; k <
getNPar(); ++k) {
187 os <<
" " << getSecondDerivative_Meta_Local(i, j, k, metaSet);
188 if (k ==
getNPar() - 1) os <<
",";
192 os <<
"##" << std::endl;
200 for (
int ilocal = 0; ilocal <
getNPar(); ++ilocal) {
203 assert(iglobal >= 0 && iglobal < idim);
207 bool thisresult =
setParam(ilocal, p[iglobal]);
208 result = result || thisresult;
219 for (
int ilocal = 0; ilocal <
getNPar(); ++ilocal) {
222 assert(iglobal >= 0 && iglobal < idim);
223 int ioffs = idim * iglobal;
224 for (
int jlocal = 0; jlocal <
getNPar(); ++jlocal) {
227 assert(jglobal >= 0 && jglobal < idim);
228 globCov[ioffs + jglobal] +=
getCov(ilocal, jlocal);
242 gsl_matrix* covm = gsl_matrix_alloc(n, n);
243 gsl_matrix_set_identity(covm);
245 for (
int i = 0; i < n; ++i) {
247 for (
int j = 0; j < n; ++j) {
249 gsl_matrix_set(covm, i, j,
cov[i][j]);
254 gsl_error_handler_t* e = gsl_set_error_handler_off();
255 int result = gsl_linalg_cholesky_decomp(covm);
256 if (result == 0) result = gsl_linalg_cholesky_invert(covm);
257 gsl_set_error_handler(e);
259 for (
int i = 0; i < n; ++i) {
260 for (
int j = 0; j < i; ++j) {
261 covinv[i][j] =
covinv[j][i] = gsl_matrix_get(covm, i, j);
263 covinv[i][i] = gsl_matrix_get(covm, i, i);
266 gsl_matrix_free(covm);
270 B2WARNING(
"ERROR, COULD NOT INVERT COV MATR!");
273 for (
int i = 0; i < n; ++i) {
275 for (
int j = 0; j < n; ++j) {
277 B2INFO(
cov[i][j] <<
" ");
284 for (
int i = 0; i < n; ++i) {
286 for (
int j = 0; j < n; ++j) {
300 bool measured_,
bool fixed_)
302 assert(ilocal >= 0 && ilocal <
getNPar());
305 fixed[ilocal] = fixed_;
311 if (!isfinite(par_))
return true;
312 assert(ilocal >= 0 && ilocal <
getNPar());
313 if (
par[ilocal] == par_)
return false;
315 bool result = pow((par_ -
par[ilocal]), 2) > eps2 *
cov[ilocal][ilocal];
322 if (!isfinite(mpar_))
return false;
323 assert(ilocal >= 0 && ilocal <
getNPar());
324 if (
mpar[ilocal] == mpar_)
return true;
326 mpar[ilocal] = mpar_;
332 if (!isfinite(err_))
return false;
333 assert(ilocal >= 0 && ilocal <
getNPar());
336 cov[ilocal][ilocal] = err_ * err_;
342 if (!isfinite(cov_))
return false;
343 assert(ilocal >= 0 && ilocal <
getNPar());
344 assert(jlocal >= 0 && jlocal <
getNPar());
347 cov[ilocal][jlocal] =
cov[jlocal][ilocal] = cov_;
354 assert(ilocal >= 0 && ilocal <
getNPar());
355 return fixed [ilocal] = fix;
360 if (ilocal < 0 || ilocal >=
getNPar())
return false;
367 if (ilocal < 0 || ilocal >=
getNPar())
return -1;
373 assert(ilocal >= 0 && ilocal <
getNPar());
379 assert(ilocal >= 0 && ilocal <
getNPar());
385 assert(ilocal >= 0 && ilocal <
getNPar());
386 return std::sqrt(
cov[ilocal][ilocal]);
391 assert(ilocal >= 0 && ilocal <
getNPar());
392 assert(jlocal >= 0 && jlocal <
getNPar());
393 return cov[ilocal][jlocal];
398 assert(ilocal >= 0 && ilocal <
getNPar());
399 assert(jlocal >= 0 && jlocal <
getNPar());
400 return cov[ilocal][jlocal] / std::sqrt(
cov[ilocal][ilocal] *
cov[jlocal][jlocal]);
404 assert(ilocal >= 0 && ilocal <
getNPar());
410 assert(ilocal >= 0 && ilocal <
getNPar());
411 return fixed[ilocal];
418 static double resid[BaseDefs::MAXPAR];
419 static bool chi2contr[BaseDefs::MAXPAR];
420 for (
int i = 0; i <
getNPar(); ++i) {
423 B2INFO(
" BaseFitObject::getChi2() " << i <<
" " << resid[i] <<
" " <<
covinv[i][i]);
426 chi2 += resid[i] *
covinv[i][i] * resid[i];
427 for (
int j = 0; j <
getNPar(); ++j) {
428 if (j < i && chi2contr[j]) chi2 += 2 * resid[i] *
covinv[i][j] * resid[j];
437 assert(ilocal >= 0 && ilocal <
getNPar());
443 for (
int jlocal = 0; jlocal <
getNPar(); jlocal++)
445 result +=
covinv[ilocal][jlocal] * (
par[jlocal] -
mpar[jlocal]);
451 assert(ilocal >= 0 && ilocal <
getNPar());
452 assert(jlocal >= 0 && jlocal <
getNPar());
457 return 2 *
covinv[ilocal][jlocal];
465 for (
int ilocal = 0; ilocal <
getNPar(); ++ilocal) {
468 assert(iglobal >= 0 && iglobal < idim);
469 int ioffs = idim * iglobal;
470 for (
int jlocal = 0; jlocal <
getNPar(); ++jlocal) {
473 assert(jglobal >= 0 && jglobal < idim);
485 assert(
getNPar() <= BaseDefs::MAXPAR);
487 for (
int ilocal = 0; ilocal <
getNPar(); ++ilocal) {
490 assert(iglobal >= 0 && iglobal < idim);
499 double lambda,
double der[],
int metaSet)
const
503 for (
int ilocal = 0; ilocal <
getNPar(); ilocal++) {
506 assert(iglobal < idim);
507 for (
int j = 0; j < BaseDefs::nMetaVars[metaSet]; j++) {
508 y[iglobal] += lambda * der[j] * getFirstDerivative_Meta_Local(j, ilocal, metaSet);
515 void BaseFitObject::addTo1stDerivatives(
double M[],
int idim,
516 double der[],
int kglobal,
int metaSet)
const
519 for (
int ilocal = 0; ilocal <
getNPar(); ilocal++) {
522 for (
int j = 0; j < BaseDefs::nMetaVars[metaSet]; j++) {
523 double x = der[j] * getFirstDerivative_Meta_Local(j, ilocal, metaSet);
524 M[idim * kglobal + iglobal] += x;
525 M[idim * iglobal + kglobal] += x;
534 void BaseFitObject::addTo2ndDerivatives(
double der2[],
int idim,
535 double factor[],
int metaSet
541 for (
int ilocal = 0; ilocal <
getNPar(); ilocal++) {
543 if (iglobal < 0)
continue;
544 for (
int jlocal = ilocal; jlocal <
getNPar(); jlocal++) {
546 if (jglobal < 0)
continue;
548 for (
int imeta = 0; imeta < BaseDefs::nMetaVars[metaSet]; imeta++) {
549 sum += factor[imeta] * getSecondDerivative_Meta_Local(imeta, ilocal, jlocal, metaSet);
551 der2[idim * iglobal + jglobal] += sum;
552 if (iglobal != jglobal) der2[idim * jglobal + iglobal] += sum;
559 void BaseFitObject::addTo2ndDerivatives(
double M[],
int idim,
double lambda,
double der[],
int metaSet)
const
561 double factor[BaseDefs::MAXINTERVARS];
562 for (
int i = 0; i < BaseDefs::nMetaVars[metaSet]; i++) factor[i] = lambda * der[i];
563 addTo2ndDerivatives(M, idim, factor, metaSet);
587 void BaseFitObject::initCov()
589 for (
int i = 0; i <
getNPar(); ++i) {
590 for (
int j = 0; j <
getNPar(); ++j) {
591 cov[i][j] =
static_cast<double>(i == j);
597 double BaseFitObject::getError2(
double der[],
int metaSet)
const
601 for (
int i = 0; i < BaseDefs::nMetaVars[metaSet]; i++) {
602 for (
int j = 0; j < BaseDefs::nMetaVars[metaSet]; j++) {
604 for (
int k = 0; k <
getNPar(); k++) {
605 for (
int l = 0; l <
getNPar(); l++) {
606 cov_i_j += getFirstDerivative_Meta_Local(i, k, metaSet) *
cov[k][l] * getFirstDerivative_Meta_Local(j, l, metaSet);
609 totError += der[i] * der[j] * cov_i_j;
bool covinvvalid
flag for valid inverse covariance matrix
virtual ~BaseFitObject()
Virtual destructor.
virtual bool updateParams(double p[], int idim)
Read values from global vector, readjust vector; return: significant change.
BaseFitObject & operator=(const BaseFitObject &rhs)
Assignment.
virtual int getNPar() const =0
Get total number of parameters of this FitObject.
virtual void addToGlobalChi2DerMatrix(double *M, int idim) const
Add 2nd derivatives of chi squared to global derivative matrix.
BaseFitObject()
Default constructor.
bool fixed[BaseDefs::MAXPAR]
fixed flag
virtual BaseFitObject & assign(const BaseFitObject &source)
Assign from anther object, if of same type.
virtual double getError(int ilocal) const
Get error of parameter ilocal.
virtual double getRho(int ilocal, int jlocal) const
Get correlation coefficient between parameters ilocal and jlocal.
virtual std::ostream & printRhoValues(std::ostream &os) const
print the correlation coefficients
virtual int getNFixed() const
Get number of fixed parameters of this FitObject.
virtual bool setParam(int ilocal, double par_, bool measured_, bool fixed_=false)
Set value and measured flag of parameter i; return: significant change.
void setName(const char *name_)
Set object's name.
double covinv[BaseDefs::MAXPAR][BaseDefs::MAXPAR]
inverse pf local covariance matrix
virtual double getCov(int ilocal, int jlocal) const
Get covariance between parameters ilocal and jlocal.
virtual double getChi2() const
Get chi squared from measured and fitted parameters.
virtual double getD2Chi2DParam2(int ilocal, int jlocal) const
Get second derivative of chi squared w.r.t. parameters ilocal1 and ilocal2.
bool cachevalid
flag for valid cache
virtual bool fixParam(int ilocal, bool fix=true)
Fix a parameter (fix=true), or release it (fix=false)
int globalParNum[BaseDefs::MAXPAR]
global parameter number for each parameter
virtual bool setCov(int ilocal, int jlocal, double cov_)
Set covariance of parameters ilocal and jlocal; return: success.
virtual int getGlobalParNum(int ilocal) const
Get global parameter number of parameter ilocal.
virtual bool setMParam(int ilocal, double mpar_)
Set measured value of parameter ilocal; return: success.
virtual const char * getName() const
Get object's name.
virtual int getNUnmeasured() const
Get number of unmeasured parameters of this FitObject.
virtual std::ostream & print1stDerivatives(std::ostream &os) const
print the 1st derivatives wrt metaSet 0 (E, px, py, pz)
virtual bool isParamFixed(int ilocal) const
Returns whether parameter is fixed.
double par[BaseDefs::MAXPAR]
fit parameters
virtual std::ostream & print2ndDerivatives(std::ostream &os) const
print the 2nd derivatives wrt metaSet 0 (E, px, py, pz)
void invalidateCache() const
invalidate any cached quantities
double mpar[BaseDefs::MAXPAR]
measured parameters
virtual double getParam(int ilocal) const
Get current value of parameter ilocal.
double cov[BaseDefs::MAXPAR][BaseDefs::MAXPAR]
local covariance matrix
bool measured[BaseDefs::MAXPAR]
measured flag
virtual int addToGlobalChi2DerVector(double *y, int idim) const
Add derivatives of chi squared to global derivative vector.
virtual void addToGlobCov(double *glcov, int idim) const
Add covariance matrix elements to global covariance matrix of size idim x idim.
virtual std::ostream & printParams(std::ostream &os) const
print the parameters and errors
virtual bool calculateCovInv() const
Calculate the inverse of the covariance matrix.
virtual bool isParamMeasured(int ilocal) const
Get measured flag for parameter ilocal.
virtual bool setGlobalParNum(int ilocal, int iglobal)
Set number of parameter ilocal in global list return true signals OK.
virtual double getMParam(int ilocal) const
Get measured value of parameter ilocal.
virtual double getDChi2DParam(int ilocal) const
Get derivative of chi squared w.r.t. parameter ilocal.
virtual int getNFree() const
Get number of free parameters of this FitObject.
virtual int getNMeasured() const
Get number of measured parameters of this FitObject.
virtual bool setError(int ilocal, double err_)
Set error of parameter ilocal; return: success.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.