418 mf::LogError(
"pma::VtxCandidate") <<
"Tracks already attached to the vertex.";
423 mf::LogVerbatim(
"pma::VtxCandidate")
424 <<
"JoinTracks (" <<
fAssigned.size() <<
") at:"
429 while (t < src.
size()) {
430 if (c.first.Track() == src[t].Track()) {
441 for (
auto& c : fAssigned)
442 for (
auto const& t : tracks.
tracks())
443 if (c.first.Track() == t.Track()) {
444 c.first.SetTreeId(t.TreeId());
449 std::vector<int> treeIds;
453 bool hasInnerCenter =
false;
455 for (
size_t i = 0; i < fAssigned.size(); i++) {
456 mf::LogVerbatim(
"pma::VtxCandidate") <<
"----------> track #" << i;
459 int key = fAssigned[i].first.Key();
460 int tid = fAssigned[i].first.TreeId();
461 size_t idx = fAssigned[i].second;
463 mf::LogVerbatim(
"pma::VtxCandidate") <<
" track tid:" << tid <<
", size:" << trk->
size()
464 <<
" (nodes:" << trk->
Nodes().size() <<
")";
466 if (!
has(treeIds, tid))
468 treeIds.push_back(tid);
473 mf::LogError(
"pma::VtxCandidate") <<
"Root of the tree not found in tracks collection.";
476 TVector3 p0(trk->
Nodes()[idx]->Point3D());
477 TVector3
p1(trk->
Nodes()[idx + 1]->Point3D());
479 int tpc0 = trk->
Nodes()[idx]->TPC();
480 int tpc1 = trk->
Nodes()[idx + 1]->TPC();
482 int cryo0 = trk->
Nodes()[idx]->Cryo();
483 int cryo1 = trk->
Nodes()[idx + 1]->Cryo();
493 mf::LogVerbatim(
"pma::VtxCandidate") <<
" new at front";
494 vtxCenter = trk->
Nodes().front();
499 mf::LogVerbatim(
"pma::VtxCandidate") <<
" front to center";
500 if (trk->
AttachTo(vtxCenter)) nOK++;
506 mf::LogVerbatim(
"pma::VtxCandidate") <<
" flip trk to make new center";
508 vtxCenter = trk->
Nodes().front();
511 mf::LogVerbatim(
"pma::VtxCandidate") <<
" new center at the endpoint";
512 vtxCenter = trk->
Nodes().back();
519 mf::LogVerbatim(
"pma::VtxCandidate") <<
" flip trk to attach to inner";
521 if (trk->
AttachTo(vtxCenter)) nOK++;
524 mf::LogVerbatim(
"pma::VtxCandidate") <<
" endpoint to center";
530 bool canFlipPrev =
true;
531 if (vtxCenter && vtxCenter->
Prev()) {
539 if (hasInnerCenter || !canFlipPrev) {
540 mf::LogVerbatim(
"pma::VtxCandidate") <<
" split track";
544 mf::LogVerbatim(
"pma::VtxCandidate") <<
" add center inside segment";
560 mf::LogVerbatim(
"pma::VtxCandidate") <<
" add center at end of segment";
564 mf::LogVerbatim(
"pma::VtxCandidate") <<
" center at start of segment - no action";
571 mf::LogVerbatim(
"pma::VtxCandidate")
572 <<
" trk size:" << trk->
size() <<
" (nodes:" << trk->
Nodes().size() <<
")";
576 mf::LogVerbatim(
"pma::VtxCandidate")
577 <<
" t0 size:" << t0->
size() <<
" (nodes:" << t0->
Nodes().size() <<
")";
581 tracks.
tracks().emplace_back(t0, key, tid);
583 mf::LogVerbatim(
"pma::VtxCandidate") <<
" center at trk0 back";
584 vtxCenter = trk->
Nodes().front();
588 mf::LogVerbatim(
"pma::VtxCandidate") <<
" attach trk to trk0";
589 if (trk->
AttachTo(vtxCenter)) nOK += 2;
592 mf::LogVerbatim(
"pma::VtxCandidate") <<
" done";
595 mf::LogVerbatim(
"pma::VtxCandidate") <<
" inner center";
596 hasInnerCenter =
true;
600 mf::LogVerbatim(
"pma::VtxCandidate") <<
" add center inside segment";
616 mf::LogVerbatim(
"pma::VtxCandidate") <<
" add center at end of segment";
620 mf::LogVerbatim(
"pma::VtxCandidate") <<
" center at start of segment - no action";
631 rootBranch = seg->
Parent();
638 for (
size_t j = 0; j < branches.size(); ++j) {
639 if (branches[j]->AttachTo(innerCenter,
true)) {}
641 vtxCenter = innerCenter;
644 vtxCenter = innerCenter;
649 mf::LogVerbatim(
"pma::VtxCandidate") <<
" done";
658 rootSeg = static_cast<pma::Segment3D*>(vtxCenter->
Next(0));
659 else if (vtxCenter->
Prev())
660 rootSeg = static_cast<pma::Segment3D*>(vtxCenter->
Prev());
662 throw cet::exception(
"pma::VtxCandidate") <<
"Vertex with no segments attached.";
665 if (!rootTrk) rootTrk = rootSeg->
Parent();
667 std::vector<pma::Track3D const*> branchesToRemove;
668 bool noLoops = rootTrk->
GetBranches(branchesToRemove);
671 if (noLoops && (nOK > 1)) {
688 if (noLoops && tuneOK) {
689 mf::LogVerbatim(
"pma::VtxCandidate") <<
"remove backup tracks";
690 for (
auto& c : backupTracks.
tracks())
694 mf::LogVerbatim(
"pma::VtxCandidate") <<
"restore tracks from backup....";
695 for (
int tid : treeIds) {
697 while (t < tracks.
size()) {
698 if (tracks[t].TreeId() == tid) {
699 tracks[t].DeleteTrack();
706 for (
const auto& c : backupTracks.
tracks())
708 mf::LogVerbatim(
"pma::VtxCandidate") <<
" done";
712 mf::LogError(
"pma::VtxCandidate") <<
"Cannot create common vertex";
TVector3 const & Point3D() const
pma::Track3D * getTreeCopy(pma::TrkCandidateColl &dst, size_t trkIdx, bool isRoot=true)
bool AttachTo(pma::Node3D *vStart, bool noFlip=false)
double Dist2(const TVector2 &v1, const TVector2 &v2)
void erase_at(size_t pos)
bool GetBranches(std::vector< pma::Track3D const * > &branches, bool skipFirst=false) const
std::vector< std::pair< pma::TrkCandidate, size_t > > fAssigned
virtual unsigned int NextCount(void) const
std::vector< pma::Track3D * > GetBranches() const
std::vector< pma::Node3D * > const & Nodes() const noexcept
double TuneFullTree(double eps=0.001, double gmax=50.0)
pma::Track3D * Split(detinfo::DetectorPropertiesData const &detProp, size_t idx, bool try_start_at_idx=true)
bool CanFlip() const
Check if the track can be flipped without breaking any other track.
TVector2 GetProjectionToSegment(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
static constexpr double kMinDistToNode
int getCandidateIndex(pma::Track3D const *candidate) const
bool SetPoint3D(const TVector3 &p3d)
void InsertNode(detinfo::DetectorPropertiesData const &detProp, TVector3 const &p3d, size_t at_idx, unsigned int tpc, unsigned int cryo)
virtual pma::SortedObjectBase * Next(unsigned int index=0) const
double GetSegmentProjVector(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
virtual pma::SortedObjectBase * Prev(void) const
bool Flip(const detinfo::DetectorPropertiesData &detProp, std::vector< pma::Track3D * > &allTracks)
pma::Track3D * Parent(void) const
bool AttachBackTo(pma::Node3D *vStart)
pma::Segment3D * NextSegment(pma::Node3D *vtx) const
physics associatedGroupsWithLeft p1
void push_back(const TrkCandidate &trk)
std::vector< TrkCandidate > const & tracks() const
bool has(const std::vector< int > &v, int id) const