29 if (trk == t.first.Track())
return true;
36 if (!
Has(t.first.Track()))
return false;
43 if (!rootTrk)
throw cet::exception(
"pma::VtxCandidate") <<
"Broken track.";
47 if (!rootAssn)
throw cet::exception(
"pma::VtxCandidate") <<
"Broken track.";
63 for (
size_t t = 0; t <
fAssigned.size(); t++) {
65 if (!trk_t)
throw cet::exception(
"pma::VtxCandidate") <<
"Broken track.";
67 for (
size_t u = 0; u <
fAssigned.size(); u++)
70 if (!trk_u)
throw cet::exception(
"pma::VtxCandidate") <<
"Broken track.";
82 if (c.first.Track()->Length() > minLength) n++;
97 for (
size_t n = 0;
n < trk.
Track()->
Nodes().size() - 1;
n++) {
114 if (d_best < kMaxDistToTrack) {
130 size_t n_best = 0, m_best = 0;
133 double lm, ln, l_best = 0;
134 for (
size_t m = 0; m < p0->
Nodes().size() - 1; m++) {
141 for (
size_t n = 0;
n < trk.
Track()->
Nodes().size() - 1;
n++) {
153 double d_dist = (d_best -
d) / d_best;
154 if (lm + ln > 0.8 * d_dist * l_best)
166 if (d_best < kMaxDistToTrack) {
184 for (
size_t n = 0;
n < trk.
Track()->
Nodes().size() - 1;
n++) {
206 unsigned int tpc = trk->
Nodes()[t.second]->TPC();
207 unsigned int cryo = trk->
Nodes()[t.second]->Cryo();
211 auto has_plane = [&wireReadoutGeom, cryo, tpc](
auto const view) {
212 return wireReadoutGeom.HasPlane(
geo::PlaneID{cryo, tpc, view});
229 mse += m / (double)k;
232 return mse / fAssigned.size();
240 double dw =
fErr[0] * other.
fErr[0] * dx * dx +
fErr[1] * other.
fErr[1] * dy * dy +
248 size_t max_l_idx = 0;
249 double l, max_l = 0.0;
250 for (
size_t i = 0; i <
fAssigned.size() - 1; i++) {
251 l =
fAssigned[i].first.Track()->Length();
259 dir_i *= 1.0 / dir_i.Mag();
264 for (
size_t j = 0; j <
fAssigned.size(); j++)
265 if ((j != max_l_idx) && (
fAssigned[j].first.Track()->Length() > minLength)) {
270 dir_j *= 1.0 / dir_j.Mag();
271 a = fabs(dir_i * dir_j);
272 if (a < min) min = a;
275 return 180.0 * acos(min) / TMath::Pi();
286 double dw =
Test(other);
294 if (!
Has(t.first.Track())) {
300 double mse0 =
fMse, mse1 = other.
fMse;
302 <<
"try: " << d <<
" mse0:" << sqrt(mse0) <<
" mse1:" << sqrt(mse1);
307 <<
"out: " <<
Size() <<
" mse:" << sqrt(mse) <<
" dw:" << dw;
334 std::vector<pma::Segment3D*> segments;
335 std::vector<std::pair<TVector3, TVector3>> lines;
336 std::vector<double> weights;
343 double segLength = seg->
Length();
347 std::pair<TVector3, TVector3> endpoints(vtx1->
Point3D(), vtx2->
Point3D());
348 double dy = endpoints.first.Y() - endpoints.second.Y();
349 double fy_norm = asin(fabs(dy) / segLength) / (0.5 * TMath::Pi());
350 double w = 1.0 - pow(fy_norm - 1.0, 12);
351 if (w < 0.3) w = 0.3;
353 lines.push_back(endpoints);
354 segments.push_back(seg);
355 weights.push_back(w);
360 fErr.SetXYZ(0., 0., 0.);
364 if (resultMse < 0.0) {
365 mf::LogWarning(
"pma::VtxCandidate") <<
"Cannot compute crossing point.";
372 for (
size_t s = 0; s < segments.size(); s++) {
382 fErr[0] += weights[s] * weights[s];
386 fCenter[0] += weights[s] * pproj.X();
395 fErr *= 1.0 / segments.size();
408 mf::LogError(
"pma::VtxCandidate") <<
"Tracks already attached to the vertex.";
414 <<
"JoinTracks (" <<
fAssigned.size() <<
") at:" 419 while (t < src.
size()) {
420 if (c.first.Track() == src[t].Track()) {
431 for (
auto& c : fAssigned)
432 for (
auto const& t : tracks.
tracks())
433 if (c.first.Track() == t.Track()) {
434 c.first.SetTreeId(t.TreeId());
439 std::vector<int> treeIds;
443 bool hasInnerCenter =
false;
445 for (
size_t i = 0; i < fAssigned.size(); i++) {
449 int key = fAssigned[i].first.Key();
450 int tid = fAssigned[i].first.TreeId();
451 size_t idx = fAssigned[i].second;
454 <<
" (nodes:" << trk->
Nodes().size() <<
")";
456 if (!
has(treeIds, tid))
458 treeIds.push_back(tid);
463 mf::LogError(
"pma::VtxCandidate") <<
"Root of the tree not found in tracks collection.";
466 TVector3 p0(trk->
Nodes()[idx]->Point3D());
467 TVector3 p1(trk->
Nodes()[idx + 1]->Point3D());
469 int tpc0 = trk->
Nodes()[idx]->TPC();
470 int tpc1 = trk->
Nodes()[idx + 1]->TPC();
472 int cryo0 = trk->
Nodes()[idx]->Cryo();
473 int cryo1 = trk->
Nodes()[idx + 1]->Cryo();
484 vtxCenter = trk->
Nodes().front();
490 if (trk->
AttachTo(vtxCenter)) nOK++;
496 mf::LogVerbatim(
"pma::VtxCandidate") <<
" flip trk to make new center";
498 vtxCenter = trk->
Nodes().front();
502 vtxCenter = trk->
Nodes().back();
509 mf::LogVerbatim(
"pma::VtxCandidate") <<
" flip trk to attach to inner";
511 if (trk->
AttachTo(vtxCenter)) nOK++;
520 bool canFlipPrev =
true;
521 if (vtxCenter && vtxCenter->
Prev()) {
529 if (hasInnerCenter || !canFlipPrev) {
550 mf::LogVerbatim(
"pma::VtxCandidate") <<
" add center at end of segment";
554 mf::LogVerbatim(
"pma::VtxCandidate") <<
" center at start of segment - no action";
562 <<
" trk size:" << trk->
size() <<
" (nodes:" << trk->
Nodes().size() <<
")";
567 <<
" t0 size:" << t0->
size() <<
" (nodes:" << t0->
Nodes().size() <<
")";
571 tracks.
tracks().emplace_back(t0, key, tid);
574 vtxCenter = trk->
Nodes().front();
579 if (trk->
AttachTo(vtxCenter)) nOK += 2;
586 hasInnerCenter =
true;
606 mf::LogVerbatim(
"pma::VtxCandidate") <<
" add center at end of segment";
610 mf::LogVerbatim(
"pma::VtxCandidate") <<
" center at start of segment - no action";
621 rootBranch = seg->
Parent();
628 for (
size_t j = 0; j < branches.size(); ++j) {
629 if (branches[j]->AttachTo(innerCenter,
true)) {}
631 vtxCenter = innerCenter;
634 vtxCenter = innerCenter;
648 rootSeg = static_cast<pma::Segment3D*>(vtxCenter->
Next(0));
649 else if (vtxCenter->
Prev())
650 rootSeg = static_cast<pma::Segment3D*>(vtxCenter->
Prev());
652 throw cet::exception(
"pma::VtxCandidate") <<
"Vertex with no segments attached.";
655 if (!rootTrk) rootTrk = rootSeg->
Parent();
657 std::vector<pma::Track3D const*> branchesToRemove;
658 bool noLoops = rootTrk->
GetBranches(branchesToRemove);
661 if (noLoops && (nOK > 1)) {
678 if (noLoops && tuneOK) {
680 for (
auto& c : backupTracks.
tracks())
684 mf::LogVerbatim(
"pma::VtxCandidate") <<
"restore tracks from backup....";
685 for (
int tid : treeIds) {
687 while (t < tracks.
size()) {
688 if (tracks[t].TreeId() == tid) {
689 tracks[t].DeleteTrack();
696 for (
const auto& c : backupTracks.
tracks())
702 mf::LogError(
"pma::VtxCandidate") <<
"Cannot create common vertex";
Vertex finding helper for the Projection Matching Algorithm.
code to link reconstructed objects back to the MC truth information
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
TVector3 const & Point3D() const
bool Has(pma::Track3D *trk) const
double SolveLeastSquares3D(const std::vector< std::pair< TVector3, TVector3 >> &lines, TVector3 &result)
pma::Track3D * getTreeCopy(pma::TrkCandidateColl &dst, size_t trkIdx, bool isRoot=true)
bool AttachTo(pma::Node3D *vStart, bool noFlip=false)
Implementation of the Projection Matching Algorithm.
bool IsAttachedTo(pma::Track3D const *trk) const
double Dist2(const TVector2 &v1, const TVector2 &v2)
double Test(const VtxCandidate &other) const
bool JoinTracks(detinfo::DetectorPropertiesData const &detProp, pma::TrkCandidateColl &tracks, pma::TrkCandidateColl &src)
void erase_at(size_t pos)
Implementation of the Projection Matching Algorithm.
The data type to uniquely identify a Plane.
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
Planes which measure Z direction.
Implementation of the Projection Matching Algorithm.
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
virtual pma::SortedObjectBase * Next(unsigned int=0) const
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
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)
static constexpr double kMaxDistToTrack
Definition of data types for geometry description.
double MaxAngle(double minLength=0.0) const
void InsertNode(detinfo::DetectorPropertiesData const &detProp, TVector3 const &p3d, size_t at_idx, unsigned int tpc, unsigned int cryo)
bool MergeWith(const VtxCandidate &other)
Implementation of the Projection Matching Algorithm.
virtual pma::SortedObjectBase * Next(unsigned int index=0) const
bool Add(const pma::TrkCandidate &trk)
double GetSegmentProjVector(const TVector2 &p, const TVector2 &p0, const TVector2 &p1)
TVector2 GetProjectionToPlane(const TVector3 &p, unsigned int plane, unsigned int tpc, unsigned int cryo)
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
bool IsAttached(pma::Track3D *trk) const
double GetDistance2To(const TVector3 &p3d) const override
Distance [cm] from the 3D segment to the point 3D.
std::vector< pma::Node3D * > const & Nodes() const noexcept
virtual pma::SortedObjectBase * Prev(void) const
bool Flip(const detinfo::DetectorPropertiesData &detProp, std::vector< pma::Track3D * > &allTracks)
pma::Track3D * Track() const
pma::Track3D * Parent(void) const
bool AttachBackTo(pma::Node3D *vStart)
pma::Segment3D * NextSegment(pma::Node3D *vtx) const
double Length(void) const
void push_back(const TrkCandidate &trk)
std::vector< TrkCandidate > const & tracks() const
cet::coded_exception< error, detail::translate > exception
bool has(const std::vector< int > &v, int id) const