12 #include "art/Framework/Services/Registry/ServiceHandle.h"
13 #include "boost/numeric/ublas/matrix_proxy.hpp"
14 #include "boost/numeric/ublas/vector_proxy.hpp"
15 #include "cetlib_except/exception.h"
23 #include "messagefacility/MessageLogger/MessageLogger.h"
29 #include "TLegendEntry.h"
33 #include "TPaveText.h"
35 #include "TVirtualPad.h"
56 const std::shared_ptr<const trkf::Surface>& psurf = hit.
getMeasSurface();
60 if (
const trkf::SurfYZPlane* pyz = dynamic_cast<const trkf::SurfYZPlane*>(&*psurf)) {
73 double z0 = pyz->z0();
74 double y0 = pyz->y0();
75 double phi = pyz->phi();
76 art::ServiceHandle<geo::Geometry const> geom;
77 double ymax = geom->DetHalfWidth();
79 z = z0 * std::cos(phi) + (ymax - y0) * std::sin(phi);
81 z = z0 * std::cos(phi) - (ymax + y0) * std::sin(phi);
83 else if (
const trkf::SurfYZLine* pyz = dynamic_cast<const trkf::SurfYZLine*>(&*psurf)) {
96 double z0 = pyz->z0();
97 double y0 = pyz->y0();
98 double phi = pyz->phi();
99 art::ServiceHandle<geo::Geometry const> geom;
100 double ymax = geom->DetHalfWidth();
102 z = z0 * std::cos(phi) + (ymax - y0) * std::sin(phi);
104 z = z0 * std::cos(phi) - (ymax + y0) * std::sin(phi);
142 double invp2 = invp * invp;
143 double invp3 = invp * invp2;
144 double invp4 = invp2 * invp2;
145 double mass2 = mass *
mass;
146 double k = std::sqrt(invp2 + mass2 * invp4);
147 double dkdinvp = (invp + 2. * mass2 * invp3) / k;
148 double vark = var_invp * dkdinvp * dkdinvp;
177 prod(temp1, vtemp1, vtemp2);
179 double derivk1 = -0.5 *
trkf::trace(temp1) + 0.5 * inner_prod(defl, vtemp2);
180 double derivk2 = 0.5 *
trkf::trace(temp2) - inner_prod(defl, vtemp3);
187 double q = 1. / std::sqrt(k);
188 double varq = vark / (4. * k * k *
k);
189 double derivq1 = (-2. * k /
q) * derivk1;
190 double derivq2 = 6. * k * k * derivk1 + 4. * k * k * k * derivk2;
196 double q1 = q - derivq1 / derivq2;
197 double varq1 = -1. / derivq2;
202 double newvarq = 1. / (1. / varq + 1. / varq1);
203 double newq = newvarq * (q / varq + q1 / varq1);
211 double c2 = 2. / (q4 + q2 * std::sqrt(q4 + 4. * mass2));
212 double c = std::sqrt(c2);
213 double dcdq = -2. * (c /
q) * (1. + mass2 * c2) / (1. + 2. * mass2 * c2);
214 double varc = varq * dcdq * dcdq;
231 , fMaxSeedIncChisq(0.)
232 , fMaxSmoothIncChisq(0.)
237 , fMaxSeedPredDist(0.)
245 , fFitMomRange(
false)
254 mf::LogInfo(
"KalmanFilterAlg") <<
"KalmanFilterAlg instantiated.";
256 fTrace = pset.get<
bool>(
"Trace");
257 fMaxPErr = pset.get<
double>(
"MaxPErr");
258 fGoodPErr = pset.get<
double>(
"GoodPErr");
264 fMaxLDist = pset.get<
double>(
"MaxLDist");
271 fGapDist = pset.get<
double>(
"GapDist");
276 fGTrace = pset.get<
bool>(
"GTrace");
278 fGTraceWW = pset.get<
double>(
"GTraceWW");
279 fGTraceWH = pset.get<
double>(
"GTraceWH");
282 fGTraceZMin = pset.get<std::vector<double>>(
"GTraceZMin");
283 fGTraceZMax = pset.get<std::vector<double>>(
"GTraceZMax");
320 throw cet::exception(
"KalmanFilterAlg") <<
"No direction for Kalman fit.\n";
330 std::ostringstream ostr;
331 ostr <<
"khit" << cnum;
332 fCanvases.emplace_back(
333 new TCanvas(ostr.str().c_str(), ostr.str().c_str(), fGTraceWW, fGTraceWH));
337 fCanvases.back()->Divide(2, nview / 2 + 1);
341 for (
int iview = 0; iview < nview; ++iview) {
343 std::ostringstream ostr;
344 ostr <<
"Plane " << iview;
346 fCanvases.back()->cd(iview + 1);
351 TPad*
p =
new TPad(ostr.str().c_str(), ostr.str().c_str(), zmin,
xmin, zmax, xmax);
352 p->SetBit(kCanDelete);
353 p->Range(fGTraceZMin[iview], fGTraceXMin, fGTraceZMax[iview], fGTraceXMax);
354 p->SetFillStyle(4000);
360 TText* t =
new TText(zmax - 0.02, xmax - 0.03, ostr.str().c_str());
361 t->SetBit(kCanDelete);
364 t->SetTextSize(0.04);
370 new TGaxis(zmin, xmin, zmax, xmin, fGTraceZMin[iview], fGTraceZMax[iview], 510,
"");
371 pz1->SetBit(kCanDelete);
374 TGaxis* px1 =
new TGaxis(zmin, xmin, zmin, xmax, fGTraceXMin, fGTraceXMax, 510,
"");
375 px1->SetBit(kCanDelete);
379 new TGaxis(zmin, xmax, zmax, xmax, fGTraceZMin[iview], fGTraceZMax[iview], 510,
"-");
380 pz2->SetBit(kCanDelete);
383 TGaxis* px2 =
new TGaxis(zmax, xmin, zmax, xmax, fGTraceXMin, fGTraceXMax, 510,
"L+");
384 px2->SetBit(kCanDelete);
390 fCanvases.back()->cd(nview + 1);
392 TLegend* leg =
new TLegend(0.6, 0.5, 0.99, 0.99);
393 leg->SetBit(kCanDelete);
395 TLegendEntry* entry = 0;
398 m =
new TMarker(0., 0., 20);
399 m->SetBit(kCanDelete);
400 m->SetMarkerSize(1.2);
401 m->SetMarkerColor(kRed);
402 entry = leg->AddEntry(m,
"Hits on Track",
"P");
403 entry->SetBit(kCanDelete);
405 m =
new TMarker(0., 0., 20);
406 m->SetBit(kCanDelete);
407 m->SetMarkerSize(1.2);
408 m->SetMarkerColor(kOrange);
409 entry = leg->AddEntry(m,
"Smoothed Hits on Track",
"P");
410 entry->SetBit(kCanDelete);
412 m =
new TMarker(0., 0., 20);
413 m->SetBit(kCanDelete);
414 m->SetMarkerSize(1.2);
415 m->SetMarkerColor(kBlack);
416 entry = leg->AddEntry(m,
"Available Hits",
"P");
417 entry->SetBit(kCanDelete);
419 m =
new TMarker(0., 0., 20);
420 m->SetBit(kCanDelete);
421 m->SetMarkerSize(1.2);
422 m->SetMarkerColor(kBlue);
423 entry = leg->AddEntry(m,
"Rejected Hits",
"P");
424 entry->SetBit(kCanDelete);
426 m =
new TMarker(0., 0., 20);
427 m->SetBit(kCanDelete);
428 m->SetMarkerSize(1.2);
429 m->SetMarkerColor(kGreen);
430 entry = leg->AddEntry(m,
"Removed Hits",
"P");
431 entry->SetBit(kCanDelete);
433 m =
new TMarker(0., 0., 20);
434 m->SetBit(kCanDelete);
435 m->SetMarkerSize(1.2);
436 m->SetMarkerColor(kMagenta);
437 entry = leg->AddEntry(m,
"Seed Hits",
"P");
438 entry->SetBit(kCanDelete);
440 m =
new TMarker(0., 0., 20);
441 m->SetBit(kCanDelete);
442 m->SetMarkerSize(1.2);
443 m->SetMarkerColor(kCyan);
444 entry = leg->AddEntry(m,
"Unreachable Seed Hits",
"P");
445 entry->SetBit(kCanDelete);
451 fMessages =
new TPaveText(0.01, 0.01, 0.55, 0.99,
"");
452 fMessages->SetBit(kCanDelete);
453 fMessages->SetTextFont(42);
454 fMessages->SetTextSize(0.04);
455 fMessages->SetTextAlign(12);
457 TText* t = fMessages->AddText(
"Enter buildTrack");
458 t->SetBit(kCanDelete);
460 fCanvases.back()->Update();
469 if (fGTrace && fCanvases.size() > 0) {
474 const std::list<KHitGroup>& groups = hits.
getSorted();
475 for (
auto const& gr : groups) {
479 const std::vector<std::shared_ptr<const KHitBase>>& phits = gr.getHits();
480 for (
auto const& phit : phits) {
483 if (pl >= 0 && pl <
int(fPads.size())) {
486 hit_position(hit, z, x);
487 TMarker* marker =
new TMarker(z, x, 20);
488 fMarkerMap[hit.
getID()] = marker;
490 marker->SetBit(kCanDelete);
491 marker->SetMarkerSize(0.5);
492 marker->SetMarkerColor(kMagenta);
502 const std::list<KHitGroup>& ugroups = hits.
getUnsorted();
503 for (
auto const& gr : ugroups) {
507 const std::vector<std::shared_ptr<const KHitBase>>& phits = gr.getHits();
508 for (
auto const& phit : phits) {
511 if (pl >= 0 && pl <
int(fPads.size())) {
514 hit_position(hit, z, x);
515 TMarker* marker =
new TMarker(z, x, 20);
516 fMarkerMap[hit.
getID()] = marker;
518 marker->SetBit(kCanDelete);
519 marker->SetMarkerSize(0.5);
520 marker->SetMarkerColor(kCyan);
525 fCanvases.back()->Update();
535 bool has_pref_plane =
false;
552 mf::LogInfo log(
"KalmanFilterAlg");
559 log <<
"Build Step " << step <<
"\n";
560 log <<
"KGTrack has " << trg.
numHits() <<
" hits.\n";
566 std::list<KHitGroup>::iterator it;
576 double path_est = gr.
getPath();
577 log <<
"Next surface: " << *(gr.
getSurface()) <<
"\n";
578 log <<
" Estimated path length of hit group = " << path_est <<
"\n";
586 std::shared_ptr<const Surface> psurf = trf.
getSurface();
587 if (gr.
getPlane() < 0)
throw cet::exception(
"KalmanFilterAlg") <<
"negative plane?\n";
593 if (dist &&
std::abs(*dist) > fMaxPropDist) dist = std::nullopt;
610 log <<
"After propagation\n";
611 log <<
" Incremental propagation distance = " << ds <<
"\n";
612 log <<
" Path length of prediction surface = " << path <<
"\n";
613 log <<
"KGTrack has " << trg.
numHits() <<
" hits.\n";
619 const std::vector<std::shared_ptr<const KHitBase>>& hits = gr.
getHits();
620 double best_chisq = 0.;
621 std::shared_ptr<const KHitBase> best_hit;
622 for (
std::vector<std::shared_ptr<const KHitBase>>::const_iterator ihit = hits.begin();
629 if (fGTrace && fCanvases.size() > 0) {
630 auto marker_it = fMarkerMap.find(hit.
getID());
631 if (marker_it != fMarkerMap.end()) {
632 TMarker* marker = marker_it->second;
633 marker->SetMarkerColor(kBlue);
645 log <<
"Trying Hit.\n"
646 << hit <<
"\nchisq = " << chisq <<
"\n"
647 <<
"prediction distance = " << preddist <<
"\n";
649 if ((!has_pref_plane ||
abs(preddist) < fMaxSeedPredDist) &&
650 (best_hit.get() == 0 || chisq < best_chisq)) {
652 if (chisq < fMaxSeedIncChisq) best_hit = *ihit;
657 log <<
"Best hit incremental chisquare = " << best_chisq <<
"\n";
658 if (best_hit.get() != 0) {
659 log <<
"Hit after prediction\n";
663 log <<
"No hit passed chisquare cut.\n";
665 if (fGTrace && fCanvases.size() > 0) fCanvases.back()->Update();
671 bool update_ok =
false;
672 if (best_hit.get() != 0) {
674 best_hit->update(trf);
676 if (!update_ok) trf = trf0;
679 ds += best_hit->getPredDistance();
680 tchisq += best_chisq;
692 if (fTrace) log <<
"Quitting because pointing error got too large.\n";
710 if (nsame <= fMaxSamePlane) {
714 if (fGTrace && fCanvases.size() > 0) {
715 int pl = best_hit->getMeasPlane();
716 if (pl >= 0 && pl <
int(fPads.size())) {
717 auto marker_it = fMarkerMap.find(best_hit->getID());
718 if (marker_it != fMarkerMap.end()) {
719 TMarker* marker = marker_it->second;
720 marker->SetMarkerColor(kRed);
728 fCanvases.back()->Update();
735 if (fPlane == gr.
getPlane()) has_pref_plane =
true;
739 if (!linear && pref != 0 &&
int(trg.
numHits()) >= fMinLHits &&
742 if (fTrace) log <<
"Killing reference track.\n";
746 log <<
"After update\n";
747 log <<
"KGTrack has " << trg.
numHits() <<
" hits.\n";
761 if (pref == 0 && dist &&
764 if (fTrace) log <<
"Resorting measurements.\n";
765 hits.
sort(trf,
true, prop, dir);
792 log <<
"KalmanFilterAlg build track summary.\n"
794 <<
"Track has " << trg.
numHits() <<
" hits.\n"
795 <<
"Track length = " << path <<
"\n"
796 <<
"Track chisquare = " << fchisq <<
"\n";
802 if (fGTrace && fCanvases.size() > 0) {
805 t = fMessages->AddText(
"Exit buildTrack, status success");
807 t = fMessages->AddText(
"Exit buildTrack, status fail");
808 t->SetBit(kCanDelete);
809 fInfoPad->Modified();
810 fCanvases.back()->Update();
914 throw cet::exception(
"KalmanFilterAlg") <<
"KalmanFilterAlg::smoothTrack(): no track!\n";
934 std::multimap<double, KHitTrack>::iterator it;
935 std::multimap<double, KHitTrack>::iterator itend;
946 throw cet::exception(
"KalmanFilterAlg")
947 <<
"KalmanFilterAlg::smoothTrack(): invalid direction\n";
950 mf::LogInfo log(
"KalmanFilterAlg");
956 while (dofit && it != itend) {
959 log <<
"Smooth Step " << step <<
"\n";
960 log <<
"Reverse fit track:\n";
970 log <<
"Forward track:\n";
980 std::shared_ptr<const Surface> psurf = trh.
getSurface();
1002 log <<
"Reverse fit track after propagation:\n";
1003 log <<
" Propagation distance = " << ds <<
"\n";
1036 log <<
"Combined track:\n";
1043 if (not hit.
predict(trf, prop, &ref)) {
1058 if (chisq < fMaxSmoothIncChisq) {
1065 bool update_ok = trf.
isValid();
1078 log <<
"Reverse fit track after update:\n";
1081 if (fGTrace && fCanvases.size() > 0) {
1082 auto marker_it = fMarkerMap.find(hit.
getID());
1083 if (marker_it != fMarkerMap.end()) {
1084 TMarker* marker = marker_it->second;
1085 marker->SetMarkerColor(kOrange);
1087 fCanvases.back()->Update();
1111 if (result && trg1 != 0 && trg1->
isValid()) {
1131 mf::LogInfo log(
"KalmanFilterAlg");
1132 log <<
"KalmanFilterAlg smooth track summary.\n"
1134 <<
"Track has " << trg.
numHits() <<
" hits.\n"
1136 <<
"Track chisquare = " << fchisq <<
"\n";
1162 bool result =
false;
1164 if (fGTrace && fCanvases.size() > 0) {
1165 TText* t = fMessages->AddText(
"Enter extendTrack");
1166 t->SetBit(kCanDelete);
1167 fInfoPad->Modified();
1168 fCanvases.back()->Update();
1173 unsigned int nhits0 = trg.
numHits();
1178 mf::LogInfo log(
"KalmanFilterAlg");
1251 hits.
sort(trf,
true, prop, dir);
1255 if (fGTrace && fCanvases.size() > 0) {
1260 const std::list<KHitGroup>& groups = hits.
getSorted();
1261 for (
auto const& gr : groups) {
1265 const std::vector<std::shared_ptr<const KHitBase>>& phits = gr.getHits();
1266 for (
auto const& phit : phits) {
1269 if (pl >= 0 && pl <
int(fPads.size())) {
1273 TMarker* marker = 0;
1274 auto marker_it = fMarkerMap.find(hit.
getID());
1275 if (marker_it == fMarkerMap.end()) {
1278 hit_position(hit, z, x);
1279 marker =
new TMarker(z, x, 20);
1280 fMarkerMap[hit.
getID()] = marker;
1282 marker->SetBit(kCanDelete);
1283 marker->SetMarkerSize(0.5);
1287 marker = marker_it->second;
1288 marker->SetMarkerColor(kBlack);
1296 const std::list<KHitGroup>& ugroups = hits.
getUnsorted();
1297 for (
auto const& gr : ugroups) {
1301 const std::vector<std::shared_ptr<const KHitBase>>& phits = gr.getHits();
1302 for (
auto const& phit : phits) {
1305 if (pl >= 0 && pl <
int(fPads.size())) {
1309 TMarker* marker = 0;
1310 auto marker_it = fMarkerMap.find(hit.
getID());
1311 if (marker_it == fMarkerMap.end()) {
1314 hit_position(hit, z, x);
1315 marker =
new TMarker(z, x, 20);
1316 fMarkerMap[hit.
getID()] = marker;
1318 marker->SetBit(kCanDelete);
1319 marker->SetMarkerSize(0.5);
1323 marker = marker_it->second;
1324 marker->SetMarkerColor(kBlue);
1328 fCanvases.back()->Update();
1337 int last_plane = -1;
1341 log <<
"Extend Step " << step <<
"\n";
1342 log <<
"KGTrack has " << trg.
numHits() <<
" hits.\n";
1348 std::list<KHitGroup>::iterator it;
1356 throw cet::exception(
"KalmanFilterAlg")
1357 <<
"KalmanFilterAlg::extendTrack(): invalid direction\n";
1362 double path_est = gr.
getPath();
1363 log <<
"Next surface: " << *(gr.
getSurface()) <<
"\n";
1364 log <<
" Estimated path length of hit group = " << path_est <<
"\n";
1372 std::shared_ptr<const Surface> psurf = trf.
getSurface();
1374 throw cet::exception(
"KalmanFilterAlg")
1375 <<
"KalmanFilterAlg::extendTrack(): negative plane?\n";
1381 if (dist &&
std::abs(*dist) > fMaxPropDist) dist = std::nullopt;
1398 log <<
"After propagation\n";
1399 log <<
" Incremental distance = " << ds <<
"\n";
1400 log <<
" Track path length = " << path <<
"\n";
1401 log <<
"KGTrack has " << trg.
numHits() <<
" hits.\n";
1407 const std::vector<std::shared_ptr<const KHitBase>>& hits = gr.
getHits();
1408 double best_chisq = 0.;
1409 std::shared_ptr<const KHitBase> best_hit;
1410 for (
std::vector<std::shared_ptr<const KHitBase>>::const_iterator ihit = hits.begin();
1417 if (fGTrace && fCanvases.size() > 0) {
1418 auto marker_it = fMarkerMap.find(hit.
getID());
1419 if (marker_it != fMarkerMap.end()) {
1420 TMarker* marker = marker_it->second;
1421 marker->SetMarkerColor(kBlue);
1429 bool ok = hit.
predict(trf, prop);
1433 if (
abs(preddist) < fMaxPredDist && (best_hit.get() == 0 || chisq < best_chisq)) {
1435 if (chisq < fMaxIncChisq) best_hit = *ihit;
1440 log <<
"Best hit incremental chisquare = " << best_chisq <<
"\n";
1441 if (best_hit.get() != 0) {
1442 log <<
"Hit after prediction\n";
1446 log <<
"No hit passed chisquare cut.\n";
1448 if (fGTrace && fCanvases.size() > 0) fCanvases.back()->Update();
1454 bool update_ok =
false;
1455 if (best_hit.get() != 0) {
1457 best_hit->update(trf);
1459 if (!update_ok) trf = trf0;
1462 ds += best_hit->getPredDistance();
1463 tchisq += best_chisq;
1474 if (fTrace) log <<
"Quitting because pointing error got too large.\n";
1492 if (nsame <= fMaxSamePlane) {
1496 if (fGTrace && fCanvases.size() > 0) {
1497 int pl = best_hit->getMeasPlane();
1498 if (pl >= 0 && pl <
int(fPads.size())) {
1499 auto marker_it = fMarkerMap.find(best_hit->getID());
1500 if (marker_it != fMarkerMap.end()) {
1501 TMarker* marker = marker_it->second;
1502 marker->SetMarkerColor(kRed);
1510 fCanvases.back()->Update();
1519 log <<
"After update\n";
1520 log <<
"KGTrack has " << trg.
numHits() <<
" hits.\n";
1536 if (fTrace) log <<
"Resorting measurements.\n";
1537 hits.
sort(trf,
true, prop, dir);
1563 throw cet::exception(
"KalmanFilterAlg")
1564 <<
"KalmanFilterAlg::extendTrack(): invalid direction [II]\n";
1570 log <<
"KalmanFilterAlg extend track summary.\n"
1572 <<
"Track has " << trg.
numHits() <<
" hits.\n"
1573 <<
"Track length = " << path <<
"\n"
1574 <<
"Track chisquare = " << fchisq <<
"\n";
1580 result = (trg.
numHits() > nhits0);
1582 if (fGTrace && fCanvases.size() > 0) {
1585 t = fMessages->AddText(
"Exit extendTrack, status success");
1587 t = fMessages->AddText(
"Exit extendTrack, status fail");
1588 t->SetBit(kCanDelete);
1589 fInfoPad->Modified();
1590 fCanvases.back()->Update();
1613 if (!trg.
isValid())
return false;
1619 throw cet::exception(
"KalmanFilterAlg")
1620 <<
"KalmanFilterAlg::fitMomentumRange(): invalid end track\n";
1671 const std::multimap<double, KHitTrack>& trackmap = trg.
getTrackMap();
1672 if (trackmap.size() < 2)
return false;
1673 std::multimap<double, KHitTrack>::const_iterator itend[2];
1674 itend[0] = trackmap.begin();
1675 itend[1] = trackmap.end();
1683 for (
int i = 0; result && i < 2; ++i) {
1684 const KHitTrack& trh = itend[i]->second;
1688 for (
int j = 0; j < 4; ++j) {
1689 if (
err(4, j) != 0.) result =
false;
1692 if (!result)
return result;
1708 double s_sample = itend[1]->first;
1709 const KETrack& tre = itend[1]->second;
1719 double invp0 = tre_noise.
getVector()(4);
1720 double var_invp0 = tre_noise.
getError()(4, 4);
1725 for (
auto it = trackmap.rbegin(); it != trackmap.rend(); ++it) {
1726 double s = it->first;
1737 if (
std::abs(s - s_sample) > fMinSampleDist) {
1741 std::shared_ptr<const Surface> psurf = trh.
getSurface();
1743 std::optional<double> dist_range =
1745 std::optional<double> dist_noise =
1751 bool momentum_updated =
false;
1752 if (dist_inf && dist_range && dist_noise) {
1756 double invp1 = tre_noise.
getVector()(4);
1757 double var_invp1 = tre_noise.
getError()(4, 4);
1762 double invp = 0.5 * (invp0 + invp1);
1763 double var_invp = 0.5 * (var_invp0 + var_invp1);
1764 double mass = tre_inf.
Mass();
1765 double beta = std::sqrt(1. + mass * mass * invp * invp);
1766 double invbp = invp / beta;
1784 project(tre_inf.
getError(), ublas::range(2, 4), ublas::range(2, 4));
1788 project(tre_noise.
getError(), ublas::range(2, 4), ublas::range(2, 4));
1794 double new_invp = invp;
1795 double new_var_invp = var_invp;
1796 update_momentum(defl, errc, errn, mass, new_invp, new_var_invp);
1801 double dp = 1. / new_invp - 1. / invp;
1802 invp0 = 1. / (1. / invp1 + dp);
1803 var_invp0 = new_var_invp;
1804 momentum_updated =
true;
1809 double invp_range = trk_range.
getVector()(4);
1810 if (invp0 > invp_range) invp0 = invp_range;
1815 if (momentum_updated) {
1820 double invp_range = trk_range.
getVector()(4);
1825 tre_noise.
getError()(4, 4) = var_invp0;
1834 const KHitTrack& trh0 = itend[0]->second;
1835 std::shared_ptr<const Surface> psurf = trh0.
getSurface();
1837 result = dist_noise.has_value();
1841 mf::LogInfo log(
"KalmanFilterAlg");
1842 if (result) tremom = tre_noise;
1864 mf::LogInfo log(
"KalmanFilterAlg");
1865 double invp_range = 0.;
1866 double invp_ms = 0.;
1873 ok_ms = fitMomentumMS(trg, prop, tremom_ms);
1876 ok_ms = updateMomentum(tremom_ms, prop, trg_ms);
1881 if (invp_ms != 0.) p = 1. / invp_ms;
1882 double err_p = p * p * std::sqrt(var_invp);
1883 log <<
"Multiple scattering momentum estimate = " << p <<
"+-" << err_p <<
"\n";
1891 bool ok_range =
false;
1893 ok_range = fitMomentumRange(trg, tremom_range);
1896 ok_range = updateMomentum(tremom_range, prop, trg_range);
1901 if (invp_range != 0.) p = 1. / invp_range;
1902 double err_p = p * p * std::sqrt(var_invp);
1903 log <<
"Range momentum estimate = " << p <<
"+-" << err_p <<
"\n";
1908 bool result =
false;
1910 tremom = tremom_range;
1948 std::multimap<double, KHitTrack>& trackmap = trg.
getTrackMap();
1952 if (trackmap.size() == 0)
return false;
1960 std::optional<double> dist0 =
1965 std::optional<double> dist1 =
1970 bool forward =
true;
1971 std::multimap<double, KHitTrack>::iterator it = trackmap.begin();
1983 it = trackmap.end();
1996 it = trackmap.end();
2015 throw cet::exception(
"KalmanFilterAlg")
2016 <<
"KalmanFilterAlg::updateMomentum(): invalid track\n";
2025 std::multimap<double, KHitTrack>::iterator erase_it = trackmap.end();
2046 done = (it == trackmap.end());
2049 done = (it == trackmap.begin());
2056 if (erase_it == trackmap.end())
2059 trackmap.erase(erase_it);
2062 return not
empty(trackmap);
2084 for (
int ismooth = 0; ok && ismooth < nsmooth - 1; ++ismooth) {
2086 ok = smoothTrack(trg, &trg1, prop);
2093 if (ok) ok = smoothTrack(trg, 0, prop);
2111 std::multimap<double, KHitTrack>& trackmap = trg.
getTrackMap();
2121 int ntrack = trackmap.size();
2122 if (ntrack <= fMaxNoiseHits) {
2123 for (
auto const& trackmap_entry : trackmap) {
2124 const KHitTrack& trh = trackmap_entry.second;
2126 auto marker_it = fMarkerMap.find(hit.
getID());
2127 if (marker_it != fMarkerMap.end()) {
2128 TMarker* marker = marker_it->second;
2129 marker->SetMarkerColor(kGreen);
2144 std::multimap<double, KHitTrack>::iterator it = trackmap.begin();
2154 if ((plane1 >= 0 && plane2 >= 0 && plane1 == plane2) || chisq1 > fMaxEndChisq ||
2155 chisq2 > fMaxEndChisq) {
2156 auto marker_it = fMarkerMap.find(hit1a.
getID());
2157 if (marker_it != fMarkerMap.end()) {
2158 TMarker* marker = marker_it->second;
2159 marker->SetMarkerColor(kGreen);
2161 trackmap.erase(trackmap.begin(), it);
2168 it = trackmap.end();
2179 if ((plane1 >= 0 && plane2 >= 0 && plane1 == plane2) || chisq1 > fMaxEndChisq ||
2180 chisq2 > fMaxEndChisq) {
2182 auto marker_it = fMarkerMap.find(hit1b.
getID());
2183 if (marker_it != fMarkerMap.end()) {
2184 TMarker* marker = marker_it->second;
2185 marker->SetMarkerColor(kGreen);
2187 trackmap.erase(it, trackmap.end());
2197 std::multimap<double, KHitTrack>::iterator it = trackmap.begin();
2198 std::multimap<double, KHitTrack>::iterator jt = trackmap.end();
2201 bool found_noise =
false;
2202 for (; it != trackmap.end(); ++it, ++nb, --ne) {
2203 if (jt == trackmap.end())
2204 jt = trackmap.begin();
2207 throw cet::exception(
"KalmanFilterAlg")
2208 <<
"KalmanFilterAlg::cleanTrack(): nb not positive\n";
2210 throw cet::exception(
"KalmanFilterAlg")
2211 <<
"KalmanFilterAlg::cleanTrack(): ne not positive\n";
2213 double disti = (*it).first;
2214 double distj = (*jt).first;
2215 double sep = disti - distj;
2217 throw cet::exception(
"KalmanFilterAlg")
2218 <<
"KalmanFilterAlg::fitMomentumRange(): negative separation\n";
2220 if (sep > fGapDist) {
2224 if (nb <= fMaxNoiseHits) {
2229 for (
auto jt = trackmap.begin(); jt != it; ++jt) {
2232 auto marker_it = fMarkerMap.find(hit.
getID());
2233 if (marker_it != fMarkerMap.end()) {
2234 TMarker* marker = marker_it->second;
2235 marker->SetMarkerColor(kGreen);
2238 trackmap.erase(trackmap.begin(), it);
2241 if (ne <= fMaxNoiseHits) {
2246 for (
auto jt = it; jt != trackmap.end(); ++jt) {
2249 auto marker_it = fMarkerMap.find(hit.
getID());
2250 if (marker_it != fMarkerMap.end()) {
2251 TMarker* marker = marker_it->second;
2252 marker->SetMarkerColor(kGreen);
2255 trackmap.erase(it, trackmap.end());
2265 done = !found_noise;
2267 if (fGTrace && fCanvases.size() > 0) fCanvases.back()->Update();
bool fGTrace
Graphical trace flag.
ublas::symmetric_matrix< double, ublas::lower, ublas::row_major, ublas::bounded_array< double, N *(N+1)/2 > > type
const TrackError & getError() const
Track error matrix.
process_name opflash particleana ie ie ie z
virtual double getChisq() const =0
Return incremental chisquare.
const std::shared_ptr< const KHitBase > & getHit() const
Measurement.
bool fFitMomRange
Fit momentum using range.
double fMaxPropDist
Maximum propagation distance to candidate surface.
double fGapDist
Minimum gap distance.
bool fFitMomMS
Fit momentum using multiple scattering.
virtual void update(KETrack &tre) const =0
Update track method.
double Mass() const
Based on pdg code.
const std::shared_ptr< const Surface > & getSurface() const
Surface.
double PointingError() const
Pointing error (radians).
double getPredDistance() const
Prediction distance.
void recalibrate()
Recalibrate track map.
process_name opflash particleana ie x
int getMeasPlane() const
Measurement plane index.
const std::list< KHitGroup > & getUnused() const
ublas::matrix< double, ublas::row_major, ublas::bounded_array< double, N *M > > type
bool smoothTrackIter(int niter, KGTrack &trg, const Propagator &prop) const
Iteratively smooth a track.
const KHitTrack & endTrack() const
Track at end point.
KSymMatrix< 5 >::type TrackError
Track error matrix, dimension 5x5.
const std::vector< std::shared_ptr< const KHitBase > > & getHits() const
Measurement collection accessor.
double fMaxEndChisq
Maximum incremental chisquare for endpoint hit.
Planar surface parallel to x-axis.
EResult err(const char *call)
KalmanFilterAlg(const fhicl::ParameterSet &pset)
Constructor.
A collection of KHitGroups.
void cleanTrack(KGTrack &trg) const
Clean track by removing noise hits near endpoints.
void addTrack(const KHitTrack &trh)
Add track.
double getPath() const
Estimated path distance.
FitStatus
Fit status enum.
int getID() const
Unique id.
virtual bool predict(const KETrack &tre, const Propagator &prop, const KTrack *ref=0) const =0
Prediction method (return false if fail).
tuple m
now if test mode generate materials, CRT shell, world, gdml header else just generate CRT shell for u...
std::vector< double > fGTraceZMin
Graphical trace minimum z for each view.
const std::multimap< double, KHitTrack > & getTrackMap() const
KHitTrack collection, indexed by path distance.
std::optional< double > vec_prop(KTrack &trk, const std::shared_ptr< const Surface > &psurf, PropDirection dir, bool doDedx, TrackMatrix *prop_matrix=0, TrackError *noise_matrix=0) const
Propagate without error (long distance).
double fMaxLDist
Maximum distance for linearized propagation.
double fMaxSortDist
Sort high distance threshold.
double fMaxSeedPredDist
Maximum prediciton distance to accept a hit in seed phase.
double fMaxPredDist
Maximum prediciton distance to accept a hit.
process_name pandoraGausCryo1 vertexChargeCryo1 vertexStubCryo1 xmin
BEGIN_PROLOG triggeremu_data_config_icarus settings PMTADCthresholds sequence::icarus_stage0_multiTPC_TPC physics sequence::icarus_stage0_EastHits_TPC physics sequence::icarus_stage0_WestHits_TPC physics producers purityana0 caloskimCalorimetryCryoE physics caloskimCalorimetryCryoW physics path
M::value_type trace(const M &m)
std::optional< double > noise_prop(KETrack &tre, const std::shared_ptr< const Surface > &psurf, PropDirection dir, bool doDedx, KTrack *ref=0) const
Propagate with error and noise.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
bool fitMomentumMS(const KGTrack &trg, const Propagator &prop, KETrack &tremom) const
Estimate track momentum using multiple scattering.
void setChisq(double chisq)
Set chisquare.
bool buildTrack(const KTrack &trk, KGTrack &trg, const Propagator &prop, const Propagator::PropDirection dir, KHitContainer &hits, bool linear) const
Make a new track.
double getPath() const
Propagation distance.
Kalman filter measurement class template.
ublas::vector< double, ublas::bounded_array< double, N > > type
bool syminvert(ublas::symmetric_matrix< T, TRI, L, A > &m)
double fGTraceWH
Window height.
bool extendTrack(KGTrack &trg, const Propagator &prop, KHitContainer &hits) const
Add hits to existing track.
std::optional< double > err_prop(KETrack &tre, const std::shared_ptr< const Surface > &psurf, PropDirection dir, bool doDedx, KTrack *ref=0, TrackMatrix *prop_matrix=0) const
Propagate with error, but without noise.
const std::list< KHitGroup > & getUnsorted() const
double fGTraceXMin
Graphical trace minimum x.
double fGoodPErr
Pointing error threshold for switching to free propagation.
void setStat(FitStatus stat)
Set fit status.
double fMaxSeedIncChisq
Maximum incremental chisquare to accept a hit in seed phase.
double fMaxSmoothIncChisq
Maximum incremental chisquare to accept a hit in smooth phase.
double fMaxIncChisq
Maximum incremental chisquare to accept a hit.
bool smoothTrack(KGTrack &trg, KGTrack *trg1, const Propagator &prop) const
Smooth track.
double fMinSampleDist
Minimum sample distance (for momentum measurement).
double fMinSortDist
Sort low distance threshold.
const TrackVector & getVector() const
Track state vector.
const KVector< N >::type & getMeasVector() const
Measurement vector.
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
double fGTraceXMax
Graphical trace maximum x.
void sort(const KTrack &trk, bool addUnsorted, const Propagator &prop, Propagator::PropDirection dir=Propagator::UNKNOWN)
(Re)sort objects in unsorted and sorted lists.
then echo File list $list not found else cat $list while read file do echo $file sed s
size_t numHits() const
Number of measurements in track.
double fGTraceWW
Window width.
const std::shared_ptr< const Surface > & getSurface() const
Surface accessor.
bool combineFit(const KFitTrack &trf)
Combine two tracks.
void setPath(double path)
Set propagation distance.
std::vector< double > fGTraceZMax
Graphical trace maximum z for each view.
int fMaxSamePlane
Maximum consecutive hits in same plane.
Line surface perpendicular to x-axis.
int fMaxNoiseHits
Maximum number of hits in noise cluster.
A collection of KHitTracks.
Basic Kalman filter track class, with fit information.
double fMaxPErr
Maximum pointing error for free propagation.
bool fitMomentumRange(const KGTrack &trg, KETrack &tremom) const
Estimate track momentum using range.
bool isValid() const
Validity flag.
bool empty(FixedBins< T, C > const &) noexcept
bool fitMomentum(const KGTrack &trg, const Propagator &prop, KETrack &tremom) const
Estimate track momentum using either range or multiple scattering.
bool updateMomentum(const KETrack &tremom, const Propagator &prop, KGTrack &trg) const
Set track momentum at each track surface.
double getChisq() const
Fit chisquare.
const KHitTrack & startTrack() const
Track at start point.
art framework interface to geometry description
const std::shared_ptr< const Surface > & getMeasSurface() const
Measurement surface.
int fMinLHits
Minimum number of hits to turn off linearized propagation.
bool isValid() const
Test if track is valid.
PropDirection
Propagation direction enum.
FitStatus getStat() const
Fit status.
int getPlane() const
Plane index.
const std::list< KHitGroup > & getSorted() const