10#include <Math/Vector4D.h>
12#include <analysis/dataobjects/Particle.h>
14#include <framework/logging/Logger.h>
15#include <framework/gearbox/Const.h>
17#include <analysis/VertexFitting/TreeFitter/FitManager.h>
18#include <analysis/VertexFitting/TreeFitter/FitParams.h>
19#include <analysis/VertexFitting/TreeFitter/DecayChain.h>
20#include <analysis/VertexFitting/TreeFitter/ParticleBase.h>
51 const int nitermax = 100;
52 const int maxndiverging = 3;
53 const double dChisqConv =
m_prec;
57 if (
m_status == VertexStatus::UnFitted) {
66 bool finished =
false;
68 for (niter = 0; niter < nitermax && !finished; ++niter) {
85 if ((std::abs(deltachisq) /
m_chiSquare < dChisqConv)) {
90 }
else if (deltachisq > 0 && ++ndiverging >= maxndiverging) {
92 m_status = VertexStatus::NonConverged;
103 if (niter == nitermax &&
m_status != VertexStatus::Success) {
105 m_status = VertexStatus::NonConverged;
113 if (
m_status == VertexStatus::Success) {
116 if (
m_config.m_massConstraintListPDG.size() != 0) {
122 return (
m_status == VertexStatus::Success);
131 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> cov =
m_fitparams->getCovariance().selfadjointView<Eigen::Lower>();
134 if (posindex < 0 && pb->mother()) {
141 for (
int row = 0; row < 4; ++row) {
142 for (
int col = 0; col < 4; ++col) {
143 returncov(row, col) = cov(momindex + row, momindex + col);
147 for (
int row = 0; row < 3; ++row) {
148 for (
int col = 0; col < 3; ++col) {
149 returncov(row + 4, col + 4) = cov(posindex + row, posindex + col);
154 Eigen::Matrix<double, 6, 6> cov6 =
155 Eigen::Matrix<double, 6, 6>::Zero(6, 6);
157 for (
int row = 0; row < 3; ++row) {
158 for (
int col = 0; col < 3; ++col) {
159 cov6(row, col) = cov(momindex + row, momindex + col);
160 cov6(row + 3, col + 3) = cov(posindex + row, posindex + col);
168 Eigen::Matrix<double, 3, 1> momVec =
169 m_fitparams->getStateVector().segment(momindex, 3);
171 double energy2 = momVec.transpose() * momVec;
172 energy2 += mass * mass;
173 double energy = sqrt(energy2);
175 Eigen::Matrix<double, 7, 6> jacobian =
176 Eigen::Matrix<double, 7, 6>::Zero(7, 6);
178 for (
int col = 0; col < 3; ++col) {
179 jacobian(col, col) = 1;
180 jacobian(3, col) =
m_fitparams->getStateVector()(momindex + col) / energy;
181 jacobian(col + 4, col + 3) = 1;
184 Eigen::Matrix<double, 7, 7> cov7
185 = jacobian * cov6.selfadjointView<Eigen::Lower>() * jacobian.transpose();
187 for (
int row = 0; row < 7; ++row) {
188 for (
int col = 0; col < 7; ++col) {
189 returncov(row, col) = cov7(row, col);
201 B2ERROR(
"Can't find candidate " << cand.
getName() <<
" in tree " <<
m_particle->getName());
203 return pb !=
nullptr;
210 if (posindex < 0 && pb.
mother()) {
215 TMatrixFSym cov7b2(7);
217 const ROOT::Math::XYZVector pos(
m_fitparams->getStateVector()(posindex),
222 const double fitparchi2 =
m_fitparams->chiSquare();
225 cand.
writeExtraInfo(
"modifiedPValue", TMath::Prob(fitparchi2, 3));
230 if (motherPosIndex >= 0) {
235 if (not isTreeHead) {
255 ROOT::Math::PxPyPzEVector p;
257 p.SetPy(
m_fitparams->getStateVector()(momindex + 1));
258 p.SetPz(
m_fitparams->getStateVector()(momindex + 2));
260 p.SetE(
m_fitparams->getStateVector()(momindex + 3));
264 if (cand.
hasExtraInfo(
"treeFitterMassConstraintValue")) {
265 mass = cand.
getExtraInfo(
"treeFitterMassConstraintValue");
267 p.SetE(std::sqrt(p.P2() + mass * mass));
276 const std::tuple<double, double>life =
getLifeTime(cand);
286 const bool updateableMother =
updateCand(cand, isTreeHead);
288 if (updateableMother and not cand.
hasExtraInfo(
"bremsCorrected") and
289 not(cand.
hasExtraInfo(
"treeFitterTreatMeAsInvisible") and cand.
getExtraInfo(
"treeFitterTreatMeAsInvisible") == 1)) {
291 for (
int i = 0; i < ndaughters; i++) {
303 const int momindex = pb->
momIndex();
304 const int tauIndex = pb->
tauIndex();
305 const Eigen::Matrix<double, 1, 3> mom_vec =
m_fitparams->getStateVector().segment(momindex, 3);
307 const Eigen::Matrix<double, 3, 3> mom_cov =
m_fitparams->getCovariance().block<3, 3>(momindex, momindex);
308 Eigen::Matrix<double, 4, 4> comb_cov = Eigen::Matrix<double, 4, 4>::Zero(4, 4);
312 const double lenErr = std::get<1>(lenTuple);
313 comb_cov(0, 0) = lenErr * lenErr;
314 comb_cov(1, 0) =
m_fitparams->getCovariance()(momindex, tauIndex);
315 comb_cov(2, 0) =
m_fitparams->getCovariance()(momindex + 1, tauIndex);
316 comb_cov(3, 0) =
m_fitparams->getCovariance()(momindex + 2, tauIndex);
318 comb_cov.block<3, 3>(1, 1) = mom_cov;
325 const double mom = mom_vec.norm();
326 const double mom3 = mom * mom * mom;
328 const double len = std::get<0>(lenTuple);
329 const double t = len / mom * mBYc;
331 Eigen::Matrix<double, 1, 4> jac = Eigen::Matrix<double, 1, 4>::Zero();
332 jac(0) = 1. / mom * mBYc;
333 jac(1) = -1. * len * mom_vec(0) / mom3 * mBYc;
334 jac(2) = -1. * len * mom_vec(1) / mom3 * mBYc;
335 jac(3) = -1. * len * mom_vec(2) / mom3 * mBYc;
337 const double tErr2 = jac * comb_cov.selfadjointView<Eigen::Lower>() * jac.transpose();
339 return std::make_tuple(t, std::sqrt(tErr2));
341 return std::make_tuple(-999, -999);
353 const int tauindex = pb->
tauIndex();
355 const double lenErr2 = fitparams.
getCovariance()(tauindex, tauindex);
356 return std::make_tuple(len, std::sqrt(lenErr2));
358 return std::make_tuple(-999, -999);
363 std::tuple<double, double> rc = std::make_tuple(-999, -999);
static const double speedOfLight
[cm/ns]
Class to store reconstructed particles.
std::string getName() const override
Return name of this particle.
void writeExtraInfo(const std::string &name, const double value)
Sets the user defined extraInfo.
void setVertex(const ROOT::Math::XYZVector &vertex)
Sets position (decay vertex)
void set4VectorDividingByMomentumScaling(const ROOT::Math::PxPyPzEVector &p4)
Sets Lorentz vector dividing by the momentum scaling factor.
bool hasExtraInfo(const std::string &name) const
Return whether the extra info with the given name is set.
unsigned getNDaughters(void) const
Returns number of daughter particles.
double getPDGMass(void) const
Returns uncertainty on the invariant mass (requires valid momentum error matrix)
void setMomentumVertexErrorMatrix(const TMatrixFSym &errMatrix)
Sets 7x7 error matrix.
void setPValue(double pValue)
Sets chi^2 probability of fit.
const Particle * getDaughter(unsigned i) const
Returns a pointer to the i-th daughter particle.
double getExtraInfo(const std::string &name) const
Return given value if set.
constraint configuration class
this class does a lot of stuff: Build decaytree structure allowing to index particles and handle the ...
abstract errorocode be aware that the default is success
const ConstraintConfiguration m_config
config container
DecayChain * m_decaychain
the decay tree
Belle2::Particle * particle()
getter for the head of the tree
ErrCode m_errCode
errorcode
void getCovFromPB(const ParticleBase *pb, TMatrixFSym &returncov) const
extract cov from particle base
void updateTree(Belle2::Particle &particle, const bool isTreeHead) const
update the Belle2::Particles with the fit results
FitParams * m_fitparams
parameters to be fitted
const bool m_updateDaugthers
if this is set all daughters will be updated otherwise only the head of the tree
~FitManager()
destructor does stuff
int m_ndf
number of degrees of freedom for this topology
double m_prec
precision that is needed for status:converged (delta chi2)
bool fit()
main fit function that uses the kalman filter
int m_status
status of the current iteration
Belle2::Particle * m_particle
head of the tree
double m_chiSquare
chi2 of the current iteration
VertexStatus
status flag of the fit-itereation (the step in the newton method)
std::tuple< double, double > getLifeTime(Belle2::Particle &cand) const
get lifetime
std::tuple< double, double > getDecayLength(const ParticleBase *pb) const
get decay length
bool updateCand(Belle2::Particle &particle, const bool isTreeHead) const
update particles parameters with the fit results
Class to store and manage fitparams (statevector)
Eigen::Matrix< double, -1, 1, 0, MAX_MATRIX_SIZE, 1 > & getStateVector()
getter for the fit parameters/statevector
Eigen::Matrix< double, -1, -1, 0, MAX_MATRIX_SIZE, MAX_MATRIX_SIZE > & getCovariance()
getter for the states covariance
base class for all particles
Belle2::Particle * particle() const
get basf2 particle
virtual int dim() const =0
get dimension of constraint
virtual int posIndex() const
get vertex index (in statevector!)
virtual int momIndex() const
get momentum index
virtual bool hasEnergy() const
get momentum dimension
virtual int tauIndex() const
get tau index
const ParticleBase * mother() const
getMother() / hasMother()