Belle II Software prerelease-10-00-00a
RecoPhoton.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * External Contributor: Wouter Hulsbergen *
5 * *
6 * See git log for contributors and copyright holders. *
7 * This file is licensed under LGPL-3.0, see LICENSE.md. *
8 **************************************************************************/
9
10#include <framework/logging/Logger.h>
11
12#include <analysis/dataobjects/Particle.h>
13#include <mdst/dataobjects/ECLCluster.h>
14
15#include <analysis/ClusterUtility/ClusterUtils.h>
16
17#include <analysis/VertexFitting/TreeFitter/RecoPhoton.h>
18#include <analysis/VertexFitting/TreeFitter/FitParams.h>
19#include <analysis/VertexFitting/TreeFitter/ErrCode.h>
20
21#include <framework/gearbox/Const.h>
22
23namespace TreeFitter {
24
35
37 {
38 const int posindexmother = mother()->posIndex();
39
40 Eigen::Matrix<double, 1, 3> vertexToCluster = Eigen::Matrix<double, 1, 3>::Zero(1, 3);
41 for (unsigned int i = 0; i < 3; ++i) {
42 vertexToCluster(i) = m_clusterPars(i) - fitparams.getStateVector()(posindexmother + i);
43 }
44
45 const double distanceToMother = vertexToCluster.norm();
46 const double energy = m_momentumScalingFactor * m_clusterPars(3); // apply scaling factor to correct energy bias
47 const int momindex = momIndex();
48
49 for (unsigned int i = 0; i < 3; ++i) {
50 // px = E dx/|dx|
51 fitparams.getStateVector()(momindex + i) = energy * vertexToCluster(i) / distanceToMother;
52 }
53
54 return ErrCode(ErrCode::Status::success);
55 }
56
58 {
59 return ErrCode(ErrCode::Status::success);
60 }
61
63 {
64 bool rc = true;
65 const int pdg = particle.getPDGCode();
66 if (pdg &&
69 rc = false;
70 }
71 return rc;
72 }
73
75 {
76 const int momindex = momIndex();
77 const int posindex = mother()->posIndex();
78
79 const double factorE = 1000 * m_covariance(3, 3);
80 const double factorX = 1000; // ~ 10cm error on initial vertex
81
82 fitparams.getCovariance().block<4, 4>(momindex, momindex) =
83 Eigen::Matrix<double, 4, 4>::Identity(4, 4) * factorE;
84
85 fitparams.getCovariance().block<3, 3>(posindex, posindex) =
86 Eigen::Matrix<double, 3, 3>::Identity(3, 3) * factorX;
87
88 return ErrCode(ErrCode::Status::success);
89 }
90
92 {
93 const Belle2::ECLCluster* cluster = particle()->getECLCluster();
95 const ROOT::Math::XYZVector centroid = cluster->getClusterPosition();
96 const double energy = cluster->getEnergy(clusterhypo);
97
98 m_init = true;
99 m_covariance = Eigen::Matrix<double, 4, 4>::Zero(4, 4);
101
102 TMatrixDSym cov_EPhiTheta = C.GetCovarianceMatrix3x3FromCluster(cluster);
103
104 Eigen::Matrix<double, 2, 2> covPhiTheta = Eigen::Matrix<double, 2, 2>::Zero(2, 2);
105
106 for (int row = 0; row < 2; ++row) {
107 // we go through all elements here instead of selfadjoint view later
108 for (int col = 0; col < 2; ++col) {
109 covPhiTheta(row, col) = cov_EPhiTheta[row + 1][col + 1];
110 }
111 }
112
113 // the in going x-E correlations are 0 so we don't fill them
114 const double R = cluster->getR();
115 const double theta = cluster->getPhi();
116 const double phi = cluster->getTheta();
117
118 const double st = std::sin(theta);
119 const double ct = std::cos(theta);
120 const double sp = std::sin(phi);
121 const double cp = std::cos(phi);
122
123 Eigen::Matrix<double, 2, 3> polarToCartesian = Eigen::Matrix<double, 2, 3>::Zero(2, 3);
124
125 // polarToCartesian({phi,theta} -> {x,y,z} )
126 polarToCartesian(0, 0) = -1. * R * st * sp; // dx/dphi
127 polarToCartesian(0, 1) = R * st * cp; // dy/dphi
128 polarToCartesian(0, 2) = 0; // dz/dphi
129
130 polarToCartesian(1, 0) = R * ct * cp; // dx/dtheta
131 polarToCartesian(1, 1) = R * ct * sp; // dy/dtheta
132 polarToCartesian(1, 2) = -1. * R * st; // dz/dtheta
133
134 m_covariance.block<3, 3>(0, 0) = polarToCartesian.transpose() * covPhiTheta * polarToCartesian;
135
136 m_covariance(3, 3) = cov_EPhiTheta[0][0];
137 m_clusterPars(0) = centroid.X();
138 m_clusterPars(1) = centroid.Y();
139 m_clusterPars(2) = centroid.Z();
140 m_clusterPars(3) = energy;
141
142 auto p_vec = particle()->getMomentum();
143 // find highest momentum, eliminate dim with highest mom
144 if ((std::abs(p_vec.X()) >= std::abs(p_vec.Y())) && (std::abs(p_vec.X()) >= std::abs(p_vec.Z()))) {
145 m_i1 = 0;
146 m_i2 = 1;
147 m_i3 = 2;
148 } else if ((std::abs(p_vec.Y()) >= std::abs(p_vec.X())) && (std::abs(p_vec.Y()) >= std::abs(p_vec.Z()))) {
149 m_i1 = 1;
150 m_i2 = 0;
151 m_i3 = 2;
152 } else if ((std::abs(p_vec.Z()) >= std::abs(p_vec.Y())) && (std::abs(p_vec.Z()) >= std::abs(p_vec.X()))) {
153 m_i1 = 2;
154 m_i2 = 1;
155 m_i3 = 0;
156 } else {
157 B2ERROR("Could not estimate highest momentum for photon constraint. Aborting this fit.\n px: "
158 << p_vec.X() << " py: " << p_vec.Y() << " pz: " << p_vec.Z() << " calculated from Ec: " << m_clusterPars(3));
159 return ErrCode(ErrCode::Status::photondimerror);
160 }
161
162 return ErrCode(ErrCode::Status::success);
163 }
164
166 {
167 const int momindex = momIndex();
168 const int posindex = mother()->posIndex();
184
185 const Eigen::Matrix<double, 1, 3> x_vertex = fitparams.getStateVector().segment(posindex, 3);
186 const Eigen::Matrix<double, 1, 3> p_vec = fitparams.getStateVector().segment(momindex, 3);
187
188 if (0 == p_vec[m_i1]) {
189 return ErrCode(ErrCode::photondimerror);
190 }
191
192 // p_vec[m_i1] must not be 0
193 const double elim = (m_clusterPars[m_i1] - x_vertex[m_i1]) / p_vec[m_i1];
194 const double mom = p_vec.norm();
195
196 // r'
197 Eigen::Matrix<double, 3, 1> residual3 = Eigen::Matrix<double, 3, 1>::Zero(3, 1);
198 residual3(0) = m_clusterPars[m_i2] - x_vertex[m_i2] - p_vec[m_i2] * elim;
199 residual3(1) = m_clusterPars[m_i3] - x_vertex[m_i3] - p_vec[m_i3] * elim;
200 residual3(2) = m_momentumScalingFactor * m_clusterPars[3] - mom; // scale measured energy by scaling factor
201
202 // dr'/dm | m:={xc,yc,zc,Ec} the measured quantities
203 Eigen::Matrix<double, 3, 4> P = Eigen::Matrix<double, 3, 4>::Zero(3, 4);
204 // deriving by the cluster pars
205 P(0, m_i2) = 1;
206 P(0, m_i1) = -p_vec[m_i2] / p_vec[m_i1];
207
208 P(1, m_i3) = 1;
209 P(1, m_i1) = -p_vec[m_i3] / p_vec[m_i1];
210 P(2, 3) = 1; // dE/dEc
211
212 p.getResiduals().segment(0, 3) = residual3;
213
214 p.getV() = P * m_covariance.selfadjointView<Eigen::Lower>() * P.transpose();
215
216 // dr'/dm | m:={x,y,z,px,py,pz,E}
217 // x := x_vertex (decay vertex of mother)
218 p.getH()(0, posindex + m_i1) = p_vec[m_i2] / p_vec[m_i1];
219 p.getH()(0, posindex + m_i2) = -1.0;
220 p.getH()(0, posindex + m_i3) = 0;
221
222 p.getH()(1, posindex + m_i1) = p_vec[m_i3] / p_vec[m_i1];
223 p.getH()(1, posindex + m_i2) = 0;
224 p.getH()(1, posindex + m_i3) = -1.0;
225
226 // elim already divided by p_vec[m_i1]
227 p.getH()(0, momindex + m_i1) = p_vec[m_i2] * elim / p_vec[m_i1];
228 p.getH()(0, momindex + m_i2) = -1. * elim;
229 p.getH()(0, momindex + m_i3) = 0;
230
231 p.getH()(1, momindex + m_i1) = p_vec[m_i3] * elim / p_vec[m_i1];
232 p.getH()(1, momindex + m_i2) = 0;
233 p.getH()(1, momindex + m_i3) = -1. * elim;
234
235 p.getH()(2, momindex + m_i1) = -1. * p_vec[m_i1] / mom;
236 p.getH()(2, momindex + m_i2) = -1. * p_vec[m_i2] / mom;
237 p.getH()(2, momindex + m_i3) = -1. * p_vec[m_i3] / mom;
238 // the photon does not store an energy in the state vector
239 // so no p.getH()(2, momindex + 3) here
240
241 return ErrCode(ErrCode::Status::success);
242 }
243
244}
double R
typedef autogenerated by FFTW
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)
The ParticleType class for identifying different particle types.
Definition Const.h:408
static const ParticleType pi0
neutral pion particle
Definition Const.h:674
static const ParticleType photon
photon particle
Definition Const.h:673
ECL cluster data.
Definition ECLCluster.h:27
EHypothesisBit
The hypothesis bits for this ECLCluster (Connected region (CR) is split using this hypothesis.
Definition ECLCluster.h:31
Class to store reconstructed particles.
Definition Particle.h:76
const ECLCluster * getECLCluster() const
Returns the pointer to the ECLCluster object that was used to create this Particle (if ParticleType =...
Definition Particle.cc:976
ROOT::Math::XYZVector getMomentum() const
Returns momentum vector.
Definition Particle.h:580
ECLCluster::EHypothesisBit getECLClusterEHypothesisBit() const
Returns the ECLCluster EHypothesisBit for this Particle.
Definition Particle.h:1029
abstract errorocode be aware that the default is success
Definition ErrCode.h:14
Class to store and manage fitparams (statevector)
Definition FitParams.h:20
Eigen::Matrix< double, -1, 1, 0, MAX_MATRIX_SIZE, 1 > & getStateVector()
getter for the fit parameters/statevector
Definition FitParams.h:65
Eigen::Matrix< double, -1, -1, 0, MAX_MATRIX_SIZE, MAX_MATRIX_SIZE > & getCovariance()
getter for the states covariance
Definition FitParams.h:53
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...
Definition Projection.h:18
virtual int momIndex() const override
get momentum index
RecoParticle(Belle2::Particle *bc, const ParticleBase *mother)
constructor
bool m_useEnergy
has energy ins statevector
Definition RecoPhoton.h:70
Eigen::Matrix< double, 4, 4 > m_covariance
covariance (x_c,y_c,z_c,E_c) of measured pars
Definition RecoPhoton.h:76
ErrCode initCovariance(FitParams &fitparams) const override
init covariance
Definition RecoPhoton.cc:74
RecoPhoton(Belle2::Particle *bc, const ParticleBase *mother)
constructor
Definition RecoPhoton.cc:25
ErrCode initParams()
update or init params
Definition RecoPhoton.cc:91
const float m_momentumScalingFactor
scale the momentum / energy by this correction factor
Definition RecoPhoton.h:86
const int m_dim
dimension of residuals and 'width' of H
Definition RecoPhoton.h:64
int m_i3
another random index
Definition RecoPhoton.h:83
int m_i1
index with the highest momentum.
Definition RecoPhoton.h:79
virtual ErrCode initParticleWithMother(FitParams &fitparams) override
init particle with mother
Definition RecoPhoton.cc:36
static bool useEnergy(const Belle2::Particle &cand)
has energy in fit params?
Definition RecoPhoton.cc:62
int m_i2
random other index
Definition RecoPhoton.h:81
virtual ErrCode initMotherlessParticle(FitParams &fitparams) override
init particle without mother
Definition RecoPhoton.cc:57
bool m_init
was initialized*
Definition RecoPhoton.h:67
ErrCode projectRecoConstraint(const FitParams &fitparams, Projection &p) const override
project photon constraint
Eigen::Matrix< double, 1, 4 > m_clusterPars
constrains measured params (x_c, y_c, z_c, E_c)
Definition RecoPhoton.h:73