17#include "analysis/OrcaKinFit/SoftGaussParticleConstraint.h"
18#include "analysis/OrcaKinFit/ParticleFitObject.h"
19#include <framework/logging/Logger.h>
29 namespace OrcaKinFit {
44 if (sigma_ != 0)
sigma = std::abs(sigma_);
58 for (
unsigned int i = 0; i <
fitobjects.size(); ++i) {
62 error2 += foi->getError2(dgdpi, getVarBasis());
65 return std::sqrt(std::abs(error2));
102 double fact = 2 *
getValue() / (s * s);
106 double d2GdPidPj[16];
113 auto* dPidAk =
new double[n * KMAX * 4];
114 bool* dPidAkval =
new bool[n];
116 for (
int i = 0; i < n; ++i) dPidAkval[i] =
false;
120 double d2GdPdAl[4 * KMAX];
122 double d2GdAkdAl[KMAX * KMAX] = {0};
126 int* parglobal =
new int[KMAX * n];
128 for (
int i = 0; i < n; ++i) {
131 for (
int klocal = 0; klocal < foi->
getNPar(); ++klocal) {
137 for (
int i = 0; i < n; ++i) {
140 for (
int j = 0; j < n; ++j) {
145 foi->getDerivatives(dPidAk + i * (KMAX * 4), KMAX * 4);
149 foj->getDerivatives(dPidAk + j * (KMAX * 4), KMAX * 4);
159 for (
int llocal = 0; llocal < foj->
getNPar(); ++llocal) {
160 for (
int ii = 0; ii < 4; ++ii) {
162 int ind2 = (KMAX * 4) * j + 4 * llocal;
163 double& r = d2GdPdAl[4 * llocal + ii];
164 r = d2GdPidPj[ ind1] * dPidAk[ ind2];
165 r += d2GdPidPj[++ind1] * dPidAk[++ind2];
166 r += d2GdPidPj[++ind1] * dPidAk[++ind2];
167 r += d2GdPidPj[++ind1] * dPidAk[++ind2];
176 for (
int klocal = 0; klocal < foi->
getNPar(); ++klocal) {
177 for (
int llocal = 0; llocal < foj->
getNPar(); ++llocal) {
178 int ind1 = 4 * llocal;
179 int ind2 = (KMAX * 4) * i + 4 * klocal;
180 double& r = d2GdAkdAl[KMAX * klocal + llocal];
181 r = d2GdPdAl[ ind1] * dPidAk[ ind2];
182 r += d2GdPdAl[++ind1] * dPidAk[++ind2];
183 r += d2GdPdAl[++ind1] * dPidAk[++ind2];
184 r += d2GdPdAl[++ind1] * dPidAk[++ind2];
188 for (
int klocal = 0; klocal < foi->
getNPar(); ++klocal) {
189 int kglobal = parglobal [KMAX * i + klocal];
190 for (
int llocal = 0; llocal < foj->
getNPar(); ++llocal) {
191 int lglobal = parglobal [KMAX * j + llocal];
192 M [idim * kglobal + lglobal] += fact * d2GdAkdAl[KMAX * klocal + llocal];
216 auto* v =
new double[idim];
217 for (
int i = 0; i < idim; ++i) v[i] = 0;
218 double sqrtfact2 =
sqrt(2.0) / s;
221 for (
int i = 0; i < n; ++i) {
225 foi->addTo2ndDerivatives(M, idim, fact, dgdpi, getVarBasis());
230 for (
int i = 0; i < idim; ++i) {
231 if (
double vi = v[i]) {
232 int ioffs = i * idim;
233 for (
double* pvj = v; pvj < v + idim; ++pvj) {
234 M[ioffs++] += vi * (*pvj);
250 double r = 2 *
getValue() / (s * s);
251 for (
unsigned int i = 0; i <
fitobjects.size(); ++i) {
260 void SoftGaussParticleConstraint::test1stDerivatives()
262 B2INFO(
"SoftGaussParticleConstraint::test1stDerivatives for " <<
getName());
264 for (
double& i : y) i = 0;
266 double eps = 0.00001;
267 for (
unsigned int ifo = 0; ifo <
fitobjects.size(); ++ifo) {
270 for (
int ilocal = 0; ilocal < fo->
getNPar(); ++ilocal) {
272 double calc = y[iglobal];
274 B2INFO(
"fo: " << fo->
getName() <<
" par " << ilocal <<
"/"
276 <<
") calc: " << calc <<
" - num: " << num <<
" = " << calc - num);
280 void SoftGaussParticleConstraint::test2ndDerivatives()
282 B2INFO(
"SoftGaussParticleConstraint::test2ndDerivatives for " <<
getName());
283 const int idim = 100;
284 auto* M =
new double[idim * idim];
285 for (
int i = 0; i < idim * idim; ++i) M[i] = 0;
288 B2INFO(
"eps=" << eps);
290 for (
unsigned int ifo1 = 0; ifo1 <
fitobjects.size(); ++ifo1) {
293 for (
unsigned int ifo2 = ifo1; ifo2 <
fitobjects.size(); ++ifo2) {
296 for (
int ilocal1 = 0; ilocal1 < fo1->getNPar(); ++ilocal1) {
297 int iglobal1 = fo1->getGlobalParNum(ilocal1);
298 for (
int ilocal2 = (ifo1 == ifo2 ? ilocal1 : 0); ilocal2 < fo2->getNPar(); ++ilocal2) {
299 int iglobal2 = fo2->getGlobalParNum(ilocal2);
300 double calc = M[idim * iglobal1 + iglobal2];
302 B2INFO(
"fo1: " << fo1->getName() <<
" par " << ilocal1 <<
"/"
303 << iglobal1 <<
" (" << fo1->getParamName(ilocal1)
304 <<
"), fo2: " << fo2->getName() <<
" par " << ilocal2 <<
"/"
305 << iglobal2 <<
" (" << fo2->getParamName(ilocal2)
306 <<
") calc: " << calc <<
" - num: " << num <<
" = " << calc - num);
324 double result = (v1 - v2) / (2 * eps);
330 int ifo2,
int ilocal2,
double eps2)
334 if (ifo1 == ifo2 && ilocal1 == ilocal2) {
337 double save = fo->
getParam(ilocal1);
343 result = (v1 + v2 - 2 * v0) / (eps1 * eps1);
350 double save1 = fo1->
getParam(ilocal1);
351 double save2 = fo2->
getParam(ilocal2);
352 fo1->
setParam(ilocal1, save1 + eps1);
353 fo2->
setParam(ilocal2, save2 + eps2);
355 fo2->
setParam(ilocal2, save2 - eps2);
357 fo1->
setParam(ilocal1, save1 - eps1);
359 fo2->
setParam(ilocal2, save2 + eps2);
361 result = (v11 + v22 - v12 - v21) / (4 * eps1 * eps2);
368 int SoftGaussParticleConstraint::getVarBasis()
const
virtual const char * getName() const
Returns the name of the constraint.
virtual int getNPar() const =0
Get total number of parameters of this FitObject.
virtual const char * getParamName(int ilocal) const =0
Get name of parameter ilocal.
virtual bool setParam(int ilocal, double par_, bool measured_, bool fixed_=false)
Set value and measured flag of parameter i; return: significant change.
virtual int getGlobalParNum(int ilocal) const
Get global parameter number of parameter ilocal.
virtual const char * getName() const
Get object's name.
virtual double getParam(int ilocal) const
Get current value of parameter ilocal.
virtual int addToGlobalChi2DerVector(double *y, int idim) const
Add derivatives of chi squared to global derivative vector.
virtual double getValue() const override=0
Returns the value of the constraint function.
FitObjectContainer fitobjects
The FitObjectContainer.
virtual void add2ndDerivativesToMatrix(double *M, int idim) const override
Adds second order derivatives to global covariance matrix M.
virtual double getError() const override
Returns the error on the value of the constraint.
double sigma
The sigma of the Gaussian.
virtual void addToGlobalChi2DerVector(double *y, int idim) const override
Add derivatives of chi squared to global derivative matrix.
virtual bool secondDerivatives(int i, int j, double *derivatives) const =0
Second derivatives with respect to the 4-vectors of Fit objects i and j; result false if all derivati...
virtual bool firstDerivatives(int i, double *derivatives) const =0
First derivatives with respect to the 4-vector of Fit objects i; result false if all derivatives are ...
void invalidateCache() const
Invalidates any cached values for the next event.
virtual double setSigma(double sigma_)
Sets the sigma.
virtual double getSigma() const
Returns the sigma.
SoftGaussParticleConstraint(double sigma_)
Creates an empty SoftGaussParticleConstraint object.
double num2ndDerivative(int ifo1, int ilocal1, double eps1, int ifo2, int ilocal2, double eps2)
Evaluates numerically the 2nd derivative w.r.t. 2 parameters.
virtual double getChi2() const override
Returns the chi2.
double num1stDerivative(int ifo, int ilocal, double eps)
Evaluates numerically the 1st derivative w.r.t. a parameter.
double sqrt(double a)
sqrt for double
Abstract base class for different kinds of events.