-
Notifications
You must be signed in to change notification settings - Fork 119
Fix duplicate skeletons during labels merge #2075
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThis update refines the label update process in the dataset module and adjusts GUI command tests. In the dataset code, the merging logic for skeletons, nodes, and tracks has been reorganized for clarity and reliability. Additionally, the expected track count for DeepLabCut imports has been modified, and a test function related to skeleton unification has been removed, indicating a shift in testing focus. Changes
Sequence Diagram(s)sequenceDiagram
participant L as Labels Instance
participant S as Skeletons List
participant N as Nodes List
participant T as Tracks List
L->>L: _update_from_labels(merge)
alt Skeleton list is empty
L->>S: Create new skeletons
else merge flag is true
L->>S: Check and merge duplicate skeletons
end
alt Nodes list is empty
L->>N: Build nodes from skeletons
end
alt Tracks list is empty
L->>T: Update and merge tracks
end
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ Context from checks skipped due to timeout of 90000ms (3)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (1)
sleap/io/dataset.py (1)
486-503: Nested loops may add skeletons repeatedly or hamper performance.This triple-nested loop can re-check skeleton matches an excessive number of times. Once a match has been found, consider breaking early to avoid redundant checks. Additionally, partial matches across multiple frames might make merges fail or run slower than necessary.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
sleap/io/dataset.py(4 hunks)tests/gui/test_commands.py(1 hunks)tests/io/test_dataset.py(0 hunks)
💤 Files with no reviewable changes (1)
- tests/io/test_dataset.py
🔇 Additional comments (1)
tests/gui/test_commands.py (1)
73-73: Change in the number of expected tracks from 3 to 2.
This updated assertion likely reflects the new logic that merges or removes duplicates. Confirm that the new expectation accurately represents the final track count after the improved merging routine.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #2075 +/- ##
===========================================
+ Coverage 75.43% 76.15% +0.71%
===========================================
Files 134 134
Lines 24749 25050 +301
===========================================
+ Hits 18670 19077 +407
+ Misses 6079 5973 -106 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (5)
sleap/io/dataset.py (5)
469-470: Minor optimization suggestion for set union.Since
self.skeletonsis guaranteed to be empty in this block, the union withself.skeletonsis redundant. You can directly build the list of skeletons from the labeled frames:-if len(self.skeletons) == 0: - self.skeletons = list( - set(self.skeletons).union( - { - instance.skeleton - for label in self.labels - for instance in label.instances - } - ) - ) +if not self.skeletons: + self.skeletons = list( + { + instance.skeleton + for label in self.labels + for instance in label.instances + } + )
483-484: Use generator expression instead of list comprehension for sets.Minor style improvement: you can simplify the comprehension by dropping the brackets inside
set():-set([node for skeleton in self.skeletons for node in skeleton.nodes]) +set(node for skeleton in self.skeletons for node in skeleton.nodes)
507-525: Consider consolidating track merging logic further.Your approach for deduplicating tracks relies on checking each new track against all existing tracks using
any(track.matches(t) for t in new_tracks). This works but is O(n^2) in the worst case for large sets. Also, consider whether you need to unify references in the labeled frames (like with skeleton merging). You might unify track objects similarly so that instances reference a single canonical track.
1926-1926: Avoid repeating “update nodes” logic.You are repeating the same “collect all nodes from skeletons” pattern here (similar to lines 483-484). Consider extracting this into a helper method (e.g.
_update_nodes_from_skeletons) to maintain consistency and reduce duplication.
2326-2328: Use “if not ret” instead of “if ret == False”.It’s more Pythonic to write:
-if ret == False: +if not ret:This improves readability and better conveys intent.
🧰 Tools
🪛 Ruff (0.8.2)
2327-2327: Avoid equality comparisons to
False; useif not ret:for false checksReplace with
not ret(E712)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
sleap/io/dataset.py(3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: Tests (macos-14)
- GitHub Check: Tests (windows-2022)
- GitHub Check: Tests (ubuntu-22.04)
🔇 Additional comments (1)
sleap/io/dataset.py (1)
481-481: No immediate issues.The guarded check on
len(self.nodes) == 0is logically consistent with how skeletons are handled. It cleanly ensures nodes are updated only if they’re empty.
Description
This PR fixes the duplicate skeleton issue when merging labels file. After every update to the labels file, we check if there's a existing skeleton that matches with a new Skeleton associated with an instance in the Labeled frame. If the skeleton doesn't match, then we add it to the list of skeletons in the Labels object.
Types of changes
Does this address any currently open issues?
Outside contributors checklist
Thank you for contributing to SLEAP!
❤️
Summary by CodeRabbit