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) {
 
   79           for (
int j = 0; j < BaseDefs::MAXPAR; ++j) {
 
   80             cov[i][j] = source.
cov[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) {
 
  288                 B2INFO(
cov[i][j] / sqrt(
cov[i][i]*
cov[j][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.
Abstract base class for different kinds of events.