10#include <framework/logging/Logger.h>
12#include <analysis/dataobjects/Particle.h>
13#include <mdst/dataobjects/ECLCluster.h>
14#include <mdst/dataobjects/KLMCluster.h>
16#include <analysis/ClusterUtility/ClusterUtils.h>
18#include <analysis/VertexFitting/TreeFitter/RecoNeutral.h>
19#include <analysis/VertexFitting/TreeFitter/FitParams.h>
20#include <analysis/VertexFitting/TreeFitter/ErrCode.h>
21#include <analysis/VertexFitting/TreeFitter/Projection.h>
23#include <framework/gearbox/Const.h>
43 Eigen::Matrix<double, 1, 3> vertexToCluster = Eigen::Matrix<double, 1, 3>::Zero(1, 3);
44 for (
unsigned int i = 0; i < 3; ++i) {
48 const double distanceToMother = vertexToCluster.norm();
50 const double absMom = std::sqrt(energy * energy -
m_mass *
m_mass);
54 for (
unsigned int i = 0; i < 3; ++i) {
55 fitparams.
getStateVector()(momindex + i) = absMom * vertexToCluster(i) / distanceToMother;
58 return ErrCode(ErrCode::Status::success);
63 return ErrCode(ErrCode::Status::success);
72 const double factorX = 1000;
75 Eigen::Matrix<double, 4, 4>::Identity(4, 4) * factorE;
78 Eigen::Matrix<double, 3, 3>::Identity(3, 3) * factorX;
80 return ErrCode(ErrCode::Status::success);
85 ROOT::Math::XYZVector clusterCenter;
88 if (
m_particleSource == Belle2::Particle::EParticleSourceObject::c_KLMCluster) {
90 clusterCenter = cluster->getClusterPosition();
91 const double momentum = cluster->getMomentumMag();
94 TMatrixDSym cov7 = cluster->getError7x7();
95 for (
int row = 0; row < 3; ++row) {
96 for (
int col = 0; col < 3; ++col) {
105 }
else if (
m_particleSource == Belle2::Particle::EParticleSourceObject::c_ECLCluster) {
107 clusterCenter = cluster->getClusterPosition();
109 energy = cluster->getEnergy(clusterhypo);
114 Eigen::Matrix<double, 2, 2> covPhiTheta = Eigen::Matrix<double, 2, 2>::Zero(2, 2);
116 for (
int row = 0; row < 2; ++row) {
118 for (
int col = 0; col < 2; ++col) {
119 covPhiTheta(row, col) = cov_EPhiTheta[row + 1][col + 1];
124 const double R = cluster->getR();
125 const double theta = cluster->getPhi();
126 const double phi = cluster->getTheta();
128 const double st = std::sin(theta);
129 const double ct = std::cos(theta);
130 const double sp = std::sin(phi);
131 const double cp = std::cos(phi);
133 Eigen::Matrix<double, 2, 3> polarToCartesian = Eigen::Matrix<double, 2, 3>::Zero(2, 3);
136 polarToCartesian(0, 0) = -1. *
R * st * sp;
137 polarToCartesian(0, 1) =
R * st * cp;
138 polarToCartesian(0, 2) = 0;
140 polarToCartesian(1, 0) =
R * ct * cp;
141 polarToCartesian(1, 1) =
R * ct * sp;
142 polarToCartesian(1, 2) = -1. *
R * st;
144 m_covariance.block<3, 3>(0, 0) = polarToCartesian.transpose() * covPhiTheta * polarToCartesian;
158 if ((std::abs(p_vec.X()) >= std::abs(p_vec.Y())) && (std::abs(p_vec.X()) >= std::abs(p_vec.Z()))) {
162 }
else if ((std::abs(p_vec.Y()) >= std::abs(p_vec.X())) && (std::abs(p_vec.Y()) >= std::abs(p_vec.Z()))) {
166 }
else if ((std::abs(p_vec.Z()) >= std::abs(p_vec.Y())) && (std::abs(p_vec.Z()) >= std::abs(p_vec.X()))) {
171 B2ERROR(
"Could not estimate highest momentum for neutral particle constraint. Aborting this fit.\n px: "
172 << p_vec.X() <<
" py: " << p_vec.Y() <<
" pz: " << p_vec.Z() <<
" calculated from Ec: " <<
m_clusterPars(3));
173 return ErrCode(ErrCode::Status::photondimerror);
176 return ErrCode(ErrCode::Status::success);
198 const Eigen::Matrix<double, 1, 3> x_vertex = fitparams.
getStateVector().segment(posindex, 3);
199 const Eigen::Matrix<double, 1, 3> p_vec = fitparams.
getStateVector().segment(momindex, 3);
201 if (0 == p_vec[
m_i1]) {
return ErrCode(ErrCode::photondimerror); }
205 const double mom = p_vec.norm();
206 const double energy = std::sqrt(mom * mom +
m_mass *
m_mass);
209 Eigen::Matrix<double, 3, 1> residual3 = Eigen::Matrix<double, 3, 1>::Zero(3, 1);
215 Eigen::Matrix<double, 3, 4> P = Eigen::Matrix<double, 3, 4>::Zero(3, 4);
224 p.getResiduals().segment(0, 3) = residual3;
226 p.getV() = P *
m_covariance.selfadjointView<Eigen::Lower>() * P.transpose();
230 p.getH()(0, posindex +
m_i1) = p_vec[
m_i2] / p_vec[
m_i1];
231 p.getH()(0, posindex +
m_i2) = -1.0;
232 p.getH()(0, posindex +
m_i3) = 0;
234 p.getH()(1, posindex +
m_i1) = p_vec[
m_i3] / p_vec[
m_i1];
235 p.getH()(1, posindex +
m_i2) = 0;
236 p.getH()(1, posindex +
m_i3) = -1.0;
239 p.getH()(0, momindex +
m_i1) = p_vec[
m_i2] * elim / p_vec[
m_i1];
240 p.getH()(0, momindex +
m_i2) = -1. * elim;
241 p.getH()(0, momindex +
m_i3) = 0;
243 p.getH()(1, momindex +
m_i1) = p_vec[
m_i3] * elim / p_vec[
m_i1];
244 p.getH()(1, momindex +
m_i2) = 0;
245 p.getH()(1, momindex +
m_i3) = -1. * elim;
247 p.getH()(2, momindex +
m_i1) = -1. * p_vec[
m_i1] / mom;
248 p.getH()(2, momindex +
m_i2) = -1. * p_vec[
m_i2] / mom;
249 p.getH()(2, momindex +
m_i3) = -1. * p_vec[
m_i3] / mom;
251 return ErrCode(ErrCode::Status::success);
Class to provide momentum-related information from ECLClusters.
const TMatrixDSym GetCovarianceMatrix3x3FromCluster(const ECLCluster *cluster, int particleHypo=Const::photon.getPDGCode())
Returns 3x3 covariance matrix (E, theta, phi)
EHypothesisBit
The hypothesis bits for this ECLCluster (Connected region (CR) is split using this hypothesis.
Class to store reconstructed particles.
const KLMCluster * getKLMCluster() const
Returns the pointer to the KLMCluster object that was used to create this Particle (ParticleType == c...
const ECLCluster * getECLCluster() const
Returns the pointer to the ECLCluster object that was used to create this Particle (if ParticleType =...
ROOT::Math::XYZVector getMomentum() const
Returns momentum vector.
ECLCluster::EHypothesisBit getECLClusterEHypothesisBit() const
Returns the ECLCluster EHypothesisBit for this Particle.
abstract errorocode be aware that the default is success
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 posIndex() const
get vertex index (in statevector!)
const ParticleBase * mother() const
getMother() / hasMother()
class to store the projected residuals and the corresponding jacobian as well as the covariance matri...
Eigen::Matrix< double, 4, 4 > m_covariance
covariance (x_c,y_c,z_c,E_c) of measured pars
ErrCode initCovariance(FitParams &fitparams) const override
init covariance
RecoNeutral(Belle2::Particle *bc, const ParticleBase *mother)
constructor
ErrCode initParams()
update or init params
const float m_momentumScalingFactor
scale the momentum / energy by this correction factor
const int m_dim
dimension of residuals and 'width' of H
int m_i3
another random index
int m_i1
index with the highest momentum.
virtual ErrCode initParticleWithMother(FitParams &fitparams) override
init particle with mother
int m_i2
random other index
virtual ErrCode initMotherlessParticle(FitParams &fitparams) override
init particle without mother
bool m_init
was initialized
ErrCode projectRecoConstraint(const FitParams &fitparams, Projection &p) const override
project neutral particle constraint
const Belle2::Particle::EParticleSourceObject m_particleSource
(mdst) source of particle
const double m_mass
invariant mass
Eigen::Matrix< double, 1, 4 > m_clusterPars
constrains measured params (x_c, y_c, z_c, E_c)
virtual int momIndex() const override
get momentum index
RecoParticle(Belle2::Particle *bc, const ParticleBase *mother)
constructor