Skip to content
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

Labels.split and Labels.make_training_splits #98

Merged
merged 12 commits into from
Jun 19, 2024
Merged

Labels.split and Labels.make_training_splits #98

merged 12 commits into from
Jun 19, 2024

Conversation

talmo
Copy link
Contributor

@talmo talmo commented Jun 16, 2024

Summary by CodeRabbit

  • New Features

    • Introduced new functionalities for fixing video paths, saving labels with embedded images, and making training/validation/test splits.
    • Added options for embedding frames in saved labels files.
    • Implemented data splitting methods to facilitate training, validation, and test sets.
  • Bug Fixes

    • Ensured unique frame indices for each video.
    • Improved error handling in linking instances based on predictions.
  • Documentation

    • Updated method calls and added references to related functions and modules.
    • Enhanced parameter documentation for better clarity.
  • Chores

    • Updated package version to "0.1.5".
    • Updated copyright year.

Copy link
Contributor

coderabbitai bot commented Jun 16, 2024

Warning

Review failed

The pull request is closed.

Walkthrough

This release includes enhancements and new features across several modules. Key changes involve updates to file saving and embedding functionalities, introduction of data splitting methods, and improvements in metadata handling. Notable additions include more flexible embedding options when saving labels, methods to create training/validation/test splits, and provenance tracking in label reading functions. These updates aim to enhance user experience, improve data handling, and provide greater control over dataset management.

Changes

Files Change Summary
docs/index.md Updated method calls for saving files, added functionalities for fixing video paths, embedding images in labels, and creating data splits.
mkdocs.yml Updated copyright year and renamed navigation sections.
sleap_io/io/jabs.py, sleap_io/io/labelstudio.py, sleap_io/io/nwb.py Added provenance information to labels before returning in read_labels functions.
sleap_io/io/main.py Enhanced save_slp embedding options, clarified embed parameter handling, improved file handling in load_file.
sleap_io/io/slp.py Improved handling of frame indices, metadata encoding, error handling, and embedding options in functions related to label processing.
sleap_io/io/video.py Converted frame_numbers slice to integers in find_embedded function.
sleap_io/model/labels.py Updated save method, added split and make_training_splits methods for enhanced data management.
sleap_io/model/video.py Revised logic for backend attribute in __attrs_post_init__ method.
sleap_io/version.py Updated version to "0.1.5".
tests/io/test_slp.py Expanded test_embed function to handle new embedding options.
tests/model/test_labels.py Added tests for data splitting and training split functionalities.

A Rabbit’s Whimsy

In the code, new paths we chart,
Fixing labels with an art.
Embedding frames so clear and bright,
Splitting data day and night.
To celebrate, we’ve hopped ahead,
Version one point five is now spread!


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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 as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

Outside diff range and nitpick comments (26)
mkdocs.yml (3)

Line range hint 72-72: Remove trailing spaces to maintain clean and consistent code formatting.

Tools
yamllint

[warning] 154-154: wrong indentation: expected 6 but found 4 (indentation)


[error] 156-156: no new line character at the end of file (new-line-at-end-of-file)


Line range hint 101-101: Remove the duplicate key anchor_linenums to avoid confusion and potential errors in markdown rendering.

-  anchor_linenums: true
Tools
yamllint

[warning] 154-154: wrong indentation: expected 6 but found 4 (indentation)


[error] 156-156: no new line character at the end of file (new-line-at-end-of-file)


Line range hint 120-120: Remove trailing spaces to maintain clean and consistent code formatting.

Also applies to: 138-138

Tools
yamllint

[warning] 154-154: wrong indentation: expected 6 but found 4 (indentation)


[error] 156-156: no new line character at the end of file (new-line-at-end-of-file)

docs/index.md (1)

45-45: Remove multiple consecutive blank lines to comply with markdown best practices and maintain readability.

Also applies to: 66-66, 81-81, 82-82, 124-124, 143-143, 158-158, 178-178

Tools
Markdownlint

45-45: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines

sleap_io/io/labelstudio.py (2)

Line range hint 36-36: Consider removing the "r" mode from open as it's the default mode.

- with open(labels_path, "r") as task_file:
+ with open(labels_path) as task_file:

Line range hint 39-39: Use isinstance for type checking instead of direct type comparison for better practice and future Python compatibility.

- if type(skeleton) == list:
+ if isinstance(skeleton, list):
tests/io/test_slp.py (1)

Line range hint 326-329: Combine similar if branches using logical or to simplify the code.

- elif to_embed == "user":
-    assert labels.video.backend.embedded_frame_inds == [0, 220, 440, 770, 990]
- elif to_embed == "suggestions":
-    assert len(labels.video.backend.embedded_frame_inds) == 10
- elif to_embed == "suggestions+user":
-    assert len(labels.video.backend.embedded_frame_inds) == 10
+ elif to_embed in ["user", "suggestions", "suggestions+user"]:
+    assert len(labels.video.backend.embedded_frame_inds) == 10
sleap_io/io/nwb.py (1)

Line range hint 54-54: Optimize dictionary key access by removing .keys() which is unnecessary and less efficient.

- video_keys: List[str] = [key for key in nwb_file.keys() if "SLEAP_VIDEO" in key]
+ video_keys: List[str] = [key for key in nwb_file if "SLEAP_VIDEO" in key]
tests/model/test_labels.py (4)

Line range hint 3-3: Remove unused import: numpy.testing.assert_equal.

- from numpy.testing import assert_equal

Line range hint 14-14: Remove unused import: sleap_io.load_video.

- from sleap_io import load_video

421-525: The test cases for the split function are comprehensive and cover various edge cases, including empty data, real data, rounding errors, and serialization. However, consider adding assertions to verify the contents of the splits, not just their lengths, to ensure the data integrity is maintained after the split.


560-577: The test_make_training_splits_save function tests the saving of labels after making training splits and verifies their integrity post-save. It's well-implemented and checks the provenance field to ensure traceability. However, consider adding more detailed checks on the contents of the saved files to ensure all data is correctly serialized and deserialized.

sleap_io/io/jabs.py (6)

Line range hint 71-71: Update the type annotation to use modern Python syntax.

- def read_labels(labels_path: str, skeleton: Optional[Skeleton] = JABS_DEFAULT_SKELETON) -> Labels:
+ def read_labels(labels_path: str, skeleton: Skeleton | None = JABS_DEFAULT_SKELETON) -> Labels:

Line range hint 86-86: Modernize the type annotation by using list instead of List.

- frames: List[LabeledFrame] = []
+ frames: list[LabeledFrame] = []

Line range hint 141-141: Simplify dictionary key checks by removing .keys().

- if "static_objects" in pose_file.keys()
+ if "static_objects" in pose_file

Also applies to: 155-155, 537-537


Line range hint 193-193: Update the type annotation to use modern Python syntax.

- data: Union[np.ndarray[np.uint16], np.ndarray[np.float32]],
+ data: np.ndarray[np.uint16] | np.ndarray[np.float32],

Line range hint 229-229: Modernize the type annotation by using list instead of List.

- def get_max_ids_in_video(labels: List[Labels], key: str = "Mouse") -> int:
+ def get_max_ids_in_video(labels: list[Labels], key: str = "Mouse") -> int:

Line range hint 291-291: Consider adding an explicit stacklevel to warnings to improve debugging.

- warnings.warn(f"Skipping {out_filename} because it already exists.")
+ warnings.warn(f"Skipping {out_filename} because it already exists.", stacklevel=2)

Also applies to: 306-306, 343-343

sleap_io/io/video.py (6)

Line range hint 16-19: Consider using contextlib.suppress for cleaner exception handling.

- try:
-     import cv2
- except ImportError:
-     pass
+ from contextlib import suppress
+ with suppress(ImportError):
+     import cv2

Line range hint 21-24: Refactor repeated try-except blocks for imports using contextlib.suppress.

- try:
-     import imageio_ffmpeg
- except ImportError:
-     pass
- try:
-     import av
- except ImportError:
-     pass
+ from contextlib import suppress
+ with suppress(ImportError):
+     import imageio_ffmpeg
+ with suppress(ImportError):
+     import av

Also applies to: 26-29


Line range hint 22-22: Imports are unused; consider checking for module availability instead of importing.

Consider using importlib.util.find_spec to check for module availability without importing them, which can be more efficient and clear.

from importlib import util
imageio_ffmpeg_available = util.find_spec("imageio_ffmpeg") is not None
av_available = util.find_spec("av") is not None

Also applies to: 27-27


Line range hint 55-65: Update type annotations to use modern Python type hinting syntax.

- filename: str | Path | list[str] | list[Path]
- grayscale: Optional[bool] = None
- keep_open: bool = True
- _cached_shape: Optional[Tuple[int, int, int, int]] = None
- _open_reader: Optional[object] = None
+ filename: str | Path | list[str | Path]
+ grayscale: bool | None = None
+ keep_open: bool = True
+ _cached_shape: tuple[int, int, int, int] | None = None
+ _open reader: object | None = None

Also applies to: 87-90, 161-167, 486-493, 559-559


Line range hint 528-530: Simplify nested if statements.

- if "format" in ds.attrs:
-     if "frame_numbers" in ds.parent:
-         frame_numbers = ds.parent["frame_numbers"][:].astype(int)
-         self.frame_map = {frame: idx for idx, frame in enumerate(frame_numbers)}
-         self.source_inds = frame_numbers
+ if "format" in ds.attrs and "frame_numbers" in ds.parent:
+     frame_numbers = ds.parent["frame_numbers"][:].astype(int)
+     self.frame_map = {frame: idx for idx, frame in enumerate(frame_numbers)}
+     self.source_inds = frame_numbers

Line range hint 577-580: Use a ternary operator for conditional assignment.

- if self.frame_map:
-     frame_idx = list(self.frame_map.keys())[0]
- else:
-     frame_idx = 0
+ frame_idx = list(self.frame_map.keys())[0] if self.frame_map else 0
sleap_io/io/slp.py (2)

Line range hint 33-36: Consider using contextlib.suppress for cleaner handling of optional imports.

- try:
-     import cv2
- except ImportError:
-     pass
+ from contextlib import suppress
+ with suppress(ImportError):
+     import cv2

Line range hint 784-784: For type annotations, use the modern | syntax for union types.

- def read_instances(labels_path: str, skeletons: list[Skeleton], tracks: list[Track], points: list[Point], pred_points: list[PredictedPoint], format_id: float) -> list[Union[Instance, PredictedInstance]]:
+ def read_instances(labels_path: str, skeletons: list[Skeleton], tracks: list[Track], points: list[Point], pred_points: list[PredictedPoint], format_id: float) -> list[Instance | PredictedInstance]:
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between aaeb0f2 and af3e508.

Files selected for processing (13)
  • docs/index.md (4 hunks)
  • mkdocs.yml (1 hunks)
  • sleap_io/io/jabs.py (1 hunks)
  • sleap_io/io/labelstudio.py (1 hunks)
  • sleap_io/io/main.py (2 hunks)
  • sleap_io/io/nwb.py (1 hunks)
  • sleap_io/io/slp.py (5 hunks)
  • sleap_io/io/video.py (1 hunks)
  • sleap_io/model/labels.py (3 hunks)
  • sleap_io/model/video.py (2 hunks)
  • sleap_io/version.py (1 hunks)
  • tests/io/test_slp.py (4 hunks)
  • tests/model/test_labels.py (1 hunks)
Files not reviewed due to errors (1)
  • sleap_io/model/labels.py (no review received)
Files skipped from review due to trivial changes (1)
  • sleap_io/version.py
Additional context used
yamllint
mkdocs.yml

[error] 72-72: trailing spaces (trailing-spaces)


[error] 101-101: duplication of key "anchor_linenums" in mapping (key-duplicates)


[error] 120-120: trailing spaces (trailing-spaces)


[error] 138-138: trailing spaces (trailing-spaces)


[warning] 154-154: wrong indentation: expected 6 but found 4 (indentation)


[error] 156-156: no new line character at the end of file (new-line-at-end-of-file)

Markdownlint
docs/index.md

45-45: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


66-66: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


81-81: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


82-82: Expected: 1; Actual: 3 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


124-124: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


143-143: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


158-158: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


178-178: Expected: 1; Actual: 2 (MD012, no-multiple-blanks)
Multiple consecutive blank lines


16-16: Expected: 1; Actual: 0; Below (MD022, blanks-around-headings)
Headings should be surrounded by blank lines


179-179: Expected: 1; Actual: 0; Below (MD022, blanks-around-headings)
Headings should be surrounded by blank lines


187-187: Expected: 1; Actual: 0; Below (MD022, blanks-around-headings)
Headings should be surrounded by blank lines


17-17: null (MD031, blanks-around-fences)
Fenced code blocks should be surrounded by blank lines


22-22: null (MD031, blanks-around-fences)
Fenced code blocks should be surrounded by blank lines


24-24: null (MD031, blanks-around-fences)
Fenced code blocks should be surrounded by blank lines


25-25: null (MD031, blanks-around-fences)
Fenced code blocks should be surrounded by blank lines


17-17: null (MD040, fenced-code-language)
Fenced code blocks should have a language specified


22-22: null (MD040, fenced-code-language)
Fenced code blocks should have a language specified


25-25: null (MD040, fenced-code-language)
Fenced code blocks should have a language specified


189-189: null (MD047, single-trailing-newline)
Files should end with a single newline character

Ruff
sleap_io/io/main.py

80-80: Use X | Y for type annotations (UP007)

Convert to X | Y


80-80: Use X | Y for type annotations (UP007)

Convert to X | Y


107-107: Use X | Y for type annotations (UP007)

Convert to X | Y


120-120: Use X | Y for type annotations (UP007)

Convert to X | Y


150-150: Use X | Y for type annotations (UP007)

Convert to X | Y


151-151: Use X | Y for type annotations (UP007)

Convert to X | Y


196-196: Use X | Y for type annotations (UP007)

Convert to X | Y

sleap_io/model/video.py

9-9: Redefinition of unused Optional from line 9 (F811)

Remove definition: Optional


47-47: Use X | Y for type annotations (UP007)

Convert to X | Y


49-49: Use X | Y for type annotations (UP007)

Convert to X | Y


62-62: Use X | Y for type annotations (UP007)

Convert to X | Y


63-63: Use X | Y for type annotations (UP007)

Convert to X | Y


65-65: Use X | Y for type annotations (UP007)

Convert to X | Y


102-102: Use tuple instead of Tuple for type annotation (UP006)

Replace with tuple


110-110: Use tuple instead of Tuple for type annotation (UP006)

Replace with tuple


118-118: Do not use bare except (E722)


189-192: Use return all(Path(f).exists() for f in self.filename) instead of for loop (SIM110)

Replace with return all(Path(f).exists() for f in self.filename)


204-204: Use X | Y for type annotations (UP007)

Convert to X | Y


205-205: Use X | Y for type annotations (UP007)

Convert to X | Y

sleap_io/io/labelstudio.py

36-36: Unnecessary open mode parameters (UP015)

Remove open mode parameters


39-39: Do not compare types, use isinstance() (E721)


244-244: No explicit stacklevel keyword argument found (B028)


259-259: Loop control variable indv not used within loop body (B007)

Rename unused indv to _indv

tests/io/test_slp.py

6-6: sleap_io.Edge imported but unused (F401)

Remove unused import


9-9: sleap_io.LabeledFrame imported but unused (F401)

Remove unused import


10-10: sleap_io.Track imported but unused (F401)

Remove unused import


11-11: sleap_io.Point imported but unused (F401)

Remove unused import


12-12: sleap_io.PredictedPoint imported but unused (F401)

Remove unused import


25-25: sleap_io.io.slp.serialize_skeletons imported but unused (F401)

Remove unused import


29-29: Redefinition of unused read_instances from line 22 (F811)

Remove definition: read_instances


29-29: sleap_io.io.slp.read_instances imported but unused (F401)

Remove unused import


36-36: sleap_io.io.utils.read_hdf5_dataset imported but unused (F401)

Remove unused import: sleap_io.io.utils.read_hdf5_dataset


38-38: simplejson imported but unused (F401)

Remove unused import: simplejson


60-60: Do not compare types, use isinstance() (E721)


194-194: Do not compare types, use isinstance() (E721)


326-329: Combine if branches using logical or operator (SIM114)

Combine if branches

sleap_io/io/nwb.py

54-54: Use key in dict instead of key in dict.keys() (SIM118)

Remove .keys()


265-265: Loop control variable track_index not used within loop body (B007)

Rename unused track_index to _track_index

tests/model/test_labels.py

3-3: numpy.testing.assert_equal imported but unused (F401)

Remove unused import: numpy.testing.assert_equal


14-14: sleap_io.load_video imported but unused (F401)

Remove unused import: sleap_io.load_video


192-192: Found useless expression. Either assign it to a variable or remove it. (B018)


200-200: Found useless expression. Either assign it to a variable or remove it. (B018)


207-207: Found useless expression. Either assign it to a variable or remove it. (B018)


215-215: Found useless expression. Either assign it to a variable or remove it. (B018)

sleap_io/io/jabs.py

71-71: Use X | Y for type annotations (UP007)

Convert to X | Y


86-86: Use list instead of List for type annotation (UP006)

Replace with list


141-141: Use key not in dict instead of key not in dict.keys() (SIM118)

Remove .keys()


155-155: Use key in dict instead of key in dict.keys() (SIM118)

Remove .keys()


193-193: Use X | Y for type annotations (UP007)

Convert to X | Y


229-229: Use list instead of List for type annotation (UP006)

Replace with list


291-291: No explicit stacklevel keyword argument found (B028)


306-306: No explicit stacklevel keyword argument found (B028)


343-343: No explicit stacklevel keyword argument found (B028)


537-537: Use key in dict instead of key in dict.keys() (SIM118)

Remove .keys()

sleap_io/model/labels.py

17-17: sleap_io.Instance imported but unused (F401)

Remove unused import: sleap_io.Instance


88-88: Do not compare types, use isinstance() (E721)


92-92: Do not compare types, use isinstance() (E721)


183-183: Use X | Y for type annotations (UP007)

Convert to X | Y


183-183: Use X | Y for type annotations (UP007)

Convert to X | Y


217-217: Do not compare types, use isinstance() (E721)


238-242: Use ternary operator n_tracks = n_preds if untracked else len(self.tracks) instead of if-else-block (SIM108)


344-344: Use X | Y for type annotations (UP007)

Convert to X | Y


532-532: Do not compare types, use isinstance() (E721)


549-549: Do not compare types, use isinstance() (E721)


602-605: Use ternary operator inds2 = np.array([0]) if n0 == 1 else np.setdiff1d(np.arange(n0), inds1) instead of if-else-block (SIM108)

Replace if-else-block with inds2 = np.array([0]) if n0 == 1 else np.setdiff1d(np.arange(n0), inds1)

sleap_io/io/video.py

16-19: Use contextlib.suppress(ImportError) instead of try-except-pass (SIM105)

Replace with contextlib.suppress(ImportError)


21-24: Use contextlib.suppress(ImportError) instead of try-except-pass (SIM105)

Replace with contextlib.suppress(ImportError)


22-22: imageio_ffmpeg imported but unused; consider using importlib.util.find_spec to test for availability (F401)


26-29: Use contextlib.suppress(ImportError) instead of try-except-pass (SIM105)

Replace with contextlib.suppress(ImportError)


27-27: av imported but unused; consider using importlib.util.find_spec to test for availability (F401)


55-55: Use X | Y for type annotations (UP007)

Convert to X | Y


57-57: Use X | Y for type annotations (UP007)

Convert to X | Y


57-57: Use tuple instead of Tuple for type annotation (UP006)

Replace with tuple


58-58: Use X | Y for type annotations (UP007)

Convert to X | Y


64-64: Use X | Y for type annotations (UP007)

Convert to X | Y


65-65: Use X | Y for type annotations (UP007)

Convert to X | Y


87-87: Do not compare types, use isinstance() (E721)


90-90: Do not compare types, use isinstance() (E721)


161-161: Use tuple instead of Tuple for type annotation (UP006)

Replace with tuple


167-167: Use tuple instead of Tuple for type annotation (UP006)

Replace with tuple


486-486: Use X | Y for type annotations (UP007)

Convert to X | Y


492-492: Use X | Y for type annotations (UP007)

Convert to X | Y


493-493: Use X | Y for type annotations (UP007)

Convert to X | Y


528-530: Use a single if statement instead of nested if statements (SIM102)


559-559: Use tuple instead of Tuple for type annotation (UP006)

Replace with tuple


577-580: Use ternary operator frame_idx = list(self.frame_map.keys())[0] if self.frame_map else 0 instead of if-else-block (SIM108)

Replace if-else-block with frame_idx = list(self.frame_map.keys())[0] if self.frame_map else 0

sleap_io/io/slp.py

33-36: Use contextlib.suppress(ImportError) instead of try-except-pass (SIM105)

Replace with contextlib.suppress(ImportError)


376-376: Avoid equality comparisons to True; use if embed: for truth checks (E712)

Replace with embed


784-784: Use X | Y for type annotations (UP007)

Convert to X | Y


970-975: Use instances[instance_id][5] = inst_to_id.get(id(from_predicted), -1) instead of an if block (SIM401)

Additional comments not posted (10)
docs/index.md (3)

130-138: Highlight the addition of a new functionality for fixing video paths. Ensure to add documentation or examples on how the prefix_map works.


153-153: Highlight the new feature of saving labels with embedded images, which enhances data portability and usability.


168-168: Highlight the addition of a method for creating training, validation, and test splits, which is crucial for model training processes.

sleap_io/io/main.py (2)

25-25: The documentation for the embed parameter has been updated to reflect its flexible nature, allowing for multiple embedding options.


164-164: Convert the filename to a string using .as_posix() method for consistency in handling file paths across different operating systems.

sleap_io/model/video.py (1)

271-271: Ensure that the new_filename is converted to a posix path, which standardizes the file handling across different operating systems.

sleap_io/io/labelstudio.py (1)

46-48: Properly added provenance information to labels, enhancing traceability.

tests/io/test_slp.py (1)

Line range hint 286-324: Comprehensive tests for embedding functionality with various options.

sleap_io/io/nwb.py (1)

143-143: Provenance information correctly added to labels, enhancing traceability.

sleap_io/io/jabs.py (1)

172-174: Properly track provenance in read_labels by adding filename to the labels' provenance information.

This change aligns with the PR's goal of enhancing provenance tracking across different modules.

sleap_io/io/slp.py Outdated Show resolved Hide resolved
<a href="#__consent">Change cookie settings</a>

nav:
- Overview: index.md
- Changelog: https://github.com/talmolab/sleap-io/releases
- Core API:
- Data model: model.md
- Data formats: formats.md
- Model: model.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct the indentation of the Model and Formats items under the Core API section to align with the expected YAML structure.

-    - Model: model.md
-    - Formats: formats.md
+      - Model: model.md
+      - Formats: formats.md
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Model: model.md
- Model: model.md
Tools
yamllint

[warning] 154-154: wrong indentation: expected 6 but found 4 (indentation)

sio.save_file(labels, "predictions.nwb")
# Or:
# labels.save("predictions.nwb")
labels.save("predictions.nwb")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update method call to match the new method signature as per the PR changes.

- labels.save("predictions.nwb")
+ labels.save("predictions.nwb", embed=None)
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
labels.save("predictions.nwb")
labels.save("predictions.nwb", embed=None)

Copy link

codecov bot commented Jun 16, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 96.04%. Comparing base (d857684) to head (4a9108e).
Report is 1 commits behind head on main.

Current head 4a9108e differs from pull request most recent head d272c54

Please upload reports for the commit d272c54 to get more accurate results.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #98      +/-   ##
==========================================
+ Coverage   95.82%   96.04%   +0.22%     
==========================================
  Files          17       17              
  Lines        1962     2022      +60     
==========================================
+ Hits         1880     1942      +62     
+ Misses         82       80       -2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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

Outside diff range and nitpick comments (4)
tests/model/test_labels.py (2)

Line range hint 3-3: Remove unused import: numpy.testing.assert_equal


Line range hint 14-14: Remove unused import: sleap_io.load_video

sleap_io/io/slp.py (2)

Line range hint 33-36: Consider using contextlib.suppress for cleaner handling of optional imports.

- try:
-     import cv2
- except ImportError:
-     pass
+ from contextlib import suppress
+ with suppress(ImportError):
+     import cv2

Line range hint 784-784: Use the | operator for union type annotations to enhance readability.

- def read_instances(
-    labels_path: str,
-    skeletons: list[Skeleton],
-    tracks: list[Track],
-    points: list[Point],
-    pred_points: list[PredictedPoint],
-    format_id: float,
- ) -> list[Union[Instance, PredictedInstance]]:
+ def read_instances(
+    labels_path: str,
+    skeletons: list[Skeleton],
+    tracks: list[Track],
+    points: list[Point],
+    pred_points: list[PredictedPoint],
+    format_id: float,
+ ) -> list[Instance | PredictedInstance]:
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between af3e508 and 4a9108e.

Files selected for processing (2)
  • sleap_io/io/slp.py (5 hunks)
  • tests/model/test_labels.py (1 hunks)
Additional context used
Ruff
tests/model/test_labels.py

3-3: numpy.testing.assert_equal imported but unused (F401)

Remove unused import: numpy.testing.assert_equal


14-14: sleap_io.load_video imported but unused (F401)

Remove unused import: sleap_io.load_video


192-192: Found useless expression. Either assign it to a variable or remove it. (B018)


200-200: Found useless expression. Either assign it to a variable or remove it. (B018)


207-207: Found useless expression. Either assign it to a variable or remove it. (B018)


215-215: Found useless expression. Either assign it to a variable or remove it. (B018)

sleap_io/io/slp.py

33-36: Use contextlib.suppress(ImportError) instead of try-except-pass (SIM105)

Replace with contextlib.suppress(ImportError)


376-376: Avoid equality comparisons to True; use if embed: for truth checks (E712)

Replace with embed


784-784: Use X | Y for type annotations (UP007)

Convert to X | Y

Additional comments not posted (4)
tests/model/test_labels.py (3)

540-570: The previous comment about adding error handling for the sum of split ratios exceeding 1 still applies.


421-537: The tests for the split method are comprehensive and cover various scenarios including edge cases with rounding and integer inputs. However, consider adding assertions to verify the actual contents of the splits to ensure that the splitting logic is not only dividing the counts correctly but also assigning the right frames to each split.


572-589: The tests for make_training_splits_save are good as they verify the integrity of the saved splits. However, adding checks for the contents of the saved files can further ensure that the data is saved correctly and not just the metadata.

sleap_io/io/slp.py (1)

970-972: This change has already been reviewed and approved.

"""
if embed == True:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplify the truth check for better readability and performance.

- if embed == True:
+ if embed:
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if embed == True:
if embed:
Tools
Ruff

376-376: Avoid equality comparisons to True; use if embed: for truth checks (E712)

Replace with embed

Comment on lines +540 to +570
def test_make_training_splits(slp_real_data, tmp_path):
labels = load_slp(slp_real_data)
assert len(labels.user_labeled_frames) == 5

train, val = labels.make_training_splits(0.8)
assert len(train) == 4
assert len(val) == 1

train, val = labels.make_training_splits(3)
assert len(train) == 3
assert len(val) == 2

train, val = labels.make_training_splits(0.8, 0.2)
assert len(train) == 4
assert len(val) == 1

train, val, test = labels.make_training_splits(0.8, 0.1, 0.1)
assert len(train) == 4
assert len(val) == 1
assert len(test) == 1

train, val, test = labels.make_training_splits(n_train=0.6, n_test=1)
assert len(train) == 3
assert len(val) == 1
assert len(test) == 1

train, val, test = labels.make_training_splits(n_train=1, n_val=1, n_test=1)
assert len(train) == 1
assert len(val) == 1
assert len(test) == 1

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test for make_training_splits method seems to lack error handling for cases where the sum of the split ratios exceeds 1. This should raise an appropriate error to prevent data inconsistencies.

def make_training_splits(
    self,
    n_train: int | float,
    n_val: int | float | None = None,
    n_test: int | float | None = None,
    save_dir: str | Path | None = None,
    seed: int | None = None,
) -> tuple[Labels, Labels] | tuple[Labels, Labels, Labels]:
    total = (n_train if n_train < 1 else 0) + (n_val if n_val and n_val < 1 else 0) + (n_test if n_test and n_test < 1 else 0)
    if total > 1:
        raise ValueError("The sum of n_train, n_val, and n_test should not exceed 1.")
    # rest of the method

@talmo talmo merged commit 5a30110 into main Jun 19, 2024
6 checks passed
@talmo talmo deleted the talmo/split branch June 19, 2024 02:36
@talmo talmo linked an issue Jun 25, 2024 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Labels.split
1 participant