-
Notifications
You must be signed in to change notification settings - Fork 96
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
Allowing inference on multiple videos via sleap-track
#1784
Allowing inference on multiple videos via sleap-track
#1784
Conversation
WalkthroughThe recent updates to the Changes
Poem
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? 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 as PR comments)
Additionally, you can add 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
Review Details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- sleap/nn/inference.py (4 hunks)
Additional Context Used
Ruff (3)
sleap/nn/inference.py (3)
149-149: Undefined name
Task
584-584: Local variable
outputs
is assigned to but never used
4615-4615: Do not compare types, use
isinstance()
Additional comments not posted (2)
sleap/nn/inference.py (2)
5291-5340
: Refactor to handle multiple data paths and providers looks good. Consider adding comments to explain the handling of different file types.
5474-5474
: Integration of the new provider and data path handling in data loader setup looks correct. Ensure compatibility with the tracker setup.Verification successful
The
_make_tracker_from_cli
function and its usage appear to be correctly integrated with the new data structures. The function creates a tracker based on CLI arguments, and the test file verifies its output, ensuring compatibility.
sleap/nn/inference.py
:
- Function definition:
_make_tracker_from_cli(args: argparse.Namespace) -> Optional[Tracker]
- The function creates a tracker based on parsed CLI arguments.
tests/nn/test_inference.py
:
- The function is used to create a tracker and verify its output.
The integration of the new provider and data path handling in the data loader setup looks correct. Ensure compatibility with the tracker setup.
Scripts Executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify tracker setup compatibility with new data structures. # Test: Search for the tracker setup function and its usage. Expect: Compatibility with new data structures. rg --type python $'_make_tracker_from_cli'Length of output: 72
Script:
#!/bin/bash # Description: Verify tracker setup compatibility with new data structures. # Test: Search for the tracker setup function and its usage. Expect: Compatibility with new data structures. rg --type py '_make_tracker_from_cli'Length of output: 328
Script:
#!/bin/bash # Description: Extract the `_make_tracker_from_cli` function definition and its usage. # Extract the function definition. rg --type py --context 10 'def _make_tracker_from_cli' sleap/nn/inference.py # Extract the usage in the test file. rg --type py --context 10 '_make_tracker_from_cli' tests/nn/test_inference.pyLength of output: 1899
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
Review Details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- sleap/nn/inference.py (3 hunks)
Additional Context Used
Ruff (3)
sleap/nn/inference.py (3)
149-149: Undefined name
Task
584-584: Local variable
outputs
is assigned to but never used
4615-4615: Do not compare types, use
isinstance()
Additional comments not posted (1)
sleap/nn/inference.py (1)
5600-5600
: Refine the error message to provide more context and guidance.- "Use \"sleap-track --tracking.tracker ...' to specify tracker to use." + "Specify the tracker using 'sleap-track --tracking.tracker'. Refer to the documentation for more details."
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: 3
Review Details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- sleap/nn/inference.py (4 hunks)
Additional Context Used
Ruff (3)
sleap/nn/inference.py (3)
149-149: Undefined name
Task
584-584: Local variable
outputs
is assigned to but never used
4615-4615: Do not compare types, use
isinstance()
Additional comments not posted (1)
sleap/nn/inference.py (1)
5607-5607
: The device setup logic is correctly implemented to handle both CPU and GPU based on the user's configuration.
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
Review Details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- sleap/nn/inference.py (4 hunks)
Additional Context Used
Ruff (3)
sleap/nn/inference.py (3)
149-149: Undefined name
Task
584-584: Local variable
outputs
is assigned to but never used
4615-4615: Do not compare types, use
isinstance()
Additional comments not posted (2)
sleap/nn/inference.py (2)
5611-5611
: Refine the error message to provide more context and guidance.
5611-5611
: Refine the error message to provide more context and guidance.
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: 4
Outside diff range and nitpick comments (10)
tests/nn/test_inference.py (10)
Line range hint
11-11
: Remove unused import:tensorflow_hub
.- import tensorflow_hub as hub
Tools
Ruff
6-6:
os
imported but unused (F401)Remove unused import:
os
Line range hint
15-15
: Remove unused import:sleap.gui.learning.runners
.- from sleap.gui.learning import runners
Tools
Ruff
6-6:
os
imported but unused (F401)Remove unused import:
os
Line range hint
23-24
: Remove unused imports related toInferenceLayer
andInferenceModel
.- from sleap.nn.inference import ( - InferenceLayer, - InferenceModel,Tools
Ruff
6-6:
os
imported but unused (F401)Remove unused import:
os
Line range hint
57-57
: Remove unused import:sleap.nn.tracking.MatchedFrameInstance
.- from sleap.nn.tracking import ( - MatchedFrameInstance,Tools
Ruff
6-6:
os
imported but unused (F401)Remove unused import:
os
Line range hint
62-62
: Remove unused import:sleap.instance.Track
.- from sleap.instance import Track
Tools
Ruff
6-6:
os
imported but unused (F401)Remove unused import:
os
Line range hint
605-605
: Replace equality comparisons toFalse
andTrue
with more Pythonic expressions.- if predictor.is_grayscale == False + if not predictor.is_grayscale - if predictor.is_grayscale == True + if predictor.is_grayscaleAlso applies to: 653-653, 702-702, 735-735, 1644-1644
Tools
Ruff
6-6:
os
imported but unused (F401)Remove unused import:
os
Line range hint
890-890
: Remove assignment to unused variablepredictor
.- predictor = load_model(model_path)
Tools
Ruff
6-6:
os
imported but unused (F401)Remove unused import:
os
Line range hint
1249-1249
: Consider replacingpytest.raises(Exception)
with a more specific exception type to improve test clarity and error handling.Tools
Ruff
6-6:
os
imported but unused (F401)Remove unused import:
os
Line range hint
1379-1379
: Remove assignment to unused variablelabels
.- labels = min_tracks_2node_labels
Tools
Ruff
6-6:
os
imported but unused (F401)Remove unused import:
os
Line range hint
1565-1565
: Usekey in dict
instead ofkey in dict.keys()
for more efficient dictionary lookups.- for track in tracker.track_matching_queue_dict.keys(): + for track in tracker.track_matching_queue_dict: - for key in tracker.candidate_maker.shifted_instances.keys(): + for key in tracker.candidate_maker.shifted_instances:Also applies to: 1609-1609, 1614-1614
Tools
Ruff
6-6:
os
imported but unused (F401)Remove unused import:
os
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (2)
- sleap/nn/inference.py (4 hunks)
- tests/nn/test_inference.py (4 hunks)
Additional context used
Ruff
tests/nn/test_inference.py
6-6:
os
imported but unused (F401)Remove unused import:
os
11-11:
tensorflow_hub
imported but unused (F401)Remove unused import:
tensorflow_hub
15-15:
sleap.gui.learning.runners
imported but unused (F401)Remove unused import:
sleap.gui.learning.runners
23-23:
sleap.nn.inference.InferenceLayer
imported but unused (F401)Remove unused import
24-24:
sleap.nn.inference.InferenceModel
imported but unused (F401)Remove unused import
57-57:
sleap.nn.tracking.MatchedFrameInstance
imported but unused (F401)Remove unused import:
sleap.nn.tracking.MatchedFrameInstance
62-62:
sleap.instance.Track
imported but unused (F401)Remove unused import:
sleap.instance.Track
605-605: Avoid equality comparisons to
False
; useif not predictor.is_grayscale:
for false checks (E712)Replace with
not predictor.is_grayscale
653-653: Avoid equality comparisons to
True
; useif predictor.is_grayscale:
for truth checks (E712)Replace with
predictor.is_grayscale
702-702: Avoid equality comparisons to
True
; useif predictor.is_grayscale:
for truth checks (E712)Replace with
predictor.is_grayscale
735-735: Avoid equality comparisons to
True
; useif predictor.is_grayscale:
for truth checks (E712)Replace with
predictor.is_grayscale
794-794: Pointless comparison. Did you mean to assign a value? Otherwise, prepend
assert
or remove it. (B015)
795-795: Pointless comparison. Did you mean to assign a value? Otherwise, prepend
assert
or remove it. (B015)
890-890: Local variable
predictor
is assigned to but never used (F841)Remove assignment to unused variable
predictor
1249-1249:
pytest.raises(Exception)
should be considered evil (B017)
1379-1379: Local variable
labels
is assigned to but never used (F841)Remove assignment to unused variable
labels
1565-1565: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1609-1609: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1614-1614: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1644-1644: Avoid equality comparisons to
False
; useif not predictor.is_grayscale:
for false checks (E712)Replace with
not predictor.is_grayscale
sleap/nn/inference.py
131-131:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
149-149: Undefined name
Task
(F821)
584-584: Local variable
outputs
is assigned to but never used (F841)Remove assignment to unused variable
outputs
605-605:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
613-613:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
627-627:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
641-641:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
695-696: Use a single
if
statement instead of nestedif
statements (SIM102)Combine
if
statements usingand
1183-1183: No explicit
stacklevel
keyword argument found (B028)
1325-1328: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
1468-1468:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
1758-1763: Use ternary operator
imgs = inputs["image"] if isinstance(inputs, dict) else inputs
instead ofif
-else
-block (SIM108)
2394-2394:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
2395-2395:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
2822-2825: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
3110-3110:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
3424-3427: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
3436-3439: Use ternary operator
offsets = preds[self.offsets_ind] if self.offsets_ind is not None else None
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withoffsets = preds[self.offsets_ind] if self.offsets_ind is not None else None
3654-3654:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
3756-3756: Loop control variable
image
not used within loop body (B007)Rename unused
image
to_image
4262-4262:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4263-4263:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4452-4452: Loop control variable
image
not used within loop body (B007)Rename unused
image
to_image
4615-4619: Use ternary operator
img = ex["image"] if type(ex) == dict else ex
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimg = ex["image"] if type(ex) == dict else ex
4615-4615: Do not compare types, use
isinstance()
(E721)
4709-4709:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4873-4876: Use ternary operator
model_paths = [model_path] if isinstance(model_path, str) else model_path
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withmodel_paths = [model_path] if isinstance(model_path, str) else model_path
5294-5297: Use ternary operator
data_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withdata_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
5350-5350: Local variable
e
is assigned to but never used (F841)Remove assignment to unused variable
e
Additional comments not posted (7)
tests/nn/test_inference.py (1)
1486-1537
: The test functiontest_sleap_track_mult_input
is designed to handle multiple input files for tracking. Ensure that the test covers all necessary assertions and cleanup operations correctly.Verification successful
The test function
test_sleap_track_mult_input
and its related functionstest_sleap_track_mult_inputs_folder_slp_files
andtest_sleap_track_mult_inputs_folder
have been successfully extracted. The implementation shows that the test function is designed to handle multiple input files for tracking and includes assertions to ensure the existence of prediction files and cleanup operations.
test_sleap_track_mult_input
handles multiple files by iterating over the directory contents and asserting the existence of files before and after running thesleap_track
command.- The function
test_sleap_track_mult_inputs_folder_slp_files
returns a path to a directory containing multiple input files.- The function
test_sleap_track_mult_inputs_folder
is defined as a fixture but its implementation is not fully shown.Based on the extracted code, the test function appears to cover the necessary assertions and cleanup operations correctly.
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that the test function `test_sleap_track_mult_input` handles multiple files correctly. # Test: Search for the function usage. Expect: Proper handling of multiple files. rg --type python $'test_sleap_track_mult_input'Length of output: 77
Script:
#!/bin/bash # Description: Verify that the test function `test_sleap_track_mult_input` handles multiple files correctly. # Test: Search for the function usage. Expect: Proper handling of multiple files. rg --type py $'test_sleap_track_mult_input'Length of output: 578
Script:
#!/bin/bash # Description: Extract the implementation of `test_sleap_track_mult_input` and related functions from `tests/nn/test_inference.py`. # Extract the implementation of the function `test_sleap_track_mult_input` and related functions. ast-grep --lang python --pattern $'def test_sleap_track_mult_input($_$$$) { $$$ }' tests/nn/test_inference.py ast-grep --lang python --pattern $'def test_sleap_track_mult_inputs_folder_slp_files($_$$$) { $$$ }' tests/nn/test_inference.py ast-grep --lang python --pattern $'def test_sleap_track_mult_inputs_folder($_$$$) { $$$ }' tests/nn/test_inference.pyLength of output: 1803
Script:
#!/bin/bash # Description: Extract the implementation of `test_sleap_track_mult_input` and related functions from `tests/nn/test_inference.py`. # Extract the implementation of the function `test_sleap_track_mult_input` and related functions. ast-grep --lang python --pattern 'def test_sleap_track_mult_input($_$$$): $$$' tests/nn/test_inference.py ast-grep --lang python --pattern 'def test_sleap_track_mult_inputs_folder_slp_files($_$$$): $$$' tests/nn/test_inference.py ast-grep --lang python --pattern 'def test_sleap_track_mult_inputs_folder($_$$$): $$$' tests/nn/test_inference.pyLength of output: 349
Script:
#!/bin/bash # Description: Search for the function definitions of `test_sleap_track_mult_input` and related functions in `tests/nn/test_inference.py`. # Search for the function definitions. rg 'def test_sleap_track_mult_input' tests/nn/test_inference.py rg 'def test_sleap_track_mult_inputs_folder_slp_files' tests/nn/test_inference.py rg 'def test_sleap_track_mult_inputs_folder' tests/nn/test_inference.pyLength of output: 501
Script:
#!/bin/bash # Description: Extract the full implementation of `test_sleap_track_mult_input` and related functions from `tests/nn/test_inference.py`. # Extract the full implementation of the function `test_sleap_track_mult_input`. sed -n '/def test_sleap_track_mult_input/,/^def/p' tests/nn/test_inference.py # Extract the full implementation of the function `test_sleap_track_mult_inputs_folder_slp_files`. sed -n '/def test_sleap_track_mult_inputs_folder_slp_files/,/^def/p' tests/nn/test_inference.py # Extract the full implementation of the function `test_sleap_track_mult_inputs_folder`. sed -n '/def test_sleap_track_mult_inputs_folder/,/^def/p' tests/nn/test_inference.pyLength of output: 2565
sleap/nn/inference.py (6)
5300-5307
: Ensure proper handling of directories and files. The current implementation is correct but consider adding a comment about the expected directory structure or file types for clarity.
5448-5448
: Logging the parsed arguments is good for debugging. Ensure sensitive information is not logged.
5488-5488
: Correct setup of data loaders and trackers. Ensure that_make_provider_from_cli
and_make_tracker_from_cli
are robust and handle errors appropriately.
5510-5564
: This block handles the core functionality of running inference on multiple inputs. Ensure that all edge cases are handled, such as empty input lists or errors during processing.
5568-5617
: The tracking logic appears robust. Consider adding more detailed logging to help with debugging and ensure that all paths are correctly reset after each iteration.
5627-5627
: Refine the error message to provide more context and guidance.
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: 5
Outside diff range and nitpick comments (12)
tests/nn/test_inference.py (11)
Line range hint
10-10
: Remove unused import:tensorflow_hub
.- import tensorflow_hub as hub
Line range hint
14-14
: Remove unused import:sleap.gui.learning.runners
.- from sleap.gui.learning import runners
Line range hint
22-23
: Remove unused imports related to inference layers and models.- from sleap.nn.inference import InferenceLayer - from sleap.nn.inference import InferenceModel
Line range hint
56-56
: Remove unused import:sleap.nn.tracking.MatchedFrameInstance
.- from sleap.nn.tracking import MatchedFrameInstance
Line range hint
61-61
: Remove unused import:sleap.instance.Track
.- from sleap.instance import Track
Line range hint
608-608
: Replace equality comparisons to boolean values with direct truthy or falsy checks.- if predictor.is_grayscale == False + if not predictor.is_grayscale - if predictor.is_grayscale == True + if predictor.is_grayscaleAlso applies to: 656-656, 705-705, 738-738, 1743-1743
Line range hint
797-798
: These lines appear to be comparisons without assertions or any other form of logical continuation. If these are intended to be assertions, please add theassert
keyword; otherwise, these lines should be removed or corrected.- out["instance_peaks"].shape == (2, 1, 17, 2) + assert out["instance_peaks"].shape == (2, 1, 17, 2) - out["instance_peak_vals"].shape == (2, 1, 17) + assert out["instance_peak_vals"].shape == (2, 1, 17)
Line range hint
893-893
: Remove assignment to unused variablepredictor
.- predictor = load_model(model_path)
Line range hint
1252-1252
: Usingpytest.raises(Exception)
is generally considered too broad. It is better to specify the exact type of exception expected to make the test more precise and informative.- with pytest.raises(Exception): + with pytest.raises(SpecificExceptionType):
Line range hint
1382-1382
: Remove assignment to unused variablelabels
.- labels: Labels = centered_pair_predictions
Line range hint
1664-1664
: Use direct dictionary key checks instead of calling.keys()
.- if key in dict.keys(): + if key in dict:Also applies to: 1708-1708, 1713-1713
sleap/nn/inference.py (1)
5448-5448
: Consider adding more descriptive comments or logging for debugging purposes.It might be helpful to add more context to the printed arguments for easier debugging and maintenance.
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (2)
- sleap/nn/inference.py (4 hunks)
- tests/nn/test_inference.py (3 hunks)
Additional context used
Ruff
tests/nn/test_inference.py
10-10:
tensorflow_hub
imported but unused (F401)Remove unused import:
tensorflow_hub
14-14:
sleap.gui.learning.runners
imported but unused (F401)Remove unused import:
sleap.gui.learning.runners
22-22:
sleap.nn.inference.InferenceLayer
imported but unused (F401)Remove unused import
23-23:
sleap.nn.inference.InferenceModel
imported but unused (F401)Remove unused import
56-56:
sleap.nn.tracking.MatchedFrameInstance
imported but unused (F401)Remove unused import:
sleap.nn.tracking.MatchedFrameInstance
61-61:
sleap.instance.Track
imported but unused (F401)Remove unused import:
sleap.instance.Track
608-608: Avoid equality comparisons to
False
; useif not predictor.is_grayscale:
for false checks (E712)Replace with
not predictor.is_grayscale
656-656: Avoid equality comparisons to
True
; useif predictor.is_grayscale:
for truth checks (E712)Replace with
predictor.is_grayscale
705-705: Avoid equality comparisons to
True
; useif predictor.is_grayscale:
for truth checks (E712)Replace with
predictor.is_grayscale
738-738: Avoid equality comparisons to
True
; useif predictor.is_grayscale:
for truth checks (E712)Replace with
predictor.is_grayscale
797-797: Pointless comparison. Did you mean to assign a value? Otherwise, prepend
assert
or remove it. (B015)
798-798: Pointless comparison. Did you mean to assign a value? Otherwise, prepend
assert
or remove it. (B015)
893-893: Local variable
predictor
is assigned to but never used (F841)Remove assignment to unused variable
predictor
1252-1252:
pytest.raises(Exception)
should be considered evil (B017)
1382-1382: Local variable
labels
is assigned to but never used (F841)Remove assignment to unused variable
labels
1664-1664: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1708-1708: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1713-1713: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1743-1743: Avoid equality comparisons to
False
; useif not predictor.is_grayscale:
for false checks (E712)Replace with
not predictor.is_grayscale
sleap/nn/inference.py
131-131:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
149-149: Undefined name
Task
(F821)
584-584: Local variable
outputs
is assigned to but never used (F841)Remove assignment to unused variable
outputs
605-605:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
613-613:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
627-627:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
641-641:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
695-696: Use a single
if
statement instead of nestedif
statements (SIM102)Combine
if
statements usingand
1183-1183: No explicit
stacklevel
keyword argument found (B028)
1325-1328: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
1468-1468:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
1758-1763: Use ternary operator
imgs = inputs["image"] if isinstance(inputs, dict) else inputs
instead ofif
-else
-block (SIM108)
2394-2394:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
2395-2395:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
2822-2825: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
3110-3110:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
3424-3427: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
3436-3439: Use ternary operator
offsets = preds[self.offsets_ind] if self.offsets_ind is not None else None
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withoffsets = preds[self.offsets_ind] if self.offsets_ind is not None else None
3654-3654:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
3756-3756: Loop control variable
image
not used within loop body (B007)Rename unused
image
to_image
4262-4262:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4263-4263:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4452-4452: Loop control variable
image
not used within loop body (B007)Rename unused
image
to_image
4615-4619: Use ternary operator
img = ex["image"] if type(ex) == dict else ex
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimg = ex["image"] if type(ex) == dict else ex
4615-4615: Do not compare types, use
isinstance()
(E721)
4709-4709:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4873-4876: Use ternary operator
model_paths = [model_path] if isinstance(model_path, str) else model_path
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withmodel_paths = [model_path] if isinstance(model_path, str) else model_path
5294-5297: Use ternary operator
data_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withdata_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
5350-5350: Local variable
e
is assigned to but never used (F841)Remove assignment to unused variable
e
Additional comments not posted (1)
tests/nn/test_inference.py (1)
67-77
: The new fixtures introduced here are crucial for testing the multi-video inference capabilities. They correctly set up paths to test data for different input formats. Ensure that the paths are valid and the data is correctly formatted for these tests.
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: 5
Outside diff range and nitpick comments (2)
sleap/nn/inference.py (2)
5368-5368
: Consider removing or guarding debug print statements in production code.It's generally good practice to avoid leaving debug prints in production code or guard them with a verbosity check.
5449-5449
: Ensure that the debug prints are necessary or are appropriately gated by a debug or verbose flag.Consider wrapping debug statements with a verbosity check to avoid cluttering the output in production environments.
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (2)
- sleap/nn/inference.py (5 hunks)
- tests/nn/test_inference.py (3 hunks)
Additional context used
Ruff
tests/nn/test_inference.py
10-10:
tensorflow_hub
imported but unused (F401)Remove unused import:
tensorflow_hub
14-14:
sleap.gui.learning.runners
imported but unused (F401)Remove unused import:
sleap.gui.learning.runners
22-22:
sleap.nn.inference.InferenceLayer
imported but unused (F401)Remove unused import
23-23:
sleap.nn.inference.InferenceModel
imported but unused (F401)Remove unused import
56-56:
sleap.nn.tracking.MatchedFrameInstance
imported but unused (F401)Remove unused import:
sleap.nn.tracking.MatchedFrameInstance
61-61:
sleap.instance.Track
imported but unused (F401)Remove unused import:
sleap.instance.Track
612-612: Avoid equality comparisons to
False
; useif not predictor.is_grayscale:
for false checks (E712)Replace with
not predictor.is_grayscale
660-660: Avoid equality comparisons to
True
; useif predictor.is_grayscale:
for truth checks (E712)Replace with
predictor.is_grayscale
709-709: Avoid equality comparisons to
True
; useif predictor.is_grayscale:
for truth checks (E712)Replace with
predictor.is_grayscale
742-742: Avoid equality comparisons to
True
; useif predictor.is_grayscale:
for truth checks (E712)Replace with
predictor.is_grayscale
801-801: Pointless comparison. Did you mean to assign a value? Otherwise, prepend
assert
or remove it. (B015)
802-802: Pointless comparison. Did you mean to assign a value? Otherwise, prepend
assert
or remove it. (B015)
897-897: Local variable
predictor
is assigned to but never used (F841)Remove assignment to unused variable
predictor
1256-1256:
pytest.raises(Exception)
should be considered evil (B017)
1386-1386: Local variable
labels
is assigned to but never used (F841)Remove assignment to unused variable
labels
1708-1708: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1752-1752: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1757-1757: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1787-1787: Avoid equality comparisons to
False
; useif not predictor.is_grayscale:
for false checks (E712)Replace with
not predictor.is_grayscale
sleap/nn/inference.py
131-131:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
149-149: Undefined name
Task
(F821)
584-584: Local variable
outputs
is assigned to but never used (F841)Remove assignment to unused variable
outputs
605-605:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
613-613:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
627-627:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
641-641:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
695-696: Use a single
if
statement instead of nestedif
statements (SIM102)Combine
if
statements usingand
1183-1183: No explicit
stacklevel
keyword argument found (B028)
1325-1328: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
1468-1468:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
1758-1763: Use ternary operator
imgs = inputs["image"] if isinstance(inputs, dict) else inputs
instead ofif
-else
-block (SIM108)
2394-2394:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
2395-2395:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
2822-2825: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
3110-3110:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
3424-3427: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
3436-3439: Use ternary operator
offsets = preds[self.offsets_ind] if self.offsets_ind is not None else None
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withoffsets = preds[self.offsets_ind] if self.offsets_ind is not None else None
3654-3654:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
3756-3756: Loop control variable
image
not used within loop body (B007)Rename unused
image
to_image
4262-4262:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4263-4263:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4452-4452: Loop control variable
image
not used within loop body (B007)Rename unused
image
to_image
4615-4619: Use ternary operator
img = ex["image"] if type(ex) == dict else ex
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimg = ex["image"] if type(ex) == dict else ex
4615-4615: Do not compare types, use
isinstance()
(E721)
4709-4709:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4873-4876: Use ternary operator
model_paths = [model_path] if isinstance(model_path, str) else model_path
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withmodel_paths = [model_path] if isinstance(model_path, str) else model_path
5294-5297: Use ternary operator
data_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withdata_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
5350-5350: Local variable
e
is assigned to but never used (F841)Remove assignment to unused variable
e
Additional comments not posted (4)
tests/nn/test_inference.py (4)
66-69
: LGTM! This fixture correctly provides a path for multiple.slp
inputs as expected.
74-77
: LGTM! This fixture properly returns a directory path for testing with both.slp
and.mp4
inputs.
78-81
: LGTM! The fixture correctly provides a path for directories with multiple.mp4
files, facilitating testing of the new multi-input feature.
1524-1637
: Excellent work on testing the new multi-input functionality. The test is well-structured and covers the essential aspects of the feature by checking the existence of expected output files.
sleap/nn/inference.py
Outdated
|
||
if args.open_in_gui: | ||
subprocess.call(["sleap-label", output_path]) | ||
|
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.
Refine the error message to provide more context and guidance.
- "Use \"sleap-track --tracking.tracker ...' to specify tracker to use."
+ "Specify the tracker using 'sleap-track --tracking.tracker'. Refer to the documentation for more details."
Committable suggestion was skipped due to low confidence.
sleap/nn/inference.py
Outdated
|
||
# Figure out which input path to use. | ||
labels_path = getattr(args, "labels", None) | ||
if labels_path is not None: | ||
data_path = labels_path | ||
data_path = Path(labels_path) | ||
else: | ||
data_path = Path(args.data_path) | ||
|
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.
Consider using a ternary operator for cleaner and more concise code.
- if labels_path is not None:
- data_path = Path(labels_path)
- else:
- data_path = Path(args.data_path)
+ data_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
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.
# Figure out which input path to use. | |
labels_path = getattr(args, "labels", None) | |
if labels_path is not None: | |
data_path = labels_path | |
data_path = Path(labels_path) | |
else: | |
data_path = Path(args.data_path) | |
# Figure out which input path to use. | |
labels_path = getattr(args, "labels", None) | |
data_path = Path(labels_path) if labels_path is not None else Path(args.data_path) | |
Tools
Ruff
5294-5297: Use ternary operator
data_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withdata_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
sleap/nn/inference.py
Outdated
if output_path is not None and (Path.is_file(output_path_obj) and len(data_path_list) > 1): | ||
raise ValueError( | ||
"output_path argument must be a directory if multiple video inputs are given" | ||
) |
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.
Validate the output path more robustly to handle cases where the output path is not a directory but should be.
- if output_path is not None and (Path.is_file(output_path_obj) and len(data_path_list) > 1):
+ if output_path is not None and not Path(output_path_obj).is_dir() and len(data_path_list) > 1:
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.
if output_path is not None and (Path.is_file(output_path_obj) and len(data_path_list) > 1): | |
raise ValueError( | |
"output_path argument must be a directory if multiple video inputs are given" | |
) | |
if output_path is not None and not Path(output_path_obj).is_dir() and len(data_path_list) > 1: | |
raise ValueError( | |
"output_path argument must be a directory if multiple video inputs are given" | |
) |
sleap/nn/inference.py
Outdated
# Check for multiple video inputs | ||
# Compile file(s) into a list for later itteration | ||
if data_path.is_dir: | ||
data_path_list = [] | ||
for file_path in data_path.iterdir(): | ||
if file_path.is_file(): | ||
data_path_list.append(file_path) | ||
elif data_path.is_file: | ||
data_path_list = [args.data_path] |
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.
Ensure is_dir
is called as a method to check if the path is a directory.
- if data_path.is_dir:
+ if data_path.is_dir():
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.
# Check for multiple video inputs | |
# Compile file(s) into a list for later itteration | |
if data_path.is_dir: | |
data_path_list = [] | |
for file_path in data_path.iterdir(): | |
if file_path.is_file(): | |
data_path_list.append(file_path) | |
elif data_path.is_file: | |
data_path_list = [args.data_path] | |
# Check for multiple video inputs | |
# Compile file(s) into a list for later itteration | |
if data_path.is_dir(): | |
data_path_list = [] | |
for file_path in data_path.iterdir(): | |
if file_path.is_file(): | |
data_path_list.append(file_path) | |
elif data_path.is_file: | |
data_path_list = [args.data_path] |
sleap/nn/inference.py
Outdated
# Provider list to accomodate multiple video inputs | ||
provider_list = [] | ||
tmp_data_path_list = [] | ||
for data_path_file in data_path_list: | ||
data_path_file = Path(data_path_file) | ||
# Create a provider for each file | ||
if data_path_file.as_posix().endswith(".slp"): | ||
print(f"Sleap file: {data_path_file}") | ||
labels = sleap.load_file(data_path_file.as_posix()) | ||
|
||
if args.only_labeled_frames: | ||
provider_list.append(LabelsReader.from_user_labeled_frames(labels)) | ||
elif args.only_suggested_frames: | ||
provider_list.append(LabelsReader.from_unlabeled_suggestions(labels)) | ||
elif getattr(args, "video.index") != "": | ||
provider_list.append(VideoReader( | ||
video=labels.videos[int(getattr(args, "video.index"))], | ||
example_indices=frame_list(args.frames), | ||
)) | ||
else: | ||
provider_list.append(LabelsReader(labels)) | ||
|
||
tmp_data_path_list.append(data_path_file) | ||
|
||
else: | ||
print(f"Video: {data_path}") | ||
# TODO: Clean this up. | ||
video_kwargs = dict( | ||
dataset=vars(args).get("video.dataset"), | ||
input_format=vars(args).get("video.input_format"), | ||
) | ||
provider = VideoReader.from_filepath( | ||
filename=data_path, example_indices=frame_list(args.frames), **video_kwargs | ||
) | ||
else: | ||
try: | ||
video_kwargs = dict( | ||
dataset=vars(args).get("video.dataset"), | ||
input_format=vars(args).get("video.input_format"), | ||
) | ||
provider_list.append(VideoReader.from_filepath( | ||
filename=data_path_file.as_posix(), example_indices=frame_list(args.frames), **video_kwargs | ||
)) | ||
print(f"Video: {data_path_file}") | ||
tmp_data_path_list.append(data_path_file) | ||
# TODO: Clean this up. | ||
except Exception as e: | ||
print(f"Error reading file: {data_path_file}") | ||
|
||
data_path_list = tmp_data_path_list | ||
|
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.
Refactor exception handling to catch specific exceptions and remove the assignment to the unused variable e
.
- except Exception as e:
+ except (FileNotFoundError, PermissionError):
- print(f"Error reading file: {data_path_file}")
+ print(f"Error reading file: {data_path_file}. Please check the file's existence and permissions.")
- except Exception as e:
+ except Exception:
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.
# Provider list to accomodate multiple video inputs | |
provider_list = [] | |
tmp_data_path_list = [] | |
for data_path_file in data_path_list: | |
data_path_file = Path(data_path_file) | |
# Create a provider for each file | |
if data_path_file.as_posix().endswith(".slp"): | |
print(f"Sleap file: {data_path_file}") | |
labels = sleap.load_file(data_path_file.as_posix()) | |
if args.only_labeled_frames: | |
provider_list.append(LabelsReader.from_user_labeled_frames(labels)) | |
elif args.only_suggested_frames: | |
provider_list.append(LabelsReader.from_unlabeled_suggestions(labels)) | |
elif getattr(args, "video.index") != "": | |
provider_list.append(VideoReader( | |
video=labels.videos[int(getattr(args, "video.index"))], | |
example_indices=frame_list(args.frames), | |
)) | |
else: | |
provider_list.append(LabelsReader(labels)) | |
tmp_data_path_list.append(data_path_file) | |
else: | |
print(f"Video: {data_path}") | |
# TODO: Clean this up. | |
video_kwargs = dict( | |
dataset=vars(args).get("video.dataset"), | |
input_format=vars(args).get("video.input_format"), | |
) | |
provider = VideoReader.from_filepath( | |
filename=data_path, example_indices=frame_list(args.frames), **video_kwargs | |
) | |
else: | |
try: | |
video_kwargs = dict( | |
dataset=vars(args).get("video.dataset"), | |
input_format=vars(args).get("video.input_format"), | |
) | |
provider_list.append(VideoReader.from_filepath( | |
filename=data_path_file.as_posix(), example_indices=frame_list(args.frames), **video_kwargs | |
)) | |
print(f"Video: {data_path_file}") | |
tmp_data_path_list.append(data_path_file) | |
# TODO: Clean this up. | |
except Exception as e: | |
print(f"Error reading file: {data_path_file}") | |
data_path_list = tmp_data_path_list | |
# Provider list to accomodate multiple video inputs | |
provider_list = [] | |
tmp_data_path_list = [] | |
for data_path_file in data_path_list: | |
data_path_file = Path(data_path_file) | |
# Create a provider for each file | |
if data_path_file.as_posix().endswith(".slp"): | |
print(f"Sleap file: {data_path_file}") | |
labels = sleap.load_file(data_path_file.as_posix()) | |
if args.only_labeled_frames: | |
provider_list.append(LabelsReader.from_user_labeled_frames(labels)) | |
elif args.only_suggested_frames: | |
provider_list.append(LabelsReader.from_unlabeled_suggestions(labels)) | |
elif getattr(args, "video.index") != "": | |
provider_list.append(VideoReader( | |
video=labels.videos[int(getattr(args, "video.index"))], | |
example_indices=frame_list(args.frames), | |
)) | |
else: | |
provider_list.append(LabelsReader(labels)) | |
tmp_data_path_list.append(data_path_file) | |
else: | |
try: | |
video_kwargs = dict( | |
dataset=vars(args).get("video.dataset"), | |
input_format=vars(args).get("video.input_format"), | |
) | |
provider_list.append(VideoReader.from_filepath( | |
filename=data_path_file.as_posix(), example_indices=frame_list(args.frames), **video_kwargs | |
)) | |
print(f"Video: {data_path_file}") | |
tmp_data_path_list.append(data_path_file) | |
# TODO: Clean this up. | |
except (FileNotFoundError, PermissionError): | |
print(f"Error reading file: {data_path_file}. Please check the file's existence and permissions.") | |
except Exception: | |
print(f"Error reading file: {data_path_file}") | |
data_path_list = tmp_data_path_list |
Tools
Ruff
5350-5350: Local variable
e
is assigned to but never used (F841)Remove assignment to unused variable
e
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: 5
Outside diff range and nitpick comments (10)
tests/nn/test_inference.py (10)
Line range hint
10-10
: Remove unused import: tensorflow_hubThe import
tensorflow_hub
is not used anywhere in the code. To maintain clean and efficient code, it's best to remove unused imports.- import tensorflow_hub as hub
Line range hint
14-14
: Remove unused import:sleap.gui.learning.runners
This import is not utilized in the file and should be removed to keep the codebase clean and efficient.
- from sleap.gui.learning import runners
Line range hint
22-23
: Remove unused imports related to inferenceThe imports
InferenceLayer
andInferenceModel
fromsleap.nn.inference
are not used in this file. Removing unused imports can help reduce confusion and improve code cleanliness.- from sleap.nn.inference import InferenceLayer - from sleap.nn.inference import InferenceModel
Line range hint
56-56
: Remove unused import:sleap.nn.tracking.MatchedFrameInstance
This import is not utilized in the file and should be removed to keep the codebase clean and efficient.
- from sleap.nn.tracking import MatchedFrameInstance
Line range hint
61-61
: Remove unused import:sleap.instance.Track
This import is not utilized in the file and should be removed to keep the codebase clean and efficient.
- from sleap.instance import Track
Line range hint
616-616
: Refactor boolean checks for clarityBoolean comparisons to
True
orFalse
are not necessary and can be simplified for better readability and performance.- if predictor.is_grayscale == False: + if not predictor.is_grayscale: - if predictor.is_grayscale == True: + if predictor.is_grayscale:Also applies to: 664-664, 713-713, 746-746, 1821-1821
Line range hint
901-901
: Remove unused variable:predictor
The variable
predictor
is assigned but never used, which can lead to unnecessary memory usage and potential confusion.- predictor = load_model(model_path)
Line range hint
1260-1260
: Avoid general exception types in testsUsing
pytest.raises(Exception)
is too broad and can potentially catch unintended exceptions. It's recommended to specify the exact exception type expected.- with pytest.raises(Exception): + with pytest.raises(SpecificExceptionType):
Line range hint
1390-1390
: Remove unused variable:labels
The variable
labels
is assigned but never used, which can lead to unnecessary memory usage and potential confusion.- labels = Labels(min_tracks_2node_labels[[0]])
Line range hint
1742-1742
: Simplify dictionary key checksUsing
key in dict.keys()
is redundant and can be simplified tokey in dict
for clarity and efficiency.- for key in tracker.track_matching_queue_dict.keys(): + for key in tracker.track_matching_queue_dict:Also applies to: 1786-1786, 1791-1791
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (2)
- sleap/nn/inference.py (5 hunks)
- tests/nn/test_inference.py (3 hunks)
Additional context used
Ruff
tests/nn/test_inference.py
10-10:
tensorflow_hub
imported but unused (F401)Remove unused import:
tensorflow_hub
14-14:
sleap.gui.learning.runners
imported but unused (F401)Remove unused import:
sleap.gui.learning.runners
22-22:
sleap.nn.inference.InferenceLayer
imported but unused (F401)Remove unused import
23-23:
sleap.nn.inference.InferenceModel
imported but unused (F401)Remove unused import
56-56:
sleap.nn.tracking.MatchedFrameInstance
imported but unused (F401)Remove unused import:
sleap.nn.tracking.MatchedFrameInstance
61-61:
sleap.instance.Track
imported but unused (F401)Remove unused import:
sleap.instance.Track
616-616: Avoid equality comparisons to
False
; useif not predictor.is_grayscale:
for false checks (E712)Replace with
not predictor.is_grayscale
664-664: Avoid equality comparisons to
True
; useif predictor.is_grayscale:
for truth checks (E712)Replace with
predictor.is_grayscale
713-713: Avoid equality comparisons to
True
; useif predictor.is_grayscale:
for truth checks (E712)Replace with
predictor.is_grayscale
746-746: Avoid equality comparisons to
True
; useif predictor.is_grayscale:
for truth checks (E712)Replace with
predictor.is_grayscale
805-805: Pointless comparison. Did you mean to assign a value? Otherwise, prepend
assert
or remove it. (B015)
806-806: Pointless comparison. Did you mean to assign a value? Otherwise, prepend
assert
or remove it. (B015)
901-901: Local variable
predictor
is assigned to but never used (F841)Remove assignment to unused variable
predictor
1260-1260:
pytest.raises(Exception)
should be considered evil (B017)
1390-1390: Local variable
labels
is assigned to but never used (F841)Remove assignment to unused variable
labels
1742-1742: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1786-1786: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1791-1791: Use
key in dict
instead ofkey in dict.keys()
(SIM118)Remove
.keys()
1821-1821: Avoid equality comparisons to
False
; useif not predictor.is_grayscale:
for false checks (E712)Replace with
not predictor.is_grayscale
sleap/nn/inference.py
131-131:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
149-149: Undefined name
Task
(F821)
584-584: Local variable
outputs
is assigned to but never used (F841)Remove assignment to unused variable
outputs
605-605:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
613-613:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
627-627:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
641-641:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
695-696: Use a single
if
statement instead of nestedif
statements (SIM102)Combine
if
statements usingand
1183-1183: No explicit
stacklevel
keyword argument found (B028)
1325-1328: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
1468-1468:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
1758-1763: Use ternary operator
imgs = inputs["image"] if isinstance(inputs, dict) else inputs
instead ofif
-else
-block (SIM108)
2394-2394:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
2395-2395:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
2822-2825: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
3110-3110:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
3424-3427: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
3436-3439: Use ternary operator
offsets = preds[self.offsets_ind] if self.offsets_ind is not None else None
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withoffsets = preds[self.offsets_ind] if self.offsets_ind is not None else None
3654-3654:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
3756-3756: Loop control variable
image
not used within loop body (B007)Rename unused
image
to_image
4262-4262:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4263-4263:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4452-4452: Loop control variable
image
not used within loop body (B007)Rename unused
image
to_image
4615-4619: Use ternary operator
img = ex["image"] if type(ex) == dict else ex
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimg = ex["image"] if type(ex) == dict else ex
4615-4615: Do not compare types, use
isinstance()
(E721)
4709-4709:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4873-4876: Use ternary operator
model_paths = [model_path] if isinstance(model_path, str) else model_path
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withmodel_paths = [model_path] if isinstance(model_path, str) else model_path
5294-5297: Use ternary operator
data_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withdata_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
5356-5356: Local variable
e
is assigned to but never used (F841)Remove assignment to unused variable
e
Additional comments not posted (3)
sleap/nn/inference.py (3)
5373-5373
: Consider removing debug statements.The
print(args)
statement appears to be for debugging purposes. If it's no longer needed, consider removing it to clean up the code.- print(args)
5454-5454
: Review necessity of verbose argument logging.Printing all arguments might expose sensitive information in logs and could clutter the output. Ensure that this is necessary, or consider logging at a debug level or to a file that is not generally accessible.
5503-5510
: Error handling for output path conflicts is robust.The check to ensure the
output_path
is a directory when multiple inputs are provided is crucial for preventing file overwriting and data loss. This is a good practice in handling user input for batch processing scenarios.
sleap/nn/inference.py
Outdated
# Compile file(s) into a list for later itteration | ||
if data_path.is_dir(): | ||
data_path_list = [] | ||
for file_path in data_path.iterdir(): | ||
if file_path.is_file(): | ||
data_path_list.append(file_path) | ||
elif data_path.is_file: | ||
data_path_list = [args.data_path] |
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.
Implementation of multiple video input handling appears robust.
The code effectively handles multiple video inputs by checking if the path is a directory and iterating over all files. This implementation aligns with the PR's objective to allow sleap-track
to process multiple videos. The use of lists to manage providers and paths is appropriate, and the error handling for unsupported paths is a good practice.
However, the use of data_path.is_file
without calling it (i.e., data_path.is_file()
) appears to be a typo that could lead to unexpected behavior.
- elif data_path.is_file:
+ elif data_path.is_file():
Also applies to: 5314-5361
sleap/nn/inference.py
Outdated
# Run inference on all files inputed | ||
for data_path, provider in zip(data_path_list, provider_list): | ||
# Setup models. | ||
predictor = _make_predictor_from_cli(args) | ||
print(f"predictor.tracker: {tracker}") | ||
predictor.tracker = tracker | ||
|
||
if output_path is None: | ||
output_path = data_path + ".predictions.slp" | ||
# Run inference! | ||
labels_pr = predictor.predict(provider) | ||
|
||
labels_pr.provenance["model_paths"] = predictor.model_paths | ||
labels_pr.provenance["predictor"] = type(predictor).__name__ | ||
if output_path is None: | ||
|
||
output_path = data_path.parent / (data_path.stem + ".predictions.slp") | ||
output_path_obj = Path(output_path) | ||
|
||
else: | ||
output_path = output_path + "/" + (data_path.stem + ".predictions.slp") | ||
|
||
labels_pr.provenance["model_paths"] = predictor.model_paths | ||
labels_pr.provenance["predictor"] = type(predictor).__name__ | ||
|
||
if args.no_empty_frames: | ||
# Clear empty frames if specified. | ||
labels_pr.remove_empty_frames() | ||
|
||
finish_timestamp = str(datetime.now()) | ||
total_elapsed = time() - t0 | ||
print("Finished inference at:", finish_timestamp) | ||
print(f"Total runtime: {total_elapsed} secs") | ||
print(f"Predicted frames: {len(labels_pr)}/{len(provider)}") | ||
|
||
# Add provenance metadata to predictions. | ||
labels_pr.provenance["sleap_version"] = sleap.__version__ | ||
labels_pr.provenance["platform"] = platform.platform() | ||
labels_pr.provenance["command"] = " ".join(sys.argv) | ||
labels_pr.provenance["data_path"] = data_path.as_posix() | ||
labels_pr.provenance["output_path"] = output_path_obj.as_posix() | ||
labels_pr.provenance["total_elapsed"] = total_elapsed | ||
labels_pr.provenance["start_timestamp"] = start_timestamp | ||
labels_pr.provenance["finish_timestamp"] = finish_timestamp | ||
|
||
print("Provenance:") | ||
print(labels_pr.provenance) | ||
print() | ||
|
||
labels_pr.provenance["args"] = vars(args) | ||
|
||
# Save results. | ||
labels_pr.save(output_path) | ||
print("Saved output:", output_path) | ||
|
||
if args.open_in_gui: | ||
subprocess.call(["sleap-label", output_path]) | ||
|
||
# Reset output_path for next iteration | ||
output_path = args.output | ||
|
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.
Ensure consistency in output path handling.
The loop handles inference for multiple files, but the handling of output_path
could lead to inconsistencies or errors if not managed correctly, especially when it's reset at the end of the loop. Consider encapsulating output path generation and handling in a separate function to reduce complexity and improve maintainability.
def generate_output_path(data_path, output_dir, suffix=".predictions.slp"):
return output_dir / (data_path.stem + suffix)
# Usage within the loop
output_path = generate_output_path(data_path, output_path_obj)
sleap/nn/inference.py
Outdated
except Exception as e: | ||
print(f"Error reading file: {data_path_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.
Remove unused variable and improve error handling.
The variable e
in the exception block is unused, which can be cleaned up. Additionally, consider logging the error or providing more detailed feedback to the user.
- except Exception as e:
- print(f"Error reading file: {data_path_file}")
+ except Exception:
+ print(f"Error reading file: {data_path_file}. Please check the file format and accessibility.")
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.
except Exception as e: | |
print(f"Error reading file: {data_path_file}") | |
except Exception: | |
print(f"Error reading file: {data_path_file}. Please check the file format and accessibility.") |
Tools
Ruff
5356-5356: Local variable
e
is assigned to but never used (F841)Remove assignment to unused variable
e
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: 4
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- sleap/nn/inference.py (5 hunks)
Additional context used
Ruff
sleap/nn/inference.py
131-131:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
149-149: Undefined name
Task
(F821)
584-584: Local variable
outputs
is assigned to but never used (F841)Remove assignment to unused variable
outputs
605-605:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
613-613:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
627-627:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
641-641:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
695-696: Use a single
if
statement instead of nestedif
statements (SIM102)Combine
if
statements usingand
1183-1183: No explicit
stacklevel
keyword argument found (B028)
1325-1328: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
1468-1468:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
1758-1763: Use ternary operator
imgs = inputs["image"] if isinstance(inputs, dict) else inputs
instead ofif
-else
-block (SIM108)
2394-2394:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
2395-2395:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
2822-2825: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
3110-3110:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
3424-3427: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
3436-3439: Use ternary operator
offsets = preds[self.offsets_ind] if self.offsets_ind is not None else None
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withoffsets = preds[self.offsets_ind] if self.offsets_ind is not None else None
3654-3654:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
3756-3756: Loop control variable
image
not used within loop body (B007)Rename unused
image
to_image
4262-4262:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4263-4263:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4452-4452: Loop control variable
image
not used within loop body (B007)Rename unused
image
to_image
4615-4619: Use ternary operator
img = ex["image"] if type(ex) == dict else ex
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withimg = ex["image"] if type(ex) == dict else ex
4615-4615: Do not compare types, use
isinstance()
(E721)
4709-4709:
typing.Text
is deprecated, usestr
(UP019)Replace with
str
4873-4876: Use ternary operator
model_paths = [model_path] if isinstance(model_path, str) else model_path
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withmodel_paths = [model_path] if isinstance(model_path, str) else model_path
5294-5297: Use ternary operator
data_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
instead ofif
-else
-block (SIM108)Replace
if
-else
-block withdata_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
Additional comments not posted (3)
sleap/nn/inference.py (3)
5504-5509
: Validate output path for multiple inputs.The validation for
output_path
when multiple video inputs are provided is crucial. Ensure that this logic is robust and tested to prevent runtime errors.
5575-5626
: Refactor tracking logic for clarity.The tracking logic, especially with the handling of existing prediction files, could benefit from refactoring for better clarity and maintainability. Consider separating the concerns into more discrete functions or methods.
[REFACTOR_Suggestion]def handle_existing_predictions(data_path, provider, tracker, args): print("Loading predictions...") labels_pr = sleap.load_file(args.data_path.as_posix()) frames = sorted(labels_pr.labeled_frames, key=lambda lf: lf.frame_idx) print("Starting tracker...") frames = run_tracker(frames=frames, tracker=tracker) tracker.final_pass(frames) return Labels(labeled_frames=frames)
5524-5568
: Review inference execution and result handling.The inference execution and handling of results appear to be implemented correctly. However, ensure that all edge cases are covered, especially with file paths and output handling.
Verification successful
Edge cases for file paths and output handling are covered.
The test case
test_sleap_track_output_mult
intests/nn/test_inference.py
verifies the correct construction of output file paths and ensures that predictions files are created as expected. It checks for the existence of the output files and handles different video formats.
tests/nn/test_inference.py
:
test_sleap_track_output_mult
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that all edge cases for file paths and output handling are covered in tests. # Test: Search for test cases covering file paths and output handling. rg --type python "test_sleap_track_output_mult"Length of output: 78
Script:
#!/bin/bash # Description: Verify that all edge cases for file paths and output handling are covered in tests. # Correcting the file type argument to 'py' instead of 'python'. rg --type py "test_sleap_track_output_mult"Length of output: 104
Script:
#!/bin/bash # Description: Extract and review the identified test case to ensure it covers edge cases for file paths and output handling. # Extract the content of the identified test case. rg --type py -A 20 "def test_sleap_track_output_mult" tests/nn/test_inference.pyLength of output: 821
Script:
#!/bin/bash # Description: Extract and review the identified test case to ensure it covers edge cases for file paths and output handling. # Extract more lines of the identified test case for comprehensive review. rg --type py -A 50 "def test_sleap_track_output_mult" tests/nn/test_inference.pyLength of output: 1749
sleap/nn/inference.py
Outdated
if data_path_file.as_posix().endswith(".slp"): | ||
print(f"Sleap file: {data_path_file}") | ||
labels = sleap.load_file(data_path_file.as_posix()) | ||
|
||
if args.only_labeled_frames: | ||
provider_list.append(LabelsReader.from_user_labeled_frames(labels)) | ||
elif args.only_suggested_frames: | ||
provider_list.append(LabelsReader.from_unlabeled_suggestions(labels)) | ||
elif getattr(args, "video.index") != "": | ||
provider_list.append( | ||
VideoReader( | ||
video=labels.videos[int(getattr(args, "video.index"))], | ||
example_indices=frame_list(args.frames), | ||
) | ||
) | ||
else: | ||
provider_list.append(LabelsReader(labels)) | ||
|
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.
Consider refactoring provider creation for clarity and modularity.
The code for creating providers based on file types is spread across multiple conditional branches. Consider refactoring this into a separate function or method to improve clarity and maintainability.
def create_provider(data_path_file, args):
if data_path_file.as_posix().endswith(".slp"):
labels = sleap.load_file(data_path_file.as_posix())
# Additional conditions based on args
else:
video_kwargs = dict(
dataset=vars(args).get("video.dataset"),
input_format=vars(args).get("video.input_format"),
)
return VideoReader.from_filepath(filename=data_path_file.as_posix(), example_indices=frame_list(args.frames), **video_kwargs)
return None # or appropriate return
Also applies to: 5347-5352
sleap/nn/inference.py
Outdated
except Exception: | ||
print(f"Error reading file: {data_path_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.
Improve error handling in file reading.
Currently, the error handling in the file reading process just prints an error message. It might be beneficial to either raise an exception or handle the error in a way that doesn't stop the execution, depending on the intended behavior of the application.
- except Exception:
- print(f"Error reading file: {data_path_file}")
+ except Exception as e:
+ logging.error(f"Failed to read file {data_path_file}: {e}")
+ continue # or other handling logic
Committable suggestion was skipped due to low confidence.
sleap/nn/inference.py
Outdated
if data_path.is_dir(): | ||
data_path_list = [] | ||
for file_path in data_path.iterdir(): | ||
if file_path.is_file(): | ||
data_path_list.append(file_path) | ||
elif data_path.is_file(): | ||
data_path_list = [args.data_path] |
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.
Ensure robust directory and file handling.
When handling directories and files, it's crucial to ensure that the code robustly checks for valid directories and handles potential errors gracefully. Consider adding more specific error handling for directory-related issues.
+ if not data_path.exists():
+ raise FileNotFoundError(f"The specified path does not exist: {data_path}")
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.
if data_path.is_dir(): | |
data_path_list = [] | |
for file_path in data_path.iterdir(): | |
if file_path.is_file(): | |
data_path_list.append(file_path) | |
elif data_path.is_file(): | |
data_path_list = [args.data_path] | |
if not data_path.exists(): | |
raise FileNotFoundError(f"The specified path does not exist: {data_path}") | |
if data_path.is_dir(): | |
data_path_list = [] | |
for file_path in data_path.iterdir(): | |
if file_path.is_file(): | |
data_path_list.append(file_path) | |
elif data_path.is_file(): | |
data_path_list = [args.data_path] |
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: 6
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- sleap/nn/inference.py (5 hunks)
Additional context used
Ruff
sleap/nn/inference.py
131-131:
typing.Text
is deprecated, usestr
Replace with
str
(UP019)
149-149: Undefined name
Task
(F821)
584-584: Local variable
outputs
is assigned to but never usedRemove assignment to unused variable
outputs
(F841)
605-605:
typing.Text
is deprecated, usestr
Replace with
str
(UP019)
613-613:
typing.Text
is deprecated, usestr
Replace with
str
(UP019)
627-627:
typing.Text
is deprecated, usestr
Replace with
str
(UP019)
641-641:
typing.Text
is deprecated, usestr
Replace with
str
(UP019)
695-696: Use a single
if
statement instead of nestedif
statementsCombine
if
statements usingand
(SIM102)
1183-1183: No explicit
stacklevel
keyword argument found(B028)
1325-1328: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-blockReplace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
(SIM108)
1468-1468:
typing.Text
is deprecated, usestr
Replace with
str
(UP019)
1758-1763: Use ternary operator
imgs = inputs["image"] if isinstance(inputs, dict) else inputs
instead ofif
-else
-block(SIM108)
2394-2394:
typing.Text
is deprecated, usestr
Replace with
str
(UP019)
2395-2395:
typing.Text
is deprecated, usestr
Replace with
str
(UP019)
2822-2825: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-blockReplace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
(SIM108)
3110-3110:
typing.Text
is deprecated, usestr
Replace with
str
(UP019)
3424-3427: Use ternary operator
imgs = data["image"] if isinstance(data, dict) else data
instead ofif
-else
-blockReplace
if
-else
-block withimgs = data["image"] if isinstance(data, dict) else data
(SIM108)
3436-3439: Use ternary operator
offsets = preds[self.offsets_ind] if self.offsets_ind is not None else None
instead ofif
-else
-blockReplace
if
-else
-block withoffsets = preds[self.offsets_ind] if self.offsets_ind is not None else None
(SIM108)
3654-3654:
typing.Text
is deprecated, usestr
Replace with
str
(UP019)
3756-3756: Loop control variable
image
not used within loop bodyRename unused
image
to_image
(B007)
4262-4262:
typing.Text
is deprecated, usestr
Replace with
str
(UP019)
4263-4263:
typing.Text
is deprecated, usestr
Replace with
str
(UP019)
4452-4452: Loop control variable
image
not used within loop bodyRename unused
image
to_image
(B007)
4615-4619: Use ternary operator
img = ex["image"] if type(ex) == dict else ex
instead ofif
-else
-blockReplace
if
-else
-block withimg = ex["image"] if type(ex) == dict else ex
(SIM108)
4615-4615: Do not compare types, use
isinstance()
(E721)
4709-4709:
typing.Text
is deprecated, usestr
Replace with
str
(UP019)
4873-4876: Use ternary operator
model_paths = [model_path] if isinstance(model_path, str) else model_path
instead ofif
-else
-blockReplace
if
-else
-block withmodel_paths = [model_path] if isinstance(model_path, str) else model_path
(SIM108)
5294-5297: Use ternary operator
data_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
instead ofif
-else
-blockReplace
if
-else
-block withdata_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
(SIM108)
sleap/nn/inference.py
Outdated
if data_path.is_dir(): | ||
data_path_list = [] | ||
for file_path in data_path.iterdir(): | ||
if file_path.is_file(): | ||
data_path_list.append(Path(file_path)) | ||
elif data_path.is_file(): | ||
data_path_list = [data_path] | ||
else: | ||
data_path = args.data_path | ||
|
||
if data_path is None or data_path == "": | ||
raise ValueError( | ||
"You must specify a path to a video or a labels dataset. " | ||
"Run 'sleap-track -h' to see full command documentation." | ||
) | ||
|
||
if data_path.endswith(".slp"): | ||
labels = sleap.load_file(data_path) | ||
|
||
if args.only_labeled_frames: | ||
provider = LabelsReader.from_user_labeled_frames(labels) | ||
elif args.only_suggested_frames: | ||
provider = LabelsReader.from_unlabeled_suggestions(labels) | ||
elif getattr(args, "video.index") != "": | ||
provider = VideoReader( | ||
video=labels.videos[int(getattr(args, "video.index"))], | ||
example_indices=frame_list(args.frames), | ||
) | ||
# Provider list to accomodate multiple video inputs | ||
provider_list = [] | ||
tmp_data_path_list = [] | ||
for data_path_file in data_path_list: | ||
# Create a provider for each file | ||
if data_path_file.as_posix().endswith(".slp"): | ||
print(f"Sleap file: {data_path_file}") | ||
labels = sleap.load_file(data_path_file.as_posix()) | ||
|
||
if args.only_labeled_frames: | ||
provider_list.append(LabelsReader.from_user_labeled_frames(labels)) | ||
elif args.only_suggested_frames: | ||
provider_list.append(LabelsReader.from_unlabeled_suggestions(labels)) | ||
elif getattr(args, "video.index") != "": | ||
provider_list.append( | ||
VideoReader( | ||
video=labels.videos[int(getattr(args, "video.index"))], | ||
example_indices=frame_list(args.frames), | ||
) | ||
) | ||
else: | ||
provider_list.append(LabelsReader(labels)) | ||
|
||
tmp_data_path_list.append(data_path_file) | ||
|
||
else: | ||
provider = LabelsReader(labels) | ||
try: | ||
video_kwargs = dict( | ||
dataset=vars(args).get("video.dataset"), | ||
input_format=vars(args).get("video.input_format"), | ||
) | ||
provider_list.append( | ||
VideoReader.from_filepath( | ||
filename=data_path_file.as_posix(), | ||
example_indices=frame_list(args.frames), | ||
**video_kwargs, | ||
) | ||
) | ||
print(f"Video: {data_path_file}") | ||
tmp_data_path_list.append(data_path_file) | ||
# TODO: Clean this up. | ||
except Exception: | ||
print(f"Error reading file: {data_path_file}") | ||
|
||
else: | ||
print(f"Video: {data_path}") | ||
# TODO: Clean this up. | ||
video_kwargs = dict( | ||
dataset=vars(args).get("video.dataset"), | ||
input_format=vars(args).get("video.input_format"), | ||
) | ||
provider = VideoReader.from_filepath( | ||
filename=data_path, example_indices=frame_list(args.frames), **video_kwargs | ||
) | ||
data_path_list = tmp_data_path_list | ||
|
||
return provider, data_path | ||
return provider_list, data_path_list |
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.
Logic to handle multiple video inputs looks good.
The logic to compile files into a list for iteration and the creation of providers based on file types are well implemented. However, consider refactoring the provider creation into a separate function for better modularity and clarity.
def create_provider(data_path_file, args):
if data_path_file.as_posix().endswith(".slp"):
labels = sleap.load_file(data_path_file.as_posix())
# Additional conditions based on args
else:
video_kwargs = dict(
dataset=vars(args).get("video.dataset"),
input_format=vars(args).get("video.input_format"),
)
return VideoReader.from_filepath(filename=data_path_file.as_posix(), example_indices=frame_list(args.frames), **video_kwargs)
return None # or appropriate return
# Reset output_path for next iteration | ||
output_path = args.output | ||
|
||
# running tracking on existing prediction 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.
Improve error handling for missing tracker specification.
The error message is clear, but consider providing more guidance or a direct link to documentation on how to specify a tracker.
raise ValueError(
"To retrack on predictions, must specify tracker. "
"Use 'sleap-track --tracking.tracker ...' to specify tracker to use. "
"See [documentation link] for more details."
)
sleap/nn/inference.py
Outdated
labels_pr.provenance["predictor"] = type(predictor).__name__ | ||
|
||
if args.no_empty_frames: | ||
# Clear empty frames if specified. | ||
labels_pr.remove_empty_frames() | ||
|
||
finish_timestamp = str(datetime.now()) | ||
total_elapsed = time() - t0 | ||
print("Finished inference at:", finish_timestamp) | ||
print(f"Total runtime: {total_elapsed} secs") | ||
print(f"Predicted frames: {len(labels_pr)}/{len(provider)}") | ||
|
||
# Add provenance metadata to predictions. | ||
labels_pr.provenance["sleap_version"] = sleap.__version__ | ||
labels_pr.provenance["platform"] = platform.platform() | ||
labels_pr.provenance["command"] = " ".join(sys.argv) | ||
labels_pr.provenance["data_path"] = data_path.as_posix() | ||
labels_pr.provenance["output_path"] = output_path_obj.as_posix() | ||
labels_pr.provenance["total_elapsed"] = total_elapsed | ||
labels_pr.provenance["start_timestamp"] = start_timestamp | ||
labels_pr.provenance["finish_timestamp"] = finish_timestamp | ||
|
||
print("Provenance:") | ||
print(labels_pr.provenance) | ||
print() | ||
|
||
labels_pr.provenance["args"] = vars(args) | ||
|
||
# Save results. | ||
labels_pr.save(output_path) | ||
print("Saved output:", output_path) | ||
|
||
if args.open_in_gui: | ||
subprocess.call(["sleap-label", output_path]) | ||
|
||
# Reset output_path for next iteration | ||
output_path = args.output | ||
|
||
# running tracking on existing prediction file | ||
elif getattr(args, "tracking.tracker") is not None: | ||
# Load predictions | ||
print("Loading predictions...") | ||
labels_pr = sleap.load_file(args.data_path) | ||
frames = sorted(labels_pr.labeled_frames, key=lambda lf: lf.frame_idx) | ||
for data_path, provider in zip(data_path_list, provider_list): | ||
# Load predictions | ||
print("Loading predictions...") | ||
labels_pr = sleap.load_file(data_path.as_posix()) | ||
frames = sorted(labels_pr.labeled_frames, key=lambda lf: lf.frame_idx) | ||
|
||
print("Starting tracker...") | ||
frames = run_tracker(frames=frames, tracker=tracker) | ||
tracker.final_pass(frames) | ||
|
||
print("Starting tracker...") | ||
frames = run_tracker(frames=frames, tracker=tracker) | ||
tracker.final_pass(frames) | ||
labels_pr = Labels(labeled_frames=frames) | ||
|
||
labels_pr = Labels(labeled_frames=frames) | ||
if output_path is None: | ||
output_path = f"{data_path}.{tracker.get_name()}.slp" | ||
|
||
if output_path is None: | ||
output_path = f"{data_path}.{tracker.get_name()}.slp" | ||
if args.no_empty_frames: | ||
# Clear empty frames if specified. | ||
labels_pr.remove_empty_frames() | ||
|
||
finish_timestamp = str(datetime.now()) | ||
total_elapsed = time() - t0 | ||
print("Finished inference at:", finish_timestamp) | ||
print(f"Total runtime: {total_elapsed} secs") | ||
print(f"Predicted frames: {len(labels_pr)}/{len(provider)}") | ||
|
||
# Add provenance metadata to predictions. | ||
labels_pr.provenance["sleap_version"] = sleap.__version__ | ||
labels_pr.provenance["platform"] = platform.platform() | ||
labels_pr.provenance["command"] = " ".join(sys.argv) | ||
labels_pr.provenance["data_path"] = data_path | ||
labels_pr.provenance["output_path"] = output_path | ||
labels_pr.provenance["total_elapsed"] = total_elapsed | ||
labels_pr.provenance["start_timestamp"] = start_timestamp | ||
labels_pr.provenance["finish_timestamp"] = finish_timestamp | ||
|
||
print("Provenance:") | ||
pprint(labels_pr.provenance) | ||
print() | ||
|
||
labels_pr.provenance["args"] = vars(args) | ||
|
||
# Save results. | ||
labels_pr.save(output_path) | ||
print("Saved output:", output_path) | ||
|
||
if args.open_in_gui: | ||
subprocess.call(["sleap-label", output_path]) | ||
|
||
# Reset output_path for next iteration | ||
output_path = args.output |
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.
Review output path handling logic.
The handling of the output path, especially when multiple inputs are given, needs careful attention. Consider refining the logic to ensure that the output path is correctly set in all scenarios.
if output_path is not None and Path.is_file(output_path_obj) and len(data_path_list) > 1:
raise ValueError(
"output_path argument must be a directory if multiple video inputs are given"
)
# Ensure that the output path is reset correctly after each iteration
+ original_output_path = args.output
for data_path, provider in zip(data_path_list, provider_list):
...
- output_path = args.output
+ output_path = original_output_path
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.
provider_list, data_path_list = _make_provider_from_cli(args) | |
# Setup tracker. | |
tracker = _make_tracker_from_cli(args) | |
output_path = args.output | |
if output_path is not None: | |
output_path_obj = Path(output_path) | |
# Output path given is a file, but multiple inputs were given | |
if output_path is not None and ( | |
#TODO check if directory exists | |
#always specify output directory | |
Path.is_file(output_path_obj) and len(data_path_list) > 1 | |
): | |
raise ValueError( | |
"output_path argument must be a directory if multiple video inputs are given" | |
) | |
if args.models is not None and "movenet" in args.models[0]: | |
args.models = args.models[0] | |
# Either run inference (and tracking) or just run tracking | |
# Either run inference (and tracking) or just run tracking (if using an existing prediction where inference has already been run) | |
if args.models is not None: | |
# Setup models. | |
predictor = _make_predictor_from_cli(args) | |
predictor.tracker = tracker | |
# Run inference! | |
labels_pr = predictor.predict(provider) | |
# Run inference on all files inputed | |
for data_path, provider in zip(data_path_list, provider_list): | |
# Setup models. | |
predictor = _make_predictor_from_cli(args) | |
print(f"predictor.tracker: {tracker}") | |
predictor.tracker = tracker | |
# Run inference! | |
labels_pr = predictor.predict(provider) | |
if output_path is None: | |
output_path = data_path + ".predictions.slp" | |
if output_path is None: | |
labels_pr.provenance["model_paths"] = predictor.model_paths | |
labels_pr.provenance["predictor"] = type(predictor).__name__ | |
output_path = data_path.parent / (data_path.stem + ".predictions.slp") | |
output_path_obj = Path(output_path) | |
else: | |
output_path = output_path + "/" + (data_path.stem + ".predictions.slp") | |
output_path_obj = Path(output_path) | |
labels_pr.provenance["model_paths"] = predictor.model_paths | |
labels_pr.provenance["predictor"] = type(predictor).__name__ | |
if args.no_empty_frames: | |
# Clear empty frames if specified. | |
labels_pr.remove_empty_frames() | |
finish_timestamp = str(datetime.now()) | |
total_elapsed = time() - t0 | |
print("Finished inference at:", finish_timestamp) | |
print(f"Total runtime: {total_elapsed} secs") | |
print(f"Predicted frames: {len(labels_pr)}/{len(provider)}") | |
# Add provenance metadata to predictions. | |
labels_pr.provenance["sleap_version"] = sleap.__version__ | |
labels_pr.provenance["platform"] = platform.platform() | |
labels_pr.provenance["command"] = " ".join(sys.argv) | |
labels_pr.provenance["data_path"] = data_path.as_posix() | |
labels_pr.provenance["output_path"] = output_path_obj.as_posix() | |
labels_pr.provenance["total_elapsed"] = total_elapsed | |
labels_pr.provenance["start_timestamp"] = start_timestamp | |
labels_pr.provenance["finish_timestamp"] = finish_timestamp | |
print("Provenance:") | |
print(labels_pr.provenance) | |
print() | |
labels_pr.provenance["args"] = vars(args) | |
# Save results. | |
labels_pr.save(output_path) | |
print("Saved output:", output_path) | |
if args.open_in_gui: | |
subprocess.call(["sleap-label", output_path]) | |
# Reset output_path for next iteration | |
output_path = args.output | |
# running tracking on existing prediction file | |
elif getattr(args, "tracking.tracker") is not None: | |
# Load predictions | |
print("Loading predictions...") | |
labels_pr = sleap.load_file(args.data_path) | |
frames = sorted(labels_pr.labeled_frames, key=lambda lf: lf.frame_idx) | |
for data_path, provider in zip(data_path_list, provider_list): | |
# Load predictions | |
print("Loading predictions...") | |
labels_pr = sleap.load_file(data_path.as_posix()) | |
frames = sorted(labels_pr.labeled_frames, key=lambda lf: lf.frame_idx) | |
print("Starting tracker...") | |
frames = run_tracker(frames=frames, tracker=tracker) | |
tracker.final_pass(frames) | |
print("Starting tracker...") | |
frames = run_tracker(frames=frames, tracker=tracker) | |
tracker.final_pass(frames) | |
labels_pr = Labels(labeled_frames=frames) | |
labels_pr = Labels(labeled_frames=frames) | |
if output_path is None: | |
output_path = f"{data_path}.{tracker.get_name()}.slp" | |
if output_path is None: | |
output_path = f"{data_path}.{tracker.get_name()}.slp" | |
if args.no_empty_frames: | |
# Clear empty frames if specified. | |
labels_pr.remove_empty_frames() | |
finish_timestamp = str(datetime.now()) | |
total_elapsed = time() - t0 | |
print("Finished inference at:", finish_timestamp) | |
print(f"Total runtime: {total_elapsed} secs") | |
print(f"Predicted frames: {len(labels_pr)}/{len(provider)}") | |
# Add provenance metadata to predictions. | |
labels_pr.provenance["sleap_version"] = sleap.__version__ | |
labels_pr.provenance["platform"] = platform.platform() | |
labels_pr.provenance["command"] = " ".join(sys.argv) | |
labels_pr.provenance["data_path"] = data_path | |
labels_pr.provenance["output_path"] = output_path | |
labels_pr.provenance["total_elapsed"] = total_elapsed | |
labels_pr.provenance["start_timestamp"] = start_timestamp | |
labels_pr.provenance["finish_timestamp"] = finish_timestamp | |
print("Provenance:") | |
pprint(labels_pr.provenance) | |
print() | |
labels_pr.provenance["args"] = vars(args) | |
# Save results. | |
labels_pr.save(output_path) | |
print("Saved output:", output_path) | |
if args.open_in_gui: | |
subprocess.call(["sleap-label", output_path]) | |
# Reset output_path for next iteration | |
output_path = args.output | |
provider_list, data_path_list = _make_provider_from_cli(args) | |
# Setup tracker. | |
tracker = _make_tracker_from_cli(args) | |
output_path = args.output | |
if output_path is not None: | |
output_path_obj = Path(output_path) | |
# Output path given is a file, but multiple inputs were given | |
if output_path is not None and ( | |
#TODO check if directory exists | |
#always specify output directory | |
Path.is_file(output_path_obj) and len(data_path_list) > 1 | |
): | |
raise ValueError( | |
"output_path argument must be a directory if multiple video inputs are given" | |
) | |
if args.models is not None and "movenet" in args.models[0]: | |
args.models = args.models[0] | |
# Either run inference (and tracking) or just run tracking (if using an existing prediction where inference has already been run) | |
if args.models is not None: | |
# Run inference on all files inputed | |
original_output_path = args.output | |
for data_path, provider in zip(data_path_list, provider_list): | |
# Setup models. | |
predictor = _make_predictor_from_cli(args) | |
print(f"predictor.tracker: {tracker}") | |
predictor.tracker = tracker | |
# Run inference! | |
labels_pr = predictor.predict(provider) | |
if output_path is None: | |
output_path = data_path.parent / (data_path.stem + ".predictions.slp") | |
output_path_obj = Path(output_path) | |
else: | |
output_path = output_path + "/" + (data_path.stem + ".predictions.slp") | |
output_path_obj = Path(output_path) | |
labels_pr.provenance["model_paths"] = predictor.model_paths | |
labels_pr.provenance["predictor"] = type(predictor).__name__ | |
if args.no_empty_frames: | |
# Clear empty frames if specified. | |
labels_pr.remove_empty_frames() | |
finish_timestamp = str(datetime.now()) | |
total_elapsed = time() - t0 | |
print("Finished inference at:", finish_timestamp) | |
print(f"Total runtime: {total_elapsed} secs") | |
print(f"Predicted frames: {len(labels_pr)}/{len(provider)}") | |
# Add provenance metadata to predictions. | |
labels_pr.provenance["sleap_version"] = sleap.__version__ | |
labels_pr.provenance["platform"] = platform.platform() | |
labels_pr.provenance["command"] = " ".join(sys.argv) | |
labels_pr.provenance["data_path"] = data_path.as_posix() | |
labels_pr.provenance["output_path"] = output_path_obj.as_posix() | |
labels_pr.provenance["total_elapsed"] = total_elapsed | |
labels_pr.provenance["start_timestamp"] = start_timestamp | |
labels_pr.provenance["finish_timestamp"] = finish_timestamp | |
print("Provenance:") | |
print(labels_pr.provenance) | |
print() | |
labels_pr.provenance["args"] = vars(args) | |
# Save results. | |
labels_pr.save(output_path) | |
print("Saved output:", output_path) | |
if args.open_in_gui: | |
subprocess.call(["sleap-label", output_path]) | |
# Reset output_path for next iteration | |
output_path = original_output_path | |
# running tracking on existing prediction file | |
elif getattr(args, "tracking.tracker") is not None: | |
for data_path, provider in zip(data_path_list, provider_list): | |
# Load predictions | |
print("Loading predictions...") | |
labels_pr = sleap.load_file(data_path.as_posix()) | |
frames = sorted(labels_pr.labeled_frames, key=lambda lf: lf.frame_idx) | |
print("Starting tracker...") | |
frames = run_tracker(frames=frames, tracker=tracker) | |
tracker.final_pass(frames) | |
labels_pr = Labels(labeled_frames=frames) | |
if output_path is None: | |
output_path = f"{data_path}.{tracker.get_name()}.slp" | |
if args.no_empty_frames: | |
# Clear empty frames if specified. | |
labels_pr.remove_empty_frames() | |
finish_timestamp = str(datetime.now()) | |
total_elapsed = time() - t0 | |
print("Finished inference at:", finish_timestamp) | |
print(f"Total runtime: {total_elapsed} secs") | |
print(f"Predicted frames: {len(labels_pr)}/{len(provider)}") | |
# Add provenance metadata to predictions. | |
labels_pr.provenance["sleap_version"] = sleap.__version__ | |
labels_pr.provenance["platform"] = platform.platform() | |
labels_pr.provenance["command"] = " ".join(sys.argv) | |
labels_pr.provenance["data_path"] = data_path | |
labels_pr.provenance["output_path"] = output_path | |
labels_pr.provenance["total_elapsed"] = total_elapsed | |
labels_pr.provenance["start_timestamp"] = start_timestamp | |
labels_pr.provenance["finish_timestamp"] = finish_timestamp | |
print("Provenance:") | |
pprint(labels_pr.provenance) | |
print() | |
labels_pr.provenance["args"] = vars(args) | |
# Save results. | |
labels_pr.save(output_path) | |
print("Saved output:", output_path) | |
if args.open_in_gui: | |
subprocess.call(["sleap-label", output_path]) | |
# Reset output_path for next iteration | |
output_path = args.output |
734d441
to
5ffdc96
Compare
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: 4
Outside diff range and nitpick comments (4)
sleap/nn/inference.py (4)
5291-5298
: Optimize conditional assignment using a ternary operator.The current
if-else
block for settingdata_path
can be simplified using a ternary operator, which makes the code cleaner and more concise.- if labels_path is not None: - data_path = Path(labels_path) - else: - data_path = Path(args.data_path) + data_path = Path(labels_path) if labels_path is not None else Path(args.data_path)Tools
Ruff
5294-5297: Use ternary operator
data_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
instead ofif
-else
-blockReplace
if
-else
-block withdata_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
(SIM108)
5307-5307
: Ensure consistent path format.Use
as_posix()
consistently to ensure the path format is consistent across different operating systems.- data_path_list = [data_path.as_posix()] + data_path_list = [data_path.as_posix() for data_path in data_path_list]
5373-5373
: Use logging instead of print statements.Using logging instead of print statements provides better control over the output and can be easily disabled or redirected.
- print(args) + logging.debug(args)
5527-5528
: Clarify error message.The error message can be clarified to provide more information to the user.
- "output_path argument must be a directory if multiple video inputs are given" + "The output_path argument must be a directory when multiple video inputs are given. Please specify a valid directory."
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files ignored due to path filters (5)
tests/data/videos/multiple_inputs_mp4/centered_pair_small.mp4
is excluded by!**/*.mp4
tests/data/videos/multiple_inputs_mp4/centered_pair_small_2.mp4
is excluded by!**/*.mp4
tests/data/videos/multiple_inputs_mp4/centered_pair_small_3.mp4
is excluded by!**/*.mp4
tests/data/videos/multiple_inputs_slp_mp4/centered_pair_small_2.mp4
is excluded by!**/*.mp4
tests/data/videos/multiple_inputs_slp_mp4/centered_pair_small_3.mp4
is excluded by!**/*.mp4
Files selected for processing (1)
- sleap/nn/inference.py (5 hunks)
Additional context used
Ruff
sleap/nn/inference.py
5294-5297: Use ternary operator
data_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
instead ofif
-else
-blockReplace
if
-else
-block withdata_path = Path(labels_path) if labels_path is not None else Path(args.data_path)
(SIM108)
Additional comments not posted (1)
sleap/nn/inference.py (1)
5608-5612
: Ensure directory creation for output path.Ensure that the directory for the output path is created if it does not exist.
output_path_obj.mkdir(parents=True, exist_ok=True)
sleap/nn/inference.py
Outdated
output_path = output_path + "/" + (data_path_obj.stem + ".predictions.slp") | ||
output_path_obj = Path(output_path) | ||
|
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.
Ensure directory creation for output path.
Ensure that the directory for the output path is created if it does not exist.
output_path_obj.mkdir(parents=True, exist_ok=True)
Review notes from subgroup:
|
6192d8a
to
3b9cd45
Compare
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: 4
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (2)
- sleap/nn/inference.py (5 hunks)
- tests/nn/test_inference.py (3 hunks)
Files skipped from review as they are similar to previous changes (1)
- sleap/nn/inference.py
Additional comments not posted (7)
tests/nn/test_inference.py (7)
Line range hint
1511-1538
:
LGTM!The function is well-structured and tests the
sleap-track
command with a single input.
1717-1736
: LGTM!The function is well-structured and tests the
sleap-track
command with an invalid output file.
1739-1755
: LGTM!The function is well-structured and tests the
sleap-track
command with an invalid input.
1487-1487
: UsePath(test_sleap_track_mult_inputs_folder_slp).as_posix()
instead ofstr(...)
.This ensures consistency in handling file paths.
- slp_path = Path(test_sleap_track_mult_inputs_folder_slp).as_posix() + slp_path = str(Path(test_sleap_track_mult_inputs_folder_slp))Likely invalid or redundant comment.
1692-1710
: Add comments explaining the removal of files.The function
test_sleap_track_output_mult
is well-structured but lacks comments explaining why files are removed.- files_to_remove = set(new_output_path_list) - set(output_path_list) + # This ensures the output folder is reverted to its original state after the test. + files_to_remove = set(new_output_path_list) - set(output_path_list)Likely invalid or redundant comment.
1575-1578
: Add comments explaining the removal of files.The function
test_sleap_track_mult_input_slp
is well-structured but lacks comments explaining why files are removed.- files_to_remove = set(new_slp_path_list) - set(slp_path_list) + # This ensures the input folder is reverted to its original state after the test. + files_to_remove = set(new_slp_path_list) - set(slp_path_list)Likely invalid or redundant comment.
1487-1487
: UsePath(test_sleap_track_mult_inputs_folder_slp).as_posix()
instead ofstr(...)
.This ensures consistency in handling file paths.
- slp_path = Path(test_sleap_track_mult_inputs_folder_slp).as_posix() + slp_path = str(Path(test_sleap_track_mult_inputs_folder_slp))Likely invalid or redundant comment.
tests/nn/test_inference.py
Outdated
files_to_remove = set(new_output_path_list) - set(output_path_list) | ||
for file in files_to_remove: | ||
file.unlink() |
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.
Add comments explaining the removal of files.
The function test_sleap_track_output_mult
is well-structured but lacks comments explaining why files are removed.
- files_to_remove = set(new_output_path_list) - set(output_path_list)
+ # This ensures the output folder is reverted to its original state after the test.
+ files_to_remove = set(new_output_path_list) - set(output_path_list)
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.
files_to_remove = set(new_output_path_list) - set(output_path_list) | |
for file in files_to_remove: | |
file.unlink() | |
# This ensures the output folder is reverted to its original state after the test. | |
files_to_remove = set(new_output_path_list) - set(output_path_list) | |
for file in files_to_remove: | |
file.unlink() |
tests/nn/test_inference.py
Outdated
# remove the files that have been added within the test case to revert input folders to their original state | ||
files_to_remove = set(new_slp_path_list) - set(slp_path_list) | ||
for file in files_to_remove: | ||
file.unlink() |
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.
Add comments explaining the removal of files.
The function test_sleap_track_mult_input_slp_mp4
is well-structured but lacks comments explaining why files are removed.
- files_to_remove = set(new_slp_path_list) - set(slp_path_list)
+ # This ensures the input folder is reverted to its original state after the test.
+ files_to_remove = set(new_slp_path_list) - set(slp_path_list)
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.
# remove the files that have been added within the test case to revert input folders to their original state | |
files_to_remove = set(new_slp_path_list) - set(slp_path_list) | |
for file in files_to_remove: | |
file.unlink() | |
# remove the files that have been added within the test case to revert input folders to their original state | |
# This ensures the input folder is reverted to its original state after the test. | |
files_to_remove = set(new_slp_path_list) - set(slp_path_list) | |
for file in files_to_remove: | |
file.unlink() |
tests/nn/test_inference.py
Outdated
# remove the files that have been added within the test case to revert input folders to their original state | ||
files_to_remove = set(new_slp_path_list) - set(slp_path_list) | ||
for file in files_to_remove: | ||
file.unlink() |
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.
Add comments explaining the removal of files.
The function test_sleap_track_mult_input_slp
is well-structured but lacks comments explaining why files are removed.
- files_to_remove = set(new_slp_path_list) - set(slp_path_list)
+ # This ensures the input folder is reverted to its original state after the test.
+ files_to_remove = set(new_slp_path_list) - set(slp_path_list)
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.
# remove the files that have been added within the test case to revert input folders to their original state | |
files_to_remove = set(new_slp_path_list) - set(slp_path_list) | |
for file in files_to_remove: | |
file.unlink() | |
# remove the files that have been added within the test case to revert input folders to their original state | |
# This ensures the input folder is reverted to its original state after the test. | |
files_to_remove = set(new_slp_path_list) - set(slp_path_list) | |
for file in files_to_remove: | |
file.unlink() |
tests/nn/test_inference.py
Outdated
files_to_remove = set(new_slp_path_list) - set(slp_path_list) | ||
for file in files_to_remove: | ||
file.unlink() |
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.
Add comments explaining the removal of files.
The function test_sleap_track_mult_input_mp4
is well-structured but lacks comments explaining why files are removed.
- files_to_remove = set(new_slp_path_list) - set(slp_path_list)
+ # This ensures the input folder is reverted to its original state after the test.
+ files_to_remove = set(new_slp_path_list) - set(slp_path_list)
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.
files_to_remove = set(new_slp_path_list) - set(slp_path_list) | |
for file in files_to_remove: | |
file.unlink() | |
# This ensures the input folder is reverted to its original state after the test. | |
files_to_remove = set(new_slp_path_list) - set(slp_path_list) | |
for file in files_to_remove: | |
file.unlink() |
fd558cd
to
be02a7d
Compare
2fd8ab9
to
6a481c3
Compare
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: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (2)
- sleap/nn/inference.py (5 hunks)
- tests/nn/test_inference.py (3 hunks)
Files skipped from review as they are similar to previous changes (1)
- sleap/nn/inference.py
Additional comments not posted (9)
tests/nn/test_inference.py (9)
1451-1480
: LGTM!The function
test_make_predictor_from_cli_mult_input
correctly tests the creation of a predictor from CLI arguments with multiple inputs.
Line range hint
1482-1509
: LGTM!The function
test_sleap_track_single_input
correctly tests thesleap-track
command with a single input, including both valid and invalid scenarios.
1511-1558
: LGTM!The function
test_sleap_track_mult_input_slp
correctly tests thesleap-track
command with multiple SLP files as input, ensuring predictions are generated for each file.
1561-1607
: LGTM!The function
test_sleap_track_mult_input_slp_mp4
correctly tests thesleap-track
command with a mix of SLP and MP4 files as input, ensuring predictions are generated for each file.
1610-1653
: LGTM!The function
test_sleap_track_mult_input_mp4
correctly tests thesleap-track
command with multiple MP4 files as input, ensuring predictions are generated for each file.
1655-1704
: LGTM!The function
test_sleap_track_output_mult
correctly tests thesleap-track
command with multiple outputs, ensuring predictions are saved to the specified output directory.
1706-1737
: LGTM!The function
test_sleap_track_invalid_output
correctly tests thesleap-track
command with an invalid output path, ensuring aValueError
is raised.
1740-1757
: LGTM!The function
test_sleap_track_invalid_input
correctly tests thesleap-track
command with an invalid input path, ensuring aValueError
is raised.
1560-1608
: LGTM!The function
test_sleap_track_mult_inputs_folder_mp4
correctly tests thesleap-track
command with multiple MP4 files as input, ensuring predictions are generated and saved for each file.
In addition to the changes above, another comment re: supporting inputs that are multiple SLP files:
@roomrys am I missing any other dangerzone cases? |
fc9dcb5
to
488edde
Compare
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
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (2)
- sleap/nn/inference.py (5 hunks)
- tests/nn/test_inference.py (3 hunks)
Files skipped from review as they are similar to previous changes (1)
- sleap/nn/inference.py
Additional context used
Ruff
tests/nn/test_inference.py
1726-1726: Undefined name
as_posix
(F821)
Additional comments not posted (10)
tests/nn/test_inference.py (10)
1451-1491
: Ensure proper handling of multiple input files.The function
test_make_predictor_from_cli_mult_input
correctly handles multiple input SLP files by copying them into a temporary directory and running inference on each copy. The assertions ensure that the predictor correctly handles the maximum number of instances.
1521-1569
: Ensure proper handling of multiple input SLP files.The function
test_sleap_track_mult_input_slp
correctly handles multiple input SLP files by copying them into a temporary directory and running thesleap-track
command on each copy. The assertions ensure that the predictions files are correctly generated for each input file.
1571-1618
: Ensure proper handling of multiple input SLP and MP4 files.The function
test_sleap_track_mult_input_slp_mp4
correctly handles multiple input SLP and MP4 files by copying them into a temporary directory and running thesleap-track
command on each copy. The assertions ensure that the predictions files are correctly generated for each input file.
1620-1664
: Ensure proper handling of multiple input MP4 files.The function
test_sleap_track_mult_input_mp4
correctly handles multiple input MP4 files by copying them into a temporary directory and running thesleap-track
command on each copy. The assertions ensure that the predictions files are correctly generated for each input file.
1666-1715
: Ensure proper handling of multiple input files with specified output directory.The function
test_sleap_track_output_mult
correctly handles multiple input MP4 files by copying them into a temporary directory and running thesleap-track
command on each copy with a specified output directory. The assertions ensure that the predictions files are correctly generated in the specified output directory.
1717-1750
: Ensure proper handling of invalid output path.The function
test_sleap_track_invalid_output
correctly handles an invalid output path by raising aValueError
exception. The test ensures that thesleap-track
command correctly handles invalid output paths.Tools
Ruff
1726-1726: Undefined name
as_posix
(F821)
1752-1769
: Ensure proper handling of invalid input path.The function
test_sleap_track_invalid_input
correctly handles an invalid input path by raising aValueError
exception. The test ensures that thesleap-track
command correctly handles invalid input paths.
1521-1569
: Ensure proper handling of multiple input SLP files with different tracking options.The function
test_sleap_track_mult_input_slp
correctly handles multiple input SLP files by copying them into a temporary directory and running thesleap-track
command on each copy with different tracking options. The assertions ensure that the predictions files are correctly generated for each input file and tracking option.
1571-1618
: Ensure proper handling of multiple input SLP and MP4 files with different tracking options.The function
test_sleap_track_mult_input_slp_mp4
correctly handles multiple input SLP and MP4 files by copying them into a temporary directory and running thesleap-track
command on each copy with different tracking options. The assertions ensure that the predictions files are correctly generated for each input file and tracking option.
1621-1664
: Ensure proper handling of multiple input MP4 files with different tracking options.The function
test_sleap_track_mult_input_mp4
correctly handles multiple input MP4 files by copying them into a temporary directory and running thesleap-track
command on each copy with different tracking options. The assertions ensure that the predictions files are correctly generated for each input file and tracking option.
tests/nn/test_inference.py
Outdated
): | ||
|
||
output_path = Path(tmpdir, "output_file.slp").as_posix() | ||
output_path = Path(tmpdir, "output_file.slp"),as_posix() |
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.
Fix the typo in defining the output_path
.
The output_path
is defined incorrectly due to a typo. The correct method should be used to define the path.
- output_path = Path(tmpdir, "output_file.slp"),as_posix()
+ output_path = Path(tmpdir, "output_file.slp").as_posix()
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.
output_path = Path(tmpdir, "output_file.slp"),as_posix() | |
output_path = Path(tmpdir, "output_file.slp").as_posix() |
Tools
Ruff
1726-1726: Undefined name
as_posix
(F821)
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: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- tests/nn/test_inference.py (3 hunks)
Files skipped from review as they are similar to previous changes (1)
- tests/nn/test_inference.py
On further assessment during subgroup: let's actually just not do multiple SLP file support. |
3915e56
to
d86123d
Compare
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: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (2)
- sleap/nn/inference.py (4 hunks)
- tests/nn/test_inference.py (3 hunks)
Files skipped from review as they are similar to previous changes (2)
- sleap/nn/inference.py
- tests/nn/test_inference.py
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: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- sleap/nn/inference.py (4 hunks)
Files skipped from review as they are similar to previous changes (1)
- sleap/nn/inference.py
) | ||
output_path_obj = Path(output_path) | ||
# Create the containing directory if needed. | ||
output_path_obj.parent.mkdir(exist_ok=True, parents=True) |
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.
is this what you wanted to do, or did you want to make the directory itself instead of the parent?
84674d0
to
fb587e5
Compare
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: 0
Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Files selected for processing (1)
- sleap/nn/inference.py (4 hunks)
Files skipped from review as they are similar to previous changes (1)
- sleap/nn/inference.py
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.
LGTM!
Description
Adding an option to add a directory to
sleap-track
to allow the command to iterate through the files in the directory and run inferences on all of them.Types of changes
Does this address any currently open issues?
#1777
Outside contributors checklist
Thank you for contributing to SLEAP!
❤️
Summary by CodeRabbit
New Features
Improvements
Bug Fixes
Tests