sleap icon indicating copy to clipboard operation
sleap copied to clipboard

Replacing missing videos does not prompt user to save changes

Open talmo opened this issue 3 years ago • 1 comments

Bug description

When user open a project with video paths pointed to a different location, a GUI appears to allow for interactively browsing to the new video file locations.

This does not cause the project to be in an "unsaved" state though, so training is allowed to run without saving again, resulting in errors since the SLP file on disk still has the old paths.

The workaround for now is to go to File -> Save As... and save a new copy.

Expected behaviour

Replacing video file paths at load time should trigger the unsaved state: labels.state["has_changes"] = True or context.changestack_push().

Actual behaviour

Replacing video file paths does not trigger the unsaved state.

Your personal set up

  • OS: All
  • Version(s): SLEAP v1.2.4
Environment packages N/A
Logs ``` Traceback (most recent call last): File "/Users/chapinlenthall-cleary/miniforge3/envs/sleap_m1/bin/sleap-train", line 33, in sys.exit(load_entry_point('sleap', 'console_scripts', 'sleap-train')()) File "/Users/chapinlenthall-cleary/sleap_m1/sleap/nn/training.py", line 1625, in main trainer.train() File "/Users/chapinlenthall-cleary/sleap_m1/sleap/nn/training.py", line 879, in train self.setup() File "/Users/chapinlenthall-cleary/sleap_m1/sleap/nn/training.py", line 865, in setup self._setup_model() File "/Users/chapinlenthall-cleary/sleap_m1/sleap/nn/training.py", line 698, in _setup_model base_example = next(iter(base_pipeline.make_dataset())) File "/Users/chapinlenthall-cleary/sleap_m1/sleap/nn/data/pipelines.py", line 277, in make_dataset ds = self.providers[0].make_dataset() File "/Users/chapinlenthall-cleary/sleap_m1/sleap/nn/data/providers.py", line 179, in make_dataset first_image = tf.convert_to_tensor(self.labels[0].image) File "/Users/chapinlenthall-cleary/sleap_m1/sleap/instance.py", line 1753, in image return self.video.get_frame(self.frame_idx) File "/Users/chapinlenthall-cleary/sleap_m1/sleap/io/video.py", line 1022, in get_frame return self.backend.get_frame(idx) File "/Users/chapinlenthall-cleary/sleap_m1/sleap/io/video.py", line 472, in get_frame if self.__reader.get(cv2.CAP_PROP_POS_FRAMES) != idx: File "/Users/chapinlenthall-cleary/sleap_m1/sleap/io/video.py", line 380, in __reader raise FileNotFoundError( FileNotFoundError: Could not find filename video filename named /home/data/birds/postures/birdview-2019/2019-06-09-13-16-11_BDY.wav.mp4 Run Path: /Users/chapinlenthall-cleary/Downloads/BirdTracking-2/Sleap-bird/models/cowbird-bottomup-test1220720_132724.centroid.n=30 ```

Screenshots

How to reproduce

  1. Import a file with non-existent paths.
  2. Replace paths in GUI.
  3. Try to train without re-saving.

talmo avatar Jul 20 '22 21:07 talmo

Problem Analysis

SLEAP uses a class method on the Labels object to return a callable for the missing video search. We should return something from this callable to let the MainWindow or CommandContext know that some video paths were updated. The difficulty is that the video_search callable is called by Adaptor.read (which should not return anything other than the Labels object), all methods that are passed video_search are classmethods (thus, we cannot just pass an attribute to the object), and the file could be of any SLEAP-supported format (we would need to add a line of code to each adaptor format).

Relevant Code

  1. Load project https://github.com/talmolab/sleap/blob/219a60fad332afb047c2d000e8bf15abcd2b7674/sleap/gui/app.py#L1425-L1459

  2. Create callable https://github.com/talmolab/sleap/blob/219a60fad332afb047c2d000e8bf15abcd2b7674/sleap/gui/app.py#L1439-L1441

  3. Attempt to load the file https://github.com/talmolab/sleap/blob/219a60fad332afb047c2d000e8bf15abcd2b7674/sleap/gui/app.py#L1451-L1452

  4. The Labels.load_file function https://github.com/talmolab/sleap/blob/219a60fad332afb047c2d000e8bf15abcd2b7674/sleap/io/dataset.py#L1931-L1944

roomrys avatar Aug 09 '22 22:08 roomrys

This feature is now available in the (pre) release 1.3.0a0, to install, first uninstall and then: conda (Windows/Linux/GPU):

conda create -y -n sleap -c sleap -c sleap/label/dev -c nvidia -c conda-forge sleap=1.3.0a0

pip (any OS except Apple Silicon):

pip install sleap==1.3.0a0

Warning: This is a pre-release! Expect bugs and strange behavior when testing.

roomrys avatar Feb 24 '23 23:02 roomrys