Belle II Software  release-08-01-10
NeutrinoFitObject.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * Forked from https://github.com/iLCSoft/MarlinKinfit *
6  * *
7  * Further information about the fit engine and the user interface *
8  * provided in MarlinKinfit can be found at *
9  * https://www.desy.de/~blist/kinfit/doc/html/ *
10  * and in the LCNotes LC-TOOL-2009-001 and LC-TOOL-2009-004 available *
11  * from http://www-flc.desy.de/lcnotes/ *
12  * *
13  * See git log for contributors and copyright holders. *
14  * This file is licensed under LGPL-3.0, see LICENSE.md. *
15  **************************************************************************/
16 
17 #include "analysis/OrcaKinFit/NeutrinoFitObject.h"
18 #include <framework/logging/Logger.h>
19 #include <cmath>
20 
21 #undef NDEBUG
22 #include <cassert>
23 
24 #include <algorithm>
25 
26 using std::sqrt;
27 using std::sin;
28 using std::cos;
29 
30 namespace Belle2 {
35  namespace OrcaKinFit {
36 
37 // constructor
38  NeutrinoFitObject::NeutrinoFitObject(double E, double theta, double phi,
39  double DE, double Dtheta, double Dphi)
40  : ctheta(0), stheta(0), cphi(0), sphi(0), pt(0), px(0), py(0), pz(0), dptdE(0),
41  dpxdE(0), dpydE(0), dpxdtheta(0), dpydtheta(0), chi2(0)
42  {
43 
44  assert(int(NPAR) <= int(BaseDefs::MAXPAR));
45 
46  setMass(0);
47  setParam(0, E, false);
48  setParam(1, theta, false);
49  setParam(2, phi, false);
50  setError(0, DE);
51  setError(1, Dtheta);
52  setError(2, Dphi);
53  invalidateCache();
54  }
55 
56 // destructor
57  NeutrinoFitObject::~NeutrinoFitObject() = default;
58 
59  NeutrinoFitObject::NeutrinoFitObject(const NeutrinoFitObject& rhs)
60  : ParticleFitObject(rhs), ctheta(0), stheta(0), cphi(0), sphi(0), pt(0), px(0), py(0), pz(0), dptdE(0),
61  dpxdE(0), dpydE(0), dpxdtheta(0), dpydtheta(0), chi2(0)
62  {
64  }
65 
67  {
68  if (this != &rhs) {
69  assign(rhs);
70  }
71  return *this;
72  }
73 
75  {
76  return new NeutrinoFitObject(*this);
77  }
78 
80  {
81  if (const auto* psource = dynamic_cast<const NeutrinoFitObject*>(&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* NeutrinoFitObject::getParamName(int ilocal) const
93  {
94  switch (ilocal) {
95  case 0: return "E";
96  case 1: return "theta";
97  case 2: return "phi";
98  }
99  return "undefined";
100  }
101 
102 
103  bool NeutrinoFitObject::updateParams(double pp[], int idim)
104  {
105 
106  invalidateCache();
107 
108  int iE = getGlobalParNum(0);
109  int ith = getGlobalParNum(1);
110  int iph = getGlobalParNum(2);
111  assert(iE >= 0 && iE < idim);
112  assert(ith >= 0 && ith < idim);
113  assert(iph >= 0 && iph < idim);
114 
115  double e = pp[iE];
116  double th = pp[ith];
117  double ph = pp[iph];
118  if (e < 0) {
119  e = -e;
120  th = M_PI - th;
121  ph = M_PI + ph;
122  }
123  if (th < 0 || th > M_PI) {
124  th = M_PI - th;
125  ph = M_PI + ph;
126  }
127 
128  bool result = (e - par[0]) * (e - par[0]) > eps2 * cov[0][0] ||
129  (th - par[1]) * (th - par[1]) > eps2 * cov[1][1] ||
130  (ph - par[2]) * (ph - par[2]) > eps2 * cov[2][2];
131  par[0] = e;
132  par[1] = (th >= 0 && th < M_PI) ?
133  th : std::acos(std::cos(th));
134  if (std::abs(ph) > M_PI) ph = atan2(sin(ph), cos(ph));
135  par[2] = ph;
136  pp[iE] = par[0];
137  pp[ith] = par[1];
138  pp[iph] = par[2];
139  return result;
140  }
141 
142 // these depend on actual parametrisation!
143  double NeutrinoFitObject::getDPx(int ilocal) const
144  {
145  assert(ilocal >= 0 && ilocal < NPAR);
146  if (!cachevalid) updateCache();
147  switch (ilocal) {
148  case 0: return dpxdE;
149  case 1: return dpxdtheta;
150  case 2: return -py;
151  }
152  return 0;
153  }
154 
155  double NeutrinoFitObject::getDPy(int ilocal) const
156  {
157  assert(ilocal >= 0 && ilocal < NPAR);
158  if (!cachevalid) updateCache();
159  switch (ilocal) {
160  case 0: return dpydE;
161  case 1: return dpydtheta;
162  case 2: return px;
163  }
164  return 0;
165  }
166 
167  double NeutrinoFitObject::getDPz(int ilocal) const
168  {
169  assert(ilocal >= 0 && ilocal < NPAR);
170  if (!cachevalid) updateCache();
171  switch (ilocal) {
172  case 0: return ctheta;
173  case 1: return -pt;
174  case 2: return 0;
175  }
176  return 0;
177  }
178 
179  double NeutrinoFitObject::getDE(int ilocal) const
180  {
181  assert(ilocal >= 0 && ilocal < NPAR);
182  switch (ilocal) {
183  case 0: return 1;
184  case 1: return 0;
185  case 2: return 0;
186  }
187  return 0;
188  }
189 
190  double NeutrinoFitObject::getFirstDerivative_Meta_Local(int iMeta, int ilocal, int metaSet) const
191  {
192  // iMeta = intermediate variable (i.e. E,px,py,pz)
193  // ilocal = local variable (E, theta, phi)
194  // metaSet = which set of intermediate varlables
195 
196  assert(metaSet == 0); // only defined for E,px,py,pz
197 
198  switch (iMeta) {
199  case 0: // E
200  return getDE(ilocal);
201  break;
202  case 1: // Px
203  return getDPx(ilocal);
204  break;
205  case 2: // Py
206  return getDPy(ilocal);
207  break;
208  case 3: // Pz
209  return getDPz(ilocal);
210  break;
211  default:
212  assert(0);
213  }
214  return -999;
215  }
216 
217 
218  double NeutrinoFitObject::getSecondDerivative_Meta_Local(int iMeta, int ilocal, int jlocal, int metaSet) const
219  {
220  assert(metaSet == 0);
221  if (!cachevalid) updateCache();
222 
223  if (jlocal < ilocal) {
224  int temp = jlocal;
225  jlocal = ilocal;
226  ilocal = temp;
227  }
228 
229  // daniel hasn't checked these, copied from orig code
230  switch (iMeta) {
231 
232  case 0:
233  return 0;
234  break;
235  case 1:
236  if (ilocal == 0 && jlocal == 1) return ctheta * cphi;
237  else if (ilocal == 0 && jlocal == 2) return -dpydE;
238  else if (ilocal == 1 && jlocal == 1) return -px;
239  else if (ilocal == 1 && jlocal == 2) return -dpydtheta;
240  else if (ilocal == 2 && jlocal == 2) return -px;
241  else return 0;
242  break;
243  case 2:
244  if (ilocal == 0 && jlocal == 1) return ctheta * sphi;
245  else if (ilocal == 0 && jlocal == 2) return dpxdE;
246  else if (ilocal == 1 && jlocal == 1) return -py;
247  else if (ilocal == 1 && jlocal == 2) return dpxdtheta;
248  else if (ilocal == 2 && jlocal == 2) return -py;
249  else return 0;
250  break;
251  case 3:
252  if (ilocal == 0 && jlocal == 1) return -stheta;
253  else if (ilocal == 1 && jlocal == 1) return -pz;
254  else return 0;
255  break;
256  default:
257  assert(0);
258  }
259  return -999;
260  }
261 
262 
263  void NeutrinoFitObject::updateCache() const
264  {
265  double e = par[0];
266  double theta = par[1];
267  double phi = par[2];
268 
269  ctheta = cos(theta);
270  stheta = sin(theta);
271  cphi = cos(phi);
272  sphi = sin(phi);
273 
274  pt = e * stheta;
275 
276  px = pt * cphi;
277  py = pt * sphi;
278  pz = e * ctheta;
279 
280  fourMomentum.setValues(e, px, py, pz);
281 
282  dpxdE = stheta * cphi;
283  dpydE = stheta * sphi;
284  dpxdtheta = pz * cphi;
285  dpydtheta = pz * sphi;
286 
287  cachevalid = true;
288  }
289 
290  }// end OrcaKinFit namespace
292 } // end Belle2 namespace
293 
R E
internal precision of FFTW codelets
bool cachevalid
flag for valid cache
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 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)
NeutrinoFitObject & operator=(const NeutrinoFitObject &rhs)
Assignment.
virtual double getDE(int ilocal) const override
Return d E / d par_ilocal (derivative of E w.r.t. local parameter ilocal)
virtual NeutrinoFitObject & assign(const BaseFitObject &source) override
Assign from anther object, if of same type.
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.
virtual NeutrinoFitObject * copy() const override
Return a new copy of itself.
virtual ParticleFitObject & assign(const BaseFitObject &source) override
Assign from anther object, if of same type.
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.