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>
28 const bool useReferencing
31 m_decaychain(nullptr),
35 m_updateDaugthers(updateDaughters),
38 m_useReferencing(useReferencing),
53 const int nitermax = 100;
54 const int maxndiverging = 3;
55 const double dChisqConv =
m_prec;
59 if (
m_status == VertexStatus::UnFitted) {
68 bool finished =
false;
70 for (niter = 0; niter < nitermax && !finished; ++niter) {
87 if ((std::abs(deltachisq) /
m_chiSquare < dChisqConv)) {
92 }
else if (deltachisq > 0 && ++ndiverging >= maxndiverging) {
94 m_status = VertexStatus::NonConverged;
105 if (niter == nitermax &&
m_status != VertexStatus::Success) {
107 m_status = VertexStatus::NonConverged;
115 if (
m_status == VertexStatus::Success) {
124 return (
m_status == VertexStatus::Success);
130 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> cov =
m_fitparams->
getCovariance().selfadjointView<Eigen::Lower>();
133 if (posindex < 0 && pb->mother()) {
140 for (
int row = 0; row < 4; ++row) {
141 for (
int col = 0; col < 4; ++col) {
142 returncov(row, col) = cov(momindex + row, momindex + col);
146 for (
int row = 0; row < 3; ++row) {
147 for (
int col = 0; col < 3; ++col) {
148 returncov(row + 4, col + 4) = cov(posindex + row, posindex + col);
153 Eigen::Matrix<double, 6, 6> cov6 =
154 Eigen::Matrix<double, 6, 6>::Zero(6, 6);
156 for (
int row = 0; row < 3; ++row) {
157 for (
int col = 0; col < 3; ++col) {
158 cov6(row, col) = cov(momindex + row, momindex + col);
159 cov6(row + 3, col + 3) = cov(posindex + row, posindex + col);
164 Eigen::Matrix<double, 3, 1> momVec =
167 double energy2 = momVec.transpose() * momVec;
168 energy2 += mass * mass;
169 double energy = sqrt(energy2);
171 Eigen::Matrix<double, 7, 6> jacobian =
172 Eigen::Matrix<double, 7, 6>::Zero(7, 6);
174 for (
int col = 0; col < 3; ++col) {
175 jacobian(col, col) = 1;
177 jacobian(col + 4, col + 3) = 1;
180 Eigen::Matrix<double, 7, 7> cov7
181 = jacobian * cov6.selfadjointView<Eigen::Lower>() * jacobian.transpose();
183 for (
int row = 0; row < 7; ++row) {
184 for (
int col = 0; col < 7; ++col) {
185 returncov(row, col) = cov7(row, col);
199 return pb !=
nullptr;
206 if (posindex < 0 && pb.
mother()) {
220 cand.
writeExtraInfo(
"modifiedPValue", TMath::Prob(fitparchi2, 3));
225 if (motherPosIndex >= 0) {
235 ROOT::Math::PxPyPzEVector p;
244 p.SetE(std::sqrt(p.P2() + mass * mass));
247 TMatrixFSym cov7b2(7);
254 const std::tuple<double, double>life =
getLifeTime(cand);
264 const bool updateableMother =
updateCand(cand, isTreeHead);
266 if (updateableMother and not cand.
hasExtraInfo(
"bremsCorrected") and
267 not(cand.
hasExtraInfo(
"treeFitterTreatMeAsInvisible") and cand.
getExtraInfo(
"treeFitterTreatMeAsInvisible") == 1)) {
269 for (
int i = 0; i < ndaughters; i++) {
281 const int momindex = pb->
momIndex();
282 const int tauIndex = pb->
tauIndex();
286 Eigen::Matrix<double, 4, 4> comb_cov = Eigen::Matrix<double, 4, 4>::Zero(4, 4);
290 const double lenErr = std::get<1>(lenTuple);
291 comb_cov(0, 0) = lenErr * lenErr;
296 comb_cov.block<3, 3>(1, 1) = mom_cov;
300 const double mom = mom_vec.norm();
301 const double mom3 = mom * mom * mom;
303 const double len = std::get<0>(lenTuple);
304 const double t = len / mom * mBYc;
306 Eigen::Matrix<double, 1, 4> jac = Eigen::Matrix<double, 1, 4>::Zero();
307 jac(0) = 1. / mom * mBYc;
308 jac(1) = -1. * len * mom_vec(0) / mom3 * mBYc;
309 jac(2) = -1. * len * mom_vec(1) / mom3 * mBYc;
310 jac(3) = -1. * len * mom_vec(2) / mom3 * mBYc;
312 const double tErr2 = jac * comb_cov.selfadjointView<Eigen::Lower>() * jac.transpose();
314 return std::make_tuple(t, std::sqrt(tErr2));
316 return std::make_tuple(-999, -999);
328 const int tauindex = pb->
tauIndex();
330 const double lenErr2 = fitparams.
getCovariance()(tauindex, tauindex);
331 return std::make_tuple(len, std::sqrt(lenErr2));
333 return std::make_tuple(-999, -999);
338 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
const std::vector< int > m_massConstraintListPDG
list of pdg codes to mass constrain
this class does a lot of stuff: Build decaytree structure allowing to index particles and handle the ...
ErrCode initialize(FitParams &par)
initialize the chain
const ParticleBase * locate(Belle2::Particle *bc) const
convert Belle2::particle into particle base(fitter base particle)
int dim() const
get dimension
const ParticleBase * cand()
get candidate
ErrCode filterWithReference(FitParams &par, const FitParams &ref)
filter with respect to a previous iteration for better stability
ErrCode filter(FitParams &par)
filter down the chain
abstract errorocode be aware that the default is success
bool failure() const
returns true if errorcode is error
void reset()
reset the errorcode to default (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
bool m_useReferencing
use referencing
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
bool testCovariance() const
test if the covariance makes sense
double chiSquare() const
get chi2 of statevector
int nDof() const
get number of degrees of freedom
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 void forceP4Sum(FitParams &) const
force p4 sum conservation all along the tree
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()