Persistent graph#241
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #241 +/- ##
==========================================
+ Coverage 93.78% 93.89% +0.10%
==========================================
Files 59 58 -1
Lines 3284 3275 -9
==========================================
- Hits 3080 3075 -5
+ Misses 204 200 -4 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@cmalinmayor, persistent graph is ready for a first glance 😇 |
cmalinmayor
left a comment
There was a problem hiding this comment.
First pass, some high level comments, some low level suggestions
| self.tracks: SolutionTracks # Narrow type from base class | ||
| if not self.tracks.graph.has_edge(*edge): | ||
| self.tracks: Tracks # Narrow type from base class | ||
| if not self.tracks.graph_solution.has_edge(*edge): |
There was a problem hiding this comment.
graph_solution, because we can only remove edges that are in the solution, since we only do a soft-delete technically
updates: - [github.com/astral-sh/ruff-pre-commit: v0.15.17 → v0.15.18](astral-sh/ruff-pre-commit@v0.15.17...v0.15.18)
# Conflicts: # src/funtracks/annotators/_track_annotator.py # src/funtracks/import_export/geff/_export.py # tests/import_export/test_export_to_geff.py
…gree + graph_annotator default is graph_full
…now automatically has tracklet_ids
…1, if so, recompute
…can be expensive)
|
Hi @cmalinmayor, here we go again, hahah (why are these PRs always so big 😂) I implemented and answered all of your concerns. Biggest change is that:
Notes:
Let me know what you think 😊 |
…mply took the old ones
Updates
SolutionTracks— track-id logic (get/set track & lineage ids,from_tracks, neighbor lookups) folded intoTracks;TrackAnnotatornow registers based on a non-Nonetracklet_keyinstead of anisinstancecheck.graph_full+graph_solution—tracks.graphis gone;graph_solutionis thesolution=Trueview,graph_fullis its root (every node/edge ever known). All call sites insrc/andtests/migrated.DeleteNode/DeleteEdgeflipsolution=Falseingraph_fulland remove from the view only (remove_*_from_view);AddNode/AddEdgebranch ongraph_full.has_node/has_edgeto revive the same id in place or add genuinely new. Topology is append-only, so delete↔undo is a true inverse across repeated/divergent cycles.RegionpropsAnnotator/EdgeAnnotatorcompute ongraph_full(features persist on soft-deleted candidates, ready for re-solving);TrackAnnotatorstays ongraph_solution. Low-level attr get/set route throughgraph_full(shared attr dicts keep the view in sync).Tracks.__init__raises ifgraph_solution._rootis itself aGraphView, and_get_new_node_idsallocates againstgraph_fullto avoid colliding with soft-deleted ids.TeunHuijben/tracksdata@040ed9ffor the view-only add/remove primitives (revert once merged upstream).Tracks(declaring tracklet/lineage intent), preservesolutionflags, and backfillSolution()on legacy saves.test_soft_delete_roundtrip.py(12 cases) andtest_features_on_full_graph.py; full suite green (588 passed).Breaking changes
SolutionTracksis removed — useTracks(passtracklet_attr/lineage_attr, or aFeatureDictwith atracklet_key).tracks.graphis removed — usetracks.graph_solution(solution view) ortracks.graph_full(full graph).