10#include <TMatrixFSym.h>
12#include <analysis/utility/ROOTToCLHEP.h>
13#include <analysis/VertexFitting/KFit/KFitBase.h>
17using namespace Belle2::analysis;
47KFitBase::addTrack(
const CLHEP::HepLorentzVector& p,
const HepPoint3D& x,
const CLHEP::HepSymMatrix& e,
const double q) {
62 ROOTToCLHEP::getHepLorentzVector(particle->
get4Vector()),
63 ROOTToCLHEP::getPoint3D(particle->
getVertex()),
153const HepLorentzVector
204 const int idx1 = id1 < id2 ? id1 : id2, idx2 = id1 < id2 ? id2 : id1;
208 for (
int i = 0; i < idx1; i++) index +=
m_TrackCount - 1 - i;
230 for (
int i = 0; i < 3; i++)
for (
int j = i; j < 3; j++) {
232 hsm[4 + i][4 + j] = e[3 + i][3 + j];
234 for (
int i = 0; i < 3; i++)
for (
int j = 0; j < 3; j++) {
235 hsm[i][4 + j] = e[i][3 + j];
238 const double invE = 1 / p.t();
239 hsm[0][3] = (p.x() * hsm[0][0] + p.y() * hsm[0][1] + p.z() * hsm[0][2]) * invE;
240 hsm[1][3] = (p.x() * hsm[0][1] + p.y() * hsm[1][1] + p.z() * hsm[1][2]) * invE;
241 hsm[2][3] = (p.x() * hsm[0][2] + p.y() * hsm[1][2] + p.z() * hsm[2][2]) * invE;
242 hsm[3][3] = (p.x() * p.x() * hsm[0][0] + p.y() * p.y() * hsm[1][1] + p.z() * p.z() * hsm[2][2]
243 + 2.0 * p.x() * p.y() * hsm[0][1]
244 + 2.0 * p.x() * p.z() * hsm[0][2]
245 + 2.0 * p.y() * p.z() * hsm[1][2]) * invE * invE;
246 hsm[3][4] = (p.x() * hsm[0][4] + p.y() * hsm[1][4] + p.z() * hsm[2][4]) * invE;
247 hsm[3][5] = (p.x() * hsm[0][5] + p.y() * hsm[1][5] + p.z() * hsm[2][5]) * invE;
248 hsm[3][6] = (p.x() * hsm[0][6] + p.y() * hsm[1][6] + p.z() * hsm[2][6]) * invE;
255KFitBase::makeError1(
const CLHEP::HepLorentzVector& p1,
const CLHEP::HepLorentzVector& p2,
const CLHEP::HepMatrix& e)
const
265 for (
int i = 0; i < 3; i++)
for (
int j = 0; j < 3; j++) {
267 hm[4 + i][4 + j] = e[3 + i][3 + j];
268 hm[4 + i][j] = e[3 + i][j];
269 hm[i][4 + j] = e[i][3 + j];
272 const double invE1 = 1 / p1.t();
273 const double invE2 = 1 / p2.t();
274 hm[0][3] = (p2.x() * hm[0][0] + p2.y() * hm[0][1] + p2.z() * hm[0][2]) * invE2;
275 hm[1][3] = (p2.x() * hm[1][0] + p2.y() * hm[1][1] + p2.z() * hm[1][2]) * invE2;
276 hm[2][3] = (p2.x() * hm[2][0] + p2.y() * hm[2][1] + p2.z() * hm[2][2]) * invE2;
277 hm[4][3] = (p2.x() * hm[4][0] + p2.y() * hm[4][1] + p2.z() * hm[4][2]) * invE2;
278 hm[5][3] = (p2.x() * hm[5][0] + p2.y() * hm[5][1] + p2.z() * hm[5][2]) * invE2;
279 hm[6][3] = (p2.x() * hm[6][0] + p2.y() * hm[6][1] + p2.z() * hm[6][2]) * invE2;
280 hm[3][3] = (p1.x() * p2.x() * hm[0][0] + p1.y() * p2.y() * hm[1][1] + p1.z() * p2.z() * hm[2][2] +
281 p1.x() * p2.y() * hm[0][1] + p2.x() * p1.y() * hm[1][0] +
282 p1.x() * p2.z() * hm[0][2] + p2.x() * p1.z() * hm[2][0] +
283 p1.y() * p2.z() * hm[1][2] + p2.y() * p1.z() * hm[2][1]) * invE1 * invE2;
284 hm[3][0] = (p1.x() * hm[0][0] + p1.y() * hm[1][0] + p1.z() * hm[2][0]) * invE1;
285 hm[3][1] = (p1.x() * hm[0][1] + p1.y() * hm[1][1] + p1.z() * hm[2][1]) * invE1;
286 hm[3][2] = (p1.x() * hm[0][2] + p1.y() * hm[1][2] + p1.z() * hm[2][2]) * invE1;
287 hm[3][4] = (p1.x() * hm[0][4] + p1.y() * hm[1][4] + p1.z() * hm[2][4]) * invE1;
288 hm[3][5] = (p1.x() * hm[0][5] + p1.y() * hm[1][5] + p1.z() * hm[2][5]) * invE1;
289 hm[3][6] = (p1.x() * hm[0][6] + p1.y() * hm[1][6] + p1.z() * hm[2][6]) * invE1;
305 for (
int i = 0; i < 3; i++)
for (
int j = 0; j < 3; j++) {
307 hm[i][4 + j] = e[i][3 + j];
310 const double invE = 1 / p.t();
311 hm[0][3] = (p.x() * hm[0][0] + p.y() * hm[0][1] + p.z() * hm[0][2]) * invE;
312 hm[1][3] = (p.x() * hm[1][0] + p.y() * hm[1][1] + p.z() * hm[1][2]) * invE;
313 hm[2][3] = (p.x() * hm[2][0] + p.y() * hm[2][1] + p.z() * hm[2][2]) * invE;
331 for (
int i = 0; i < 7; i++)
for (
int j = i; j < 7; j++) {
339 for (
int i = 0; i < 7; i++) {
341 for (
int j = i; j < 7; j++) hsm[i][j] = e[i][j];
344 double invE = 1 / p.t();
345 hsm[0][3] = (p.x() * hsm[0][0] + p.y() * hsm[0][1] + p.z() * hsm[0][2]) * invE;
346 hsm[1][3] = (p.x() * hsm[0][1] + p.y() * hsm[1][1] + p.z() * hsm[1][2]) * invE;
347 hsm[2][3] = (p.x() * hsm[0][2] + p.y() * hsm[1][2] + p.z() * hsm[2][2]) * invE;
348 hsm[3][3] = (p.x() * p.x() * hsm[0][0] + p.y() * p.y() * hsm[1][1] + p.z() * p.z() * hsm[2][2]
349 + 2.0 * p.x() * p.y() * hsm[0][1]
350 + 2.0 * p.x() * p.z() * hsm[0][2]
351 + 2.0 * p.y() * p.z() * hsm[1][2]) * invE * invE;
352 hsm[3][4] = (p.x() * hsm[0][4] + p.y() * hsm[1][4] + p.z() * hsm[2][4]) * invE;
353 hsm[3][5] = (p.x() * hsm[0][5] + p.y() * hsm[1][5] + p.z() * hsm[2][5]) * invE;
354 hsm[3][6] = (p.x() * hsm[0][6] + p.y() * hsm[1][6] + p.z() * hsm[2][6]) * invE;
361KFitBase::makeError3(
const CLHEP::HepLorentzVector& p1,
const CLHEP::HepLorentzVector& p2,
const CLHEP::HepMatrix& e,
362 const bool is_fix_mass1,
363 const bool is_fix_mass2)
const
370 if (is_fix_mass1 && is_fix_mass2) {
376 const double invE1 = 1 / p1.t();
377 const double invE2 = 1 / p2.t();
378 hm[0][3] = (p2.x() * hm[0][0] + p2.y() * hm[0][1] + p2.z() * hm[0][2]) * invE2;
379 hm[1][3] = (p2.x() * hm[1][0] + p2.y() * hm[1][1] + p2.z() * hm[1][2]) * invE2;
380 hm[2][3] = (p2.x() * hm[2][0] + p2.y() * hm[2][1] + p2.z() * hm[2][2]) * invE2;
381 hm[4][3] = (p2.x() * hm[4][0] + p2.y() * hm[4][1] + p2.z() * hm[4][2]) * invE2;
382 hm[5][3] = (p2.x() * hm[5][0] + p2.y() * hm[5][1] + p2.z() * hm[5][2]) * invE2;
383 hm[6][3] = (p2.x() * hm[6][0] + p2.y() * hm[6][1] + p2.z() * hm[6][2]) * invE2;
384 hm[3][0] = (p1.x() * hm[0][0] + p1.y() * hm[1][0] + p1.z() * hm[2][0]) * invE1;
385 hm[3][1] = (p1.x() * hm[0][1] + p1.y() * hm[1][1] + p1.z() * hm[2][1]) * invE1;
386 hm[3][2] = (p1.x() * hm[0][2] + p1.y() * hm[1][2] + p1.z() * hm[2][2]) * invE1;
387 hm[3][3] = (p1.x() * p2.x() * hm[0][0] + p1.y() * p2.y() * hm[1][1] + p1.z() * p2.z() * hm[2][2] +
388 p1.x() * p2.y() * hm[0][1] + p2.x() * p1.y() * hm[1][0] +
389 p1.x() * p2.z() * hm[0][2] + p2.x() * p1.z() * hm[2][0] +
390 p1.y() * p2.z() * hm[1][2] + p2.y() * p1.z() * hm[2][1]) * invE1 * invE2;
391 hm[3][4] = (p1.x() * hm[0][4] + p1.y() * hm[1][4] + p1.z() * hm[2][4]) * invE1;
392 hm[3][5] = (p1.x() * hm[0][5] + p1.y() * hm[1][5] + p1.z() * hm[2][5]) * invE1;
393 hm[3][6] = (p1.x() * hm[0][6] + p1.y() * hm[1][6] + p1.z() * hm[2][6]) * invE1;
399 if (is_fix_mass1 && !is_fix_mass2) {
404 const double invE1 = 1 / p1.t();
405 hm[3][0] = (p1.x() * hm[0][0] + p1.y() * hm[1][0] + p1.z() * hm[2][0]) * invE1;
406 hm[3][1] = (p1.x() * hm[0][1] + p1.y() * hm[1][1] + p1.z() * hm[2][1]) * invE1;
407 hm[3][2] = (p1.x() * hm[0][2] + p1.y() * hm[1][2] + p1.z() * hm[2][2]) * invE1;
408 hm[3][3] = (p1.x() * hm[0][3] + p1.y() * hm[1][3] + p1.z() * hm[2][3]) * invE1;
409 hm[3][4] = (p1.x() * hm[0][4] + p1.y() * hm[1][4] + p1.z() * hm[2][4]) * invE1;
410 hm[3][5] = (p1.x() * hm[0][5] + p1.y() * hm[1][5] + p1.z() * hm[2][5]) * invE1;
411 hm[3][6] = (p1.x() * hm[0][6] + p1.y() * hm[1][6] + p1.z() * hm[2][6]) * invE1;
417 if (!is_fix_mass1 && is_fix_mass2) {
422 const double invE2 = 1 / p2.t();
423 hm[0][3] = (p2.x() * hm[0][0] + p2.y() * hm[0][1] + p2.z() * hm[0][2]) * invE2;
424 hm[1][3] = (p2.x() * hm[1][0] + p2.y() * hm[1][1] + p2.z() * hm[1][2]) * invE2;
425 hm[2][3] = (p2.x() * hm[2][0] + p2.y() * hm[2][1] + p2.z() * hm[2][2]) * invE2;
426 hm[3][3] = (p2.x() * hm[3][0] + p2.y() * hm[3][1] + p2.z() * hm[3][2]) * invE2;
427 hm[4][3] = (p2.x() * hm[4][0] + p2.y() * hm[4][1] + p2.z() * hm[4][2]) * invE2;
428 hm[5][3] = (p2.x() * hm[5][0] + p2.y() * hm[5][1] + p2.z() * hm[5][2]) * invE2;
429 hm[6][3] = (p2.x() * hm[6][0] + p2.y() * hm[6][1] + p2.z() * hm[6][2]) * invE2;
449 const double invE = 1 / p.t();
450 hm[0][3] = (p.x() * hm[0][0] + p.y() * hm[0][1] + p.z() * hm[0][2]) * invE;
451 hm[1][3] = (p.x() * hm[1][0] + p.y() * hm[1][1] + p.z() * hm[1][2]) * invE;
452 hm[2][3] = (p.x() * hm[2][0] + p.y() * hm[2][1] + p.z() * hm[2][2]) * invE;
468 int row = 0, col = 0;
479 for (
int i = 0; i < 3; i++)
for (
int j = 0; j < 3; j++) {
480 tmp_hm[i][j] = hm[i][j];
481 tmp_hm[3 + i][3 + j] = hm[4 + i][4 + j];
482 tmp_hm[3 + i][j] = hm[4 + i][j];
483 tmp_hm[i][3 + j] = hm[i][4 + j];
520 HepMatrix tmp_al_1(
m_al_1);
524 HepMatrix tmp_al_a(
m_al_a);
532 if (err_inverse != 0) {
542 if (tmp_chisq <= chisq) {
597 HepMatrix tmp_al_a(
m_al_a);
599 HepMatrix tmp_D(
m_D), tmp_E(
m_E);
603 HepMatrix tmp2_D(
m_D), tmp2_E(
m_E);
633 if (tmp_chisq <= chisq) {
680 if (tmp2_chisq <= chisq) {
752 if (p.t() != 0)
return true;
Class to store reconstructed particles.
ROOT::Math::XYZVector getVertex() const
Returns vertex position (POCA for charged, IP for neutral FS particles)
double getCharge(void) const
Returns particle charge.
ROOT::Math::PxPyPzEVector get4Vector() const
Returns Lorentz vector.
TMatrixFSym getMomentumVertexErrorMatrix() const
Returns 7x7 error matrix.
KFitBase(void)
Construct an object with no argument.
int m_NecessaryTrackCount
Number needed tracks to perform fit.
virtual enum KFitError::ECode prepareInputMatrix(void)=0
Build grand matrices for minimum search from input-track properties.
enum KFitError::ECode addTrack(const KFitTrack &kp)
Add a track to the fitter object.
virtual enum KFitError::ECode prepareOutputMatrix(void)=0
Build an output error matrix.
double m_MagneticField
Magnetic field.
const CLHEP::HepSymMatrix makeError1(const CLHEP::HepLorentzVector &p, const CLHEP::HepMatrix &e) const
Rebuild an error matrix from a Lorentz vector and an error matrix.
bool isNonZeroEnergy(const CLHEP::HepLorentzVector &p) const
Check if the energy is non-zero.
CLHEP::HepMatrix m_al_1
See J.Tanaka Ph.D (2001) p136 for definition.
CLHEP::HepMatrix m_V_Dt
See J.Tanaka Ph.D (2001) p138 for definition.
virtual enum KFitError::ECode setCorrelation(const CLHEP::HepMatrix &c)
Set a correlation matrix.
const CLHEP::HepSymMatrix makeError3(const CLHEP::HepLorentzVector &p, const CLHEP::HepMatrix &e, const bool is_fix_mass) const
Rebuild an error matrix from a Lorentz vector and an error matrix.
const CLHEP::HepSymMatrix getTrackError(const int id) const
Get an error matrix of the track.
virtual double getCHIsq(void) const
Get a chi-square of the fit.
const CLHEP::HepLorentzVector getTrackMomentum(const int id) const
Get a Lorentz vector of the track.
CLHEP::HepMatrix m_lam
See J.Tanaka Ph.D (2001) p137 for definition.
double getMagneticField(void) const
Get a magnetic field.
enum KFitError::ECode doFit2(void)
Perform a fit (used in VertexFitKFit::doFit() and MassVertexFitKFit::doFit()).
CLHEP::HepMatrix m_E
See J.Tanaka Ph.D (2001) p137 for definition.
const HepPoint3D getTrackPosition(const int id) const
Get a position of the track.
bool m_FlagOverIteration
Flag whether the iteration count exceeds the limit.
virtual double getTrackCHIsq(const int id) const
Get a chi-square of the track.
enum KFitError::ECode m_ErrorCode
Error code.
virtual enum KFitError::ECode prepareInputSubMatrix(void)=0
Build sub-matrices for minimum search from input-track properties.
virtual enum KFitError::ECode setZeroCorrelation(void)
Indicate no correlation between tracks.
CLHEP::HepMatrix m_V_al_1
See J.Tanaka Ph.D (2001) p138 for definition.
virtual int getNDF(void) const
Get an NDF of the fit.
CLHEP::HepMatrix m_d
See J.Tanaka Ph.D (2001) p137 for definition.
CLHEP::HepMatrix m_lam0
See J.Tanaka Ph.D (2001) p138 for definition.
virtual ~KFitBase(void)
Destruct the object.
bool isFitted(void) const
Return false if fit is not performed yet or performed fit is failed; otherwise true.
CLHEP::HepMatrix m_al_a
See J.Tanaka Ph.D (2001) p137 for definition.
enum KFitError::ECode setMagneticField(const double mf)
Change a magnetic field from the default value KFitConst::kDefaultMagneticField.
CLHEP::HepMatrix m_D
See J.Tanaka Ph.D (2001) p137 for definition.
CLHEP::HepMatrix m_V_D
See J.Tanaka Ph.D (2001) p138 for definition.
bool isTrackIDInRange(const int id) const
Check if the id is in the range.
CLHEP::HepMatrix m_v_a
See J.Tanaka Ph.D (2001) p137 for definition.
virtual const CLHEP::HepMatrix getCorrelation(const int id1, const int id2, const int flag=KFitConst::kAfterFit) const
Get a correlation matrix between two tracks.
bool m_FlagCorrelation
Flag whether a correlation among tracks exists.
CLHEP::HepSymMatrix m_V_al_0
See J.Tanaka Ph.D (2001) p137 for definition.
CLHEP::HepMatrix m_V_E
See J.Tanaka Ph.D (2001) p138 for definition.
CLHEP::HepMatrix m_Cov_v_al_1
See J.Tanaka Ph.D (2001) p137 for definition.
const KFitTrack getTrack(const int id) const
Get a specified track object.
virtual enum KFitError::ECode prepareCorrelation(void)
Build a grand correlation matrix from input-track properties.
virtual enum KFitError::ECode makeCoreMatrix(void)=0
Build matrices using the kinematical constraint.
const CLHEP::HepMatrix makeError2(const CLHEP::HepLorentzVector &p, const CLHEP::HepMatrix &e) const
Rebuild an error matrix from a Lorentz vector and an error matrix.
enum KFitError::ECode addParticle(const Particle *particle)
Add a particle to the fitter.
std::vector< CLHEP::HepMatrix > m_BeforeCorrelation
Container of input correlation matrices.
bool m_FlagFitted
Flag to indicate if the fit is performed and succeeded.
double m_CHIsq
chi-square of the fit.
int getTrackCount(void) const
Get the number of added tracks.
std::vector< KFitTrack > m_Tracks
Container of input tracks.
CLHEP::HepMatrix m_v
See J.Tanaka Ph.D (2001) p137 for definition.
virtual enum KFitError::ECode calculateNDF(void)=0
Calculate an NDF of the fit.
const CLHEP::HepMatrix makeError4(const CLHEP::HepLorentzVector &p, const CLHEP::HepMatrix &e) const
Rebuild an error matrix from a Lorentz vector and an error matrix.
int m_TrackCount
Number of tracks.
CLHEP::HepMatrix m_al_0
See J.Tanaka Ph.D (2001) p136 for definition.
enum KFitError::ECode doFit1(void)
Perform a fit (used in MassFitKFit::doFit()).
enum KFitError::ECode getErrorCode(void) const
Get a code of the last error.
static void displayError(const char *file, const int line, const char *func, const enum ECode code)
Display a description of error and its location.
ECode
ECode is a error code enumerate.
@ kCannotGetMatrixInverse
Cannot calculate matrix inverse (bad track property or internal error)
@ kOutOfRange
Specified track-id out of range.
@ kNotFittedYet
Not fitted yet.
@ kDivisionByZero
Division by zero (bad track property or internal error)
@ kBadInitialCHIsq
Bad initial chi-square (internal error)
@ kBadTrackSize
Track count too small to perform fit.
@ kBadMatrixSize
Wrong correlation matrix size.
@ kBadCorrelationSize
Wrong correlation matrix size (internal error)
KFitTrack is a container of the track information (Lorentz vector, position, and error matrix),...
Abstract base class for different kinds of events.
static constexpr double kInitialCHIsq
Initial chi-square value (internal use)
static constexpr double kDefaultMagneticField
Default magnetic field when not set externally.
static const int kNumber6
Constant 6 to check matrix size (internal use)
static const int kMaxIterationCount
Maximum iteration step (internal use)
static const int kAfterFit
Input parameter to specify after-fit when setting/getting a track attribute.
static const int kBeforeFit
Input parameter to specify before-fit when setting/getting a track attribute.
static const int kNumber7
Constant 7 to check matrix size (internal use)