Belle II Software  light-2403-persian
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 CLHEP::HepLorentzVector& p, const HepPoint3D& x, const CLHEP::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 CLHEP::HepLorentzVector& p, const CLHEP::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 CLHEP::HepLorentzVector& p1, const CLHEP::HepLorentzVector& p2, const CLHEP::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 CLHEP::HepLorentzVector& p, const CLHEP::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 CLHEP::HepLorentzVector& p1, const CLHEP::HepLorentzVector& p2, const CLHEP::HepMatrix& e,
362  const bool is_fix_mass1,
363  const bool is_fix_mass2) const
364 {
365  // track and track
366  // Error(7x7,e) ==> Error(7x7,output(hm)) using Momentum(p1&p2).
367  // is_fix_mass = 1 : Energy term is recalculated from the other parameters.
368  // is_fix_mass = 0 : not.
369 
370  if (is_fix_mass1 && is_fix_mass2) {
371  if (!isNonZeroEnergy(p1)) return HepSymMatrix(KFitConst::kNumber7, 0);
372  if (!isNonZeroEnergy(p2)) return HepSymMatrix(KFitConst::kNumber7, 0);
373 
374  HepMatrix hm(e);
375 
376  const double invE1 = 1 / p1.t();
377  const double invE2 = 1 / p2.t();
378  hm[0][3] = (p2.x() * hm[0][0] + p2.y() * hm[0][1] + p2.z() * hm[0][2]) * invE2;
379  hm[1][3] = (p2.x() * hm[1][0] + p2.y() * hm[1][1] + p2.z() * hm[1][2]) * invE2;
380  hm[2][3] = (p2.x() * hm[2][0] + p2.y() * hm[2][1] + p2.z() * hm[2][2]) * invE2;
381  hm[4][3] = (p2.x() * hm[4][0] + p2.y() * hm[4][1] + p2.z() * hm[4][2]) * invE2;
382  hm[5][3] = (p2.x() * hm[5][0] + p2.y() * hm[5][1] + p2.z() * hm[5][2]) * invE2;
383  hm[6][3] = (p2.x() * hm[6][0] + p2.y() * hm[6][1] + p2.z() * hm[6][2]) * invE2;
384  hm[3][0] = (p1.x() * hm[0][0] + p1.y() * hm[1][0] + p1.z() * hm[2][0]) * invE1;
385  hm[3][1] = (p1.x() * hm[0][1] + p1.y() * hm[1][1] + p1.z() * hm[2][1]) * invE1;
386  hm[3][2] = (p1.x() * hm[0][2] + p1.y() * hm[1][2] + p1.z() * hm[2][2]) * invE1;
387  hm[3][3] = (p1.x() * p2.x() * hm[0][0] + p1.y() * p2.y() * hm[1][1] + p1.z() * p2.z() * hm[2][2] +
388  p1.x() * p2.y() * hm[0][1] + p2.x() * p1.y() * hm[1][0] +
389  p1.x() * p2.z() * hm[0][2] + p2.x() * p1.z() * hm[2][0] +
390  p1.y() * p2.z() * hm[1][2] + p2.y() * p1.z() * hm[2][1]) * invE1 * invE2;
391  hm[3][4] = (p1.x() * hm[0][4] + p1.y() * hm[1][4] + p1.z() * hm[2][4]) * invE1;
392  hm[3][5] = (p1.x() * hm[0][5] + p1.y() * hm[1][5] + p1.z() * hm[2][5]) * invE1;
393  hm[3][6] = (p1.x() * hm[0][6] + p1.y() * hm[1][6] + p1.z() * hm[2][6]) * invE1;
394 
395  return hm;
396  }
397 
398 
399  if (is_fix_mass1 && !is_fix_mass2) {
400  if (!isNonZeroEnergy(p1)) return HepSymMatrix(KFitConst::kNumber7, 0);
401 
402  HepMatrix hm(e);
403 
404  const double invE1 = 1 / p1.t();
405  hm[3][0] = (p1.x() * hm[0][0] + p1.y() * hm[1][0] + p1.z() * hm[2][0]) * invE1;
406  hm[3][1] = (p1.x() * hm[0][1] + p1.y() * hm[1][1] + p1.z() * hm[2][1]) * invE1;
407  hm[3][2] = (p1.x() * hm[0][2] + p1.y() * hm[1][2] + p1.z() * hm[2][2]) * invE1;
408  hm[3][3] = (p1.x() * hm[0][3] + p1.y() * hm[1][3] + p1.z() * hm[2][3]) * invE1;
409  hm[3][4] = (p1.x() * hm[0][4] + p1.y() * hm[1][4] + p1.z() * hm[2][4]) * invE1;
410  hm[3][5] = (p1.x() * hm[0][5] + p1.y() * hm[1][5] + p1.z() * hm[2][5]) * invE1;
411  hm[3][6] = (p1.x() * hm[0][6] + p1.y() * hm[1][6] + p1.z() * hm[2][6]) * invE1;
412 
413  return hm;
414  }
415 
416 
417  if (!is_fix_mass1 && is_fix_mass2) {
418  if (!isNonZeroEnergy(p2)) return HepSymMatrix(KFitConst::kNumber7, 0);
419 
420  HepMatrix hm(e);
421 
422  const double invE2 = 1 / p2.t();
423  hm[0][3] = (p2.x() * hm[0][0] + p2.y() * hm[0][1] + p2.z() * hm[0][2]) * invE2;
424  hm[1][3] = (p2.x() * hm[1][0] + p2.y() * hm[1][1] + p2.z() * hm[1][2]) * invE2;
425  hm[2][3] = (p2.x() * hm[2][0] + p2.y() * hm[2][1] + p2.z() * hm[2][2]) * invE2;
426  hm[3][3] = (p2.x() * hm[3][0] + p2.y() * hm[3][1] + p2.z() * hm[3][2]) * invE2;
427  hm[4][3] = (p2.x() * hm[4][0] + p2.y() * hm[4][1] + p2.z() * hm[4][2]) * invE2;
428  hm[5][3] = (p2.x() * hm[5][0] + p2.y() * hm[5][1] + p2.z() * hm[5][2]) * invE2;
429  hm[6][3] = (p2.x() * hm[6][0] + p2.y() * hm[6][1] + p2.z() * hm[6][2]) * invE2;
430 
431  return hm;
432  }
433 
434  return e;
435 }
436 
437 
438 const HepMatrix
439 KFitBase::makeError4(const HepLorentzVector& p, const HepMatrix& e) const
440 {
441  // vertex and track
442  // Error(3x7,e) ==> Error(3x7,output(hm)) using Momentum(p).
443  // Energy term is recalculated from the other parameters.
444 
445  if (!isNonZeroEnergy(p)) return HepSymMatrix(KFitConst::kNumber7, 0);
446 
447  HepMatrix hm(e);
448 
449  const double invE = 1 / p.t();
450  hm[0][3] = (p.x() * hm[0][0] + p.y() * hm[0][1] + p.z() * hm[0][2]) * invE;
451  hm[1][3] = (p.x() * hm[1][0] + p.y() * hm[1][1] + p.z() * hm[1][2]) * invE;
452  hm[2][3] = (p.x() * hm[2][0] + p.y() * hm[2][1] + p.z() * hm[2][2]) * invE;
453 
454  return hm;
455 }
456 
457 
458 enum KFitError::ECode
459 KFitBase::prepareCorrelation() {
460  if (m_BeforeCorrelation.size() != (double)m_TrackCount * ((double)m_TrackCount - 1)*.5)
461  {
462  m_ErrorCode = KFitError::kBadCorrelationSize;
463  KFitError::displayError(__FILE__, __LINE__, __func__, m_ErrorCode);
464  return m_ErrorCode;
465  }
466 
467  HepMatrix tmp_hm(KFitConst::kNumber6, KFitConst::kNumber6, 0);
468  int row = 0, col = 0;
469 
470  for (auto& hm : m_BeforeCorrelation)
471  {
472  row++;
473  if (row == m_TrackCount) {
474  col++;
475  row = col + 1;
476  }
477 
478  // 7x7 --> 6x6
479  for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {
480  tmp_hm[i][j] = hm[i][j];
481  tmp_hm[3 + i][3 + j] = hm[4 + i][4 + j];
482  tmp_hm[3 + i][j] = hm[4 + i][j];
483  tmp_hm[i][3 + j] = hm[i][4 + j];
484  }
485 
486  int ii = 0, jj = 0;
487  for (int i = KFitConst::kNumber6 * row; i < KFitConst::kNumber6 * (row + 1); i++) {
488  for (int j = KFitConst::kNumber6 * col; j < KFitConst::kNumber6 * (col + 1); j++) {
489  m_V_al_0[i][j] = tmp_hm[ii][jj];
490  jj++;
491  }
492  jj = 0;
493  ii++;
494  }
495  }
496 
497  return m_ErrorCode = KFitError::kNoError;
498 }
499 
500 
501 enum KFitError::ECode
502 KFitBase::doFit1() {
503  if (m_ErrorCode != KFitError::kNoError) return m_ErrorCode;
504 
505  if (m_TrackCount < m_NecessaryTrackCount)
506  {
507  m_ErrorCode = KFitError::kBadTrackSize;
508  KFitError::displayError(__FILE__, __LINE__, __func__, m_ErrorCode);
509  return m_ErrorCode;
510  }
511 
512  if (prepareInputMatrix() != KFitError::kNoError) return m_ErrorCode;
513  if (calculateNDF() != KFitError::kNoError) return m_ErrorCode;
514 
515 
516  double chisq = 0;
517  double tmp_chisq = KFitConst::kInitialCHIsq;
518  int err_inverse = 0;
519 
520  HepMatrix tmp_al_1(m_al_1);
521  HepMatrix tmp_V_al_1(m_V_al_1);
522 
523  m_al_a = m_al_0;
524  HepMatrix tmp_al_a(m_al_a);
525 
526 
527  for (int i = 0; i < KFitConst::kMaxIterationCount; i++)
528  {
529  if (makeCoreMatrix() != KFitError::kNoError) return m_ErrorCode;
530 
531  m_V_D = (m_V_al_0.similarity(m_D)).inverse(err_inverse);
532  if (err_inverse != 0) {
533  m_ErrorCode = KFitError::kCannotGetMatrixInverse;
534  return m_ErrorCode;
535  }
536 
537  m_lam = m_V_D * (m_D * (m_al_0 - m_al_1) + m_d);
538  chisq = ((m_lam.T()) * (m_D * (m_al_0 - m_al_1) + m_d))(1, 1);
539  m_al_1 = m_al_0 - m_V_al_0 * (m_D.T()) * m_lam;
540  m_V_al_1 = m_V_al_0 - m_V_al_0 * (m_D.T()) * m_V_D * m_D * m_V_al_0;
541 
542  if (tmp_chisq <= chisq) {
543  if (i == 0) {
544  m_ErrorCode = KFitError::kBadInitialCHIsq;
545  return m_ErrorCode;
546  } else {
547  chisq = tmp_chisq;
548  m_al_1 = tmp_al_1;
549  m_al_a = tmp_al_a;
550  m_V_al_1 = tmp_V_al_1;
551  break;
552  }
553  } else {
554  tmp_chisq = chisq;
555  tmp_al_a = tmp_al_1;
556  tmp_al_1 = m_al_1;
557  tmp_V_al_1 = m_V_al_1;
558  if (i == KFitConst::kMaxIterationCount - 1) {
559  m_al_a = tmp_al_1;
560  m_FlagOverIteration = true;
561  }
562  }
563  }
564 
565  if (m_ErrorCode != KFitError::kNoError) return m_ErrorCode;
566 
567  if (prepareOutputMatrix() != KFitError::kNoError) return m_ErrorCode;
568 
569  m_CHIsq = chisq;
570 
571  m_FlagFitted = true;
572 
573  return m_ErrorCode = KFitError::kNoError;
574 }
575 
576 
577 enum KFitError::ECode
578 KFitBase::doFit2() {
579  if (m_ErrorCode != KFitError::kNoError) return m_ErrorCode;
580 
581  if (m_TrackCount < m_NecessaryTrackCount)
582  {
583  m_ErrorCode = KFitError::kBadTrackSize;
584  KFitError::displayError(__FILE__, __LINE__, __func__, m_ErrorCode);
585  return m_ErrorCode;
586  }
587 
588  if (prepareInputMatrix() != KFitError::kNoError) return m_ErrorCode;
589  if (calculateNDF() != KFitError::kNoError) return m_ErrorCode;
590 
591 
592  double chisq = 0;
593  double tmp2_chisq = KFitConst::kInitialCHIsq;
594  int err_inverse = 0;
595 
596  m_al_a = m_al_0;
597  HepMatrix tmp_al_a(m_al_a);
598 
599  HepMatrix tmp_D(m_D), tmp_E(m_E);
600  HepMatrix tmp_V_D(m_V_D), tmp_V_E(m_V_E);
601  HepMatrix tmp_lam0(m_lam0), tmp_v_a(m_v_a);
602 
603  HepMatrix tmp2_D(m_D), tmp2_E(m_E);
604  HepMatrix tmp2_V_D(m_V_D), tmp2_V_E(m_V_E);
605  HepMatrix tmp2_lam0(m_lam0), tmp2_v_a(m_v_a), tmp2_v(m_v_a);
606 
607 
608  for (int j = 0; j < KFitConst::kMaxIterationCount; j++) // j'th loop start
609  {
610 
611  double tmp_chisq = KFitConst::kInitialCHIsq;
612 
613  for (int i = 0; i < KFitConst::kMaxIterationCount; i++) { // i'th loop start
614 
615  if (prepareInputSubMatrix() != KFitError::kNoError) return m_ErrorCode;
616  if (makeCoreMatrix() != KFitError::kNoError) return m_ErrorCode;
617 
618  m_V_D = (m_V_al_0.similarity(m_D)).inverse(err_inverse);
619  if (err_inverse) {
620  m_ErrorCode = KFitError::kCannotGetMatrixInverse;
621  return m_ErrorCode;
622  }
623 
624  m_V_E = ((m_E.T()) * m_V_D * m_E).inverse(err_inverse);
625  if (err_inverse) {
626  m_ErrorCode = KFitError::kCannotGetMatrixInverse;
627  return m_ErrorCode;
628  }
629  m_lam0 = m_V_D * (m_D * (m_al_0 - m_al_1) + m_d);
630  chisq = ((m_lam0.T()) * (m_D * (m_al_0 - m_al_1) + m_E * (m_v - m_v_a) + m_d))(1, 1);
631  m_v_a = m_v_a - m_V_E * (m_E.T()) * m_lam0;
632 
633  if (tmp_chisq <= chisq) {
634  if (i == 0) {
635  m_ErrorCode = KFitError::kBadInitialCHIsq;
636  return m_ErrorCode;
637  } else {
638  chisq = tmp_chisq;
639  m_v_a = tmp_v_a;
640  m_V_E = tmp_V_E;
641  m_V_D = tmp_V_D;
642  m_lam0 = tmp_lam0;
643  m_E = tmp_E;
644  m_D = tmp_D;
645  break;
646  }
647  } else {
648  tmp_chisq = chisq;
649  tmp_v_a = m_v_a;
650  tmp_V_E = m_V_E;
651  tmp_V_D = m_V_D;
652  tmp_lam0 = m_lam0;
653  tmp_E = m_E;
654  tmp_D = m_D;
655  if (i == KFitConst::kMaxIterationCount - 1) {
656  m_FlagOverIteration = true;
657  }
658  }
659  } // i'th loop over
660 
661 
662  m_al_a = m_al_1;
663  m_lam = m_lam0 - m_V_D * m_E * m_V_E * (m_E.T()) * m_lam0;
664  m_al_1 = m_al_0 - m_V_al_0 * (m_D.T()) * m_lam;
665 
666  if (j == 0) {
667 
668  tmp2_chisq = chisq;
669  tmp2_v_a = m_v_a;
670  tmp2_v = m_v;
671  tmp2_V_E = m_V_E;
672  tmp2_V_D = m_V_D;
673  tmp2_lam0 = m_lam0;
674  tmp2_E = m_E;
675  tmp2_D = m_D;
676  tmp_al_a = m_al_a;
677 
678  } else {
679 
680  if (tmp2_chisq <= chisq) {
681  chisq = tmp2_chisq;
682  m_v_a = tmp2_v_a;
683  m_v = tmp2_v;
684  m_V_E = tmp2_V_E;
685  m_V_D = tmp2_V_D;
686  m_lam0 = tmp2_lam0;
687  m_E = tmp2_E;
688  m_D = tmp2_D;
689  m_al_a = tmp_al_a;
690  break;
691  } else {
692  tmp2_chisq = chisq;
693  tmp2_v_a = m_v_a;
694  tmp2_v = m_v;
695  tmp2_V_E = m_V_E;
696  tmp2_V_D = m_V_D;
697  tmp2_lam0 = m_lam0;
698  tmp2_E = m_E;
699  tmp2_D = m_D;
700  tmp_al_a = m_al_a;
701  if (j == KFitConst::kMaxIterationCount - 1) {
702  m_FlagOverIteration = true;
703  }
704  }
705  }
706  } // j'th loop over
707 
708 
709  if (m_ErrorCode != KFitError::kNoError) return m_ErrorCode;
710 
711  m_lam = m_lam0 - m_V_D * m_E * m_V_E * (m_E.T()) * m_lam0;
712  m_al_1 = m_al_0 - m_V_al_0 * (m_D.T()) * m_lam;
713  m_V_Dt = m_V_D - m_V_D * m_E * m_V_E * (m_E.T()) * m_V_D;
714  m_V_al_1 = m_V_al_0 - m_V_al_0 * (m_D.T()) * m_V_Dt * m_D * m_V_al_0;
715  m_Cov_v_al_1 = -m_V_E * (m_E.T()) * m_V_D * m_D * m_V_al_0;
716 
717  if (prepareOutputMatrix() != KFitError::kNoError) return m_ErrorCode;
718 
719  m_CHIsq = chisq;
720 
721  m_FlagFitted = true;
722 
723  return m_ErrorCode = KFitError::kNoError;
724 }
725 
726 
727 bool
728 KFitBase::isFitted() const
729 {
730  if (m_FlagFitted) return true;
731 
732  KFitError::displayError(__FILE__, __LINE__, __func__, KFitError::kNotFittedYet);
733 
734  return false;
735 }
736 
737 
738 bool
739 KFitBase::isTrackIDInRange(const int id) const
740 {
741  if (0 <= id && id < m_TrackCount) return true;
742 
743  KFitError::displayError(__FILE__, __LINE__, __func__, KFitError::kOutOfRange);
744 
745  return false;
746 }
747 
748 
749 bool
750 KFitBase::isNonZeroEnergy(const HepLorentzVector& p) const
751 {
752  if (p.t() != 0) return true;
753 
754  KFitError::displayError(__FILE__, __LINE__, __func__, KFitError::kDivisionByZero);
755 
756  return false;
757 }
Class to store reconstructed particles.
Definition: Particle.h:75
ROOT::Math::XYZVector getVertex() const
Returns vertex position (POCA for charged, IP for neutral FS particles)
Definition: Particle.h:631
double getCharge(void) const
Returns particle charge.
Definition: Particle.cc:622
ROOT::Math::PxPyPzEVector get4Vector() const
Returns Lorentz vector.
Definition: Particle.h:547
TMatrixFSym getMomentumVertexErrorMatrix() const
Returns 7x7 error matrix.
Definition: Particle.cc:420
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.
Definition: ClusterUtils.h:24