Belle II Software  release-08-01-10
KFitBase.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * External Contributor: J. Tanaka *
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 <TMatrixFSym.h>
11 
12 #include <analysis/utility/ROOTToCLHEP.h>
13 #include <analysis/VertexFitting/KFit/KFitBase.h>
14 
15 using namespace std;
16 using namespace Belle2;
17 using namespace Belle2::analysis;
18 using namespace CLHEP;
19 
20 KFitBase::KFitBase()
21 {
22  m_ErrorCode = KFitError::kNoError;
23  m_FlagFitted = false;
24  m_FlagCorrelation = false;
25  m_FlagOverIteration = false;
26  m_MagneticField = KFitConst::kDefaultMagneticField;
27  m_NDF = 0;
28  m_CHIsq = -1;
29  m_NecessaryTrackCount = -1;
30  m_TrackCount = 0;
31 }
32 
33 
34 KFitBase::~KFitBase() = default;
35 
36 
38 KFitBase::addTrack(const KFitTrack& p) {
39  m_Tracks.push_back(p);
40  m_TrackCount = m_Tracks.size();
41 
42  return m_ErrorCode = KFitError::kNoError;
43 }
44 
45 
47 KFitBase::addTrack(const HepLorentzVector& p, const HepPoint3D& x, const HepSymMatrix& e, const double q) {
48  if (e.num_row() != KFitConst::kNumber7)
49  {
50  m_ErrorCode = KFitError::kBadMatrixSize;
51  KFitError::displayError(__FILE__, __LINE__, __func__, m_ErrorCode);
52  return m_ErrorCode;
53  }
54 
55  return this->addTrack(KFitTrack(p, x, e, q));
56 }
57 
58 
59 enum KFitError::ECode KFitBase::addParticle(const Particle* particle)
60 {
61  return addTrack(
62  ROOTToCLHEP::getHepLorentzVector(particle->get4Vector()),
63  ROOTToCLHEP::getPoint3D(particle->getVertex()),
64  ROOTToCLHEP::getHepSymMatrix(particle->getMomentumVertexErrorMatrix()),
65  particle->getCharge());
66 }
67 
68 
70 KFitBase::setCorrelation(const HepMatrix& e) {
71  if (e.num_row() != KFitConst::kNumber7)
72  {
73  m_ErrorCode = KFitError::kBadMatrixSize;
74  KFitError::displayError(__FILE__, __LINE__, __func__, m_ErrorCode);
75  return m_ErrorCode;
76  }
77  m_BeforeCorrelation.push_back(e);
78  m_FlagCorrelation = true;
79 
80  return m_ErrorCode = KFitError::kNoError;
81 }
82 
83 
85 KFitBase::setZeroCorrelation() {
86  HepMatrix zero(KFitConst::kNumber7, KFitConst::kNumber7, 0);
87 
88  return this->setCorrelation(zero);
89 }
90 
91 
93 KFitBase::setMagneticField(const double mf) {
94  m_MagneticField = mf;
95 
96  return m_ErrorCode = KFitError::kNoError;
97 }
98 
99 
100 enum KFitError::ECode
101 KFitBase::getErrorCode() const {
102  return m_ErrorCode;
103 }
104 
105 
106 int
107 KFitBase::getTrackCount() const
108 {
109  return m_TrackCount;
110 }
111 
112 
113 int
114 KFitBase::getNDF() const
115 {
116  return m_NDF;
117 }
118 
119 
120 double
121 KFitBase::getCHIsq() const
122 {
123  return m_CHIsq;
124 }
125 
126 
127 double
128 KFitBase::getMagneticField() const
129 {
130  return m_MagneticField;
131 }
132 
133 
134 double
135 KFitBase::getTrackCHIsq(const int id) const
136 {
137  if (!isFitted()) return -1.;
138  if (!isTrackIDInRange(id)) return -1.;
139 
140  HepMatrix da(m_Tracks[id].getFitParameter(KFitConst::kBeforeFit) - m_Tracks[id].getFitParameter(KFitConst::kAfterFit));
141  int err_inverse = 0;
142  const double chisq = (da.T() * (m_Tracks[id].getFitError(KFitConst::kBeforeFit).inverse(err_inverse)) * da)[0][0];
143 
144  if (err_inverse) {
145  KFitError::displayError(__FILE__, __LINE__, __func__, KFitError::kCannotGetMatrixInverse);
146  return -1.;
147  }
148 
149  return chisq;
150 }
151 
152 
153 const HepLorentzVector
154 KFitBase::getTrackMomentum(const int id) const
155 {
156  if (!isTrackIDInRange(id)) return HepLorentzVector();
157  return m_Tracks[id].getMomentum();
158 }
159 
160 const HepPoint3D
161 KFitBase::getTrackPosition(const int id) const
162 {
163  if (!isTrackIDInRange(id)) return HepPoint3D();
164  return m_Tracks[id].getPosition();
165 }
166 
167 const HepSymMatrix
168 KFitBase::getTrackError(const int id) const
169 {
170  if (!isTrackIDInRange(id)) return HepSymMatrix(KFitConst::kNumber7, 0);
171  return m_Tracks[id].getError();
172 }
173 
174 const KFitTrack
175 KFitBase::getTrack(const int id) const
176 {
177  if (!isTrackIDInRange(id)) return KFitTrack();
178  return m_Tracks[id];
179 }
180 
181 
182 const HepMatrix
183 KFitBase::getCorrelation(const int id1, const int id2, const int flag) const
184 {
185  if (flag == KFitConst::kAfterFit && !isFitted()) return HepMatrix(KFitConst::kNumber7, KFitConst::kNumber7, 0);
186  if (!isTrackIDInRange(id1)) return HepMatrix(KFitConst::kNumber7, KFitConst::kNumber7, 0);
187  if (!isTrackIDInRange(id2)) return HepMatrix(KFitConst::kNumber7, KFitConst::kNumber7, 0);
188 
189  switch (flag) {
190  case KFitConst::kAfterFit:
191  return makeError1(
192  getTrackMomentum(id1),
193  getTrackMomentum(id2),
194  m_V_al_1.sub(KFitConst::kNumber6 * id1 + 1, KFitConst::kNumber6 * (id1 + 1), KFitConst::kNumber6 * id2 + 1,
195  KFitConst::kNumber6 * (id2 + 1))
196  );
197 
198  default:
199  if (id1 == id2) {
200 
201  return static_cast<HepMatrix>(m_Tracks[id1].getError(KFitConst::kBeforeFit));
202 
203  } else {
204  const int idx1 = id1 < id2 ? id1 : id2, idx2 = id1 < id2 ? id2 : id1;
205 
206  int index = 0;
207 
208  for (int i = 0; i < idx1; i++) index += m_TrackCount - 1 - i;
209  index -= idx1 + 1;
210  index += idx2;
211  if (id1 == idx1)
212  return m_BeforeCorrelation[index + idx2];
213  else
214  return m_BeforeCorrelation[index + idx2].T();
215  }
216  }
217 }
218 
219 
220 const HepSymMatrix
221 KFitBase::makeError1(const HepLorentzVector& p, const HepMatrix& e) const
222 {
223  // self track
224  // Error(6x6,e) ==> Error(7x7,output(hsm)) using Momentum(p).
225 
226  if (!isNonZeroEnergy(p)) return HepSymMatrix(KFitConst::kNumber7, 0);
227 
228  HepSymMatrix hsm(KFitConst::kNumber7, 0);
229 
230  for (int i = 0; i < 3; i++) for (int j = i; j < 3; j++) {
231  hsm[i][j] = e[i][j];
232  hsm[4 + i][4 + j] = e[3 + i][3 + j];
233  }
234  for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {
235  hsm[i][4 + j] = e[i][3 + j];
236  }
237 
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;
249 
250  return hsm;
251 }
252 
253 
254 const HepMatrix
255 KFitBase::makeError1(const HepLorentzVector& p1, const HepLorentzVector& p2, const HepMatrix& e) const
256 {
257  // track and track
258  // Error(6x6,e) ==> Error(7x7,output(hm)) using Momentum(p1&p2).
259 
260  if (!isNonZeroEnergy(p1)) return HepSymMatrix(KFitConst::kNumber7, 0);
261  if (!isNonZeroEnergy(p2)) return HepSymMatrix(KFitConst::kNumber7, 0);
262 
263  HepMatrix hm(KFitConst::kNumber7, KFitConst::kNumber7, 0);
264 
265  for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {
266  hm[i][j] = e[i][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];
270  }
271 
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;
290 
291  return hm;
292 }
293 
294 
295 const HepMatrix
296 KFitBase::makeError2(const HepLorentzVector& p, const HepMatrix& e) const
297 {
298  // vertex and track
299  // Error(3x6,e) ==> Error(3x7,output(hm)) using Momentum(p).
300 
301  if (!isNonZeroEnergy(p)) return HepSymMatrix(KFitConst::kNumber7, 0);
302 
303  HepMatrix hm(3, KFitConst::kNumber7, 0);
304 
305  for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {
306  hm[i][j] = e[i][j];
307  hm[i][4 + j] = e[i][3 + j];
308  }
309 
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;
314 
315  return hm;
316 }
317 
318 
319 const HepSymMatrix
320 KFitBase::makeError3(const HepLorentzVector& p, const HepMatrix& e, const bool is_fix_mass) const
321 {
322  // self track
323  // Error(7x7,e) ==> Error(7x7,output(hsm)) using Momentum(p).
324  // is_fix_mass = 1 : Energy term is recalculated from the other parameters.
325  // is_fix_mass = 0 : hsm = e.
326 
327  if (!isNonZeroEnergy(p)) return HepSymMatrix(KFitConst::kNumber7, 0);
328 
329  if (!is_fix_mass) {
330  HepSymMatrix hsm(KFitConst::kNumber7, 0);
331  for (int i = 0; i < 7; i++) for (int j = i; j < 7; j++) {
332  hsm[i][j] = e[i][j];
333  }
334  return hsm;
335  }
336 
337  HepSymMatrix hsm(KFitConst::kNumber7, 0);
338 
339  for (int i = 0; i < 7; i++) {
340  if (i != 3)
341  for (int j = i; j < 7; j++) hsm[i][j] = e[i][j];
342  }
343 
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;
355 
356  return hsm;
357 }
358 
359 
360 const HepMatrix
361 KFitBase::makeError3(const HepLorentzVector& p1, const HepLorentzVector& p2, const HepMatrix& e, const bool is_fix_mass1,
362  const bool is_fix_mass2) const
363 {
364  // track and track
365  // Error(7x7,e) ==> Error(7x7,output(hm)) using Momentum(p1&p2).
366  // is_fix_mass = 1 : Energy term is recalculated from the other parameters.
367  // is_fix_mass = 0 : not.
368 
369  if (is_fix_mass1 && is_fix_mass2) {
370  if (!isNonZeroEnergy(p1)) return HepSymMatrix(KFitConst::kNumber7, 0);
371  if (!isNonZeroEnergy(p2)) return HepSymMatrix(KFitConst::kNumber7, 0);
372 
373  HepMatrix hm(e);
374 
375  const double invE1 = 1 / p1.t();
376  const double invE2 = 1 / p2.t();
377  hm[0][3] = (p2.x() * hm[0][0] + p2.y() * hm[0][1] + p2.z() * hm[0][2]) * invE2;
378  hm[1][3] = (p2.x() * hm[1][0] + p2.y() * hm[1][1] + p2.z() * hm[1][2]) * invE2;
379  hm[2][3] = (p2.x() * hm[2][0] + p2.y() * hm[2][1] + p2.z() * hm[2][2]) * invE2;
380  hm[4][3] = (p2.x() * hm[4][0] + p2.y() * hm[4][1] + p2.z() * hm[4][2]) * invE2;
381  hm[5][3] = (p2.x() * hm[5][0] + p2.y() * hm[5][1] + p2.z() * hm[5][2]) * invE2;
382  hm[6][3] = (p2.x() * hm[6][0] + p2.y() * hm[6][1] + p2.z() * hm[6][2]) * invE2;
383  hm[3][0] = (p1.x() * hm[0][0] + p1.y() * hm[1][0] + p1.z() * hm[2][0]) * invE1;
384  hm[3][1] = (p1.x() * hm[0][1] + p1.y() * hm[1][1] + p1.z() * hm[2][1]) * invE1;
385  hm[3][2] = (p1.x() * hm[0][2] + p1.y() * hm[1][2] + p1.z() * hm[2][2]) * invE1;
386  hm[3][3] = (p1.x() * p2.x() * hm[0][0] + p1.y() * p2.y() * hm[1][1] + p1.z() * p2.z() * hm[2][2] +
387  p1.x() * p2.y() * hm[0][1] + p2.x() * p1.y() * hm[1][0] +
388  p1.x() * p2.z() * hm[0][2] + p2.x() * p1.z() * hm[2][0] +
389  p1.y() * p2.z() * hm[1][2] + p2.y() * p1.z() * hm[2][1]) * invE1 * invE2;
390  hm[3][4] = (p1.x() * hm[0][4] + p1.y() * hm[1][4] + p1.z() * hm[2][4]) * invE1;
391  hm[3][5] = (p1.x() * hm[0][5] + p1.y() * hm[1][5] + p1.z() * hm[2][5]) * invE1;
392  hm[3][6] = (p1.x() * hm[0][6] + p1.y() * hm[1][6] + p1.z() * hm[2][6]) * invE1;
393 
394  return hm;
395  }
396 
397 
398  if (is_fix_mass1 && !is_fix_mass2) {
399  if (!isNonZeroEnergy(p1)) return HepSymMatrix(KFitConst::kNumber7, 0);
400 
401  HepMatrix hm(e);
402 
403  const double invE1 = 1 / p1.t();
404  hm[3][0] = (p1.x() * hm[0][0] + p1.y() * hm[1][0] + p1.z() * hm[2][0]) * invE1;
405  hm[3][1] = (p1.x() * hm[0][1] + p1.y() * hm[1][1] + p1.z() * hm[2][1]) * invE1;
406  hm[3][2] = (p1.x() * hm[0][2] + p1.y() * hm[1][2] + p1.z() * hm[2][2]) * invE1;
407  hm[3][3] = (p1.x() * hm[0][3] + p1.y() * hm[1][3] + p1.z() * hm[2][3]) * invE1;
408  hm[3][4] = (p1.x() * hm[0][4] + p1.y() * hm[1][4] + p1.z() * hm[2][4]) * invE1;
409  hm[3][5] = (p1.x() * hm[0][5] + p1.y() * hm[1][5] + p1.z() * hm[2][5]) * invE1;
410  hm[3][6] = (p1.x() * hm[0][6] + p1.y() * hm[1][6] + p1.z() * hm[2][6]) * invE1;
411 
412  return hm;
413  }
414 
415 
416  if (!is_fix_mass1 && is_fix_mass2) {
417  if (!isNonZeroEnergy(p2)) return HepSymMatrix(KFitConst::kNumber7, 0);
418 
419  HepMatrix hm(e);
420 
421  const double invE2 = 1 / p2.t();
422  hm[0][3] = (p2.x() * hm[0][0] + p2.y() * hm[0][1] + p2.z() * hm[0][2]) * invE2;
423  hm[1][3] = (p2.x() * hm[1][0] + p2.y() * hm[1][1] + p2.z() * hm[1][2]) * invE2;
424  hm[2][3] = (p2.x() * hm[2][0] + p2.y() * hm[2][1] + p2.z() * hm[2][2]) * invE2;
425  hm[3][3] = (p2.x() * hm[3][0] + p2.y() * hm[3][1] + p2.z() * hm[3][2]) * invE2;
426  hm[4][3] = (p2.x() * hm[4][0] + p2.y() * hm[4][1] + p2.z() * hm[4][2]) * invE2;
427  hm[5][3] = (p2.x() * hm[5][0] + p2.y() * hm[5][1] + p2.z() * hm[5][2]) * invE2;
428  hm[6][3] = (p2.x() * hm[6][0] + p2.y() * hm[6][1] + p2.z() * hm[6][2]) * invE2;
429 
430  return hm;
431  }
432 
433  return e;
434 }
435 
436 
437 const HepMatrix
438 KFitBase::makeError4(const HepLorentzVector& p, const HepMatrix& e) const
439 {
440  // vertex and track
441  // Error(3x7,e) ==> Error(3x7,output(hm)) using Momentum(p).
442  // Energy term is recalculated from the other parameters.
443 
444  if (!isNonZeroEnergy(p)) return HepSymMatrix(KFitConst::kNumber7, 0);
445 
446  HepMatrix hm(e);
447 
448  const double invE = 1 / p.t();
449  hm[0][3] = (p.x() * hm[0][0] + p.y() * hm[0][1] + p.z() * hm[0][2]) * invE;
450  hm[1][3] = (p.x() * hm[1][0] + p.y() * hm[1][1] + p.z() * hm[1][2]) * invE;
451  hm[2][3] = (p.x() * hm[2][0] + p.y() * hm[2][1] + p.z() * hm[2][2]) * invE;
452 
453  return hm;
454 }
455 
456 
457 enum KFitError::ECode
458 KFitBase::prepareCorrelation() {
459  if (m_BeforeCorrelation.size() != (double)m_TrackCount * ((double)m_TrackCount - 1)*.5)
460  {
461  m_ErrorCode = KFitError::kBadCorrelationSize;
462  KFitError::displayError(__FILE__, __LINE__, __func__, m_ErrorCode);
463  return m_ErrorCode;
464  }
465 
466  HepMatrix tmp_hm(KFitConst::kNumber6, KFitConst::kNumber6, 0);
467  int row = 0, col = 0;
468 
469  for (auto& hm : m_BeforeCorrelation)
470  {
471  row++;
472  if (row == m_TrackCount) {
473  col++;
474  row = col + 1;
475  }
476 
477  // 7x7 --> 6x6
478  for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {
479  tmp_hm[i][j] = hm[i][j];
480  tmp_hm[3 + i][3 + j] = hm[4 + i][4 + j];
481  tmp_hm[3 + i][j] = hm[4 + i][j];
482  tmp_hm[i][3 + j] = hm[i][4 + j];
483  }
484 
485  int ii = 0, jj = 0;
486  for (int i = KFitConst::kNumber6 * row; i < KFitConst::kNumber6 * (row + 1); i++) {
487  for (int j = KFitConst::kNumber6 * col; j < KFitConst::kNumber6 * (col + 1); j++) {
488  m_V_al_0[i][j] = tmp_hm[ii][jj];
489  jj++;
490  }
491  jj = 0;
492  ii++;
493  }
494  }
495 
496  return m_ErrorCode = KFitError::kNoError;
497 }
498 
499 
500 enum KFitError::ECode
501 KFitBase::doFit1() {
502  if (m_ErrorCode != KFitError::kNoError) return m_ErrorCode;
503 
504  if (m_TrackCount < m_NecessaryTrackCount)
505  {
506  m_ErrorCode = KFitError::kBadTrackSize;
507  KFitError::displayError(__FILE__, __LINE__, __func__, m_ErrorCode);
508  return m_ErrorCode;
509  }
510 
511  if (prepareInputMatrix() != KFitError::kNoError) return m_ErrorCode;
512  if (calculateNDF() != KFitError::kNoError) return m_ErrorCode;
513 
514 
515  double chisq = 0;
516  double tmp_chisq = KFitConst::kInitialCHIsq;
517  int err_inverse = 0;
518 
519  HepMatrix tmp_al_1(m_al_1);
520  HepMatrix tmp_V_al_1(m_V_al_1);
521 
522  m_al_a = m_al_0;
523  HepMatrix tmp_al_a(m_al_a);
524 
525 
526  for (int i = 0; i < KFitConst::kMaxIterationCount; i++)
527  {
528  if (makeCoreMatrix() != KFitError::kNoError) return m_ErrorCode;
529 
530  m_V_D = (m_V_al_0.similarity(m_D)).inverse(err_inverse);
531  if (err_inverse != 0) {
532  m_ErrorCode = KFitError::kCannotGetMatrixInverse;
533  return m_ErrorCode;
534  }
535 
536  m_lam = m_V_D * (m_D * (m_al_0 - m_al_1) + m_d);
537  chisq = ((m_lam.T()) * (m_D * (m_al_0 - m_al_1) + m_d))(1, 1);
538  m_al_1 = m_al_0 - m_V_al_0 * (m_D.T()) * m_lam;
539  m_V_al_1 = m_V_al_0 - m_V_al_0 * (m_D.T()) * m_V_D * m_D * m_V_al_0;
540 
541  if (tmp_chisq <= chisq) {
542  if (i == 0) {
543  m_ErrorCode = KFitError::kBadInitialCHIsq;
544  return m_ErrorCode;
545  } else {
546  chisq = tmp_chisq;
547  m_al_1 = tmp_al_1;
548  m_al_a = tmp_al_a;
549  m_V_al_1 = tmp_V_al_1;
550  break;
551  }
552  } else {
553  tmp_chisq = chisq;
554  tmp_al_a = tmp_al_1;
555  tmp_al_1 = m_al_1;
556  tmp_V_al_1 = m_V_al_1;
557  if (i == KFitConst::kMaxIterationCount - 1) {
558  m_al_a = tmp_al_1;
559  m_FlagOverIteration = true;
560  }
561  }
562  }
563 
564  if (m_ErrorCode != KFitError::kNoError) return m_ErrorCode;
565 
566  if (prepareOutputMatrix() != KFitError::kNoError) return m_ErrorCode;
567 
568  m_CHIsq = chisq;
569 
570  m_FlagFitted = true;
571 
572  return m_ErrorCode = KFitError::kNoError;
573 }
574 
575 
576 enum KFitError::ECode
577 KFitBase::doFit2() {
578  if (m_ErrorCode != KFitError::kNoError) return m_ErrorCode;
579 
580  if (m_TrackCount < m_NecessaryTrackCount)
581  {
582  m_ErrorCode = KFitError::kBadTrackSize;
583  KFitError::displayError(__FILE__, __LINE__, __func__, m_ErrorCode);
584  return m_ErrorCode;
585  }
586 
587  if (prepareInputMatrix() != KFitError::kNoError) return m_ErrorCode;
588  if (calculateNDF() != KFitError::kNoError) return m_ErrorCode;
589 
590 
591  double chisq = 0;
592  double tmp2_chisq = KFitConst::kInitialCHIsq;
593  int err_inverse = 0;
594 
595  m_al_a = m_al_0;
596  HepMatrix tmp_al_a(m_al_a);
597 
598  HepMatrix tmp_D(m_D), tmp_E(m_E);
599  HepMatrix tmp_V_D(m_V_D), tmp_V_E(m_V_E);
600  HepMatrix tmp_lam0(m_lam0), tmp_v_a(m_v_a);
601 
602  HepMatrix tmp2_D(m_D), tmp2_E(m_E);
603  HepMatrix tmp2_V_D(m_V_D), tmp2_V_E(m_V_E);
604  HepMatrix tmp2_lam0(m_lam0), tmp2_v_a(m_v_a), tmp2_v(m_v_a);
605 
606 
607  for (int j = 0; j < KFitConst::kMaxIterationCount; j++) // j'th loop start
608  {
609 
610  double tmp_chisq = KFitConst::kInitialCHIsq;
611 
612  for (int i = 0; i < KFitConst::kMaxIterationCount; i++) { // i'th loop start
613 
614  if (prepareInputSubMatrix() != KFitError::kNoError) return m_ErrorCode;
615  if (makeCoreMatrix() != KFitError::kNoError) return m_ErrorCode;
616 
617  m_V_D = (m_V_al_0.similarity(m_D)).inverse(err_inverse);
618  if (err_inverse) {
619  m_ErrorCode = KFitError::kCannotGetMatrixInverse;
620  return m_ErrorCode;
621  }
622 
623  m_V_E = ((m_E.T()) * m_V_D * m_E).inverse(err_inverse);
624  if (err_inverse) {
625  m_ErrorCode = KFitError::kCannotGetMatrixInverse;
626  return m_ErrorCode;
627  }
628  m_lam0 = m_V_D * (m_D * (m_al_0 - m_al_1) + m_d);
629  chisq = ((m_lam0.T()) * (m_D * (m_al_0 - m_al_1) + m_E * (m_v - m_v_a) + m_d))(1, 1);
630  m_v_a = m_v_a - m_V_E * (m_E.T()) * m_lam0;
631 
632  if (tmp_chisq <= chisq) {
633  if (i == 0) {
634  m_ErrorCode = KFitError::kBadInitialCHIsq;
635  return m_ErrorCode;
636  } else {
637  chisq = tmp_chisq;
638  m_v_a = tmp_v_a;
639  m_V_E = tmp_V_E;
640  m_V_D = tmp_V_D;
641  m_lam0 = tmp_lam0;
642  m_E = tmp_E;
643  m_D = tmp_D;
644  break;
645  }
646  } else {
647  tmp_chisq = chisq;
648  tmp_v_a = m_v_a;
649  tmp_V_E = m_V_E;
650  tmp_V_D = m_V_D;
651  tmp_lam0 = m_lam0;
652  tmp_E = m_E;
653  tmp_D = m_D;
654  if (i == KFitConst::kMaxIterationCount - 1) {
655  m_FlagOverIteration = true;
656  }
657  }
658  } // i'th loop over
659 
660 
661  m_al_a = m_al_1;
662  m_lam = m_lam0 - m_V_D * m_E * m_V_E * (m_E.T()) * m_lam0;
663  m_al_1 = m_al_0 - m_V_al_0 * (m_D.T()) * m_lam;
664 
665  if (j == 0) {
666 
667  tmp2_chisq = chisq;
668  tmp2_v_a = m_v_a;
669  tmp2_v = m_v;
670  tmp2_V_E = m_V_E;
671  tmp2_V_D = m_V_D;
672  tmp2_lam0 = m_lam0;
673  tmp2_E = m_E;
674  tmp2_D = m_D;
675  tmp_al_a = m_al_a;
676 
677  } else {
678 
679  if (tmp2_chisq <= chisq) {
680  chisq = tmp2_chisq;
681  m_v_a = tmp2_v_a;
682  m_v = tmp2_v;
683  m_V_E = tmp2_V_E;
684  m_V_D = tmp2_V_D;
685  m_lam0 = tmp2_lam0;
686  m_E = tmp2_E;
687  m_D = tmp2_D;
688  m_al_a = tmp_al_a;
689  break;
690  } else {
691  tmp2_chisq = chisq;
692  tmp2_v_a = m_v_a;
693  tmp2_v = m_v;
694  tmp2_V_E = m_V_E;
695  tmp2_V_D = m_V_D;
696  tmp2_lam0 = m_lam0;
697  tmp2_E = m_E;
698  tmp2_D = m_D;
699  tmp_al_a = m_al_a;
700  if (j == KFitConst::kMaxIterationCount - 1) {
701  m_FlagOverIteration = true;
702  }
703  }
704  }
705  } // j'th loop over
706 
707 
708  if (m_ErrorCode != KFitError::kNoError) return m_ErrorCode;
709 
710  m_lam = m_lam0 - m_V_D * m_E * m_V_E * (m_E.T()) * m_lam0;
711  m_al_1 = m_al_0 - m_V_al_0 * (m_D.T()) * m_lam;
712  m_V_Dt = m_V_D - m_V_D * m_E * m_V_E * (m_E.T()) * m_V_D;
713  m_V_al_1 = m_V_al_0 - m_V_al_0 * (m_D.T()) * m_V_Dt * m_D * m_V_al_0;
714  m_Cov_v_al_1 = -m_V_E * (m_E.T()) * m_V_D * m_D * m_V_al_0;
715 
716  if (prepareOutputMatrix() != KFitError::kNoError) return m_ErrorCode;
717 
718  m_CHIsq = chisq;
719 
720  m_FlagFitted = true;
721 
722  return m_ErrorCode = KFitError::kNoError;
723 }
724 
725 
726 bool
727 KFitBase::isFitted() const
728 {
729  if (m_FlagFitted) return true;
730 
731  KFitError::displayError(__FILE__, __LINE__, __func__, KFitError::kNotFittedYet);
732 
733  return false;
734 }
735 
736 
737 bool
738 KFitBase::isTrackIDInRange(const int id) const
739 {
740  if (0 <= id && id < m_TrackCount) return true;
741 
742  KFitError::displayError(__FILE__, __LINE__, __func__, KFitError::kOutOfRange);
743 
744  return false;
745 }
746 
747 
748 bool
749 KFitBase::isNonZeroEnergy(const HepLorentzVector& p) const
750 {
751  if (p.t() != 0) return true;
752 
753  KFitError::displayError(__FILE__, __LINE__, __func__, KFitError::kDivisionByZero);
754 
755  return false;
756 }
Class to store reconstructed particles.
Definition: Particle.h:75
ECode
ECode is a error code enumerate.
Definition: KFitError.h:34
KFitTrack is a container of the track information (Lorentz vector, position, and error matrix),...
Definition: KFitTrack.h:38
Abstract base class for different kinds of events.