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>
30 m_decaychain(nullptr),
34 m_updateDaugthers(updateDaughters),
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) {
122 return (
m_status == VertexStatus::Success);
128 Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic> cov =
m_fitparams->
getCovariance().selfadjointView<Eigen::Lower>();
131 if (posindex < 0 && pb->mother()) {
138 for (
int row = 0; row < 4; ++row) {
139 for (
int col = 0; col < 4; ++col) {
140 returncov(row, col) = cov(momindex + row, momindex + col);
144 for (
int row = 0; row < 3; ++row) {
145 for (
int col = 0; col < 3; ++col) {
146 returncov(row + 4, col + 4) = cov(posindex + row, posindex + col);
151 Eigen::Matrix<double, 6, 6> cov6 =
152 Eigen::Matrix<double, 6, 6>::Zero(6, 6);
154 for (
int row = 0; row < 3; ++row) {
155 for (
int col = 0; col < 3; ++col) {
156 cov6(row, col) = cov(momindex + row, momindex + col);
157 cov6(row + 3, col + 3) = cov(posindex + row, posindex + col);
165 Eigen::Matrix<double, 3, 1> momVec =
168 double energy2 = momVec.transpose() * momVec;
169 energy2 += mass * mass;
170 double energy = sqrt(energy2);
172 Eigen::Matrix<double, 7, 6> jacobian =
173 Eigen::Matrix<double, 7, 6>::Zero(7, 6);
175 for (
int col = 0; col < 3; ++col) {
176 jacobian(col, col) = 1;
178 jacobian(col + 4, col + 3) = 1;
181 Eigen::Matrix<double, 7, 7> cov7
182 = jacobian * cov6.selfadjointView<Eigen::Lower>() * jacobian.transpose();
184 for (
int row = 0; row < 7; ++row) {
185 for (
int col = 0; col < 7; ++col) {
186 returncov(row, col) = cov7(row, col);
200 return pb !=
nullptr;
207 if (posindex < 0 && pb.
mother()) {
212 TMatrixFSym cov7b2(7);
222 cand.
writeExtraInfo(
"modifiedPValue", TMath::Prob(fitparchi2, 3));
227 if (motherPosIndex >= 0) {
232 if (not isTreeHead) {
252 ROOT::Math::PxPyPzEVector p;
261 if (cand.
hasExtraInfo(
"treeFitterMassConstraintValue")) {
262 mass = cand.
getExtraInfo(
"treeFitterMassConstraintValue");
264 p.SetE(std::sqrt(p.P2() + mass * mass));
273 const std::tuple<double, double>life =
getLifeTime(cand);
283 const bool updateableMother =
updateCand(cand, isTreeHead);
285 if (updateableMother and not cand.
hasExtraInfo(
"bremsCorrected") and
286 not(cand.
hasExtraInfo(
"treeFitterTreatMeAsInvisible") and cand.
getExtraInfo(
"treeFitterTreatMeAsInvisible") == 1)) {
288 for (
int i = 0; i < ndaughters; i++) {
300 const int momindex = pb->
momIndex();
301 const int tauIndex = pb->
tauIndex();
305 Eigen::Matrix<double, 4, 4> comb_cov = Eigen::Matrix<double, 4, 4>::Zero(4, 4);
309 const double lenErr = std::get<1>(lenTuple);
310 comb_cov(0, 0) = lenErr * lenErr;
315 comb_cov.block<3, 3>(1, 1) = mom_cov;
322 const double mom = mom_vec.norm();
323 const double mom3 = mom * mom * mom;
325 const double len = std::get<0>(lenTuple);
326 const double t = len / mom * mBYc;
328 Eigen::Matrix<double, 1, 4> jac = Eigen::Matrix<double, 1, 4>::Zero();
329 jac(0) = 1. / mom * mBYc;
330 jac(1) = -1. * len * mom_vec(0) / mom3 * mBYc;
331 jac(2) = -1. * len * mom_vec(1) / mom3 * mBYc;
332 jac(3) = -1. * len * mom_vec(2) / mom3 * mBYc;
334 const double tErr2 = jac * comb_cov.selfadjointView<Eigen::Lower>() * jac.transpose();
336 return std::make_tuple(t, std::sqrt(tErr2));
338 return std::make_tuple(-999, -999);
350 const int tauindex = pb->
tauIndex();
352 const double lenErr2 = fitparams.
getCovariance()(tauindex, tauindex);
353 return std::make_tuple(len, std::sqrt(lenErr2));
355 return std::make_tuple(-999, -999);
360 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
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()