Function where the core of the fit is performed.
312 fwdPrdTkState.clear();
313 fwdUpdTkState.clear();
315 rejectedhsidx.clear();
316 sortedtksidx.clear();
318 fwdPrdTkState.reserve(hitstatev.size());
319 fwdUpdTkState.reserve(hitstatev.size());
320 hitstateidx.reserve(hitstatev.size());
323 KFTrackState startState = trackState;
327 const unsigned int nplanes =
geom->MaxPlanes();
328 std::vector<std::vector<unsigned int>> hitsInPlanes(nplanes);
329 for (
unsigned int ihit = 0; ihit < hitstatev.size(); ihit++) {
330 hitsInPlanes[hitstatev[ihit].wireId().Plane].push_back(ihit);
333 for (
unsigned int iplane = 0; iplane < nplanes; ++iplane) {
334 if (
geom->Plane(iplane).GetIncreasingWireDirection<
Vector_t>().Dot(trackState.momentum()) >
336 std::sort(hitsInPlanes[iplane].
begin(),
337 hitsInPlanes[iplane].
end(),
338 [hitstatev](
const unsigned int&
a,
const unsigned int& b) ->
bool {
339 return hitstatev[
a].wireId().Wire < hitstatev[b].wireId().Wire;
343 std::sort(hitsInPlanes[iplane].
begin(),
344 hitsInPlanes[iplane].
end(),
345 [hitstatev](
const unsigned int& a,
const unsigned int& b) ->
bool {
346 return hitstatev[
a].wireId().Wire > hitstatev[b].wireId().Wire;
355 for (
auto p : hitsInPlanes) {
357 std::cout <<
"hit #/Plane/Wire/x/mask: " << ch++ <<
" " << hitstatev[
h].wireId().Plane
358 <<
" " << hitstatev[
h].wireId().Wire <<
" " << hitstatev[
h].hitMeas() <<
" "
359 << hitflagsv[
h] << std::endl;
365 std::vector<unsigned int> iterHitsInPlanes(nplanes, 0);
366 for (
unsigned int p = 0; p < hitstatev.size(); ++
p) {
369 std::cout <<
"hit sizes: rej=" << rejectedhsidx.size() <<
" good=" << hitstateidx.size()
370 <<
" input=" << hitstatev.size() << std::endl;
372 std::cout <<
"compute distance from state=" << std::endl;
376 double min_dist = DBL_MAX;
378 for (
unsigned int iplane = 0; iplane < nplanes; ++iplane) {
381 std::cout <<
"iplane=" << iplane <<
" nplanes=" << nplanes
382 <<
" iterHitsInPlanes[iplane]=" << iterHitsInPlanes[iplane]
383 <<
" hitsInPlanes[iplane].size()=" << hitsInPlanes[iplane].size() << std::endl;
384 for (
unsigned int& ih = iterHitsInPlanes[iplane]; ih < hitsInPlanes[iplane].size(); ++ih) {
386 unsigned int ihit = hitsInPlanes[iplane][ih];
388 std::cout <<
"ih=" << ih <<
" ihit=" << ihit <<
" size=" << hitsInPlanes[iplane].size()
390 const auto& hitstate = hitstatev[ihit];
391 const auto& hitflags = hitflagsv[ihit];
400 << hitflags << std::endl;
401 rejectedhsidx.push_back(ihit);
409 std::cout <<
"distance to plane " << iplane <<
" wire=" << hitstate.wireId().Wire
410 <<
" = " << dist <<
", min_dist=" << std::min(min_dist, 999.)
411 <<
" min_plane=" << min_plane <<
" success=" << success
412 <<
" wirepo=" << hitstate.plane().position() << std::endl;
414 rejectedhsidx.push_back(ihit);
417 if (applySkipClean &&
skipNegProp_ && fwdUpdTkState.size() > 0 &&
419 rejectedhsidx.push_back(ihit);
422 if (dist < min_dist) {
431 <<
"pick min_dist=" << min_dist <<
" min_plane=" << min_plane <<
" wire="
434 hitstatev[hitsInPlanes[min_plane][iterHitsInPlanes[min_plane]]].wireId().Wire)
439 if (rejectedhsidx.size() + hitstateidx.size() == hitstatev.size())
444 unsigned int ihit = hitsInPlanes[min_plane][iterHitsInPlanes[min_plane]];
445 const auto* hitstate = &hitstatev[ihit];
446 iterHitsInPlanes[min_plane]++;
452 trackState.trackState(),
457 if (!propok && !(applySkipClean && fwdUpdTkState.size() > 0 &&
skipNegProp_)) {
461 trackState.trackState(),
470 std::cout <<
"propagation result=" << propok << std::endl;
471 std::cout <<
"propagated state " << std::endl;
474 << hitstate->plane().direction().Dot(hitstate->plane().position() -
475 trackState.position())
477 std::cout <<
"residual=" << trackState.residual(*hitstate)
478 <<
" chi2=" << trackState.chi2(*hitstate) << std::endl;
483 if (applySkipClean && fwdUpdTkState.size() == 0 &&
486 std::cout <<
"rejecting first hit with residual=" << trackState.residual(*hitstate)
488 rejectedhsidx.push_back(ihit);
489 trackState = startState;
495 auto wire = hitstate->wireId().Wire;
496 float min_chi2_wire = trackState.chi2(*hitstate);
497 for (
unsigned int jh = iterHitsInPlanes[min_plane]; jh < hitsInPlanes[min_plane].size();
499 const unsigned int jhit = hitsInPlanes[min_plane][jh];
500 const auto& jhitstate = hitstatev[jhit];
501 if (jhitstate.wireId().Wire != wire)
break;
502 if (ihit != jhit) iterHitsInPlanes[min_plane]++;
503 float chi2 = trackState.chi2(jhitstate);
505 std::cout <<
"additional hit on the same wire with jhit=" << jhit <<
" chi2=" << chi2
506 <<
" ihit=" << ihit <<
" min_chi2_wire=" << min_chi2_wire << std::endl;
507 if (chi2 < min_chi2_wire) {
508 min_chi2_wire = chi2;
513 if (ihit != jhit) rejectedhsidx.push_back(ihit);
517 rejectedhsidx.push_back(jhit);
522 hitstate = &hitstatev[ihit];
523 auto& hitflags = hitflagsv[ihit];
526 if (fwdUpdTkState.size() > 0 && applySkipClean &&
531 std::cout <<
"rejecting hit with res=" <<
std::abs(trackState.residual(*hitstate))
532 <<
" chi2=" << trackState.chi2(*hitstate) <<
" dist=" << min_dist
535 if (fwdUpdTkState.size() > 0)
536 trackState = fwdUpdTkState.back();
538 trackState = startState;
539 rejectedhsidx.push_back(ihit);
547 hitstateidx.push_back(ihit);
548 fwdPrdTkState.push_back(trackState);
559 if (fwdUpdTkState.size() > 0)
560 trackState = fwdUpdTkState.back();
562 trackState = startState;
563 fwdUpdTkState.push_back(trackState);
571 bool upok = trackState.updateWithHitState(*hitstate);
573 mf::LogWarning(
"TrackKalmanFitter") <<
"Fit failure at " << __FILE__ <<
" " << __LINE__;
577 std::cout <<
"updated state " << std::endl;
580 fwdUpdTkState.push_back(trackState);
584 std::cout <<
"WARNING: forward propagation failed. Skip this hit..." << std::endl;
586 if (fwdPrdTkState.size() > 0)
587 trackState = fwdPrdTkState.back();
589 trackState = startState;
590 rejectedhsidx.push_back(ihit);
593 if (rejectedhsidx.size() + hitstateidx.size() == hitstatev.size())
break;
597 for (
unsigned int ihit = 0; ihit < hitstatev.size(); ++ihit) {
598 const auto& hitstate = hitstatev[ihit];
600 std::cout << std::endl <<
"processing hit #" << ihit << std::endl;
603 auto& hitflags = hitflagsv[ihit];
606 rejectedhsidx.push_back(ihit);
612 if (applySkipClean && fwdUpdTkState.size() > 0 &&
skipNegProp_) {
613 if (dist < 0. || success ==
false) {
615 std::cout <<
"WARNING: negative propagation distance. Skip this hit..." << std::endl;
617 rejectedhsidx.push_back(ihit);
625 trackState.trackState(),
633 trackState.trackState(),
639 hitstateidx.push_back(ihit);
640 fwdPrdTkState.push_back(trackState);
648 (fwdUpdTkState.size() > 0 && applySkipClean &&
652 std::cout <<
"rejecting hit with res=" <<
std::abs(trackState.residual(hitstate))
653 <<
" chi2=" << trackState.chi2(hitstate) <<
" dist=" << dist << std::endl;
655 if (fwdUpdTkState.size() > 0)
656 trackState = fwdUpdTkState.back();
658 trackState = startState;
659 fwdUpdTkState.push_back(trackState);
667 bool upok = trackState.updateWithHitState(hitstate);
669 mf::LogWarning(
"TrackKalmanFitter") <<
"Fit failure at " << __FILE__ <<
" " << __LINE__;
672 fwdUpdTkState.push_back(trackState);
676 std::cout <<
"WARNING: forward propagation failed. Skip this hit..." << std::endl;
679 if (fwdPrdTkState.size() > 0)
680 trackState = fwdPrdTkState.back();
682 trackState = startState;
683 rejectedhsidx.push_back(ihit);
689 if (
dumpLevel_ > 2) assert(rejectedhsidx.size() + hitstateidx.size() == hitstatev.size());
691 std::cout <<
"TRACK AFTER FWD" << std::endl;
692 std::cout <<
"hit sizes=" << rejectedhsidx.size() <<
" " << hitstateidx.size() <<
" "
693 << hitstatev.size() << std::endl;
698 trackState.setCovariance(100. * trackState.covariance());
700 startState = trackState;
704 for (
int itk = fwdPrdTkState.size() - 1; itk >= 0; itk--) {
705 auto& fwdPrdTrackState = fwdPrdTkState[itk];
706 auto& fwdUpdTrackState = fwdUpdTkState[itk];
707 const auto& hitstate = hitstatev[hitstateidx[itk]];
708 auto& hitflags = hitflagsv[hitstateidx[itk]];
710 std::cout << std::endl <<
"processing backward hit #" << itk << std::endl;
716 trackState.trackState(),
724 trackState.trackState(),
731 std::cout <<
"propagation result=" << propok << std::endl;
732 std::cout <<
"propagated state " << std::endl;
735 << hitstate.plane().direction().Dot(hitstate.plane().position() -
736 trackState.position())
741 bool pcombok = fwdPrdTrackState.combineWithTrackState(trackState.trackState());
743 mf::LogWarning(
"TrackKalmanFitter") <<
"Fit failure at " << __FILE__ <<
" " << __LINE__;
747 std::cout <<
"combined prd state " << std::endl;
748 fwdPrdTrackState.dump();
752 bool ucombok = fwdUpdTrackState.combineWithTrackState(trackState.trackState());
754 mf::LogWarning(
"TrackKalmanFitter") <<
"Fit failure at " << __FILE__ <<
" " << __LINE__;
758 std::cout <<
"combined upd state " << std::endl;
759 fwdUpdTrackState.dump();
761 bool upok = trackState.updateWithHitState(hitstate);
763 mf::LogWarning(
"TrackKalmanFitter") <<
"Fit failure at " << __FILE__ <<
" " << __LINE__;
767 std::cout <<
"updated state " << std::endl;
771 startState = trackState;
776 fwdUpdTrackState = fwdPrdTrackState;
787 std::cout <<
"WARNING: backward propagation failed. Skip this hit... hitstateidx[itk]="
788 << hitstateidx[itk] <<
" itk=" << itk << std::endl;
791 trackState = startState;
796 if (nvalidhits < 4) {
797 mf::LogWarning(
"TrackKalmanFitter") <<
"Fit failure at " << __FILE__ <<
" " << __LINE__ <<
" ";
801 if (
dumpLevel_ > 1)
std::cout <<
"sort output with nvalidhits=" << nvalidhits << std::endl;
805 hitstatev, fwdUpdTkState, hitstateidx, rejectedhsidx, sortedtksidx, hitflagsv, applySkipClean);
806 size_t nsortvalid = 0;
807 for (
auto& idx : sortedtksidx) {
808 auto& hitflags = hitflagsv[hitstateidx[idx]];
811 if (nsortvalid < 4) {
812 mf::LogWarning(
"TrackKalmanFitter") <<
"Fit failure at " << __FILE__ <<
" " << __LINE__ <<
" ";
816 if (
dumpLevel_ > 2) assert(rejectedhsidx.size() + sortedtksidx.size() == hitstatev.size());
static constexpr Flag_t Merged
The hit might have contribution from particles other than this.
static constexpr Flag_t Suspicious
The point reconstruction is somehow questionable.
static constexpr Flag_t NoPoint
The trajectory point is not defined.
Namespace for the trajectory point flags.
art::ServiceHandle< geo::Geometry const > geom
TrackState propagateToPlane(bool &success, const detinfo::DetectorPropertiesData &detProp, const TrackState &origin, const Plane &target, bool dodedx, bool domcs, PropDirection dir=FORWARD) const
Main function for propagation of a TrackState to a Plane.
double distanceToPlane(bool &success, const Point_t &origpos, const Vector_t &origdir, const Plane &target) const
Distance of a TrackState (Point and Vector) to a Plane, along the TrackState direction.
void sortOutput(std::vector< HitState > &hitstatev, std::vector< KFTrackState > &fwdUpdTkState, std::vector< unsigned int > &hitstateidx, std::vector< unsigned int > &rejectedhsidx, std::vector< unsigned int > &sortedtksidx, std::vector< recob::TrajectoryPointFlags::Mask_t > &hitflagsv, bool applySkipClean=true) const
Sort the output states.
auto end(FixedBins< T, C > const &) noexcept
const TrackStatePropagator * propagator
static constexpr Flag_t HitIgnored
Hit was not included for the computation of the trajectory.
static constexpr Flag_t Rejected
The hit is extraneous to this track.
static constexpr Flag_t ExcludedFromFit
auto begin(FixedBins< T, C > const &) noexcept
float maxResidueFirstHit_
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
static constexpr Flag_t DetectorIssue
The hit is associated to a problematic channel.
static constexpr Flag_t DeltaRay
The hit might have contribution from a δ ray.
static constexpr Flag_t Shared
The hit is known to be associated also to another trajectory.
recob::tracking::Vector_t Vector_t
BEGIN_PROLOG could also be cout