Error occurs during creation of subsequent training configurations and merging predictions in SLEAP GUI
Bug description
Hi,
I am attempting to create multiple training configuration files with different parameter settings in the SLEAP GUI to export them to a .zip file for remote training. The first training file exports as expected. Then, when I select "Predict>Run Training..." a second time, no window pops up and conda provides an error message:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\sleap\gui\app.py", line 817, in <lambda>
lambda: self._show_learning_dialog("training"),
File "C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\sleap\gui\app.py", line 1696, in _show_learning_dialog
self._child_windows[mode].skeleton = self.labels.skeleton
File "C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\sleap\io\dataset.py", line 565, in skeleton
"Labels.skeleton can only be used when there is only a single skeleton "
ValueError: Labels.skeleton can only be used when there is only a single skeleton saved in the labels. Use Labels.skeletons instead.
I am confused because there has not been any new skeleton saved. If I close out of the GUI entirely and restart, then I can export another single training configuration file and the second time the same issue arises again. I have experienced this since versions 1.26-1.2.9
The same error occurs when attempting to merge predictions:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\sleap\gui\commands.py", line 554, in mergeProject
self.execute(MergeProject, filenames=filenames)
File "C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\sleap\gui\commands.py", line 240, in execute
command().execute(context=self, params=kwargs)
File "C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\sleap\gui\commands.py", line 133, in execute
self.ask_and_do(context, params)
File "C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\sleap\gui\commands.py", line 2520, in ask_and_do
MergeDialog(base_labels=context.labels, new_labels=new_labels).exec_()
File "C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\sleap\gui\dialogs\merge.py", line 48, in __init__
if self.base_labels.skeleton.node_names != self.new_labels.skeleton.node_names:
File "C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\sleap\io\dataset.py", line 565, in skeleton
"Labels.skeleton can only be used when there is only a single skeleton "
ValueError: Labels.skeleton can only be used when there is only a single skeleton saved in the labels. Use Labels.skeletons instead.
Expected behaviour
Multiple training configurations should be able to be exportedActual behaviour
Your personal set up
- OS: Windows 10
- Version(s): SLEAP v1.2.6-1.2.9
- SLEAP installation method (listed here):
- [X] Conda from package
- [ ] Conda from source
- [ ] pip package
- [ ] M1 Macs
Environment packages
# packages in environment at C:\ProgramData\Anaconda2\envs\sleap129:
#
# Name Version Build Channel
absl-py 0.15.0 pypi_0 pypi
aom 3.5.0 h63175ca_0 conda-forge
astunparse 1.6.3 pypi_0 pypi
attrs 21.2.0 pypi_0 pypi
backports-zoneinfo 0.2.1 pypi_0 pypi
bzip2 1.0.8 h8ffe710_4 conda-forge
ca-certificates 2022.12.7 h5b45459_0 conda-forge
cached-property 1.5.2 hd8ed1ab_1 conda-forge
cached_property 1.5.2 pyha770c72_1 conda-forge
cachetools 4.2.4 pypi_0 pypi
cattrs 1.1.1 pypi_0 pypi
certifi 2021.10.8 pypi_0 pypi
charset-normalizer 2.0.12 pypi_0 pypi
clang 5.0 pypi_0 pypi
colorama 0.4.6 pypi_0 pypi
commonmark 0.9.1 pypi_0 pypi
cuda-nvcc 11.3.58 hb8d16a4_0 nvidia
cudatoolkit 11.3.1 hf2f0253_11 conda-forge
cudnn 8.2.1.32 h754d62a_0 conda-forge
cycler 0.11.0 pypi_0 pypi
efficientnet 1.0.0 pypi_0 pypi
expat 2.5.0 h1537add_0 conda-forge
ffmpeg 5.1.2 gpl_h5b1d025_105 conda-forge
flatbuffers 1.12 pypi_0 pypi
font-ttf-dejavu-sans-mono 2.37 hab24e00_0 conda-forge
font-ttf-inconsolata 3.000 h77eed37_0 conda-forge
font-ttf-source-code-pro 2.038 h77eed37_0 conda-forge
font-ttf-ubuntu 0.83 hab24e00_0 conda-forge
fontconfig 2.14.1 hbde0cde_0 conda-forge
fonts-conda-ecosystem 1 0 conda-forge
fonts-conda-forge 1 0 conda-forge
fonttools 4.38.0 pypi_0 pypi
freetype 2.12.1 h546665d_1 conda-forge
gast 0.4.0 pypi_0 pypi
geos 3.9.1 h39d44d4_2 conda-forge
google-auth 1.35.0 pypi_0 pypi
google-auth-oauthlib 0.4.6 pypi_0 pypi
google-pasta 0.2.0 pypi_0 pypi
grpcio 1.44.0 pypi_0 pypi
h5py 3.1.0 nompi_py37h19fda09_100 conda-forge
hdf5 1.10.6 nompi_he0bbb20_101 conda-forge
hdmf 3.4.7 pypi_0 pypi
idna 3.3 pypi_0 pypi
image-classifiers 1.0.0 pypi_0 pypi
imageio 2.15.0 pypi_0 pypi
imgaug 0.4.0 pypi_0 pypi
imgstore 0.2.9 pypi_0 pypi
importlib-metadata 4.11.1 pypi_0 pypi
importlib-resources 5.10.0 pypi_0 pypi
intel-openmp 2023.0.0 h57928b3_25922 conda-forge
joblib 1.2.0 pypi_0 pypi
jpeg 9e h8ffe710_2 conda-forge
jsmin 3.0.1 pypi_0 pypi
jsonpickle 1.2 pypi_0 pypi
jsonschema 4.17.0 pypi_0 pypi
keras 2.6.0 pypi_0 pypi
keras-applications 1.0.8 pypi_0 pypi
keras-preprocessing 1.1.2 pypi_0 pypi
kiwisolver 1.4.4 pypi_0 pypi
lcms2 2.12 h2a16943_0 conda-forge
lerc 3.0 h0e60522_0 conda-forge
libblas 3.9.0 16_win64_mkl conda-forge
libcblas 3.9.0 16_win64_mkl conda-forge
libdeflate 1.10 h8ffe710_0 conda-forge
libhwloc 2.8.0 h039e092_1 conda-forge
libiconv 1.17 h8ffe710_0 conda-forge
liblapack 3.9.0 16_win64_mkl conda-forge
libpng 1.6.39 h19919ed_0 conda-forge
libsqlite 3.40.0 hcfcfb64_0 conda-forge
libtiff 4.3.0 hc4061b1_4 conda-forge
libxml2 2.10.3 hc3477c8_0 conda-forge
libzlib 1.2.13 hcfcfb64_4 conda-forge
m2w64-gcc-libgfortran 5.3.0 6 conda-forge
m2w64-gcc-libs 5.3.0 7 conda-forge
m2w64-gcc-libs-core 5.3.0 7 conda-forge
m2w64-gmp 6.1.0 2 conda-forge
m2w64-libwinpthread-git 5.0.0.4634.697f757 2 conda-forge
markdown 3.3.6 pypi_0 pypi
matplotlib 3.5.3 pypi_0 pypi
mkl 2022.1.0 h6a75c08_874 conda-forge
msys2-conda-epoch 20160418 1 conda-forge
ndx-pose 0.1.1 pypi_0 pypi
networkx 2.6.3 pypi_0 pypi
numpy 1.19.5 py37h4c2b6ed_3 conda-forge
oauthlib 3.2.0 pypi_0 pypi
olefile 0.46 pyh9f0ad1d_1 conda-forge
opencv-python 4.5.5.62 pypi_0 pypi
opencv-python-headless 4.5.5.62 pypi_0 pypi
openh264 2.3.1 h63175ca_1 conda-forge
openjpeg 2.5.0 hb211442_0 conda-forge
openssl 3.0.7 hcfcfb64_1 conda-forge
opt-einsum 3.3.0 pypi_0 pypi
packaging 21.3 pypi_0 pypi
pandas 1.3.5 py37h9386db6_0 conda-forge
pillow 8.4.0 py37hd7d9ad0_0 conda-forge
pip 22.3.1 pyhd8ed1ab_0 conda-forge
pkgutil-resolve-name 1.3.10 pypi_0 pypi
protobuf 3.19.4 pypi_0 pypi
psutil 5.9.4 pypi_0 pypi
pthreads-win32 2.9.1 hfa6e2cd_3 conda-forge
pyasn1 0.4.8 pypi_0 pypi
pyasn1-modules 0.2.8 pypi_0 pypi
pygments 2.13.0 pypi_0 pypi
pykalman 0.9.5 pypi_0 pypi
pynwb 2.2.0 pypi_0 pypi
pyparsing 3.0.6 pypi_0 pypi
pyreadline 2.1 py37h03978a9_1006 conda-forge
pyrsistent 0.19.2 pypi_0 pypi
pyside2 5.14.1 pypi_0 pypi
python 3.7.12 h900ac77_100_cpython conda-forge
python-dateutil 2.8.2 pyhd8ed1ab_0 conda-forge
python-rapidjson 1.9 pypi_0 pypi
python_abi 3.7 3_cp37m conda-forge
pytz 2022.7 pyhd8ed1ab_0 conda-forge
pytz-deprecation-shim 0.1.0.post0 pypi_0 pypi
pywavelets 1.3.0 pypi_0 pypi
pyzmq 24.0.1 pypi_0 pypi
qimage2ndarray 1.9.0 pypi_0 pypi
qtpy 2.3.0 pyhd8ed1ab_0 conda-forge
requests 2.27.1 pypi_0 pypi
requests-oauthlib 1.3.1 pypi_0 pypi
rich 10.16.1 pypi_0 pypi
ruamel-yaml 0.17.21 pypi_0 pypi
ruamel-yaml-clib 0.2.7 pypi_0 pypi
scikit-image 0.19.3 pypi_0 pypi
scikit-learn 1.0.2 pypi_0 pypi
scikit-video 1.1.11 pypi_0 pypi
scipy 1.7.3 py37hb6553fb_0 conda-forge
seaborn 0.12.1 pypi_0 pypi
segmentation-models 1.0.1 pypi_0 pypi
setuptools 59.8.0 py37h03978a9_1 conda-forge
setuptools-scm 6.3.2 pypi_0 pypi
shapely 1.7.1 py37hc520ffa_5 conda-forge
shiboken2 5.14.1 pypi_0 pypi
six 1.15.0 pyh9f0ad1d_0 conda-forge
sleap 1.2.9 pypi_0 pypi
sqlite 3.40.0 hcfcfb64_0 conda-forge
svt-av1 1.4.1 h63175ca_0 conda-forge
tbb 2021.7.0 h91493d7_1 conda-forge
tensorboard 2.6.0 pypi_0 pypi
tensorboard-data-server 0.6.1 pypi_0 pypi
tensorboard-plugin-wit 1.8.1 pypi_0 pypi
tensorflow 2.6.3 pypi_0 pypi
tensorflow-estimator 2.6.0 pypi_0 pypi
termcolor 1.1.0 pypi_0 pypi
threadpoolctl 3.1.0 pypi_0 pypi
tifffile 2021.11.2 pypi_0 pypi
tk 8.6.12 h8ffe710_0 conda-forge
tomli 2.0.1 pypi_0 pypi
typing-extensions 3.10.0.2 pypi_0 pypi
tzdata 2022.6 pypi_0 pypi
tzlocal 4.2 pypi_0 pypi
ucrt 10.0.22621.0 h57928b3_0 conda-forge
urllib3 1.26.8 pypi_0 pypi
vc 14.3 h3d8a991_9 conda-forge
vs2015_runtime 14.32.31332 h1d6e394_9 conda-forge
werkzeug 2.0.3 pypi_0 pypi
wheel 0.38.4 pyhd8ed1ab_0 conda-forge
wrapt 1.12.1 pypi_0 pypi
x264 1!164.3095 h8ffe710_2 conda-forge
x265 3.5 h2d74725_3 conda-forge
xz 5.2.6 h8d14728_0 conda-forge
zipp 3.7.0 pypi_0 pypi
zlib 1.2.13 hcfcfb64_4 conda-forge
zstd 1.5.2 h7755175_4 conda-forge
Logs Anaconda terminal log
``` Traceback (most recent call last): File "C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\sleap\gui\app.py", line 817, inLogs sleap-diagnostic
(sleap129) C:\Users\psych>sleap-diagnostic
==========SYSTEM==========
utc: 2022-12-21 20:20:15.505595
python: 3.7.12
system: Windows, AMD64, 10, 10.0.19041
path: C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\PySide2;C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\cv2\../../x64/vc14/bin;C:\ProgramData\Anaconda2\envs\sleap129;C:\ProgramData\Anaconda2\envs\sleap129\Library\mingw-w64\bin;C:\ProgramData\Anaconda2\envs\sleap129\Library\usr\bin;C:\ProgramData\Anaconda2\envs\sleap129\Library\bin;C:\ProgramData\Anaconda2\envs\sleap129\Scripts;C:\ProgramData\Anaconda2\envs\sleap129\bin;C:\ProgramData\Anaconda2\condabin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.1\libnvvp;C:\Program Files (x86)\Intel\iCLS Client;C:\Program Files\Intel\iCLS Client;C:\windows\system32;C:\windows;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\WINDOWS\System32\OpenSSH;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\WINDOWS\System32\OpenSSH;C:\Program Files\MATLAB\R2022a\bin;.;C:\Program Files\MEGA11;C:\Users\psych\AppData\Local\Microsoft\WindowsApps;C:\PAUP4;C:\ffmpeg;.;C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\scipy\.libs
==========IMPORTS==========
sleap import: True
sleap path: C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\sleap\__init__.py
sleap version: 1.2.9
pyside2 import: True
pyside path: C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\PySide2\__init__.py
call to C:\ProgramData\Anaconda2\envs\sleap129\python.exe failed
C:\ProgramData\Anaconda2\envs\sleap129\python.exe: can't open file 'C:\ProgramData\Anaconda2\envs\sleap129\Scripts\sleap-diagnostic': [Errno 2] No such file or directory
pyside6 import: False
cv2 import: True
==========GIT==========
unable to locate git
unable to locate git
==========TENSORFLOW==========
tensorflow import: True
tensorflow version: 2.6.3
tensorflow path: C:\ProgramData\Anaconda2\envs\sleap129\lib\site-packages\tensorflow\__init__.py
gpus: [PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
==========CONDA==========
unable to locate conda
==========PIP==========
absl-py==0.15.0
astunparse==1.6.3
attrs==21.2.0
backports.zoneinfo==0.2.1
cached-property @ file:///home/conda/feedstock_root/build_artifacts/cached_property_1615209429212/work
cachetools==4.2.4
cattrs==1.1.1
certifi==2021.10.8
charset-normalizer==2.0.12
clang==5.0
colorama==0.4.6
commonmark==0.9.1
cycler==0.11.0
efficientnet==1.0.0
flatbuffers==1.12
fonttools==4.38.0
gast==0.4.0
google-auth==1.35.0
google-auth-oauthlib==0.4.6
google-pasta==0.2.0
grpcio==1.44.0
h5py @ file:///D:/bld/h5py_1604753757907/work
hdmf==3.4.7
idna==3.3
image-classifiers==1.0.0
imageio==2.15.0
imgaug==0.4.0
imgstore==0.2.9
importlib-metadata==4.11.1
importlib-resources==5.10.0
joblib==1.2.0
jsmin==3.0.1
jsonpickle==1.2
jsonschema==4.17.0
keras==2.6.0
Keras-Applications==1.0.8
Keras-Preprocessing==1.1.2
kiwisolver==1.4.4
Markdown==3.3.6
matplotlib==3.5.3
ndx-pose==0.1.1
networkx==2.6.3
numpy @ file:///D:/bld/numpy_1649281563521/work
oauthlib==3.2.0
olefile @ file:///home/conda/feedstock_root/build_artifacts/olefile_1602866521163/work
opencv-python @ git+https://github.com/talmolab/wrap_opencv-python-headless.git@ede49f6a23a73033216339f29515e59d594ba921
opencv-python-headless==4.5.5.62
opt-einsum==3.3.0
packaging @ file:///home/conda/feedstock_root/build_artifacts/packaging_1670530880680/work
pandas @ file:///D:/bld/pandas_1639398349358/work
Pillow @ file:///D:/bld/pillow_1636559064986/work
pkgutil_resolve_name==1.3.10
protobuf==3.19.4
psutil==5.9.4
pyasn1==0.4.8
pyasn1-modules==0.2.8
Pygments==2.13.0
pykalman==0.9.5
pynwb==2.2.0
pyparsing==3.0.7
pyreadline @ file:///D:/bld/pyreadline_1655703530615/work
pyrsistent==0.19.2
PySide2==5.14.1
python-dateutil @ file:///home/conda/feedstock_root/build_artifacts/python-dateutil_1626286286081/work
python-rapidjson==1.9
pytz @ file:///home/conda/feedstock_root/build_artifacts/pytz_1671365381334/work
pytz-deprecation-shim==0.1.0.post0
PyWavelets==1.3.0
PyYAML==6.0
pyzmq==24.0.1
qimage2ndarray==1.9.0
QtPy @ file:///home/conda/feedstock_root/build_artifacts/qtpy_1667873092748/work
requests==2.27.1
requests-oauthlib==1.3.1
rich==10.16.1
rsa==4.8
ruamel.yaml==0.17.21
ruamel.yaml.clib==0.2.7
scikit-image==0.19.3
scikit-learn==1.0.2
scikit-video==1.1.11
scipy @ file:///C:/bld/scipy_1637806996411/work
seaborn==0.12.1
segmentation-models==1.0.1
setuptools-scm==6.4.2
Shapely==1.7.1
shiboken2==5.14.1
six @ file:///home/conda/feedstock_root/build_artifacts/six_1590081179328/work
sleap==1.2.9
tensorboard==2.6.0
tensorboard-data-server==0.6.1
tensorboard-plugin-wit==1.8.1
tensorflow==2.6.3
tensorflow-estimator==2.6.0
termcolor==1.1.0
threadpoolctl==3.1.0
tifffile==2021.11.2
tomli==2.0.1
typing-extensions==3.10.0.2
tzdata==2022.6
tzlocal==4.2
urllib3==1.26.8
Werkzeug==2.0.3
wrapt==1.12.1
zipp==3.7.0
==========NVIDIA==========
unable to locate nvidia-smi
Screenshots
How to reproduce
- In SLEAP GUI, Go to 'Predict'
- Click on 'Run Training...'
- In Training Configuration window, Click on 'Export training job package...'
- In SLEAP GUI, Go to 'Predict'
- Click on 'Run Training...'
- See error in Conda terminal
For Import Predictions:
- In SLEAP GUI, Go to 'Merge into Project...'
- Select Predictions file and click 'Open'
- See error in Conda terminal
Hi @amblypatty,
I am having a bit of trouble replicating the issue. Are you able/willing to share your troublesome project (slp, videos/images) with [email protected] for troubleshooting purposes?
Thanks for writing the very thorough report! Liezl
Hi @roomrys,
I will send the project package file and video. Thank you for the reply.
Cheers, Patrick
Hi @amblypatty,
The problem
It seems that your project does indeed have two skeletons in it:
which was caused by an old bug that seems to keep haunting us. We will need to develop an automatic script to help users get past this error (but that might mask the root cause if there are any other entry points for the bug).
Previously, the "Load Skeleton" button allowed users to load more than one skeletons into a project - which SLEAP is not ready for yet (different species). Do you recall using the "Load Skeleton" button at any point in the lifetime of the project? Another possible culprit is the "Merge labels into project...", but I did not find the error in that section of code after a first-pass.
I will remove the redundant skeleton and send you back both the slp file and the script used to remove the skeleton.
Why does the Training Pipeline pop-up the first time?
The reason the Training Pipeline pops up the first time is due to this conditional:
https://github.com/talmolab/sleap/blob/9ae2941649c81ca5b8e8301ccd99725732599fa5/sleap/gui/app.py#L1616-L1625
where we create a new LearningDialog the first time around which just uses the first Skeleton in the list of Labels.skeletons:
https://github.com/talmolab/sleap/blob/9ae2941649c81ca5b8e8301ccd99725732599fa5/sleap/gui/learning/dialog.py#L66-L67
The Training Pipeline fails the second time around because we head into the later part of the conditional:
https://github.com/talmolab/sleap/blob/9ae2941649c81ca5b8e8301ccd99725732599fa5/sleap/gui/app.py#L1626-L1635
which references labels.skeleton resulting in an error if there are multiple Skeletons in labels.skeletons.
Related Issues
- #713
- #913
- #1066 (#1063)
- #1144
Thanks, Liezl
The script to remove redundant skeletons:
WARNING(S)
I have not tested the case where multiple skeletons are actually used by instances. Always save to an output_path different from the original slp_path - otherwise, you will overwrite your current project.
"""Get rid of redundant Skeletons."""
from typing import Dict, List
from itertools import permutations
import sleap
from sleap import Skeleton, Instance, Labels
def resolve_skeleton_conflicts(
slp_path, output_path: str = "resolved_skeletons.slp", save: bool = True
) -> Labels:
"""Resolve multiple skeleton conflicts in SLEAP project.
Args:
slp_path: The path to the SLEAP project (.slp).
output_path: The path to save the SLEAP project to if `save` is True (use a
different path than `slp_path`).
save: Option to save to a new SLEAP project at `output_path`.
Raises:
ValueError: if the script detects that the `Skeleton` conflict was not resolved
by running this function. If this is raised contact SLEAP support through
https://github.com/talmolab/sleap for help.
Returns:
The `Labels` object with `Skeleton` conflicts resolved.
"""
# Load the troublesome SLEAP project
labels = sleap.load_file(slp_path)
if len(labels.skeletons) <= 1:
print(
"\nThere is only one (or less) skeleton(s) in this project. "
"Nothing to resolve."
)
return labels
# Create a dictionary of all the skeletons in the project
skeleton_dict: Dict[Skeleton, List[Instance]] = {
skeleton: [] for skeleton in labels.skeletons
}
# Find all instances that use each skeleton
for lf in labels.labeled_frames:
for inst in lf.instances:
skeleton_dict[inst.skeleton].append(inst)
# Remove unused skeletons from labels
for skeleton in list(labels.skeletons):
if len(skeleton_dict[skeleton]) == 0:
skeleton_dict.pop(skeleton)
labels.skeletons.pop(labels.skeletons.index(skeleton))
print(f"\nRemoved unused skeleton:\n{skeleton}")
if len(labels.skeletons) > 1:
# Ensure that the skeletons are identical
for skeleton_a, skeleton_b in permutations(labels.skeletons, 2):
if not skeleton_a.matches(skeleton_b):
raise ValueError(
"Oh no!"
"The skeletons in your project don't have the same nodes!"
"Recieved:\n"
f"{skeleton_a}\nand:\n"
f"{skeleton_b}\n"
"Contact SLEAP support through https://github.com/talmolab/sleap for help"
)
# Check which Skeleton has the greater number of instances labeled
n_instances = {}
max_inst_skeleton = None
for skeleton, instances in skeleton_dict.items():
n_instances[skeleton] = len(instances)
if n_instances[skeleton] >= n_instances.get(skeleton, -1):
max_inst_skeleton = skeleton
# Keep the skeleton with the maximum number of instances
skeleton_dict.pop(max_inst_skeleton, None)
print(f"\nKeeping skeleton with max number of instances:\n{max_inst_skeleton}")
# Replace all the skeletons
for skeleton, instances in skeleton_dict.items():
for inst in instances:
inst.skeleton = skeleton
labels.skeletons.pop(labels.skeletons.index(skeleton))
try:
print(f"\nThe remaining skeleton is:\n{labels.skeleton}")
except Exception as e:
raise ValueError(
"Oh no! This script has a bug somewhere... you still have multiple skeletons"
) from e
# Save the new SLEAP project
if save:
labels.save_file(labels, output_path)
print(f"\nSuccess! SLEAP project saved to: {output_path}")
return labels
if __name__ == "__main__":
import os
ds = os.environ["ds-patty"] # Replace with path to slp file.
resolve_skeleton_conflicts(ds)
Flagging this suspicious piece of code (called in Labels.finish_complex_merge) for further inspection:
https://github.com/talmolab/sleap/blob/833c2d5bdcf4cfef4e0adc7569b8e2245494a8fa/sleap/io/dataset.py#L469-L479