Belle II Software  release-08-01-10
PxPyPzMFitObject.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include "analysis/OrcaKinFit/PxPyPzMFitObject.h"
10 #include <framework/logging/Logger.h>
11 #include <cmath>
12 #include <cassert>
13 #include <iostream>
14 
15 using std::sqrt;
16 using std::sin;
17 using std::cos;
18 
19 namespace Belle2 {
24  namespace OrcaKinFit {
25 
26 // constructor
27  PxPyPzMFitObject::PxPyPzMFitObject(CLHEP::HepLorentzVector& particle, const CLHEP::HepSymMatrix& covmatrix)
28  : cachevalid(false), chi2(0), dEdpx(0), dEdpy(0), dEdpz(0),
29  dE2dpxdpx(0), dE2dpxdpy(0), dE2dpxdpz(0), dE2dpydpy(0), dE2dpydpz(0), dE2dpzdpz(0)
30  {
31 
32  assert(int(NPAR) <= int(BaseDefs::MAXPAR));
33 
34  initCov();
35  setMass(particle.m());
36 
37  setParam(0, particle.px(), true);
38  setParam(1, particle.py(), true);
39  setParam(2, particle.pz(), true);
40 
41  setMParam(0, particle.px());
42  setMParam(1, particle.py());
43  setMParam(2, particle.pz());
44 
45  //set covariance matrix
46  for (int i = 0; i < int(NPAR); i++) {
47  for (int j = 0; j < int(NPAR); j++) {
48  setCov(i, j, covmatrix[i][j]);
49  }
50  }
51 
52  invalidateCache();
53  }
54 
55 // destructor
56  PxPyPzMFitObject::~PxPyPzMFitObject() = default;
57 
58  PxPyPzMFitObject::PxPyPzMFitObject(const PxPyPzMFitObject& rhs)
59  : ParticleFitObject(rhs), cachevalid(false), chi2(0), dEdpx(0), dEdpy(0), dEdpz(0),
60  dE2dpxdpx(0), dE2dpxdpy(0), dE2dpxdpz(0), dE2dpydpy(0), dE2dpydpz(0), dE2dpzdpz(0)
61  {
62 
64  }
65 
67  {
68  if (this != &rhs) {
69  assign(rhs); // calls virtual function assign of derived class
70  }
71  return *this;
72  }
73 
75  {
76  return new PxPyPzMFitObject(*this);
77  }
78 
80  {
81  if (const auto* psource = dynamic_cast<const PxPyPzMFitObject*>(&source)) {
82  if (psource != this) {
84  // only mutable data members, need not to be copied, if cache is invalid
85  }
86  } else {
87  assert(0);
88  }
89  return *this;
90  }
91 
92  const char* PxPyPzMFitObject::getParamName(int ilocal) const
93  {
94  switch (ilocal) {
95  case 0: return "px";
96  case 1: return "py";
97  case 2: return "pz";
98  }
99  return "undefined";
100  }
101 
102 
103  bool PxPyPzMFitObject::updateParams(double p[], int idim)
104  {
105  invalidateCache();
106 
107  int ipx = getGlobalParNum(0);
108  int ipy = getGlobalParNum(1);
109  int ipz = getGlobalParNum(2);
110  assert(ipx >= 0 && ipx < idim);
111  assert(ipy >= 0 && ipy < idim);
112  assert(ipz >= 0 && ipz < idim);
113 
114  double px = p[ipx];
115  double py = p[ipy];
116  double pz = p[ipz];
117 
118  bool result = ((px - par[0]) * (px - par[0]) > eps2 * cov[0][0]) ||
119  ((py - par[1]) * (py - par[1]) > eps2 * cov[1][1]) ||
120  ((pz - par[2]) * (pz - par[2]) > eps2 * cov[2][2]);
121 
122  par[0] = px;
123  par[1] = py;
124  par[2] = pz;
125  p[ipx] = par[0];
126  p[ipy] = par[1];
127  p[ipz] = par[2];
128  return result;
129  }
130 
131 // these depend on actual parametrisation!
132 
133  double PxPyPzMFitObject::getDPx(int ilocal) const
134  {
135  assert(ilocal >= 0 && ilocal < NPAR);
136  if (!cachevalid) updateCache();
137  switch (ilocal) {
138  case 0: return 1.0;
139  case 1: return 0.0;
140  case 2: return 0.0;
141  }
142  return 0;
143  }
144 
145  double PxPyPzMFitObject::getDPy(int ilocal) const
146  {
147  assert(ilocal >= 0 && ilocal < NPAR);
148  if (!cachevalid) updateCache();
149  switch (ilocal) {
150  case 0: return 0.0;
151  // case 1: return dpydtheta;
152  case 1: return 1.0;
153  case 2: return 0.0;
154  }
155  return 0;
156  }
157 
158  double PxPyPzMFitObject::getDPz(int ilocal) const
159  {
160  assert(ilocal >= 0 && ilocal < NPAR);
161  if (!cachevalid) updateCache();
162  switch (ilocal) {
163  case 0: return 0.0;
164  case 1: return 0.0;
165  case 2: return 1.0;
166  }
167  return 0;
168  }
169 
170  double PxPyPzMFitObject::getDE(int ilocal) const
171  {
172  assert(ilocal >= 0 && ilocal < NPAR);
173  if (!cachevalid) updateCache();
174  switch (ilocal) {
175  case 0: return dEdpx;
176  case 1: return dEdpy;
177  case 2: return dEdpz;
178  }
179  return 0;
180  }
181 
182  double PxPyPzMFitObject::getFirstDerivative_Meta_Local(int iMeta, int ilocal, int metaSet) const
183  {
184  // iMeta = intermediate variable (i.e. E,px,py,pz)
185  // ilocal = local variable (ptinv, theta, phi)
186  // metaSet = which set of intermediate varlables
187 
188  assert(metaSet == 0); // only defined for E,px,py,pz
189 
190  switch (iMeta) {
191  case 0: // E
192  return getDE(ilocal);
193  break;
194  case 1: // Px
195  return getDPx(ilocal);
196  break;
197  case 2: // Py
198  return getDPy(ilocal);
199  break;
200  case 3: // Pz
201  return getDPz(ilocal);
202  break;
203  default:
204  assert(0);
205  }
206  }
207 
208  double PxPyPzMFitObject::getSecondDerivative_Meta_Local(int iMeta, int ilocal, int jlocal, int metaSet) const
209  {
210  assert(metaSet == 0);
211  if (!cachevalid) updateCache();
212  if (jlocal < ilocal) {
213  int temp = jlocal;
214  jlocal = ilocal;
215  ilocal = temp;
216  }
217 
218  switch (iMeta) {
219  case 0: // E
220  if (ilocal == 0 && jlocal == 0) return dE2dpxdpx;
221  else if (ilocal == 0 && jlocal == 1) return dE2dpxdpy;
222  else if (ilocal == 0 && jlocal == 2) return dE2dpxdpz;
223  else if (ilocal == 1 && jlocal == 1) return dE2dpydpy;
224  else if (ilocal == 1 && jlocal == 2) return dE2dpydpz;
225  else if (ilocal == 2 && jlocal == 2) return dE2dpzdpz;
226  else return 0;
227  break;
228  case 1: // px
229  return 0;
230  break;
231  case 2: // py
232  return 0;
233  break;
234  case 3: // pz
235  return 0;
236  break;
237  default:
238  assert(0);
239  }
240  }
241 
242  void PxPyPzMFitObject::updateCache() const
243  {
244 
245  // get the basic quantities
246  double px = par[0];
247  double py = par[1];
248  double pz = par[2];
249  double px2 = px * px;
250  double py2 = py * py;
251  double pz2 = pz * pz;
252  double p = std::sqrt(px2 + py2 + pz2);
253  assert(p != 0);
254 
255  double mass2 = mass * mass;
256  double e2 = px2 + py2 + pz2 + mass2;
257  double e = std::sqrt(e2);
258 
259  // get the first derivatives
260  dEdpx = px / e;
261  dEdpy = py / e;
262  dEdpz = pz / e;
263 
264  // get second derivatives
265  double e32 = std::pow(e, 1.5);
266  dE2dpxdpx = (py2 + pz2 + mass2) / (e32);
267  dE2dpxdpy = -(px * py) / (e32);
268  dE2dpxdpz = -(px * pz) / (e32);
269  dE2dpydpy = (px2 + pz2 + mass2) / (e32);
270  dE2dpydpz = -(py * pz) / (e32);
271  dE2dpzdpz = (px2 + py2 + mass2) / (e32);
272 
273  fourMomentum.setValues(e, px, py, pz);
274 
275  cachevalid = true;
276  }
277  }// end OrcaKinFit namespace
279 } // end Belle2 namespace
280 
virtual int getGlobalParNum(int ilocal) const
Get global parameter number of parameter ilocal.
double par[BaseDefs::MAXPAR]
fit parameters
void invalidateCache() const
invalidate any cached quantities
double cov[BaseDefs::MAXPAR][BaseDefs::MAXPAR]
local covariance matrix
virtual ParticleFitObject & assign(const BaseFitObject &source) override
Assign from anther object, if of same type.
virtual double getDPx(int ilocal) const override
Return d p_x / d par_ilocal (derivative of px w.r.t. local parameter ilocal)
virtual double getDPy(int ilocal) const override
Return d p_y / d par_ilocal (derivative of py w.r.t. local parameter ilocal)
virtual PxPyPzMFitObject & assign(const BaseFitObject &source) override
Assign from anther object, if of same type.
virtual double getDE(int ilocal) const override
Return d E / d par_ilocal (derivative of E w.r.t. local parameter ilocal)
virtual PxPyPzMFitObject * copy() const override
Return a new copy of itself.
virtual const char * getParamName(int ilocal) const override
Get name of parameter ilocal.
virtual double getDPz(int ilocal) const override
Return d p_z / d par_ilocal (derivative of pz w.r.t. local parameter ilocal)
virtual bool updateParams(double p[], int idim) override
Read values from global vector, readjust vector; return: significant change.
PxPyPzMFitObject & operator=(const PxPyPzMFitObject &rhs)
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.