Belle II Software light-2607-kasei
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 <analysis/VertexFitting/KFit/KFitBase.h>
11
12#include <analysis/utility/ROOTToCLHEP.h>
13#include <analysis/dataobjects/Particle.h>
14
15using namespace std;
16using namespace Belle2;
17using namespace Belle2::analysis;
18using namespace CLHEP;
19
32
33
34KFitBase::~KFitBase() = default;
35
36
39 m_Tracks.push_back(p);
40 m_TrackCount = m_Tracks.size();
41
43}
44
45
47KFitBase::addTrack(const CLHEP::HepLorentzVector& p, const HepPoint3D& x, const CLHEP::HepSymMatrix& e, const double q) {
48 if (e.num_row() != KFitConst::kNumber7)
49 {
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
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
70KFitBase::setCorrelation(const HepMatrix& e) {
71 if (e.num_row() != KFitConst::kNumber7)
72 {
74 KFitError::displayError(__FILE__, __LINE__, __func__, m_ErrorCode);
75 return m_ErrorCode;
76 }
77 m_BeforeCorrelation.push_back(e);
78 m_FlagCorrelation = true;
79
81}
82
83
86 HepMatrix zero(KFitConst::kNumber7, KFitConst::kNumber7, 0);
87
88 return this->setCorrelation(zero);
89}
90
91
94 m_MagneticField = mf;
95
97}
98
99
102 return m_ErrorCode;
103}
104
105
106int
108{
109 return m_TrackCount;
110}
111
112
113int
115{
116 return m_NDF;
117}
118
119
120double
122{
123 return m_CHIsq;
124}
125
126
127double
129{
130 return m_MagneticField;
131}
132
133
134double
135KFitBase::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
153const HepLorentzVector
154KFitBase::getTrackMomentum(const int id) const
155{
156 if (!isTrackIDInRange(id)) return HepLorentzVector();
157 return m_Tracks[id].getMomentum();
158}
159
160const HepPoint3D
161KFitBase::getTrackPosition(const int id) const
162{
163 if (!isTrackIDInRange(id)) return HepPoint3D();
164 return m_Tracks[id].getPosition();
165}
166
167const HepSymMatrix
168KFitBase::getTrackError(const int id) const
169{
170 if (!isTrackIDInRange(id)) return HepSymMatrix(KFitConst::kNumber7, 0);
171 return m_Tracks[id].getError();
172}
173
174const KFitTrack
175KFitBase::getTrack(const int id) const
176{
177 if (!isTrackIDInRange(id)) return KFitTrack();
178 return m_Tracks[id];
179}
180
181
182const HepMatrix
183KFitBase::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) {
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 // idx1 is min(id1, id2) and id1 != id2 here, so both branches are reachable
212 // cppcheck-suppress knownConditionTrueFalse
213 if (id1 == idx1)
214 return m_BeforeCorrelation[index + idx2];
215 else
216 return m_BeforeCorrelation[index + idx2].T();
217 }
218 }
219}
220
221
222HepSymMatrix
223KFitBase::makeError1(const CLHEP::HepLorentzVector& p, const CLHEP::HepMatrix& e)
224{
225 // self track
226 // Error(6x6,e) ==> Error(7x7,output(hsm)) using Momentum(p).
227
228 if (!isNonZeroEnergy(p)) return HepSymMatrix(KFitConst::kNumber7, 0);
229
230 HepSymMatrix hsm(KFitConst::kNumber7, 0);
231
232 for (int i = 0; i < 3; i++) for (int j = i; j < 3; j++) {
233 hsm[i][j] = e[i][j];
234 hsm[4 + i][4 + j] = e[3 + i][3 + j];
235 }
236 for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {
237 hsm[i][4 + j] = e[i][3 + j];
238 }
239
240 const double invE = 1 / p.t();
241 hsm[0][3] = (p.x() * hsm[0][0] + p.y() * hsm[0][1] + p.z() * hsm[0][2]) * invE;
242 hsm[1][3] = (p.x() * hsm[0][1] + p.y() * hsm[1][1] + p.z() * hsm[1][2]) * invE;
243 hsm[2][3] = (p.x() * hsm[0][2] + p.y() * hsm[1][2] + p.z() * hsm[2][2]) * invE;
244 hsm[3][3] = (p.x() * p.x() * hsm[0][0] + p.y() * p.y() * hsm[1][1] + p.z() * p.z() * hsm[2][2]
245 + 2.0 * p.x() * p.y() * hsm[0][1]
246 + 2.0 * p.x() * p.z() * hsm[0][2]
247 + 2.0 * p.y() * p.z() * hsm[1][2]) * invE * invE;
248 hsm[3][4] = (p.x() * hsm[0][4] + p.y() * hsm[1][4] + p.z() * hsm[2][4]) * invE;
249 hsm[3][5] = (p.x() * hsm[0][5] + p.y() * hsm[1][5] + p.z() * hsm[2][5]) * invE;
250 hsm[3][6] = (p.x() * hsm[0][6] + p.y() * hsm[1][6] + p.z() * hsm[2][6]) * invE;
251
252 return hsm;
253}
254
255
256HepMatrix
257KFitBase::makeError1(const CLHEP::HepLorentzVector& p1, const CLHEP::HepLorentzVector& p2, const CLHEP::HepMatrix& e)
258{
259 // track and track
260 // Error(6x6,e) ==> Error(7x7,output(hm)) using Momentum(p1&p2).
261
262 if (!isNonZeroEnergy(p1)) return HepSymMatrix(KFitConst::kNumber7, 0);
263 if (!isNonZeroEnergy(p2)) return HepSymMatrix(KFitConst::kNumber7, 0);
264
266
267 for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {
268 hm[i][j] = e[i][j];
269 hm[4 + i][4 + j] = e[3 + i][3 + j];
270 hm[4 + i][j] = e[3 + i][j];
271 hm[i][4 + j] = e[i][3 + j];
272 }
273
274 const double invE1 = 1 / p1.t();
275 const double invE2 = 1 / p2.t();
276 hm[0][3] = (p2.x() * hm[0][0] + p2.y() * hm[0][1] + p2.z() * hm[0][2]) * invE2;
277 hm[1][3] = (p2.x() * hm[1][0] + p2.y() * hm[1][1] + p2.z() * hm[1][2]) * invE2;
278 hm[2][3] = (p2.x() * hm[2][0] + p2.y() * hm[2][1] + p2.z() * hm[2][2]) * invE2;
279 hm[4][3] = (p2.x() * hm[4][0] + p2.y() * hm[4][1] + p2.z() * hm[4][2]) * invE2;
280 hm[5][3] = (p2.x() * hm[5][0] + p2.y() * hm[5][1] + p2.z() * hm[5][2]) * invE2;
281 hm[6][3] = (p2.x() * hm[6][0] + p2.y() * hm[6][1] + p2.z() * hm[6][2]) * invE2;
282 hm[3][3] = (p1.x() * p2.x() * hm[0][0] + p1.y() * p2.y() * hm[1][1] + p1.z() * p2.z() * hm[2][2] +
283 p1.x() * p2.y() * hm[0][1] + p2.x() * p1.y() * hm[1][0] +
284 p1.x() * p2.z() * hm[0][2] + p2.x() * p1.z() * hm[2][0] +
285 p1.y() * p2.z() * hm[1][2] + p2.y() * p1.z() * hm[2][1]) * invE1 * invE2;
286 hm[3][0] = (p1.x() * hm[0][0] + p1.y() * hm[1][0] + p1.z() * hm[2][0]) * invE1;
287 hm[3][1] = (p1.x() * hm[0][1] + p1.y() * hm[1][1] + p1.z() * hm[2][1]) * invE1;
288 hm[3][2] = (p1.x() * hm[0][2] + p1.y() * hm[1][2] + p1.z() * hm[2][2]) * invE1;
289 hm[3][4] = (p1.x() * hm[0][4] + p1.y() * hm[1][4] + p1.z() * hm[2][4]) * invE1;
290 hm[3][5] = (p1.x() * hm[0][5] + p1.y() * hm[1][5] + p1.z() * hm[2][5]) * invE1;
291 hm[3][6] = (p1.x() * hm[0][6] + p1.y() * hm[1][6] + p1.z() * hm[2][6]) * invE1;
292
293 return hm;
294}
295
296
297HepMatrix
298KFitBase::makeError2(const HepLorentzVector& p, const HepMatrix& e)
299{
300 // vertex and track
301 // Error(3x6,e) ==> Error(3x7,output(hm)) using Momentum(p).
302
303 if (!isNonZeroEnergy(p)) return HepSymMatrix(KFitConst::kNumber7, 0);
304
305 HepMatrix hm(3, KFitConst::kNumber7, 0);
306
307 for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {
308 hm[i][j] = e[i][j];
309 hm[i][4 + j] = e[i][3 + j];
310 }
311
312 const double invE = 1 / p.t();
313 hm[0][3] = (p.x() * hm[0][0] + p.y() * hm[0][1] + p.z() * hm[0][2]) * invE;
314 hm[1][3] = (p.x() * hm[1][0] + p.y() * hm[1][1] + p.z() * hm[1][2]) * invE;
315 hm[2][3] = (p.x() * hm[2][0] + p.y() * hm[2][1] + p.z() * hm[2][2]) * invE;
316
317 return hm;
318}
319
320
321HepSymMatrix
322KFitBase::makeError3(const CLHEP::HepLorentzVector& p, const CLHEP::HepMatrix& e, const bool is_fix_mass)
323{
324 // self track
325 // Error(7x7,e) ==> Error(7x7,output(hsm)) using Momentum(p).
326 // is_fix_mass = 1 : Energy term is recalculated from the other parameters.
327 // is_fix_mass = 0 : hsm = e.
328
329 if (!isNonZeroEnergy(p)) return HepSymMatrix(KFitConst::kNumber7, 0);
330
331 if (!is_fix_mass) {
332 HepSymMatrix hsm(KFitConst::kNumber7, 0);
333 for (int i = 0; i < 7; i++) for (int j = i; j < 7; j++) {
334 hsm[i][j] = e[i][j];
335 }
336 return hsm;
337 }
338
339 HepSymMatrix hsm(KFitConst::kNumber7, 0);
340
341 for (int i = 0; i < 7; i++) {
342 if (i != 3)
343 for (int j = i; j < 7; j++) hsm[i][j] = e[i][j];
344 }
345
346 double invE = 1 / p.t();
347 hsm[0][3] = (p.x() * hsm[0][0] + p.y() * hsm[0][1] + p.z() * hsm[0][2]) * invE;
348 hsm[1][3] = (p.x() * hsm[0][1] + p.y() * hsm[1][1] + p.z() * hsm[1][2]) * invE;
349 hsm[2][3] = (p.x() * hsm[0][2] + p.y() * hsm[1][2] + p.z() * hsm[2][2]) * invE;
350 hsm[3][3] = (p.x() * p.x() * hsm[0][0] + p.y() * p.y() * hsm[1][1] + p.z() * p.z() * hsm[2][2]
351 + 2.0 * p.x() * p.y() * hsm[0][1]
352 + 2.0 * p.x() * p.z() * hsm[0][2]
353 + 2.0 * p.y() * p.z() * hsm[1][2]) * invE * invE;
354 hsm[3][4] = (p.x() * hsm[0][4] + p.y() * hsm[1][4] + p.z() * hsm[2][4]) * invE;
355 hsm[3][5] = (p.x() * hsm[0][5] + p.y() * hsm[1][5] + p.z() * hsm[2][5]) * invE;
356 hsm[3][6] = (p.x() * hsm[0][6] + p.y() * hsm[1][6] + p.z() * hsm[2][6]) * invE;
357
358 return hsm;
359}
360
361
362HepMatrix
363KFitBase::makeError3(const CLHEP::HepLorentzVector& p1, const CLHEP::HepLorentzVector& p2, const CLHEP::HepMatrix& e,
364 const bool is_fix_mass1,
365 const bool is_fix_mass2)
366{
367 // track and track
368 // Error(7x7,e) ==> Error(7x7,output(hm)) using Momentum(p1&p2).
369 // is_fix_mass = 1 : Energy term is recalculated from the other parameters.
370 // is_fix_mass = 0 : not.
371
372 if (is_fix_mass1 && is_fix_mass2) {
373 if (!isNonZeroEnergy(p1)) return HepSymMatrix(KFitConst::kNumber7, 0);
374 if (!isNonZeroEnergy(p2)) return HepSymMatrix(KFitConst::kNumber7, 0);
375
376 HepMatrix hm(e);
377
378 const double invE1 = 1 / p1.t();
379 const double invE2 = 1 / p2.t();
380 hm[0][3] = (p2.x() * hm[0][0] + p2.y() * hm[0][1] + p2.z() * hm[0][2]) * invE2;
381 hm[1][3] = (p2.x() * hm[1][0] + p2.y() * hm[1][1] + p2.z() * hm[1][2]) * invE2;
382 hm[2][3] = (p2.x() * hm[2][0] + p2.y() * hm[2][1] + p2.z() * hm[2][2]) * invE2;
383 hm[4][3] = (p2.x() * hm[4][0] + p2.y() * hm[4][1] + p2.z() * hm[4][2]) * invE2;
384 hm[5][3] = (p2.x() * hm[5][0] + p2.y() * hm[5][1] + p2.z() * hm[5][2]) * invE2;
385 hm[6][3] = (p2.x() * hm[6][0] + p2.y() * hm[6][1] + p2.z() * hm[6][2]) * invE2;
386 hm[3][0] = (p1.x() * hm[0][0] + p1.y() * hm[1][0] + p1.z() * hm[2][0]) * invE1;
387 hm[3][1] = (p1.x() * hm[0][1] + p1.y() * hm[1][1] + p1.z() * hm[2][1]) * invE1;
388 hm[3][2] = (p1.x() * hm[0][2] + p1.y() * hm[1][2] + p1.z() * hm[2][2]) * invE1;
389 hm[3][3] = (p1.x() * p2.x() * hm[0][0] + p1.y() * p2.y() * hm[1][1] + p1.z() * p2.z() * hm[2][2] +
390 p1.x() * p2.y() * hm[0][1] + p2.x() * p1.y() * hm[1][0] +
391 p1.x() * p2.z() * hm[0][2] + p2.x() * p1.z() * hm[2][0] +
392 p1.y() * p2.z() * hm[1][2] + p2.y() * p1.z() * hm[2][1]) * invE1 * invE2;
393 hm[3][4] = (p1.x() * hm[0][4] + p1.y() * hm[1][4] + p1.z() * hm[2][4]) * invE1;
394 hm[3][5] = (p1.x() * hm[0][5] + p1.y() * hm[1][5] + p1.z() * hm[2][5]) * invE1;
395 hm[3][6] = (p1.x() * hm[0][6] + p1.y() * hm[1][6] + p1.z() * hm[2][6]) * invE1;
396
397 return hm;
398 }
399
400
401 if (is_fix_mass1 && !is_fix_mass2) {
402 if (!isNonZeroEnergy(p1)) return HepSymMatrix(KFitConst::kNumber7, 0);
403
404 HepMatrix hm(e);
405
406 const double invE1 = 1 / p1.t();
407 hm[3][0] = (p1.x() * hm[0][0] + p1.y() * hm[1][0] + p1.z() * hm[2][0]) * invE1;
408 hm[3][1] = (p1.x() * hm[0][1] + p1.y() * hm[1][1] + p1.z() * hm[2][1]) * invE1;
409 hm[3][2] = (p1.x() * hm[0][2] + p1.y() * hm[1][2] + p1.z() * hm[2][2]) * invE1;
410 hm[3][3] = (p1.x() * hm[0][3] + p1.y() * hm[1][3] + p1.z() * hm[2][3]) * invE1;
411 hm[3][4] = (p1.x() * hm[0][4] + p1.y() * hm[1][4] + p1.z() * hm[2][4]) * invE1;
412 hm[3][5] = (p1.x() * hm[0][5] + p1.y() * hm[1][5] + p1.z() * hm[2][5]) * invE1;
413 hm[3][6] = (p1.x() * hm[0][6] + p1.y() * hm[1][6] + p1.z() * hm[2][6]) * invE1;
414
415 return hm;
416 }
417
418
419 if (!is_fix_mass1 && is_fix_mass2) {
420 if (!isNonZeroEnergy(p2)) return HepSymMatrix(KFitConst::kNumber7, 0);
421
422 HepMatrix hm(e);
423
424 const double invE2 = 1 / p2.t();
425 hm[0][3] = (p2.x() * hm[0][0] + p2.y() * hm[0][1] + p2.z() * hm[0][2]) * invE2;
426 hm[1][3] = (p2.x() * hm[1][0] + p2.y() * hm[1][1] + p2.z() * hm[1][2]) * invE2;
427 hm[2][3] = (p2.x() * hm[2][0] + p2.y() * hm[2][1] + p2.z() * hm[2][2]) * invE2;
428 hm[3][3] = (p2.x() * hm[3][0] + p2.y() * hm[3][1] + p2.z() * hm[3][2]) * invE2;
429 hm[4][3] = (p2.x() * hm[4][0] + p2.y() * hm[4][1] + p2.z() * hm[4][2]) * invE2;
430 hm[5][3] = (p2.x() * hm[5][0] + p2.y() * hm[5][1] + p2.z() * hm[5][2]) * invE2;
431 hm[6][3] = (p2.x() * hm[6][0] + p2.y() * hm[6][1] + p2.z() * hm[6][2]) * invE2;
432
433 return hm;
434 }
435
436 return e;
437}
438
439
440HepMatrix
441KFitBase::makeError4(const HepLorentzVector& p, const HepMatrix& e)
442{
443 // vertex and track
444 // Error(3x7,e) ==> Error(3x7,output(hm)) using Momentum(p).
445 // Energy term is recalculated from the other parameters.
446
447 if (!isNonZeroEnergy(p)) return HepSymMatrix(KFitConst::kNumber7, 0);
448
449 HepMatrix hm(e);
450
451 const double invE = 1 / p.t();
452 hm[0][3] = (p.x() * hm[0][0] + p.y() * hm[0][1] + p.z() * hm[0][2]) * invE;
453 hm[1][3] = (p.x() * hm[1][0] + p.y() * hm[1][1] + p.z() * hm[1][2]) * invE;
454 hm[2][3] = (p.x() * hm[2][0] + p.y() * hm[2][1] + p.z() * hm[2][2]) * invE;
455
456 return hm;
457}
458
459
462 if (m_BeforeCorrelation.size() != (double)m_TrackCount * ((double)m_TrackCount - 1)*.5)
463 {
465 KFitError::displayError(__FILE__, __LINE__, __func__, m_ErrorCode);
466 return m_ErrorCode;
467 }
468
469 HepMatrix tmp_hm(KFitConst::kNumber6, KFitConst::kNumber6, 0);
470 int row = 0, col = 0;
471
472 for (const auto& hm : m_BeforeCorrelation)
473 {
474 row++;
475 if (row == m_TrackCount) {
476 col++;
477 row = col + 1;
478 }
479
480 // 7x7 --> 6x6
481 for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) {
482 tmp_hm[i][j] = hm[i][j];
483 tmp_hm[3 + i][3 + j] = hm[4 + i][4 + j];
484 tmp_hm[3 + i][j] = hm[4 + i][j];
485 tmp_hm[i][3 + j] = hm[i][4 + j];
486 }
487
488 int ii = 0, jj = 0;
489 for (int i = KFitConst::kNumber6 * row; i < KFitConst::kNumber6 * (row + 1); i++) {
490 for (int j = KFitConst::kNumber6 * col; j < KFitConst::kNumber6 * (col + 1); j++) {
491 m_V_al_0[i][j] = tmp_hm[ii][jj];
492 jj++;
493 }
494 jj = 0;
495 ii++;
496 }
497 }
498
500}
501
502
506
508 {
510 KFitError::displayError(__FILE__, __LINE__, __func__, m_ErrorCode);
511 return m_ErrorCode;
512 }
513
516
517
518 double chisq = 0;
519 double tmp_chisq = KFitConst::kInitialCHIsq;
520 int err_inverse = 0;
521
522 HepMatrix tmp_al_1(m_al_1);
523 HepMatrix tmp_V_al_1(m_V_al_1);
524
525 m_al_a = m_al_0;
526 HepMatrix tmp_al_a(m_al_a);
527
528
529 for (int i = 0; i < KFitConst::kMaxIterationCount; i++)
530 {
532
533 m_V_D = (m_V_al_0.similarity(m_D)).inverse(err_inverse);
534 if (err_inverse != 0) {
536 return m_ErrorCode;
537 }
538
539 m_lam = m_V_D * (m_D * (m_al_0 - m_al_1) + m_d);
540 chisq = ((m_lam.T()) * (m_D * (m_al_0 - m_al_1) + m_d))(1, 1);
541 m_al_1 = m_al_0 - m_V_al_0 * (m_D.T()) * m_lam;
542 m_V_al_1 = m_V_al_0 - m_V_al_0 * (m_D.T()) * m_V_D * m_D * m_V_al_0;
543
544 if (tmp_chisq <= chisq) {
545 if (i == 0) {
547 return m_ErrorCode;
548 } else {
549 chisq = tmp_chisq;
550 m_al_1 = tmp_al_1;
551 m_al_a = tmp_al_a;
552 m_V_al_1 = tmp_V_al_1;
553 break;
554 }
555 } else {
556 tmp_chisq = chisq;
557 tmp_al_a = tmp_al_1;
558 tmp_al_1 = m_al_1;
559 tmp_V_al_1 = m_V_al_1;
560 if (i == KFitConst::kMaxIterationCount - 1) {
561 m_al_a = tmp_al_1;
562 m_FlagOverIteration = true;
563 }
564 }
565 }
566
568
570
571 m_CHIsq = chisq;
572
573 m_FlagFitted = true;
574
576}
577
578
582
584 {
586 KFitError::displayError(__FILE__, __LINE__, __func__, m_ErrorCode);
587 return m_ErrorCode;
588 }
589
592
593
594 double chisq = 0;
595 double tmp2_chisq = KFitConst::kInitialCHIsq;
596 int err_inverse = 0;
597
598 m_al_a = m_al_0;
599 HepMatrix tmp_al_a(m_al_a);
600
601 HepMatrix tmp_D(m_D), tmp_E(m_E);
602 HepMatrix tmp_V_D(m_V_D), tmp_V_E(m_V_E);
603 HepMatrix tmp_lam0(m_lam0), tmp_v_a(m_v_a);
604
605 HepMatrix tmp2_D(m_D), tmp2_E(m_E);
606 HepMatrix tmp2_V_D(m_V_D), tmp2_V_E(m_V_E);
607 HepMatrix tmp2_lam0(m_lam0), tmp2_v_a(m_v_a), tmp2_v(m_v_a);
608
609
610 for (int j = 0; j < KFitConst::kMaxIterationCount; j++) // j'th loop start
611 {
612
613 double tmp_chisq = KFitConst::kInitialCHIsq;
614
615 for (int i = 0; i < KFitConst::kMaxIterationCount; i++) { // i'th loop start
616
619
620 m_V_D = (m_V_al_0.similarity(m_D)).inverse(err_inverse);
621 if (err_inverse) {
623 return m_ErrorCode;
624 }
625
626 m_V_E = ((m_E.T()) * m_V_D * m_E).inverse(err_inverse);
627 if (err_inverse) {
629 return m_ErrorCode;
630 }
631 m_lam0 = m_V_D * (m_D * (m_al_0 - m_al_1) + m_d);
632 chisq = ((m_lam0.T()) * (m_D * (m_al_0 - m_al_1) + m_E * (m_v - m_v_a) + m_d))(1, 1);
633 m_v_a = m_v_a - m_V_E * (m_E.T()) * m_lam0;
634
635 if (tmp_chisq <= chisq) {
636 if (i == 0) {
638 return m_ErrorCode;
639 } else {
640 chisq = tmp_chisq;
641 m_v_a = tmp_v_a;
642 m_V_E = tmp_V_E;
643 m_V_D = tmp_V_D;
644 m_lam0 = tmp_lam0;
645 m_E = tmp_E;
646 m_D = tmp_D;
647 break;
648 }
649 } else {
650 tmp_chisq = chisq;
651 tmp_v_a = m_v_a;
652 tmp_V_E = m_V_E;
653 tmp_V_D = m_V_D;
654 tmp_lam0 = m_lam0;
655 tmp_E = m_E;
656 tmp_D = m_D;
657 if (i == KFitConst::kMaxIterationCount - 1) {
658 m_FlagOverIteration = true;
659 }
660 }
661 } // i'th loop over
662
663
664 m_al_a = m_al_1;
665 m_lam = m_lam0 - m_V_D * m_E * m_V_E * (m_E.T()) * m_lam0;
666 m_al_1 = m_al_0 - m_V_al_0 * (m_D.T()) * m_lam;
667
668 if (j == 0) {
669
670 tmp2_chisq = chisq;
671 tmp2_v_a = m_v_a;
672 tmp2_v = m_v;
673 tmp2_V_E = m_V_E;
674 tmp2_V_D = m_V_D;
675 tmp2_lam0 = m_lam0;
676 tmp2_E = m_E;
677 tmp2_D = m_D;
678 tmp_al_a = m_al_a;
679
680 } else {
681
682 if (tmp2_chisq <= chisq) {
683 chisq = tmp2_chisq;
684 m_v_a = tmp2_v_a;
685 m_v = tmp2_v;
686 m_V_E = tmp2_V_E;
687 m_V_D = tmp2_V_D;
688 m_lam0 = tmp2_lam0;
689 m_E = tmp2_E;
690 m_D = tmp2_D;
691 m_al_a = tmp_al_a;
692 break;
693 } else {
694 tmp2_chisq = chisq;
695 tmp2_v_a = m_v_a;
696 tmp2_v = m_v;
697 tmp2_V_E = m_V_E;
698 tmp2_V_D = m_V_D;
699 tmp2_lam0 = m_lam0;
700 tmp2_E = m_E;
701 tmp2_D = m_D;
702 tmp_al_a = m_al_a;
703 if (j == KFitConst::kMaxIterationCount - 1) {
704 m_FlagOverIteration = true;
705 }
706 }
707 }
708 } // j'th loop over
709
710
712
713 m_lam = m_lam0 - m_V_D * m_E * m_V_E * (m_E.T()) * m_lam0;
714 m_al_1 = m_al_0 - m_V_al_0 * (m_D.T()) * m_lam;
715 m_V_Dt = m_V_D - m_V_D * m_E * m_V_E * (m_E.T()) * m_V_D;
716 m_V_al_1 = m_V_al_0 - m_V_al_0 * (m_D.T()) * m_V_Dt * m_D * m_V_al_0;
717 m_Cov_v_al_1 = -m_V_E * (m_E.T()) * m_V_D * m_D * m_V_al_0;
718
720
721 m_CHIsq = chisq;
722
723 m_FlagFitted = true;
724
726}
727
728
729bool
731{
732 if (m_FlagFitted) return true;
733
734 KFitError::displayError(__FILE__, __LINE__, __func__, KFitError::kNotFittedYet);
735
736 return false;
737}
738
739
740bool
741KFitBase::isTrackIDInRange(const int id) const
742{
743 if (0 <= id && id < m_TrackCount) return true;
744
745 KFitError::displayError(__FILE__, __LINE__, __func__, KFitError::kOutOfRange);
746
747 return false;
748}
749
750
751bool
752KFitBase::isNonZeroEnergy(const HepLorentzVector& p)
753{
754 if (p.t() != 0) return true;
755
756 KFitError::displayError(__FILE__, __LINE__, __func__, KFitError::kDivisionByZero);
757
758 return false;
759}
Class to store reconstructed particles.
Definition Particle.h:76
ROOT::Math::XYZVector getVertex() const
Returns vertex position (POCA for charged, IP for neutral FS particles)
Definition Particle.h:651
double getCharge(void) const
Returns particle charge.
Definition Particle.cc:653
ROOT::Math::PxPyPzEVector get4Vector() const
Returns Lorentz vector.
Definition Particle.h:567
TMatrixFSym getMomentumVertexErrorMatrix() const
Returns 7x7 error matrix.
Definition Particle.cc:451
KFitBase(void)
Construct an object with no argument.
Definition KFitBase.cc:20
int m_NecessaryTrackCount
Number needed tracks to perform fit.
Definition KFitBase.h:303
virtual enum KFitError::ECode prepareInputMatrix(void)=0
Build grand matrices for minimum search from input-track properties.
enum KFitError::ECode addTrack(const KFitTrack &kp)
Add a track to the fitter object.
Definition KFitBase.cc:38
virtual enum KFitError::ECode prepareOutputMatrix(void)=0
Build an output error matrix.
double m_MagneticField
Magnetic field.
Definition KFitBase.h:311
static CLHEP::HepSymMatrix makeError3(const CLHEP::HepLorentzVector &p, const CLHEP::HepMatrix &e, const bool is_fix_mass)
Rebuild an error matrix from a Lorentz vector and an error matrix.
Definition KFitBase.cc:322
CLHEP::HepMatrix m_al_1
See J.Tanaka Ph.D (2001) p136 for definition.
Definition KFitBase.h:259
CLHEP::HepMatrix m_V_Dt
See J.Tanaka Ph.D (2001) p138 for definition.
Definition KFitBase.h:289
virtual enum KFitError::ECode setCorrelation(const CLHEP::HepMatrix &c)
Set a correlation matrix.
Definition KFitBase.cc:70
const CLHEP::HepSymMatrix getTrackError(const int id) const
Get an error matrix of the track.
Definition KFitBase.cc:168
virtual double getCHIsq(void) const
Get a chi-square of the fit.
Definition KFitBase.cc:121
const CLHEP::HepLorentzVector getTrackMomentum(const int id) const
Get a Lorentz vector of the track.
Definition KFitBase.cc:154
static CLHEP::HepSymMatrix makeError1(const CLHEP::HepLorentzVector &p, const CLHEP::HepMatrix &e)
Rebuild an error matrix from a Lorentz vector and an error matrix.
Definition KFitBase.cc:223
CLHEP::HepMatrix m_lam
See J.Tanaka Ph.D (2001) p137 for definition.
Definition KFitBase.h:276
double getMagneticField(void) const
Get a magnetic field.
Definition KFitBase.cc:128
enum KFitError::ECode doFit2(void)
Perform a fit (used in VertexFitKFit::doFit() and MassVertexFitKFit::doFit()).
Definition KFitBase.cc:580
CLHEP::HepMatrix m_E
See J.Tanaka Ph.D (2001) p137 for definition.
Definition KFitBase.h:279
static CLHEP::HepMatrix makeError2(const CLHEP::HepLorentzVector &p, const CLHEP::HepMatrix &e)
Rebuild an error matrix from a Lorentz vector and an error matrix.
Definition KFitBase.cc:298
const HepPoint3D getTrackPosition(const int id) const
Get a position of the track.
Definition KFitBase.cc:161
bool m_FlagOverIteration
Flag whether the iteration count exceeds the limit.
Definition KFitBase.h:308
virtual double getTrackCHIsq(const int id) const
Get a chi-square of the track.
Definition KFitBase.cc:135
enum KFitError::ECode m_ErrorCode
Error code.
Definition KFitBase.h:243
virtual enum KFitError::ECode prepareInputSubMatrix(void)=0
Build sub-matrices for minimum search from input-track properties.
virtual enum KFitError::ECode setZeroCorrelation(void)
Indicate no correlation between tracks.
Definition KFitBase.cc:85
static CLHEP::HepMatrix makeError4(const CLHEP::HepLorentzVector &p, const CLHEP::HepMatrix &e)
Rebuild an error matrix from a Lorentz vector and an error matrix.
Definition KFitBase.cc:441
CLHEP::HepMatrix m_V_al_1
See J.Tanaka Ph.D (2001) p138 for definition.
Definition KFitBase.h:274
virtual int getNDF(void) const
Get an NDF of the fit.
Definition KFitBase.cc:114
CLHEP::HepMatrix m_d
See J.Tanaka Ph.D (2001) p137 for definition.
Definition KFitBase.h:268
CLHEP::HepMatrix m_lam0
See J.Tanaka Ph.D (2001) p138 for definition.
Definition KFitBase.h:283
virtual ~KFitBase(void)
Destruct the object.
bool isFitted(void) const
Return false if fit is not performed yet or performed fit is failed; otherwise true.
Definition KFitBase.cc:730
CLHEP::HepMatrix m_al_a
See J.Tanaka Ph.D (2001) p137 for definition.
Definition KFitBase.h:261
enum KFitError::ECode setMagneticField(const double mf)
Change a magnetic field from the default value KFitConst::kDefaultMagneticField.
Definition KFitBase.cc:93
CLHEP::HepMatrix m_D
See J.Tanaka Ph.D (2001) p137 for definition.
Definition KFitBase.h:266
CLHEP::HepMatrix m_V_D
See J.Tanaka Ph.D (2001) p138 for definition.
Definition KFitBase.h:271
bool isTrackIDInRange(const int id) const
Check if the id is in the range.
Definition KFitBase.cc:741
static bool isNonZeroEnergy(const CLHEP::HepLorentzVector &p)
Check if the energy is non-zero.
Definition KFitBase.cc:752
CLHEP::HepMatrix m_v_a
See J.Tanaka Ph.D (2001) p137 for definition.
Definition KFitBase.h:287
virtual const CLHEP::HepMatrix getCorrelation(const int id1, const int id2, const int flag=KFitConst::kAfterFit) const
Get a correlation matrix between two tracks.
Definition KFitBase.cc:183
bool m_FlagCorrelation
Flag whether a correlation among tracks exists.
Definition KFitBase.h:306
CLHEP::HepSymMatrix m_V_al_0
See J.Tanaka Ph.D (2001) p137 for definition.
Definition KFitBase.h:255
CLHEP::HepMatrix m_V_E
See J.Tanaka Ph.D (2001) p138 for definition.
Definition KFitBase.h:281
CLHEP::HepMatrix m_Cov_v_al_1
See J.Tanaka Ph.D (2001) p137 for definition.
Definition KFitBase.h:291
const KFitTrack getTrack(const int id) const
Get a specified track object.
Definition KFitBase.cc:175
virtual enum KFitError::ECode prepareCorrelation(void)
Build a grand correlation matrix from input-track properties.
Definition KFitBase.cc:461
virtual enum KFitError::ECode makeCoreMatrix(void)=0
Build matrices using the kinematical constraint.
enum KFitError::ECode addParticle(const Particle *particle)
Add a particle to the fitter.
Definition KFitBase.cc:59
std::vector< CLHEP::HepMatrix > m_BeforeCorrelation
Container of input correlation matrices.
Definition KFitBase.h:251
bool m_FlagFitted
Flag to indicate if the fit is performed and succeeded.
Definition KFitBase.h:245
double m_CHIsq
chi-square of the fit.
Definition KFitBase.h:297
int getTrackCount(void) const
Get the number of added tracks.
Definition KFitBase.cc:107
int m_NDF
NDF of the fit.
Definition KFitBase.h:295
std::vector< KFitTrack > m_Tracks
Container of input tracks.
Definition KFitBase.h:249
CLHEP::HepMatrix m_v
See J.Tanaka Ph.D (2001) p137 for definition.
Definition KFitBase.h:285
virtual enum KFitError::ECode calculateNDF(void)=0
Calculate an NDF of the fit.
int m_TrackCount
Number of tracks.
Definition KFitBase.h:301
CLHEP::HepMatrix m_al_0
See J.Tanaka Ph.D (2001) p136 for definition.
Definition KFitBase.h:257
enum KFitError::ECode doFit1(void)
Perform a fit (used in MassFitKFit::doFit()).
Definition KFitBase.cc:504
enum KFitError::ECode getErrorCode(void) const
Get a code of the last error.
Definition KFitBase.cc:101
static void displayError(const char *file, const int line, const char *func, const enum ECode code)
Display a description of error and its location.
Definition KFitError.h:71
ECode
ECode is a error code enumerate.
Definition KFitError.h:33
@ kCannotGetMatrixInverse
Cannot calculate matrix inverse (bad track property or internal error)
Definition KFitError.h:57
@ kOutOfRange
Specified track-id out of range.
Definition KFitError.h:41
@ kNotFittedYet
Not fitted yet.
Definition KFitError.h:38
@ kDivisionByZero
Division by zero (bad track property or internal error)
Definition KFitError.h:55
@ kBadInitialCHIsq
Bad initial chi-square (internal error)
Definition KFitError.h:52
@ kBadTrackSize
Track count too small to perform fit.
Definition KFitError.h:46
@ kBadMatrixSize
Wrong correlation matrix size.
Definition KFitError.h:48
@ kBadCorrelationSize
Wrong correlation matrix size (internal error)
Definition KFitError.h:50
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.
STL namespace.
static constexpr double kInitialCHIsq
Initial chi-square value (internal use)
Definition KFitConst.h:46
static constexpr double kDefaultMagneticField
Default magnetic field when not set externally.
Definition KFitConst.h:49
static const int kNumber6
Constant 6 to check matrix size (internal use)
Definition KFitConst.h:28
static const int kMaxIterationCount
Maximum iteration step (internal use)
Definition KFitConst.h:43
static const int kAfterFit
Input parameter to specify after-fit when setting/getting a track attribute.
Definition KFitConst.h:35
static const int kBeforeFit
Input parameter to specify before-fit when setting/getting a track attribute.
Definition KFitConst.h:33
static const int kNumber7
Constant 7 to check matrix size (internal use)
Definition KFitConst.h:30