diff --git a/.conda/README.md b/.conda/README.md new file mode 100644 index 000000000..65fadd36e --- /dev/null +++ b/.conda/README.md @@ -0,0 +1,21 @@ +This folder defines the conda package build for Linux and Windows. There are runners for both Linux and Windows on GitHub Actions, but it is faster to experiment with builds locally first. + +To build, first go to the base repo directory and install the build environment: + +``` +conda env create -f environment_build.yml -n sleap_build && conda activate sleap_build +``` + +And finally, run the build command pointing to this directory: + +``` +conda build .conda --output-folder build -c conda-forge -c nvidia -c https://conda.anaconda.org/sleap/ -c anaconda +``` + +To install the local package: + +``` +conda create -n sleap_0 -c conda-forge -c nvidia -c ./build -c https://conda.anaconda.org/sleap/ -c anaconda sleap=x.x.x +``` + +replacing x.x.x with the version of SLEAP that you just built. diff --git a/.conda/bld.bat b/.conda/bld.bat index 1fb7dc081..22b63e50a 100644 --- a/.conda/bld.bat +++ b/.conda/bld.bat @@ -1,60 +1,14 @@ -@echo off +@REM Install anything that didn't get conda installed via pip. -rem # Install anything that didn't get conda installed via pip. -rem # We need to turn pip index back on because Anaconda turns -rem # it off for some reason. Just pip install -r requirements.txt -rem # doesn't seem to work, tensorflow-gpu, jsonpickle, networkx, -rem # all get installed twice if we do this. pip doesn't see the -rem # conda install of the packages. - -rem # Install the pip dependencies and their dependencies. Conda turns of -rem # pip index and dependencies by default so re-enable them. Had to figure -rem # this out myself, ughhh. +@REM We need to turn pip index back on because Anaconda turns it off for some reason. set PIP_NO_INDEX=False set PIP_NO_DEPENDENCIES=False set PIP_IGNORE_INSTALLED=False -pip install numpy==1.19.5 -pip install six==1.15.0 -pip install imageio==2.15.0 -pip install attrs==21.2.0 -pip install cattrs==1.1.1 -pip install jsonpickle==1.2 -pip install networkx -@REM pip install tensorflow>=2.6.3,<=2.7.1 -@REM pip install h5py>=3.1.0,<=3.6.0 -pip install python-rapidjson -@REM pip install opencv-python-headless>=4.2.0.34,<=4.5.5.62 -@REM pip install opencv-python @ git+https://github.com/talmolab/wrap_opencv-python-headless.git@ede49f6a23a73033216339f29515e59d594ba921 -@REM pip install pandas -pip install psutil -@REM pip install PySide2>=5.13.2,<=5.14.1 -pip install pyzmq -pip install pyyaml -pip install imgaug==0.4.0 -@REM pip install scipy>=1.4.1,<=1.7.3 -pip install scikit-image -pip install scikit-learn==1.0.* -pip install scikit-video -pip install imgstore==0.2.9 -pip install qimage2ndarray==1.9.0 -pip install jsmin -pip install seaborn -pip install pykalman==0.9.5 -pip install segmentation-models==1.0.1 -pip install rich==10.16.1 -pip install certifi==2021.10.8 -pip install pynwb -pip install ndx-pose - -rem # Use and update environment.yml call to install pip dependencies. This is slick. -rem # While environment.yml contains the non pip dependencies, the only thing left -rem # uninstalled should be the pip stuff because that is left out of meta.yml -rem conda env update -f=environment.yml - -rem # Install requires setuptools-scm -pip install setuptools-scm +@REM Install the pip dependencies. Note: Using urls to wheels might be better: +@REM https://docs.conda.io/projects/conda-build/en/stable/user-guide/wheel-files.html) +pip install --no-cache-dir -r .\requirements.txt -rem # Install sleap itself. -rem # NOTE: This is the recommended way to install packages +@REM Install sleap itself. This does not install the requirements, but will list which +@REM requirements are missing (see "install_requires") when user attempts to install. python setup.py install --single-version-externally-managed --record=record.txt diff --git a/.conda/build.sh b/.conda/build.sh index 3e1e1a705..86ab5af73 100644 --- a/.conda/build.sh +++ b/.conda/build.sh @@ -1,49 +1,23 @@ -#!/usr/bin/env bash - # Install anything that didn't get conda installed via pip. -# We need to turn pip index back on because Anaconda turns -# it off for some reason. Just pip install -r requirements.txt -# doesn't seem to work, tensorflow-gpu, jsonpickle, networkx, -# all get installed twice if we do this. pip doesn't see the -# conda install of the packages. +# We need to turn pip index back on because Anaconda turns it off for some reason. export PIP_NO_INDEX=False export PIP_NO_DEPENDENCIES=False export PIP_IGNORE_INSTALLED=False -pip install numpy==1.19.5 -pip install six==1.15.0 -pip install imageio==2.15.0 -pip install attrs==21.2.0 -pip install cattrs==1.1.1 -pip install jsonpickle==1.2 -pip install networkx -# pip install tensorflow>=2.6.3,<=2.7.1 -# pip install h5py>=3.1.0,<=3.6.0 -pip install python-rapidjson -# pip install opencv-python-headless==4.5.5.62 -# pip install git+https://github.com/talmolab/wrap_opencv-python-headless.git@ede49f6a23a73033216339f29515e59d594ba921 -# pip install pandas -pip install psutil -# pip install PySide2>=5.13.2,<=5.14.1 -pip install pyzmq -pip install pyyaml -pip install imgaug==0.4.0 -# pip install scipy>=1.4.1,<=1.7.3 -pip install scikit-image -pip install scikit-learn==1.0.* -pip install scikit-video -pip install imgstore==0.2.9 -pip install qimage2ndarray==1.9.0 -pip install jsmin -pip install seaborn -pip install pykalman==0.9.5 -pip install segmentation-models==1.0.1 -pip install rich==10.16.1 -pip install certifi==2021.10.8 -pip install pynwb -pip install ndx-pose +# Install the pip dependencies. Note: Using urls to wheels might be better: +# https://docs.conda.io/projects/conda-build/en/stable/user-guide/wheel-files.html) +pip install --no-cache-dir -r ./requirements.txt + -pip install setuptools-scm +# Install sleap itself. This does not install the requirements, but will list which +# requirements are missing (see "install_requires") when user attempts to install. +python setup.py install --single-version-externally-managed --record=record.txt -python setup.py install --single-version-externally-managed --record=record.txt \ No newline at end of file +# Copy the activate scripts to $PREFIX/etc/conda/activate.d. +# This will allow them to be run on environment activation. +for CHANGE in "activate" "deactivate" +do + mkdir -p "${PREFIX}/etc/conda/${CHANGE}.d" + cp "${RECIPE_DIR}/${PKG_NAME}_${CHANGE}.sh" "${PREFIX}/etc/conda/${CHANGE}.d/${PKG_NAME}_${CHANGE}.sh" +done \ No newline at end of file diff --git a/.conda/conda_build_config.yaml b/.conda/conda_build_config.yaml deleted file mode 100644 index 80fadb65d..000000000 --- a/.conda/conda_build_config.yaml +++ /dev/null @@ -1,10 +0,0 @@ -# We specify the numpy version here for build compatibility. -# -# Ref: https://docs.conda.io/projects/conda-build/en/latest/resources/variants.html#conda-build-variant-config-files - -python: - - 3.7 - -numpy: - - 1.19.5 - # - 1.21.2 \ No newline at end of file diff --git a/.conda/condarc.yaml b/.conda/condarc.yaml new file mode 100644 index 000000000..c5fbc2d96 --- /dev/null +++ b/.conda/condarc.yaml @@ -0,0 +1,6 @@ +channels: + - conda-forge + - nvidia + - https://conda.anaconda.org/sleap/label/dev + - sleap + - anaconda diff --git a/.conda/meta.yaml b/.conda/meta.yaml index fbe01340a..c1781a3ee 100644 --- a/.conda/meta.yaml +++ b/.conda/meta.yaml @@ -1,6 +1,3 @@ -# Ref: https://docs.conda.io/projects/conda-build/en/latest/resources/define-metadata.html - -# Jinja template: Process setup.py to obtain version and metadata {% set data = load_setup_py_data() %} @@ -15,50 +12,89 @@ about: license: {{ data.get('license') }} summary: {{ data.get('description') }} -build: - number: 1 - source: path: ../ +build: + number: 0 + requirements: host: - - python=3.7 - # - sleap::pyside2=5.14.1 - - conda-forge::numpy=1.19.5 - - sleap::tensorflow=2.6.3 - - conda-forge::pyside2=5.13.2 - - conda-forge::h5py=3.1.0 - - conda-forge::scipy=1.7.3 - - conda-forge::six=1.15.0 - - pillow=8.4.0 - - shapely=1.7.1 - - conda-forge::pandas - - ffmpeg - - qtpy>=2.0.1 - - conda-forge::pip!=22.0.4 + - conda-forge::python ==3.7.12 # Run into _MAX_WINDOWS_WORKERS not found if < + - numpy >=1.19.5,<1.23.0 # Linux likes anaconda, windows likes conda-forge + - conda-forge::cudatoolkit ==11.3.1 + - conda-forge::cudnn=8.2.1 + - nvidia::cuda-nvcc=11.3 + - conda-forge::setuptools + - conda-forge::pip - run: - - python=3.7 - - conda-forge::numpy~=1.19.5 - - sleap::tensorflow=2.6.3 - - conda-forge::pyside2>=5.13.2,<=5.14.1 - - conda-forge::h5py~=3.1.0 - - conda-forge::scipy>=1.4.1,<=1.7.3 - - conda-forge::six~=1.15.0 - - pillow=8.4.0 - - shapely=1.7.1 + # Only the packages above are required to build, but listing them all ensures no + # unnecessary pypi packages are installed via the build script (bld.bat, build.sh) + - conda-forge::attrs ==21.4.0 + - conda-forge::cattrs ==1.1.1 + - conda-forge::h5py ==3.7.0 + - conda-forge::imageio-ffmpeg # Required for imageio to read/write videos with ffmpeg + - conda-forge::jsmin + - conda-forge::jsonpickle ==1.2 + - conda-forge::networkx + - conda-forge::opencv <4.9.0 - conda-forge::pandas - - ffmpeg - - qtpy>=2.0.1 - - cudatoolkit=11.3.1 - - cudnn=8.2.1 + - conda-forge::pillow >=8.3.2 + - conda-forge::psutil + - conda-forge::pykalman + - conda-forge::pyside2 >=5.12,<5.14 + - conda-forge::python-rapidjson + - conda-forge::pyyaml + - conda-forge::pyzmq + - conda-forge::qtpy >=2.0.1 + - conda-forge::rich + - conda-forge::scipy >=1.4.1,<=1.9.0 + - conda-forge::scikit-image + - conda-forge::scikit-learn ==1.0 + - conda-forge::scikit-video + - conda-forge::seaborn + - conda-forge::qudida + - conda-forge::albumentations + - conda-forge::ndx-pose <0.2.0 + - conda-forge::importlib-metadata ==4.11.4 + run: + - conda-forge::python ==3.7.12 # Run into _MAX_WINDOWS_WORKERS not found if < + - conda-forge::attrs ==21.4.0 + - conda-forge::cattrs ==1.1.1 + - conda-forge::imageio-ffmpeg # Required for imageio to read/write videos with ffmpeg + - conda-forge::cudatoolkit ==11.3.1 + - conda-forge::cudnn=8.2.1 - nvidia::cuda-nvcc=11.3 - - conda-forge::pip!=22.0.4 - - run_constrained: - - pyqt==9999999999 + - conda-forge::h5py ==3.7.0 + - conda-forge::jsmin + - conda-forge::jsonpickle ==1.2 + - conda-forge::networkx + - numpy >=1.19.5,<1.23.0 # Linux likes anaconda, windows likes conda-forge + - conda-forge::opencv <4.9.0 + - conda-forge::pandas + - conda-forge::pillow >=8.3.2 + - conda-forge::psutil + - conda-forge::pykalman + - conda-forge::pyside2 >=5.12,<5.14 # To ensure works correctly with QtPy. + - conda-forge::python-rapidjson + - conda-forge::pyyaml + - conda-forge::pyzmq + - conda-forge::qtpy >=2.0.1 + - conda-forge::rich + - conda-forge::scipy >=1.4.1,<=1.9.0 + - conda-forge::scikit-image + - conda-forge::scikit-learn ==1.0 + - conda-forge::scikit-video + - conda-forge::seaborn + - sleap/label/dev::tensorflow ==2.7.0 # TODO: Switch to main label when updated + - conda-forge::tensorflow-hub <0.14.0 # Causes pynwb conflicts on linux GH-1446 + - conda-forge::qudida + - conda-forge::albumentations + - conda-forge::ndx-pose <0.2.0 + - conda-forge::importlib-metadata ==4.11.4 -test: - imports: - - sleap +# This no longer works so we have moved it to the build workflow +# https://github.com/talmolab/sleap/pull/1744 +# test: +# imports: +# - sleap \ No newline at end of file diff --git a/.conda/sleap_activate.sh b/.conda/sleap_activate.sh new file mode 100644 index 000000000..885879a89 --- /dev/null +++ b/.conda/sleap_activate.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +# Remember the old library path for when we deactivate +export SLEAP_OLD_LD_LIBRARY_PATH=$LD_LIBRARY_PATH +# Help CUDA find GPUs! +export LD_LIBRARY_PATH=$CONDA_PREFIX/lib:$LD_LIBRARY_PATH \ No newline at end of file diff --git a/.conda/sleap_deactivate.sh b/.conda/sleap_deactivate.sh new file mode 100644 index 000000000..857c0f49c --- /dev/null +++ b/.conda/sleap_deactivate.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +# Reset to the old library path for when deactivating the environment +export LD_LIBRARY_PATH=$SLEAP_OLD_LD_LIBRARY_PATH \ No newline at end of file diff --git a/.conda_m1/README.md b/.conda_m1/README.md deleted file mode 100644 index d6ffd6eaa..000000000 --- a/.conda_m1/README.md +++ /dev/null @@ -1,16 +0,0 @@ -This folder defines the conda package build for M1 Macs. Until there are aarm64 runners, we have to run this manually on Apple M1 silicon. - -To build, first go to the base repo directory and install the M1-compatible environment: -``` -conda env create -f environment_m1.yml -n sleap_build && conda activate sleap_build -``` - -Next, install build dependencies: -``` -conda install conda-build=3.21.7 && conda install anaconda-client && conda install conda-verify -``` - -And finally, run the build command pointing to this directory: -``` -conda build .conda_m1 --output-folder build -c https://conda.anaconda.org/sleap/ -c nvidia -c conda-forge -c apple -``` \ No newline at end of file diff --git a/.conda_m1/build.sh b/.conda_m1/build.sh deleted file mode 100644 index 9652efb47..000000000 --- a/.conda_m1/build.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env bash - -# Install anything that didn't get conda installed via pip. -# We need to turn pip index back on because Anaconda turns -# it off for some reason. Just pip install -r requirements.txt -# doesn't seem to work, tensorflow-gpu, jsonpickle, networkx, -# all get installed twice if we do this. pip doesn't see the -# conda install of the packages. - -export PIP_NO_INDEX=False -export PIP_NO_DEPENDENCIES=False -export PIP_IGNORE_INSTALLED=False - -# pip install numpy==1.22.3 -pip install attrs==21.4.0 -pip install cattrs==1.1.1 -pip install jsonpickle==1.2 -pip install networkx -# pip install tensorflow>=2.6.3,<2.9.0; platform_machine != 'arm64' -pip install tensorflow-macos==2.9.2 -pip install tensorflow-metal==0.5.0 -# pip install h5py==3.6.0 -pip install python-rapidjson -# pip install opencv-python==4.6.0 -pip install pandas -pip install psutil -# pip install PySide2==5.15.5 -pip install pyzmq -pip install pyyaml -# pip install pillow==8.4.0 -pip install imageio<=2.15.0 -pip install imgaug==0.4.0 -# pip install scipy==1.7.3 -pip install scikit-image -pip install scikit-learn==1.0.* -pip install scikit-video -pip install imgstore==0.2.9 -pip install qimage2ndarray==1.9.0 -pip install jsmin -pip install seaborn -pip install pykalman==0.9.5 -pip install segmentation-models==1.0.1 -pip install rich==10.16.1 -pip install certifi==2021.10.8 -pip install pynwb -pip install ndx-pose - - -pip install setuptools-scm - -python setup.py install --single-version-externally-managed --record=record.txt \ No newline at end of file diff --git a/.conda_m1/conda_build_config.yaml b/.conda_m1/conda_build_config.yaml deleted file mode 100644 index 1e9e2addf..000000000 --- a/.conda_m1/conda_build_config.yaml +++ /dev/null @@ -1,9 +0,0 @@ -# We specify the numpy version here for build compatibility. -# -# Ref: https://docs.conda.io/projects/conda-build/en/latest/resources/variants.html#conda-build-variant-config-files - -python: - - 3.9 - -numpy: - - 1.22.3 \ No newline at end of file diff --git a/.conda_m1/meta.yaml b/.conda_m1/meta.yaml deleted file mode 100644 index 250f200dd..000000000 --- a/.conda_m1/meta.yaml +++ /dev/null @@ -1,56 +0,0 @@ -# Ref: https://docs.conda.io/projects/conda-build/en/latest/resources/define-metadata.html - -# Jinja template: Process setup.py to obtain version and metadata -{% set data = load_setup_py_data() %} - - -package: - # Repeating name because of the following issue: - # https://github.com/conda/conda-build/issues/2475 - name: sleap - version: {{ data.get('version') }} - -about: - home: {{ data.get('url') }} - license: {{ data.get('license') }} - summary: {{ data.get('description') }} - -build: - number: 1 - -source: - path: ../ - -requirements: - host: - - python=3.9 - - shapely=1.7.1 - - conda-forge::h5py=3.6.0 - - conda-forge::numpy=1.22.3 - - scipy=1.7.3 - - pillow=8.4.0 - - apple::tensorflow-deps=2.9.0 - - conda-forge::pyside2=5.15.5 - - conda-forge::opencv=4.6.0 - - qtpy=2.0.1 - - conda-forge::pip!=22.0.4 - - run: - - python=3.9 - - shapely=1.7.1 - - conda-forge::h5py=3.6.0 - - conda-forge::numpy=1.22.3 - - scipy=1.7.3 - - pillow=8.4.0 - - apple::tensorflow-deps=2.9.0 - - conda-forge::pyside2=5.15.5 - - conda-forge::opencv=4.6.0 - - qtpy=2.0.1 - - conda-forge::pip!=22.0.4 - - run_constrained: - - pyqt==9999999999 - -test: - imports: - - sleap diff --git a/.conda_mac/README.md b/.conda_mac/README.md new file mode 100644 index 000000000..06f370b4f --- /dev/null +++ b/.conda_mac/README.md @@ -0,0 +1,21 @@ +This folder defines the conda package build for Apple silicon Macs. Until there are aarm64 runners, we have to run this manually on Apple M1 silicon. + +To build, first go to the base repo directory and install the build environment: + +``` +conda env create -f environment_build.yml -n sleap_build && conda activate sleap_build +``` + +And finally, run the build command pointing to this directory: + +``` +conda build .conda_mac --output-folder build -c conda-forge -c anaconda +``` + +To install the local package: + +``` +conda create -n sleap_0 -c conda-forge -c anaconda -c ./build sleap=x.x.x +``` + +replacing x.x.x with the version of SLEAP that you just built. diff --git a/.conda_mac/build.sh b/.conda_mac/build.sh new file mode 100644 index 000000000..a68193560 --- /dev/null +++ b/.conda_mac/build.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +# Install anything that didn't get conda installed via pip. +# We need to turn pip index back on because Anaconda turns it off for some reason. +export PIP_NO_INDEX=False +export PIP_NO_DEPENDENCIES=False +export PIP_IGNORE_INSTALLED=False + +pip install --no-cache-dir -r requirements.txt + +python setup.py install --single-version-externally-managed --record=record.txt \ No newline at end of file diff --git a/.conda_mac/condarc.yaml b/.conda_mac/condarc.yaml new file mode 100644 index 000000000..c1be41bf1 --- /dev/null +++ b/.conda_mac/condarc.yaml @@ -0,0 +1,5 @@ +# https://github.com/github/roadmap/issues/528 + +channels: + - conda-forge + - anaconda \ No newline at end of file diff --git a/.conda_mac/meta.yaml b/.conda_mac/meta.yaml new file mode 100644 index 000000000..8f773badf --- /dev/null +++ b/.conda_mac/meta.yaml @@ -0,0 +1,96 @@ +# Ref: https://docs.conda.io/projects/conda-build/en/latest/resources/define-metadata.html + +# Jinja template: Process setup.py to obtain version and metadata +{% set data = load_setup_py_data() %} + + +package: + # Repeating name because of the following issue: + # https://github.com/conda/conda-build/issues/2475 + name: sleap + version: {{ data.get('version') }} + +about: + home: {{ data.get('url') }} + license: {{ data.get('license') }} + summary: {{ data.get('description') }} + +build: + number: 0 + +source: + path: ../ + +requirements: + host: + - conda-forge::python >=3.9.0, <3.10.0 + - anaconda::numpy >=1.19.5,<1.23.0 + - conda-forge::setuptools + - conda-forge::packaging + - conda-forge::pip + + # Only the packages above are required to build, but listing them all ensures no + # unnecessary pypi packages are installed via the build script (bld.bat, build.sh) + - conda-forge::attrs >=21.2.0 + - conda-forge::cattrs ==1.1.1 + - conda-forge::h5py + - conda-forge::imageio-ffmpeg # Required for imageio to read/write videos with ffmpeg + - conda-forge::jsmin + - conda-forge::jsonpickle ==1.2 + - conda-forge::keras <2.10.0,>=2.9.0rc0 # Required by tensorflow-macos + - conda-forge::networkx <3.3 + - conda-forge::opencv + - conda-forge::pandas + - conda-forge::pillow + - conda-forge::psutil + - conda-forge::pykalman + - conda-forge::pyside2 >=5.12 + - conda-forge::python-rapidjson + - conda-forge::pyyaml + - conda-forge::pyzmq + - conda-forge::qtpy >=2.0.1 + - conda-forge::rich + - conda-forge::scipy >=1.4.1,<=1.9.0 + - conda-forge::scikit-image + - conda-forge::scikit-learn ==1.0 + - conda-forge::scikit-video + - conda-forge::seaborn + - conda-forge::qudida + - conda-forge::albumentations + - conda-forge::ndx-pose <0.2.0 + + run: + - conda-forge::python >=3.9.0, <3.10.0 + - conda-forge::attrs >=21.2.0 + - conda-forge::cattrs ==1.1.1 + - conda-forge::h5py + - conda-forge::imageio-ffmpeg # Required for imageio to read/write videos with ffmpeg + - conda-forge::jsmin + - conda-forge::jsonpickle ==1.2 + - conda-forge::keras <2.10.0,>=2.9.0rc0 # Required by tensorflow-macos + - conda-forge::networkx <3.3 + - anaconda::numpy >=1.19.5,<1.23.0 + - conda-forge::opencv + - conda-forge::pandas + - conda-forge::pillow + - conda-forge::psutil + - conda-forge::pykalman + - conda-forge::pyside2 >=5.12 + - conda-forge::python-rapidjson + - conda-forge::pyyaml + - conda-forge::pyzmq + - conda-forge::qtpy >=2.0.1 + - conda-forge::rich + - conda-forge::scipy >=1.4.1,<=1.9.0 + - conda-forge::scikit-image + - conda-forge::scikit-learn ==1.0 + - conda-forge::scikit-video + - conda-forge::seaborn + # - conda-forge::tensorflow-hub # pulls in tensorflow cpu from conda-forge + - conda-forge::qudida + - conda-forge::albumentations + - conda-forge::ndx-pose <0.2.0 + +# test: +# imports: +# - sleap diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ae0418034..6a92c2e3b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -25,15 +25,15 @@ Tell us a little about the system you're using. Please include information about how you installed. --> -- OS: +- OS: -- Version(s): - -- SLEAP installation method (listed [here](https://sleap.ai/installation.html#)): - - [ ] [Conda from package](https://sleap.ai/installation.html#conda-package) - - [ ] [Conda from source](https://sleap.ai/installation.html#conda-from-source) - - [ ] [pip package](https://sleap.ai/installation.html#pip-package) - - [ ] [M1 Macs](https://sleap.ai/installation.html#m1-macs) +- Version(s): + +- SLEAP installation method (listed [here](https://sleap.ai/installation.html#)): + - [ ] [Conda from package](https://sleap.ai/installation.html#conda-package) + - [ ] [Conda from source](https://sleap.ai/installation.html#conda-from-source) + - [ ] [pip package](https://sleap.ai/installation.html#pip-package) + - [ ] [Apple Silicon Macs](https://sleap.ai/installation.html#apple-silicon-macs)
Environment packages diff --git a/.github/workflows/archive/comment-template.yml b/.github/workflows/archive/comment-template.yml new file mode 100644 index 000000000..3bef84531 --- /dev/null +++ b/.github/workflows/archive/comment-template.yml @@ -0,0 +1,71 @@ +name: Reusable Comment Workflow + +on: + workflow_call: + inputs: + subject_id: + required: true + type: string + body_prefix: + required: true + type: string + comment_type: + required: true + type: string + +jobs: + comment: + runs-on: ubuntu-latest + steps: + - name: Post a comment + uses: actions/github-script@v6 + with: + script: | + const { owner, repo } = context.repo; + const subject_id = '${{ inputs.subject_id }}'; + const comment_type = '${{ inputs.comment_type }}'; + const baseBody = ` + We appreciate your input and will review it soon. + + > [!WARNING] + > A friendly reminder that this is a public forum. Please be cautious when clicking links, downloading files, or running scripts posted by others. + > + > - Always verify the credibility of links and code. + > - Avoid running scripts or installing files from untrusted sources. + > - If you're unsure, ask for clarification before proceeding. + + Stay safe and happy SLEAPing! + + Best regards, + The Team + `; + const body = `${{ inputs.body_prefix }}\n\n${baseBody}`; + + const mutation = comment_type === 'discussion' + ? ` + mutation($discussionId: ID!, $body: String!) { + addDiscussionComment(input: {discussionId: $discussionId, body: $body}) { + comment { + id + } + } + } + ` + : ` + mutation($issueId: ID!, $body: String!) { + addComment(input: {subjectId: $issueId, body: $body}) { + commentEdge { + node { + id + body + } + } + } + } + `; + + const variables = comment_type === 'discussion' + ? { discussionId: subject_id, body: body.trim() } + : { issueId: subject_id, body: body.trim() }; + + await github.graphql(mutation, variables); diff --git a/.github/workflows/archive/comment.yml b/.github/workflows/archive/comment.yml new file mode 100644 index 000000000..a24df018f --- /dev/null +++ b/.github/workflows/archive/comment.yml @@ -0,0 +1,24 @@ +name: Comment on New Discussions and Issues + +on: + discussion: + types: [created] + issues: + types: [opened] + +jobs: + comment_on_discussion: + if: github.event_name == 'discussion' + uses: ./.github/workflows/comment-template.yml + with: + subject_id: ${{ github.event.discussion.node_id }} + body_prefix: "Thank you for starting a new discussion!" + comment_type: "discussion" + + comment_on_issue: + if: github.event_name == 'issues' + uses: ./.github/workflows/comment-template.yml + with: + subject_id: ${{ github.event.issue.node_id }} + body_prefix: "Thank you for opening a new issue!" + comment_type: "issue" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ec4005497..74203245c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -13,98 +13,210 @@ jobs: strategy: fail-fast: false matrix: - os: ["ubuntu-18.04", "windows-2019"] - # os: ["ubuntu-18.04"] + os: ["ubuntu-22.04", "windows-2022", "macos-14"] + # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrixinclude + include: + # Use this condarc as default + - condarc: .conda/condarc.yaml + - pyver: "3.7" + # Use special condarc if macos + - os: "macos-14" + condarc: .conda_mac/condarc.yaml + pyver: "3.9" steps: # Setup - - uses: actions/checkout@v2 - - name: Cache conda - uses: actions/cache@v1 - env: - # Increase this value to reset cache if environment_build.yml has not changed - CACHE_NUMBER: 0 - with: - path: ~/conda_pkgs_dir - key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('environment_build.yml', 'requirements.txt') }} + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Miniconda - # https://github.com/conda-incubator/setup-miniconda - uses: conda-incubator/setup-miniconda@v2.0.1 + uses: conda-incubator/setup-miniconda@v3.0.3 with: - python-version: 3.7 - use-only-tar-bz2: true # IMPORTANT: This needs to be set for caching to work properly! + miniforge-version: latest + condarc-file: ${{ matrix.condarc }} + python-version: ${{ matrix.pyver }} environment-file: environment_build.yml - activate-environment: sleap + activate-environment: sleap_ci + conda-solver: "libmamba" + - name: Print environment info shell: bash -l {0} run: | which python conda info + conda list # Build pip wheel (Ubuntu) - name: Build pip wheel (Ubuntu) - if: matrix.os == 'ubuntu-18.04' + if: matrix.os == 'ubuntu-22.04' shell: bash -l {0} run: | python setup.py bdist_wheel # Upload pip wheel (Ubuntu) - name: Upload pip wheel (Ubuntu) - if: matrix.os == 'ubuntu-18.04' + if: matrix.os == 'ubuntu-22.04' env: PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} shell: bash -l {0} run: | twine upload -u __token__ -p "$PYPI_TOKEN" dist/* --non-interactive --skip-existing --disable-progress-bar - # Build conda package + # Build conda package (Ubuntu) - name: Build conda package (Ubuntu) - if: matrix.os == 'ubuntu-18.04' + if: matrix.os == 'ubuntu-22.04' shell: bash -l {0} run: | - conda build .conda --output-folder build -c https://conda.anaconda.org/sleap/ -c nvidia -c conda-forge + conda build .conda --output-folder build + echo "BUILD_PATH=$(pwd)/build" >> "$GITHUB_ENV" + + # Build conda package (Windows) - name: Build conda package (Windows) - if: matrix.os == 'windows-2019' + if: matrix.os == 'windows-2022' shell: powershell run: | - conda activate sleap - pytest tests/ - conda build .conda --output-folder build -c https://conda.anaconda.org/sleap/ -c nvidia -c conda-forge + conda build .conda --output-folder build + echo "BUILD_PATH=\$(pwd)\build" >> "$env:GITHUB_ENV" + + # Build conda package (Mac) + - name: Build conda package (Mac) + if: matrix.os == 'macos-14' + shell: bash -l {0} + run: | + conda build .conda_mac --output-folder build + echo "BUILD_PATH=$(pwd)/build" >> "$GITHUB_ENV" + + # Test built conda package (Ubuntu and Windows) + - name: Test built conda package (Ubuntu and Windows) + if: matrix.os != 'macos-14' + shell: bash -l {0} + run: | + echo "Current build path: $BUILD_PATH" + conda deactivate + + echo "Python executable before activating environment:" + which python + echo "Python version before activating environment:" + python --version + echo "Conda info before activating environment:" + conda info + + echo "Creating and testing conda environment with sleap package..." + conda create -y -n sleap_test -c file://$BUILD_PATH -c sleap/label/dev -c conda-forge -c nvidia -c anaconda sleap + conda activate sleap_test + + echo "Python executable after activating sleap_test environment:" + which python + echo "Python version after activating sleap_test environment:" + python --version + echo "Conda info after activating sleap_test environment:" + conda info + echo "List of installed conda packages in the sleap_test environment:" + conda list + echo "List of installed pip packages in the sleap_test environment:" + pip list + + echo "Testing sleap package installation..." + sleap_version=$(python -c "import sleap; print(sleap.__version__)") + echo "Test completed using sleap version: $sleap_version" - # Upload conda package + # Test built conda package (Mac) + - name: Test built conda package (Mac) + if: matrix.os == 'macos-14' + shell: bash -l {0} + run: | + echo "Current build path: $BUILD_PATH" + conda deactivate + + echo "Python executable before activating environment:" + which python + echo "Python version before activating environment:" + python --version + echo "Conda info before activating environment:" + conda info + + echo "Creating and testing conda environment with sleap package..." + conda create -y -n sleap_test -c file://$BUILD_PATH -c conda-forge -c anaconda sleap + conda activate sleap_test + + echo "Python executable after activating sleap_test environment:" + which python + echo "Python version after activating sleap_test environment:" + python --version + echo "Conda info after activating sleap_test environment:" + conda info + echo "List of installed conda packages in the sleap_test environment:" + conda list + echo "List of installed pip packages in the sleap_test environment:" + pip list + + echo "Testing sleap package installation..." + sleap_version=$(python -c "import sleap; print(sleap.__version__)") + echo "Test completed using sleap version: $sleap_version" + + # Login to conda (Ubuntu) - name: Login to Anaconda (Ubuntu) - if: matrix.os == 'ubuntu-18.04' + if: matrix.os == 'ubuntu-22.04' env: ANACONDA_LOGIN: ${{ secrets.ANACONDA_LOGIN }} shell: bash -l {0} run: | yes 2>/dev/null | anaconda login --username sleap --password "$ANACONDA_LOGIN" || true + + # Login to conda (Windows) - name: Login to Anaconda (Windows) - if: matrix.os == 'windows-2019' + if: matrix.os == 'windows-2022' env: ANACONDA_LOGIN: ${{ secrets.ANACONDA_LOGIN }} shell: powershell run: | echo "yes" | anaconda login --username sleap --password "$env:ANACONDA_LOGIN" + + # Login to conda (Mac) + - name: Login to Anaconda (Mac) + if: matrix.os == 'macos-14' + env: + ANACONDA_LOGIN: ${{ secrets.ANACONDA_LOGIN }} + shell: bash -l {0} + run: | + yes 2>/dev/null | anaconda login --username sleap --password "$ANACONDA_LOGIN" || true + + # Upload conda package (Windows) - name: Upload conda package (Windows/main) - if: matrix.os == 'windows-2019' && !github.event.release.prerelease + if: matrix.os == 'windows-2022' && !github.event.release.prerelease shell: powershell run: | anaconda -v upload "build\win-64\*.tar.bz2" - name: Upload conda package (Windows/dev) - if: matrix.os == 'windows-2019' && github.event.release.prerelease + if: matrix.os == 'windows-2022' && github.event.release.prerelease shell: powershell run: | anaconda -v upload "build\win-64\*.tar.bz2" --label dev + + # Upload conda package (Ubuntu) - name: Upload conda package (Ubuntu/main) - if: matrix.os == 'ubuntu-18.04' && !github.event.release.prerelease + if: matrix.os == 'ubuntu-22.04' && !github.event.release.prerelease shell: bash -l {0} run: | anaconda -v upload build/linux-64/*.tar.bz2 - name: Upload conda package (Ubuntu/dev) - if: matrix.os == 'ubuntu-18.04' && github.event.release.prerelease + if: matrix.os == 'ubuntu-22.04' && github.event.release.prerelease shell: bash -l {0} run: | anaconda -v upload build/linux-64/*.tar.bz2 --label dev + + # Upload conda package (Mac) + - name: Upload conda package (Mac/main) + if: matrix.os == 'macos-14' && !github.event.release.prerelease + shell: bash -l {0} + run: | + anaconda -v upload build/osx-arm64/*.tar.bz2 --label dev + - name: Upload conda package (Mac/dev) + if: matrix.os == 'macos-14' && github.event.release.prerelease + shell: bash -l {0} + run: | + anaconda -v upload build/osx-arm64/*.tar.bz2 --label dev + + # Logout - name: Logout from Anaconda shell: bash -l {0} run: | diff --git a/.github/workflows/build_conda_ci.yml b/.github/workflows/build_conda_ci.yml new file mode 100644 index 000000000..3fd3d2b92 --- /dev/null +++ b/.github/workflows/build_conda_ci.yml @@ -0,0 +1,179 @@ +# Run tests using built conda packages. +name: Build Conda CI (no upload) + +# Run when changes to pip wheel +on: + push: + paths: + - ".conda/meta.yaml" + - ".conda_mac/meta.yaml" + - "setup.py" + - "requirements.txt" + - "dev_requirements.txt" + - "environment_build.yml" + - ".github/workflows/build_conda_ci.yml" # Run! + +# If RUN_BUILD_JOB is set to true, then RUN_ID will be overwritten to the current run id +env: + RUN_BUILD_JOB: true + RUN_ID: 10713717594 # Only used if RUN_BUILD_JOB is false (to dowload build artifact) + +jobs: + build: + name: Build package from push (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: ["windows-2022", "ubuntu-22.04", "macos-14"] + # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrixinclude + include: + # Use these variables as defaults + - condarc: .conda/condarc.yaml + - conda-folder: .conda + - pyver: "3.10" + - build-prefix: win + - os: "ubuntu-22.04" + build-prefix: linux + # Use special condarc if macos + - os: "macos-14" + condarc: .conda_mac/condarc.yaml + conda-folder: .conda_mac + build-prefix: osx + + steps: + # Setup + - name: Checkout + if: env.RUN_BUILD_JOB == 'true' + uses: actions/checkout@v4 + + - name: Setup Miniconda + if: env.RUN_BUILD_JOB == 'true' + uses: conda-incubator/setup-miniconda@v3.0.4 + with: + miniforge-version: latest + condarc-file: ${{ matrix.condarc }} + python-version: ${{ matrix.pyver }} + environment-file: environment_build.yml + activate-environment: sleap_ci + conda-solver: "libmamba" + + - name: Print build environment info + if: env.RUN_BUILD_JOB == 'true' + shell: bash -l {0} + run: | + which python + conda list + pip freeze + + # Build conda package + - name: Build conda package + if: env.RUN_BUILD_JOB == 'true' + shell: bash -l {0} + run: | + conda build ${{ matrix.conda-folder }} --output-folder build + + # Upload artifact "tests" can use it + - name: Upload conda package artifact + if: env.RUN_BUILD_JOB == 'true' + uses: actions/upload-artifact@v4 + with: + name: sleap-build-${{ matrix.build-prefix }} + path: build # Upload entire build directory + retention-days: 1 + overwrite: true + + tests: + name: Run tests using package (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + needs: build # Ensure the build job has completed before starting this job. + strategy: + fail-fast: false + matrix: + os: ["windows-2022", "ubuntu-22.04", "macos-14"] + # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrixinclude + include: + # Default values + - build-prefix: win + - build-suffix: 64 + - test_args: pytest --durations=-1 tests/ + - condarc: .conda/condarc.yaml + - pyver: "3.10" + - conda-channels: -c conda-forge -c nvidia -c anaconda + # Ubuntu specific values + - os: ubuntu-22.04 + build-prefix: linux + # Otherwise core dumped in github actions + test_args: | + sudo apt install xvfb libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 + sudo Xvfb :1 -screen 0 1024x768x24 > $GITHUB_ENV + + # https://github.com/actions/download-artifact?tab=readme-ov-file#usage + - name: Download conda package artifact + uses: actions/download-artifact@v4 + id: download + with: + name: sleap-build-${{ matrix.build-prefix }} + path: build + run-id: ${{ env.RUN_ID }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: List items in current directory + run: | + ls . + ls -R build + + - name: Setup Miniconda + uses: conda-incubator/setup-miniconda@v3.0.4 + with: + miniforge-version: latest + condarc-file: ${{ matrix.condarc }} + python-version: ${{ matrix.pyver }} + conda-solver: "libmamba" + + - name: Create conda environment + shell: bash -l {0} + run: conda create sleap -y -n sleap_ci -c ./build ${{ matrix.conda-channels }} + + - name: Install packages for testing + shell: bash -l {0} + run: | + conda activate sleap_ci + pip install -r "dev_requirements.txt" + + # Note: "conda activate" does not persist across steps + - name: Print environment info + shell: bash -l {0} + run: | + conda activate sleap_ci + conda info + conda list + pip freeze + + - name: Test package + shell: bash -l {0} + run: | + conda activate sleap_ci + ${{ matrix.test_args}} diff --git a/.github/workflows/build_manual.yml b/.github/workflows/build_manual.yml index 4c8fd1448..7cba65d67 100644 --- a/.github/workflows/build_manual.yml +++ b/.github/workflows/build_manual.yml @@ -7,8 +7,11 @@ on: push: paths: - '.conda/meta.yaml' + - '.conda_mac/meta.yaml' + - '.github/workflows/build_manual.yml' branches: - - develop + # - develop + - fakebranch jobs: build: @@ -17,93 +20,195 @@ jobs: strategy: fail-fast: false matrix: - os: ["ubuntu-18.04", "windows-2019"] - # os: ["ubuntu-18.04"] + os: ["ubuntu-22.04", "windows-2022", "macos-14"] + # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrixinclude + include: + # Use this condarc as default + - condarc: .conda/condarc.yaml + - pyver: "3.7" + # Use special condarc if macos + - os: "macos-14" + condarc: .conda_mac/condarc.yaml + pyver: "3.9" steps: # Setup - - uses: actions/checkout@v2 - - name: Cache conda - uses: actions/cache@v1 - env: - # Increase this value to reset cache if environment_build.yml has not changed - CACHE_NUMBER: 0 - with: - path: ~/conda_pkgs_dir - key: ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('environment_build.yml', 'requirements.txt') }} + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Miniconda - # https://github.com/conda-incubator/setup-miniconda - uses: conda-incubator/setup-miniconda@v2.0.1 + uses: conda-incubator/setup-miniconda@v3.0.3 with: - python-version: 3.7 - use-only-tar-bz2: true # IMPORTANT: This needs to be set for caching to work properly! + miniforge-version: latest + condarc-file: ${{ matrix.condarc }} + python-version: ${{ matrix.pyver }} environment-file: environment_build.yml - activate-environment: sleap + activate-environment: sleap_ci + conda-solver: "libmamba" + - name: Print environment info shell: bash -l {0} run: | which python conda info + conda list - # Build pip wheel (Ubuntu) - - name: Build pip wheel (Ubuntu) - if: matrix.os == 'ubuntu-18.04' + # Build pip wheel (Not Windows) + - name: Build pip wheel (Not Windows) + if: matrix.os != 'windows-2022' shell: bash -l {0} run: | python setup.py bdist_wheel - # Upload pip wheel (Ubuntu) - - name: Upload pip wheel (Ubuntu) - if: matrix.os == 'ubuntu-18.04' - env: - PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} - shell: bash -l {0} - run: | - twine upload -u __token__ -p "$PYPI_TOKEN" dist/* --non-interactive --skip-existing --disable-progress-bar + # # Upload pip wheel (Ubuntu) + # - name: Upload pip wheel (Ubuntu) + # if: matrix.os == 'ubuntu-22.04' + # env: + # PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} + # shell: bash -l {0} + # run: | + # twine upload -u __token__ -p "$PYPI_TOKEN" dist/* --non-interactive --skip-existing --disable-progress-bar - # Build conda package + # Build conda package (Ubuntu) - name: Build conda package (Ubuntu) - if: matrix.os == 'ubuntu-18.04' + if: matrix.os == 'ubuntu-22.04' shell: bash -l {0} - # sudo apt install xvfb libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 - # sudo Xvfb :1 -screen 0 1024x768x24 > "$GITHUB_ENV" + + # Build conda package (Windows) - name: Build conda package (Windows) - if: matrix.os == 'windows-2019' + if: matrix.os == 'windows-2022' shell: powershell run: | - conda activate sleap - pytest tests/ - conda build .conda --output-folder build -c https://conda.anaconda.org/sleap/ -c nvidia -c conda-forge + conda build .conda --output-folder build + echo "BUILD_PATH=\$(pwd)\build" >> "$env:GITHUB_ENV" - # Upload conda package - - name: Login to Anaconda (Ubuntu) - if: matrix.os == 'ubuntu-18.04' - env: - ANACONDA_LOGIN: ${{ secrets.ANACONDA_LOGIN }} + # Build conda package (Mac) + - name: Build conda package (Mac) + if: matrix.os == 'macos-14' shell: bash -l {0} run: | - yes 2>/dev/null | anaconda login --username sleap --password "$ANACONDA_LOGIN" || true - - name: Login to Anaconda (Windows) - if: matrix.os == 'windows-2019' - env: - ANACONDA_LOGIN: ${{ secrets.ANACONDA_LOGIN }} - shell: powershell - run: | - echo "yes" | anaconda login --username sleap --password "$env:ANACONDA_LOGIN" - - name: Upload conda package (Windows/dev) - if: matrix.os == 'windows-2019' - shell: powershell - run: | - anaconda -v upload "build\win-64\*.tar.bz2" --label dev - - name: Upload conda package (Ubuntu/dev) - if: matrix.os == 'ubuntu-18.04' + conda build .conda_mac --output-folder build + echo "BUILD_PATH=$(pwd)/build" >> "$GITHUB_ENV" + + # Test built conda package (Ubuntu and Windows) + - name: Test built conda package (Ubuntu and Windows) + if: matrix.os != 'macos-14' shell: bash -l {0} run: | - anaconda -v upload build/linux-64/*.tar.bz2 --label dev - - name: Logout from Anaconda + echo "Current build path: $BUILD_PATH" + conda deactivate + + echo "Python executable before activating environment:" + which python + echo "Python version before activating environment:" + python --version + echo "Conda info before activating environment:" + conda info + + echo "Creating and testing conda environment with sleap package..." + conda create -y -n sleap_test -c file://$BUILD_PATH -c sleap/label/dev -c conda-forge -c nvidia -c anaconda sleap + conda activate sleap_test + + echo "Python executable after activating sleap_test environment:" + which python + echo "Python version after activating sleap_test environment:" + python --version + echo "Conda info after activating sleap_test environment:" + conda info + echo "List of installed conda packages in the sleap_test environment:" + conda list + echo "List of installed pip packages in the sleap_test environment:" + pip list + + echo "Testing sleap package installation..." + sleap_version=$(python -c "import sleap; print(sleap.__version__)") + echo "Test completed using sleap version: $sleap_version" + + # Test built conda package (Mac) + - name: Test built conda package (Mac) + if: matrix.os == 'macos-14' shell: bash -l {0} run: | - anaconda logout + echo "Current build path: $BUILD_PATH" + conda deactivate + + echo "Python executable before activating environment:" + which python + echo "Python version before activating environment:" + python --version + echo "Conda info before activating environment:" + conda info + + echo "Creating and testing conda environment with sleap package..." + conda create -y -n sleap_test -c file://$BUILD_PATH -c conda-forge -c anaconda sleap + conda activate sleap_test + + echo "Python executable after activating sleap_test environment:" + which python + echo "Python version after activating sleap_test environment:" + python --version + echo "Conda info after activating sleap_test environment:" + conda info + echo "List of installed conda packages in the sleap_test environment:" + conda list + echo "List of installed pip packages in the sleap_test environment:" + pip list + + echo "Testing sleap package installation..." + sleap_version=$(python -c "import sleap; print(sleap.__version__)") + echo "Test completed using sleap version: $sleap_version" + + # # Login to conda (Ubuntu) + # - name: Login to Anaconda (Ubuntu) + # if: matrix.os == 'ubuntu-22.04' + # env: + # ANACONDA_LOGIN: ${{ secrets.ANACONDA_LOGIN }} + # shell: bash -l {0} + # run: | + # yes 2>/dev/null | anaconda login --username sleap --password "$ANACONDA_LOGIN" || true + + # # Login to conda (Windows) + # - name: Login to Anaconda (Windows) + # if: matrix.os == 'windows-2022' + # env: + # ANACONDA_LOGIN: ${{ secrets.ANACONDA_LOGIN }} + # shell: powershell + # run: | + # echo "yes" | anaconda login --username sleap --password "$env:ANACONDA_LOGIN" + + # # Login to conda (Mac) + # - name: Login to Anaconda (Mac) + # if: matrix.os == 'macos-14' + # env: + # ANACONDA_LOGIN: ${{ secrets.ANACONDA_LOGIN }} + # shell: bash -l {0} + # run: | + # yes 2>/dev/null | anaconda login --username sleap --password "$ANACONDA_LOGIN" || true + + # # Upload conda package (Windows) + # - name: Upload conda package (Windows/dev) + # if: matrix.os == 'windows-2022' + # shell: powershell + # run: | + # anaconda -v upload "build\win-64\*.tar.bz2" --label dev + + # # Upload conda package (Ubuntu) + # - name: Upload conda package (Ubuntu/dev) + # if: matrix.os == 'ubuntu-22.04' + # shell: bash -l {0} + # run: | + # anaconda -v upload build/linux-64/*.tar.bz2 --label dev + + # # Upload conda package (Mac) + # - name: Upload conda package (Mac/dev) + # if: matrix.os == 'macos-14' + # shell: bash -l {0} + # run: | + # anaconda -v upload build/osx-arm64/*.tar.bz2 --label dev + + # - name: Logout from Anaconda + # shell: bash -l {0} + # run: | + # anaconda logout diff --git a/.github/workflows/build_pypi_ci.yml b/.github/workflows/build_pypi_ci.yml new file mode 100644 index 000000000..68142b288 --- /dev/null +++ b/.github/workflows/build_pypi_ci.yml @@ -0,0 +1,151 @@ +# Run tests using built wheels. +name: Build PyPI CI (no upload) + +# Run when changes to pip wheel +on: + push: + paths: + - "setup.py" + - "requirements.txt" + - "dev_requirements.txt" + - "jupyter_requirements.txt" + - "pypi_requirements.txt" + - "environment_build.yml" + - ".github/workflows/build_pypi_ci.yml" # Run! + +jobs: + build: + name: Build wheel (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: ["ubuntu-22.04"] + # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrixinclude + include: + # Use this condarc as default + - condarc: .conda/condarc.yaml + - wheel_name: sleap-wheel-linux + - pyver: "3.7" + steps: + # Setup + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Miniconda + uses: conda-incubator/setup-miniconda@v3.0.3 + with: + miniforge-version: latest + condarc-file: ${{ matrix.condarc }} + python-version: ${{ matrix.pyver }} + environment-file: environment_build.yml + activate-environment: sleap_ci + conda-solver: "libmamba" + + - name: Print build environment info + shell: bash -l {0} + run: | + which python + conda list + pip freeze + + # Build pip wheel + - name: Build pip wheel + shell: bash -l {0} + run: | + python setup.py bdist_wheel + + # Upload artifact "tests" can use it + - name: Upload wheel artifact + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.wheel_name }} + path: dist/*.whl + retention-days: 1 + + tests: + name: Run tests using wheel (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + needs: build # Ensure the build job has completed before starting this job. + strategy: + fail-fast: false + matrix: + os: ["ubuntu-22.04", "windows-2022"] + # os: ["ubuntu-22.04", "windows-2022", "macos-14"] # removing macos-14 for now since the setup-python action only support py>=3.10, which is breaking this CI. + # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrixinclude + include: + # Default values + - wheel_name: sleap-wheel-linux + - venv_cmd: source venv/bin/activate + - pip_cmd: | + wheel_path=$(find dist -name "*.whl") + echo $wheel_path + pip install '$wheel_path'[dev] + - test_args: pytest --durations=-1 tests/ + - condarc: .conda/condarc.yaml + - pyver: "3.7" + # Use special condarc if macos + - os: "macos-14" + condarc: .conda_mac/condarc.yaml + pyver: "3.10" + # Ubuntu specific values + - os: ubuntu-22.04 + # Otherwise core dumped in github actions + test_args: | + sudo apt install xvfb libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0 + sudo Xvfb :1 -screen 0 1024x768x24 Example Inc. Jeremy Delahanty The Salk Institute for Biological Studies + +Lili Karashchuk Allen Institute of Neural Dynamics diff --git a/MANIFEST.in b/MANIFEST.in index 19228f5f2..db7d5b458 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,5 @@ include sleap/config/*.yaml -include sleap/training_profiles/*.json \ No newline at end of file +include sleap/training_profiles/*.json + +prune tests/* +prune docs/* \ No newline at end of file diff --git a/README.rst b/README.rst index 460d5df16..f7a5acd6c 100644 --- a/README.rst +++ b/README.rst @@ -11,7 +11,7 @@ :alt: Coverage .. |Documentation| image:: - https://img.shields.io/github/workflow/status/talmolab/sleap/Build%20website?label=Documentation + https://img.shields.io/badge/Documentation-sleap.ai-lightgrey :target: https://sleap.ai :alt: Documentation @@ -42,7 +42,7 @@ Social LEAP Estimates Animal Poses (SLEAP) .. image:: https://sleap.ai/docs/_static/sleap_movie.gif :width: 600px -**SLEAP** is an open source deep-learning based framework for multi-animal pose tracking. It can be used to track any type or number of animals and includes an advanced labeling/training GUI for active learning and proofreading. +**SLEAP** is an open source deep-learning based framework for multi-animal pose tracking `(Pereira et al., Nature Methods, 2022) `__. It can be used to track any type or number of animals and includes an advanced labeling/training GUI for active learning and proofreading. Features @@ -69,14 +69,13 @@ Quick install .. code-block:: bash - conda create -y -n sleap -c sleap -c nvidia -c conda-forge sleap + conda create -y -n sleap -c conda-forge -c nvidia -c sleap/label/dev -c sleap -c anaconda sleap - -`pip` **(any OS)**: +`pip` **(any OS except Apple silicon)**: .. code-block:: bash - pip install sleap + pip install sleap[pypi] See the docs for `full installation instructions `_. @@ -85,7 +84,7 @@ Learn to SLEAP -------------- - **Learn step-by-step**: `Tutorial `_ - **Learn more advanced usage**: `Guides `__ and `Notebooks `__ -- **Learn by watching**: `MIT CBMM Tutorial `_ +- **Learn by watching**: `ABL:AOC 2023 Workshop `_ and `MIT CBMM Tutorial `_ - **Learn by reading**: `Paper (Pereira et al., Nature Methods, 2022) `__ and `Review on behavioral quantification (Pereira et al., Nature Neuroscience, 2020) `_ - **Learn from others**: `Discussions on Github `_ diff --git a/codecov.yml b/codecov.yml index 81a3d1710..5952871fe 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,4 +1,6 @@ coverage: + ignore: + - "tests" status: project: # Measures overall project coverage. default: false @@ -7,10 +9,11 @@ coverage: threshold: 0.5% # Some leeway with GUI code. paths: - "sleap/gui/" - backend: + non-gui: target: auto threshold: 0.05% # Less leeway with backend code. paths: + - "sleap/" - "!sleap/gui/" patch: # Only measures lines adjusted in the pull request. default: false @@ -19,9 +22,9 @@ coverage: paths: - "sleap/gui/" informational: true # GUI patch coverage for stats only. - backend: + non-gui: target: 100% # All backend code should be tested... threshold: 20% # ... but some tests are infeasable. paths: + - "sleap/" - "!sleap/gui/" - diff --git a/dev_requirements.txt b/dev_requirements.txt index e5fc92e6f..709fb48fd 100644 --- a/dev_requirements.txt +++ b/dev_requirements.txt @@ -1,22 +1,23 @@ +# This file contains the dependencies to be installed if in developer mode. + pytest pytest-qt>=4.0.0 -pytest-cov +pytest-cov<=3.0.0 pytest-xvfb ipython -sphinx +sphinx>=5.0 # sphinxcontrib.applehelp extension needs at least Sphinx v5.0 # furo sphinx-book-theme sphinx-copybutton +sphinx-tabs nbformat==5.1.3 -myst-nb==0.13.2 -myst-parser==0.15.2 +myst-nb>=0.16.0 # sphinx>=5.0 needs myst-nb>=0.16.0 +myst-parser linkify-it-py sphinx-autobuild black==21.6b0 pre-commit twine==3.3.0 PyGithub -jupyterlab jedi==0.17.2 -ipykernel click==8.0.4 \ No newline at end of file diff --git a/docs/_static/bonsai-connection.jpg b/docs/_static/bonsai-connection.jpg new file mode 100644 index 000000000..32b725416 Binary files /dev/null and b/docs/_static/bonsai-connection.jpg differ diff --git a/docs/_static/bonsai-filecapture.jpg b/docs/_static/bonsai-filecapture.jpg new file mode 100644 index 000000000..7a809d67a Binary files /dev/null and b/docs/_static/bonsai-filecapture.jpg differ diff --git a/docs/_static/bonsai-predictcentroids.jpg b/docs/_static/bonsai-predictcentroids.jpg new file mode 100644 index 000000000..e284f2338 Binary files /dev/null and b/docs/_static/bonsai-predictcentroids.jpg differ diff --git a/docs/_static/bonsai-predictposeidentities.jpg b/docs/_static/bonsai-predictposeidentities.jpg new file mode 100644 index 000000000..8582fd707 Binary files /dev/null and b/docs/_static/bonsai-predictposeidentities.jpg differ diff --git a/docs/_static/bonsai-predictposes.jpg b/docs/_static/bonsai-predictposes.jpg new file mode 100644 index 000000000..2e4f04a22 Binary files /dev/null and b/docs/_static/bonsai-predictposes.jpg differ diff --git a/docs/_static/bonsai-workflow.jpg b/docs/_static/bonsai-workflow.jpg new file mode 100644 index 000000000..0481c3dcf Binary files /dev/null and b/docs/_static/bonsai-workflow.jpg differ diff --git a/docs/_static/css/tabs.css b/docs/_static/css/tabs.css new file mode 100644 index 000000000..95765dff6 --- /dev/null +++ b/docs/_static/css/tabs.css @@ -0,0 +1,91 @@ +.sphinx-tabs { + margin-bottom: 1rem; +} + +[role="tablist"] { + border-bottom: 1px solid #a0b3bf; +} + +.sphinx-tabs-tab { + position: relative; + font-family: Lato,'Helvetica Neue',Arial,Helvetica,sans-serif; + color: var(--pst-color-link); + line-height: 24px; + margin: 3px; + font-size: 16px; + font-weight: 400; + background-color: rgb(241 244 249); + border-radius: 5px 5px 0 0; + border: 0; + padding: 1rem 1.5rem; + margin-bottom: 0; +} + +.sphinx-tabs-tab[aria-selected="true"] { + font-weight: 700; + border: 1px solid #a0b3bf; + border-bottom: 1px solid rgb(241 244 249); + margin: -1px; + background-color: rgb(242 247 255); +} + +.admonition .sphinx-tabs-tab[aria-selected="true"]:last-child { + margin-bottom: -1px; +} + +.sphinx-tabs-tab:focus { + z-index: 1; + outline-offset: 1px; +} + +.sphinx-tabs-panel { + position: relative; + padding: 1rem; + border: 1px solid #a0b3bf; + margin: 0px -1px -1px -1px; + border-radius: 0 0 5px 5px; + border-top: 0; + background: rgb(242 247 255); +} + +.sphinx-tabs-panel.code-tab { + padding: 0.4rem; +} + +.sphinx-tab img { + margin-bottom: 24px; +} + +/* Dark theme preference styling */ + +html[data-theme="dark"] .sphinx-tabs-panel { + color: white; + background-color: rgb(50, 50, 50); +} + +html[data-theme="dark"] .sphinx-tabs-tab { + color: var(--pst-color-link); + background-color: rgba(255, 255, 255, 0.05); +} + +html[data-theme="dark"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid rgb(50, 50, 50); + background-color: rgb(50, 50, 50); +} + +/* Light theme preference styling */ + +html[data-theme="light"] .sphinx-tabs-panel { + color: black; + background-color: white; +} + +html[data-theme="light"] .sphinx-tabs-tab { + color: var(--pst-color-link); + background-color: rgba(0, 0, 0, 0.05); +} + +html[data-theme="light"] .sphinx-tabs-tab[aria-selected="true"] { + border-bottom: 2px solid white; + background-color: white; +} \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 7ce2823bc..074869903 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,10 +15,10 @@ import os import sys import shutil -import docs.utils from datetime import date sys.path.insert(0, os.path.abspath("..")) +import docs.utils # -- Project information ----------------------------------------------------- @@ -28,7 +28,7 @@ copyright = f"2019–{date.today().year}, Talmo Lab" # The short X.Y version -version = "1.2.7" +version = "1.4.1" # Get the sleap version # with open("../sleap/version.py") as f: @@ -36,7 +36,7 @@ # version = re.search("\d.+(?=['\"])", version_file).group(0) # Release should be the full branch name -release = "v1.2.7" +release = "v1.4.1" html_title = f"SLEAP ({release})" html_short_title = "SLEAP" @@ -59,6 +59,7 @@ "sphinx.ext.linkcode", "sphinx.ext.napoleon", "sphinx_copybutton", + "sphinx_tabs.tabs", # For tabs inside docs # https://myst-nb.readthedocs.io/en/latest/ "myst_nb", ] @@ -85,6 +86,7 @@ pygments_style = "sphinx" pygments_dark_style = "monokai" + # Autosummary linkcode resolution # https://www.sphinx-doc.org/en/master/usage/extensions/linkcode.html def linkcode_resolve(domain, info): @@ -173,6 +175,12 @@ def linkcode_resolve(domain, info): # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] +# These paths are either relative to html_static_path +# or fully qualified paths (eg. https://...) +html_css_files = [ + "css/tabs.css", +] + # Custom sidebar templates, must be a dictionary that maps document names # to template names. # @@ -219,3 +227,7 @@ def linkcode_resolve(domain, info): # https://myst-nb.readthedocs.io/en/latest/use/config-reference.html jupyter_execute_notebooks = "off" + +# Sphinx-tabs settings +# https://sphinx-tabs.readthedocs.io/en/latest/ +sphinx_tabs_disable_css_loading = True # Use the theme's CSS diff --git a/docs/datasets.md b/docs/datasets.md index d4501f838..5cb560bc0 100644 --- a/docs/datasets.md +++ b/docs/datasets.md @@ -11,6 +11,10 @@ For the full set of labeled datasets and trained models reported in the SLEAP pa ([Pereira et al., Nature Methods, 2022](https://www.nature.com/articles/s41592-022-01426-1)), please see the [OSF repository](https://osf.io/36har/). +````{hint} +Need a quick testing clip? [Here's a video of a pair of mice in a standard home cage setting.]( +https://storage.googleapis.com/sleap-data/sandbox/sleap-mice-demo/mice.mp4) +```` ## `fly32` ![fly32](_static/example.fly32.jpg) @@ -43,7 +47,9 @@ widths: 10 40 * - Labels - 1500 * - Download - - [Train](https://storage.googleapis.com/sleap-data/datasets/BermanFlies/random_split1/train.pkg.slp) / [Validation](https://storage.googleapis.com/sleap-data/datasets/BermanFlies/random_split1/val.pkg.slp) / [Test](https://storage.googleapis.com/sleap-data/datasets/BermanFlies/random_split1/test.pkg.slp) + - [Train (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/BermanFlies/random_split1/train.pkg.slp) / [Validation (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/BermanFlies/random_split1/val.pkg.slp) / [Test (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/BermanFlies/random_split1/test.pkg.slp) +* - Example + - [Clip (`.mp4`)](https://storage.googleapis.com/sleap-data/datasets/BermanFlies/clips/072212_173836%400-3200.mp4) / [Tracking (`.slp`)](https://storage.googleapis.com/sleap-data/datasets/BermanFlies/clips/072212_173836%400-3200.slp) * - Credit - [Berman et al. (2014)](https://royalsocietypublishing.org/doi/10.1098/rsif.2014.0672), [Pereira et al. (2019)](https://www.nature.com/articles/s41592-018-0234-5), [Pereira et al. (2022)](https://www.nature.com/articles/s41592-022-01426-1), Talmo Pereira, Gordon Berman, Joshua Shaevitz ``` @@ -77,9 +83,11 @@ widths: 10 40 * - Identity - ✔ * - Labels - - 2000 frames, 2000 instances + - 2000 frames, 4000 instances * - Download - - [Train](https://storage.googleapis.com/sleap-data/datasets/wt_gold.13pt/tracking_split2/train.pkg.slp) / [Validation](https://storage.googleapis.com/sleap-data/datasets/wt_gold.13pt/tracking_split2/val.pkg.slp) / [Test](https://storage.googleapis.com/sleap-data/datasets/wt_gold.13pt/tracking_split2/test.pkg.slp) + - [Train (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/wt_gold.13pt/tracking_split2/train.pkg.slp) / [Validation (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/wt_gold.13pt/tracking_split2/val.pkg.slp) / [Test (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/wt_gold.13pt/tracking_split2/test.pkg.slp) +* - Example + - [Clip (`.mp4`)](https://storage.googleapis.com/sleap-data/datasets/wt_gold.13pt/clips/talk_title_slide%4013150-14500.mp4) / [Tracking (`.slp`)](https://storage.googleapis.com/sleap-data/datasets/wt_gold.13pt/clips/talk_title_slide%4013150-14500.slp) * - Credit - [Pereira et al. (2022)](https://www.nature.com/articles/s41592-022-01426-1), Junyu Li, Shruthi Ravindranath, Talmo Pereira, Mala Murthy ``` @@ -115,7 +123,9 @@ widths: 10 40 * - Labels - 1000 frames, 2950 instances * - Download - - [Train](https://storage.googleapis.com/sleap-data/datasets/wang_4mice_john/labels.full/random_split1/train.pkg.slp) / [Validation](https://storage.googleapis.com/sleap-data/datasets/wang_4mice_john/labels.full/random_split1/val.pkg.slp) / [Test](https://storage.googleapis.com/sleap-data/datasets/wang_4mice_john/labels.full/random_split1/test.pkg.slp) + - [Train (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/wang_4mice_john/labels.full/random_split1/train.pkg.slp) / [Validation (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/wang_4mice_john/labels.full/random_split1/val.pkg.slp) / [Test (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/wang_4mice_john/labels.full/random_split1/test.pkg.slp) +* - Example + - [Clip (`.mp4`)](https://storage.googleapis.com/sleap-data/datasets/wang_4mice_john/clips/OFTsocial5mice-0000-00%4015488-18736.mp4) / [Tracking (`.slp`)](https://storage.googleapis.com/sleap-data/datasets/wang_4mice_john/clips/OFTsocial5mice-0000-00%4015488-18736.slp) * - Credit - [Pereira et al. (2022)](https://www.nature.com/articles/s41592-022-01426-1), John D'Uva, Mikhail Kislin, Samuel S.-H. Wang ``` @@ -151,7 +161,9 @@ widths: 10 40 * - Labels - 1474 frames, 2948 instances * - Download - - [Train](https://storage.googleapis.com/sleap-data/datasets/eleni_mice/random_split1/train.pkg.slp) / [Validation](https://storage.googleapis.com/sleap-data/datasets/eleni_mice/random_split1/val.pkg.slp) / [Test](https://storage.googleapis.com/sleap-data/datasets/eleni_mice/random_split1/test.pkg.slp) + - [Train (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/eleni_mice/random_split1/train.pkg.slp) / [Validation (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/eleni_mice/random_split1/val.pkg.slp) / [Test (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/eleni_mice/random_split1/test.pkg.slp) +* - Example + - [Clip (`.mp4`)](https://storage.googleapis.com/sleap-data/datasets/eleni_mice/clips/20200111_USVpairs_court1_M1_F1_top-01112020145828-0000%400-2560.mp4) / [Tracking (`.slp`)](https://storage.googleapis.com/sleap-data/datasets/eleni_mice/clips/20200111_USVpairs_court1_M1_F1_top-01112020145828-0000%400-2560.slp) * - Credit - [Pereira et al. (2022)](https://www.nature.com/articles/s41592-022-01426-1), Eleni Papadoyannis, Mala Murthy, Annegret Falkner ``` @@ -187,7 +199,9 @@ widths: 10 40 * - Labels - 804 frames, 1604 instances * - Download - - [Train](https://storage.googleapis.com/sleap-data/datasets/yan_bees/random_split1/train.pkg.slp) / [Validation](https://storage.googleapis.com/sleap-data/datasets/yan_bees/random_split1/val.pkg.slp) / [Test](https://storage.googleapis.com/sleap-data/datasets/yan_bees/random_split1/test.pkg.slp) + - [Train (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/yan_bees/random_split1/train.pkg.slp) / [Validation (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/yan_bees/random_split1/val.pkg.slp) / [Test (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/yan_bees/random_split1/test.pkg.slp) +* - Example + - [Clip (`.mp4`)](https://storage.googleapis.com/sleap-data/datasets/yan_bees/clips/bees_demo%4021000-23000.mp4) / [Tracking (`.slp`)](https://storage.googleapis.com/sleap-data/datasets/yan_bees/clips/bees_demo%4021000-23000.slp) * - Credit - [Pereira et al. (2022)](https://www.nature.com/articles/s41592-022-01426-1), Grace McKenzie-Smith, Z. Yan Wang, Joshua Shaevitz, Sarah Kocher ``` @@ -223,7 +237,9 @@ widths: 10 40 * - Labels - 425 frames, 1588 instances * - Download - - [Train](https://storage.googleapis.com/sleap-data/datasets/nyu-gerbils/cohort1_compressedTalmo_23vids_march_7_to_march_17/random_split1.day001/train.pkg.slp) / [Validation](https://storage.googleapis.com/sleap-data/datasets/nyu-gerbils/cohort1_compressedTalmo_23vids_march_7_to_march_17/random_split1.day001/val.pkg.slp) / [Test](https://storage.googleapis.com/sleap-data/datasets/nyu-gerbils/cohort1_compressedTalmo_23vids_march_7_to_march_17/random_split1.day001/test.pkg.slp) + - [Train (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/nyu-gerbils/cohort1_compressedTalmo_23vids_march_7_to_march_17/random_split1.day001/train.pkg.slp) / [Validation (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/nyu-gerbils/cohort1_compressedTalmo_23vids_march_7_to_march_17/random_split1.day001/val.pkg.slp) / [Test (`.pkg.slp`)](https://storage.googleapis.com/sleap-data/datasets/nyu-gerbils/cohort1_compressedTalmo_23vids_march_7_to_march_17/random_split1.day001/test.pkg.slp) +* - Example + - [Clip (`.mp4`)](https://storage.googleapis.com/sleap-data/datasets/nyu-gerbils/clips/2020-3-10_daytime_5mins_compressedTalmo%403200-5760.mp4) / [Tracking (`.slp`)](https://storage.googleapis.com/sleap-data/datasets/nyu-gerbils/clips/2020-3-10_daytime_5mins_compressedTalmo%403200-5760.slp) * - Credit - [Pereira et al. (2022)](https://www.nature.com/articles/s41592-022-01426-1), Catalin Mitelut, Marielisa Diez Castro, Dan H. Sanes ``` \ No newline at end of file diff --git a/docs/guides/bonsai.md b/docs/guides/bonsai.md new file mode 100644 index 000000000..d262873b6 --- /dev/null +++ b/docs/guides/bonsai.md @@ -0,0 +1,75 @@ +(bonsai)= + +# Using Bonsai with SLEAP + +Bonsai is a visual language for reactive programming and currently supports SLEAP models. + +:::{note} +Currently Bonsai supports only single instance, top-down and top-down-id SLEAP models. +::: + +### Exporting a SLEAP trained model + +Before we can import a trained model into Bonsai, we need to use the {code}`sleap-export` command to convert the model to a format supported by Bonsai. For example, to export a top-down-id model, the command is as follows: + +```bash +sleap-export -m centroid/model/folder/path -m top_down_id/model/folder/path -e exported/model/path +``` + +Please refer to the {ref}`sleap-export` docs for more details on using the command. + +This will generate the necessary `.pb` file and other information files required by Bonsai. In this example, these files were saved to the specified `exported/model/path` folder. + +The `exported/model/path` folder will have a structure like the following: + +```plaintext +exported/model/path +├── centroid_config.json +├── confmap_config.json +├── frozen_graph.pb +└── info.json +``` + +### Installing Bonsai and necessary packages + +1. Install Bonsai. See the [Bonsai installation instructions](https://bonsai-rx.org/docs/articles/installation.html). + +2. Download and add the necessary packages for Bonsai to run with SLEAP. See the official [Bonsai SLEAP documentation](https://github.com/bonsai-rx/sleap?tab=readme-ov-file#bonsai---sleap) for more information. + +### Using Bonsai SLEAP modules + +Once you have Bonsai installed with the required packages, you should be able to open the Bonsai application. The workflow must have a source module `FileCapture` which can be found in the toolbox search in the workflow editor. Provide the path to the video that was used to train the SLEAP model in the `FileName` field of the module. + +![Bonsai FileCapture module](../_static/bonsai-filecapture.jpg) + +#### Top-down model +The top-down model requires both the `PredictCentroids` and the `PredictPoses` modules. + +The `PredictCentroids` module will predict the centroids of detections. There are two fields inside the `PredictCentroids` module: the `ModelFileName` field and the `TrainingConfig` field. The `TrainingConfig` field expects the path to the training config JSON file for the centroid model. The `ModelFileName` field expects the path to the `frozen_graph.pb` file in the `exported/model/path` folder. + +![Bonsai PredictCentroids module](../_static/bonsai-predictcentroids.jpg) + +The `PredictPoses` module will predict the instances of detections. Similar to the `PredictCentroid` module, there are two fields inside the `PredictPoses` module: the `ModelFileName` field and the `TrainingConfig` field. The `TrainingConfig` field expects the path to the training config JSON file for the centered instance model. The `ModelFileName` field expects the path to the `frozen_graph.pb` file in the `exported/model/path` folder. + +![Bonsai PredictPoses module](../_static/bonsai-predictposes.jpg) + +#### Top-Down-ID model +The `PredictPoseIdentities` module will predict the instances with identities. This module has two fields: the `ModelFileName` field and the `TrainingConfig` field. The `TrainingConfig` field expects the path to the training config JSON file for the top-down-id model. The `ModelFileName` field expects the path to the `frozen_graph.pb` file in the `exported/model/path` folder. + +![Bonsai PredictPoseIdentities module](../_static/bonsai-predictposeidentities.jpg) + +#### Single instance model +The `PredictSinglePose` module will predict the poses for single instance models. This module also has two fields: the `ModelFileName` field and the `TrainingConfig` field. The `TrainingConfig` field expects the path to the training config JSON file for the single instance model. The `ModelFileName` field expects the path to the `frozen_graph.pb` file in the `exported/model/path` folder. + +### Connecting the modules +Right-click on the `FileCapture` module and select **Create Connection**. Now click on the required SLEAP module to complete the connection. + +![Bonsai module connection ](../_static/bonsai-connection.jpg) + +Once it is done, the workflow in Bonsai will look something like the following: + +![Bonsai.SLEAP workflow](../_static/bonsai-workflow.jpg) + +Now you can click the green start button to run the workflow and you can add more modules to analyze and visualize the results in Bonsai. + +For more documentation on various modules and workflows, please refer to the [official Bonsai docs](https://bonsai-rx.org/docs/articles/editor.html). diff --git a/docs/guides/cli.md b/docs/guides/cli.md index 7c49326e4..134461c60 100644 --- a/docs/guides/cli.md +++ b/docs/guides/cli.md @@ -36,8 +36,8 @@ optional arguments: ```none usage: sleap-train [-h] [--video-paths VIDEO_PATHS] [--val_labels VAL_LABELS] - [--test_labels TEST_LABELS] [--tensorboard] [--save_viz] - [--zmq] [--run_name RUN_NAME] [--prefix PREFIX] + [--test_labels TEST_LABELS] [--tensorboard] [--save_viz] + [--keep_viz] [--zmq] [--run_name RUN_NAME] [--prefix PREFIX] [--suffix SUFFIX] training_job_path [labels_path] @@ -60,11 +60,16 @@ optional arguments: Path to labels file to use for test. If specified, overrides the path specified in the training job config. + --base_checkpoint BASE_CHECKPOINT + Path to base checkpoint (directory containing best_model.h5) + to resume training from. --tensorboard Enable TensorBoard logging to the run path if not already specified in the training job config. --save_viz Enable saving of prediction visualizations to the run folder if not already specified in the training job config. + --keep_viz Keep prediction visualization images in the run + folder after training if --save_viz is enabled. --zmq Enable ZMQ logging (for GUI) if not already specified in the training job config. --run_name RUN_NAME Run name to use when saving file, overrides other run @@ -77,7 +82,31 @@ optional arguments: --last-gpu Run training on the last GPU, if available. --gpu GPU Run training on the i-th GPU on the system. If 'auto', run on the GPU with the highest percentage of available memory. - (default: '0') +``` + +(sleap-export)= + +### `sleap-export` + +{code}`sleap-export` is a command-line interface for exporting trained models as a TensorFlow graph for use in other applications. See [this guide](https://www.tensorflow.org/guide/saved_model) for details on how TensorFlow saves models and the [`sleap.nn.inference.InferenceModel.export_model`](sleap.nn.inference.InferenceModel.export_model) documentation. + +```none +usage: sleap-export [-h] [-m MODELS] [-e [EXPORT_PATH]] + +optional arguments: + -h, --help show this help message and exit + -m MODELS, --model MODELS + Path to trained model directory (with training_config.json). Multiple + models can be specified, each preceded by --model. + -e [EXPORT_PATH], --export_path [EXPORT_PATH] + Path to output directory where the frozen model will be exported to. + Defaults to a folder named 'exported_model'. + -r, --ragged RAGGED + Keep tensors ragged if present. If ommited, convert + ragged tensors into regular tensors with NaN padding. + -n, --max_instances MAX_INSTANCES + Limit maximum number of instances in multi-instance models. + Not available for ID models. Defaults to None. ``` ## Inference and Tracking @@ -91,147 +120,169 @@ optional arguments: If you specify how many identities there should be in a frame (i.e., the number of animals) with the {code}`--tracking.clean_instance_count` argument, then we will use a heuristic method to connect "breaks" in the track identities where we lose one identity and spawn another. This can be used as part of the inference pipeline (if models are specified), as part of the tracking-only pipeline (if the predictions file is specified and no models are specified), or by itself on predictions with pre-tracked identities (if you specify {code}`--tracking.tracker none`). See {ref}`proofreading` for more details on tracking. ```none -usage: sleap-track [-h] [-m MODELS] [--frames FRAMES] [--only-labeled-frames] - [--only-suggested-frames] [-o OUTPUT] [--no-empty-frames] - [--verbosity {none,rich,json}] - [--video.dataset VIDEO.DATASET] - [--video.input_format VIDEO.INPUT_FORMAT] - [--video.index VIDEO.INDEX] - [--cpu | --first-gpu | --last-gpu | --gpu GPU] - [--peak_threshold PEAK_THRESHOLD] [--batch_size BATCH_SIZE] - [--open-in-gui] [--tracking.tracker TRACKING.TRACKER] - [--tracking.target_instance_count TRACKING.TARGET_INSTANCE_COUNT] - [--tracking.pre_cull_to_target TRACKING.PRE_CULL_TO_TARGET] - [--tracking.pre_cull_iou_threshold TRACKING.PRE_CULL_IOU_THRESHOLD] +usage: sleap-track [-h] [-m MODELS] [--frames FRAMES] [--only-labeled-frames] [--only-suggested-frames] [-o OUTPUT] [--no-empty-frames] + [--verbosity {none,rich,json}] [--video.dataset VIDEO.DATASET] [--video.input_format VIDEO.INPUT_FORMAT] + [--video.index VIDEO.INDEX] [--cpu | --first-gpu | --last-gpu | --gpu GPU] [--max_edge_length_ratio MAX_EDGE_LENGTH_RATIO] + [--dist_penalty_weight DIST_PENALTY_WEIGHT] [--batch_size BATCH_SIZE] [--open-in-gui] [--peak_threshold PEAK_THRESHOLD] + [-n MAX_INSTANCES] [--tracking.tracker TRACKING.TRACKER] [--tracking.max_tracking TRACKING.MAX_TRACKING] + [--tracking.max_tracks TRACKING.MAX_TRACKS] [--tracking.target_instance_count TRACKING.TARGET_INSTANCE_COUNT] + [--tracking.pre_cull_to_target TRACKING.PRE_CULL_TO_TARGET] [--tracking.pre_cull_iou_threshold TRACKING.PRE_CULL_IOU_THRESHOLD] [--tracking.post_connect_single_breaks TRACKING.POST_CONNECT_SINGLE_BREAKS] - [--tracking.clean_instance_count TRACKING.CLEAN_INSTANCE_COUNT] - [--tracking.clean_iou_threshold TRACKING.CLEAN_IOU_THRESHOLD] - [--tracking.similarity TRACKING.SIMILARITY] - [--tracking.match TRACKING.MATCH] - [--tracking.track_window TRACKING.TRACK_WINDOW] - [--tracking.save_shifted_instances TRACKING.SAVE_SHIFTED_INSTANCES] - [--tracking.min_new_track_points TRACKING.MIN_NEW_TRACK_POINTS] - [--tracking.min_match_points TRACKING.MIN_MATCH_POINTS] - [--tracking.img_scale TRACKING.IMG_SCALE] - [--tracking.of_window_size TRACKING.OF_WINDOW_SIZE] - [--tracking.of_max_levels TRACKING.OF_MAX_LEVELS] - [--tracking.kf_node_indices TRACKING.KF_NODE_INDICES] + [--tracking.clean_instance_count TRACKING.CLEAN_INSTANCE_COUNT] [--tracking.clean_iou_threshold TRACKING.CLEAN_IOU_THRESHOLD] + [--tracking.similarity TRACKING.SIMILARITY] [--tracking.match TRACKING.MATCH] [--tracking.robust TRACKING.ROBUST] + [--tracking.track_window TRACKING.TRACK_WINDOW] [--tracking.min_new_track_points TRACKING.MIN_NEW_TRACK_POINTS] + [--tracking.min_match_points TRACKING.MIN_MATCH_POINTS] [--tracking.img_scale TRACKING.IMG_SCALE] + [--tracking.of_window_size TRACKING.OF_WINDOW_SIZE] [--tracking.of_max_levels TRACKING.OF_MAX_LEVELS] + [--tracking.save_shifted_instances TRACKING.SAVE_SHIFTED_INSTANCES] [--tracking.kf_node_indices TRACKING.KF_NODE_INDICES] [--tracking.kf_init_frame_count TRACKING.KF_INIT_FRAME_COUNT] [data_path] positional arguments: - data_path Path to data to predict on. This can be a labels - (.slp) file or any supported video format. + data_path Path to data to predict on. This can be one of the following: A .slp file containing labeled data; A folder containing multiple + video files in supported formats; An individual video file in a supported format; A CSV file with a column of video file paths. + If more than one column is provided in the CSV file, the first will be used for the input data paths and the next column will be + used as the output paths; A text file with a path to a video file on each line optional arguments: -h, --help show this help message and exit -m MODELS, --model MODELS - Path to trained model directory (with - training_config.json). Multiple models can be - specified, each preceded by --model. - --frames FRAMES List of frames to predict when running on a video. Can - be specified as a comma separated list (e.g. 1,2,3) or - a range separated by hyphen (e.g., 1-3, for 1,2,3). If - not provided, defaults to predicting on the entire - video. + Path to trained model directory (with training_config.json). Multiple models can be specified, each preceded by --model. + --frames FRAMES List of frames to predict when running on a video. Can be specified as a comma separated list (e.g. 1,2,3) or a range + separated by hyphen (e.g., 1-3, for 1,2,3). If not provided, defaults to predicting on the entire video. --only-labeled-frames - Only run inference on user labeled frames when running - on labels dataset. This is useful for generating - predictions to compare against ground truth. + Only run inference on user labeled frames when running on labels dataset. This is useful for generating predictions to compare + against ground truth. --only-suggested-frames - Only run inference on unlabeled suggested frames when - running on labels dataset. This is useful for - generating predictions for initialization during - labeling. + Only run inference on unlabeled suggested frames when running on labels dataset. This is useful for generating predictions for + initialization during labeling. -o OUTPUT, --output OUTPUT - The output filename to use for the predicted data. If - not provided, defaults to - '[data_path].predictions.slp' if generating predictions or - '[data_path].[tracker].[similarity method].[matching method].slp' - if retracking predictions. - --no-empty-frames Clear any empty frames that did not have any detected - instances before saving to output. + The output filename or directory path to use for the predicted data. If not provided, defaults to '[data_path].predictions.slp'. + --no-empty-frames Clear any empty frames that did not have any detected instances before saving to output. --verbosity {none,rich,json} - Verbosity of inference progress reporting. 'none' does - not output anything during inference, 'rich' displays - an updating progress bar, and 'json' outputs the - progress as a JSON encoded response to the console. + Verbosity of inference progress reporting. 'none' does not output anything during inference, 'rich' displays an updating + progress bar, and 'json' outputs the progress as a JSON encoded response to the console. --video.dataset VIDEO.DATASET The dataset for HDF5 videos. --video.input_format VIDEO.INPUT_FORMAT The input_format for HDF5 videos. --video.index VIDEO.INDEX - The index of the video to run inference on. Only used if - data_path points to a labels file. - --cpu Run inference only on CPU. If not specified, will use - available GPU. + Integer index of video in .slp file to predict on. To be used with an .slp path as an alternative to specifying the video + path. + --cpu Run inference only on CPU. If not specified, will use available GPU. --first-gpu Run inference on the first GPU, if available. --last-gpu Run inference on the last GPU, if available. - --gpu GPU Run training on the i-th GPU on the system. If 'auto', run on - the GPU with the highest percentage of available memory. - (default: '0') - --peak_threshold PEAK_THRESHOLD - Minimum confidence map value to consider a peak as - valid. + --gpu GPU Run training on the i-th GPU on the system. If 'auto', run on the GPU with the highest percentage of available memory. + --max_edge_length_ratio MAX_EDGE_LENGTH_RATIO + The maximum expected length of a connected pair of points as a fraction of the image size. Candidate connections longer than + this length will be penalized during matching. Only applies to bottom-up (PAF) models. + --dist_penalty_weight DIST_PENALTY_WEIGHT + A coefficient to scale weight of the distance penalty. Set to values greater than 1.0 to enforce the distance penalty more + strictly. Only applies to bottom-up (PAF) models. --batch_size BATCH_SIZE - Number of frames to predict at a time. Larger values - result in faster inference speeds, but require more - memory. - --open-in-gui Open the resulting predictions in the GUI when - finished. + Number of frames to predict at a time. Larger values result in faster inference speeds, but require more memory. + --open-in-gui Open the resulting predictions in the GUI when finished. + --peak_threshold PEAK_THRESHOLD + Minimum confidence map value to consider a peak as valid. + -n MAX_INSTANCES, --max_instances MAX_INSTANCES + Limit maximum number of instances in multi-instance models. Not available for ID models. Defaults to None. --tracking.tracker TRACKING.TRACKER - Options: simple, flow, None (default: None) + Options: simple, flow, simplemaxtracks, flowmaxtracks, None (default: None) + --tracking.max_tracking TRACKING.MAX_TRACKING + If true then the tracker will cap the max number of tracks. (default: False) + --tracking.max_tracks TRACKING.MAX_TRACKS + Maximum number of tracks to be tracked by the tracker. (default: None) --tracking.target_instance_count TRACKING.TARGET_INSTANCE_COUNT - Target number of instances to track per frame. - (default: 0) + Target number of instances to track per frame. (default: 0) --tracking.pre_cull_to_target TRACKING.PRE_CULL_TO_TARGET - If non-zero and target_instance_count is also non- - zero, then cull instances over target count per frame - *before* tracking. (default: 0) + If non-zero and target_instance_count is also non-zero, then cull instances over target count per frame *before* tracking. + (default: 0) --tracking.pre_cull_iou_threshold TRACKING.PRE_CULL_IOU_THRESHOLD - If non-zero and pre_cull_to_target also set, then use - IOU threshold to remove overlapping instances over - count *before* tracking. (default: 0) + If non-zero and pre_cull_to_target also set, then use IOU threshold to remove overlapping instances over count *before* + tracking. (default: 0) --tracking.post_connect_single_breaks TRACKING.POST_CONNECT_SINGLE_BREAKS - If non-zero and target_instance_count is also non- - zero, then connect track breaks when exactly one track - is lost and exactly one track is spawned in frame. - (default: 0) + If non-zero and target_instance_count is also non-zero, then connect track breaks when exactly one track is lost and exactly + one track is spawned in frame. (default: 0) --tracking.clean_instance_count TRACKING.CLEAN_INSTANCE_COUNT - Target number of instances to clean *after* tracking. - (default: 0) + Target number of instances to clean *after* tracking. (default: 0) --tracking.clean_iou_threshold TRACKING.CLEAN_IOU_THRESHOLD - IOU to use when culling instances *after* tracking. - (default: 0) + IOU to use when culling instances *after* tracking. (default: 0) --tracking.similarity TRACKING.SIMILARITY - Options: instance, centroid, iou (default: instance) + Options: instance, normalized_instance, object_keypoint, centroid, iou (default: instance) --tracking.match TRACKING.MATCH Options: hungarian, greedy (default: greedy) + --tracking.robust TRACKING.ROBUST + Robust quantile of similarity score for instance matching. If equal to 1, keep the max similarity score (non-robust). + (default: 1) --tracking.track_window TRACKING.TRACK_WINDOW How many frames back to look for matches (default: 5) - --tracking.save_shifted_instances TRACKING.SAVE_SHIFTED_INSTANCES - For optical-flow: Save the shifted instances between - elapsed frames for optimal comparison (default: 0) --tracking.min_new_track_points TRACKING.MIN_NEW_TRACK_POINTS - Minimum number of instance points for spawning new - track (default: 0) + Minimum number of instance points for spawning new track (default: 0) --tracking.min_match_points TRACKING.MIN_MATCH_POINTS Minimum points for match candidates (default: 0) --tracking.img_scale TRACKING.IMG_SCALE For optical-flow: Image scale (default: 1.0) --tracking.of_window_size TRACKING.OF_WINDOW_SIZE - For optical-flow: Optical flow window size to consider - at each pyramid (default: 21) + For optical-flow: Optical flow window size to consider at each pyramid (default: 21) --tracking.of_max_levels TRACKING.OF_MAX_LEVELS - For optical-flow: Number of pyramid scale levels to - consider (default: 3) + For optical-flow: Number of pyramid scale levels to consider (default: 3) + --tracking.save_shifted_instances TRACKING.SAVE_SHIFTED_INSTANCES + If non-zero and tracking.tracker is set to flow, save the shifted instances between elapsed frames (default: 0) --tracking.kf_node_indices TRACKING.KF_NODE_INDICES - For Kalman filter: Indices of nodes to track. - (default: ) + For Kalman filter: Indices of nodes to track. (default: ) --tracking.kf_init_frame_count TRACKING.KF_INIT_FRAME_COUNT - For Kalman filter: Number of frames to track with - other tracker. 0 means no Kalman filters will be used. - (default: 0) + For Kalman filter: Number of frames to track with other tracker. 0 means no Kalman filters will be used. (default: 0) +``` + +#### Examples: + +**1. Simple inference without tracking:** + +```none +sleap-track -m "models/my_model" -o "output_predictions.slp" "input_video.mp4" +``` + +**2. Inference with multi-model pipelines (e.g., top-down):** + +```none +sleap-track -m "models/centroid" -m "models/centered_instance" -o "output_predictions.slp" "input_video.mp4" +``` + +**3. Inference on suggested frames of a labeling project:** + +```none +sleap-track -m "models/my_model" --only-suggested-frames -o "labels_with_predictions.slp" "labels.v005.slp" +``` + +The resulting `labels_with_predictions.slp` can then merged into the base labels project from the SLEAP GUI via **File** --> **Merge into project...**. + +**4. Inference with simple tracking:** + +```none +sleap-track -m "models/my_model" --tracking.tracker simple -o "output_predictions.slp" "input_video.mp4" +``` + +**5. Inference with max tracks limit:** + +```none +sleap-track -m "models/my_model" --tracking.tracker simplemaxtracks --tracking.max_tracking 1 --tracking.max_tracks 4 -o "output_predictions.slp" "input_video.mp4" +``` + +**6. Re-tracking without pose inference:** + +```none +sleap-track --tracking.tracker simplemaxtracks --tracking.max_tracking 1 --tracking.max_tracks 4 -o "retracked.slp" "input_predictions.slp" +``` + +**7. Select GPU for pose inference:** + +```none +sleap-track --gpu 1 ... +``` + +**8. Select subset of frames to predict on:** + +```none +sleap-track -m "models/my_model" --frames 1000-2000 "input_video.mp4" ``` ## Dataset files @@ -275,8 +326,10 @@ optional arguments: only a single --output argument was specified, the analysis file for the latter video is given a default name. --format FORMAT Output format. Default ('slp') is SLEAP dataset; - 'analysis' results in analysis.h5 file; 'h5' or 'json' - results in SLEAP dataset with specified file format. + 'analysis' results in analysis.h5 file; 'analysis.nix' results + in an analysis nix file; 'analysis.csv' results + in an analysis csv file; 'h5' or 'json' results in SLEAP dataset + with specified file format. --video VIDEO Path to video (if needed for conversion). ``` @@ -324,13 +377,27 @@ optional arguments: -h, --help show this help message and exit -o OUTPUT, --output OUTPUT Path for saving output (default: None) + --video-index VIDEO_INDEX + Index of video in labels dataset (default: 0) + --frames FRAMES List of frames to predict. Either comma separated list (e.g. 1,2,3) + or a range separated by hyphen (e.g. 1-3). (default is entire video) -f FPS, --fps FPS Frames per second for output video (default: 25) --scale SCALE Output image scale (default: 1.0) --crop CROP Crop size as , (default: None) - --frames FRAMES List of frames to predict. Either comma separated list (e.g. 1,2,3) - or a range separated by hyphen (e.g. 1-3). (default is entire video) - -video-index VIDEO_INDEX - Index of video in labels dataset (default: 0) + --show_edges SHOW_EDGES + Whether to draw lines between nodes (default: 1) + --edge_is_wedge EDGE_IS_WEDGE + Whether to draw edges as wedges (default: 0) + --marker_size MARKER_SIZE + Size of marker in pixels before scaling by SCALE (default: 4) + --palette PALETTE SLEAP color palette to use. Options include: "alphabet", "five+", + "solarized", or "standard" (default: "standard") + --distinctly_color DISTINCTLY_COLOR + Specify how to color instances. Options include: "instances", + "edges", and "nodes" (default: "instances") + --background BACKGROUND + Specify the type of background to be used to save the videos. + Options: original, black, white and grey. (default: "original") ``` ## Debugging diff --git a/docs/guides/gui.md b/docs/guides/gui.md index 88cf3f656..813ed68fa 100644 --- a/docs/guides/gui.md +++ b/docs/guides/gui.md @@ -60,7 +60,7 @@ Note that many of the menu command have keyboard shortcuts which can be configur "**Edge Style**" controls whether edges are drawn as thin lines or as wedges which indicate the {ref}`orientation` of the instance (as well as the direction of the part affinity field which would be used to predict the connection between nodes when using a "bottom-up" approach). -"**Trail Length**" allows you to show a trail of where each instance was located in prior frames (the length of the trail is the number of prior frames). This can be useful when proofreading predictions since it can help you detect swaps in the identities of animals across frames. +"**Trail Length**" allows you to show a trail of where each instance was located in prior frames (the length of the trail is the number of prior frames). This can be useful when proofreading predictions since it can help you detect swaps in the identities of animals across frames. By default, you can only select trail lengths of up to 250 frames. You can use a custom trail length by modifying the default length in the `preferences.yaml` file. However, using trail lengths longer than about 500 frames can result in significant lag. "**Fit Instances to View**" allows you to toggle whether the view is auto-zoomed to the instances in each frame. This can be useful when proofreading predictions. diff --git a/docs/guides/index.md b/docs/guides/index.md index 7eb55b2b2..6d773d9de 100644 --- a/docs/guides/index.md +++ b/docs/guides/index.md @@ -30,6 +30,10 @@ {ref}`remote-inference` when you trained models and you want to run inference on a different machine using a **command-line interface**. +## SLEAP with Bonsai + +{ref}`bonsai` when you want to analyze the trained SLEAP model to visualize the poses, centroids and identities for further visual analysis. + ```{toctree} :hidden: true :maxdepth: 2 @@ -44,4 +48,5 @@ proofreading colab custom-training remote +bonsai ``` diff --git a/docs/guides/proofreading.md b/docs/guides/proofreading.md index fea1c5ebc..941b85154 100644 --- a/docs/guides/proofreading.md +++ b/docs/guides/proofreading.md @@ -50,6 +50,8 @@ There are currently three methods for matching instances in frame N against thes - “**centroid**” measures similarity by the distance between the instance centroids - “**iou**” measures similarity by the intersection/overlap of the instance bounding boxes - “**instance**” measures similarity by looking at the distances between corresponding nodes in the instances, normalized by the number of valid nodes in the candidate instance. +- “**normalized_instance**” measures similarity by looking at the distances between corresponding nodes in the instances, normalized by the number of valid nodes in the candidate instance and the keypoints normalized by the image size. +- “**object_keypoint**” measures similarity by measuring the distance between each keypoints from a reference instance and a query instance, takes the exp(-d**2), sum for all the keypoints and divide by the number of visible keypoints in the reference instance. Once SLEAP has measured the similarity between all the candidates and the instances in frame N, you need to choose a way to pair them up. You can do this either by picking the best match, and the picking the best remaining match for each remaining instance in turn—this is “**greedy**” matching—or you can find the way of matching identities which minimizes the total cost (or: maximizes the total similarity)—this is “**Hungarian**” matching. diff --git a/docs/help.md b/docs/help.md index fa37d8904..cd41a5e59 100644 --- a/docs/help.md +++ b/docs/help.md @@ -79,3 +79,58 @@ Or [open an issue](https://github.com/talmolab/sleap/issues) and we'll get back SLEAP is a complex machine learning system intended for general use, so it's possible that we failed to consider the specifics of the situation in which you may be interested in using it with. Feel free to reach out to us at `talmo@salk.edu` if you have a question that isn't covered here. + +## Improving SLEAP + +### How can I help improve SLEAP? + +- Tell your friends about SLEAP! We also love to hear stories about what worked or didn't work, or your experience if you came from other software tools (`talmo@salk.edu`). + +- [Cite our paper](https://www.nature.com/articles/s41592-022-01426-1)! Here's a BibTeX citation for your reference manager: + + ``` + @ARTICLE{Pereira2022sleap, + title={SLEAP: A deep learning system for multi-animal pose tracking}, + author={Pereira, Talmo D and + Tabris, Nathaniel and + Matsliah, Arie and + Turner, David M and + Li, Junyu and + Ravindranath, Shruthi and + Papadoyannis, Eleni S and + Normand, Edna and + Deutsch, David S and + Wang, Z. Yan and + McKenzie-Smith, Grace C and + Mitelut, Catalin C and + Castro, Marielisa Diez and + D'Uva, John and + Kislin, Mikhail and + Sanes, Dan H and + Kocher, Sarah D and + Samuel S-H and + Falkner, Annegret L and + Shaevitz, Joshua W and + Murthy, Mala}, + journal={Nature Methods}, + volume={19}, + number={4}, + year={2022}, + publisher={Nature Publishing Group} + } + } + ``` + +- Share new ideas for new features or improvements in the [Discussion forum](https://github.com/talmolab/sleap/discussions/categories/ideas). + +- Contribute some code! See our [contribution guidelines](https://sleap.ai/CONTRIBUTING.html) for more info. + + +(usage-data)= +### What is usage data? + +To help us improve SLEAP, you may allow us to collect basic and **anonymous** usage data. If enabled from the **Help** menu, the SLEAP GUI will transmit information such as which version of Python and operating system you are running SLEAP on. + +This helps us understand on which types of computers SLEAP is being used so we can ensure that our software is maximally accessible to the broadest userbase possible, for example, by telling us whether it's safe to update our dependencies without breaking SLEAP for most users. Collecting usage data also helps us get a sense for how often SLEAP is being used so that we can report its impact to external grant funding agencies. + +You can opt out at any time from the menu (this preference will be stored). If you want to prevent these data from being shared with us, you can launch the GUI with `sleap-label --no-usage-data`. Usage data is only shared when the GUI is used, not the API or CLIs. You can check out the [source code](https://github.com/talmolab/sleap/blob/main/sleap/gui/web.py) to see exactly what data is collected. \ No newline at end of file diff --git a/docs/installation.md b/docs/installation.md index 597757095..2c1ef41be 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,10 +1,21 @@ # Installation -SLEAP can be installed as a Python package on Windows, Linux and Mac OS X. We currently provide {ref}`experimental support for M1 Macs `. +SLEAP can be installed as a Python package on Windows, Linux, and Mac OS. For quick install using conda, see below: -SLEAP requires many complex dependencies, so we **strongly** recommend using [Miniconda](https://docs.conda.io/en/latest/miniconda.html) to install it in its own isolated environment. See {ref}`Installing Miniconda` below for more instructions. +````{tabs} + ```{group-tab} Windows and Linux + ```bash + conda create -y -n sleap -c conda-forge -c nvidia -c sleap/label/dev -c sleap -c anaconda sleap=1.4.1 + ``` + ``` + ```{group-tab} Mac OS + ```bash + conda create -y -n sleap -c conda-forge -c anaconda -c sleap sleap=1.4.1 + ``` + ``` +```` -The newest version of SLEAP can always be found in the [Releases page](https://github.com/talmolab/sleap/releases). +. For more in-depth installation instructions, see the [installation methods](installation-methods). The newest version of SLEAP can always be found in the [Releases page](https://github.com/talmolab/sleap/releases). ```{contents} Contents --- @@ -12,180 +23,239 @@ local: --- ``` -(miniconda)= - -## Installing Miniconda - -**Anaconda** is a Python environment manager that makes it easy to install SLEAP and its necessary dependencies without affecting other Python software on your computer. - -**Miniconda** is a lightweight version of Anaconda that we recommend. To install it: - -1. Go to: https://docs.conda.io/en/latest/miniconda.html#latest-miniconda-installer-links -2. Download the latest version for your OS. -3. Follow the installer instructions. - -**On Windows**, just click through the installation steps. We recommend using the following settings: - -- Install for: All Users (requires admin privileges) -- Destination folder: `C:\Miniconda3` -- Advanced Options: Add Miniconda3 to the system PATH environment variable -- Advanced Options: Register Miniconda3 as the system Python 3.X - These will make sure that Anaconda is easily accessible from most places on your computer. - -**On Linux**, it might be easier to do this straight from the terminal (Ctrl + Alt + T) with this one-liner: - -```bash -wget -nc https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh && bash Miniconda3-latest-Linux-x86_64.sh -b && ~/miniconda3/bin/conda init bash -``` - -Restart the terminal after running this command. - -**On Macs**, you can run the graphical installer using the pkg file, or this terminal command: +`````{hint} + Installation requires entering commands in a terminal. To open one: + ````{tabs} + ```{tab} Windows + Open the *Start menu* and search for the *Anaconda Prompt* (if using Miniconda) or the *Command Prompt* if not. + ```{note} + On Windows, our personal preference is to use alternative terminal apps like [Cmder](https://cmder.net) or [Windows Terminal](https://aka.ms/terminal). + ``` + ``` + ```{tab} Linux + Launch a new terminal by pressing Ctrl + Alt + T. + ``` + ```{group-tab} Mac OS + Launch a new terminal by pressing Cmd + Space and searching for _Terminal_. + ``` + ```` +````` + +## Package Manager + +SLEAP requires many complex dependencies, so we **strongly** recommend using a package manager such as [Miniforge](https://github.com/conda-forge/miniforge) or [Miniconda](https://docs.anaconda.com/free/miniconda/) to install SLEAP in its own isolated environment. + +````{note} +If you already have Anaconda on your computer (and it is an [older installation](https://conda.org/blog/2023-11-06-conda-23-10-0-release/)), then make sure to [set the solver to `libmamba`](https://www.anaconda.com/blog/a-faster-conda-for-a-growing-community) in the `base` environment. ```bash -wget -nc https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh && bash Miniconda3-latest-MacOSX-x86_64.sh -b && ~/miniconda3/bin/conda init zsh +conda update -n base conda +conda install -n base conda-libmamba-solver +conda config --set solver libmamba ``` -## Installation methods - -````{hint} -Installation requires entering commands in a terminal. To open one: - -**Windows:** Open the *Start menu* and search for the *Anaconda Command Prompt* (if using Miniconda) or the *Command Prompt* if not. -```{note} -On Windows, our personal preference is to use alternative terminal apps like [Cmder](https://cmder.net) or [Windows Terminal](https://aka.ms/terminal). +```{warning} +Any subsequent `conda` commands in the docs will need to be replaced with `mamba` if you have [Mamba](https://mamba.readthedocs.io/en/latest/) installed instead of Anaconda or Miniconda. ``` -**Linux:** Launch a new terminal by pressing Ctrl + Alt + T. - -**Mac:** Launch a new terminal by pressing Cmd + Space and searching for *Terminal*. ```` -### `conda` package - -```bash -conda create -y -n sleap -c sleap -c nvidia -c conda-forge sleap=1.2.7 -``` - -**This is the recommended installation method**. Works on **Windows** and **Linux**. +If you don't have a `conda` package manager installation, here are some quick install options: -```{note} -- This comes with CUDA to enable GPU support. All you need is to have an NVIDIA GPU and [updated drivers](https://nvidia.com/drivers). -- If you already have CUDA installed on your system, this will not conflict with it. -- This will also work in CPU mode if you don't have a GPU on your machine. -``` +### Miniforge (recommended) -### `conda` from source +Miniforge is a minimal installer for conda that includes the `conda` package manager and is maintained by the [conda-forge](https://conda-forge.org) community. The only difference between Miniforge and Miniconda is that Miniforge uses the `conda-forge` channel by default, which provides a much wider selection of community-maintained packages. -1. First, ensure git is installed: +````{tabs} + ```{group-tab} Windows + Open a new PowerShell terminal (does not need to be admin) and enter: - ```bash - git --version + ```bash + Invoke-WebRequest -Uri "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Windows-x86_64.exe" -OutFile "$env:UserProfile/Downloads/Miniforge3-Windows-x86_64.exe"; Start-Process -FilePath "$env:UserProfile/Downloads/Miniforge3-Windows-x86_64.exe" -ArgumentList "/InstallationType=JustMe /RegisterPython=1 /S" -Wait; Remove-Item -Path "$env:UserProfile/Downloads/Miniforge3-Windows-x86_64.exe" + ``` ``` + ```{group-tab} Linux + Open a new terminal and enter: - If 'git' is not recognized, then [install git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git). - -2. Then, clone the repository: - - ```bash - git clone https://github.com/talmolab/sleap && cd sleap + ```bash + curl -fsSL --compressed https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh -o "~/Downloads/Miniforge3-Linux-x86_64.sh" && chmod +x "~/Downloads/Miniforge3-Linux-x86_64.sh" && "~/Downloads/Miniforge3-Linux-x86_64.sh" -b -p ~/miniforge3 && rm "~/Downloads/Miniforge3-Linux-x86_64.sh" && ~/miniforge3/bin/conda init "$(basename "${SHELL}")" && source "$HOME/.$(basename "${SHELL}")rc" + ``` ``` + ```{group-tab} Mac (Apple Silicon) + Open a new terminal and enter: -3. Finally, install from the environment file: - - ```bash - conda env create -f environment.yml -n sleap + ```bash + curl -fsSL --compressed https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-arm64.sh -o "~/Downloads/Miniforge3-MacOSX-arm64.sh" && chmod +x "~/Downloads/Miniforge3-MacOSX-arm64.sh" && "~/Downloads/Miniforge3-MacOSX-arm64.sh" -b -p ~/miniforge3 && rm "~/Downloads/Miniforge3-MacOSX-arm64.sh" && ~/miniforge3/bin/conda init "$(basename "${SHELL}")" && source "$HOME/.$(basename "${SHELL}")rc" + ``` ``` + ```{group-tab} Mac (Intel) + Open a new terminal and enter: - If you do not have a NVIDIA GPU, then you should use the no CUDA environment file: - - ```bash - conda env create -f environment_no_cuda.yml -n sleap + ```bash + curl -fsSL --compressed https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-MacOSX-x86_64.sh -o "~/Downloads/Miniforge3-MacOSX-x86_64.sh" && chmod +x "~/Downloads/Miniforge3-MacOSX-x86_64.sh" && "~/Downloads/Miniforge3-MacOSX-x86_64.sh" -b -p ~/miniforge3 && rm "~/Downloads/Miniforge3-MacOSX-x86_64.sh" && ~/miniforge3/bin/conda init "$(basename "${SHELL}")" && source "$HOME/.$(basename "${SHELL}")rc" + ``` ``` +```` - This works on **Windows**, **Linux** and **Mac OS X** (pre-M1). This is the **recommended method for development**. - -```{note} -- This installs SLEAP in development mode, which means that edits to the source code will be applied the next time you run SLEAP. -- Change the `-n sleap` in the command to create an environment with a different name (e.g., `-n sleap_develop`). -``` - -### `pip` package - -```bash -pip install sleap==1.2.7 -``` - -This works on **any OS** and on **Google Colab**. - -```{note} -- Requires Python 3.7 or 3.8. -- To enable GPU support, make sure that you have **CUDA Toolkit v11.3** and **cuDNN v8.2** installed. -``` - -```{warning} -This will uninstall existing libraries and potentially install conflicting ones. - -We strongly recommend that you **only use this method if you know what you're doing**! -``` - -(m1mac)= - -### M1 Macs - -SLEAP can be installed on newer M1 Macs by following these instructions: +### Miniconda -1. In addition to being on an M1 Mac, make sure you're on **macOS Monterey**, i.e., version 12+. We've tested this on a MacBook Pro (14-inch, 2021) running macOS version 12.0.1. +This is a minimal installer for conda that includes the `conda` package manager and is maintained by the [Anaconda](https://www.anaconda.com) company. -2. If you don't have it yet, install **homebrew**, a convenient package manager for Macs (skip this if you can run `brew` from the terminal): +````{tabs} + ```{group-tab} Windows + Open a new PowerShell terminal (does not need to be admin) and enter: - ```bash - /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + ```bash + curl https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe -o miniconda.exe; Start-Process -FilePath ".\miniconda.exe" -ArgumentList "/S" -Wait; del miniconda.exe + ``` ``` + ```{group-tab} Linux + Open a new terminal and enter: - This might take a little while since it'll also install Xcode (which we'll need later). Once it's finished, run this to enable the `brew` command in your shell, then close and re-open the terminal for it to take effect: - - ```bash - echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile && eval "$(/opt/homebrew/bin/brew shellenv)" + ```bash + mkdir -p ~/miniconda3 && wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh && bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3 && rm ~/miniconda3/miniconda.sh && ~/miniconda3/bin/conda init "$(basename "${SHELL}")" && source "$HOME/.$(basename "${SHELL}")rc" + ``` ``` + ```{group-tab} Mac (Apple Silicon) + Open a new terminal and enter: -3. Install wget, a CLI downloading utility (also makes sure your homebrew setup worked): - - ```bash - brew install wget + ```bash + curl -fsSL --compressed https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh -o "~/Downloads/Miniconda3-latest-MacOSX-arm64.sh" && chmod +x "~/Downloads/Miniconda3-latest-MacOSX-arm64.sh" && "~/Downloads/Miniconda3-latest-MacOSX-arm64.sh" -b -u -p ~/miniconda3 && rm "~/Downloads/Miniconda3-latest-MacOSX-arm64.sh" && ~/miniconda3/bin/conda init "$(basename "${SHELL}")" && source "$HOME/.$(basename "${SHELL}")rc" + ``` ``` + ```{group-tab} Mac (Intel) + Open a new terminal and enter: -4. Install the **M1 Mac version of Miniconda** -- this is important, so make sure you don't have the regular Mac version! If you're not sure, type `which conda` and delete the containing directory to uninstall your existing conda. To install the correct Miniconda, just run: - - ```bash - wget -nc https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh && bash Miniconda3-latest-MacOSX-arm64.sh -b && rm Miniconda3-latest-MacOSX-arm64.sh && ~/miniconda3/bin/conda init zsh + ```bash + curl -fsSL --compressed https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -o "~/Downloads/Miniconda3-latest-MacOSX-x86_64.sh" && chmod +x "~/Downloads/Miniconda3-latest-MacOSX-x86_64.sh" && "~/Downloads/Miniconda3-latest-MacOSX-x86_64.sh" -b -u -p ~/miniconda3 && rm "~/Downloads/Miniconda3-latest-MacOSX-x86_64.sh" && ~/miniconda3/bin/conda init "$(basename "${SHELL}")" && source "$HOME/.$(basename "${SHELL}")rc" + ``` ``` +```` - Then close and re-open the terminal again. +See the [Miniconda website](https://docs.anaconda.com/free/miniconda/) for up-to-date installation instructions if the above instructions don't work for your system. -5. **Download the SLEAP**: +(installation-methods)= - ```bash - cd ~ && git clone https://github.com/talmolab/sleap.git sleap && cd sleap - ``` +## Installation methods -6. **Install SLEAP in a conda environment**: +SLEAP can be installed three different ways: via {ref}`conda package`, {ref}`conda from source`, or {ref}`pip package`. Select one of the methods below to install SLEAP. We recommend {ref}`conda package`. + +`````{tabs} + ```{tab} conda package + **This is the recommended installation method**. + ````{tabs} + ```{group-tab} Windows and Linux + ```bash + conda create -y -n sleap -c conda-forge -c nvidia -c sleap/label/dev -c sleap -c anaconda sleap=1.4.1 + ``` + ```{note} + - This comes with CUDA to enable GPU support. All you need is to have an NVIDIA GPU and [updated drivers](https://nvidia.com/drivers). + - If you already have CUDA installed on your system, this will not conflict with it. + - This will also work in CPU mode if you don't have a GPU on your machine. + ``` + ``` + ```{group-tab} Mac OS + ```bash + conda create -y -n sleap -c conda-forge -c anaconda -c sleap sleap=1.4.1 + ``` + ```{note} + This will also work in CPU mode if you don't have a GPU on your machine. + ``` + ``` + ```` - ```bash - conda env create -f environment_m1.yml ``` - - Your Mac will then automatically sign a devil's pact with Apple to install the correct versions of everything on your system. Once the blood sacrifice/installation process completes, SLEAP will be available in an environment called `sleap`. - - _Note:_ This installs SLEAP in development mode, so changes to the source code are immediately applied in case you wanted to mess around with it. You can also just do a `git pull` to update it (no need to re-do any of the previous steps). - -7. **Test it out** by activating the environment and opening the GUI! - ```bash - conda activate sleap + ```{tab} conda from source + This is the **recommended method for development**. + 1. First, ensure git is installed: + ```bash + git --version + ``` + If `git` is not recognized, then [install git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git). + 2. Then, clone the repository: + ```bash + git clone https://github.com/talmolab/sleap && cd sleap + ``` + 3. Finally, install SLEAP from the environment file: + ````{tabs} + ```{group-tab} Windows and Linux + ````{tabs} + ```{group-tab} NVIDIA GPU + ```bash + conda env create -f environment.yml -n sleap + ``` + ``` + ```{group-tab} CPU or other GPU + ```bash + conda env create -f environment_no_cuda.yml -n sleap + ``` + ``` + ```` + ``` + ```{group-tab} Mac OS + ```bash + conda env create -f environment_mac.yml -n sleap + ``` + ``` + ```` + ```{note} + - This installs SLEAP in development mode, which means that edits to the source code will be applied the next time you run SLEAP. + - Change the `-n sleap` in the command to create an environment with a different name (e.g., `-n sleap_develop`). + ``` ``` - ```bash - sleap-label + ```{tab} pip package + This is the **recommended method for Google Colab only**. + ```{warning} + This will uninstall existing libraries and potentially install conflicting ones. + + We strongly recommend that you **only use this method if you know what you're doing**! + ``` + ````{tabs} + ```{group-tab} Windows and Linux + ```{note} + - Requires Python 3.7 + - To enable GPU support, make sure that you have **CUDA Toolkit v11.3** and **cuDNN v8.2** installed. + ``` + Although you do not need Miniconda installed to perform a `pip install`, we recommend [installing Miniconda](https://docs.anaconda.com/free/miniconda/) to create a new environment where we can isolate the `pip install`. Alternatively, you can use a venv if you have an existing Python 3.7 installation. If you are working on **Google Colab**, skip to step 3 to perform the `pip install` without using a conda environment. + 1. Otherwise, create a new conda environment where we will `pip install sleap`: + ````{tabs} + ```{group-tab} NVIDIA GPU + ```bash + conda create --name sleap pip python=3.7.12 cudatoolkit=11.3 cudnn=8.2 -c conda-forge -c nvidia + ``` + ``` + ```{group-tab} CPU or other GPU + ```bash + conda create --name sleap pip python=3.7.12 + ``` + ``` + ```` + 2. Then activate the environment to isolate the `pip install` from other environments on your computer: + ```bash + conda activate sleap + ``` + ```{warning} + Refrain from installing anything into the `base` environment. Always create a new environment to install new packages. + ``` + 3. Finally, we can perform the `pip install`: + ```bash + pip install sleap[pypi]==1.4.1 + ``` + ```{note} + The pypi distributed package of SLEAP ships with the following extras: + - **pypi**: For installation without an conda environment file. All dependencies come from PyPI. + - **jupyter**: This installs all *pypi* and jupyter lab dependencies. + - **dev**: This installs all *jupyter* dependencies and developement tools for testing and building docs. + - **conda_jupyter**: For installation using a conda environment file included in the source code. Most dependencies are listed as conda packages in the environment file and only a few come from PyPI to allow jupyter lab support. + - **conda_dev**: For installation using [a conda environment](https://github.com/search?q=repo%3Atalmolab%2Fsleap+path%3Aenvironment*.yml&type=code) with a few PyPI dependencies for development tools. + ``` + ``` + ```{group-tab} Mac OS + Not supported. + ``` + ```` ``` +````` ## Testing that things are working @@ -273,10 +343,45 @@ python -c "import tensorflow as tf; print(tf.config.list_physical_devices('GPU') ````{warning} TensorFlow 2.7+ is currently failing to detect CUDA Toolkit and CuDNN on some systems (see [Issue thread](https://github.com/tensorflow/tensorflow/issues/52988)). -If you run into issues, try downgrading the TensorFlow 2.6: +If you run into issues, either try downgrading the TensorFlow 2.6: ```bash pip install tensorflow==2.6.3 ``` +or follow the note below. +```` + +````{note} +If you are on Linux, have a NVIDIA GPU, but cannot detect your GPU: + +```bash +W tensorflow/stream_executor/platform/default/dso_loader.cc:64 Could not load dynamic +library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object +file: No such file or directory +``` + +then activate the environment: + +```bash +conda activate sleap +``` + +and run the commands: +```bash +mkdir -p $CONDA_PREFIX/etc/conda/activate.d +echo '#!/bin/sh' >> $CONDA_PREFIX/etc/conda/activate.d/sleap_activate.sh +echo 'export SLEAP_OLD_LD_LIBRARY_PATH=$LD_LIBRARY_PATH' >> $CONDA_PREFIX/etc/conda/activate.d/sleap_activate.sh +echo 'export LD_LIBRARY_PATH=$CONDA_PREFIX/lib:$LD_LIBRARY_PATH' >> $CONDA_PREFIX/etc/conda/activate.d/sleap_activate.sh +source $CONDA_PREFIX/etc/conda/activate.d/sleap_activate.sh +``` + +This will set the environment variable `LD_LIBRARY_PATH` each time the environment is activated. The environment variable will remain set in the current terminal even if we deactivate the environment. Although not strictly necessary, if you would also like the environment variable to be reset to the original value when deactivating the environment, we can run the following commands: +```bash +mkdir -p $CONDA_PREFIX/etc/conda/deactivate.d +echo '#!/bin/sh' >> $CONDA_PREFIX/etc/conda/deactivate.d/sleap_deactivate.sh +echo 'export LD_LIBRARY_PATH=$SLEAP_OLD_LD_LIBRARY_PATH' >> $CONDA_PREFIX/etc/conda/deactivate.d/sleap_deactivate.sh +``` + +These commands only need to be run once and will subsequently run automatically upon [de]activating your `sleap` environment. ```` ## Upgrading and uninstalling diff --git a/docs/make_api_doctree.py b/docs/make_api_doctree.py index a507070d7..68de7ba95 100644 --- a/docs/make_api_doctree.py +++ b/docs/make_api_doctree.py @@ -10,6 +10,7 @@ "sleap.version", ] + def make_api_doctree(): doctree = "" @@ -42,4 +43,4 @@ def make_api_doctree(): if __name__ == "__main__": - make_api_doctree() \ No newline at end of file + make_api_doctree() diff --git a/docs/notebooks/Data_structures.ipynb b/docs/notebooks/Data_structures.ipynb index 7eb9a552c..ff0ea2d3d 100644 --- a/docs/notebooks/Data_structures.ipynb +++ b/docs/notebooks/Data_structures.ipynb @@ -1,21 +1,4 @@ { - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "name": "SLEAP - Data structures.ipynb", - "provenance": [], - "collapsed_sections": [] - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" - }, - "accelerator": "GPU" - }, "cells": [ { "cell_type": "markdown", @@ -29,6 +12,9 @@ }, { "cell_type": "markdown", + "metadata": { + "id": "NqgGonrTRLg9" + }, "source": [ "# Data structures\n", "\n", @@ -41,10 +27,7 @@ "- `Skeleton` → Defines the nodes and edges that define the set of unique landmark types that each point represents, e.g., \"head\", \"tail\", etc. This *does not contain positions* -- those are stored in individual `Point`s.\n", "- `LabeledFrame` → Contains a set of `Instance`/`PredictedInstance`s for a single frame.\n", "- `Labels` → Contains a set of `LabeledFrame`s and the associated metadata for the videos and other information related to the project or predictions." - ], - "metadata": { - "id": "NqgGonrTRLg9" - } + ] }, { "cell_type": "markdown", @@ -61,6 +44,7 @@ }, { "cell_type": "code", + "execution_count": 1, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -68,179 +52,19 @@ "id": "3GTiapGASisF", "outputId": "c7ce8c05-a473-4995-8cab-0f20d04a52b1" }, + "outputs": [], "source": [ "# This should take care of all the dependencies on colab:\n", - "!pip uninstall -y opencv-python opencv-contrib-python && pip install sleap\n", + "!pip uninstall -qqq -y opencv-python opencv-contrib-python\n", + "!pip install -qqq \"sleap[pypi]>=1.3.3\"\n", "\n", "# But to do it locally, we'd recommend the conda package (available on Windows + Linux):\n", "# conda create -n sleap -c sleap -c conda-forge -c nvidia sleap" - ], - "execution_count": 1, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Found existing installation: opencv-python 4.1.2.30\n", - "Uninstalling opencv-python-4.1.2.30:\n", - " Successfully uninstalled opencv-python-4.1.2.30\n", - "Found existing installation: opencv-contrib-python 4.1.2.30\n", - "Uninstalling opencv-contrib-python-4.1.2.30:\n", - " Successfully uninstalled opencv-contrib-python-4.1.2.30\n", - "Collecting sleap\n", - " Downloading sleap-1.2.2-py3-none-any.whl (62.0 MB)\n", - "\u001b[K |████████████████████████████████| 62.0 MB 1.1 MB/s \n", - "\u001b[?25hCollecting python-rapidjson\n", - " Downloading python_rapidjson-1.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.6 MB)\n", - "\u001b[K |████████████████████████████████| 1.6 MB 28.0 MB/s \n", - "\u001b[?25hCollecting opencv-python-headless<=4.5.5.62,>=4.2.0.34\n", - " Downloading opencv_python_headless-4.5.5.62-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (47.7 MB)\n", - "\u001b[K |████████████████████████████████| 47.7 MB 82 kB/s \n", - "\u001b[?25hRequirement already satisfied: h5py<=3.6.0,>=3.1.0 in /usr/local/lib/python3.7/dist-packages (from sleap) (3.1.0)\n", - "Collecting pykalman==0.9.5\n", - " Downloading pykalman-0.9.5.tar.gz (228 kB)\n", - "\u001b[K |████████████████████████████████| 228 kB 61.2 MB/s \n", - "\u001b[?25hRequirement already satisfied: seaborn in /usr/local/lib/python3.7/dist-packages (from sleap) (0.11.2)\n", - "Collecting attrs==21.2.0\n", - " Downloading attrs-21.2.0-py2.py3-none-any.whl (53 kB)\n", - "\u001b[K |████████████████████████████████| 53 kB 2.3 MB/s \n", - "\u001b[?25hCollecting imgstore==0.2.9\n", - " Downloading imgstore-0.2.9-py2.py3-none-any.whl (904 kB)\n", - "\u001b[K |████████████████████████████████| 904 kB 47.6 MB/s \n", - "\u001b[?25hRequirement already satisfied: pyzmq in /usr/local/lib/python3.7/dist-packages (from sleap) (22.3.0)\n", - "Collecting qimage2ndarray<=1.8.3,>=1.8.2\n", - " Downloading qimage2ndarray-1.8.3-py3-none-any.whl (11 kB)\n", - "Requirement already satisfied: networkx in /usr/local/lib/python3.7/dist-packages (from sleap) (2.6.3)\n", - "Collecting scikit-video\n", - " Downloading scikit_video-1.1.11-py2.py3-none-any.whl (2.3 MB)\n", - "\u001b[K |████████████████████████████████| 2.3 MB 51.0 MB/s \n", - "\u001b[?25hRequirement already satisfied: scikit-image in /usr/local/lib/python3.7/dist-packages (from sleap) (0.18.3)\n", - "Requirement already satisfied: pyyaml in /usr/local/lib/python3.7/dist-packages (from sleap) (3.13)\n", - "Requirement already satisfied: psutil in /usr/local/lib/python3.7/dist-packages (from sleap) (5.4.8)\n", - "Requirement already satisfied: numpy<=1.21.5,>=1.19.5 in /usr/local/lib/python3.7/dist-packages (from sleap) (1.21.5)\n", - "Requirement already satisfied: scipy<=1.7.3,>=1.4.1 in /usr/local/lib/python3.7/dist-packages (from sleap) (1.4.1)\n", - "Collecting rich==10.16.1\n", - " Downloading rich-10.16.1-py3-none-any.whl (214 kB)\n", - "\u001b[K |████████████████████████████████| 214 kB 63.7 MB/s \n", - "\u001b[?25hCollecting segmentation-models==1.0.1\n", - " Downloading segmentation_models-1.0.1-py3-none-any.whl (33 kB)\n", - "Collecting cattrs==1.1.1\n", - " Downloading cattrs-1.1.1-py3-none-any.whl (16 kB)\n", - "Requirement already satisfied: scikit-learn==1.0.* in /usr/local/lib/python3.7/dist-packages (from sleap) (1.0.2)\n", - "Requirement already satisfied: imageio<=2.15.0 in /usr/local/lib/python3.7/dist-packages (from sleap) (2.4.1)\n", - "Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from sleap) (1.3.5)\n", - "Requirement already satisfied: certifi<=2021.10.8,>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from sleap) (2021.10.8)\n", - "Collecting jsonpickle==1.2\n", - " Downloading jsonpickle-1.2-py2.py3-none-any.whl (32 kB)\n", - "Collecting PySide2<=5.14.1,>=5.13.2\n", - " Downloading PySide2-5.14.1-5.14.1-cp35.cp36.cp37.cp38-abi3-manylinux1_x86_64.whl (165.5 MB)\n", - "\u001b[K |████████████████████████████████| 165.5 MB 79 kB/s \n", - "\u001b[?25hCollecting imgaug==0.4.0\n", - " Downloading imgaug-0.4.0-py2.py3-none-any.whl (948 kB)\n", - "\u001b[K |████████████████████████████████| 948 kB 54.8 MB/s \n", - "\u001b[?25hCollecting jsmin\n", - " Downloading jsmin-3.0.1.tar.gz (13 kB)\n", - "Requirement already satisfied: tensorflow<2.9.0,>=2.6.3 in /usr/local/lib/python3.7/dist-packages (from sleap) (2.8.0)\n", - "Requirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (1.15.0)\n", - "Requirement already satisfied: matplotlib in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (3.2.2)\n", - "Collecting opencv-python\n", - " Downloading opencv_python-4.5.5.64-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (60.5 MB)\n", - "\u001b[K |████████████████████████████████| 60.5 MB 1.3 MB/s \n", - "\u001b[?25hRequirement already satisfied: Shapely in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (1.8.1.post1)\n", - "Requirement already satisfied: Pillow in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (7.1.2)\n", - "Requirement already satisfied: pytz in /usr/local/lib/python3.7/dist-packages (from imgstore==0.2.9->sleap) (2018.9)\n", - "Requirement already satisfied: python-dateutil in /usr/local/lib/python3.7/dist-packages (from imgstore==0.2.9->sleap) (2.8.2)\n", - "Requirement already satisfied: tzlocal in /usr/local/lib/python3.7/dist-packages (from imgstore==0.2.9->sleap) (1.5.1)\n", - "Collecting commonmark<0.10.0,>=0.9.0\n", - " Downloading commonmark-0.9.1-py2.py3-none-any.whl (51 kB)\n", - "\u001b[K |████████████████████████████████| 51 kB 8.0 MB/s \n", - "\u001b[?25hRequirement already satisfied: pygments<3.0.0,>=2.6.0 in /usr/local/lib/python3.7/dist-packages (from rich==10.16.1->sleap) (2.6.1)\n", - "Collecting colorama<0.5.0,>=0.4.0\n", - " Downloading colorama-0.4.4-py2.py3-none-any.whl (16 kB)\n", - "Requirement already satisfied: typing-extensions<5.0,>=3.7.4 in /usr/local/lib/python3.7/dist-packages (from rich==10.16.1->sleap) (3.10.0.2)\n", - "Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn==1.0.*->sleap) (3.1.0)\n", - "Requirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn==1.0.*->sleap) (1.1.0)\n", - "Collecting image-classifiers==1.0.0\n", - " Downloading image_classifiers-1.0.0-py3-none-any.whl (19 kB)\n", - "Collecting keras-applications<=1.0.8,>=1.0.7\n", - " Downloading Keras_Applications-1.0.8-py3-none-any.whl (50 kB)\n", - "\u001b[K |████████████████████████████████| 50 kB 6.9 MB/s \n", - "\u001b[?25hCollecting efficientnet==1.0.0\n", - " Downloading efficientnet-1.0.0-py3-none-any.whl (17 kB)\n", - "Requirement already satisfied: cached-property in /usr/local/lib/python3.7/dist-packages (from h5py<=3.6.0,>=3.1.0->sleap) (1.5.2)\n", - "Collecting shiboken2==5.14.1\n", - " Downloading shiboken2-5.14.1-5.14.1-cp35.cp36.cp37.cp38-abi3-manylinux1_x86_64.whl (847 kB)\n", - "\u001b[K |████████████████████████████████| 847 kB 52.6 MB/s \n", - "\u001b[?25hRequirement already satisfied: tifffile>=2019.7.26 in /usr/local/lib/python3.7/dist-packages (from scikit-image->sleap) (2021.11.2)\n", - "Requirement already satisfied: PyWavelets>=1.1.1 in /usr/local/lib/python3.7/dist-packages (from scikit-image->sleap) (1.3.0)\n", - "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->imgaug==0.4.0->sleap) (1.4.0)\n", - "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib->imgaug==0.4.0->sleap) (0.11.0)\n", - "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->imgaug==0.4.0->sleap) (3.0.7)\n", - "Requirement already satisfied: astunparse>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.6.3)\n", - "Requirement already satisfied: grpcio<2.0,>=1.24.3 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.44.0)\n", - "Requirement already satisfied: tensorflow-io-gcs-filesystem>=0.23.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (0.24.0)\n", - "Requirement already satisfied: keras<2.9,>=2.8.0rc0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (2.8.0)\n", - "Requirement already satisfied: absl-py>=0.4.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.0.0)\n", - "Requirement already satisfied: setuptools in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (57.4.0)\n", - "Requirement already satisfied: opt-einsum>=2.3.2 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (3.3.0)\n", - "Requirement already satisfied: protobuf>=3.9.2 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (3.17.3)\n", - "Requirement already satisfied: flatbuffers>=1.12 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (2.0)\n", - "Requirement already satisfied: google-pasta>=0.1.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (0.2.0)\n", - "Requirement already satisfied: wrapt>=1.11.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.14.0)\n", - "Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.1.0)\n", - "Requirement already satisfied: libclang>=9.0.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (13.0.0)\n", - "Collecting tf-estimator-nightly==2.8.0.dev2021122109\n", - " Downloading tf_estimator_nightly-2.8.0.dev2021122109-py2.py3-none-any.whl (462 kB)\n", - "\u001b[K |████████████████████████████████| 462 kB 57.3 MB/s \n", - "\u001b[?25hRequirement already satisfied: tensorboard<2.9,>=2.8 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (2.8.0)\n", - "Requirement already satisfied: keras-preprocessing>=1.1.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.1.2)\n", - "Requirement already satisfied: gast>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (0.5.3)\n", - "Requirement already satisfied: wheel<1.0,>=0.23.0 in /usr/local/lib/python3.7/dist-packages (from astunparse>=1.6.0->tensorflow<2.9.0,>=2.6.3->sleap) (0.37.1)\n", - "Requirement already satisfied: google-auth<3,>=1.6.3 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.35.0)\n", - "Requirement already satisfied: tensorboard-data-server<0.7.0,>=0.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.6.1)\n", - "Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.0.1)\n", - "Requirement already satisfied: tensorboard-plugin-wit>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.8.1)\n", - "Requirement already satisfied: requests<3,>=2.21.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (2.23.0)\n", - "Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.4.6)\n", - "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.3.6)\n", - "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (4.8)\n", - "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.2.8)\n", - "Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (4.2.4)\n", - "Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.7/dist-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.3.1)\n", - "Requirement already satisfied: importlib-metadata>=4.4 in /usr/local/lib/python3.7/dist-packages (from markdown>=2.6.8->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (4.11.3)\n", - "Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata>=4.4->markdown>=2.6.8->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.7.0)\n", - "Requirement already satisfied: pyasn1<0.5.0,>=0.4.6 in /usr/local/lib/python3.7/dist-packages (from pyasn1-modules>=0.2.1->google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.4.8)\n", - "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.0.4)\n", - "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.24.3)\n", - "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (2.10)\n", - "Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.7/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.2.0)\n", - "Building wheels for collected packages: pykalman, jsmin\n", - " Building wheel for pykalman (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Created wheel for pykalman: filename=pykalman-0.9.5-py3-none-any.whl size=48462 sha256=a06494160ef192a795ebcc248474d9c759e93594f237a46d572d71045302de71\n", - " Stored in directory: /root/.cache/pip/wheels/6a/04/02/2dda6ea59c66d9e685affc8af3a31ad3a5d87b7311689efce6\n", - " Building wheel for jsmin (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Created wheel for jsmin: filename=jsmin-3.0.1-py3-none-any.whl size=13782 sha256=11175f12c4cdb3583f65125aa1f875e232ab437f5d9bdf1a6a73fbdb3d9ba69a\n", - " Stored in directory: /root/.cache/pip/wheels/a4/0b/64/fb4f87526ecbdf7921769a39d91dcfe4860e621cf15b8250d6\n", - "Successfully built pykalman jsmin\n", - "Installing collected packages: keras-applications, tf-estimator-nightly, shiboken2, opencv-python, image-classifiers, efficientnet, commonmark, colorama, attrs, segmentation-models, scikit-video, rich, qimage2ndarray, python-rapidjson, PySide2, pykalman, opencv-python-headless, jsonpickle, jsmin, imgstore, imgaug, cattrs, sleap\n", - " Attempting uninstall: attrs\n", - " Found existing installation: attrs 21.4.0\n", - " Uninstalling attrs-21.4.0:\n", - " Successfully uninstalled attrs-21.4.0\n", - " Attempting uninstall: imgaug\n", - " Found existing installation: imgaug 0.2.9\n", - " Uninstalling imgaug-0.2.9:\n", - " Successfully uninstalled imgaug-0.2.9\n", - "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", - "datascience 0.10.6 requires folium==0.2.1, but you have folium 0.8.3 which is incompatible.\n", - "albumentations 0.1.12 requires imgaug<0.2.7,>=0.2.5, but you have imgaug 0.4.0 which is incompatible.\u001b[0m\n", - "Successfully installed PySide2-5.14.1 attrs-21.2.0 cattrs-1.1.1 colorama-0.4.4 commonmark-0.9.1 efficientnet-1.0.0 image-classifiers-1.0.0 imgaug-0.4.0 imgstore-0.2.9 jsmin-3.0.1 jsonpickle-1.2 keras-applications-1.0.8 opencv-python-4.5.5.64 opencv-python-headless-4.5.5.62 pykalman-0.9.5 python-rapidjson-1.6 qimage2ndarray-1.8.3 rich-10.16.1 scikit-video-1.1.11 segmentation-models-1.0.1 shiboken2-5.14.1 sleap-1.2.2 tf-estimator-nightly-2.8.0.dev2021122109\n" - ] - } ] }, { "cell_type": "code", + "execution_count": 4, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -248,76 +72,76 @@ "id": "0n8oqLWBU0v7", "outputId": "f9cdcfe1-d152-4a0a-b769-6f9f7d8c0cf0" }, - "source": [ - "# Test video:\n", - "!wget https://storage.googleapis.com/sleap-data/reference/flies13/190719_090330_wt_18159206_rig1.2%4015000-17560.mp4\n", - "\n", - "# Test video labels (from predictions/not necessary for inference benchmarking):\n", - "!wget https://storage.googleapis.com/sleap-data/reference/flies13/190719_090330_wt_18159206_rig1.2%4015000-17560.slp\n", - "\n", - "# Bottom-up model:\n", - "# !wget https://storage.googleapis.com/sleap-data/reference/flies13/bu.210506_230852.multi_instance.n%3D1800.zip\n", - "\n", - "# Top-down model (two-stage):\n", - "!wget https://storage.googleapis.com/sleap-data/reference/flies13/centroid.fast.210504_182918.centroid.n%3D1800.zip\n", - "!wget https://storage.googleapis.com/sleap-data/reference/flies13/td_fast.210505_012601.centered_instance.n%3D1800.zip" - ], - "execution_count": 2, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "--2022-04-04 00:19:01-- https://storage.googleapis.com/sleap-data/reference/flies13/190719_090330_wt_18159206_rig1.2%4015000-17560.mp4\n", - "Resolving storage.googleapis.com (storage.googleapis.com)... 142.250.97.128, 142.251.107.128, 173.194.214.128, ...\n", - "Connecting to storage.googleapis.com (storage.googleapis.com)|142.250.97.128|:443... connected.\n", + "--2023-08-31 12:03:50-- https://storage.googleapis.com/sleap-data/reference/flies13/190719_090330_wt_18159206_rig1.2%4015000-17560.mp4\n", + "Resolving storage.googleapis.com (storage.googleapis.com)... 142.250.176.16, 142.250.72.144, 172.217.12.144, ...\n", + "Connecting to storage.googleapis.com (storage.googleapis.com)|142.250.176.16|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 85343812 (81M) [video/mp4]\n", - "Saving to: ‘190719_090330_wt_18159206_rig1.2@15000-17560.mp4’\n", + "Saving to: ‘190719_090330_wt_18159206_rig1.2@15000-17560.mp4.1’\n", "\n", - "190719_090330_wt_18 100%[===================>] 81.39M 142MB/s in 0.6s \n", + "190719_090330_wt_18 100%[===================>] 81.39M 27.7MB/s in 2.9s \n", "\n", - "2022-04-04 00:19:02 (142 MB/s) - ‘190719_090330_wt_18159206_rig1.2@15000-17560.mp4’ saved [85343812/85343812]\n", + "2023-08-31 12:03:53 (27.7 MB/s) - ‘190719_090330_wt_18159206_rig1.2@15000-17560.mp4.1’ saved [85343812/85343812]\n", "\n", - "--2022-04-04 00:19:02-- https://storage.googleapis.com/sleap-data/reference/flies13/190719_090330_wt_18159206_rig1.2%4015000-17560.slp\n", - "Resolving storage.googleapis.com (storage.googleapis.com)... 173.194.214.128, 173.194.215.128, 173.194.216.128, ...\n", - "Connecting to storage.googleapis.com (storage.googleapis.com)|173.194.214.128|:443... connected.\n", + "--2023-08-31 12:03:53-- https://storage.googleapis.com/sleap-data/reference/flies13/190719_090330_wt_18159206_rig1.2%4015000-17560.slp\n", + "Resolving storage.googleapis.com (storage.googleapis.com)... 142.250.188.240, 142.250.217.144, 142.250.68.16, ...\n", + "Connecting to storage.googleapis.com (storage.googleapis.com)|142.250.188.240|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 1581400 (1.5M) [application/octet-stream]\n", - "Saving to: ‘190719_090330_wt_18159206_rig1.2@15000-17560.slp’\n", + "Saving to: ‘190719_090330_wt_18159206_rig1.2@15000-17560.slp.1’\n", "\n", - "190719_090330_wt_18 100%[===================>] 1.51M --.-KB/s in 0.01s \n", + "190719_090330_wt_18 100%[===================>] 1.51M 3.99MB/s in 0.4s \n", "\n", - "2022-04-04 00:19:02 (151 MB/s) - ‘190719_090330_wt_18159206_rig1.2@15000-17560.slp’ saved [1581400/1581400]\n", + "2023-08-31 12:03:54 (3.99 MB/s) - ‘190719_090330_wt_18159206_rig1.2@15000-17560.slp.1’ saved [1581400/1581400]\n", "\n", - "--2022-04-04 00:19:02-- https://storage.googleapis.com/sleap-data/reference/flies13/centroid.fast.210504_182918.centroid.n%3D1800.zip\n", - "Resolving storage.googleapis.com (storage.googleapis.com)... 173.194.214.128, 173.194.215.128, 173.194.216.128, ...\n", - "Connecting to storage.googleapis.com (storage.googleapis.com)|173.194.214.128|:443... connected.\n", + "--2023-08-31 12:03:54-- https://storage.googleapis.com/sleap-data/reference/flies13/centroid.fast.210504_182918.centroid.n%3D1800.zip\n", + "Resolving storage.googleapis.com (storage.googleapis.com)... 142.250.72.240, 142.250.188.240, 142.250.189.16, ...\n", + "Connecting to storage.googleapis.com (storage.googleapis.com)|142.250.72.240|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 6372537 (6.1M) [application/zip]\n", - "Saving to: ‘centroid.fast.210504_182918.centroid.n=1800.zip’\n", + "Saving to: ‘centroid.fast.210504_182918.centroid.n=1800.zip.1’\n", "\n", - "centroid.fast.21050 100%[===================>] 6.08M --.-KB/s in 0.05s \n", + "centroid.fast.21050 100%[===================>] 6.08M --.-KB/s in 0.1s \n", "\n", - "2022-04-04 00:19:02 (134 MB/s) - ‘centroid.fast.210504_182918.centroid.n=1800.zip’ saved [6372537/6372537]\n", + "2023-08-31 12:03:54 (56.6 MB/s) - ‘centroid.fast.210504_182918.centroid.n=1800.zip.1’ saved [6372537/6372537]\n", "\n", - "--2022-04-04 00:19:02-- https://storage.googleapis.com/sleap-data/reference/flies13/td_fast.210505_012601.centered_instance.n%3D1800.zip\n", - "Resolving storage.googleapis.com (storage.googleapis.com)... 173.194.216.128, 173.194.217.128, 173.194.218.128, ...\n", - "Connecting to storage.googleapis.com (storage.googleapis.com)|173.194.216.128|:443... connected.\n", + "--2023-08-31 12:03:54-- https://storage.googleapis.com/sleap-data/reference/flies13/td_fast.210505_012601.centered_instance.n%3D1800.zip\n", + "Resolving storage.googleapis.com (storage.googleapis.com)... 172.217.14.112, 142.250.176.16, 142.250.72.176, ...\n", + "Connecting to storage.googleapis.com (storage.googleapis.com)|172.217.14.112|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 30775963 (29M) [application/zip]\n", - "Saving to: ‘td_fast.210505_012601.centered_instance.n=1800.zip’\n", + "Saving to: ‘td_fast.210505_012601.centered_instance.n=1800.zip.1’\n", "\n", - "td_fast.210505_0126 100%[===================>] 29.35M 190MB/s in 0.2s \n", + "td_fast.210505_0126 100%[===================>] 29.35M 21.3MB/s in 1.4s \n", "\n", - "2022-04-04 00:19:03 (190 MB/s) - ‘td_fast.210505_012601.centered_instance.n=1800.zip’ saved [30775963/30775963]\n", + "2023-08-31 12:03:56 (21.3 MB/s) - ‘td_fast.210505_012601.centered_instance.n=1800.zip.1’ saved [30775963/30775963]\n", "\n" ] } + ], + "source": [ + "# Test video:\n", + "!wget https://storage.googleapis.com/sleap-data/reference/flies13/190719_090330_wt_18159206_rig1.2%4015000-17560.mp4\n", + "\n", + "# Test video labels (from predictions/not necessary for inference benchmarking):\n", + "!wget https://storage.googleapis.com/sleap-data/reference/flies13/190719_090330_wt_18159206_rig1.2%4015000-17560.slp\n", + "\n", + "# Bottom-up model:\n", + "# !wget https://storage.googleapis.com/sleap-data/reference/flies13/bu.210506_230852.multi_instance.n%3D1800.zip\n", + "\n", + "# Top-down model (two-stage):\n", + "!wget https://storage.googleapis.com/sleap-data/reference/flies13/centroid.fast.210504_182918.centroid.n%3D1800.zip\n", + "!wget https://storage.googleapis.com/sleap-data/reference/flies13/td_fast.210505_012601.centered_instance.n%3D1800.zip" ] }, { "cell_type": "code", + "execution_count": 5, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -325,30 +149,42 @@ "id": "F-zzLnAoWrC5", "outputId": "b0ae7571-3ac0-42c7-d50f-982e4d9a459f" }, - "source": [ - "!ls -lah" - ], - "execution_count": 3, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "total 119M\n", - "drwxr-xr-x 1 root root 4.0K Apr 4 00:19 .\n", - "drwxr-xr-x 1 root root 4.0K Apr 4 00:15 ..\n", - "-rw-r--r-- 1 root root 82M May 20 2021 190719_090330_wt_18159206_rig1.2@15000-17560.mp4\n", - "-rw-r--r-- 1 root root 1.6M May 20 2021 190719_090330_wt_18159206_rig1.2@15000-17560.slp\n", - "-rw-r--r-- 1 root root 6.1M May 20 2021 'centroid.fast.210504_182918.centroid.n=1800.zip'\n", - "drwxr-xr-x 4 root root 4.0K Mar 23 14:21 .config\n", - "drwxr-xr-x 1 root root 4.0K Mar 23 14:22 sample_data\n", - "-rw-r--r-- 1 root root 30M May 20 2021 'td_fast.210505_012601.centered_instance.n=1800.zip'\n" + "total 239M\n", + "drwxrwxr-x 3 talmolab talmolab 4.0K Aug 31 12:03 .\n", + "drwxrwxr-x 7 talmolab talmolab 4.0K Aug 31 11:39 ..\n", + "-rw-rw-r-- 1 talmolab talmolab 82M May 20 2021 190719_090330_wt_18159206_rig1.2@15000-17560.mp4\n", + "-rw-rw-r-- 1 talmolab talmolab 82M May 20 2021 190719_090330_wt_18159206_rig1.2@15000-17560.mp4.1\n", + "-rw-rw-r-- 1 talmolab talmolab 1.6M May 20 2021 190719_090330_wt_18159206_rig1.2@15000-17560.slp\n", + "-rw-rw-r-- 1 talmolab talmolab 1.6M May 20 2021 190719_090330_wt_18159206_rig1.2@15000-17560.slp.1\n", + "drwxrwxr-x 2 talmolab talmolab 4.0K Jun 20 10:00 analysis_example\n", + "-rw-rw-r-- 1 talmolab talmolab 713K Jun 20 10:00 Analysis_examples.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 6.1M May 20 2021 'centroid.fast.210504_182918.centroid.n=1800.zip'\n", + "-rw-rw-r-- 1 talmolab talmolab 6.1M May 20 2021 'centroid.fast.210504_182918.centroid.n=1800.zip.1'\n", + "-rw-rw-r-- 1 talmolab talmolab 486K Aug 31 11:39 Data_structures.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 4.1K Jun 20 10:00 index.rst\n", + "-rw-rw-r-- 1 talmolab talmolab 197K Aug 31 11:39 Interactive_and_realtime_inference.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 398K Aug 31 11:39 Interactive_and_resumable_training.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 149K Aug 31 11:39 Model_evaluation.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 150K Aug 31 11:39 Post_inference_tracking.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 30M May 20 2021 'td_fast.210505_012601.centered_instance.n=1800.zip'\n", + "-rw-rw-r-- 1 talmolab talmolab 30M May 20 2021 'td_fast.210505_012601.centered_instance.n=1800.zip.1'\n", + "-rw-rw-r-- 1 talmolab talmolab 9.5K Aug 31 11:39 Training_and_inference_on_an_example_dataset.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 12K Aug 31 11:39 Training_and_inference_using_Google_Drive.ipynb\n" ] } + ], + "source": [ + "!ls -lah" ] }, { "cell_type": "code", + "execution_count": 6, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -356,6 +192,51 @@ "id": "w6xCj73QXM0t", "outputId": "47d181ba-9272-4b9d-ab2a-0fcae34f38d1" }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-08-31 12:03:56.989133: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX512F AVX512_VNNI FMA\n", + "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n", + "2023-08-31 12:03:57.058048: I tensorflow/core/util/port.cc:104] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n", + "2023-08-31 12:03:57.060007: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-08-31 12:03:57.060013: I tensorflow/compiler/xla/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n", + "2023-08-31 12:03:57.445179: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-08-31 12:03:57.445232: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-08-31 12:03:57.445236: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SLEAP: 1.3.2\n", + "TensorFlow: 2.11.0\n", + "Numpy: 1.21.6\n", + "Python: 3.7.12\n", + "OS: Linux-5.15.0-78-generic-x86_64-with-debian-bookworm-sid\n", + "GPUs: None detected.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-08-31 12:03:58.223182: I tensorflow/compiler/xla/stream_executor/cuda/cuda_gpu_executor.cc:981] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-08-31 12:03:58.223923: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-08-31 12:03:58.223968: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcublas.so.11'; dlerror: libcublas.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-08-31 12:03:58.223999: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcublasLt.so.11'; dlerror: libcublasLt.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-08-31 12:03:58.224028: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcufft.so.10'; dlerror: libcufft.so.10: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-08-31 12:03:58.224057: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcurand.so.10'; dlerror: libcurand.so.10: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-08-31 12:03:58.224084: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcusolver.so.11'; dlerror: libcusolver.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-08-31 12:03:58.224111: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcusparse.so.11'; dlerror: libcusparse.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-08-31 12:03:58.224140: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudnn.so.8'; dlerror: libcudnn.so.8: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-08-31 12:03:58.224144: W tensorflow/core/common_runtime/gpu/gpu_device.cc:1934] Cannot dlopen some GPU libraries. Please make sure the missing libraries mentioned above are installed properly if you would like to use GPU. Follow the guide at https://www.tensorflow.org/install/gpu for how to download and setup the required libraries for your platform.\n", + "Skipping registering GPU devices...\n" + ] + } + ], "source": [ "import sleap\n", "\n", @@ -369,26 +250,6 @@ "# Print some info:\n", "sleap.versions()\n", "sleap.system_summary()" - ], - "execution_count": 4, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "INFO:numexpr.utils:NumExpr defaulting to 2 threads.\n", - "SLEAP: 1.2.2\n", - "TensorFlow: 2.8.0\n", - "Numpy: 1.21.5\n", - "Python: 3.7.13\n", - "OS: Linux-5.4.144+-x86_64-with-Ubuntu-18.04-bionic\n", - "GPUs: 1/1 available\n", - " Device: /physical_device:GPU:0\n", - " Available: True\n", - " Initalized: False\n", - " Memory growth: True\n" - ] - } ] }, { @@ -402,17 +263,18 @@ }, { "cell_type": "markdown", + "metadata": { + "id": "0Fyey-smRjXx" + }, "source": [ "SLEAP can read videos in a variety of different formats through the `sleap.load_video` high level API. Once loaded, the `sleap.Video` object allows you to access individual frames as if the it were a standard numpy array.\n", "\n", "**Note:** The actual frames are not loaded until you access them so we don't blow up our memory when using long videos." - ], - "metadata": { - "id": "0Fyey-smRjXx" - } + ] }, { "cell_type": "code", + "execution_count": 7, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -420,6 +282,16 @@ "id": "cH_qfme2We7k", "outputId": "cb6aaf9c-ab38-4b3b-ffac-8acd78bf13c1" }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(2560, 1024, 1024, 1)\n", + "(4, 1024, 1024, 1) uint8\n" + ] + } + ], "source": [ "# Videos can be represented agnostic to the backend format\n", "video = sleap.load_video(\"190719_090330_wt_18159206_rig1.2@15000-17560.mp4\")\n", @@ -430,17 +302,6 @@ "# And we can load images in the video using array indexing:\n", "imgs = video[:4]\n", "print(imgs.shape, imgs.dtype)" - ], - "execution_count": 5, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "(2560, 1024, 1024, 1)\n", - "(4, 1024, 1024, 1) uint8\n" - ] - } ] }, { @@ -463,9 +324,20 @@ }, { "cell_type": "code", + "execution_count": 8, "metadata": { "id": "wnIgeeivXiln" }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-08-31 12:03:58.498908: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX512F AVX512_VNNI FMA\n", + "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n" + ] + } + ], "source": [ "# Top-down\n", "predictor = sleap.load_model([\n", @@ -475,9 +347,7 @@ "\n", "# Bottom-up\n", "# predictor = sleap.load_model(\"bu.210506_230852.multi_instance.n=1800.zip\")" - ], - "execution_count": 6, - "outputs": [] + ] }, { "cell_type": "markdown", @@ -490,6 +360,7 @@ }, { "cell_type": "code", + "execution_count": 9, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -502,61 +373,67 @@ "id": "4RWl4PwTZkuN", "outputId": "82141aed-1fa1-4d44-8bad-d8d78a642cd7" }, - "source": [ - "labels = predictor.predict(video)\n", - "labels" - ], - "execution_count": 7, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "Output()" - ], "application/vnd.jupyter.widget-view+json": { + "model_id": "cf38d776e9fc48ada47705ce018c64af", "version_major": 2, - "version_minor": 0, - "model_id": "581b3a9402bc4837bde932e98fa475a7" - } + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-08-31 12:04:01.923466: W tensorflow/core/grappler/costs/op_level_cost_estimator.cc:690] Error in PredictCost() for the op: op: \"CropAndResize\" attr { key: \"T\" value { type: DT_FLOAT } } attr { key: \"extrapolation_value\" value { f: 0 } } attr { key: \"method\" value { s: \"bilinear\" } } inputs { dtype: DT_FLOAT shape { dim { size: -45 } dim { size: -46 } dim { size: -47 } dim { size: 1 } } } inputs { dtype: DT_FLOAT shape { dim { size: -15 } dim { size: 4 } } } inputs { dtype: DT_INT32 shape { dim { size: -15 } } } inputs { dtype: DT_INT32 shape { dim { size: 2 } } } device { type: \"CPU\" vendor: \"GenuineIntel\" model: \"103\" frequency: 3600 num_cores: 16 environment { key: \"cpu_instruction_set\" value: \"AVX SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2\" } environment { key: \"eigen\" value: \"3.4.90\" } l1_cache_size: 49152 l2_cache_size: 524288 l3_cache_size: 16777216 memory_size: 268435456 } outputs { dtype: DT_FLOAT shape { dim { size: -15 } dim { size: -48 } dim { size: -49 } dim { size: 1 } } }\n", + "2023-08-31 12:04:01.923717: W tensorflow/core/grappler/costs/op_level_cost_estimator.cc:690] Error in PredictCost() for the op: op: \"CropAndResize\" attr { key: \"T\" value { type: DT_UINT8 } } attr { key: \"extrapolation_value\" value { f: 0 } } attr { key: \"method\" value { s: \"bilinear\" } } inputs { dtype: DT_UINT8 shape { dim { size: 4 } dim { size: 1024 } dim { size: 1024 } dim { size: 1 } } } inputs { dtype: DT_FLOAT shape { dim { size: -15 } dim { size: 4 } } } inputs { dtype: DT_INT32 shape { dim { size: -15 } } } inputs { dtype: DT_INT32 shape { dim { size: 2 } } } device { type: \"CPU\" vendor: \"GenuineIntel\" model: \"103\" frequency: 3600 num_cores: 16 environment { key: \"cpu_instruction_set\" value: \"AVX SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2\" } environment { key: \"eigen\" value: \"3.4.90\" } l1_cache_size: 49152 l2_cache_size: 524288 l3_cache_size: 16777216 memory_size: 268435456 } outputs { dtype: DT_FLOAT shape { dim { size: -15 } dim { size: -56 } dim { size: -57 } dim { size: 1 } } }\n", + "2023-08-31 12:04:01.926044: W tensorflow/core/grappler/costs/op_level_cost_estimator.cc:690] Error in PredictCost() for the op: op: \"CropAndResize\" attr { key: \"T\" value { type: DT_FLOAT } } attr { key: \"extrapolation_value\" value { f: 0 } } attr { key: \"method\" value { s: \"bilinear\" } } inputs { dtype: DT_FLOAT shape { dim { size: -90 } dim { size: -91 } dim { size: -92 } dim { size: 1 } } } inputs { dtype: DT_FLOAT shape { dim { size: -20 } dim { size: 4 } } } inputs { dtype: DT_INT32 shape { dim { size: -20 } } } inputs { dtype: DT_INT32 shape { dim { size: 2 } } } device { type: \"CPU\" vendor: \"GenuineIntel\" model: \"103\" frequency: 3600 num_cores: 16 environment { key: \"cpu_instruction_set\" value: \"AVX SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2\" } environment { key: \"eigen\" value: \"3.4.90\" } l1_cache_size: 49152 l2_cache_size: 524288 l3_cache_size: 16777216 memory_size: 268435456 } outputs { dtype: DT_FLOAT shape { dim { size: -20 } dim { size: -94 } dim { size: -95 } dim { size: 1 } } }\n" + ] }, { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "
\n"
-            ]
+            ],
+            "text/plain": []
           },
-          "metadata": {}
+          "metadata": {},
+          "output_type": "display_data"
         },
         {
-          "output_type": "display_data",
           "data": {
-            "text/plain": [
-              "\n"
-            ],
             "text/html": [
               "
\n",
               "
\n" + ], + "text/plain": [ + "\n" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "execute_result", "data": { "text/plain": [ "Labels(labeled_frames=2560, videos=1, skeletons=1, tracks=0)" ] }, + "execution_count": 9, "metadata": {}, - "execution_count": 7 + "output_type": "execute_result" } + ], + "source": [ + "labels = predictor.predict(video)\n", + "labels" ] }, { @@ -570,6 +447,7 @@ }, { "cell_type": "code", + "execution_count": 10, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -577,25 +455,25 @@ "id": "EgL-bqRj-l6R", "outputId": "3fd8f355-92b1-4bbb-b7e9-d564b007d97b" }, - "source": [ - "labels.videos" - ], - "execution_count": 8, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "[Video(backend=MediaVideo(filename='190719_090330_wt_18159206_rig1.2@15000-17560.mp4', grayscale=True, bgr=True, dataset='', input_format='channels_last'))]" ] }, + "execution_count": 10, "metadata": {}, - "execution_count": 8 + "output_type": "execute_result" } + ], + "source": [ + "labels.videos" ] }, { "cell_type": "code", + "execution_count": 11, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -603,21 +481,20 @@ "id": "EOu9c9ly-nkN", "outputId": "3e66210c-12f6-48e4-c829-41aa3768b140" }, - "source": [ - "labels.skeletons" - ], - "execution_count": 9, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ - "[Skeleton(name='Skeleton-0', nodes=['head', 'thorax', 'abdomen', 'wingL', 'wingR', 'forelegL4', 'forelegR4', 'midlegL4', 'midlegR4', 'hindlegL4', 'hindlegR4', 'eyeL', 'eyeR'], edges=[('thorax', 'head'), ('thorax', 'abdomen'), ('thorax', 'wingL'), ('thorax', 'wingR'), ('thorax', 'forelegL4'), ('thorax', 'forelegR4'), ('thorax', 'midlegL4'), ('thorax', 'midlegR4'), ('thorax', 'hindlegL4'), ('thorax', 'hindlegR4'), ('head', 'eyeL'), ('head', 'eyeR')], symmetries=[('wingL', 'wingR'), ('forelegL4', 'forelegR4'), ('hindlegL4', 'hindlegR4'), ('eyeL', 'eyeR'), ('midlegL4', 'midlegR4')])]" + "[Skeleton(name='Skeleton-0', description='None', nodes=['head', 'thorax', 'abdomen', 'wingL', 'wingR', 'forelegL4', 'forelegR4', 'midlegL4', 'midlegR4', 'hindlegL4', 'hindlegR4', 'eyeL', 'eyeR'], edges=[('thorax', 'head'), ('thorax', 'abdomen'), ('thorax', 'wingL'), ('thorax', 'wingR'), ('thorax', 'forelegL4'), ('thorax', 'forelegR4'), ('thorax', 'midlegL4'), ('thorax', 'midlegR4'), ('thorax', 'hindlegL4'), ('thorax', 'hindlegR4'), ('head', 'eyeL'), ('head', 'eyeR')], symmetries=[('forelegL4', 'forelegR4'), ('wingL', 'wingR'), ('eyeL', 'eyeR'), ('midlegL4', 'midlegR4'), ('hindlegL4', 'hindlegR4')])]" ] }, + "execution_count": 11, "metadata": {}, - "execution_count": 9 + "output_type": "execute_result" } + ], + "source": [ + "labels.skeletons" ] }, { @@ -631,6 +508,7 @@ }, { "cell_type": "code", + "execution_count": 12, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -638,22 +516,21 @@ "id": "pGcyrjKf8hp4", "outputId": "1ff0ab5a-5a67-4d35-c09f-21adbcec655e" }, - "source": [ - "labeled_frame = labels[0] # shortcut for labels.labeled_frames[0]\n", - "labeled_frame" - ], - "execution_count": 10, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "LabeledFrame(video=MediaVideo('190719_090330_wt_18159206_rig1.2@15000-17560.mp4'), frame_idx=0, instances=2)" ] }, + "execution_count": 12, "metadata": {}, - "execution_count": 10 + "output_type": "execute_result" } + ], + "source": [ + "labeled_frame = labels[0] # shortcut for labels.labeled_frames[0]\n", + "labeled_frame" ] }, { @@ -667,6 +544,7 @@ }, { "cell_type": "code", + "execution_count": 13, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -675,21 +553,20 @@ "id": "s2YiRWSa7f6D", "outputId": "3f76ae98-dd72-4c2e-ac06-9bfe3b2c2637" }, - "source": [ - "labels[0].plot(scale=0.5)" - ], - "execution_count": 11, "outputs": [ { - "output_type": "display_data", "data": { + "image/png": "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", "text/plain": [ "
" - ], - "image/png": "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\n" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" } + ], + "source": [ + "labels[0].plot(scale=0.5)" ] }, { @@ -703,6 +580,7 @@ }, { "cell_type": "code", + "execution_count": 14, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -710,26 +588,26 @@ "id": "ZP9Z0etc9e0c", "outputId": "00986c80-23d0-43fa-f4f9-c60482e5293e" }, - "source": [ - "labeled_frame.instances" - ], - "execution_count": 12, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "[PredictedInstance(video=Video(filename=190719_090330_wt_18159206_rig1.2@15000-17560.mp4, shape=(2560, 1024, 1024, 1), backend=MediaVideo), frame_idx=0, points=[head: (234.2, 430.5, 0.98), thorax: (271.6, 436.1, 0.94), abdomen: (308.0, 438.6, 0.59), wingL: (321.8, 440.1, 0.39), wingR: (322.0, 436.8, 0.49), forelegL4: (246.1, 450.6, 0.92), forelegR4: (242.3, 413.9, 0.78), midlegL4: (285.8, 459.9, 0.47), midlegR4: (272.3, 406.7, 0.77), hindlegR4: (317.6, 430.6, 0.30), eyeL: (242.1, 441.9, 0.89), eyeR: (245.3, 420.9, 0.92)], score=0.95, track=None, tracking_score=0.00),\n", " PredictedInstance(video=Video(filename=190719_090330_wt_18159206_rig1.2@15000-17560.mp4, shape=(2560, 1024, 1024, 1), backend=MediaVideo), frame_idx=0, points=[head: (319.4, 435.9, 0.83), thorax: (354.4, 435.2, 0.80), abdomen: (368.3, 433.8, 0.71), wingL: (393.9, 480.3, 0.83), wingR: (398.4, 430.0, 0.81), forelegL4: (307.8, 445.7, 0.26), forelegR4: (305.6, 421.4, 0.69), midlegL4: (325.7, 475.0, 0.94), midlegR4: (331.8, 385.1, 0.88), hindlegL4: (363.7, 474.1, 0.88), hindlegR4: (376.0, 398.4, 0.52), eyeL: (329.3, 445.6, 0.90), eyeR: (327.9, 425.1, 0.84)], score=0.84, track=None, tracking_score=0.00)]" ] }, + "execution_count": 14, "metadata": {}, - "execution_count": 12 + "output_type": "execute_result" } + ], + "source": [ + "labeled_frame.instances" ] }, { "cell_type": "code", + "execution_count": 15, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -737,22 +615,21 @@ "id": "Y-stVhiw9uIr", "outputId": "4cd7dbdf-bd91-4037-b971-3a17c85193bd" }, - "source": [ - "instance = labeled_frame[0] # shortcut for labeled_frame.instances[0]\n", - "instance" - ], - "execution_count": 13, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "PredictedInstance(video=Video(filename=190719_090330_wt_18159206_rig1.2@15000-17560.mp4, shape=(2560, 1024, 1024, 1), backend=MediaVideo), frame_idx=0, points=[head: (234.2, 430.5, 0.98), thorax: (271.6, 436.1, 0.94), abdomen: (308.0, 438.6, 0.59), wingL: (321.8, 440.1, 0.39), wingR: (322.0, 436.8, 0.49), forelegL4: (246.1, 450.6, 0.92), forelegR4: (242.3, 413.9, 0.78), midlegL4: (285.8, 459.9, 0.47), midlegR4: (272.3, 406.7, 0.77), hindlegR4: (317.6, 430.6, 0.30), eyeL: (242.1, 441.9, 0.89), eyeR: (245.3, 420.9, 0.92)], score=0.95, track=None, tracking_score=0.00)" ] }, + "execution_count": 15, "metadata": {}, - "execution_count": 13 + "output_type": "execute_result" } + ], + "source": [ + "instance = labeled_frame[0] # shortcut for labeled_frame.instances[0]\n", + "instance" ] }, { @@ -766,6 +643,7 @@ }, { "cell_type": "code", + "execution_count": 16, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -773,32 +651,31 @@ "id": "7xK-uGJZ905J", "outputId": "102accd0-ba45-44b0-b839-eff15a06245a" }, - "source": [ - "instance.points" - ], - "execution_count": 14, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ - "(PredictedPoint(x=234.244384765625, y=430.52001953125, visible=True, complete=False, score=0.9790461659431458),\n", - " PredictedPoint(x=271.5894470214844, y=436.1461181640625, visible=True, complete=False, score=0.9357967376708984),\n", - " PredictedPoint(x=308.02899169921875, y=438.5711975097656, visible=True, complete=False, score=0.5859644412994385),\n", - " PredictedPoint(x=321.8167419433594, y=440.0872802734375, visible=True, complete=False, score=0.3912011682987213),\n", - " PredictedPoint(x=322.0196533203125, y=436.77008056640625, visible=True, complete=False, score=0.48613619804382324),\n", - " PredictedPoint(x=246.1430206298828, y=450.56182861328125, visible=True, complete=False, score=0.9176540970802307),\n", - " PredictedPoint(x=242.2632293701172, y=413.94976806640625, visible=True, complete=False, score=0.7807964086532593),\n", - " PredictedPoint(x=285.78167724609375, y=459.9156494140625, visible=True, complete=False, score=0.4739593267440796),\n", - " PredictedPoint(x=272.27996826171875, y=406.71759033203125, visible=True, complete=False, score=0.7721188068389893),\n", - " PredictedPoint(x=317.5997619628906, y=430.6052551269531, visible=True, complete=False, score=0.2960105538368225),\n", - " PredictedPoint(x=242.1038055419922, y=441.94561767578125, visible=True, complete=False, score=0.8855815529823303),\n", - " PredictedPoint(x=245.3200225830078, y=420.93609619140625, visible=True, complete=False, score=0.9199579954147339))" + "(PredictedPoint(x=234.24440002441406, y=430.52008056640625, visible=True, complete=False, score=0.9790770411491394),\n", + " PredictedPoint(x=271.58941650390625, y=436.1461486816406, visible=True, complete=False, score=0.9358043670654297),\n", + " PredictedPoint(x=308.02960205078125, y=438.57135009765625, visible=True, complete=False, score=0.5861632227897644),\n", + " PredictedPoint(x=321.81768798828125, y=440.08721923828125, visible=True, complete=False, score=0.39127233624458313),\n", + " PredictedPoint(x=322.0193176269531, y=436.7702941894531, visible=True, complete=False, score=0.48629727959632874),\n", + " PredictedPoint(x=246.14295959472656, y=450.5621643066406, visible=True, complete=False, score=0.9176925420761108),\n", + " PredictedPoint(x=242.2632598876953, y=413.9497375488281, visible=True, complete=False, score=0.780803382396698),\n", + " PredictedPoint(x=285.78155517578125, y=459.91552734375, visible=True, complete=False, score=0.47393468022346497),\n", + " PredictedPoint(x=272.280029296875, y=406.71759033203125, visible=True, complete=False, score=0.7721256017684937),\n", + " PredictedPoint(x=317.598876953125, y=430.6053466796875, visible=True, complete=False, score=0.296230286359787),\n", + " PredictedPoint(x=242.10415649414062, y=441.9450378417969, visible=True, complete=False, score=0.8855596780776978),\n", + " PredictedPoint(x=245.32009887695312, y=420.9360656738281, visible=True, complete=False, score=0.9200019240379333))" ] }, + "execution_count": 16, "metadata": {}, - "execution_count": 14 + "output_type": "execute_result" } + ], + "source": [ + "instance.points" ] }, { @@ -812,6 +689,7 @@ }, { "cell_type": "code", + "execution_count": 17, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -819,31 +697,30 @@ "id": "jEWddPpg93GM", "outputId": "ddd09bae-83e1-48f7-b870-3155a68e6ecb" }, - "source": [ - "pts = instance.numpy()\n", - "print(pts)" - ], - "execution_count": 15, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "[[234.24438477 430.52001953]\n", - " [271.58944702 436.14611816]\n", - " [308.0289917 438.57119751]\n", - " [321.81674194 440.08728027]\n", - " [322.01965332 436.77008057]\n", - " [246.14302063 450.56182861]\n", - " [242.26322937 413.94976807]\n", - " [285.78167725 459.91564941]\n", - " [272.27996826 406.71759033]\n", + "[[234.24440002 430.52008057]\n", + " [271.5894165 436.14614868]\n", + " [308.02960205 438.5713501 ]\n", + " [321.81768799 440.08721924]\n", + " [322.01931763 436.77029419]\n", + " [246.14295959 450.56216431]\n", + " [242.26325989 413.94973755]\n", + " [285.78155518 459.91552734]\n", + " [272.2800293 406.71759033]\n", " [ nan nan]\n", - " [317.59976196 430.60525513]\n", - " [242.10380554 441.94561768]\n", - " [245.32002258 420.93609619]]\n" + " [317.59887695 430.60534668]\n", + " [242.10415649 441.94503784]\n", + " [245.32009888 420.93606567]]\n" ] } + ], + "source": [ + "pts = instance.numpy()\n", + "print(pts)" ] }, { @@ -857,15 +734,15 @@ }, { "cell_type": "code", + "execution_count": 18, "metadata": { "id": "Thx9INKJ_JHk" }, + "outputs": [], "source": [ "labels = sleap.Labels(labels.labeled_frames[:4]) # crop to the first few labels for this example\n", "labels.save(\"labels_with_images.pkg.slp\", with_images=True, embed_all_labeled=True)" - ], - "execution_count": 16, - "outputs": [] + ] }, { "cell_type": "markdown", @@ -878,14 +755,14 @@ }, { "cell_type": "code", + "execution_count": 19, "metadata": { "id": "fJvcyJDw_Wbz" }, + "outputs": [], "source": [ "!rm \"190719_090330_wt_18159206_rig1.2@15000-17560.mp4\"" - ], - "execution_count": 17, - "outputs": [] + ] }, { "cell_type": "markdown", @@ -898,6 +775,7 @@ }, { "cell_type": "code", + "execution_count": 20, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -905,26 +783,26 @@ "id": "enTHiSIY_qg0", "outputId": "96589190-e771-4fd8-bc41-7cd7bf7262d9" }, - "source": [ - "labels = sleap.load_file(\"labels_with_images.pkg.slp\")\n", - "labels" - ], - "execution_count": 18, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "Labels(labeled_frames=4, videos=1, skeletons=1, tracks=0)" ] }, + "execution_count": 20, "metadata": {}, - "execution_count": 18 + "output_type": "execute_result" } + ], + "source": [ + "labels = sleap.load_file(\"labels_with_images.pkg.slp\")\n", + "labels" ] }, { "cell_type": "code", + "execution_count": 21, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -933,22 +811,47 @@ "id": "X8zy1PyP_2cW", "outputId": "757240fe-eb6f-465f-b079-170ef889144d" }, - "source": [ - "labels[0].plot(scale=0.5)" - ], - "execution_count": 19, "outputs": [ { - "output_type": "display_data", "data": { + "image/png": "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", "text/plain": [ "
" - ], - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAg4AAAIOCAYAAADQu4U5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOy9WW8kyZGubbkwV7JYVd0qdUut2YC50MVczf+Ynz7ACDMYQJiGBKkldVU3WcUtk2QucS54XucTb5pHZHXPwYcPoAMEMyMjfDG35TVzc49B0zTxUl7KS3kpL+WlvJSXckwZ/n/dgZfyUl7KS3kpL+Wl/P+nvACHl/JSXspLeSkv5aUcXV6Aw0t5KS/lpbyUl/JSji4vwOGlvJSX8lJeykt5KUeXF+DwUl7KS3kpL+WlvJSjywtweCkv5aW8lJfyUl7K0WXc9ePbt2+biAht2dzv9zEctrEGrw0Gg/Dtnfo+GAzK9/1+H03TRNM0MRwOYzAYlHp2u12pb7fbHdSlevhdf/v9/qAf4/G41d7nFvZbZTgcxn6/T8fr42Yd6iPHMBgMYjKZxHa7jd1uV54bDocHdY9Go/Kb6CaaeZsq0+k0zs/P4/LyMna7XYxGo9jtdrHf7w/G0DRNnJycxHQ6jcfHx1iv1wc0YL9Go1GZz2OK8w5pxX5oPiOeeMDnQHQQz5ycnLTmWJ/1O2lFXhbtIyIeHh7KOMbjcZmLbB6d1l6v7h2Px63+fG5he/wueok2LhdeNOd9Y2BRn3X95OQkRqNR3N/fl/GSpj5G8obq0XyQ38hTLk81WddvLtfOJ7yX94kf9J08ltFR8uCy633SeHmt1p/xeByj0SjW63V1DknDPl3D38WDornk3vVORhtd8+uZvva6sjkU/2S/ie6cD+l/8bfoQPpyjNPptNVP12/sH/ukZ3zudL/zKfs+HA5jNBrFdrtNbZLT0fmbNo71c1zsh9fNueM87ff7wjNOZ7+ezbHqFf3X63VVqXQCBydETfG7sNSEn/VQ6ZEh2QYN47GKl0TgJGXGbTwex3a77ayja7zq98nJSTw+Pvb20RWPFCmvuwHNaEM6s/8uKBo/+7vdbg8ULg3mYDCI1WoVw+EwxuPxQb0SYgqNz3uN3t6/LmWYlZqAanxSFi4c7MtoNCrfRY+agsiKzw2FzeWgi2/7jL2PkbTfbDbl+zF9Zn9r10kDjUf/xTNufNwAe50ZDzh/+zj1vWagm6YpdOgrDhLVJo2f83BWNP6++XL91dWv7XYbj4+PVcDCfm42m4P5cdoJAD8+PpbfSS8aQncWsv7pP/mcfO3j5D18JqOvPo9Go6JzpMcy/qJRJQimnqF+k97rm9cufcLfMzBUA6dOD6dnBrhYXMfzM8GR+qkxbrfbg/sy3vLPlIPPKZ3A4XOVujNcVt9+v4+Tk5MWoqSHKIERI/GaK6IaWuRzXZ+z/mZI1Men6+PxOE5OTmI+n8dut0tBCA0V2+J/TjrH4BGYTFgdrUq5E5nf3d21ojeiJQGFDNFms4ndbheTySTm83mJhMgIeoQjUxQ1Q5IhZfWnpsAyw6SxUYAIRL3dTOjFfy40ut+RuM+h389xKcqVzXs2vq5CGnvUIKvPC/vuXge9QRkYgqqIZ4C43W4P+Jv85pGo09PTuLq6KrxdM7wud37N24toRyJ572DwHL2TUeYf6zk5OTnaIeG4fa79WldxvdJ3v9O7ZpjEGy5nboxres/70gVmMlCXfe7S/x4B5HU3yhnQ1PMq5FvKiffJx9YHpKlfWJyXBWaoj53fpDupW2o00m8erVFdzrdOS9KaYI/3kQ505I8BvhFHRhz6GNzvzRrXoGi0/PeIaHmNDka8P04A3qdna96v2uKzWT0aS7bEIMS8Xq/TyfQJzQwZGcL7JsWcLRGxDhoUhsdVN8Pw3i6/y5Odz+dlbI+Pjy0aCESoD5niyOZuMBjEyclJDIfD4kFpftQ+29E1zmcNPPYZHI6V4+kTXj5fM9JUpq7QjjFKfaWrPvUro5e+UxFnS4Acm/hNwN35NqMBgS2V1P39fetaRsNsTLqWyaSP3Z8VwNntdmUpQH3kPU3TxP39fdVA1vrXN59Zf/rud+OYje0YQHJsVIT1i3fEI65jMtmqgQn2hb91/c7IgeYqoq0Ls+hS1i9vU23VeM7lKqN3lz7zKG429uxejfdYWaBMufxyHvWZUYga/3G8ivjQNh2jtzqBg9ZGOChXIl1rME5wes76LRNqV3is2793KRkq1ez3LLTv99UYVAzjuQleuvIPsnG7MYiIsmzA+dA9GW0ZTci8eV++0H1autH9DHG6MNOTzEpGr/1+3/KifFlKyssBhO51j3m/3xe61DwJR+u8zuLeDxVpDYj4GD0nx3mR8+y/9wF0LsewX8rvEKjzIoDL8XPeNU49q3l1haTPijAIZDpdVTw/Rv11R4Cl1mYml/Tysjo0j3RCnC7ev4x2rsO8na7Spby9LoJi55Mug1LTxbynq2T5P+wXPx/Dt326lMtbBC9u8EkHFTkzEdFavlEbviTF31h319zVDK/zAZdMOC7vtwNztluzcbQDNRsoh1J8nulSHz/1eK1Px4LPo5cqMiWYMVBGMEdrMrZSaPrPdSlXMt7Wzyl9z9cE1kFELTzufe5Skv6cPsuQOz3c62bob7fblSSupmlaBt5Bmtqo1RURcXt728qJGAyek7q6jLCKh8KdwckzpCl/Ux9p0GuIOjNgrqhcwLikE9EWyJphPMZoeNFYPKGqBky76mA/NptNC1RxjgX83OMRLfk7x9VlDJTTk4XveX9NP2T3c2zZeqvrFekQN0AZP/vYMzpnukv083b9uVqdtb77byxd0VG/n/xck79jQZH4QMa4Ji8+joxf6GhmSyWj0Sjm83ms1+uWU0KDnfEP23eApHq4XFB7XnUw0pLRrKt9v8/vr/G600Ggf7PZHIzHlxlqPO7AsWZreN0jHqTFsfkOncChhpgJCryDfd/ZOf25x0iFrmtdffzcUmPMvu9ZkYHmmJz5maXPZzKmpcftwMsTRakU3RPV71q68Gd1nfczdHh/f99aUtI9DMtlio/9zlC4I3Ayu8bhCjLzpBwxDwbtBCv+sb9UMH6vC47GzmQ60qJPwFzYadSPRfYsvo7LKIkMuo/L+VKFUZ3MWNUA2uPjYzw8PJRxqQ03Nk7jLno5QPN5Y5+z5UX22UuXYfWxer1ZzhL73De+zwGFfUuJWfu1a5mx6qqDOUz8rSsiq+8un9vt9iBXQfVMJpNomibW63WRNRUC30wPq637+/uWviWvdQFYtyfZmFSf87zzEJ93gJ3l33gUYzgclp06XWCEO0xIR/3mepL6iQAu6ztp4+P5XwEOnKDPUXQciBs0ohtfb84YoIZ0P7c/TqzPEeyu+zSOLFQc0Z1df0xxAdb/2WzWyl9wD1+eaObJSEj1HOumkaMS0Dgy4VZb6u8xIMyBhUCWC/l0Oi1AhvdzzS8TZNKiRn8JmdpwBC9lNxgMiqAfa4z0vysvo+95Vw41HmyaJqbTaVFezEXJ5orzn4F1LzVDeSyI+inFgY7kzAGcCmW8Vrpo+Dn94fdjnZyf26fsvq5naw5SrW6vzwGn/6+BfkXBvG0thTpAZERRdXlkMKKdHMs5ZsTCn8kinCpZThVp5g6ayyJL1t+Mxqr34eHhoC6vM5Nf14E1AKTnMjDk87hcLmO73ZbIR5e+VOldquhC+Nn93sGa0comoavDNWK5sayhSa7N/pTSpZDc62LxdTdHk15Prf81D6vvfhkQjlvz6sKn3xj1oHFXqF1hbo0nY2YqhS7jl/XZ51QJjQSemfFSvz0qU6PfZDKJzWYT+/0+1ut1a8lMdb969Sru7+9jtVod8FiXcGUKiGP2ufdnu8AX69Wab0S05jhT3HqWa//MmekC7X3GmCWTd352BZ/V7TzWxTfeFkO94/H4YD3c+8I+uH6pyV3EM5jJHJnPoZf3p6/tGk1UjnGKMnr6GJiYmPGRX890MOXv4eGhda5O5jhSb3k/yJ+sn8uM3jc9U6MVASnvdbroupaPs5LpOhbVo6gMx0p9qehLll/mRt9pzBy3DCiwPtV/d3fXov0xjlFvcmQfms2u1ZSPI2BX+jWPva9d1SPDcXJyUrK61d50Om0ldGWlJrhdjMd7a8Lo36UQu0KhPuasyFCQMcgAynFghrzCfI6yHQTU9sqLOV2peD2uCEhLCUeNToPB81ZJfc6iE6Q522Eos6t4iJPzIiH++PFjSxDdaHTNTzb2vvtPTk7i9evXcXFx0SsPmgsthWX3Z4ZNBlX0dUVT66MDGn33+x34ZWPPwC7boYI7BqT5mHWNMuYAwdvPlP4xNOEzXfrF6/Prfc9m7dZ0z7EgJuLZ+BKEau54fTwel1yIrG4uVbI/kivxtztvtTnR/+122zLYbNPzkXzs2fjVl2x3US3B2cFYRlMHkscWBzw1vUJnjsVl17enOi9Il/KwLB9TX/87gQM9z8wIumfRldxEJORnDai+WvFBZMBDAxfYcS94vV5XiXlMOVYhsD9dQMONHw2SJtXPd2C9pLP+M+FU332tWYxD2ivhcTQalfVrV0xZGJsINesjP3N8WT0EFGrTcyacZtkSDevguJkFrZKdS+BeBw/pYflcI3EMz4l/tSxzTHukBemje927ywAcn+kDK4xk1BSyg1Mfgyv5jE6fK58ExvqetZkZgkxh+u8ZSM367zzqz/eNgTRw58VLNq6sT1kf+ZvnJLAfMtj6XUt3MjhZX5i4KtmUbnGgUesXx+S2JhufeJu6qmZf+j6zPgcC3kfSTA6VRwAyW6n7m6YpwF808WcIwBT19eLzz+UVORfcBj+fz8uJwrruUb6u0nuOQ1chQWkQKLwaBI0AlZgTiGEjJ4xPciakEc8JOl76lFFNGao9/+6/eTZsVnwMpA2ZPwNqEc9bkrRk4ACJDMkDjnydiwJ9enoak8kkrq+vD5JxuM42m81iu90WBZCF7Wg4XHFmdI04PMGTApeVjG9Iv5OTk5jNZnFzc1PqXy6XcXt7W+hS60vXenWfIq/9/jlGcLfbxdXV1cFYu+qg0XfARTDvHrwDq4zHs9IFHkTfmqHzktGJvK5Sy2vInu0CHjVePJZXa333uXeD3qeIayXrTx8/ZG1RN/nzmSFW8WPTb29ve/tM/lDdOtGy1nfyo/ch63PmrHjx3XrH9NWNNsFPbX7puGS7slRHdqCXdDijql06qHb4mb77MoT+/ITczWZTlo4inp0ojzzVyk86AKpm/DKvVPf6VpkM3fkkZIZThWjw2NKnIGposg+BURG70jq2HTJiTdnQkHeFziOecyh4D2nvYcnFYhF3d3elLwIdUjbD4TBms1mMx+P48ccfDwCIh7CZuFijBQFKBjK9OJ2IorlW6Uf57na7uLm56YyaRERLuGrFBdv75sbX76m13cdf+p/JhZQyPRd6HJPJpHUgUyY73FrsoK3Wz9pn0iNLZszayEqWOa5xRrQdBNbttPLfMrl2j1t9V2i9q6/cnlprS6XPy86uH6N7jimZjmH9nisQ0c7FEt9kwCzzslk/Zd37QUeydu4NQch0Oo3JZBIPDw+t5Wc6ENJzdJgyXezOh/ODnvU8CzpYep7bJlmX+u7nqeh/duqnntF3LinoWY+sEuRwSYljUr+32218+vSpXI94nvdjHJ3O8yXdM1EnZMBo7DNlyjAXierIKENyXvyc/M8pxz6XGTV+rv2e3aOwUnafaKI1QxVuSRJ9dTy3C5IEmuvT+i5D4v30uVT0YrPZFDBAIKA2tIzx6tWrePXqVbqVVMdvk/n0bAac9DzPmeDvEYf7jd1ICMjw9/1+f3A8Mj2IiCdF35XklClGXScP1+7jGD8H2LJt1k2Bd3qIXzhGgi95F+y/5rkG0LLEKtXln2lUXGGyT108UKOD7qNzoX4Ph087XsRz5BWnU6aMM5BXo3HG7xyHR1RrPJEt32T3HwNef8q9Xdci2kvTpL/67ctdrM+XC3Wdc+d057OiM3nd+yu+PTs7i9/+9rdxfn5eBU5qK8tjyOZehp16i8t40odZ1M7nVXXzeW+v1mc95/wc0Xa+M9nlc5+jdxysZXzqpTfi4EgoC4WoUVfsHq7mYH1wjmSdObO1V28vE0CGf1h3DYE6WBJDHWsESCdnGoWxRqNR/OpXv4qbm5sSlpYRp+Blivfk5KTs1ycgEyomnWvhLwIWMprmVDsN9OIc9V8HQgn06Hn3IDNjn0WHRAs/SIvzpDF6aZqm7HSo1a/7MkWZ1ds1v108xnnuUupdAJYKi8ljNGqexERZlFLX52y5gM/6fOkzs945Jv33tVM+77JL2XdvK+MZGhlP9mT94pfJZBLn5+dxe3tbDhTSvWy7CyB68dNy/ejsjEfH43GMx+NYrVatezKaa8xcr+5S0s5PNT6sFdKBhTqiBqA015lRlF50ucuMVsZHPqZMbhyMad53u138+OOP5c2i7HsmLxHtkx6dBzO7Q8BAYy0erS0n+NIxE5cdDGXj9ggJ69H9dDClM/x56gZftnA7qGcJkPps3VE5Dposz4TPJp2dcWLV1papEI8xzn33dHkHGZLldzKoJkJhfIXFMuElo/G3TNFHRFxeXpYzGGrMr2eo1KVwdOqYH33qffJtnwINEgDVped08mREtIz6breLy8vLwqhKkmL7FNJsPdWFUn2mIvX56DLG2We24Yk+EjYZWb2Lo08Jyzjoef+Nn6VUPgfxq3juz2QyaXljBBRci+ShO4vFItbrdXoaXUSUudaY9Lx+07tXGLWiUnHwz5KFXAmsnG7OD03zdIT2l19+GVdXV3F9fV3As/NG0zwt0dzd3bV49qfMwWAwiNPT09jtdi0wWuML97xr4CQzoozUZvoue0Zt6HeXhwzM1vpPnVtz1na7XTkTpJazldF3Mpm0llO9zxlQzfqdXef8r1arsqzqTlJEGxQTiMpZ6JpXza3snfNSDQCp+DINk71V/Hl3rlyfu52VnPj88URm6lTqYo9wM2LN/vWVo46cdsNHZZAZYjd8ukYi+ElhTGTpEvifAhpckJyBuwCF1sd5P8fThTw9SZRMfHt7mypwhpuYX8DliMlkEqPRKO7u7g7oy/bYpjxJhnr5jIyTmLYrPBsRZZ1xt9sVhiWNJEDsgx8wQh6SIee7P0hj0t1pnu2YoPfpGeBdwu88omvL5bLMW1dxBdOlvCMiXr16VU5jVNRpuVzGZrOJ5XJZjug9OTmJi4uLct92u43z8/NYLpdxc3MTq9UqZrNZAbfj8Tgmk0k5tEpKQnOhZZ6medrHLfq/evUqZrNZK4/F54vj8PnIxqplITeU9Ip0r+Tt4eEh9ZToxQ0Gg7i/v29l8as+1ZUZKzdcTdN0OgWZcWfJ3hyaFdaTnSdD/em6t1ZfH8jp6kNNdw+Hw9YhThHPbxT1drP5zOaasu5A1EEhI2fiXe+vQL/3n9EAtcXvitbW6OpzwKUql22PeLMt0U76jBHOTMewzYh2voH42KNxGisdDPVB9zndSON/+Id/iMvLy7i8vGz9VtuKz3L0UoV7jlQiYgAnBBUKUZUbOf3PBKerZPf4s5rgjFmy5QSvK+IJPMi4d/WNIV7WL8V5fn4e0+k0vv/++5Sm9PRpcM/OziIi4urqKobDYczn89aR0OoTQZiucflCbfjana4pyUtnXlDxMkohEPDFF1/Eu3fv4q9//Wthvi5aMoKhQoCi35R3oXZFS805QQmf0+9uNFSosLL5Un9kcH38enGTojZUXGwja5NFClintdHLUSRhNpsVr+/Tp09l3hUNaJomLi4uyk6Rx8fHlgEbDAZlDAyPk1b39/ex2WxKxIIgWaAwWzZRER2kIHUPgYAACZWtnz+iupSfcn19XZbk/C2dAlL7/b6cvpcBRzdeXUBgv9+XJQnqsT7jQjBTm+8+3dL1bHa/t+tGl3X2gYna7zJIWuffbDYxHo9jPp8fnDBIetFQZSCsBtaz9nV/Nr6IKDxwDGBTPXK6lFRZi3DWnvfS5XBSN+nevj7qv4MPr5vyRkDv8i2Z5rIy+3JxcRGr1aroOd13jO3tjTg4SqdRlIERyskQVBf65JY5j2YcU6Rw9azvFCDAoaAe42n6RNIL5vP03rPXqxKFStF5+1LuFBi+DIlerjz91WpVlLKKnmFUge3pfmaJC1HLi5WBGQwG5Ux5gi/S5ePHj7Fer1vjytbWSKuMPrxX93nCH5/LwGbm+XghzWuvIR6NRvH3f//38ac//al44vv9Pq6vr1uAIyJab6ZkHzLDQh7cbDYF1Ss0zhyA1WpVEr+ur69jvV7H+fl5vH37Nj59+tQyvJIBAQC14YlSakPz73PLtrVmPxwOWzxNXh+Px3F2dlaW2wRcPZqlPoo2BE0aswNlAmi1T552JS5gzkTbwaB92JDrMT5LgNgHGjJeyp7JjCT5+6cU0YggLdNlP7V+9VH6gPpoPB63jn5nW5RX7y8/u6zSwanZCM6b88dsNmstLXEM+s/lh6Z5yovKlr5cV7qOYQQky/3gWAnURTttYffIA+0pbZOcH46b+pB9cHCttjkmni+hZ6+urlpjIJ36bPBnn+PASZLH1YWwMyMhz4rhFleufaiZzHYMGmSd3tbnFk5kxOHBS7V67+7uCghwheKRA06ylJ8UqZS1jL6elXfAtS5lnesAFnmrBFuqX8ZiMpkUL5TGVYCDYEUCobapADQvEiAZC7UvARIq5jxSQXJZi8WF2hOTanPhgITXHx8f49tvv22BK08CI1Agn3EHiYNuv9/D6FQgu90urq+vY7PZxP39fex2T2c73N7eluO3dW8Gml3p6v7pdFoiJeKf2WxWvHcfl6+Rqo9a0hiNRnFzcxODwfP7RMSTVED0vpqmaSX30ltiqJWJX+JlAQQux3BeJIOKlmjcXV6pZ8qThsd4Xj6/Kp8DQI5px3XXsX3L+leTCX/Glwoo674OTweO11k0Hwy905BG1LcEutMSEQXgNk2TzjF5OKOX04V8o0ggnR7KtEcrOT8e5VMEM5s36n2O00EUx8Q+UEZ5v9Mv29rctcTYVz7r7ZhOKHoGVFKevcpC5ZQNhiiXdWaIlO06oRgedSUuhdU15owpMu+BY+Hz6h+f6zr+lgIqoyljKlS93z9ttRyNRrFarWIwGJT3LUihSojUh81mU6IUJycnrTeySWnyMCkJs0LmqlMGjGEt0ZKCQkDAuZPRciNK8KBwfG1+HJE7D/nvWXGF7vfJiLKNjPe8jpOTkzg9PY3RaBTn5+fx5z//uWWMIw7PWfC6HEhst9s4PT2N6+vr1tHhSnB8fHwsIE+gZbPZxMnJSTnQS2vTw+GwKH4qHi2/8AwLygjzJKT8xH8M74/H4zg9PS0eqerTOJWXQ7Cv9rbbbcsJEeDVc4poqX0CZYJNKfOHh4fYbrelTT+fI6N5VroMdGYYadjcAGQ8mdXB+7O2ff3+GOeHIMD7WhvbdrttbQXXgUHuAeu/QFy2/KdCACi94t43DanvxOG8q76IJ/7zV73zPh8vZVpt1U5jJK84IM/o5s83TXv3l+udGg9Rph1UeB/caRIdPfeHY2E0w8eQXfdydI4DP7sQeBJGhsD1PUN/vqZFQ8REqGxiRKSugXo4kigyCzd5W+pLBmD4nLd3LKLLJk9KUevaane73bbeFHlychK73e7gbWucfEYgaoUGnx5txDPAyMLEui9DyuqLQBCL5k336O/x8THm8/kBk8vL0X2Zl1jzLI4tNSHOgCTHK+O8XC7LFjElemb90e+Z10KeZnQh4nk+dF0AU/eqHkadZEj93Ar1S0ZW7YpvHADqGeUD6MU40+m08NXJyUkBJ9xmqDlcLBYHhpy8Kx7jEejSAaqDUS3dK1DMXAXdL9CksRC81ea99lsfb7lecSXvsuPGv6ZX3HDUfvdxUK966TKEBBoy9Hr/j+okuJdDwXC4SvaOCep1FgFGAgrSUoZU+S90enSdy3W1cVM/Sw5VN5ekFXngUppkgPKS0VP38XNXvzhnWQSbgEr9FZ34neCcOtaBmdri3HMMfYD06KWKzCBwYLrmazV+v3eeHVZ2qJK6NDhNKNvSZ4bq+YwIL8VW23ZH4jmw8TEfCwQypeGFhsfpp7Ldbls7Ohjm1/08ApoKSkrVXyrjXsJsNivLDI40yUjcfilFLnp5fgLHw/VPRUf0PJlf46LgatyOkGshRGf8DHA6zTnP5KfJZFK8fdHGBZH13t3dlddy393dxatXr1pgTvOpZ50XnefUjs4G0HPukWWeTNM0raUW0oF0zWSQwJ3X9QzHwH5qZ4iecV4eDNqvW454zsN4eHg4aFMGgGFt8oq+i58ELN1o+3z1rcW7Io1oG3xftsnqcdn39piIXItCZp/7lLkXybi22PpYvW80zhq35kg6xHcyUP596VQJ1qpXzoPqVF3ymDPnToAg24Uip4nt+Bz4XNGOMAF7NBq1cjjENxqfeL8G/jLa06ElT9C4u60gQFE9rJ/ObgZcXI40LzVAQDmhfPTtrDj6HIcuIjmxso6pQ5kS0wB1iAuJpW1ZNaHRZDvTaW1/NpsVz2y3e946KGXDED2ND8fiSqivkOlIM32v1SPkSHqq+HWuITu9CTC4zYz09meoBLKtTq4cVJc8ay6P6BnnBxklCiCNFfs/GAzSKIr6IHqJpp7wSeXnSod95Hs/SJumaUpoVl5yV9axjF3E024FX6bgGJRXUIukdckY7xEfc/mDY3feIOhwAK5rnqviIVxXKNwa1nevt0fFVhuj/rgTKAP07tFpbtmvmv7i2nutH+S9vvmh4cn63DRNLJfLuLu7S9vM+tkFGrp+22w2RZYzD5N95HXxwnw+b0UcKdOiuRIn5RhInjg2zaMiQKSL9BRzHpQbwKVT1amokpaxFJ1SH2UExcfkh0yGFblQFCPi+cyciOcIH/WLG3SXuS4HlM84X7kO9ciq5oURoYzO6oPPK6NCNb4R7brK0RGHjLGcIEQ6LGKwjOA03rrX251OpwcH0ui/zjKgAhII2e/3ZfcBEwdF/MlkEuv1urVlRchT12VI5dlrnOq3gIsbKiJVX/sTQKBA6N5MiTpTOkJ1huZnv8fnLcf/z44AACAASURBVEP5FJpavayHyzLO+OQLrrmR2SXUel7r0zWQRa9T4W9lCBOc+lKU84+e564V9UvbG+fzefz617+ODx8+FK9NZTqdxsnJSTmMRvVmwJE0Vz3HAAQvTv/sPQoOEBmZUP8c1OoZj8xxLKyfbfjck/YZSFFh28733HUhx0PPKPxNnSEeJM/XDJ7qJP9mJQPamTHQfQ5euFuJbe/3+4O981kbWT+6QAKfzeY2+57pA+pRgWCGz7Ol1aZpWluY6eFqfpjwyh1gqkP3RDwvcWROj+7TEp0iqyoCi+7MbLfbcn6Jg3ZFLSIOdyQJWPB7xhtyWElLGmk6PKQPATTnxK/zeRaBBwEf9lH0F2io6RxG9GoAm+WoA6DYAW+IyoFC5Qze1RGtjR7TFxGTYITKyvsgJuO20Yhnr1BFTPb4+FjCVZos3y0gARgMBq18A62XDQaDcooaaSFlKsZkyEoT63Rmu7yXxWlNRnOQ5ojTwUVGZykNX4ZQ9ED36V73ejn+zLvhZyphv56Bkru7u3J/rV6vmwrg5uamyreDwVN4UrsZvA3mBmRz8urVq5hMJnF5edlae836xjHVSk1xsE3NsXg/i7ZQQTnN3DBStpyWNUOW8RLHLq9S/a3JvitlXxbz/ohGk8kkFotFebEZvTT2l8DS6ZEBgwys+7j9t2Pkteu3DKh0la66nc+8vxqbdNN8Po+Idk4NIwDkx2ycojnzm5inlOWaMKdCSxE8YE6Fc0mQ6b9x3E3TpJFDd2YkO9zm6HqN48t0lT5Lx7te0xilVzzPyJ/TNTfslGc6uu5QOF94REy/0yZ1lV7gkCkBnxB99rUVdswJqv9kJA6Q7Yq4TghOhhTGeDw+OI6UY/GQv+ogYxK1sT0Wf4lS0zStNTNHqKxXRkUH8GQGi8icRoeKjgbdw1UcHxmR/ZZQc170rO8IyUBLl0KkMLrHx7oo5AJVBIQsGchRHU7DLHKVfeeuDM8h2e+fdlj88MMP5RnRhTtROF7S/e7uLu7u7tLzPdiPPoTv43XZotFUO1qq85CxeCVTDtncEjgwiuBz4aAwAxfervixZtCc56kDXN9obs7Pz+PVq1cxHA4LKHTeo16oLT04P/Eeet/k4cxoc8x9wPBzAEVWuvpcA0WeTKd53mw2cXt7G8PhsCQsZgBP9XIZTAaTu17YpkeYqe9kHJUETjrz82AwKDlaniPTRZPs3SDUj2qbBll04v/MJgpwRLSXCTL96rbJ/4vXpZ91ouz19fXBGAW2lGPlvMhlYUYQu/j2fyXHwZEPO1QDFbV6smtU3uw48yJcKbM+Kt4vvvgiBoPBwdHANeWc1cfxUXlRyTtNHAFmSy+sSycAUhmqHiVPdYWWsuKKVO1pW5Wj1VoEYDqdRsTTS60kkFx2caaqKUUqFYXSSGce7pOBjqy4AnRjwnvEO131st0vvvgittvtQRjZx8lQJxUR+YGRKl5jP73PfSVTOhHtd4OoKKKWLTEcw1Pqrw56Go1G8cMPP7RyZjLwkdWTAeOuMRMIZLxVU3YRz+8x0PIhFaRn8ssoDgaDYny65oMAzWW+pluOmd+a/GTgq6tk+qirzYhoOSWkOfvOxGnqpGxeJAu13I3ss4CEPG/OF/tKmihfYT6ft5wv6c9aH6UTPDeAJwP7GQ581vMoItpLgR6Vdz7Rd7bB65l9EV20/E591zRN2S6t+7lLSf1jvepLFhmuRTO9HPVabf/uf05c3UuPx41upjw5gL51RxJcRS+9OTs7O0B5XYouG4Pfz/oyxeUTrknIgNVw2N45okk8OTkpSUbb7ba8WMvrkOBw4onws6QY/REsOI1ms1lL+HhP9gwVqRtFCZnTWB6me2Kkm79QirRkuDSbM31mxERjFjLPxjSZTGK5XKYRhBq/MHfF+SQDjM5/3p9ayfiI7WWy4koo4hlw1JLEWBRK/frrr+O3v/1t/Mu//EvM5/PWkpXqE60Z+eGYM9qp7zVZUt890qjf+Z/8/vDw0PK8fL3a6Snjk/F61lZtDrIImTsFXiiXGb2ytr191y2kqdO39jnTxaKb16//fP+I/gtYKAEym7NsTv03p4/3jTlYp6enJR8qo4P3IdOL/rkGGCRrAjecO9eBmVxRbgTK3759e2DA9Rt1WNM05b0s0juua9SuR2BdF/FPfZ7NZvH69euW7HWVzzqb1Csjksl+d4WWTWqNgbra9ftZrq+v4/7+PmazWbmWKbSusWWorq/wfkfxnKCI50x0FTLd+fl5LBaLVgiv1gefZCXj+Dj9PAFfm2S/9vunhNIff/yxla3PEBeZW6/eVn9EAwmZI1gKoYp/z4wpBc5BDWnhvMVTDt2I8ruSJLNQoD/nEZcMhHUZDIGjbDul36ckXr7BlAqiy7DW+MbXZdm+8+0333wTj4+P8bvf/S59bbS3m4WLVRi6ZqlFnDg+0cL1zXK5jMVi0XpGhevUDk51793dXXz69Cld6usDdF26xMeTRff4ezaPmb4lEMoAThf9+0otN4ntd+kjzpn3i78LZOh37tLq0tGsQzI4mUyKDvLTZ/lMlw6Xc+v84RHcPmCgwlwcPuvj2mw2rcOhqA/oANbowSTTzI7qM/shZ4V6bL9/2tWijQbHRB16uayG3GQgKZT6restajUUSHTkTJchJC9iKK3NsQ/ev77x0nOvIe7sORoNTz7pSmijQRyNRuVNhzKg2lIq+ux2u9aeebUxHo+LEuU4NQ4lGZGBnB5aM9Qygl617MpPf77W78JLHvBtWlw31zVtt2K9RNQRUZZSsrnwbXu73a71Ihf2kX17fHyMy8vLg7a8PDw8lByan1JE79FoFIvFIhaLRbqEoe9KcMwS0LpkSvNGBR0RqTH2OrgN7Xe/+138/ve/L7uTsqUP9s2XbdQm73evyBWdZ9RTmbpzQV7V8xyzK07SzPvstM/mxIv30cfubTiA/xyjqZwkOkV+v+8wUJsZ//SVzHkSfWu852Fx1wXOC2wnA0TZWrvqVh4E6ZjlZrG9LPfAeVrP8T5f/nAdI7lycJzxF3lC785gOxHt3Bi3o2yb/WeENrN5DoA4ZtnOY+3k0cmRJKIj6oNKcWpeXwey9mod9wlT8QQn5hioXv3PiMn6XTG74nUU6v3Tf1cUXjfLcPh8vsHFxUXJZlZkQh4n2xUDaMlDbet+taXcAvWJB3xMp9Pi+WqrKgVBz1NR+ZqxK+2zs7PChMzuVYIVhWS5XBZvQYmiWofmYUEcM3fH+DyrXkZFdrtdKys84w/lnLin4PxBvuB8Hyts6rP69nd/93cxm83i3//931v8kvHVMWvGelZzrrFoi6WDW4ILXVNOiwyNEtTo2THfJcvnUfifvEnAQHqcnJyU14GLl1SvxkVwzRfrqb/cqqndAPLkjnEaanoqm/sMzHQZ4y4eEXiv7SrJ+pRFM9lfbmWugZlakeEjIOwbE9uhU+IAgH3xJRx9pwdcK+Lv/X5fzkOhQeSuMe1yI638RYj6jTolM659/dLvfNYTqd2pcb7jWMTbDhD8fum4rEg2qbMp/6pfb+GtJU1npTc5MlOgHAyTGHVdB3Q4szpCyoy7f2dbGXLL2siExpFbZpQcNPgYagT9HHDE/ug5KUyeFyHwIINLz1900N5jnk1xcnJSljpkwIfDYes12QJEOrhFyluMywQ4MZ7q1jwwC5k8IsWl+vUK2/2+vRda45dwz+fzmM1m5bfa+QQ0olRM3MI1Ho/LuzwkWFQK3hf1vQYw+3jh2Pkn3z88PMQf/vCHKihgOxnf0bhznEr84rsaptNpmUue1ieQySO+NfcORvUODPGW6iDQ1PzLwGs+CUIZRZIM8uRHFY9gkU+4X10GR59FW9FIS1BSnDIsNWfoGGcn4wOvg3pF9w0Gz8cl65yQWl21ovFx7CyK2HU5RLXxsN++dCIeq+lVj5r6W0lZSGPSiTJK46br+k0OzhdffBGLxSLev39f+JZtiG9EN/132eEZEz53w+GwdeaEeMztBunGqLmS3Elf0o/9Ij+6bazZp4i2M8tlHPGH+qu+KYdMZbfbxdnZWYn01uaNpRM4kJA+2SJkFnrKiiPOrtLX6S4j3zRNK4zP4kTNlISDjAxU6L5af/17di4776VCGwyezobgS38kQDwEK6Kd06B75LlT8Q8Gg1bmsWihe6XodZ4G180Gg0F5sZboSq+CxlYCKANCoOICpXnSWfCnp6exXq9bIIOASM8RYVO4p9NpnJ6exuPjYwFCw+HTuz7ev39fTnKUUWVfOBcZYFA5lte7CunlB0d5qfEYjTGLL61Jeeve7XbbWvbgW1cF4ujRsS7NiXuL+p285rtlyOO+V96jQXxuv9+X6JmiF7pX4EFyo8xyjVFREhow0tNBQp9OOqZkukSRHzlTERHL5bKAsdqppse0VeOd7Fqt3ozHa/dqPggAsz7xNEfftu5ty7jJacpkkoZeRk86br/fx5s3b2K1WhX9KPCqP313eukz+a2m6xXhoGHl7oxsPggyON6M7yhLlBHSlfTm/X5vRmP/7rY8It+dVStHRxyOqcw7pOdqhtUFmb9lpYacXXHVBIdAx/tAD4gI2MOmn1vUJkNVtYODHFw58lQfhKIlPJpw9VUKvrbWRgaRQZAwCmBQWN37kKA5ctVnJdmI5vqNDDoaPR0Hri1GV1dXLZBBY0OhVvuO3LWc8unTp6JgIqIVss7onF3PeNfv+xxeoMeg5xipY8lkouaZqCh64DJE71SG2ueWgNKNmNqkYpViE43Zt0zRkfe9Hj5LGkU8r9f6wW3eFmnMtgUi/N0a4klX3i77mezVSgYYSEN+13Kkjzurp6s4vX4qkO17Tocrad6ZQ6G5JdCknGuJVWA1op30R8O9WCxay6Xqm8sdd20IpEyn01gul+U+8TyPt6bBdCMvXeFbq13/ccmPkR7JAp09RV/evHlTXgqnQtmv6ReOn7q8ywFV3Yxgu5NFmrqT4cvOXeWot2OyEV4/Bu32ffff+gShT8hqAuXtujeULZ+4J/S5RQbN99lSYcmIqo9E4RyPGLFpmjg9PS3PK+TJtTspaSpt3141GAziyy+/jO12G9fX10XRRjwvj0hZiE7MEZjP5/Hu3bv48OFDMc7O1Nk5FARQQvBqw3MPdI1CzN/4eb9/Pl6cORp8RbbzhQPdmtHm/fy9i5dZZ3ave2IZP1PZsi4vGr+vLTtPE2CStuqDj92/az4ZsqVnSVppzPImCRbI45kio/Luy+0gDUWrjK7Z3Lr35Q4C9VFWarzE3xk549g1Bz/X4P+U5/t0OkEd5VrXpR+kB5qmKVFSPc9j97lURrBKOnGZQ8V3n8mAiqeapol3797Fzc1NAQ7D4bBEH7RMwHC92vNIrZY4/X0rThd3yFSo40k7LRfqZYVdYNQdDF+uIOhiXfyNtkP08PozUMwTkI/hqU7gwIrIUC6Qx4Q3MkPuitvv9zqzcJPXmdWV9YWGMBsff+dzGdNkhsGVoD775Pk1ghXRVQp7v9/HcrksKH4+nxdBIRPRs9SWSXkGPHjk48ePcXZ2Vt7Ux7YlCBHt12pHPO9qUPiV6Jlh6ojn3AO1rbLdbuPTp0+t+RsMnnMeuGZZQ+UelZEy4X3kYYEK512v29vx344BDV11ZsVBE5/J+LrGc5nxpuGmcuRZDuR/8Y2iV6qLwIOyQPDAOjIQrv55wiZ37oiHuazEPAa2K57TXBJkEeBkUSqN3QEW6eHzX5v3GsDkc+Rj78/nFrYjp6B2KmKNf2rFQRhlxF8IJ29fJ/ZymVhLRqzXHQDqpYj2cf7ZOBhhXa1WcX5+XiIgV1dXB6+XZz3csaBCHiEPSgepbdcpus5Ii8YontntdvH999+XdtzQM6/C50rfafMkB+wH7bE+01Eg3TgO6gNGddW/Pn3VCRy6FHf2ndd9fYt11VBNX4dp2FlvDe1ngqnJ4Lgc/eq+Y/pc65eu+z5brb36C5Minj19FiU/auKVPKkDiySgPHbVwZ62dqoeCapO19R68X6/L6Agor2/Wd8Hg0ERSC0LRDyfFUHm0wto6HVqTE3znESrPs/n89bLrbJQPueRgrJer0tCaTZvbgy8Lk/O428qGgO99p/i8WXjODYsHtF9TDIBnLwPenICZ6Kb5pLKMBuT8hHo0Xg0Ss96jk3TNCUpMOL5JNPhcFhCpAS78tIi2ju0xLsEG/JApagJJqfTaQHWbqzcoKqevhByl85Tf8W7tXv4uQb+vH/+7Gw2K3Mio+dFNNf5G4wA1vhH9GEfGe103Xt3dxfr9ToGg8PTN2veuetKza2eEb/IuHL84u39fh/X19fx/v37+Prrr+Pu7i7m83nr3TPZrgRd9wgEc2O4FMKi8fiyTM0ueWIm5UT1+FJuVpdf0wGBWSSSOReM5Ko9Racp80woZ/+7ylEvufJChsruqxFAz34uEKn1x0FDNtGsNwMD/Jx5fccWH2+tLSUwZs/7GwE5BtJaYSWe9UAk6uBos9kURSPGElM9PDwcvBFRhQpZ/9UnZdn70gKFVmN6eHiI5XJ54JX5/Dw+PpYtf648MxrrmtpTaFL9ZSRMURqNS+07nWvFQcfPWcJiIXCoyUzWFz2r7wRHEe3TERni9dAvlTa9GzcSWd3kGeYSKKs+M8yim04pVdIq12IFHqR8udbsO3N4VDDlVyBb3rArewcPpKuez/RNTdfod4HKWgSpb26PAaOSafKO65TB4Ok01Nls1jq4y88J0PPcxkhjJFlR1DADMfRwaayysVAvSd/5/Zp37foRYNU9cpB0gJJyGk5PT+Pjx48HfXTPW9EZX67m5+l0GrvdroAhjVVjqPEOr3M3Buklmqo+ARaPIES0QYee5w459ov9ZLu0b+wLc1f4bpvRaBTv3r3Lme//lqNfq52VrtCGr8/4BLFkISSWzMh7/fxPxeIT4fdla68UMNbH7139pJLld67X+3MavzwlZrhTwNTGdruN1WpVFDY9AhdsR7N8iyfvk7KhEZCQcZ3QDZxvbdSY9L3v3e40XGJctZvRNuMT/U4FVzMKVHT8ntVJ+tTazO6vPcPrMmDcNdJnWLrqo2JjmFbjEyjjy9iyZUbKk2SBdO8aZ1YXeUN9Y7sOtsVvw+GwRK2Gw2HrvAPVKQPAcVJHeLShr28cuxsK8l0XqKX+qOmpDKQQ/PTxXhZud36UU6D5U0LycDgsJ6RmfEd9Jd7UTglFh/Ssoln6LGdC9PflK3rcMuJsU38EKQL9zLFR3ZeXl/HmzZvWexxcFxIUqG9annUjLrrt9/uyxOvzRH5R3/10XtLQ51FAmUsP3o7PCeutRbMYWfC6yCeus+QEss23b98etMFytNtUU5wZaMiMJ5/xe7luWrunrz/ZM74+5P1xoRZTETTU2uhSRmyDDJXRqjYuLWlQQep3Kl0XzK4ipiOzcu2raZqyPS7zKjKFx3HRoySNfR5cIet+CVq2xhnRDjGyL/qs8y+y/roHzELD7XNBoEuU3wVMvI6u331cP7Vw/t0A6Y9KX0tIXWPXf687AypUWH6ctsYv/lPEqrb9TvpAtBHd2Vfvl4MPlYxfXFbIb85//O56zQt/yw7Aqz3bV5/rFKeZR4Co+xgOH4/H8c///M/xb//2b7FYLFrjd9lQnUruZJhfbcjocMurwMNg8OwZK+rIHTLSQ7rv/v4+1ut1eTkbQaKWOgU2VOf9/X387W9/Ky+lk8EXHR4fH+Ph4SHW63V57490lN6k7DqMekvgO+M7/3OdRX2nP/Ex5d1BgOrSsi15j0CficW87nKQ8Ww2Vu6W2e128fvf/z7lSZWjIw4/R6n11dlXd4bOa+DCPQhNkE+sh2dJyEzg2Ub2u//G/7repXRcGfjWyIjDHR9MbsvAm3/f7/dlOUD5FLrOZ5SDwZAcl0wIEnhYFL0DKmcdMkTBHg6HB+FP9YW7OnwMNDY0WIPBU3hRoEjzSuXkHoADGc5XX3GFUYuCZLxzbHFj0Gd0aCS4Zc69Oi5dcEdEF6jldjP2R8rPz92gt+r99y1iNFYRz7s/3AhzzEze9EKe9kx58rIDw0yh6r6seMJb1719hY6A08V5p/adnjbnXeN/fHyMP//5z8WQa4x9Do2H6pvmKSmSQJRLCnRMsqWJzMHJgDN3T7jnztyv9+/fxy9/+cviBDGpVm3LsVBfaWgJVNUulzOk51RqeRt0kFS65L9Gc0VTmLOT2TXe733q40PO+X7/9M4W6rK+pdufvFRRY7YuRddl3LqMcVc7ujciDyn6dTEWDbr3WX/evq5niTPsC3+nUa0ZD45FqFrXFV5Un6W8fd1WKHUwGJRDWiQoPLteTKkT+KbTaetwpOl0Wg7baZqntc35fF4UsIRM4+GhQPI21J6YmcssNFoKnVNBy2i40GRzRYUpEHVxcVHu82z/Gu1rBvkYI6Bxky7ZvHZd66u/S6a4Ns329QZM0lZKkGuvPDE0IspefRpVzZnyZJxfXW7ERwQvlDsqfiX5ypMkHzK3YTQatY5iF6/xLBHKgv5oSN0L4zMcC+mVzUWX4+KfM0BBYMNSWyrJ7qNRFH3cOSFIEt0uLi7i4uKilUideau+G4I05RKE5lenVUpn+I4dFXm3Dto1Lj7D6GjNGO92u7i8vCx8PBgMDs5U4DMKy3POI9rglLSQDDnNHSD5MpkDBOn1rA0WRtrc7nA8GailQ+VOZtaO+E19o3PYV44CDl1omso+E6hj6nbD2pf9m/WBdfE5D5myz0yi03USr9Y2oxh6jsZKXndGj6xOMZafaMhseH3XnuimacpJi/LAHOErZMz+qC0BkohoGXAlAzG0prAe92ZHPHkwPNxF7Tvj7Xa7uLm5OVCWNHJ6Xjs+svB0rUiRcVuql2w+u/j1WAPfNM8nMP5Ub9Prc7B0LIiJaG8/9aUI8oBoJv5Q/6m0Cd4inrP0Ocf39/et5S7VyxdsEeQyOU3XdC+z2T3CId6TgfBtvuIZFSYNe1RApebZMymYxjcL6Wch/L6SGRca3VpOEPvrAIOOkUpmXHxJONPt3J5HR4h6k3XTyAuMKKrpulXPMiLVNE0aOSJtuop4YzKZxMPDQwyHw/LyK9cHDqqoI/2dIQS4fI45ebPZLH75y1/G+/fvC7/WdLzeCcHlC81JRDtC3jXmDETxM+U2221DUEzd0mXnvfzkiAOV/ldffRXff/99bxKcl1pH+8IktedpGDUxXOtTybb4qDDzPOtXzQOmgvcDn7y/KhIwXw/1CIkfy0vkyiiKrlOR8npEtLJnmW3NP1eg2nLlyoIG3gXCvTrSj8BDxk1KhUIqRXR2dnbwClrOj+j4i1/8In788ceiPFQ332b5ucD2mFKba/c8CTB/bnsR9bf6id+l9N0biojWurTuoUJ0eREfitf0lkb3eNQ3eny+RU9tDgaD1NOTIaHRUj/EKzpXnyCHc8x7s+WEmgw7YCBwypQtaZiBga754/cuA+pHgTNS4Pot441a24NBe2lR1/x+/mm7tnvPBAHqk6KXo9GodW4Hx6rohF5epr67PmJ+gi/DaOyLxaLoNEac3J6QVoxqcEmYPEeHju3reYFnFucPyReXagSw1QajCR55dqDon902kYbeF5erzI71laOAQ5eiE1r7f6GQvXQhogxFM7FEz3HSJYwq8ob4e2aoPMT2U8cuwRVjSoCkdAkKxLB6cZByEDROz5R3RuK6HsOO6r8nSZJmDGnpfiqLzCCSdhLM2lq6MyuZeL9/2q/toMWLlmq++uqrsq+8aZp4+/Zt/OEPf4jb29sDj8zn/5iSGf6MH0k//fUBYiqmrrGqkA/dq3RPmIrOQZT++/HM7hWxzv1+38oboaKjjPncdkX0yId6jtEcAQT1j+8NoIFwbzmjfUZbjZdjqilq1eHGkGM5tlDZc5ulivRSpuh9LC677EtNl0U8yyjbd9Cp/3xfRdM0xfiJfqvVquwMU/FXfasuee3D4fBg2YkRTC5j0cBHPC/LMTdKESw6NU4j8hn1XM3e8TeC6R9//DG1F/6soiCiv3hT0RKBLAJ5zT37z5LNMceU8YpoRx5nHceUn7UdM+LJs/jTn/7UEsyMgDWjnzF9hpK6Sk2giOBdeVGpsC/87J6zF5809r0LbLEft7e3rcnkq4gpAFKci8UiZrNZ/PDDDy2ak/mF4skcg8GgeAtN07QE2bdFRRzuBolohzAFena7XeswKwqqgx4HcRqXgxLWI7pkc8SyXq/j22+/LUpsOByWUzapFFQ3DYor1Ix3M7CT8WpWh6/ddikmH+Mx/BfxrMiomAaD58OeHCBJ2XJtPOIwSY0Kzncb8V7+zjln39QfAWPdz357eN1lyb9zLn05jobB6cVnSXsPH3ONneDJAQkNXNYeI38+p26MHFRx/lzneB0qXof0h+tb9cnlPZMBLh1xjIwUah540BDnl9HFiCiJmooQkn/3+30sFov4x3/8x/if//mfuLq6Kjk4ul98vFqt4uzsrBjzpnnOtWGf6c1THk9OTopzxTlyuSEoZr1dNiqL+qluRkioC6kzydO1qDfnvxaF4nhrSzgaY5/96j0Aqq8CeiXHlAwR+++178cY46426flmCJ79EuIjU1BYqDQZpvP7slIzTmRmnu4lDzri6SVOOviJJ32JUVxxKbHSQRDX8zRWIf+IaL1iVfPLQ1O4Hq0/KgTRUzsd9IzoppPaeK+2H/k4SDMHaRz/4+NjWdY5OzuLL7/8Mj5+/HhwOI4UB6MuGmemACjIHiqtgQLnJY6TfY6IAz7zQqXhJfMosr7y7A7+Z5hffMdIEr1dX4pkAibDzb6sFRGFX/SZ5wvs9/tWqFb/aYyzA4jIf+It8Z/CwrXXs9cMrytl/ldxHpDsEmT4Mw7y2S77k+lG/000yYArwXYGaGuF92fgRkXzxvsykCYZV385Fo7RDZzny6zX67i+vi5vSaXTx2WK1WoVm82mBUx9yU08mO3SUX/IUwQZnCfN3jjGSQAAIABJREFUdWabMt1PWawVAhQHEXQAeEKwt+sANCsZr2Xz0mfTf3bEwcMoNaPIzmWCw/v4W1ZvJih+j6M01u9ehooUlH5zofRtYi4Q/owDiox2rmTYVwkBlxj0fbFYtJY1pDS5vS7iyRM/PT0tDE9ErecoJEqY5G4EFzJdlwFwGpC29/f3rV0PMj7cykX6zufz8uKuTLhJJ3p7VKLT6TS++uqrGI1G8d133x2Mw73KLjBLZcJ5dVSvfrB0gQEW0V3RJtKlpszd0DHsqTkiIKPSVPHcgIjntyGqTXl2Mu70uBgObpqmtQ2OIW/1S143QYwSbEl37ilXW1onp+FS+wIYy+WyJMgKDDM5UsVBjRuOzAng/yySQrnwuePz/J7pQrbDnBPWJf7gPVlUjnUdw4e8h6BNhkp8zyUrgkFtyY14lhHWlRkjBxyMAos/eKYA+Yl0UL4Vt9+KxuI1HmTnnrto7Plj6pMKz7Qg3Ql2SEuNp8YLDv6kp6lfuBREUKP6HZQyMsF2OLdZXziWLKmSpfNXvpYzK+xADeGoY5zQDCkfU45B0KqXuyY0oT5BGkNmVLJoAwWYyrM2Znol/hsVDidb3iF/c3Al5Swj6wLPdpgdn7022Q2fDp0i6HLmEkhRvkVX0b3z+bwV9RA9OScMNXeBTS+aF20vPT09je+//z5ub29bUQ03GCoMIzMS5cLuc6dMbHoGvL/2vAo9LtGptjzm/Jpdd0+O0R8t2biSccOoz9w6KV4gvcUbjCBdXV21lsDIv/IGpZwJcAQc/FySDOSy//o8n89buzRUL7cb12RV9OG8ctwZsOfvlMsuAMq2aiDCS83r83s5h9mSX61t55escEuv5syXnjQvBJE+l3Qc6Ag530Y8R4uYNEiayyGjcRPPLpfLwrsCCf7abM5bxt8aayZHvO6OYW3us2iOf84KdR91N58hkMn0C6/T1tAx5DISdVJX6X07Zl/JEL13XHXVEFCNaT8HXGiwXCvlpPI623SkrueIph3BdQmch5DYlkcsqIQ0qZpIR5JE2fqN3qO8SX/fBRGsjKNnm5PB5KnpgBcpAS5bsK/snyNrv57Nc2bEHWBEtNd/NX4pCAn2ZDKJL7/8Mm5vb+Pjx48pKmd4XKF2N1zqky/V+FgI2nyMXUrEadc0T8muzu9ZfV2fSUO2xfCuA2tvy38nf0pp+vzUtrJxzJIptqtcHO7AUHvL5fIgwkB6UcHpv0cAVHw5qY+ODlx9WaILUGb9zAAIx5rRrW+OVX+Wt8Df/f6s+M6riPYOKEagGGGMiALQxFtKnJSxU50PDw9lR1fEoddLp3K73ZbIpxwpbbmkEZUukO67vb2NxWJRaO46TssdjC6wHgeCk8mkta2efKf7fNmIhfUxEpzROZsr2gvaLweoNTDo9WX16DfNNWndVX7WUoUUjIfofAAuNFk9Kl339fWFRpvCTC/NBV1t94EfAqQaYvQxM5rhnmJWxMCu7LP1firK09PTEvLNGNz7yDqJovmbPAOG5Rny79uNkCkGetRas+4qmYHVWBTOXq/XMR6PYz6fx5dffhmPj49xfX3dutfnlte5/1//PUxHfiHoI20z5Z69HU/31oAUjbMbbS+Z90v66B79eR0OZPW88hxqpWbI1G/pBB9T1n/xAuvQvTzTwGlFkODLO5Q7bQOsyR7lxI1vn+Fl+5lOqOkD1uXPEZjxOp91DzNzatiu972LHvw9kz8fo+iuiKLTi8/LILlzwOUQ3c8IlZakpD8or+LXwWAQHz58aG1v32w2LVCqJTvuVlD7fF8D5Y87PdyW0R50gUcVLvH4PT5vsq36PXNIvd4auOFcUff471lUulaOSo7MmIwTniHnGpruQ+j+vLfvk9iH8rOSKQuvW991n0dMeF8N/ZE5OW4XfD2nUNvDw0O5pgxi9YNhOCnk6XQab9++je+++66EZalwuE5MY0MPICJax/jyeFgJrYSeiozKhEss7p1yyUQ5D57xrIOoVBxdO+3V3nK5jN/85jdxe3sbFxcXLeZn1MGfd6Op/76Oqf45Xzkw889KFuxaf84MRyYfLjueoMZ7ZfiZP+DAMOL59dbkN80NeVSggwqX91NGtNyl52hYWYfG4ffKMOgIXPJyBjbJb1n0kLTuk2/yGmU1A15cpmJ7nH8H/W68s6J2CEyprzxiSVnUZ6+vNjYV37Gh4oZf1zKnQHOo/tfq3Gw2MZ/PW7TPZIDRTo6NkWDZIC2T7Pf7suWROQEqyg9TNIMGVcsiOuRMtKZ+JJ+y+LxkxeXXS6bn2JY7El2F9xG0+9KO6xder/GnymdHHLKK3XDWDDPvz0BCra1aqQmCI/ZMYPsACPM7aHRrY2CdGRhRn6bTaSwWi7L+7nuXPWuWLyOSUW+aJmazWTFKHz9+jPF4HGdnZ60XtxA4rNfrluGeTCZlx4MMrRC3DveRYtR3enakjRSGJ7VJoJgRr2eGw2E5QEi0VOg6Q72e1KQIxng8jl/84hexXq/jw4cPLQGlsaRCzuafn6WQ+oSnC0g0TVOO4SWP1YCB15Hxlejq41NSKZc7BMQ0H9xhoDlTMjAzxFWfwqp8/wRPLdU8cOmBoEan5EU8r8MuFos4OTmJm5ubsmtnOp2WXBkaOT0nXmuappwNoHsJeGqA7Jjihln1uGes37jzhIbU9aBfY73isYxvOO81vaj/rM+BRAaMs3pIB40viwYy4ZFFhlrzxbdKur1gxCAzwAQFnuSYzbFkmuH1rF62r/v03h4CPDlMBBU1YMDlz2wM/F0ylclLF4gkD9TsaWaHnO8ysMw+O626Io4RPcChC4E6QvFnMmHUb67Aa4rUURqFyz2XPhSWKWlfq2XfszU/HzeVhr6TyZ0WTdOUHQNcZ6OR1etrtR5Mj5nrfHd3d60w9Pv371tbOOmFaKuSxiPDrDYkKAwvK4diOByW7YwSetalUCDzDvygJ9GS0Sl69WLUyWQSX3zxRbx//761ZZY84OBDOQ2fPn06UJY+7wJeEc/oWwld8tC51ko+9XA75949sIz3CAYzRZEpO/2vKQGV3W5XDPFw+Pz6adFVfEc6UuF6fdyZQJDB3BkZcJ4eGvEUsj49PY2PHz8WeiiKMZ/P41//9V/jP//zP8vLlhg+FcjVmDjX4q2zs7OIiLi5uSkRKipU1adx04h6lMyjFLpG8KhrHtrmVmi15QdoUU/pu/rYxwdZFKFmcKibunR2XyFgc/CQAUVvw424cqPc6SHNFaHyZTfqh67x+fIP5axrnHK8Ig6TApm34QDI2876xXE4z9WimWyLQIVRAl33xH23TeQhFS59H+MQMRqcld6lCq/wmEZrjCqC9nlz2SS5ERWhM9DhYXIxlPqfhY7ZbxoFfc+ATN/Y+YxKFvakYqDBItMqzKYwGg85kWLP2lPdzEVRpIOCTLCjTGl6MhFRDnbxRMnshDhfLnC66BqZ/+7urrz+1vuvwjyE5XIZr1+/jm+//bblGbiw6n4ap8ViEW/evIn9fl/Ofri+vk49LQfGDMFTeXg0gHzIpQXd38dHNHiiBX/jThAHAFRUn8OvKpQRAlSnCedHIJX5Nmzn9vY2/uu//isuLy9bANLr9HFQsSoS5v3zcZDHyN8+Tn2XUXz9+nXc3t7G/f19arCyeaN+YX8Z6XLA4o5GbW4IYGr3qtBTzsZZK14vx+A8oW3Doo0n2Oo+bpPVdY/ash0/+pr3ONDocg4i2ifUDgaDsvyg7c7SYwJ73k+BZMmwn+aZzTN5i3pc15VoKfpk/c6iicPhMKbTaex2u1ZiqgMNFs4D+0UedJ3G64PBIG5ubqKr/OxzHNQpNqpO+zXey07rvyNMfXZjH9HeWkPGd4OU9TMrvn5GT8X7wmd8/P5WOIIRCqOj60wR8xnRh3kEFFrWSURKsMa6XBB4Xdf07GKxiFevXsXf/va32O/3xUOQxygh2+12JXzs3jppx/ap5PmSGC5LsG/0ekU7V2KsmwlUX3zxRTw+Psb9/X28efMmVqtVOY3OgaPPh4NK0lTP0msaDp8OoXp4eDjYcaBCGrtAu9woIjOfz+P+/r71cinWR96kItTvzsO1z758IZDKetgWgRvfS8DxbTab+O6771qevBcaP54bIXr/+OOP6ammGXDIQBH1SaYPfvGLX8TDw0Pc39+nCpnPeSTA9Zx77Nln11+sp8YbXtxwZYbA5Y/9yNqm7Om6HzFOI+5LOsPh88mOGeii0dYSJ3c9UFeSv1Qn9bzrEvVfb2g9PT2N5XIZHz58KCBA90nnaxt6LdKpPtM+KDKzXC7L+O7u7lp9HQyevPflclmWErPoNf9T3qbTaXzzzTdxe3sbd3d3ZSlbfeCyMk+hzIBpLTLBdpmz1FV+NnBwZiC6z5A5P/sAxDgKjbvyzNrmf372+jPwQcI2zfPpc8cIrhtar9fbkhDS0NaKGJR1MElICnw8HhdDHXHocVD5a9sb14ipFJiEGdE+dGa73RZDJa9D9KLyl8DzhEgpECmKTNFzjpy+2W96XksLPIgqUyRUaL/61a/i8vIyPn78GOv1uvSJ69levH0XcOUKyLhp7HrZWE0OMqDGNjkebXO7u7trJcbyXtbJsL/q5vxyf763qTo0nx4tIaClV505Cx5ZU1Iht6Y5WFY9vh2NfK8+0GjLCGQhdva7JnubzSZ+//vft45Pdn7y4ryR8UmtXdZN2rsXTwPdxZ9d9Xt/pEeyiAENjYfGxdcqjKrpu/IdNB8e0if/SM9wSYNg0cet/vA+nhpKvSXele6THBHsqD6Cl4hoyXFGbz2z3W7LyZYCE6T1bDYrB5PR0ZDRd3ry2YjnLcv39/dxenoa7969i9VqVXT9ZDKJV69exV/+8peDSJzX5XPB8XB+s6irl6NyHGohkezeLmbNCpnCDzOqtVmrK+JpjZXZzmzDFT776GG5mhLn7xwrBacPcGRj0DNSdDwwRXkP6ud8Pi8ntTHXgwlKQsM6YZLXfR+0rs3n84hoJxDpLHl55mJ0HXstBaH/7IOiE9zbrfFxe2bEE2hcLBZlzH3rlBFPe8MvLy9L9IPzJcVC0PLDDz/ExcVF+V7zhLI5dV5Q4ZkJPq96K2cmD1nJFL8Kj82mJ+RAUYaZXr+Uq+5hgqvTbTweF+9LPDUcDouxVxEfUvmT76l4ld9wfn4er1+/jtVqFd99912MRqNW/oxAJ/f6Ezwo2VS/ZWFwp69n4TtdHRD4kqYbfRpdzoP65G37Pdkc+86UrG8EYjWd6vdmTgT5NAPKdEx0j0dUnOb6THnWfU5f1cdoAunFvJdsFwBzbUTb0ejpuHzlfbGt4XAYNzc3B0CAskGgSMNKPehj0DX1le/r0Vikl+7u7lqRUUbWXW8QBE0mkzg9PY2IpxOAb29vSzLx119/HfP5PMbjcZyensbZ2VmcnJzE999/fzDPbu/8P++hjHeVo4CDe29ePKzpirhWvD5Hv30C5+g+Q90+HhHVvTEnbq0faktM795M1lcHDjVa+bjImFwrZQKl6pHHq/U7er1aP3Th4dr7fv+U1CSjofYzRaaX0nCdMDOO6g9fv0zDQsWqDGeBF76avGZQd7td3NzcFIHnWrAj7z4U7aF3f9bbIE04D13K20sNyLo3kAGYWt1SRlSGCmf61lCvR3PpJzzyPso1wUnEc8RLeTA0DE3TxOvXr+P8/LwkTma8oHrkjVG3yKioPgElblF2IMTXNdccAOo3ARI3+LyX3/0el/VaFIvFgZf3kXWzPiZD+1h0P7+LpjyPhTwnfUbvmUtPXHbQM3Ie1A9GBMQP2Zg8OsUILnmXoIr3aL4JbBiJEv3pyHF+nEa0Dc4fLqfSq1yyIf+6PGXgyfUGeYHz2TRPuUGKrkqPX1xcxGq1Kg7k119/Hb/5zW/i5uYmVqtVmqgrG8LllmP4Myu9yZFOtKxwfYvPZqVmiLNSW2tSPXxW9/iLn/g/AwlkGkeZbuzYL+83+0mh9K06Xf9ZP0GJGwwqOTGm0DpBg3sLNBoZSCJtMobimq6UHb0DZ9asvxImz0Wh0ul7MZHq9/CoPtcAnNenvnHsVA4OXJyfMi83U941xZXJSyYfmeLN5I0AjoqCBpgJaOT/LKFL9TovqF6GXgUyFBb2vm02m/jw4UP88MMPcXV1VepxOvAajUu2PUw8wy3NVIa18bmXx/HVdBnrjGgn4DnNVGRAM4PkhXTkfNf0KnUQ9YTk3MemtXgtb67X6xY4Vx+VSLhYLOLy8vIgp4D5B1qq1A4MLRk6v0oPCeSJblo61b3iUxrjiCjbuRl1Vb3y0DebTUyn0xZfaux8/xB3lHFJRDTSfdwKLB7M9EDXHPvyXU1+eZ2OyWazidVq1dreOhw+JUteXV21tl9rm/N2u43Xr1/H5eXlwZKb2uKSnuaPtuKY8r+aHOnfM8aPqCvP7B7dl4WuHVTQQHGivS1X5C5kBBEyZpnhqvXX62UfvE81ungoLwMZmmzuC++afDEI1+I+t9RAgXsxmaHR81wb97pkJOhp6jc975+J9tlGTVDZNweR2VgzAXcPJVPw7F9GO13LeMJlpPYs+Vo8mxnvrDBUSu+JkaisZIAyWxN2YHh9fR0Rz1vSuBTBse92u5b36OcmUD5cMbvss0/kL/JMBkgJMmoh6y6eiXhexuLSUO1eyro+uyfLe2sODusm7+z3T7uWJpNJLJfLWCwW5c2x5NXRaBSr1Squr6+LIaVx0TIwHQadCcNzaZqmaW0Llq7i+R6iryJhmmvVy2iBokmKptFp4ltaaQzv7++Lp65rnvzHhF/OF+nvujLjr2NAIefJ+dnnX/ThqapKkB6NRiUJUzRTHXzpIdvPCvUkZfCYZeLP3o6Z3ZMZxEzZdRlNv0/hdSoJ/u6TVQvBdxUXfK69uTC6IRTRNRZfe2RfCAKIrDM0SEM2mUxaW59YfK2SY8rGyfFKuboCknAx85hjIUrP2pAwu/JWwpGUjgTHaeTrxm642RYVYrZk5ErUE+1IQ5Vs3jOwkfFu5kEI1DlP8RkpSG61Iu25nlsDbfyNvON9cQPNMzdEwwy0Ob1cCWayRyCpPvlyEvvAdp2fRUdFo/oigloaY7JYBu70vIyVR2M41kzGGCKnbDkoGgwOt51mPOTAQt40ox3ZXGuOnJ/1XQ6F6P/w8BCvX7+Os7Ozg+UrJhk7MCYtON8PDw8tb11jJEBj2zyJVu3QWDfN85KZL8myPrWng8QIMBh91ZgEcvSs6pZsEKDSuDs40Hz6kpaDZsqrG+jskLvM1s1ms7i9vS11zOfzsuXZdd9u195q6rZHJQM+rt8yO8Lyv7qrwq+rE/x+TBFy6hJ6v9/byoxHzStRcSb1MTBUz4nI2tJ/GisHOm4A3Vth9rzQtBicJyyqDp0XTwYlYmUEhevCGSKmYic61/NMuNRaM8+GoDHieqna1LGvKvIytY7NuczAFelUW6cTHXweM8+Y4874h/NPWmZKw/vQV2qg4phns7b2+6ekVL6wxuuTMVZOCY2E5wo0TVPCwGyHxkHtapeLj61pmnLYFueXx/vqNxkIPS/j4CeQ1uY9A0niQx8bCwEeeZj1ZEUK+uTkJN68eROj0Shubm5aYCciyjKqz0WtbnnsHq3z5wT4swOW9Jz6Kd11dXUV5+fnBy8oY74FIz8664SGksUBQE0+eN0Nmtp3B8tziMQDzM/SHFCvKmfLz2zQ7j31S/wm3Uqd65GfLjvmvOLjoyHneNzpUZH+1865+Xweo9GoLAdRv56dnZV8L/KKt8f/3lfXtV2lFzhkFblSz4xoplBrncqMQiZYmbfAQkLWDHlEO8PYURtDVxGHYXYqNK/X11YzhZ0BqsxwLxaLWK/XLeW+3W5LCNq9Pyku1UfDrwN5NptNWbNkGJKel7w0MT3DZYwoRDwrmVevXsVsNiuH5niYPPP8JBQcA8FRnyHNhM0NP+vWeGpGIwOK/pvXy7ZqSsXnVnSMeDa0XR6Ahxxd6LO29YwAmpSth/VlGKjwaMQj2i8S4ouMXD7VvsajkKrq0G8EGUrclSLXn3t44gvtEqKR4HjYN+Y9cIsckzadp9wwZnOm68zn4RycnZ3FbDaL1WoVr1+/jsfHx7i9vS0JxXqG/JQp7YwHa5EfGUk+R5ny67r/5uam5D3I867tKqE+oA4UAPV72bY7JPwjbeWUaG6dFtTvdGjEH2qTcx/xFPFUtFORDNZJnsxytrJ5pp3wiBDvd33Mue6KJEuGNDej0SgWi0XZIcJ6BBxXq9XBnFOnEQBlUeNjAINKJ3BwL9mLK8rM2Duqyu7VQN2IZwippqi7QIxPqCcgiWFdwWeAqYYOa3SpjTszhLqXa2v6TyYUKneFyHpUl4SGZyjIuDvI8jCwmNDXzah8BoNBiR5o6+XV1VXc3t6mURTxlHuFVB6fw8BOU9LTr9eMO59h/7wf9KYi2gqvS1bUZi3XgYbPAWTXeGs8qP7TCLi86ZpHFpy/CRL1rGjjBsCVkiteNy4CTqpX97mBoYLNnINsVwvr0ucstOzP8DdG5wh6WL8vR/zlL38piYgC+p60moECT/zzceu+iEPnpjZ3TgunkQD9bDaLxWJRIlTMyme9AqIO7LzIeNOo1orG7nLlyd6613W8tytAqr5pmznr4f3sh+RGRptzkI3BdUxmj2pA1O/Rd9Hr5OQkptPpwYu5pHM1Bzp/QmftiIf023w+bx2ln5Wa3e4qR+U4ZEbaBdAbI1FqnaDhoFHT87XIAZUaDWVtcr1PGRL2MdOIu1DW2vD/BCiqi2NUfRyHlPnt7W0ZJxE+w2gcRy2ZkN5+hnK9f0T7NeRKtK5kqslkEvf39/Hw8BDT6TTu7u4i4nn9N9se5P2gQLix7xNA50X/jUbUx8Tnaslo3o6KKx/e78BCv9EAZWvTtTG5QXUwQC86M4j8o8fmQKQm63xJFn+np8Z14YxebhB97Jl8ebjXn8sAHmkuxar+uOHhlkKNPWuH7dHrldzo2bOzs3j37l388Y9/jMfHx5jNZrFer9ODflzvZcC5ZnDkPGRGi3LkYyLIfXx8LMsQikQul8vWNm4dP6ydC8vlMk3Edn3Bl6IxkugAejgctgAJl0BFa+k75kFxaYL01NzrqObtdtvK+WGUYTB43maqfA/ys55RPzlW2iiXIeezTH+SZrQdmj8Bh/F4HK9fv46rq6sWaNMzi8XiQD9qHKvVqtUnt5V9drxWjt6O6cWNJDum/x5u8mcyQ8rniJ6y9jPAwEn0fb2u2DJCcuxeZ6Z0/Lkawq4BIGdGhY49ciLETMZyg+qGw9Gs6nKwwueoDGRgnOb6PJ/PWxnRel7h5yys7TRxgEnF4HTMPHbex6WnWhtuhDPB9eiHrn2OYHnfuvrC3/lsVl9myPwZRo1Yt37nMhF5sEuBOKBn0XIY+dbp3CcTtWsyFlw+8/FGtA9bYgRRnrRCvKS92uJ2Q80zgbjrAl7z5Ff9CSjIW9RSBeeI/cnmiddcDuVN+qFHGS2lL9zQchwCAvJw37x5UxwA3a/kRvWlBob1nfTQEmnE4Xkcqks5MF4PDZ/0I0EIT8NVkS5VgqlC/XTIyAeq13eHZTojo3MmMxlo1v8+HSK6PTw8xGw2a73rwuvVMdTOR9KH3m5mw2o6ulZ6cxxIwKwhZ0R21I2CEyxT3BHtgzv6BpRNghsF1j8ajVrZ/RloyAqFt8sT14Rx/E6zDMGqiMkfHx+LIJEBhsPnt8n5kgaFl1t3dJ+WJ4So1S8pocFg0Mrud4Wgov3Y8hR0tr9OT9Na2+vXr8ue4+Fw2Aoh+smNesU3lwN8bjOecPpmS128tzbXDrS8TudhzqHo6SC3ZohVZ5d3mfWzy5CRl8UvVNrsm9pnwqrq4L28nkUQBoNBK7lRPCmDyb4pYz3iOQlZkQAug3DJULuK1I4rxwyYqQyHw1gul/Gb3/ymeF7uRaouJZ9lvEQa1JwYJvBFRIm8SXblKbJu5QplUdfMENWMvfNJl1Fy/qnx3sPDQ3z69Cn+6Z/+Kb755pv4j//4j2JwNa/uFLixzfpGvZ617wmImYOgyAXbon4knT3RnXLHNnWPlqUioqUjM4OsvnnEg32t2TzRInP+SMuIp10VJycn8eHDh5JD5ryo5Fba5Ij2dmDyN3WD0+dYm3j0roqaUq0ZbXaIjKbrHKgrbSavZIzkW39q/fUigWX73nY2yRnyzNpyGrmi6ZsUR8IPDw+tU+8kkNrBILCg6x4C3+12cXp6WpYRxKz+FjqFBs/OzlrIVr+R4dQXZs5HtF/5q99/+ctfxnK5LC+W2u/3xVhxqUV16mUxbIu/Z95mRsuaMclKDdzxM3fRZH1wJZC1wXntAi9dfZZycwUh2uhPXqOu61AfKVb1IwMOClmrfk864/VMMRHMahyqk1GuLGFS/VBYeb/fF8AQEQdLJTqASCCDJxjq98ViEb/+9a/j+vo63r9/X+rSVsTHx8eYTqeFN1U8isAIgfoqHubOlYw2NLjkHUYcOLeZQXc9uNvtygFApJ14tSYXfYBVdT0+Psaf//znuL+/j/Pz89Y6uQywPtOoE7w7P9ccEdf7bhd8hw1por/MCVN74j+COYJr3Ud5yhxa1elyzrnxucwcaZ8Lb0f1r1arePXqVXz69KnkjNX0i7aZkkczMEDd4bkyjFR22daII3dVeMkUqrwNX6/X+hG3/DAzn/fqfl2nMHJyJOjyjh2IdI3FDVL2DIW65mXUQAWZeDB4fkW1fnPDkTEMkxQZYhQdVqtVWWd08KPvup+ejR9+wjYkRNxmqT4xTEqwotfUOj0INN68eVOOR1WbbvRFb9FOfOAJPYxwZEDUS0ZnB3I1hcOxUxlmYNeXULrAQ60fDihd+B1IO59lyiziOQKoNXl6G5mnw6Ue3culDT9Omv3kkcRej9aZ+awbONKTCW2+vZPGRyCaz6vd9Xodf/zjH8vRvORzAptsT73TXn1hXoN+Fy+qXe0GE/EqAAAgAElEQVRgIqhXfVkkjbSnPDt/+P2DwTOAV2SGc0xecUPrQMT5Zjgcxv39fXz48CGm02m8evWqLPdIRjnHogfPBeH8So4IGLXDQQDw/Pw8BoNB2VY4n8/j9PQ0Li4uymmj/jI+9le8pvbUD20X1zJLlkhO/s7kKeMN6iBG6fgb8ykyvsrmWu1eXV3F9fX1ga5j/5SwqnMsCKQEYLscrkzPZPzp5egDoFgpiSUiOWjwzrghrAmD/vN3hgJlsHxwfaDB6+XkuvGtGRSvR8UNMYs8+CyrlcLn9SmULLoyK5hj7ULGnhjk93l9VARkMB3Qo21mjG7UEDN/ExMzVJkJJr1azj/7R286629GC13L2mUbmSLls6Stj8/vz4pfd8Pv97lCy+rKxkIlJqPnv7PPBEiSVTdiMv6ena7fpaRkBBgZoYElkPF+aDxUtDLWjJRQl0h5MlSt8ctLvr29bYHvwWDQcjqcj3y+2W+Ns0uxij4ahwN/0sTH3sUH1L+8z/vuz2cg+xhe1xHSm80mlstlLJfLuL6+Lm/K1VwoCdLHwrcc81yaiCgJowQb+/0+vvnmm8JHZ2dnpb2IZ/Ahx8qNImlNuki/cilUvCLAS6DhUV439BmtNGbydAbQ3Maxf/yLaPOPxs+2p9NpiRLf3Ny06vY512/kXYEwvvTQbXytHJXjoOJrRvrMZJlM4ZCIWeFkMDvbt1k5mlMWML0gr4/jcMXov6kdBzmslwBDiiQTVhUxvfetq68qpCeVHp/38BTH5iCtFuoS3TMDqD+GlEl3Kt2IZ8YkwPN+unD5mCngGofmp+8EvsHgOWztc+zPZcmWXbzDPup6pgzcm8iUjoNF/l5TANmYM/5keD/rv4rmUMBSCY4ZKBFg49ov3wEgekp+BCZUyHvk59oSz3a7LQaCr5TPaMsEugwY8+yTGlDMgGGNfj5v5NP5fF6SCgWwCa7Y3rE6gP3zthktoW7MlgRYZ+YJs34tC6nt6+vr8jZGbu+Wrp5OpxHRXmZm/zXXihBRb4i3Li4u4vXr1/Hu3bu4vr6O7777rgU+tCykejSnAqtqXzThKZir1arwkofk5WBJ99CwcjnPwbbG57xHvetAnHM3HA7LFvbZbNYCOuqXllC49KG+zefzuL29jcvLyxbIqOmViChOoPMjZYN8VCudwIFhnQwpuUBJ2WcZyVI4Umy1kinbmler73xtc1e97LMrNr9HJSNgZjC8f03zfNhIxOHaeE1Z0FgLCfvb6XjmOvvHNSsJtJ7RvQ6anJaMcLhXwucUSSGjMlqgcSq/QXXqPvKO+jWZTA6MHvuY0Tu7nr0kK6tPtKgpZhXW3xeJqn13WpLmfu8xfXfDFxEtpaKtaBHPb5sUXehpSWl2KQqO22VQdRA8aA4z0FTTHT6P/O3u7q7kaWiclBMqWhV6pBpzja5+UFVGb1fIpA2PWZfRUp01wMExuz5he84nWT28lhkN0shlxcdC0Ef9OxgMSgK0zw9PC+VYSDPxjyI2jCALVKxWq/jv//7vkjSr5G5f9iLNxdfczsnlRekaAg6dgqpxCKTKNjHKJ/7uKqoni9Y6rRlp02uzlYN2e3vbkkU6TJJhRXg2m01cXV0VcEFa015S72d2j4cB1qLXWekEDu6xqXF2giXzHCIi9Uyz4oPsUtSacNaf3ePfXfFlCjtDhnyGdbEOKjQPF9cUT00ZNU1T0LmAkcaow0AoKJp8jms4fDrbnMhVa4oKHarvHCPzC3TuP4GZdnU4zflKboUb379/3wqjDYfD1mmBZGR6Jyr0qDNAwzCwCtGz7iMIE80Gg0EBZa4MSV+1rXYcBGYlkwUaAQfgXjgGgr3MQPhzu92utTwlo+p8KsUsmtNQ+OFiCkf73LA/BMvz+bylmF2pqp/KV2IfyUN0OObzeXk9uHiaBtq9QF+K66J3BljdkGf6yHlHW+OY2+T86M87rzhw8Pu9UG95VINtZPTgdV8+qgENB/z6rD9F/NgP9ZvLnLQlqlPRY8o99YMiJYo+sF6fC41PidnkT/GWF49K+XJBNm+ckyzaS7swHo/j7OysRGhWq1VcXFy0kpApjypcTtC7KxysZHqMvKvnfSmnxvddpTfHgUQh8TIl7wLqnWcYq0uxOgLPBkVFlYWSstIlhBlidAHpUgB9IMXbzZSZ3y9DTwEnevYQreok4r6/v2+9yEbXfS+2jKgE170h3t80Tdk/zj77jpXtdhsfP34sIUM9q3CZl81mU3aSuJF10Epa+ueaYVDip4zQer1uCZE/74ayaZqWQajNG/vSByB8DOqL96OPt1mkVFmfMsrZJxp0eoGu3MVz8uA5Nr5shwCVY5Q3SFq7UiYdM3BPgyiZ8FwDLgs4/9SAGgGL08dlwJWwnncZ9iiO182xsRD40LN0D7JWPKLobdX4lOcnqK+MHnLe5B1n9PV+OF1rfefygviwa5mR7Tw+PhYQ4IfgKYrhOQusk3PLNjX+vmiD05U7/iQH4tPRaBTn5+cxn8/j8vKyRG98Ga9L1tkfj+yrPV+KUaSCbyvN7JXTo6scvR3TFX2tYXWs9nwXYtbvUjJMeiJB9AyFuhYmql3ru9fHVwMPXCukciETZkDBlZK3KWCg8LL+EyhRudFQMHmI9xPRaj1bgiqG1Rg0X8ySPjk5idevX5cwGRUjx6X2rq+vi3FumvZLaTIPRkpXhTkRqpdJfPSMuxSyruktfkr64hqoL1nomcxT7gKJDK3SgHp4vdbfzMjwfkWKuLslAzzkj9oyhCssH7vXXTvWvLarRP8Z1XF6uZGIaGfIs1+ZZ0SPlbzs7WVA3WlxzLo0jXJNAQuMdC3/sM2aQfXjlrN+ky6+nORROBbKuU4oZC4I3yTJQ94UVeSOKgIef1500J/rzsHgOfLl/CUdyLmgTdC4SBtPwvacKD3DOngAmBtyzbGD4UzuyA9cwtNvs9ksTk9P4/37960zGXxeXbf7vPE+B2/kAfHXfD6PX/3qV/Htt9+2+LIGDrocZJWf9XbMLvTLwonks5nh9tCXI0ze72CCv5HwNcDAersE86cUZ6aaMeNYvOz3+1iv10VwsvBl9plMo75kBouCSYU5m80OGKxpnt6QeH5+Hg8PD3F3d9dKkGLhQSpUAhyD00H9ZH3uifIwK33nc7W5a5qn5CiF0DebTazX64OxS0FQ+Ci83E4o3mOIVM84cOShRseWjC9Go1G8ffs2vvrqq/jxxx/j4uKitcPIlYovsbnxcDCj53wuupQbv2fzynu01OTj8mfZd+eJrPjySXbdwZsrXZ/r8XjcMqTSYe5Fqh0H/W58apGyTEmrH+6Q1EBKRksH864reZ+ifE4fl1dek45gfQyza7mGkQfKAfW7lg6U28C8MNdj0+m0dZQ0t09ymUBzRJkl3VnUNoFhrRCk6jt/YxuMpERE2UIvZ2owGBwkpXfpsaxkvOc6drVaxV/+8peWQ86xZssdfXT4bODgDKlrnGAWMuznAA3WT2Tugp8JFPuqeuhRsv9dCtAF3VGgG2pHp13MWiuilwuZPnuyjtNdbSlZSck+2ZkIZBwtI8noZ9tH1+t1vH//vry1LVN6GjP36x8zZj9VkM8yBK3+Zh5BZgx0z36/L96SXgbjoCszwKQvEw492uLKnnNB5ZDxQiZTWRmPx/H27dtWvTT0mWwQEKrf9Nz0bNfYa5E21cPlCdbHSJHqJ/96khzHz2OEuSadeXe18LyucYmUUSyfJ9JDPJI5K+59sj9SzuqX6sv6lwEXL6JZFv1wL5P9oKzQ4SC/RMSBUeV92kauPrhxzgyN+uTRMNatpUjdq2Uw0sznRHMsQCJQwndQsA9K2BTQYESBOp/3ZnPJuaEdcnkjLWgDVAS2dB6Fnwrsbde+s9RAhvrNqMv19XWqqx0AUaa6ylHJkT6ZTix2pKswzJwZlQyRq31XrF0KlkTw9Z6sHQcKPg4i9trY+/pzLHhwEMaQ9HA4jMViUdY+PYGNgEXnLjB0rnq0tq3nZVR9a6t7ThFPyV96vbLqpIGgIppMJsXDlzfhc6T2aRwGg0GrHt1PY5SBvq75kPLTORQZ0NU8ke+p/Bn9qQHXjC8+Bzj2lfv7+/j48WN8+vTpAKQIAGqfvQCZElG9P372PTOsNX4VHkUe8eyl6T7WK6PL+Z5Op2WZiGFaBz88wppr1+PxuHhqGpMMqnbtuFEgGKb3lxk1Nyb6nwFRP0itptxpPKjDnH8yelPfZDzkQMuvady1iGyNJ2l0HAwr74I7K1wGnQ4uD5ItT+J0eefYtbTI51Q35dPBMXMsOKfe3xqwZ9+pBwm6BWC47BkR5eVUGot45vb2tgVMMnvyU/VFxiMZf+i6RxpYR19uRydwqDFrTaH7RHrxaxSsmhBS8DKE5cKdtZMxOQWjb+xuUNh/emQ+TvfAqAwyurA/YnqeQCfavnr1qhhiMT4BRsRzbsLp6WkrNEWQwaJ3Y1BA1G+iYiluKXgyPo2LjELE83qfFBmPDlZ7+/2+dZBMLbxYAw21QiGvKWzOQ7bmLBrLEKu4R+nri9myR1fJACvL4+Nj/PWvfy2elz+r592LUfTKo0AuL0pa1avYvd/sH/e9u3fl3qieVR+ye3WP+FAeGQ/90dKBwC1PzBPNORcCFvIoFV5ne1z+qhmXiMOjnBml862FXnzZJZtb0cLBg3Yg8Xhp/s56+WxfhIs0yt7aGfH8Zlsux3HcdB4innMyBNRqhkvglvWxfkYHIqKVY0H5JC2lVxyQ6E9jIK0jDmVDPJHpGNUjnpEc8rovBahNJQjXQCvH43PbVVw3qv/ZfNaezZyoPl3VCxwyZvdQ3ecYd++YI/qaYLkCOqbfx4ypdj9DizT82dhq/aWHoiIG62IMGjoqNCVLbjabkrjEer0fMtD0nNk3zlsGfEgn9lPb/Sjkqof/tewxGo2Kt+jLDkS4Prfubfnv2dqczwFzEtwD9HH5Nc0VacAMbf0nKPSQdC1foksmfAwcvyt5rzPjY64bq0+kqyeHDQaDA4Oi+13BUIF6XksGhDnP4ssMqNII06gQHCl6xLVw52PN+8PDQ2sLMOmaJVR26SIV8UaXd5YpZAdafiIg+5/pKrXL3U+ZA1bTMaK9J/K60dZzXCbScdDOxwI5up9ATm1yyWg6naYvFxsMBmWe9DyTvUkrAj+fV/JXRn+CxWwph1FUnxPypUC66wPXt0wo11h8CbmmwygvXUDCZcD1ceb4ar6yJbyu8pOSI32dR4WD4nqQSk0x8rNPvIfKa0JcE/raPeqf2sqEn8qfxpCJgxQyF1QXLk+EydAmmY5Cxe9iVnrlvmwQESX8L7BBxnHjEfG07sYlEIIm3S+mV/IY75NSy4SISmi325UjZ2sRKhofAlafG6d/F2gVeDnWQ+ZvWfsMNXq/vW3nz2PALcfZVfweV0jeZtM8LwmItylrWY6LnwgoQ6G8Dwei7vG6QeI6NWnO5TH9zwyS/sTzrFt/ngu0Wq1acq/rNZo7XQlEdrtd62TUTA+o/kyO/bNf0/h3u115Jbdk3JOSM7CgeXDdRjklzfmbPmsOCSJ9N4B2ZUjXMPrALcART2BBOQkEAa5z5JTod0YvtP2X42M/PepK+vBdKppHjpU7yWp84nOkOfFdg9R7TdO0zpKgA5DxHGlGIOBOCUtNR9GedvHLsYnmKkcBhz7lVVOQHqo9tmTLCJmguJDWlHEXwNFzmQHwezyRq1ZfrV0i4+xZGmi16UsbUrgCDup7tu6qe7nmrX5k/ZtMJuVo1lr/pSDY9+w+CpwjfAq3+upKT0aFBiyLaGXP1ubHz6eoAbwMgGZtuDDSsETEgXd0rAzIeFOxeX9qRfPuwDbrO8/7yOhI3nJgzb4wKuPn/qt9hndrc0iQynsV/iWtZXicpsyjYnHAmM1rxkMcp/qlaw6unJ+O0Ve8nukctUdjVgMj5BnRQmPP2mcbrrMZHRT9eb/q44FKGYhj0RZwbdMUTf2sCm3fnc/n5RqNJ/mCSZARz6cIKzrL+dDylsbAE2yVoCmdmS0puC1zHUL+Jb3ZZ9c/zvuq/3P0BfvEz5o3d5R4H6+7vukqR78ds2akMyLw99rgM+PN31wIuwbkyqCrfzWF4fuIvf2MqD7WmmB6nzge77sjxOl0WiafClTK2IGC+rrb/R/mzmU3kiS52p7JS2aSVdU93dPqhqDNLITRet7/AbQbaKPVSAOMIIxafSOLxUvykqlF4QS/OHnMI5LdP/A7UChmhIe7ubldjptbeLwMq0q2vVwuh1wGhrKWy+XwJTYaSuUdkFYlpum3HJWMuU7408eFZCyEur2+6NKrU9rjPj09bTc3NyPFq+an4r+Kv1NdzWdSYsqK05CMvhuYuQaADjP152P3IlCmk0GrJFDxU6cw6tn9fj+aV9WlzNAYihY6Ac6j+mlt/AlsORwaY4bD0x6tchn4lV3xQzwTTfwWAvVe86R+3MD72yEM8aof5ffQMZF/aU4qQDElsz7OBERUfJuGc8RxJHuaZFlgRc+5rWntVe/ldNlna4cgTvMuWRLdrj+qr6Rq1UuOmVEL0cDQu+hv7TNweHh4GB1PrTrMEeOhe5ILp8Ej6h7BTls/KnMcNG2RX58q5LdHK/w+2+Tv3yQ50pHRVPF6LlCs03O0qS3vXxOdBuorfE4qx6X/fY860ecghMLjDsb7oxJXxQGE0DyNqQyXjLbu63VD8ltKLyHSyk9onntuMgIORhjN0FiU3NTa6ytuihLIiOsQmNbG37EQvQxBS3F3u8/nyf/xj39s6/W6/fnPfx4+dNPjGUGRtlF4Bn0KSXuh0/btOFcy/Z22TziPnMteEV88vOwyk1YPpI3fA9F40taD8mT4eXYfk64pP4CrTtHh2wFuwLnKpNEXuBUgkLykyNlu93pC4IcPH9rd3d3o1EvS6m/50HhTpxklcfvgddmHfyNBMuvzTfCYwKWDX3c8kj2eoqqondNGeXWg6+PzNw2cdrWV6JPeUkcoC94vC2l0eaPdTb7GgbRsfmttWNj4G2OSvdbGEWzNDR067zEJ2vXeQQLljsWjfXzOeZJ+u/wlW1L5zgRgfS49t6Oar16ZvVWRBpEaT8qW6pKpjuydAb3BpXrJ2E+9S+9t+hjdoaueb18kkDOHb0lReGYAj/yVI2XIrrU2fKZW4TYattbGqxJmzcsgsW9d0zvQDN0xV0DXtYpQ+7e3t22xWAzRibu7u9Fct9ZGIEVjbK21d+/etW+++ab993//93D2vzsoyhlXkP/wD//Q/vjHP7Z/+7d/a99///1Qh9EVOdgEbjVvySC4bNJQVrrQA4rJKfn77L46TnqUZJ1GKr2hImeczp3w8Ys21wUVnw/RK50TMGR0QzT7UdbM2HfZEK0KS6stjsH5nZyp5JSg33nAdpz32+120B/fAlE9d+xeks2qHIVomLJLU45A9zwhL62KmdfAuVkuPx9d7BFA57vsgdtHRaVIt4At29F4CJb0j/TKFmnRxKgVwRT1QVsbP//88wFvPE/MeZjmSIU+huPleGiv1aZKAk0+f65nCTw4WCZg43MJeKswmTqV2RGH1g4NRFXI/Dn1neg0KU4XBb03mbqfog+8rwlNxiTR1VNiv56MEdthPRcKOjP/Ch3bYIRBjkLZyNoz5HMUXo1bAseVd3qWq+IerzQn+upbFYbX3/r9/Pzc/vKXv7S///3vIwPFkCP5yuvX19ft7u5uaDO9RqePdPkrWiw0Uj4eN7JVG1NynAqNDyNBzqNEb3U96ZfGRrDO+4zQiK4EWtL/reWk0mQ0BRTSnLK+wJD21OmUvNCh+SqvKhwv9VFtcT/cSwIN6V4Cfxojx1qBTTnEtDp3h0w+sH8lS9P5+ricr7QtCuP7UfZ6TjKlT0ULZCR6VLjoEP8IAOjwdIYN+cixpzlTtITjo1zIJijx0m1GD1DTAXMlz+c5hgQMkp90H8c+k87yPp8nXWzbx+U+aEpvFj3jdnl5uWfDdK6JWBKdEBLrTxnbqk5PMdOA2Z4EKIXaWjs8lIRItzIYTqfzgAlKPmGOYKUo+lvPk5+iWUKuuv56pvrkP2+D9X1+VZdfWWztNUFSWeUMYVJhnb8+r76iq4yY5oURiSmg6Qib/HUj4NfJD34lVO3y2aRsvajWFIB2WZYB4kFfU8+1dnj6psav3AN/zdL7lGPY7/fDtlhvi4R/u0Ejj7SK0Wt4lBueMaFn+Dqx+qiMpf5V4Jy0VHPee269Xrfn5+cDXhCEUcYp57Q35LNW00xy5j/np+wD+/B5ay07CtKo/7nt4W/GsB9GG3lAV2vj1xY9J4KfQSctalN84emPdIwCCvv95/M9BPjVDg+9820Q2U3mJ6RXvltrw2e2t9vtEPVzAKvnU9Ik54eLMN7XIo68Jk8ob6lUPmiqvr8y7L6kena327WHh4dSQSa/jul/u9Nzh+DAYko5E9EJNSWanK5e3WpPiytt0dpbGc8dUwWuKpCRiu/50jlzdeF7eGqTKzMm/qhvCfB6vR6MNw3GcrkcbSe0dvjpbPVJw7Pb7UbftacjowHTb41NhscNnxTS58IBqwq3T1ar1SgCQQNP3iejzLcwWsuvgzoIc3DYU3aOv1ePc0YjwH5ES+pTfcjx8dyGBBy0sqzyLLxf8Ua8qM66IHDgFkaaF4EKrv5S8rLGnV4/dduQ5l386gG9/f5zSNzzL3SvJ1eij22Jl+v1evR6oYMu9uH9qb5v8/K+byewDdfHql86Gn/bgHPu+iygT5DBMXoklfkz/MYFI6DMWfC6HtXSPYIXyb3bEkWxlJQtwMEoKYGgA4c0RwQc6k9j8bdfyDe16VGltxTXbdcZ6XdKRp4qs3Ic6GyrcBoN6dw2VT+tAKaMqU9Yzwg7YiSapNDruamM0kQH+yZN/EclJDJOQidDydMYT04+HyMt4RatRPxSDJ04p9cxVV/OQ+PXfF1eXg73GYGRAsmQL5fLIWtfzkB9+pyuVqvhhEvyhlEQtbFerw9W1zRolDsCD849eai6/Hx2kg1X7OQUkmFMzkjzScXvKb07igSCmSdweXnZnp6e2s3NzegZ6qZ4yOvkocsLjZiiSWlFotW/6nFFSTCouhyj6upv0qPjoukARROdiRwM+S1grVCz96tzSXy1RV773wkQ0ekkIJmccwJ0nK/W2nCuBAvnzQGH/mcbrOdtVeDVnZ7rBR2JyzHBk+cfkH76A9JOHiZdc95J7hzoyoZKptiGgBEdPW2684MJruyDssqoUOWXKpBWAQ4CZ5dH59GUM6f++DXSJVo8GsQ+55RJ4OCGk45exHjRqqYqPXQ/p1R1Ezqj4PseIIXREZ87rKov7y9d8+tuBNimhxyJkOVEtJrna0fcc2ytDcfyKpGscqxyNJozVzAl0ImO5XI5vCKajJivNtQmt0oSgFC7inJorAwxplWVxpbOGnh6emo///zzKORN5SAQJl+q+UvOxregTk5O2tdff91++OGHbg4F+eW/XYk1Ln3R0591w0CAwIObxAPfPqPh5QrPCzPNn5+fh+gTAbAfNKbCjwh5vgCjfq4DjDZ4u7vdrl1eXg4gyPVbz3OVTL0l3zQ2B126L3rdSVXOt7IPTn/1rBfXsXSfAI6vZidAkfSI/ftWhdtH/e8LRXfm3O+X3PhYmMio6xynAz9upZIX3O7yrQLymzx2B836Ly8vw7HmV1dXQ7s6+MtlVeMliKNuCIAykkG5d7rmgAaXVfpn2h8HoVpMzl3oe5l9joNfS5GH5BB7ikPUqud6oMCfdeeR6nOCq7H1jPAULT2FTo6ytdfPQ1f9J2eiv/3tAhcaPifj7nSqLhH1y8vLyDGQdwoHukLQWKV9TEY3aHwYcnZUzK0VrTpdKdJ8kObEc3+2B94qw52Mlf9+enpqP/3000H0wh2R0+/XHdTw42Osk+bV36LwL6TqWpXweHp6OuQhaN4ZXSA9Ogvi5eVltAft45BxVLKt9J6vbhIgEFzwXf7WxqdYPj09jT5mxaiiO7yqSIbpPNJWTpqzKmLA+XYHkcLUSbZFEx2vy6HLjPjDa7ruERynh3QrEVtzIqepw+RUFE3SgoYLBL15ornV4UuttcEBK8q1XC6H73GwLY1FNGhuCB5Eu46xJiDmfea3adziLxcpBCrb7XYA7LR9/NfaYZTa51/jSosfl7EqguR1KZ8OvHg/2QnpSwJOPaCiMvvI6Z6xVPFwTFrhsa39fj/aQ6+Mq5ieUGLVdmvjvAbPlE20sDjq9eIAg/txif5UKiFIz6ld8lRjYtjZFcX3r9SGI+XUF5W1tTZaGRDZ+ryQToIAPUNnTiPN1aFo4ioinUegekz0ct621j+uuiou8/53JUueF+JFh2Td3t6WES222yusw+hNlYDlxQ0Hi4AbI1sEfuqfHwhynXcwK1mVs3H5YthYsiCAIYDgtkCFb1yIfnfiqVAeqb8pPE6DntolPb5Y4SpetLJOmoPkpFjfgTfHU9kwOfHtdjs6J8LrE9S01kbbluKtnleelMbIuZNTfXx8bJvNZuhP/P706dPIFwgEaNHDedHr2fotXdK8a8tqsViMtnmlF1qI0C4SKDE64NGuKQDqMulzw0WyaFd9j8pO9cHicsZohtrv+WAvU+Ns7Y3fqvCO/W8qiIq/RsR2EgJLjtwHlVZfPQCgvyUcQrsKr7oR9W0ZR+asT6eYkqicdi+aaAqb/y16adQocO6QHZHrfzfuvMZnuLJzB6Dz5bmaYUIR6WByJsfkc8UVkMsIafbnaASSXLqx7zlrb4e0VYAhleRwOO70OtuvLeKv3p5g8hNzLxSJcvmm7mrMHmFKkSW2QQdP3VNfDjJct9g2+yNoddnwZ8iLym4kB09jy+scJ+WAxjiBfto8PqOVdLIPc2wa76d8rFRf35P4+PHjwZicb6TT+auvljL640CFtPPLl4xSkdfsS21tt9t2cvJ6qB1zc0j/y8vrtzzUhqJpBC0EtY1YnAsAACAASURBVAIkBJiPj4/DSZW0NZI70tna4XHerN/aOBdLtptRNfoPHZSnN9XYzhxb5Tx3P9bzicmfztm+mLVV4crnAk9Eygly40EC029HRj5wF+KKAWw3FV3n6qYKg3MSknFQOwx1qbizqsAEETT74quQeq76KqVvM+i6aJCCc6+Zxl4nLkq5dZ1zqed1fDQVgG9RUAY4foEq3ZNh1YqS0QnnEbcwdK0y4AmgkoeVnPXq9Zw7HVoliyxy6j3g8WvKer1urbUhbOv5RpwLBweaH21teNSBssYQr17zlCw5ACQvCV4cDIoGyYfA6Hq9bicnJwdfB3Vnr/Hqf+W3JKcsulS4UiNNHp3jcz0w2bNzbsv8Wb/eAxBekl4wuiBdIl3qg1FLB2mSI57tonrcjuLCgUX2kTLHPmknJSOXl5ft4eFhBFAETlVXNouRsbOzs+GNFcq35C7Z6dZet77kuHlAmcsex+g2g3xj/xq/DtYTTS5zyW9yTlOhnU6F7YnXfGMrRcurMusAKBJF4l3AKmXiM64EEpiUgJOUxZmZFNNXB5wQOmo3atzzUuGkThkHAhC/7uN1PieBe3l5GRw621HCItsUOud+pOqSFq1I9VtKKMOvtqU4VCId+/v09DTsdcqoar+SOQkvLy/DiZH6R17SELDvJDMOBlxONK90WByzo/DKEPv8kJeprtOkuVCeAOetpx8cszsM8WpKoReLxQj0SW5orEUrV1feBudB4FCnkSa6VKTDOp6a8iwZ43OigeFt8Y983e0+fxZbusA3PEQjI3CU2aTn/DvNHeVVbXLVSHmsVtyim46YYyK/K+DAZ5xWPk8+pbe0RK/yUPjmEm2f3tqSg0xbbnKiyTmpHfEqbZmQNuc5FxKSkfv7+9Ex0pQNLkik+5IpJXDTlnE+OS6u7n1blXxPst7a+Bstev3bX+UkIG6tjV4tdd1U+6TNZUv8I00OTDWnKh7t1Xh9SyUBFi9HfR0zofYKPfvfLBUY6DnXVN8V0g18z0D79TnM4nPsxxnPyXMUKWBSGQJvUw7V9+S48m7t9dW2/X4/hCVvb2/jykIrd67olOCm+oyeSDhfXl7ap0+fhj6Zrc56NCCkkYJOuhixIp9It4CBbwPt9/shCqKPdHkhkEiyppIAndNImlLZ7/ejqA3bqoB21acDiDlF8yk541w5nQJ7bFsOnYV5JqTNoyYauxtUyrwcBd+S4Fzwy680mtvtdsgJoFxpvM4DfhuFWxGVzidgpzFwzGxTBp/yS933fpLjVB/6vkpvtZi2PVKCGwt1U6tmtpWiw1qwuF1r7RUAuiOTfGjOCAKqQuDgvFR74jXtEvXHAYruy57RXtCecS7UvtpV/okK77kMkD9aLNDGOX20caQlzTcBAH0IZZJA0e2bLzhcftxG9Ojx8qYcBzduCVCQsDlhWUfdDlbmrLY2m03bbrfDKrtXtzLQrb0qmU8S61PoOLlVfoMrBBXKjVdlYKTw7pjZhww/+1GbMrIUQhUJtcagfmnIeDJcz6lSqTgu71PXtEJVklRPkVSfq0zNuRtdBwlTMsj6lcOQoa5eO6xob+3wtbJqrJKpntGt6E9AjjQkehnOVV13fDReNOJcUXH7w+kXAGb7BLGtvTobGn8WgRLPd0ggkI7n4uKinZyctLu7u9HWRbVA4T3XRRpftyEC4omWBEpIh0fFFovFcAxysgs+dm+bxemvtk33+9fX9OQ8meSo0w+57++gXOPQx8u0gucKndsJm82mLZefEyT1Jg/9BaMJSmAUsNT40xddGX1JWygu9z7fuu6RgNZec4a4dfby8tJub29Hbbmzd6BDGSDooT+hflFWXK48ipKipP6bdLpcTeU5HA0cqDDsxEOCTqgr4NySBDyBjP3+9YMnyZCwLX+uMj6Vgeck6zeFwZ9RXdXxPUIaFRlOGSKG0dSvI2YKlNPGFQLbT/z0MXnhqWpU7hTpSTKQfi8Wr9scU2Wz2RycSujz1+vPlcTHn4rGoq2gDx8+tNvb29HKeg5Cr/pKesExHdP2MYWGyOnq6WriHds6OTlpq9Vq9EVTGuVqRd3aa6jd+yKNy+Wyrdfr9tVXX7UffvhhqKe9aNWTvpydnbXf//737V/+5V/av/7rv7arq6tZfGECNXU3AeYK5CcH4oBDtCvBz6+rb9exXptOS6I1gUu2p349PO8AnVEl2avn5+fhtFbNmY9tv3/dRv3222/b+fl5+/nnnwdbxa0n6oJHsNSH7BLBCk/ErXLPRI9/StsXjvQru91u9DrzlK5O+a/9fj/kBp2fn48ASNLDRL/Pbc9vcg48Sqx6PT1t7Y0RByeUISB3AOn1uaokpfL76V5Cp96mJscVTs+1lhNd2E7ay2Q7Yr4LE8EA9/V9cn2iuXLb7/fDYU5SaEYA9Jt7laSLbzvwy5gy9Al18m2TxWIxnPDoAIRvdhBMbDabg0RAhi9pbGRwyDMP/fJVrORgpkpSRJcpBxcKI3OVxWx5JVoR8ad5TbJbGYYEYl3O0t8yeB7NYgQjOTnnpQw2aWSUKW0XKCysLbPWXg2s6mkFq5UrbYPuv3v3brTqlVFXv+rj+vp6kBEPdQswKMrx448/tj//+c/t06dPB7x2vvucUA7cBpCHDvaS006Gm+27DiWwomcYcfFtQY+Yij/sLwF78ZrbH7Idus88FadpsVi0L7/8st3f37dffvklAuIEmv7+978PTp5tEUCovhZdTKik/BNwEPzJxuz3nyOU7jR9m6W1NgIxal99cLFTgbHEo3Rdz2iL0+XAi64L7KRtSPGQuk3a+Nv7on2ryptfx2zt0NF5Yk5VqFxyGFPtVwbWDbSHT/2eG1UJDUNIrlTJgPv+cXIU1eojGacEVrQS2e12Q3KawAMT77j9QGV49+7daOx67efm5mZYzeiMdob/qbQEBXzXWeN3J08lF4hJgi1a1bbyMnhEsBc66ISKe4pWofBe4Zw9Pj627XY7rAZ03x1A6tf/TjRM0eYOqpLn1l4zweW4dey36nBL6/HxcXDMTJRt7fUNBW1xETgtl6/HPBME73a7QTZVX3LL1Ru3IzSPkj9FtuT8BTI0/3xlTW2KFsqWxnJ7e9tub2+jTSDvOd+iX/aB9RI4IG/nGH0PkxOcJVuSbF2yIeJLkkunuwLRrCNbytcqqfsEMq21dnV1NfDe7SkXQtTdh4eHttvthoVGtVXKMaQ3v+hEBR7IV75Kms4i8Xlx3klvPIKi4ttUSZZ4XfLiYD2VZDsceItOyoLLjX+2nltNjK795lsVIs4Hka67klKQXfG9XmrX61X9JkUjcmxtfPiGt+cOkNe9fnIOFeBJwpN4qXtcIcpg6rU07Qd6P6JBmfFy9HLuPB+f+/WbzWZk0OmgPRv44uJiUKLegTtPT08D0PH5YJv6X45C4+XYOCfqh6AzATJeF51c2VFpWNjO6elp++qrr9rHjx+Hk+3S/LhxrOip+kk8Ss+m0CLrSqZoVPzsD+mcH9P88vIyRJ80/9yGpMHx6AVXvG7c1Mbp6Wm7v78f5mO1Wg2fXFfbAiIEPuqfORL6p5WqVow8Pl0ONM2Tz4PzcblcDoCrAoapJD32a57o53Lo260OaFSH7Qqke5+eV+N/c171m7lO1FOP7LA98l9RCbWh4m9PcN6Wy+XomzoK3etbO4w0+io6rZDJNxXJDz/+V/kK/p/8gSfv+tz7lgpliIC/mt9eIQBX/8kXe2SQz1bgNwHOVH5VciSRChVi6lk6gDkgIZWElitjSppbG59w2UNZU0CAbbsis3ArhON3RO3KTBr0vAyE6hM984NTHIsM9fPz87CXKvTtzpx7ihI+nSfBFZ0SgxQSJI1Tc6g2XYjd2LNUDtrnIcmFVtI00CkU5wZe9QTY+Clz0eSrxKTEKr4Cq+pV4IdjdOVORsBlTUV852E3jNK57FBXaKz4quZisRjALM9nUJRADl0RBN1niFh1+Qqd5o+vlzqwFW/pzCq+pZKAHkETwSl5Wdkgn0fqrOu7z6FHIdhW6q/qs7XD7RXXUZdDd46ttcFOKErASKfaYiIk51f2RuX8/Hy0dcW3xRw0qA+CfgIOjp/5CTx+nHa3tXG+l8YlGXT5Vj+0Mz0bn8AHx+Nt+Tw63yswkPpIYNXbVvnqq6/a2dlZ+5//+Z9yS6T3namhzmSNieJEVsqZHGFShp7hrYo7v+R4XEl8X9CNgpxoQqROK1eyaYw09ol2CZW/WsN/jvBljPlZWRnZ1g6Ppqbxd575+LkKoVF3/vF3Mjp+3+ljUU7E09NTeWQz22Imvhv2ND4ZHx5rS8WpkPjLy0u7urqKzp7PkoeukHyWfEuGJDkBlz83iCwuD6TBvyVwfn4+fF9C+SPervimCBZXfWpLDmC1Wg2OQw7i+fl5OJXPV9jcehIfyX8CVzku9cm2PPzKuaz2atPc8H+NOYH4Hmit5o+LE24lOPhxWdT/vspWfXckus7VPeXO2yWYSFsnjNRJHlS0tUQAwIilvyoruiRzmnv/AqaiTpvNZpA5yRO3tmRPJNsCBKJL7VJWFVHTPPCNDUZY9D+/fVHNN+fQ5aW11+gJ6aaO8hoBsdtktUn9d7vuUfUPHz60x8fHdn9/31r7/EVW3+L08cwJAPwmOQ5cAU05fRlZrVj9GXc0vDZFSzL6EpKpEI2vlFknOQE3Cv4M++k5EdaX8FJJXZlp1KV8VIzWXl8XIn3qn5+5Vrv6/LX2GhlFEF3ikejT3wQ2LsSqy9Ws7vsHcF5eXtrHjx+HsyfmyhIdTnpGv7lSSqsWd1h0EuyvApAePeOca664F+vPk1YvDnLYJ/mueUvhUdHvr0hyTNyW4BgoK4wEqB5D2zR+NMQOjN3BOq8YHVJkiw5Mhph8kZPxdn1ue7zuzUvFF/WRIpaq7zlAqS+3OSrJ0HsfHvWVfGi7R3ytxkG9be31LAxfiPEgMOXIOI97TlUnMxJQUOYIOsQz5uGQRo5ZeTGSOy4seMCdQAgXe7J5sr/8+rBeia0ioKRd0SmXi4eHh+Hz8Q4UEuD1onH5/HEOyROW9+/ft/Pz8/af//mfbb/fDwnCHilmmRM1njw5steABMMRLI05B66/aey8DVfKipYELByAUIAoxBQaOh86aReAXvHxuPFSHf12Y+/tiC7lJ3g9AS79UwhQfSgSsVqtRqs9tUmDsFh8fs9dfRDN+paI/qbBvry8bO/fv28//vjjsELROJVYp+cJbAjmWnvNKvZ5dSOktntALj3v11SqRLLKObBPN3hJHpMBZXGZPqZ4e5qX9Xp9sJpvrY0STxkRcB1W2zSmXKnRATB6oGuSI2Z9y/mp7mLxGlZOPBD93LvnnLiDdD3vARWfr9YO951V5Cg1PgJJ3x5JPKRsqU8CO5/LZHOkaynC4DZPfXL8cryyh2m7xPuXbjKJWnOi++fn522/f11YcFvDnRLHLBrULxc+kjFtC8rJ60RI1Zf8KG9GNo+LHK7yGWFgIrjALfvUdU96J79aO3wbiXzTNQcHmsdK5n1eXe59sUl5YuRT///www8j4Epw1ZPZqfLmiEPl3NP/jphdkcggDy1qEI5SU3Gl89Coh+/d0XNSE/pLAMdpT4rNyeHfPYTp/wvYyHgRffpEy0hst9vR0acUKiqskv6qg7PkKEg7w65ffPFF++GHH0aRgsViMXJUvgpWGyqKdlT8oPKp8NUwl8Xk0FkoG6zvfO/Np+oQgPL51sbhZH8DogITadx8pgdY5Oi5MpRjVTu+5UCH6XOkrR3lLUiXFU5m4qH+5+e19/v9AfiVs1kulwNoJRjm0enKjeC2CkPgBPwqnvjsMpDmupeMe35+fpAYq3psuwpp+zYBFyVeKnntyTH7TrkUAuWawwqMk2YHDgQPAiL6J8Cvz09rUUD5dlDjPoB00yET8Dg/mFTLKBX1UXxgJJe2UHb466+/bvf39+3q6mqItrA9jaFnt8m/xFO24fer55L+ez1t1+73++EMFfFVW5Dud6b0Yap0gYMPoGJIYgSve+jZEVeP4DmK3aObyJHOLhk8N/zefnLS7oy9veRM+FsGNUUp+AqdrjO0pn650mNdhuuc9rTSZB0iZBWuEvT7+vp6QPxE99zD5DXyjMpOvjgyT2Btas+Wv91IVfPpUSGfM41J99yA0Og5sEshdI6VcuTjIn1cGbnMqQ1ltqs+V3hqU183TeDFTxflu/OcJ86xxrjb7Yb6DnD4t0CwXsOlPHsEQTRxxSkwwhNEnbfJzoh2Fjqz1sb64rz2NikPrivVPLpMJFDt9RPduqb7TgejfaKJ2xbsxxcWjNZw+4kfiLq7uxva51y09hls6dPdjMywfV1TX/4GC+WAR4hzMeKRJ+qV8n18m+v9+/fDokp9ydk6SEkLC1/1u647SCAffd6S30ht+bYs6zHH6/b2diSrFcjpgZZfvVXhjaZOquu+CvBn2KYj4ER0NZBKmfic/3bESccthlNxdF330qRQCDhGFxAHYHSoblASz2isFRpsbWzAPES9WCxGB0KpvjtN8YI88jwGOXutBv27CFQa7pn7uFwhWmsjw1GFgCujX72Spf89DO1zRNCQZMj7TE7CjciU3vTGk57zZLNUXL4kC9wGoiPxseo651Rz4itlp5OvS0o+SJPz8eXlpT08PAwH8shwJwctQML5cZl14Cc5nZMz4wnEpFcrUHfwiV8qyQlX0dQKALoDYtt8nv+fnJy0r7/+ui0Wi3Z1dTXwVuNwOn1xQto49wJR3BLldgWdrSJS2hbV2KvInGxZsj1qV1sR/mG25MSfn5+Hc0MIQhLv9YwiSqTL8zt6AE7jdlvvc+zbROke+68WSKpHOSF/XU8oo/78FEhIZfZWBYV3TkeVoqZrU6ChomeqL953Y6nrLAQUacXdWv2+egIopFPteeIhV4IM8SncTLBCR0CF4Vnti8Vi+GSrgwmiyWSApxxdSozrjdmdsa55/1IQJoNWfPW+9Lf/5rM92aVT5tg8esP6BJy98VKxK/nm9bS6qcZMOhywEbQRICZgy7ZdttnmnEL6fH+4MlJ+TfpB3qT2xX/Kd2vjrw32+J5oUB05KTr+9+/fD9+6IE8or76/PjdKyn4Ihvw+f2t+aT/E8/v7+/bFF1+03/3ud0P4XTSLZ9pioO4n50L+cJtI/fobTaqrFb22Ghh1UD0BATltLj7EK+aVSDZOTj6fjHt6etru7u4GXtHxpmiW+r25uRnRrYUH5Yn0VqDDx0258Pl2MMHrDhi8jaR/1NVKphKdCVykZ6fKbODgxr/XQYWUe2XKOPlEuKC6UXXm98I2rE+mpolkn55gwvZ80tSHP8MVgCuWFEIK46E3tcF3pVtrw+ddZby4UuSxpsog1ql7HoXQCpLtaoWx2+1GyVE0YDqhUu2q6E0aIvjl8vNrmNqnoxw40q94PCVnvvfMuU2OjM+xvwpIcHwVvalUMj+HNkZzCBZUjxnhDkicXzTWBHICc5KLBDhYeGCSgw93fp6U6vNzdnY2yF/Vn55Nxr4qSa8dUJEvrX3WGZ22SjtSOQMBBx1eVIE1H8disRhOT9X1RLf0z/ksR3t9fd0+ffrU1uv16EwNzWlrn3VZX+RUu5Jfzr8vbDinyWH3isYjB31+fj6AMeoogR/BOXmtXB7Rlb5h45FkzQ23KEi/6nHrhHrm9dm+eMa5FG3J97DNlKAtfZbNFF2MGqXIpMuh+Oa0EST5/FRghWUWcHCFckPce07KwP2qY0oy8lMDdGOUwICeV3Eh83b5vK/GWDchVSpEMjYSThY5WNWXosgQKGlMf7OIBn0tlIqu7wioXZ7U50aISst9Tu63MbxIJXt6ehoOeaKikVZlaWs/VM9x3jwS4CXNfwKY1TP+KqvPVTIY3r6DWl1nGxVo9XYJPnzfX9cpc4xe0eC/vLwM72x7yFPGUyF40aq3eMgHGRk3rlq1uk4TqNL4UWYEWnUioMakNvW3gIgSfZ0Gha2lbwrL0+b40cKVAydPPQJ3cnJSfvI62SY9u1qthuQ01yHqvkcNqkI+6TcjS7pGGdD7+y7fcoqcQ8qp+N9aG8YuWdF9zSu3msRHft+F+qW5enp6are3t0O7nAN3uOK73u7R13BlK7h97Hqnf4ymkF8qBGKcD16n/Di91Ral2w+nlXPpdkQ6WkUy6R968sJ5Fx2UI9qXRHcqv/rkSCfKy36/L4FDxeTktOcAFdJFhlVM8HCPCzkFo2or1SGi0/UKbOnZ1DaNkfZ4pcy6zmd4nrxvTdBxcfXQWhv2I71f0efARmFOORQCDo+aMONXRQZd41ZY0ZVA7cnIuQNNJYE7RmfSHBDJV/LiQMKBKPdwXfaclhSxo8OT89b741Xkw1eAXCVKBrWy1ArK+5R+ypgqb0Y8YxSKYXQCSAEBHxONOg/mUT39Lb1Tu5IvB7QcP50JHahvCXLR4HNBejknPm9cTfp80fGrXTnsxeLzq85KRE35Kb64mLI1SW5SHRU5V0UBGfoXuPfIAvmnaKAiJ/6pc203MHLBY8IZGvcVsBYtlCWCZ9lQHuT0/v37tlwuR9FQ2jHJIgGo2pQss30+T3+gfj3yQTvu/izJVrpW+bPk5H0BRJuvsbkf8L405l7fLHMW+G86xyE5OBpdOqzW2qBErb0a6dROat8NkdOXnqUQEkXyftW/g4/0xkMSDg+1sT0HDzJyaZ/Kec7JTyFjrvp1zR2nzw95wdeUVKTM/IoclV5/ezY868pZ+YqBhoBj5KmGvJ544g68tVcw0wO1pJ/zSJmgDPeAYgVgEkAUX8SzRB+NgYw4IwikWas9GUSPzPDAmufn57bZbA4c72LxmjBJw0KjKb7QeRP4sF9dl7NPPOGKW3PG8afwOB0LaWfYnQ6Lrw+mLRqCFc6POxfaCL7eRidCmpgAqTrb7bb94z/+Y1uv1+3q6qp9//33IzmqZGjKsCfe+nOkhaDR5V8ALQFFttHa+EA98f/+/n4AD3xekSfybblcDkmLPBdkt9sNtkY8FeAVfWrrp59+OgAvaouv7GvMlEXquN7Q8WgI50P5F7pXOV3finDb6/bV7VcC28mnOhCpAANpoB2rbI7fS5E1L7Nex6yMcWXMewPxd6LnFHeAU3V7AKNCeu6kKlCS2k8ghWF7rZgTLT5pvQmnc3Fw1tr4wyvMMXBFU1tScq4QEkBp7fVVQ+VFyBAoOYm00vG1Nv5qKg1XDxSSTv7PuRJPd7tdW61WBzkaaR41H87nqnidpIAVnd6GaKUR8H1Gd4h0nrrmAMj5TYOo6A774HzwY2h8cyCtotmnxkpg6MXb4JzwBFMHPny+tfGreIxOiC4aVgIvj264fXLwQF77m0k+z72iMeqT0avVqt3d3Y1oVP9y3iqVbeE9p4HRMucnnyNo4ti0ZcXj2NWPPh+tdltrw9st1Hl+zE6F22iyK/rui8AW54URJtGkiIjqprNmHh8fh+Op1Y9oYZRLAMfpJGhaLBajRY/n2iSbUdkDt/kJICYbyH68D/cHnPdUaCO9LY6fbfgbhanMznGoDGKq44JJwrnnxqNLq+IM4USmifDrMp6+CiJN7hj4vyeuOHpMQuQhJP1dgQdvr7XPPFyv16P9SoWxeaiTeOI5Gjy1T4aTiqiiVaI7NLWh+621tl6v24cPH9pms2m3t7ft06dPo0xn5wmjIRyXnJTqEoiwjZ6Ddh7ydSpdc3DS+zuBYwd07iBd4by9yun4GBRalaHWvWr7w2VLdGmOlfTmBobgRXNBo5kAneRWBphfMJUsOd/9cCjKIcev8XEbw8GnCgGDJymS5uoVNtd1T7rTPdmKypZU80m9EW8UufHXVDWeJHfeflpEOHhzuUgRXfXDOWZ92QYH30734+Pj6BVO6a1Hk3yLUbxV+8xHYYRSdufdu3ej71Pc3NwM2yF826y114Rv8of+RblUikbxIDHnkfRAfGLCb5of6h75QVmm86aMuF1hhIiAwOeaJdkp1ndwmmT/LQD56BwHd5RefAXVK3NCIq2NnUD6voXTV9HkWwhpdeWreCpZVXjfjbqQtY8nTRbbWixew2mtjT+BTCVR+zwpUPfu7u5GBll7lr6V01o72D5YLD6f/SClFh+vr6/b9fV1a62129vbg6RK1WutjYw82+W58q21wdE5Dan0QARXOOqf9FRbSA5CkuP0/ntzp3ppS6xSUIbpBca4ReHGQc+oD8nYbvf5bRc9r4RatiWAodfVCFB8tdra+DPEzi8fx3q9HiV10WGQH4oS3d/fj74jQr4xv+Ps7Gx4xc8TZh3sOKDoyZRHwzg2N/RnZ2dtvV63T58+jYw86VXRgVXcwiBoYNs6KZO0cmFAmXP5dCDJcfM+5VJ1SG+VZe+y5ouiJM9aSDw8PIxAGLc4JBNK9nYw+/Hjx+G3f9iKddfr9WhLgVtmGh+jGHpF1MfO9rfb7QBauLDitoaPW3aYb6z5nLCuaNXvnu3w7TXas2TDVDhXDqiddv3vMl2V2REHN6667gQkYXI0quKKwf6q3wmlcyK8LaK6NAbdS8o25dgrvlR/V7QnoWrt9b1wCf5ut2t3d3cHe2Ach5D709PTaG9W7a3X60HANSdC5C5Y3CcXahWffE+X/0Q3jfx+vx99m4C0ewTJnQDBnfOI80V+0sj2lCsVRkqcHu9X90WD5yKQJgI4rsbFXzpw0eHtu2xKyWlMzs7OhigUPznMo5z1W23QmDNKJZlgXeVVyKjrukLdPKSHvOOYdWyxomqi3cGL2l2v1yOg43OguuQv+e4RCkbSHPDyGp/zLQGfVz2nudQn7EkfHana1jZbBRR9/l1PXRYoM2ojhZ9ddgjuZCNUdKgSP6GdopS6R1vgQMnBjrbTNAdaHL28vLTVajVaLbM/yuZyuRxtgUuOLy4uhjfJXO80fo2FNPLz3/6/2xddp81wmebcERyybrIjotvl1H2JeEx7qZIiHXrO587lqCpvOjmyh+B/nDvjVQAAIABJREFUbXFD4Pc42N6z3kYPwbshdkfjTsgjCF6fAuERjERr5dD0HBN+0vg9xMtrbEcJW0SfNHxe38dFh8KsZq5UOFb2wVMuE7hUPxVfuIKogKuK9munQIMrjK8qkrz1ZJ/OyOmhERbAIx2VrGvsyYCpTxobJhxyT1fGla9Aikc0ePxmiAw6wY361PPiifjmZy9Usr3b7YbnCZQUffJ9an5d0FfubFP33YHy7Qv2Kf4youLAVrx5enpqv/zyy2g+1C/bopMgyFdb/Pjcbvc5wZARDJXkcJN8eOnpkQMcjyC4/PMZfe+CH55SfV89t9baZrMZ5RhwJc4osCIUzMfSdpe3qVdztRD59OlTe3p6at99993AR86vrikqy/mgrog+Ahi3k6I32XT6GZ8b+g9/u8H/5zNVH9JZygwjKA6SU/ssDmBcvlNZ9Azh5eXlLIRAlCyhSO0m4n1gLqweKWAfqc0K5Dg69PZ8ohIt7Itj9tWVAw7ueU0BhoQARTsdvPMr/S1jyOuOXskDonG244AovYbpSuhC7olSuuc5JFROhjaJqNPcugGgwideJTl1JO7z4oX1maeQQAbl2V9BI8gjn+ms05YQM8Nbe02I3e12AwCg3DNMrN9OZ2X0WC+tRpKDc575StnbEU+0WmT/SRYJEFt7jZARlFGuvT+G3lNEi8CGjlXzkca0WLwe7y4A5O1q3nxrziNdlFPnp9sOgibd5zUmt7oeuh54vpLT6G8GJdukcUq/CfplP+SkPULF+aI8LBaLQb4Z/ZT+kWa+wUW7RzusbTVdW6/X7ZdffmmttWGblpFYRlmcP1w8JVBHO8ntLl9oMFpDWaOc+bgpL3y7zHXf6Us+gPp1f39fooc3fx2zKhUSrkBD+l9/M7TL9isQUNGj9qgg7iDTRKe/WxsrWgI9+p8OsLXDz6YmIMEJ9tXkfv8awksrA/UjxZZicjXgSFqCJwViXTpq0uDOW89pnpT86K9jiQc0WKLH8zZorJ3HDj5ceZM8pd+9PXufp17xCJMjeDpwztnl5WXb7/dDxj33ZDl/PjbRw9WZ6uvMALUlo6z8ANJbjZvX03ZJj/e/tigaI8daZXhrxStHVNmc1g7P6eBcKAfk06dPB+DTHWEPFPG6tgR5cidBGpPBCbh6wIAlgRbqDOkTPfrbnX4qmgOuYikH7rQrnugQO7cD/gz1g/PS2ji3S/UJXtgGadC2C7fqVGQ/+UGok5PPh3xpK4aLPUZVCO64XevzVvkovVmi+3oTTr+VkL5YLIbcHy6cWLi4Ej1K5mQd0upzVs2B9+XlVwEHdeThnDnP9O5xlZVW6qzf+60yha6cca3lZCEVD4e54ND5tZa/cpn+dlTJY1Q3m80Q4uQR00ToSsjSq1E0WBwnj6HV/qqiAkSobjiY1EiDyj163Xv37t1g/Dk2rrKksJvNZmgnhT7lHE5PT9tms2lPT08H59v73LIQWFWywLngXqi34UCUIE0KenFxMbzV4HvBzjeFZ9N9zdd+vx8O4NF10UIQJiNN+eR9l2XnMfmufgjqJNOuwwShrCseka9uTBM4U79uoDkX7swJpOX4np6eDrY1HPR6ro/LNvlNulUIwkUHcz30hUi1n8bsQCzZEPLQ58n1JW0bVNE19i9ZkywR/BPQ0bmwP4IDt6fuUD05kff8GTpORuHUF+1skkvSy+0fXV8ulyNnu1gsDkB25bwTmHbg7fPLBH/RRTlKwN6BEZ8lQKVdZH09UwECr/+b5DhUpTLQqSTDVLXnk5CE6ZjVTULEyQjTwfhKwJ19Rb8bpkTn1KRQYfzVKn/VrrXx2wPPz89tu92OkiC9TeU5cLxpZUcB1twpWUnGpbVxGF20KmPaHYkbQ91Xu715pfHi547JH5WErOkYyGt3En7CH1cDCoEynEpDQ1r16lpyFPv950/gcn4YEiU96W/1oWf1P/eJeYQ0k9ROTk5G+8GaE76LT74R0MkpXlxcDPLJVSzf8ZejE+B0veaXG1VXcijHS3p9TnRfW0TUg8Xi9X18d2hJ/9zWJJvjhbLHvXvxQfqifpM9cNDjTtEds4reolK0SvJAgJbsHZNjk4N3edMRz3JSbI+O27fAaF94VLXmS9s4vgXnQIlO3V/7Ji+dV34v8ZzjTDRwm8JtO/Xac5i8+Ny6bBHAEFj4s9wmISBhJETts3B8UwByrl+dPDmSjToxrMdXVnxll4QytdFDblN0JgPrz/eMMIXCBbhqszIwoscNFK+500vCJX5SQNgW6eTrmDpK1gVFDkAZ8lJKhcd0jYKsULfo9XqihXv8+u3jo6LRuD0/P7eLi4sob+74r66uyrnuzZXXV0nInL9TX3JYAgc0qnIaaa+a7aRoUDV2N4KUiZ6O8NPGLpt8lnN+enp68I59As7Sc63qaXh9zpbL5cEZASnBWIBHX3dV/5Q1JjJyD92Bv+Saq9DFIp/6yPvkrUraTnD7lOaYH47z53iNMsix8DcdS2v5FVnaCZdf5jq5XPrYSIv60jw+PDyMtg/4qWu9Mqs543kbApBqW/TzVUnOue7rf9oeFX3IT2+a6U2ixWL8xpDokX3kW1yUWdGi15lvbm6GvjVGfqRP9CcgoL9VeD6Ey08Fyljoaxxsaoz+xgjBFGWY/Ew+OvXv5c0RBxc0CqZWZf51RT3nhM7pq6qbjGsq/mxV34WTk5DaJJPdOPfoTmDB/077TjToNJQ0IFJEB0PcG6VCV1/HpDPkK3h6TveS0GnbRPUT/xz9Om/SnFHJKgWrSjKcVQQs9a9QKcPbbmwZLajGlYxLTz4dJPbG53XcOOs+57O119wTHfDk0R9GL7Qlok8bc6uCK0gCpGo+XS597lWH22SaB933BDjyM/VLnvbmID1TteFhe1+FJ9BR6YT3QWehedDbMeSR1++NQ07Z+2ZfAmAEZ3peIE8OX9EqflyMoElvkazX6zhWLpIISgQ4mM9DgCQQr/aY/E2bpleUP3z4MJxDk5ypFkDv3r1rz8/PQ0RHdlI+jXrjcyr6HYTS2bMNAlY979vECewzx0L6TIDB65yr1vLpkG5zemXWkdNq1IUyCWca+FzHnxTT66Rnp8ocg5CYlsavvxVmo/DpHqMKVRvptT0vbFMRBV8hS/m32+2gXPzAC/vXvCi8rPPgOW4KrxRHhvvDhw9DmJGhOa1I6IQpsGqX++Os7+9MO798dc6SVnBz+er99Opx5eZ9+98q3BOtgLLLR1XSqsTv0YnJ8JIWvnWgFTvnzscgQ8r5oYGSnNA5yiBx+yCt2PWs9ID5EcpvYORMY6AT8z1sGs4qqZLP639tkzFp0VdsXtweykineXUavR3phedYJLCh+VutVu3jx48HW6MVnU5zay2G1zn/lAvJkv6XTtLhM3yvtmiLBDhXq1V7eHgY7BnlgHk/KSeG49FrusrrWi4/HwilcxsY/dYJnlz5a1715VXJwu3t7RA5Ua7M09PTKBLHhFtG20kj+2jt8DVHX2RoLh20e7u6p0RIjYuylHwat66ZLEz+kme9MusjV3MNs+r699VdCeaUKdQ8t87UM9XfKjSoFVBKDkPPVn33aJeicuuBX02kMdHfm81mFML10DBXK9wXrhwazwBQfT5DYVZ/nGeGKskrnhQn3i0W48OlXOB7cpNktMfXY+WFz7kR4z1vVzzq7Sn2rqWi9lzZ9b/ySrjSozGRkWOUSUZVYJKGUO2qrvqQEfIMbtLpqys6YW53yTjLbpCfckYu93IoijQI5MoBMcTte97JDjHCIgcnPlTgwedUupcWVu5E3AZwbnqrQD1DJ+ZlCnxyLKRD80FgoHuaA82b7ALfmHA7wjesNHaG+dW3thvOzs7a5eVlu7q6Go6X5tsgqp/yHCjvslucT86PIqFpa0AyqOf2+8+vaIoHzl/qPYEr+e30O4jz++zD34Rgn7Ivq9XqICfCI7K85/kmTstcPz0r4jDHebpRFRM967gyoo6SKkeQBpYMelWqOtV1Ojjfa+XEJAWvjMAcQMRQP9H4fj9+J5ohNoXZZEg9+YyrTP1WHVcMAQLx4OTkZFAqXaPBYZhaBiYlMGov1HkhkOERHPKO8pCMM531MeDhGEDroEHvZc/5VkbPeKQ+HLAwtMmVBUOjp6enw2ue+/1+AIvuFCRbMrD8jgkd3ePjY7u8vBz2rxWxEliU01X/4gVlJQFe0UpwqfEyGZP98YNcrKPCN4Mqm+NFDkXj9VVgcgSpDUZhfJ45Z9Uet8+92vUifoivHGtql3pC28x+2b/stYPCp6entlqtRs4s6ZmPiVsHBBDSnXfv3rXvvvuuXV5etvv7+3Z9fX2Qv8F2aV80Fm7bkGbZQ1+Nkz7qhZ5XfgxlMTl56h3brLYrXTa4xeLgUn9XdmSxWIwSTD1VwGmqwEGyh5WfZ5kEDlwdVIrDlQ0H0NoYdIio9LwT3lsd+sBTIfOmSk/4iUbdaVQ0SijmAJkePfxaHZGk0yzHzxWFDLIbM4aOBULu7+9HqyyNTW9fyFjJwdBpqc3WXpWWDs55pBWTGwD14UCt4g3H6opVGWIvdMy9er064pOv4nrFDbeDUhmNClQ4YKUubLfbYQtK9/j2RmvjMwqWy9e3KVp73UPmouH+/n44MVDywf1ePqtVkGTSV/+iSdd1oigdkZwGZXm9Xo8O7GF4n3Oj53gIDnmd5s+3PMRndxhVcVDLtntF9Zl7QhlIoMcXSezPAXrqy+lmm7RZzGchKD8/Px9tixJoqp5AwW63G14dl37v9/vRouv9+/ft8vKy/fWvf203NzcH58mIPjpW0enbNPznoNrnk8/I7mk83J5hrobzP/GeNteBHaN6DoqSf000p8K+KBcuz164daK+5vqs7smRFxcX+6mG9Py7d+/aarUaTt7iPQ6k10aqS4M8Zz+v6m+K+anwNaCkiPybKJQruV9Tes4qGUVfbfA3s5MT/aqraAAVnUURA355jitOOjR/1SqhZxUhaOdla/ljLqznoXGhcNX3MScevGWuUmiyaqdXz/dcPWGxRyONTm9Ple34VloCLA6W2Lfa1Zw7UKausl4VHiYvU10BBW2HqX8eme2rUOd9FcnS875P/RZ7wbExp4R5HA6e2G+S0wRcyLM5zsXljXygDqnN1toQXWDUkiBT9iFFaOQg/WhqtcNtTdVTHsFutxvZXd0TaPEjyUUD36IQ/xlFXSwWw0JIb+0wsqBnBXSU+Ktcmyqsr+eS3FLPRIPaTDaAsuy20m2++j8/P2/v379vu93nD4Pt9/shOpdAp3iTtqucpoeHh9Io/iYnR0p4+VElF/4k2HNQfAU4aLSTc/NogxvCXv+6LhTHUGuii8z3CMtUn96OP5f4l1YOvO9Rn9YOM9YrNJoMLFGzVoOr1aptNpt2fn7eHh4eRqehJV56v3IGquM8YD3nhTtshbz1vKIknoyU+JbmJNHu191JSunZtvSCq2PeJzhmX8nBVnSKTwlUz9m2ae0w4ZOhXRVGLPywHP9bBlSOUWOnbPlrhASZpIl75ALj1HvPFNf/zHav9JHgZW50ck7Z7/ejaCGdMvMwdC/JuNqp2hePHJR7UR+uzwkQtvYqM0q6Y2FEUX3SNjISoLlSPg375DaTohf+Ro7mkPPCA+4oD56XIX4q8uXt+JiUd0Ubojmk/FT8dR3wRQL/r0BeZY9VUgRK4/rmm2/aarVq//7v/z6K1jkNnKfkP3mtshkqs89xmKrDA1oS47w40ck49waRHLBK2hvz56bG5iG4qfG0Nl410aHQWM5ZySTg42NwwUj8SsZiCsBptaDIgowHjTGV7OLiol1eXg7v//uWifOFtKcQMelJPOgBQLbvCt0rx9QjnVTABJj8fjX3pNV5w/FVvxnW1/2ezog2hqFVePYB5ThtxWhF6St+OhDpEFfgaW7Un4y4jCK3Vfw5Hjzl88LrLo9yUEo41grWQT9pqxYCzlsHJbwn3WICJ48Hd9CebJzrec+ecA58LA4unXbWIzhlcuFisRiBOdIvGyHZkAP3aBftomhK2wb6fX9/P0qQJDBlu/pbtoz5L1zxC4AoiiqQ41tsDrYoV4wSiMfO1xTlU/+M4PGaeJ7Ahn5vt9v2l7/8pS0WrxFb6iK3Szg3Ls9uf6b81G/+rQp1PgUYvD7/9+tz+usVV/z0LK+TkWmfPRmPNAaifbZHxfcQbxJO/p7DWxee9BzbJuLkPQl85cwkqApr8nUf9iuj7KtfBwYVqEvCnsbB5+a87jpVevIo3hDdp/oePSDP3RHu9/uD1VNFV+KBHJK3rd9VngPbkXMj+NbfFYh2h0xH0trraYVcRTKXhluBel6v7Kmuj1XFjTvpotwn4CMH4iHmOfxOeujy4c5GzpQr5cVivBfu4JrjSX1NgWX1kxYtbmN8fJJfzrPkqLIvqsP55VsZDqQZgUlgxrcItDWq+4x4+Dj8PBLnmZ4XjQS5fny1z4PrFiNIi8VrYjn55n07QNCY/ONq3BZm/76Vm+w+7XhvMVKNsypHAwcOMu1vORpzBUu/WSRgPHOf7VYgobpXOSO/1gMQbvB7z7DwGw7JgTiP3Gj4PQcVTn9v/Ak8uQGko6fAybj7q3dSOI2NTtQNcdpTcz7q+px7Pv4qeTfJYQ989Uo1Ji9V+5Uh8j1NlxXWlf55W1zZVbLuR4CzMPFMCYtcSVGG9axABl/x0n0CKz3H1+AqUMaohCd8MTxNmngsshtQJvY6cNUYq3mhvvXetkjj8XvUT9FDfenZqYquqj711nXcgbv45A5dDsujIozyMKJGUEgHSkDhK3A6VJcLl0PnAbdplsvXNyO4RcRx8twavfWjHArmA4hWXe/5CPLVHTbpY33fIpCci87kQ72kt5TcZyh5OcmpXtmmf/UyZR9nnePg13oGM/1d1esBCL/eM/akiULD+mkSKkV05ObIPAGiOYqfiisgQYErvfMhzc0UmPGS5tKVtbXxB2RckenwnG9Ot68gKxpUPAye2hYdfq9SwsTXqlSGWf+cTz39qNqmkZUzlGFN21a+gtH/aXVFWfWx+MFd4jPDzwrxppCp5nOxeI1m6CAeGX2dvKc+6Ih6USHpIGlODkRggtEfRkAot6KVbTtQrcoceXEb4HKbtiJcZ+aWnj1L9iLRzwij08fnGBFgv26z9MaF61pyjFxpk2c+HuVQtfYaHSBIpgz6Kaa+YLu4uBgSKXkQEg8rS6DJgQjLYrEYjrqWbdM4BVh8nkUnFzXVdgT1X/f97bWpwmjvYrFo3333XWuttf/6r/8a6lC/5+jDrHMciKr8mojx8JW30StuHMhUrhx6dKbJ7TmXdJ/XycCUM5HGdQxo8JWPKxvpqADc3P4dkWpMFHTVk1KmzHT/neabjs/vp7BiJR+JB1VJtKW/fRXEMscxUMaS8+bYnObeOBIwVanyYpJzIE/3+/0oXLrf7w+Sv2RMPFLhulcZE4JBJjAym963A6p5d52XMXXgpANv6Dz44abWXiM4KUKmvjjfbpjTAijJB3XAZaBaWDj/vMwFJ1NF/JzrXNyJibcEfOK7Az7y0be5lGPA1zcFHNhXOuyICbJKVGROg+jlwVkfPnwYzmIgiHx5eRle9yQ4UrRiuVy2u7u7YStkt9u1zWYzyC9BdUoipIwSxNJ3qj6japwrb5O/U3TAt3+ZS+Iyzue+//770TX1rcOueC5GVWZtVXAg3ANip72MzCnDP6feVMLgMU57bkmrt7mK29r45K+quNK1lpHknEgC97zoqJIRS0CLqNgdU69QOfwVKB9DCk/OlQ/vcwr4zamr+1Udb4erdF8tJWeenBDbm1r59ubbHT2vuwPgaoorN5fx3rxX9LF/RhPYZ+Jv2rYQXanefr8fZfr3QIiv4mij5BD9+Wq7SzTyedVPYHQOgGe7VUlgbq4N6oFpdzTeV9onr9qfoodAkGPwr8Ym/gpsKuKl6/6WG+89PDwMCds6Ml8H0XGhRDq03cXjzeXgmSBOvSJ4Sqenur/yeaQd1FhdfmgX3M86qKC+Uy7TAlARnAQsPHekKm/KcajQyJTxdyFLyIq/Wzt0gqRjTp9VOcZZpRUEy5xxeHv+fM8o+LirsQt9+zGwFc1ppdraodDTwLsg+3g4Fi/+Ol1VEn+SoZqqR9rnOOA5tHHF0pPBVCeBGSYG6h3yBECSIUr64M4m7WX2QKQbeI7ZaSI9bNvveZ2eY+V90cD8mqoN8ai1drCi49/JoU7ptY8zgbTeuPicJwKm/nq06O8pOfXxOt0EveSdb1uRVl9UOJjxPuWs5dScH/qf2wu6RjniitwPj1Nki2O+vr5uX3311fChKr5RoXqLxes5IAzj7/f7g6RVbjeQh9rKcPuotsjjSh90vZKxtD2Y5teBCdsncBOfvT8CCrZXlcmtijmrjqniwtlzqIvF4ffNe0p2LIA4hn43oMeWtKLy367MfP+cwsMEtJ7h3W63pSNTHf7P+0LZ3EPzfUwKoqNk9qtMajcsrnxpDD7GqX1gJvElXpOPqW8ieRmMqVdnp4y8Awbfq6Sz4Z4raVKdBBp+DXCeGhcNZ3pNcW4OxzH0pHFU2xdOv8ukH8HrsqP21I5/E6HnmCuwOmceKF9pldpaG17XlB5Wjn/uvLvTokNz0EQ9P1ZHWXjqJG1g8iXkNaOVlZ1SoRx4H/v9vv3444+z/A3p5OF36/W6XVxcjD6MpWPXZQc9edJpE6+ZP+CgOEUunT/+N7dCfPwcF39Xc0qA5NsbvTKZHKmB+yEaJOLy8rK9vLyUH17RYNM9X121lkM/v0U5BjRIgI55ra8HEJwOKhJ/u+JqYr3NNBZ3jEmQqr8rg+H9OD94voM7+GP5532SB6mO6OaWUBqXSjVGPuPonH05fU6bt1OtFPQMvw+haENqK62Sq+t6br9/3ZKo5pR1PeNdoVudzZHexpjrMOcYozQm/5vHaKvdxCeGovmbslkBMbVTOVWXycqxJx60Vts22lp99On+/j5+XKlXnM/uuFiH8++00PGl+/67AsvOS/LP9XWuf6iue/+93BUWAQN9TFBRiqurq9ZavYVL3VF/DmLVbwIPDnxchlar1QAgORd08P5stUDR791ufO4KaeEWzJS+doGDhO78/Hx0wJMTdX9/XxqUhJh+i5IU9hhDNqfd/5dFhnBun0nBWXzvi4Xj9f1L/p1WaI7mqRAU4tbGRxFXzqJCvf73HMMw1a6306un63p9z2W4kq001vScn/Kno3aVNd4DB1My7f29pfA5ncmxXq9Hn5p253BMcQNVJVJPyULqOzkJ0uv1PWLiBpcy3QOQv1XhXO/3n8PxjKBVkcvUDmXBE5ST00vg2tvSdZ97goJEG3MKktw4aOjZjcQvLwRClexwbD4mnjUhn6Y3JhiBdFs7h172R7CRZFl1BdwdtLiN5TiS7FYLyop2Rr6r0gUOEtiHh4cY3tL//j4yB5gG0nP0bzFMFfN7dXuO7dcYiJ6DUftcfTjA8jp83ttwgzIlEK29npOxWCxikoza8KQv/y3DlPqXEroDPqb0xp/uUymn2qnmZ6r9Y0sK0yqDXMd1e0jaS6/fntFPY1L/1VtCnF9lmzMH49eCErcRx/KYX9zk2EWzZ7L765sOWPb71yx9tTO1DZMcqjsFjpn0eXH6d7vd6CAib3uqkC5G4Rg1dt5XTob6zrwH6j/nwIGugzGvm4DCHGA0hwdT9Xz+9PbRZrMZth9c5nkImv4XIPK8EBby0ceXEqPJ30+fPpVAmHrqQCkBspTwmgBJ4lEqkxEHKdtXX33V7u7u2u3t7aRj1P+9RCCWatCpfdVXPe39VwisYkZadfBvZ+wcxzEFWCqn5srXa4tCzTGkDOnEMyYaOZ/492q1GpTIDaoDmOScW2txi2WKJ6kO+3I+VW2TD3Pq/pqScieqvpfLZbu8vBwiDfpy5dRbQ1UhIKnyJFwuvA7/VyhTTkyH5jAJzPtO5S0gY0rPKn3hMxUApBw7T5RD5DI2x2nr3lvmr9LP1vL3ZvzZ5Ih0T/eraIU7DQ+D81PTzi+Wyhf09NWfr4DkW0tvznp2lbTonwAD82a8bQdiPR+Q5FHte13PvUn9JiDLZ5JPrHKm2E4vp6y1I85xuL6+nsw9cMWuwh0V43VoDL+S2HMK3odPzNS4Eg0+lqm2qvZSSYZP/VKRuZJ3QeM1Zsf6vm4ynrzmAMLHkz4oRCfFtr39NHeJHt5LwK1yclPPput8vqfYU+1X9LBeLwF0sficza0Pg029sphKigAI4PtKI9Hq1/yZl5eXIeNcr7U9Pz8P11I7c42+ZP0YJ+H7w8l+9LY//LeDBgfUyTlWslPZup6zTSUBnkpnkp5pf10lHZaV6PEchqRLaaFSJfXR+Xr7epVZe+wCp5W+/9qS7FDio/h3fX09GoO2WtzJ61l/m2K/fz0+XVt8uq5IIyN+nCMCWh7f77TzMC2XS4J/6lm11UF+TAFkL7OAQy+DlIOaKpXDpPObe9jSsf3PZQoZesx4fyvBd+GqaBTv3Ijw2QpZz/kt8KDCEF1lYF0wk8JWwM6Bz1t42QN7lZOv6lTtpGd6xsnrPj4+Hnx1cG5f3id/Ox2eEKeSwL+vSqTv2+22rVartl6vR++z+zzTcR9jB6aup8S+VKZWRyo98JSiBQ5C5wKAuTxIfDz22Tn9y3FRRtSfPkfdWxROjZ22IOn+3LeZ5pREi19L9rHXFkFOa+O3O3a7z5/z/uKLL9p2u223t7dDH+xLDn25XLZ37961m5ubA7nla50CCOKPO/IqgZH6VvFgSr8quy06+Knxqhx11umclRevSUhdWNmekJi+Sja1SlosPieNeP1jaOuNbQowsG5C6hxv9YpgorsCLL5CUhjZTzRjfxJId2a9V9qcFg9l+Rxq3iqH2RNk/U599MqcOlPPHtNGD1z0Vmk9R0bl97lNYMyf099cBb0F8FT1NfcvLy/t48eP7fvvv2/X19fdKEqiMc1+4w+oAAAgAElEQVR5GvcUTXMM4tSrs1PFjTn7PUZefC59HJX8JdrdMVRt6p7bjIo2t1NPT0+jcxCYUJnm0MfgoNWvt/YKABeLRdtsNvFMhV+zUPAt5eRrdJ91GWVi0YpfdG82m/bP//zP7cOHD6Px0sEy30G5Cdz2ka6+e/duyKkgncp7YhSZBwL6K5NuYxaLxcFJsdRl0eighXPAMU/Nx1EnRx5bKNAJJSr5qrXPiU+9lQWZrFfXqATMWk/90xBUhqhyBr3SAywVkk48IW3V/qav9n3/0k8CJA3Oi0Sv33N+Og+rsSWFTdcrWp03Xn9OX28pvecq8FOBpTnlWFpdtvnqlL8zPye3KNHDve6Xl5chypAys934+3jeOg8qPEOiV1xmKr2eAiGuL62N38l/Kxj7NXS7nFVbMlP9aW493O5OKNnPKV30Z9Re2r755ptv2s8//9yur6+P1he1r/+TvE3Z3bRA89ckCUhU7/LyskwwlP9JEQTpkhz/4+PjyDH7/2dnZ8O2YHp7Qw6e9l9HZn/48GFIKaBOzinU36n8mtaOPDmySv6pJmnKCWgitNfrbbljmVN6xmGOIs8x5glVJ6dY0e0AhX0yQzfV898pHOerujmGj7ymk6BiJGDmtEmgKfQJtOk5TzrqzXMFblK9X+u0qr6rvt5iBClHU0bf65FXfO0tvZZ4DD3eF7Pxne5qPFWhYa1KNUben+qzx88ecKhom3LwrDdH9iqZ4bNzwUHqr7K7yba4vXRbQQcl4JFsO20OP+PtzvWXX37pnvczNbaKJ/xQVQ84+mLL55R0KRLeWmv/8R//0W5vbyPwUP9qX28kETSIHx8/fhyt6vmxre12G0969Q/96fyX6+vr0db21dXV0A/fhmJ0upIffU2ztX6O1kBD9+5vUKoV4WKxGD5t2to0Wq7KWwx2rxzjcBwtuqAnlO/1qz5ltN2wVKUCMN4+HXhSTAmdo+aek/M++TbOlKEnD/1rhr2xVg5jal9zqt1EY68kg1PNwdT8ze1Xhsed+VwgMqdQTmjIvI/Ksaf+K3mekifKas9pex5GBTA9d2IuyFD/PZA7h++S0zTWqTamaJ3qN8mrg4epRR+f0xs3khMBhJRQqe2vKXvodFX2UUWn1Fb5MFNAj33zmt4qWq/X7eeffy7b4N/6zdN33717115eXoYtDE96TDSmOdHY/CNWzE9RXZ6CWdke6rc+YNba61ZNr/wq4KDBOPMqJ5YMBA+YYT2iw15x5SY9laIkWo4pXI05Db5aSqFB1XXj68+qPX+HWOPk/84PtuevVnlGbvU8r6UVUAIkbINtpRAr51+8coeV9vJ6pXJoVd05bU715cX5wv/fQoPfS1GFqQNb5pRKjtm/Z5L32nK6q2Pkp3ij/lK7nO9kS6pnq9cUqz71W7rJa9WrmNW2QtJ5b99pqIovXqbq0sGzL/3NqJBn5asen/VPbnt/vg1CnvC5XhTEC4+0VvGtugSq032fT7ext7e37e7u7oAGH6/+pqMWnefn56PvYjCCx8+LKzLhSe+ed6MEa8rzcrkcDoza7XbDpwfSfMkf+CJN/c6xJW8CDm7Yew46PaeSVha+f+PPp+d6yNTbn5uBPVV8QnwSXZl8xePKoTHzs7SVE+85x7RaoJCyHYYe+bzTS/4mcOP96P8p45wcbOWI2faceZ4qov/09DRmNc8piW/J8M+hR8/OARBSbsqbrrOtY0uiNekhjf2xpQcSkjyQNl5PTtbbSo7I+0pjPhbMyQ5WK+nes3PLFE3Vgs35WtlQ6jPBkNuM1saHIfGo9DnRPtoQv+799MrUm2fV/CcQzLwep8F5mSJV5EsCpz/99NPIFvpXk/f7/XBOitOquUj64ePTV0B5P/Ha37xT/8fMwSzgkF7x87BQUmhnQoX4qMQ9wFD9nnNtrhHoMcyFxffTkrDpN/f8uU9IXvirqZ7hXCXxpP7YtoQ1KZsrcuX0kvNPykkeVPd6c6VP2wpRp/E5Dfo7GboEKklHtVo8tiRg5f9P8dPHpMIxJTA2Rf/UHCYa+K83xjSXvevJ4M6RsZ7hTNti3k8FHpzvlWObKlXkL8lu1X4FYPx3xdtUfMHiztJtNZ2X/ufWI8fqPKXN6QGT9OqnO03OH6Ma6mO9Xh+smJO+c5F2cnIyOn1U9xOvnK9JVh0gkK+qS14le0kfWn2XRM96rlGK4PJ/L6ItvVzAOr9ZxMHD/+qgclwcSA/Rk+hkUHj/tyjJiUzRm5S1Nx4CCldAtqPry+Xy4Nv0bCvxNgGDSsC1X7VardpqtRol0MgoVMru9Pr1pOhVEmX1io8rAkFO+gw3x5xkUnX4ZcfKYUuJNA+Jx/638yDJivOtBwqcntSPAKSUujoHIpXKmU4Vj0Ql2XAArMLfzocESFivV3y+p+ibO16vl/TJ++nR0qO/B26m6OvZymPGuVjk7Uo6Wz5TbUWQDjrAFIVWXx5NZR3frvCiNp6fn0fnKSQHqN/cGnC77DzxRcScuXFZ9+fFv94rjgmQyYZpvCoJuJydnbXT09MBEPBtq2QnvRBMMqmzVyaBA50KiWACTM84OcLq9VMNbo6yJkPtdVLCTo/+yrhNgRxHvpWhcwCQnFASRBpr9uH0MmFI4CTR61nT1diT4fD2mOzqX1R0oU8Zzg8PDyM+6Thm9kmAkIo7616p3kqZU3qG1PXF60+BCF7jnFT7+FXp8Yj/90BdJes+PtUhUGRGOWW+tbGhnNr2SPLCPuc40koXvR2tcNPpi15fZU4m+jFAx/Xb68wBNG6fq/+d/urNA45Dc0mn6HPcA589eXNe+AqYjq0CDaTBo7gVeN3v96MEbfFP4ENjTHaSr26Sh6rjPOkl5qrNy8vLIaEyyQu3yER7a214w8NPenVwlorsy5Q+zgYOSemqgac2etemBGrKwM6hobV+SNdR6LFtO0DpAQr254aWK22uABKooCC4wWlt/LXKp6eng4SaSiDnjpfgRuiYr0WxfdWR0njEyo0R+ZJKz3BqvMnROb8roPTWkox6Dzz4/VTc+M1xknPoVHsyilUmddUPeer0qi6Bju8lE2RSVipn4PRIbqqV4jF88Sz1CtBX7R5jJypAlpyfl7lznualuidwl/pKNt5leMoB8vPui8XiYNvb59N/V/QTGPVsK21QArzsjxERtsm8BMqHbJoW0i57bNttT+Iny83NzUEugvNBR3i/vLy01WrVdrvd6M0iHrala1woepnr0yeBQ3KmvXucNFc+NzROZAVQ5tJIGtL9udenCuvPUfb0vDtLGcCzs7OYWJkQKut4drNQpyvQnLH2DA7rUAmT8+czukYwk/jn9yplb+1wZeTz0jMuDjR6Y62MAYtnQ6s+x8sEKPadeOG60CtTctwz/sxGb+3wYzupjR4f1JZ/HIiZ4Qyl+vir8facCGlJclLRmtrhGKYAgtPbcwbUiR5dU/Ne6c5bbJiDUIJJ8ZFbEAT+ckquZ0mm3U/08oqm7AKva/tO4NRthc9jddKtAENysm5D+Jy3XwEi2XYfY/J3DmLmyK3q6GvH5E9li52/U1vWXmafHFkhnp5RYr3ePSEnN6g9A/X/Y0l7VSo9407BS5++ZamEcbFYDJ+FpVP3lf8cADHHYSUhdFSdAIu3KyNEFM63PQiYXJFVN7Wre5Xc9n73imig86vOntArVufn5+35+TmCi2NpONZBuNGmjvkq0xNyk1NzAJEMLa9NZarT2E6BPYICp43zoeKAtuLNVCFtrjvJkXNfvbKR4o0n07mt7YET14meQ/Jxs271VVXWlbx4wrbzhWOoeJycqJc0Z9x61fYrZUX96oCk+/v7rvN1vvJtEY7NfVPFK6ed8kAe6T6Pl+6Nu+Kl65nTMjfpmyByju1vbcZntXuNeIYuCWGZYlIStjkGslKM9Xo9OtAi1anaOqZ4Ms8U4JkyYOl+zzESVcsA+Os41bNT19wI9PbkqrHwNEPOLwsBAlcLrmzs2/dVp8b0WwFQjs23OJL8ahuA73CLfhV3BClJs8rJqeZi7srBjaFoTiFMr8NrfJulAg4+5jkG0sfn/aQE7d4ihcWdrF/3eUn0VHQnsNQbb2U3ek7VafJnphyyj9nnRPOorceq/94qPa34FeHiWQKJXm9DxdtNtsWPKk913NZ5u5Qzn0+2xVwY6jjbTnkgDhoTD0gLx0OeJr75nKh+T47n+FuWo5Ijk3DT0PspVXMMtaPWuYbeGe5Iiw6r1/fUvbnGl3Q4b5Lg8Vk3Uqrj+/C9vl9eXkanlems8zkC0etfQp4ceBq/19MqYQ6IYq5EKuRHQvDVOLy/CgBxzueCJI1RRoNGRHRqT1RZyxwv8xcUoXB+T/XP9tROr+i0P41Zq0j15XpcRW4oJyyck8roOcDY7w9fb04JZ3RMeo5tOh09B5rquPE/xqAmuzdlY6bmlzlMPZlM7czhEWlMoMm3Lbx/t98VDarL7xOlfB0fE8fOJG/dT6Brv9+3+/v7kfzOKR614ficRvYtOU++wNv2BRLpT/LrH6Ni++l6a+NzNrz+3CjsVOlyVEatJ2zJWHu95PxU7/z8fEC1PcVIApva2+/3B0mAFFgXcDpoby8hcfZF3jiiVT03rKTJn0kIlI6F9KSVqQu9/tcrmXLiLuTq22lMIUmn18fqf/s4vY1EM8dSAUKvfwxA6oGG6r7XJT9VqvefxXP9f3Z21jabTTs7OzuYbzpGOdMksyzOq0pfdZ8AU+NwB+Dghaf1kU6fL7V7dnZ2IB/UG86j0y/+Jv1Isp/G7E7H6yUnT9Dgjoh/V07S5WsO8PRnWQTokkNKNPhvD9OnsUzRl/QtPc+50v/Ks/J7v/vd79o333wzHIvcm1POg8vNHD5X9rmSA4IUj1p4X1UuSAI0BPWM6tH/pHH0thv8GfJaCxSCFf0mnVVy+JRsHH1yJBmsAX/55ZfD98ePKTpfQBn/PQFI5wO4oew5EPV1c3NTKlOv9BxL6tfBRUL1FDgaLW/DUSfb5u8E3Lw9JjZRwFN41UN+CbzJwU1tayVa/G8aZRoUF/C05eVh6wSOvCT58XEmnsrhqvhZ/ax/eno6fO72+fl5OP+eIFbjTYmTPdp7sjvllFiH/PStCtGW9oqTseOcUbb8FUfWa20s42+RJedbBaIq/ian6yv2Sg9SmWMj/L4XbT0mMEM6K6eT+phTz+tqDglmq2hmeob39vt9u76+buv1ul1cXLT9fj98GVlylkoPFPeK64kvaNSm52SldqijPV7yeb6BUel0BcBor48tHJO/mZFsRwIgvXIUcEgD3+/3w4dLeI8IzVczus4s3Tl9Hys8HPx2ux0J6Nz+egbaM9CTgSUo8DbcKVehQE62J5OpD15jO9xfY122retuVEV3JbweWvb2HAwlpXD6xdfk1B05J4NKHni/iQfuFPxaUng5vfV63c7Oztr9/f1wRryMagpJtvYKHh4eHuIqhtndHmlyOhPfpxwn66R65HNlwGjg0zYF/355eWmnp6ft4uKi3d7ejuaFr2Nqzny7xktlsKkjc3iQ5rvnCMm31CfHURXK02azaV9++WW7vr5u9/f3B+MlqKP98D6qv12Gk0xPFXeoSV59PjxxmfOqrbztdtseHx+HyNtyuRzsc9X/3OKy7eNP9dM10V3NsYP9Xj+kR7ajtcNvziTn7R8M87HxOQeU4l2ypypTALAqRx82rwExFMmkvKok57vZbFprbXTeea/fOaUnZMlJ9NpPRjQVhqyreq50EqBeu5Wz86xfCiOfm1I4huP8eWYwV+Py97PZt2hK0YE5hovy4n978ba4vcP2UqnoSDSyjdPT0/bhw4f27bfftouLiyF/QdEF1VfuCQ/g0l5tte2ihEqnMfFDvylLDnb1d8WD1F4VaWIfve0GyuV+v28XFxdtvV4fyDS3SjyBrJqXqVKBi6qkuU5bd1PtSm+cFgeg+/2+nZ2dtT/96U/t22+/7bbn80o6+O8Y5zqnqG/f2qzAie45L9MCQWN6fn5uNzc33bcfjh1XBQKnfpNW2g/W4zjSlkNV5vTNe+RZVRLI9N++mEhtpEVEa+3gTZsDOnsTc3l5Wd5cr9ettVZ+W72H4nX97OysCzp6qwu2M3UtCTKNVHLQU4hO1xeLxShHgyhVxpV1k2HsIc406RWY0DVHpQnhpmQdN0gcTzJ+U0hbfZEXXMH4QTvVXCfHl4x9MtqVYnt/SX6ct+KfXrHcbDbt/Py83dzctOfn57Zer9t2ux2dBc99agKGig7233OefE4OKzlyFcphertD9ZO8ep2eIXTa9vv96PsAdB6iw3WxN3bS4rrkkbVqftN9H18PNLrNcF644fa+NAdffvllu7+/b/f397EPt1Pa8unRlspc4FM9x344bueB3ppwu6PPXvsrs2rPkx7nlikfUznUnoz59yJ8C4PJ2372QyVjnq9DO5xsuMuQeFT5H+qsP5f8TmpH80U67+/vS2HpblX0kIofNnFs2e/3ow8ZuaM+RoimFMLvM4t8Svn1fNWuxpEMLdtTv1PtsZ6u+XZDBXgkQEzEqfjiDsL3110hHCAkWlyBkmGhs2IYsuJfda5FAlU0VklB3Nmy9OQnAduHh4fR6ZR6U4GHHaV54/9TcpsMXAJZmvsKNFRj5vMpupQAireZ6PTx8YuvcpoVWHYbkPrnPHMMrY3PAHEeJHlweax45LQd44BT2e127aeffiqdGMFgBeJ8nqqSbMUc+ivbrz69LZ+XCtCxXea9HFuqcVcg1Lc90vOVnBxT3GlLxlarVWtt/pHerDMFiL3PVLhYFAhyuz1XNt70We00AC/HKlYlpKvVanSEptruOYGqPRrHqr8pIXHn5M/ydbuKR5434ILgws3r1Qraw2uVAJEmZfg7CCQN/opSUkj/u1I+r0Mj40miDkJaa5G3Tltvb9zHX9VJikm6Zej84zMy8nqrgEZDX+bjyqoHzKdodPkn/0hHa4fvsTufCTR9TgnQKmc+BdoZXUglgQfKSwKtybhqrBX/OB/kFe9XIIi0TY234ttbbGLKGXC6VLfXvtuct9DDfpOj8mRI1hfvE91z7C7bS/bRx8RIgctKOnRMz7OPHiBzfUj0ePv6oJ500yMFnt+UEkud36SbEV3XbQFR0lUtHl3uUjk6x4GlZ6DnPp8MD69rKyQZtN+yJEORypTT5DUme7nCVyjckaoLYqKltfErly4wFFaGzZSclJxQ2rt2Z1ElLs2Zn8S/NM9szxVcqxV/ZbECTpWC817PWPQK+b3ZbNpmsxn6OD09bZeXl+38/PzgOafTAVBlVBM/VHzlnOaOfam/9KolC0GAOw7leOi1Z27RuDw4PU4L6/F/8joBOgc1qdCYO2ioisvWVEl0+xynv+e0meanJ9e6lhzhHIc9ZeOr5yUT+p8lRQUrup2H6djoat7dVvvx6lP09+wt+07tkSbaXV2rZLjXdkV3ojWNjf7ItyVaG+fqTZU3RRxOT08PEtAq5NYrPrF8rkKnVbs9Jqu+nyU+VarVQkLtFAj/nVZcrvipfYIM/aZRSmCqZzgdtT49PQ37z+4IPB9BdFDpq/n3baBktHzudd+TMnthThqlysk4T9Xm2dnZ8CU8fqZ6yvH07mt/V1sW2rt+fn4eog1zMrWdn4l3FahyHlR6keSRdOgar7N9/0ej40AkzU3S+bc4MT7r8uZ/+zOe61E5irn24thn0/ynOg50fDtgCpS4ble22u0OHV+Sr+oNGdEoP8G8AbdhbL9yhqQ1bWs4EJE8poPMSKM/U+lQtS1GueOCjXzxrSaCPm5rsl/OV4qOTOmB84Z9it98I87lcE7pAoeKQGfOlLGd20cFGFR6K9yqOHPmFp/Mqk7PMFX13emmtyRSW702+dsVc67x8v1hdxoptN3a4RHQu91udFTtcrkcGY8EAPf78RZFyitIYMnHXI3Ni14RvLq6Kp+r2qra3e12ozNJVK/KUK4MfgUeqkKjoN+pjWRAXO587A4aq0Tm5+fnIdpAh6BXoJ2HaQxOL+v2jGXVVvXbn3Pj2st16I1jyol7/anV3RSYSDQkmfH8pV7b3hb78y0w8oxtnZ+fjxKBKX9MiO3l5CSnRlpok7gdKPuz339+c6X3dhLb8E+op4+96TkmeeqjhOIzZcejCtQxB260e5VcVHyqdNL9gNo/PT2N+WVOY6+86QCoKoTOwS8WiwFxkgghUU1oQkh6XoiMffPvuWClMiRzHX6vTAGMpOApOcbH0zMMLEmx6MRZkoLoWUfeVYZ6+rKh2jk9PW2Pj48HYTCXAQIMN7RcqUoWuFJI4eW0t8frrhi73a7d39+3u7u7MnQ5Rw6Sg3aj4HNMGnuOgSU5TwcEfLYyfB4J8u0sl0OXx7Qy5L6oQILnAPUAUJrTCixMAfUeQPE8jyQTHEui1fv2seqtB/0+xkaxvx5wSjrpdf2ZXjKqOzICA0+25rg9eZqHQukVZPLA+1HOD52++k9h/KQnLuN8zg+vS/qm+wLFjFDwYK2kzy63Sa9Y2LaSXtPXRdW2Rxo8N4egh885n3WdRTaac5PkoFfedABUQq/JAEux6Kx8LzUR6A6jKm8FEr0ixanQotet2mgtbzEk/lWhwKp+VU/XpoCRj0tFc0Ug0FobQu88tpshSBU/xS4Zvar/9B53AhapUP746l9ydGq3h6iryBbH5KVa1fmzPblP8+bGl+0kulJClbeve3rGw5Z0snQiDi6pK3pWTqPivY/F7/uphC7XUzqXxl09Q4dQ5WN4Hx6Rq4y4g0b/u6fvaRx8PiWxpmf9+Sn7SKdZJTlqnB6VkdzwDBL1qfNN9BaSvl55eno6nOEg+9LTuyQrXscdvf6vxl4tsvyZKQCi/DI/xKo3By4v8nm+Texb7A5+k+xLJ8/Ozkbfz6n0zq/17GNrb4g4JKXh/45y056UX0tK1AMNqZ+K1mMcABUnGWZ34j2DkDKg+TqiGx1Hr06jjDTb74X6/G8KE4uH1+gwCHyWy+Wg7J5kJIOaIlHebwKZTqfzzVeLGr8cXgqh+zyRbyzOazc8fCVuqiQD5e37atyfSc6CK1lfDU4VzkFyHupf+R5yTOmrh2mcrrt+vC3/9rnVvFURhzSWRA9pSvw8pl1vK9WVXKQ2Ep8IlpK+qm5lq1KUrdefX+f9RHPiSwIjpCftnau+2+STk5P2xRdftJubm/b09NQ+fPgw/N5utweR5USH66XLgvsljtGBappv2qlKtlmX8ksH3wMY4o14onvUgWT/Kt9KW83okPdJmhwg6z6vT4GG1iaAg38Uak6DxxSfwCTIlfLSAVXtHFuqvngvGfZqsr2+EHcPfDmSd8fvCurHPieDyhCst83TH7lF4N/HWCwWw0mf9/f3B0DGDaT69rPae/tx/rzzgGNitINhP/KAvPD9/DmlR6/aT4Y8gclksFJ/6RrBTgUA1J+343PAcan+6elp+/rrr9vt7W27u7sb0TtHtxzQ0WZUeqG6U/zpXWM/3H9PbaXfyVBW+u1jSM5rit4kf0nX1R4Taau2q2cTjalU8zQ1HylnSYsNl53n5+d2dXU1gMqbm5t2e3s7RDITCEl0afU8F3hVPKjmj6CesuTAr7Wcz0B6vaQotuqng+v8DA/S5Vtk7gO8Lfcvft19y1Skv7UJ4LBer9vj4+NB+EUDrrKSjwUYU05FbTpz0gArg9FThIredC/9duVPTsr32/g/97+mEKc7ph5t6bnKgFJwhID1b7lcttVq1U5PT9vV1dUoOdKNoNpQVvPcJBzKEumonGE1ZtX1aIzvPZOeak57ssE55Jh8i82jIYvF4Yd8nBdsK81ZNc9ePGmMRsfnQt9L4DN+YFfigTvF9C0Vr6vf2lZSzpPqnJ6ettVq1W5vb+N4EzCUAa1eKUtOOd1Lv3ullzfEou0b1nH9YfIxQQPnTvXURw8k9MBllQuU6rItp1f3ON8EhJJ/flZAQNZX2k6z2yzpw9xoWxpLpSuUCdcNt59y9gl0VnlDPXlrrR3kjPALtglYs66DEvkgbR3xTTXR/vT0FD9jP7d0gcPd3V23sSrkvNlsRqfqTRUNLB30xHZ1bw6CTHT17iWkq/Ctt1EhYtFHgUqT6o7L+yf6nWPEEv0qvmrpFT4r5VYb6/W6rVarA8TvBqVC/vo/bSvoOaJv8UDXe6fLcbWp3+zX//YyF/DOBWxOm+r0AIraT3PlyWiu7N42HYEDM/Xrvz9+/Dh6dmpcLm/7/X74Tofm4/z8fJQAV7Wx2WxGuU/pWG6WnoNkGH2OI+yVar70d2/LLV3vAVHRntqakjsf61Q/qS3273kyrb0Cb+anyfHwYDa17XkLlS5Kb6vPx7uznAIAfI6R1mN4UQFTjaOyzayT/IB/kZj0EviS9opW6bDb1tbG9o/+hEmg3n+a816ZfB2TBtuNFA1fYnKvXRJ4dnY227n1FHOqVKsBHwcFr+onGX3uM/kkOhp0OipkyX4rpJzGl1ByxSN3Lh721UFR/nXDpCRuWP1aRXvirfeTnuF4feXEcTmfHMBVsuF0kT9J9lMOhYNK/6R26ssLkwYrPlf0sk3PXajGlZ6VjFcgVyBb9xmpTHOq/z99+nRgKD1CR/0iuCSodPmZkptKlhK96ZlefpW36cBP85Z4TcBOvU1zVwG9OXKluVO7vSRtB69pjGpTvBOgSECY81PZWfGNuTdM9EtFbXq0bApAeP6Y2mLCN20ix+Fh/mR/SBv54LJMu+DAI42b96kLlCnqh3hZgW/3a1V50wFQU5PAQ4XSM+7YeDpkRfQcBU313wpGiOiS06GSuwOQUVCZm7k7d+xUcn8+jY0f4araFY3uPM7Pz9uXX37ZTk5O2s3NTVzNi56plWU1nkQz6XV+6/+5IUt39Im+ufRSwX0bxusngJrGqOtckfD5qn/ygNdcz6Z0IPFaz9IAuzP3iJCH0FXfjanzqlpd0Rhz68nBGR1rGpvXq0pl15yvqe9e+/Cz0QkAACAASURBVOSZSi+qUzmLpAe0LQQRlfwSlHjb/r87H0WF3J7RuTKp2vumwyWdlYOX46aMuWx7ofyen5/H7yH5mKvfvvhLC5DEM43JgasDX11fLBbDWycenebz4m2KKCTe6Rpf/5wClHP8ZWtHAIcEBDj4OY6ajPVBOpOm+nc6Uv9EdFO0kQ7Wr5Ja2EfVVqK/UlT97YrUc7I0Aj62FMKu6Fwul+3Dhw/t6emp3d3dDW2vVqv2+9//vp2cnLT//d//HaFZORX1xf8rRJtCsZXjZVsElYkvrqDu3BwwVLKcHH0F+MjfZOAZtaEDrcaTio8r3effyeCkcTnfGQFx4EDZd5lKKy7vp9JPBzWJ99LftOfPNhxMpXGSn5UtSfytwGYFQHtg0Z91vk61PwVMkk2u+F9tQSfH1FobRSXSnFVj9+uaR/Xhr2C640v6Ql1KPOIiqLITVVuVvqW5SvJF4OTgjLLsR1ArJ0w21nNOmA+S/GcVsSa4d5tH3fW+pmzT5Ncxe9erSVHnc0N5/nw1eZXjqGis9jrnFmd0ZbwprBR0p5k08R6VWYdmpYRU0sHJnTIy7tDUl+hp7XM+CwVI31e4ublpnz59GrXtQt0DlerfDUIakz+fHGGKbGgcTC5LJbWbjNKUvJCWnhxypc4xppXhfv+6x8lCw8K2ejyjIaKMLBaL0eFrCVB430rq80S41vpHuCcnXoG7qlB/FfZOjsTb9fAvaUo2ZY5M8pqDFx83r6e6U7pCo96L1vTspPN3rg1MNp0614uC8B6T8XpjJT/TVvixRUm9y+VyyNOaAia+1eC0Vc8RIEjupHtffvllu7m5GUU8CLw8eqcPDToAcP318TgQ81L5GtogFcr3VJkVcUgM5OsiCem4wiRBS45Z9xm6SWXK6PHalPJwDD7uqb99TB5q0rVEZzIuTCqloFDIKoPBeykxKCFPFeaynJyctIuLi/bx48eDfepe/wmpzhHEiu9E6O4AUi5B5QDYZo+f6TlvI133M/FdsdMYlTjm96o59TrUlUq3fKzqz1eVVSEw4pwsl8uDb5w4vRWY8HqpTqUjLJUhdUfgz6Qtj57dUnHA1rN3vWtpvMlOcoxpvjROl/vkgJMdmaKzGl96nrLmOuHtC9A6vemkx7nhdZbd7vORykrQb21e9FV0bDab4WwJXddzvuhyMLVcfn77bLvdRr/lYyNvCDzch3hb4ol/C4a8qXRL9VOkgfypIlIqbzoAarFYjLLup+rr/6Rwqc7Z2Vn7wx/+0H766af2008/Te5lTzmn6p4mq1ImGVoaSXecnOjeISY9oEPFY4hb96aMT69N/tb/3gfvt/ZZMLfb7fCWixtcLwyv0dEzqiG5YchtqrgB15hSJCkJfc/pJp6l36l9/U0dqEBq4lcy7AJJzKxWHQc53CutZD+BLV7TQV6V03J+uPzI2NOB+7w6uKmcMq9VBovjTLxVP2kP3vucY7ecB26cfSxOy+np6WAn01gqm+DZ7XIQrb1GJMVrT3RzHqeoloNLnyMHG+RZkgWOyU8odGCcZIynjFa8IB81fs8TIE2Pj4+DblZbL+yHekSnX82T7jHCqd/6mN319fXBGTYqbh8rvZM892xMmhe1qcRX3+oTHxNYZD+9MvvFzR7y0t9zizsPF9jWWru4uGh/+tOf2uXl5Wy6ji1TDJIhVz/+jBs/f81Fk6fJnZNAyDb1MRLR0jPs3pae0W/RlxySPyvFY/uirQJHiUbVd8FOmcdpTCnXw+lWGN3zBypH43xO/JuSCz7fA1TVs1Uf3BIgSOI1vrbme55OH2WPRshlwHlbjUX35LB4Pck1x3pycjIYfS88e6EHDjg2B5DuLJNz033nV6LbZc+fSUCSv/VF1P3+80Lo/Px8RLuPo0r4ZB3x8P379+3du3cHYe2UF5RKAmppDJpXOp6ezPjceWSBgJcfQ+OYK/uawCDnyf2Tfy+jZ791T1/K9fFwfpLt0v9PT0/t4eFhBCTc/jk9ibe+Fexj9vmrAIRHqabAn2zEbrcbXq2uynxv3w6NXQp3sO4c5MKiQby8vLS//e1v7bvvvmt/+MMfDtpxQUiKd0yfFbJkssrcsfi4ZRRJbzUpWslVykyavc+KBv/bjWAygDJ8rONCKkOQDr/Ryqii0YX1mJLkiuPz5C0aPvGWisY9wgROqr85Fq3+qvwDr5+uOS9T3x7C5DXOK42+O0reS3JAIFYZ9QoAV2NPwIFzsN/vR45EOlM5EW+797/oPT8/L4+Jdp6n/d+q3yTLlXPSHLsD8HZ9rpyu9Xo98Mvl2e0h+3UdTLLcKy6DLJIJ3qNTpB6m0rMDCbjxGc8F4fiSvXNQVIEKyaJ+p8PF3Da4XUlAi314hMmvc45TX1NyqghIZSPEvwQgemXRE5YPHz7siRKJ7nQYEL9bUE2w7qVSKd7Z2Vn7p3/6p/b8/Nz+9re/xWeOdTqpuHOsSgUuWFLILb0jnfZWWV8H5/jZ547qeSIYlTIpWJVnUc2Lgx+npbXDyJGekVHzj+WwzSlDUjlYR+bkCZUpKSqNrO+p0oE5vZWBn6I58ZkOOzmPSofodFpro3fkBUTdQPGDZKqbQpQeYnYjNbdw75Xj53jSXr3mrDpBdU7xxFjnLT/YdmzbKnT4PbuRwJg7stSuX/P21Jb4rCObEwD0/vXbdYTjkU7x2Sk+6VltfVX30rxyrny/Po0jAbNkF3syS7vhIDo54wQ+9Df574V65CA92Txf1LhPJS2KRCsHUDRzHAkMuG4nnrG/7XZbTv6sHAd93UxhGDHNUetvARrU5uPjY/vrX//apeutBsD71N9T7VXC6cLu9+dEEVgEyObUFYDoOTl3sv7dei86kIv0J4eQVoYs1dfuRI/a9dA3++CYfIxuBKgc5+fnQ9ueoOhjn9pCmio0CG7EUltuhCon0TPe2htO74QTBNGZttYimNMcah4cKLLtXnFHyetTjkgAaOrE2eRcnJ+8p7/51VTn8ZxxpXntOQf2X61qq3Gle3rWF2q6nvpLfFFSLqMqiS9zARzvrVarbkK7h/ldTnqHEyVamLPTAw8uJw7ilsvPb2BUb+OwHenHarU6sJ+0L7S1pJXgbI7NSTbPFx8q+kQEP/43BwA6WJlTZgEHhWI5sOoELxIqBlVhjynHXRkQDbIK00yhTi90HD0BdHq9Dh2qH1UtfkjxU1sUuLOzs7bbfc4Qfn5+HjlXfipV/etTtfqsrUcCuHVAhMozy+kACUbUpzshBy1UkpQU5sKsMTOBZ6oQ+Kg46tbq3Ono7cNPHR7Uo4d/i0fVYU7pk8WpLfXPBFPXIzp8XyXxf57TkPb4dW21Wg2Gx59zPfDXOv1bIK6jno/BOSOtHGflRESb5+EQKCW9JH/m2ogETvye6E7X/XfVRs9Z6TmvS/65DUnF61d0CVj4NlhqT3NZyTVX0vy0gPddzXPFn0STbIkAlvOit8XW2jh3zyMyDlgrn8b+0qvVbMfz1/SPdJA/XAzwlFb1I9BNO+zj7PnN3smgXiaPnPZJnULnfHZyn2RCWHpt9/Z2xHzfG6r6rZBjqss6Dh4cxXqCFb8Gx/Y57u12256enoY6JycnbbPZDN+t19j/j7U3DbIsu8pDv3PufDOzMrPmrp6q57lbanU3siwBEiAha8C2APuB/QJkGR5jPAIeD4PDOIIwGMnGGNthwE/h0LOZnnh6RlgjAiShAamlHqWeq6q7urqGrMrK+c73nvfj9nfyu1/ufe4th3dERt57zzl7r7322mt9a+2196HR13fcz8/Po9FoYHt7Oz+Nk0VPJeMZDZVKBe12O99DrDQwvMg1VQIHtsc/VQKVSgXNZhPlchntdnvPWRQajiyXy7mg+jrctBICavydPFc+T1tXDXktOq7abswIaT1FxXM/ZnnOAUAI7DgwLDIeRb8pIFD+0ZioIqeHQ5nSXBLSx2eBsQwyzBpSajQu6jHHDDLv1SUnJnVpCDnEhysZr6L7Yl6aKnqd3wqYZmkvZrh4TT/rve6EURdXKpWJJedYQuZwOJxYLmXR+7XfeniRR15oyBl9ZNIi74sdgU7dHVrC8PGjoacc6Hd9xgFlqO+qu2NgDcDES7tcH+kYKK9jRtudqSLbliRJnmhLG1Cr1fLETn1+GjiOAeuZ9NjUO14toXVL9z7Vq3HCQh1wZs1iOGJCpHSwvpiSLApNez3qKekeZKWByoqC68fval/d41PlyOcZVuU1p1mNI+tlCLJareYhXz+jnDT2ej0kSYLl5eV8v7MqiNFolG9LYgZ0vV5HvV7f82pwjYaw3wQlIeCgqHhhYQG1Wi0HVTGQF/MQdTKz/ZCnov91TCjDqiS8Tm1L5VnlR8fUFaE+UzSRQ7JMueDcCCUMan0cX96nR41rDgGXHEulEiqVyh7a9Iha3WFDo886Gelgv32ZQZfoqtVqbowILN3DIx2cT2ma5nKkNIb0hvLQX7YVikC40oxFAZ03XkfMmIfGNRTVDN2rusIjlCHjFGrbvc5Qn0O/q8EjGAyBXZUDX8rUJUp1MlhfpVJBt9vN5Yb1UccpWNDIkkY3fVlQ21JZYn84L6nDfSs1aVP++VJIaOx9DHQclMbY/T7+pFGv+7Me0XQ6ne8h2de2VW8W7ZrTMhU4sBH3yj2JLGT0QxOxSHGGkNuVFJ+MLlhqsP2eIiSqxt3vIyoOta/PcMkhdF+okB/9fh+VSmViYmkIWfvQ6/XQ6/XykCDp0rAj2x8MBuh2u3ndfi6HCh5frV6v19FqtaJCSNTbbDbzg1B8iUsVTLfbzbfbttvtKP8d6IUmnwNW9zi8Tsq0hiTdOIWQfwi06gQNtRMbW5UPpbdIFouKLztVKpU8aU1lmB45x6tSqaBWq03IF/miwGEwGOTg1OcAAYnKQ61WyyNVupwyHA733Mt6NdLFa5pbBSDfIaF9Yh8VELFNPY8kxstpYdqiMVFDHzMKs5YQ6NRzPfwel1tejwGTae0p4EjT3XMjCCLduKrMsM1yuZzfq0aTOozLsHR2aMwZaeU4EmxwrvI5PftB+0mQwecc3FDv6XjpHFbAwX65/nJA6VHlomhBKBISGo/Qe18UADAiDEy+rZRFo22u33hd+xDTX0VlpohD0Qts9DftvKOsIkbNMin1t2mfHYCEDGKIhqKi61CsMwSYXBCpkKrVaj5ZYoVb1jRb1p9h/SqE/G0wGKDT6aDZbOb3qmLWcWOkgAZDS6heApgivhHouCHmNe0DJyVDqKEoEOnN0XCa4K03APcdTvD4SoZPncwwyibv17Fxnun3IrAbApehyeVgJgY09FmVSQ1dusxqnaG2qcxVwVJ22E6/38/Dmv1+f895CQr4+LyuV3uEg9c4ZqyXdTHqwMI2PUmT7Sr/BoPBHkCih2Lp791uF/V6fcKz5VxjvaS7KLKoY6FGx8chBgJC+kX5WqRTQjojdM0Bqv/mvztdKpN6uJg/S7o16ZZ8AZADMOVRuVxGrVbbA1oY1dRxq1aruUwRkADjcW+32znQ0GgZ79GkS0ZCFUxQbwKTr/+mjmO/6/X6BLjUiBeBts7JWq2G7e3tPZFM5b9GW9xeudGeFlV3wKzj6O36LjeXxRCQVACnNPoSpNYTKzPlOOjk1MpZyGwnINb4tLXnaaUIiITujQGcGH1FE5kDqx6KeopaNAxOD8tLKJKjik9DyV48rORrZU63vi2OE0/XG9kHR8YKXmL1O79iE0QBhQIjNeY+CbIsQylN8NHvS/HQsQSNMtDqA189m+HdHx5ilIUnTOx0OX538KDjGAOzqgiKAOi0iedAIvS7/qni0EgJMPnekRBI8miGRpjUoOt1NRpOH4tHqdRzZF3D4RD1eh0Aco/SI2Jet65Vh8LkPo6cj+xHaDdJUdEzJEI5CLFxjSlZvZd1XmlxGVa96rKsZw2wPTXC/nwM6LBongLlQJ0OFgWRPia6+wMYjz09ZS5Z8V5NyB0MBrmDQtoUyHoUgOCUPOG84Po/6SDtjUZjj+EkLfV6PTfIjFgQTPi4uN4IAcaQftDli2l2TK/rmBEwh+af0qVyofzU4ietzmpbp0YcXKkoIlNj4pn5WkLGehaj7wZ5FlASatsHO6RgYyhfS+w3BUIKrigoitpDfdDPmjTo4IFGlhOHHpr2q1qtTrRP+uj5ETywuDIg8tYJRc8itEWU4WhOTm7dDYE0eifqJZMGHwP2nfe+9cYUD1yVYK4y/n2+Cjx0DHjbjQk+cWLvG+4U9Khc0phpeyG5Vm/WjYUa7JjxcGCicqE0hQyVllAUxg0+FSqXJlweNMTM39y7ppenCby8l/zSXItarYZOp5MrZnp1ep8rV41sqLLSvqrHmGXj/KFKpTIhs1mW7YmAKf2hOVYE9DRKQkDj0SPyW8PZs+gjzr8YkPYSA6uux1gcWKizokAzZPDYX/7Oz364lMuJ88T1mM831YVuMBW0+f2MlvmLopzfusVUl8R86Y9OkuaqaZ1chtXjwn0eaz9ZQjYtNN6h8dO6VA+qvIXuDRXXRW4/VRYcVPjnaWVqxEE/syO+FbAIjTvzKJBqmLSE1rO9eHshYfL7VdlPozFWYpGFWJt8xr3HUOFg8n6NaCg61/oUBPFez4JWo6DCQp5R+SvIoFfA0LMfOKK81nVQyka3252IQCkoUkWloejQeOjku+8I0DRpbZSBew+PgQMVkB8ZG1LysxSXfS06trE1zSKvzpW936PKyvkRAp80FtVqNfeaNAqoxmQ0GqHRaOSKlIV5DvT++Eyz2Zzw4qiYCT7odTIUTKOuYEPBK/fLNxoNAOGXuvm8Zta48iIE1LTP+nuRDgmNQWj9PNam1xMyrBoNmVZcp3p7LjveHuc6MLlkE5sDXg/HiuPP33TJyQFhUVG9wqJJtdQfClxovOfm5rB//35cuHABOzs7E8tn2m8HCM5L7R/Bq89p9bz5WQG06sgQyNFlGE/0dpqAvcvBWlz+Wb/LNdubpahcFemmWfXj1Ndqh8CDI7BYg6HfkmS8naTZbGJ9fX3Pfv8Qk2Pfi34PgZhpTJtW+KwnUvmgxFCqC3HIUFBwNZGyyKDwu0YD9KQ2ttXr9fYoBOWPGsFKpYK5uTlsbGzk9XU6naA3x7aVrwoweK+e1aDRAN4bCxGzPH4BaA2Aheru9d4QeGJlfI8fkc2ia5Dsf2zJTSe1fvf+ujw5UNH7dQzdIIQAd6z/2hd9RutkToPWTyBF5UdPncsHKtNcTiPA4L2NRgNJkuRjRRCp9XJMG40GGo3Gnh0/Clx6vR4ajUaewEhgzORI1sUEXt1+xno1ssY2WHQtPza/Y7+HDLeOk3vzPgb+LGVP63bP28eTxkf1DI0s/6s8hTx5bc+jXVpi80HrJD+bzebEtnDlvfYtTdN8q67zW+c+C0Gk9inLxtGmgwcP4tKlS3ndlAXdmq4RZHdoqEfdGdWoA/vPxHKNZPl20NAYa/+KDrHStnU5zoGC1qnffQkuBBpc77BotIxzNiSP/1OAw6yevzcWQsN6jVn6oX2/fK4IdfN/TOF6PV58aSEUro/Vpx7+NCbrJAhFKxTB67pkEQ2sNwQi+F+TK13BhGj2cKMaBj7HRCPyL8RbXdsO0eWfXYmFPAbe/+lTGb52LsODVyVoVoA0AdoD4FMn94JXR+f627TJFpMvlUkPKTq9ztcQcA2BcgefITpDRQFcCBi6NxXijS7TuMH30G6SJGi1WhM0DYfD3FDokkNIDniv7o7gNc25IcjQ5Dc3wi5TMZ0RMqwhvoZA3jQ9E2svVP+0+khnKGrgZ1xo/Q4Q2CaXhhTAOLDw+hQgahSx0Whgbm5uIh9BgQzliudA6PIm+8FnKFsEuzyJUelbX1/H448/PnF2jIJLP2SPhe03m838vAVGxvzV8lm2m8+g0Urno7YRAmi+bBhyKkJLeKHxUPDjchgDqXrN55xej0UoVHdynIpK4bsqms1mftGVnjbmjAgp6BBCc6VKwrW+mBINPav3qfFQpvlg6qlb3ldnvKI2ncAhGtUTUMWsn5UWNy6u6ELghklmnIicUOoNKt2qzDlxQ0qSGdDaR26tVEWvY+aKPBRWC/VX+6dj6NeTJEG5lOJv3VLGd999EH/v2hXUy8AbPjTA4yvY84wWlwNH7AkyvO3GBK89WsJjFzJ88sQQw9HkdkmXGx8TX6tVZemy7kmHs8q3X/fP/O+81z4ofcoLhqI9YdEVHvmmW+e0Xw5cKKcabfIQq/fTn8+yyW2C+j20S4k0h3JyYoo1xNsQ2FcjroY4NkY+t52GGA/0d+W7/hYC3g4ofFeL9j2k45RG/lGOuYPB+0CngnooScb5TJoroZ64L4OoHiZveY9HMzWSREDMujWaoXqM/VUvn0BB5ZH1eI6E6ystvpuCPNDoIMeOdbs+cvlxYKAAIkSL6nmlV+0TeUKQFEqOZluso9PpRBHu1OTIEHJ2dKIEk7hZoxXOMBfmEGoqqjdGO4vmaGg/QmtIoWd14CjEIc9SjWUMcKkSAiZ3L/B3TdTxhB4uPzAsx6REYHctL1QvJ6pu/VR6iNJ9nH0rl9OvCtvfyJZl2cRapio/jW742t8Er5IUnzqV4OXGETRKI3z/dZfw0w+m+Ecfm339mP/z/iDDR7+vhAePJWiWx8shD59N8a7/Z4jBMGyAdUL6d520IfCrgMKNeWgJSeuPFb/uRtnnjIZH1ZjzzIcQ8HdFqMeee1shwMVCGYgBo5ghc31CGkP6IAS0Y/WHDKhfD/0e2iJdVKioYwfshIxIzFhpm7PIBgE/x9cNS1HdLrc02DpfQ5FjByksvE+XYUijy7DW58us7miE5g7zs7Qf6gypXlR6i7Zfav1aCCQVHKh8Od1F9XndDrJCdIXmktsdym0MEIWWQmNlpsyKkJILoR9fa1IlNYuRj03U0H3T6Axdo4C6ovcdIZro4oMV4kMo/DNtMqvB14NU+v1+fpCTHujEnQ58Xg/xocDymGmuA+o1riXzj9ueeC/r5b1sW4+D9vHhGvTOzg7a7Tba7Xa+Js16VZF0u938iGvu/6dXEFOWnoGfZRk2Njbw8cvXYzAC3nNbgqsXwrKhk0C9CAVBb7+5hIeOJVioJiil4/8PHkvx1hv2AloFSh55CSlJ5anW48CC4xCKuoRkmvS7V+f9ZZRJASiVGNsi4CR/dL+95kuE5oQCQZ7wSJnWZFz+xkJ55306xt4X9pMnoiqtSbK79949rCLQEAN1Xryu2P/YXCddDPsyXO56M1Ri9LvssPhygfaNOk5f+DYL2HE+8b8eG667aXgvx4dH1SsPdexUb7psUXb1PAde1xwuLoupvuGzRePCo/2LwJraAwV8CjLId03eVTkMRVq17w6g1S6ExknvcVDtAEPnqS8JKs99fKeBUeAKIw6h30JK0RnyP6NMQ8ZeXIm4QGiEIXRGgbfjURV+Vu84NAhOuxrgEMhxFE76VHC1fX9lLc8u18gKJ7gKMYFEtVqdOHddadOQoU4C0kQlSEOggEa39vEZghDlFbcQsj+urDwKlGXZ+F0cjbvxydM1vPN4Fz9+f4pf+lx8qcN5zH7UajXcfyxDozzpOTfLwL2HgY+/gGBRnihdzr/QRPV+qjJRhUR+a9hT+6ERJo6zJjfq4TxOb6fT2XMYlCYbsj2ubbucci+8zwUaJ50P9Xo9b0d3Dfl6MsExDYGOPWnQ8SNooXFROfHQfMj4aZnFiIbm6pUWN3YxXRnTQ+yL6iJ31vR5rz90b1HhGFPWdDsto50qb5RVPyiO13VZzA2vg4b5+fk8Z4bOk/ZLj7QnjaE+U5aq1epEgrcuUaghV3kJLQWFlsb0epGzwuL6TeeL82Pa+Gid7lyQfr5iwEF5yMkpsqkTbRdeDRDohYx2ROMNuxF3RaCGyRmgf1p03TRUr9LiykPXuamAdelFJ2koV0Hrd1ChtDr9jkSVJv+NbdH46rbHUPKZCq5Oau0zAQPXJbVPuoSg7Su/chpKJVSP34/mg+9B9fj9SMTDdT4pUCO/mOGv3oLyywv7NRwO0Wq1sLGxgT9ZuRYA8MP3JdhXm3wuNlbkMT3Yp9fKGNgcaQ/GuzVi4CMkZ+xTDEySdpUVJgnu7Oxge3t7Qt7cM3XjwqiQhuxVTnXJwZMmPdrAbZKkKUl2z/JwYEr5UWPEOnWuMXqm99br9YktuGyP/9m275Ah7b1eD51OJwdIathcThyIzVr0fn3ejQjb0M+qC3SO+5KK9svbZFvetsuC6lM3MgoWXZeF6CDvnS5gdx7xVNrNzU2sr6/nL7Hj+GvkiNu4Nzc3sbOzk4+ZRwHUkeEBUd1uF71eb+J8GLULdEaYXM/xpx7xyBh5wOP1KYOM1vHeEJBQ+nx5hjKsvArNAZUF5TmjP7osqEsnntvhSykuB643VY8X2V6OQ9H3UJm6HZNEuOLS39kYX17iWwmLiPZ7tF0WZshub2/vOTs8RrciLm9Xv6viDRnyED/UoM9a3AC4wQ8ZTPcK+Z+IXjPQHSD5Mw6IXNF42MpBE38vlUoYjkZovv3nUT5yM5JyDRh0MVh5ATsf+3UkwMTJb1o0ysO+Mzqhbep4aH/422AwwMrKCprHb8DXLr6MBw518d77Svh3Xw8DVm0fQH7eQZqmeOryAKVXbxll2asnUo7wqZNZkPc6lj6GwOT2LQVKfF69Tf1zQ0zeUGmTfpW9UGiX8qGHPnl4mkaYwIDjokadY62ggnQzqsX+ubemfdQtvDywjEpfvSvex615uoee3x3c8DwKABPr9zo2Pj4hHeTlSsBGaC5rHT4H1Ri59xd6nkUNjF8jr3jNl161DgdaoaJtaT9V3+ghdVzfdzDD/tFRSZIkf6md6izWmSS7a/Dnzp3D3NzcHhCjkQfVZ3oInYMfynulUsHCwsLENswk2U385pKhHl+tUVLlhdqX0Jhxvjgv3c44uCSfFWzEbGhIxnmPO27kSWgJRGWFdU4DDzO9qyIkil1lrAAAIABJREFU5M6gcrmMAwcOYGVlJcpoJTTWYe8sry8tLeVr7sr4EG0+adTgK2NUkXq//HcHOEWKyAfOS2hCJ8lueJl9JI2aPEkjyz64N+L844Sm5+mGVPs0zcPKJ9XV96By1W1Iyq+ugVcbKB++GenV9yI9/809vHTl6QBMPRE/fZATVOkeDofY2NjA8ePH8cJCEw9kf4Ife12K330iQycAoHRcqtVqfoZAkiT4Jw91UE7Hx1d/7PkBnrB3YCitejJhbNxVAfo1Fj/MyD+HntPxVKPs4Ib1e8IaZUfHu91u53kDOi46TurZaWSOtKl86QutdLlAAQqVooLS0PtNlL+MjikvKJ+eVMd+TnMwnK/+m68Xez1u+FTxA5PeNOew1qP91WiQt6m/hULnrC9kMLUOX6PX/96uL5kpOOOYc+y4fOFzVCOiuuTqxo3j7zah1+vtyZOhvtPXvpO2EHhR2kkr6+XyrOo+hvT1/RusV8dI6yW9od91qVjvo71UvmjxyHMILMR+02fcLoYiXzr2zo+iMvNrtYsqGg7Hb7s7f/78BPoNTSgtIUPsKIzhydOnT0c7q99V0Ipo1vZ4fwzNeTt63RWuTyCtYxY0p4mFFCwFDlSUSZLkHpwLWigxyBMhQ0lNfD70Jk8Ke6VSQfnozUBpch0TlRrqV92E2s5pzM/Po9/vo9VqTUx4P+Bnbm5uTwKeKsEQH0nv+vo6Hn74Yex/61txeXgA18yv4n+5bw7/9yOtaM5KrVbD/Px8ngNy3/4u3nNzH51Bhh/60wFOrjF6M6mUSK8ebOXjHJrQTkPRpPVx1N/9XqVB315ID0nlkDksfEa3s6l3o6fpOeBgu3ovIxHaZ53L/KOs84hq0kwgy7o1NEzQoUnDRcCKNLItepehc0Vc3xSNXaw973NoG6veG6OZY666yo2A5zaF6vQlRu2rlhBICtUVeg5AHi1gArcaGcqS55tcaVF96mBX+eRRPEa5vG8a/geQnx+iwFL7rIDFX9LmtiFmuKeV4XA4cUia18f55+MaikDwOZdL11E6J6fRGpMzLTMtVYSUqBc1ak7YlTCYwlGv13H06FGcOXNmz+tci2jVupXRjqKVqW7QHciwfzooRV6MDrbW58rYw1jaFrAXMHi7up6nk4pvm1MaNNM9z20olTA8cgfK+44BF09h9MqTQJblB7Lom+U0fFftrqKVDYFExGfQw8JgE9fdfDOuueYanDp1ChsbGxMGRJckSBNppDergEUjEt73fr+Pp556CisrKzj0bUfxj4+u4qcfSPCR5+awtbU94Y1nWZafhjk3NzcOaw96+KX7xydj/tuHM7y4sde7dKOvv/lkn0Up6zUPO09T8iFZAna9uFJpfIwzFR6BotY/HA7zcC2NuNOsSwOsU7fnhowrD9ypVqtot9t7gCwwBsQ7Ozu5jNbr9QmvT0PQbEtlTwGCg3WlnfPLIw6h8Lv2SfvOzyHeFIFapd+XkpwWvT/0P6bgVX/ofQ6u1Niwj0p7DJCp46b1pmk64ek7AHOeuC1QYKl813HU5Q22GdL7qu94b6fTmYi+qfPqRtcj4r6UoGcceJRW9UARyHQHwP/zvRjKT1/GDS0xOh0+Dg4QQn3kd68vRn+ozLxU4Z3Ujul9IQaESmzi6bruhQsX9oQii+oNAR1gN1dA10CdubGB1n7HAIP3PzSY+l3rUm+Fz+rhOsDk+q72ncpQD3OigfCiobbRaIQMQOk7/nckh25EqVRBddDD8MILaH3i/SiVSvmrubnFExgrg1arhd7zX0Hlrndh2NgPZBmyQRfZpZOoXHoOB+66Ew899BAuX748wVOu92nRtcWFhQW02+38REL36EMKuNvt4vz58/i1j63je/9hCTc3t/Hue6/HH3y5NTFRqtUqFhYWsG/fPtRqNXS7Xbzr6g3cd2iEV7Yy/Kuv7D1yNTZxQgDBEXoMfHi9MaWrffRrOv9Y6FWVy2U0Go38nRGM2Pm9PLFRFS/lSM/1oAe5sDDe78pkTg8LU/64BERZ02ReKirWwaRMlVmdo1mW5fNgYWEhl0PflaO88YRL5aOCdlfks5ZYDsWsZRa5KfruxkL75s/E9ICCiRCgUZ2kEZz5+XmMRqM9u2z8ePuQQ8Z2Vf9RRnRXlTtAHtIHJs8PoZ0gHS4TlB931JgrofXwPvZB+asROPIn5Fj4ePm4sWh9zquQTIb4y984d0MlJucanYm1Na1MjTiQSRwwP+bTGcaOhSZJTKBCg6BnEPA3hllj68e+ROLoOWb4iwYvVLcXVUyqoLR/ei+/M5uZBzEBY09MtwyFjJnzVCe9tuF0cYKUy2UMDt+O5NBNu3kKlTpKh29G5brXILnwNEajUR7Sp3dKPqRJguX153Cp8XqULp9C74mPY/TKk9ipVPDss8/iwoULePHFF9HpdHI69TCqkNfR6XTy7VeUOx8f7zvXOzfbJfz+8038xF1b+IHjq/jDv971MAhKDh48mL9zY9Raw/9xfxsA8IufHaHVL56wod8dCDmwDCn20OdY3xw06L06pryPipjGmdvn+NIq1sUws0YWgN3olmZ1c7zYvySZjAzpmPqrtKnQaFh4LojzjHUwqsB7yItOp5PvgMmy3cQ+NUJqABSE63g5D6cpR53HIVAYW+pzg+Ohf9UL6mF7/SEaY0AnBB5cr7pMhXQiwRqNsOq8TqeTv99ElxB8aYJGiXqM0Shg17grYM2yDM1mcyLPQaObDvhCBs/nI8dGkxM9x0ONLQE3l/SUh8ojynRoPKcVB/9ep9+jNsRlJlTnlegv9skBh0fli0ohcKBXUK1Wcc0116Db7eZLBy6QOjmnTUoPzcSMq67H5gS/mj0dKgpidJBnWeaIIcLYQIXqIH1UnrH7FRBoXzhBVZkQVYcG1SciFbqHuHwbZ5ZlSA9eH8hTqKJ08DiSlWdyY0BgQyW/b9++8cQrj5+d2z6DwfmngFfbXl9fx+XLl7GzsxM0fA4qySsNg8aUNQuf0738f3r+CP7xHTt44+Ft3Lq/hOcuj2Vnbm4OBw4cyF/atbKygl963RYONhN88eUMH3kuQZpO0qY5EiF5Vnny6z4fHACE+hOS/xBQCLXBPfWkmctRGinyuQrshpJD4U8aPS1c+mGei/6mYEH5w/a4fKLJcQTNVPIcc02849zTZ5V/TuMEuA3IEXWCR7OKinui/M2dEKdN+R7TlaElixhdKp8xnRsCDwpeOE7KLx9/fcZ50G6399CnESDKDecyZVHl2XkxGAwmDoGjTGudlB/lL6PIvptCwR7lQCNsofA/AbEmQsbGwPnswI/XiyLUIZ3iwM7nkI612o9YnprLodMcArX67DQbXggcGo0G9u3bhwMHDuDw4cN46aWX9nTIGwg1qBMW2Pt2SSXaPUp/3rNh9VntOK+rJ6bX9BktqtwUCfqkdR6ElNmsvOGfHyvNdWoKoSf06Fochb9arU5kwqshpDcwGo1Q3zgHDLpApb7LQ4yRe+/VLHai9nJ5/Jrtq6++Gq9//evR7Xbx9cEiVgD0u50JPtDb5YSmN0B+kaflUoK3XDvE3QdGePxChj9/uYRSeZxb0W6395zEpspV+ch1+HThCL6w1cdbFl/Cj792hJ/5i/Fe7eXlZczPz2NjYwMXLlzAdY0WfuQ1CYYj4Bc+n6JaLU3QBWACfKkM+nKQj7+G2gnSdIeMb5MLLcdo0fo1zKqhXqWddZdKpYlDX1SRauIhi28hJV81audjWKlU8nwGB/OUV9LFE0ZDQMgjgq4b9Jr+V0Oo96uXrAAoNFf5nB8u5GveTosn36phVNmIAV4t6hG7Ifd1eqWb4+ARvFhbHhUIyZr+D4EuvzcEmPm7b2PUpQSfw5QN8qHb7SJN03zJTfUX5V/lWmlROQyBOz94i/fp3E6SvS958mfcDqg8az1Oj9IYAplqe2K6T8FTSC/6HFIg6HYsBqKnAetC4HDjjTei2Wzi9OnTOHHixMTygXbUBTimAFl8sseEOFQcffF/CAzErhfVr4YupBimecTKm9jak9ap93P910GIGmL+pic0qtLSxEbWzQgR7x2NRsjOPonS+ssYHbgRSFJ2BKX73o16qYzk6U8iybIJ47GxsYGzZ8/ijjvuwFLnILADLMw1UFtaws7OTm5wOemVT5qHkSYZ/vBvZ3jwqgy1EtAeJnjycg0/9sVllCrj7ZI8AKbX66HVauVhd57+xsLXPi8tLeET61W8ZfElfP9tGX7jsTo2BuPchjRNX82dyPCBt6Qop0P8l2dqOI9FHD1anVBGylvdBphl4xMraSxVPnzZguOq+TkhZRv7rpNbE2QVRKhSUrr5Xz1lD+G7fDJhlmPHZQg37io/TLZljkqa7ibP6fkjpJf1l0qliXeqEJj2er2JKIjSq6CFSl09JgeS6oFmIsM+T92Q8PeQQfAx1M8EPPxNtyf6+Gp96qWHxl77H4oM+HiGSkjudPzVYw7xiL/HvFNgMnKhusiXFXx5jEWjmg6QuFWXPHCgrEBPjaBHikNRhHq9jlarNZFfo3zxnWXOS2/XDb0+E+Kb6//YOMYAKPuukbBQCS2Jsd7QeBfJE0shcCiVSnj22Wexubm5Z81Ti4d/2LB6uCFE5aE6rUM/+8tZ/D5HaH499L2oeKjOEZtPNqUj1lZR+xoKJc90zZmhNi3sKz18V1yaJ0FBq9VqAF710ut17N98BucO3oTMeXXPO1C/7m7sf/ajKPV3Jjyec+fOYWlpCcOlYwCAI4cOYv999+Hs2bNYW1vLlb+ugWfZOOuZMvSd1w1x/9EuGq9K31w5w4OHOviVNw7x0dWj2MjmsLi4iGq1iu3tbfS6Hbxu3yquwkU8fKaLjz7dxk6rk/dpfn4eS0tLWO/P4Uuri3jDgQ387Lcu4iOXb8O+ffuwvr6O/fv343tuK+FNV7+CzX4Jf3jhJhw8iNxgMWyupV6v51tYma/BUwt9HNQbcFnnOLosTJugDiA5nq6oKJudTif31mig1YAnSZKf0KdtlEqlfO86gFxO1HOkIs2y8a4bKnuN6HU6nVxOCCz4amUubxAUOKjSNWkaEQe+nHvcLcJ6mRvDuur1Otrt9gRvQoCA9fm2Uh+b2GcfSzUoMYPunmDoM+ug3ilS6CEgGLoe01d6jbznfRox1HpioIC6So2wH9ikQJgAU8GTAiWnR3dh6b1sJ03TPPHWwbJGA+v1OjqdDlqt1gTAZB8pq25zphl2r4vPxGxRrF6/7gbex06BXUiGZ7VHs+olYApweOaZZya2jVxJcQMbul40SckACrB6UC7E/F60bqN1e+hP23YAos/4xPSBCYEevXdW8OKTNXSSGBVeyJviPb7myxMTS6USbrn1Vqze83ZkLVM2CVDGEJ3F63H5wR/Bm8oncH1jbGh2dnYwHA4xNzcHpGPRqZZLuPbaa7G0tIRz585NCDI9w+FwfEz05uYmRqMR/sbxi2iUuxPNlhLgnYfO4J2HzuDZ9TK+eKGBL12cwxPnU/zumzdwz/4OqskQ7zlaxv966xx+4BP7MMoS7Nu3D8ePH8exY8ewsLCA050G3tD+EN5z7WWcu/E16I5SnDt3DguNCn72hhMAgN87dwPWeyl6vd2kT91ySvp1vHlK4XA4PnxKeaxKR2Ui5nXG1lBDcuDPKTgMeWgaFVDjqHRQtijrmqTrS3o06JqTwCOBdY1Z26Gx6Pf7E6c7ElA6TVwX12OASQvzX9hHgjzWq7qBPBqNRvkptqpMOT68V7erKr8VlPP3mNfKvrjzVDSmLg/kl89XXZKaRWa87tD3ENDR/3q/5icQGDqA0yRJ1s0xY/6KOi4Ee1k2+Wp0OheUTdarZy4Q+Koc6zzlcxqdVcDO9jQJku0xYVjH2UFpUaFO1iXMWZ6J/RZyTlh8HL29kK0Jyfk0eSkqhcCByTAhQfcdDyHjGSPY69Hwv6Mm1uGT342lXncvqwiYUFh0ndfXl3zgHO3FaJq16ETwcJt7HKqEfX1Y+6rr2rx/fnE/qm98L7ZrB3Gi0cBma2+GcjUFfuC2Cr50LsNz6zV8ZngnvvfqGt55UxVbm5v5WfKPnx57pddefRWuqTUwGo1wxx13TGRCA7uHg7VaLVy6dAnr6+vYSU6hN3oUjdLupO4OgafXyrhlcYDblga4bWkL771tC+0BUC0hPxa6lgxw52IL/+hbb8NX15dx/Phx3HrrrTh69Oh4y9jwbqx//fNYap3CA5Xn8Uj6Gtxyyy147daLODLq4nR3H/5y83rMz+/k4IaKSb0cVeZqOBcXF1Epp3hwcR13HRzisfMJPnliiFEWPzfkSooCRI+AOGjW3ygvjE7p4WE0zOqd8X79z0LDS/miAiVQoPImcGUbjFQo/a1WayLyRFDghe+10H7puwdYCEholHTboB5+xXv1OZ0rClycl6E6XL/5vNei7Xp43WnSnSn8jWDI+ebgwZcvYvkRIbqcJ6pPNDIQ6gdBVafTQbPZzA2myhWNOK8xysRoqAINgk3KEnWxRz/c4aMM6pZOz2FQAKiOpQNcRuoow6wrFhn34vrXAZqDktjz+qyDUZ3/LCE51nuV7pBd1c+x+0KlEDjEBM1/n8VYxu5RxobqdabN6q2xbgcR/MzSbDZRr9exurq6x3OYpvi9TyFhmYVGpVUFjL/p6Yq6h1hzMdTzCgGMUrWKrbf+MpCmABJ0X00TuO1wE6fXOuj0R6iWgFsP1PCe1x3Du3o9/ME3NvHHT23jw8928dzaCD90ew2l0qth3Vf7enD/Eq5Zns9zM5SHVBiNRiPPW1haWsLq1jJeGryM48klVJMhelkJz7X34eefvQVnjr8dr1newbdXnsK3p4/h1vLZPTyroo933DjEdde/G8sHj+SHD9FgvnT192Dp+d/EA/2v4Ox1b8X8aBNv3PwqAOAzle/C4nIJg9Huti1N3FL58gSpWq2GQb+L3//uNu7Zn6BRLqE1AB4+m+Idf9gHZPxDCcDT5o0aLh3rogiZPptl47A+D4JSL0jrp+ImnTFZV0Wlcqk5CvyuRY2MeszqSXoUhHkOBPG+Rs37NcoB7MqYGi3qEtUdHgon/zRSwedDY+X88HEIGXZ9ruh3rVcBtzsteo8uASuvQwZs2viqMXWvmb/RqOuzlDdGbnSZSceZRcfMjbjqTncmFUgwWqF1+vNKL5cvAExEu9RB0zmmSx1MEHebEHJYdZ7pNf3s9kh56U4HsHfHht6v/NMxL7KzXofnSPn/ojLTa7WdAZ5VrI2FUE+IaB0snSCurFhniI5Quz4ZY30CxgOjOxBCaEz/O9KL9V+BUGwwQigRwB4vSyeh8ixNd19ZrIjaX/YDjJVy9U3vwzgJcpKOw/MVvPehI3j63BaunU/w7bcdQpoAvUoZP3R/BbcfqODffmUdj6/08SubCd57Rw3XzaUY8cWqo3HbzWYzVySqbDQqwmWOhYUF/PHGD+JY65s4VrqM09lR/HV2AwZ3HUC7diO+lJTwpeH9+NXhP8D7s9/B95c/N8k7AHd0vo5bX3gKm+uvxfqhB7F56CH0mkdQLpexde1b0D79e9jXXcH1nadw/eZXUc76eGnhAbRq9+NA7wy6nTZuxUncPNfCidYcvrK6D6XK7pHc5TTBUqWHw9UOltMdHCy3cLjWwx2LHdy51EOajClZqAIPHUvx3Tel+NSpSW9UxzgkiyrvMSOn3k5Ilqhka7XaxI4azZvx+eWyTQ/TgR8z3PVefqZi9jdVZlmWe2+M3Oi1JEnyHRms0wE2+6cAh0aDZwl0u918GZVKVPMo2BdVxKyHRaNCygv9roZVx0vpjHluOg90DBwIkAd6zekmWPD3nCiAC+lJ5YfSyDZ1fhLY+ftEyFcFxN532gV970kIAJOe0Wi0ZxnL50Boy7D2mXVTF/KsEI0+KP99HHwMGb3gs6G8JwIjP848NL/9mrftxekiDT5uHLuQXdV6fIx8XsRs0yzR0qnAoVqtThzcMguSjZWY8XS0HkJv/oyjakV+WqYBDH3/QAxN6iTyfoeUR6iEAJX301E9i2YW+9Y57bMqXC1pmqJ06EaEKPyrkxt4+PQWji2Ucf3+Os73N3GkmeBwA7hqLsXrjjXwG2+r4l9/6TKeWe3jNx7L8LarS3j88ri2Dz49xC/fn+Lovr3IudfroT8cYWdUxrntElZ2mtgaVbDRX8TlwVXYTO/B9rCCAVKggvEfgCp6+Ffl38YD6bM4kqwBAEZJBUk2wCitoFfZh6wyh+b2S1i+8CUsX/gSAKA9fx3WDz2I9YMP4vz178YNz30Qf/OV/4gUQAbgyX1vwXxlHgeWl/DD6UdwfWkF1TRDf5RgtVfGE+tzOFLv40ith8P1PsrTA0YAgEYZuPdwgk+ejOfzxDwH8kr5psp4ljlGJVuv1ycSFpnEqOeA+FHU6q17odJVMMiSZVk+d+h1sj4NszN3gs+490fPJ9RH9wq5e6bRaODSpUvo9XoTiZ6ktVqt5uvbnCfuoft8VGXqOknnK6/5HNPiei6my9QRIP0enlZ50LV+giXeE9JvMYOm/Io5WBwTLnNpXkIoUd6Nk9MRAlc8bErp0eVDBSyx6G25XEa9Xsfx48dx6dIlnD9/Pr/mgMlpVRrpcCno9j4WOaJqK1y22JaDI21D29TcD61f63M+h9oL9VnvC4FJYPqbMYEZTo4MVRhDzSFClcCQYXaiWbcjcK0rJIihSRDzCFg8A9dp1TpUAcWKG3Jt0/kU45n2zZOLVNFQoJnp7nRr1KJUKqG08QoGzQN72qykQGcwwsm1Hk6u9fCXJzYnri/WUhxbKOHYQgmlNME3L/bwiTMAIxcZUvzzR4AfvGmA3nCAlZ0BtoZVrPWAy906NvsJMiQA6nvaZkmzIRpJD41kiK2sjG/U3ocyqECBYQb86/KP4PuOnkNr7hpsLt2N+bkmGr1VzF96FM1Lj2Nu7Wk0tk+jsX0aV536fzHCGCzoSLzjlfejD6CMBGl1l/+1UoZjjT6ONdYn6LrcK+NCp4rz7TLOtco436lgqdLHD9ywhnpp9/n2AHhiZXLJKO9bZI1UjUWWZfnpoWrc+IwDRS0KgLnsQtCgRpkeValUmjgBUOtR5cazF7g7wucqlR3rHo1GedSJuQ+MfpAGNeS63MDfdDcF+6QGm4qU69AKPsh3fT7mffv89PHReRgaP/eAXR/5erbqM6UvZJRiBlivKd1F5xKEitbpxo7P+O6FwWCARqORy4XKoOYhKOgiT3RZSH9je64bdemMgMUjH+w7QUav18Ply5extbU10Vc9OEzlleNPkMtTkTXKSwCh0V5fPguNu/fVi8tWkuzmELluV1758zp+zpOQjvB6Y7aY908rU3Mc9CCZEDHeYIxhep2eNcM9XlxB+r5wFbYYbbH2lUbNF/AJpINDAQpt29K6db95iB4fqJBiUnDiQhFSjrHigr7w1J9g/dg9rxrxcUkT4M9+7LVodXt45pXLWBtU8cpmHy+sbOLMeg+vbPax0R1hozvC05fCY0UA8XsngImwwS4lSJMMlWQMUqopUElHSEcDrPZK6KGEEVK0shp6ox7+TeW3UcYIysJSAvz84D8AZwq7PFEcM7O66qs0ecky4LMX5vGn54/gYq+O8+0ShsnesGWv08Zdiy3cvdRBvZShPRi/kvvTp3blJuZh5rQEAGpofTQk2xo2V9mhEnXlrcCBfSCg8NwHn7u+Fq2G3oE2MJnMpV6+HiXOZwlyXOY9NMt2gPF209XVVaytrWFra2vC61cjpO0UgS43CLqu7veFlhxi8zCkv3Ssp42z6pfQSblu/J3O0P36WYEBx4i8ojOl48udNHo2C3Wnb5UngK3VahMJuS4/BMq8V5/3iBWw+2p1PeJa587q6urEOSbeb+pPzYXRl/hxx4fKg4L7EB8daPJ3jkFsvJUm8tij7tqG2o+QgY+BS322CBiE6JwGHgqBAw2mejVFlcaQvhv6LNv7hrJQXY6UFBX6xAlNvCthul7nNVVGsbCXltD12ICF6uWEYR85wf29HbxXFU6IZhXGUb+Dd/f+Es8v/w281Gtipw/sq6X44kvbOLmyiaubI7zppn1oNpbQbs+PlUi/j9OXtnBmo4fzOxkudFJ87NnJiMT0kmCUAd0M6ObzovTqX34LMiToJ3XcUzoV4CEwQoJO2kSlXMYoKQFpCSWMgFEf6bCHdNhFYoAgw2RGR/bq35frb8YD7c+jluwq2PYwxadWDuFL56vIsiGAIZJk8ujc0WgEpCW877MHcHf9HG5b7OHJi8CnTmZIS2VgsKtAdWw0TB5S+MBkcp7fGwK4VIS7PJqs2w2wGhUFH2w7Jrv+R3qAvQpat04q2CA4UEPr9PEZpZPPcqml0+nkXmXIuJN/yk83yiEvS/mg98QUrM81/haKThBwaKTDHQDyx50x76PqLF0yiEUxlG7P02D7XMpiYQRTDT6jR6EDvvSQNNbHHBd+93NpVHdRZnwrtPObcqDnfej4alSLPCFAUQAc46fupArxPmaQtQ6dRzqW/tltQlF0yNtzGWO7Idp4v84n563SMM2+aZnp7ZhMylFBd0NbJOSKnl3hhZ714szxNmKKgc9OuxZiGNG43xcSmFkAxSx91GUHPsM3Drbb7Yl1R62bE4QgjzkRul63traGT3/iE1ha+jLe+33fjy9WX4dHzmzhn33seYyy8ZbH//b0Jn7j3TfmE7OUpji2WMehZglfOtPFx07sxKgHMMLxxhDtIdDLUnSHQH+UYIQEQyQAZhPKx0c34brSxT2/PzK6GacW34Q31l7A4uazmOtc2HNPe+4a7Czfia35G3H9M7+9J+oAAEOk+NTOXdjXfhw31ddRL43QGSZ4aqOBp3pXo1zewM7OzoTC1yStnZ0drK2t4U93+vhIf/f9DXyBFseEY6rf+dl/d8Puz7gXpMpNgb0erqPtqyelCWOsixEBb9+VIIvyhrTTQ3UDpV4t6WJRZvbCAAAgAElEQVQ4mls73dPX7Zask0qdMs3+aSSO7bIPuqw4TX+ErjsIUaOkfIkpfm07ZLiclpBRmea1Uifr0oaClpAhIU36ngnvBz8z2VGBnh/epfKoMsh7OC84nkoLfwvZBe0TvxO8UJ5VNtyg8jnKjC79hpYTY/bADX/oHi2hsQ4BkRiYiNU/i73zonxQB4TPhkD9TDatyKAtLCxkrui8ESdOB8XvieVI6PUQ6i9ibmhSOM2uhLU+9fS8bkfxvn5UBEqmFfWwWFdo/zJfk9ztdicy0dUzUPDAt9J5dIj8rVQquOeee3D/e34C//X5SZpqKfCzf3M/vvWm5Xysnzy7hQ8+so5nV8f1HW0A59vemww/d1sL+0rjkwvn5+fztzDOzc0BANbWN7DVG6GdVbCd1XCiXcOTm3V8a/oE7kpexDez4/jc6D4cKHXwxfKP5jkO4z7s5d8wqWJn/51oHbgbO8t3Ymf5TvTKC8iyDMcf/TUcOvvnefwhwW704TN4EB989hBWzp/DA4truHmhjWfWK/jC+QbmFsav3T5//nweFqVM8ujrra2tiRPnVOGG1r6vVC5iJaaw9CAo/a7nU1C2dL87f+d85n+VQc2TCfWF3iIwaRT0v9JBxU1j5JEYyiiBr5+Iynv0nS5qcPxsADV4ur7tOkXnoBtlPsvrPgZaR2g5Ve9Tx0vrUbq8Pf2NhlTvpfy5/tTnnSc67gp+3MAwsdWXckiDLo2xT36QmvJDDbmOF+/z6IzKL2lVmWQblGsFyMpjyqk6v+6F+zJUSLfr75pwrH++ZBbb8hgrDk4UQMXu0+Ly6HLi9ssBkQG+KLEzRRwcUTJbmxM8NNmKAEmobp0QsS0oOoCxAQgpr1g9oWt+PdZWDDRcCZgIodwkSfLENvJS+UFh0gmgwkLlrEsbqogGgwGef/55rHz+r4GrvgUaCeiOMnzj5TXcuTjE9qiC3//GDj5/eowSFmsJ/u4tVbx2sYMLm3382pNVNe042a3jgX1jRbK4uJjTvbCwgNFonKx3+FV6Wq0W7uht4Z/2/g1uz06igS76KGMrmUOlUkOlHzkk5dX/w6SCl7MjeOSqn8SBg4fGSzr9DMmgg4Nn/wKHzv45BkkVf3b4R/HWC/8eJWQYYbw48p14GJ/Zvgovdpbxxf4CvnBxfhyuHfWxubmZAx2N2nQ6Hezs7OTvzFBF7eMdG/8Q8C0qoftVIaihopLV46a5rZeKgNsZeR/boIfogIJ1crkS2PWkQidMqger3qq+UllPclTP0fUK6WR0xLeYMkmO/GVimRo6TZz0sfKdJKF5Rtp0HoYMemxMY15hCFSoIQw5W6E2nBYfi1Db+pvWqcZNozxs219QpTST55QVjrnqH9ajEQ5GqHTZg2NL2xJa2lEa/H0qwO7ymUc3KDu+nOBnkOi4Fu2G8WfcbunvPqYh4x0ret3lMHSvO7faJy8hQBmiOfhs0Q0LCwuZEp+mKRqNBg4dOoTLly9jc3NzTwPuRRcRrJNIETPbCoXktV6dLLMwKETTNENfBBA8EhHqbwgp8hkvRMTMYHah1lclM7zsWbdc2qAR0WxdTtJyuYz0mvuAN/wwUN49KQ2jIe6uXMC++Xl8dXMBgyxBOQW+89oUb78+xbCzg7Nnz6LZbGJubg5pmuIbayk+dLKOeinDL903wFKjhKWlJWTZeD8/33O/s7OTH/Jz6dIlHF57BN+982FUsfdI10FSwTdGx/GV4a34+uhWLCct/GrlP41zGl4t7WGK/2v9DWhf+21YWFjA/Pw8DpW28R0v/HNURh18+fAP4rHkHhzqnMT3bvwuzg2X8MfPV/BTt19Ed5jgZx69EU9uzGEwGKDVaqHVauW8YsSGCYQaHgfiZ9I7gndAza3NmvA3rRSBEV12oLKtVCr5eyeorNke97orANDt1rqkoNvvNFHNj+ZVvtDYJ8lupKFWq00kQbIPlHXWOxwOJ44w1ntV5jWhjnztdru50qbh4jtIfEcI6/bDjEhHkc6K6bWQslUdFpMTfx6I5yjwvzpYziP/z/FzOaSR8ygH71fnhGPIHT+6NMIdaeQnjw3nkoLyRF+KRtr1YDver4eLsW8aHdGXzhFs8ij90WicB6PyyhyO0JgRFBHIquEkYCZd/I191xwcAHn/Y9EiHUu3VzFAoM6BzkO1Ay5zIdCg8uCOprejdHS73f/xiIMzoNvt5qHc0GD4UoNeKwIUinBDz4R+c0YVeXsxJO71XYlX6EjySu+PGQ9OaqWLe9OJhFWQQyUGWHKP7/SjqNz2ZuDAcaD06gROUnxjcBWwMX72psoG3nXdENcsN7Cz3sP6+jpWVlawvLycj9f15SFubiZ4oVXDR04M8Z5rt9Hr9dBut9Hv9/OIA5V+u93GysoKru48jXKtpwEPZBnwaOk1+Njo23BpYxMvduexU53HT+9/Emk2Oamq6QiDM4/iD75wFouLi7jnztvwC4c/iwo6eKZ0Bz67fg22tl/GhVIF35OWcFVpHV/ufAtuuFDCO4+cx6+/5iX8n8+/Di+3anlOw+rqKlqtVr4mqx6qKvyYFxfjvf8ektkYMOb32DVg0vvjm1STZPf8fZ2TqlT5bogkSfJogPaVdSttDAlrfgKf0wOfmMSmDoEqwVCd3LuvXiOX1wDkbXY6nQmgo4pXnQkCJ19uYUTOcwDUYCpYjI1nLLqq+lLnccjQ+/iFHCbysMgDLpIPNRQqww4eSAN55LRSrshn1UM6XjS67DsTKzXJ2KMsmnCrDhPbJa0EGwT2unyr7bNeBU8qr8ojXdrNHSuR1SI9y3HVHUsh26d9ZdFoH+dgkfOp92lRMBA6NEojpPp7zN6FnFovMx05reEdf8+6lmlJQlpn7Jq36Z0jA0ITweuKeQIhWmbxAH1SUsnwc0yBxCa9Ky0KqSYfZdk4QZL1aPhQQ3/anqJsrYfhRNKd/eVvIb3nnchu/y6gJKKQjbBw8i9Q23kW3zh3DC/Oz6PdHi9Z0JOr1+vIsgytVgv3Di/gJO7Coxt13N3cxLWNsQdPnqyurmJrawuj0QitVgtra2uYK6f49qOlifdVdEYpPvp8F589+3msrq7mh/l8/oYM33lvgmZ5l7/tPvC1M12cPXsWq6ur+NEbz+JqXMDqoIkPPH8Naotn8pMFXzi6jDsal3Dfcge/+ewxLKU7eOOhLfzT44/iZ755N7rlCpaWllAul3H58mWsra3lk9iBJXnpINjlyr3ILMuinkKs6D0eYlXPOQQ6dE085MFpZnporZZ9oBzRADu4Z128RsXL56ngdVkl5hzQGHmEjNfUMFAP+M4OPeBKo23eji9d8HcFTz7mofFR/vr/kEHXfrvRVpCg48LPep+3o9Fal4PYUgj7znFTB4t/jBT4tko/VKzX601sddT2CPg0IqX0qwwByOvSnRiun/UER54WSdmjzKos0OFSkKJywfmk9OtLBD26pmBO6/D+s4TGgGNTrVaxb98+nD9/PhhpI5/57ijW5zkLDpq1LuefO6ZFjmyozJTjEDO2fk0FzyfPLF69/64gwduL1aNM4L18w9o0ZV10PcZU73+ovtDWs1BRpE2B1YnGiaGCr/vhKeiu+BTpT6wtJglGwwGQlvZsW9zY3kH7+efwyiuv5G3zr9/v58sRL774IlZXV3HtkQpemrsdf3KmhrcMnkDjVWDx9NNPY2NjI1ccPBb2pcEAb27Ucee+NuqlEdqDBI9dTPGfv3AGnW5/wvP90DngXYeA1x0Zn9LYHgBfPw98+lSGDEM8dLCFv3ftBkZZgv+48jo88dxLWFrawNLSEpIkwZNb+3BH4xJuKp/Hf2sfwD/5+hH89ut7uGupi1+++Sn82FevQ6s/nqD79u0DAKytreXLCldaYrIZUv4xgxJKqtK5RPng2PI5Lk3oGj/boeLmkoZGC9geFQ6NBqNFjEgwSsF7VJ4I9Nz7oU7IsizPvSBvdV++g10tqpjZlvONfdH9+a7MQ4lmzuNZQJ3SpfVrPbweUtpKs9bDzyHj42B0VmdnmlEgWNN3NHBMFZTQ+Oo1ByakkzRS5vhdASt36/lzbMfHTIGyAlHKL5NpKesED+wP82zIE82bcH4xyhHjV+jcEfX8PXKk/SP9vN5utyfePKq06Gdvi5E61Q0eKYuB2Wn2eJpszbwdE9gbUVCDph2dhdjQdQ8NOuPYVsjLc7pCAzArqgp5DKFCwStKVlF63APRurVf6gFoOGtpaQlpmmJnZyc3xJycbEfX3ojaNZOda885wFh9CemgC1TkZMdBD9nll3Pl7rQeOnQoX088deoUNjY2cHgInD1+DTYrizgxPIZjl1/AE088gUuXLuVrzcqT4XCI73+pgjdfk+CO5QEeOz/Ep06OMBy19vBwMAT+7v8HfNfxFPccyvDkxQR/8XKKDAkONRP8++8YvzviwxdvwsnBYbRap3Dp0iVcf/31OHToEF7oHQJwEnctbGI0WsZ2b4Sf+vIR/JdvO4c7lzr4F689h5//+jHs9Ab5S6IA5JEHlpDX4eMbK7MYoyLAzXa0Phpuykqz2czf9Afsbn/2tXuCP9ap+/BdqelWbIaGCQ7UQOhWYF2n1tAyD5Or1+sT4CYUnidd5XI5b9PnSMgDzLJsIj9FeUhlGws9q5F1oOL88zF1Jyfkyarec8/ScyG0Xa1DadD2i8Lp6kgp7Q4+GEnkfR7tUGMeqp/zgw6QHlWtNPJe35VBg++7LrQdjVrovKNTQrn28LyPlYIe5Ys7ZSHe6hKXRh0UYGlkV3mm92iflQbnLenRMhE5Fp2q/PS+z7K0xu/T9FUhcNAEIjbolSoSchRIIkKgQSdmyGtXZvirZ6ehJGfyrO9UnwVUeJkl0c0R+rS2VPBKpRLm5+eRpmm+FZDXfX+8AiQVWAIHTsqJ8NsrTyJbOYHS4ZuAchUY9DC6eBK9lx5FKd1dm1ZPod/v5wmFlUoFBw8eRDXNcNPmo3jmwJvwzdItePbyCrb7C+iuPY80mVwfBXZl5L8/l+FPswyDQXwfNQ3Ip19M8OkXxzyp1+uo12v4D9++iaNzwNcuVvHB5/fjmuvGob/V1VVsb2/j+uuvx9NbQwxGCW5daKOeDDAslbDWA37m69fiP33LS3jjoS38/D2X8IGnjqLXq+an5DWbzYlI1ayAMjT+Rb/rXLgSb5fgjWPK6IPukCDApIIajUb5m0TZPp/TNXaCUO7GUIPryw4Eq4zsUTY1457zhOCBz9PAE+iyqP4g0OFzmmCnvKOc1mo1tFqt4L519oN0atFxdecjpHPUeIXq8PH0PobqiRl4jncIaHk7Sgfvd+MwC8gAdtf/dSedOwFqFwgiKZdupNWwMiFWl5NCThhlhx62nkipoIbtaWQ0y7Kcdq1bDa5HQXyMlPaQ46D3xYyyy1LoXncs9TkdF+V1LNIVc75j4MTHcpp+KwQOIWZpUWEkM0JMCYENJzxWt/7nBKhWqxOZ1BrSUjQYq3NaKRpQ/e6Kxp/TQSryCJR2Tcbha6hHoxEuXbo0kcCjwEAngKJOPYJVX1RGJM/ow/Djv47a8dehcvg4srUzSM59E6kIp3oIo9EIKysreOGFFzA3N4d6vZ5vVxxuPoZ03wMYVRro3vhtqFz3eqS3v4DWJ94PBI4XpzLQ8GFs3Oj1lstlNBoN3H777XjfvSO8Zf5htEYVfGjrjdi3VMH6+jo2NzfR7/extbWFJEmw3cvw7GYNdy11cOe+bXx5Zbzz5OVWGT//yDX4rQdP429fvYoz2yX80ZmjOWCggtzc3Cw86ZQyF/JK/DeOmUcBQhM9Vtyr9bpUPnXLNPmoHh1lgfUwDFur1fIE15A3pMqe36mcmZTJqIJ7mrpUwnoYGtYtnbrkQGWuxpcAQg1LrVbLd/xsbm7uAfZqTGMR1CJ+63f2iSCMijkmw6oz/L7QczEQE5KRkFOnXjPvKdJtfN6f8WOgqWcIEqgnOPbcrZM7J+IEKc95Tbfssk5edwDlhwjq2HDOMcEySXYPw+O9mkuhxpdHTlNW9QyJEM/5rMp1aPlIHSW9h/eFEip1vrqzxb5S7n1MfU7qb6F7ddx5LWbvtUx9yZUKU0hBeXGl5pNFByKEsLxdnVD8ndvKQgy4khK7v8iDiH2OKfwQoOD9HnrVJDNgN9uchlAFiPzzDGQ1AC6gvMf32ycAhi8/huyVJ8bKt15HgskjxvUFTBcuXMDly5cnkuDSNMXwyJ1AIu/ZqNRROnwzytfeh+yVJydoVI9GJ2CR0gXGSmt5eRkPXFvH35n7KwDAB569Dl8+8TI2Njawvb2dn7J5+fJlnDhxAkeOHMGja03ctdTB6w528flXynnI85FBDf/ssSP4tfvP4ydvW8G5VorPnF/KASp3hWxvb0dfpRuKIvk80ZwCjmGv17tipM9n+T9kcLTOUAichcZZgTf7wuRWpUnHTPmgvwHIgQNlXEEzv+s5DsPh7jHFqj+Uv0pbaF2a/9XQsWhdup1Pn9XPRWOgOk1BoBokFo38OJ1aXAe6ziUPSLcanyJ9rLLhsqBgUNtVg6z904iPRogc7CVJsgdwKhhROgg2aeRdnr0/GlFQfcDvmgNA4E+wQpBc5ASHXrLm46d/5JfOaV9CmjYmobnpY8tnqLt9xwvr8vmqdYXskAMUpWuaHpqa4+CGx0vMsIZAgRszJ9zrBfa+8Ws0GmFra6vwuRhyL+qjAxcqe1c0fn8RMNCBDykL7hNmv/R7mu4e6hNC65zMOvGI9H1bD1G3CqCeOKiCxXVChpt1ix1zHnz7Etuq3ngYlVJ58nDpchXp/uvQf/nxiTHkJFNFFRpT/s779+3bhxuvPYr3Lf81KskI//WpEn7zz07tkc8sG+9iOH36NBYWFvDkYB7AZbz2QBvl8iI6nU6eD/DpQRNHG4fwM3dexC/fdwEbwwYeW59HqVTCgQMH8oTAtbW1aAROaffJzPGm50yFo8bT58W04uDal6ZoPDU5jOOp8qRyEdoBoX/0yrhcpt68GgdVoJQjPdZaDYoaINU1CqRVMesyiMuJGrFut7snEqpGl/XFdjuRxyqnIW8t9Jxfd2AZ0iWkX9sNyXRojsSM4awOi/NHjaKOk9fHsdBrpM35pfpcn2eUQpdStd5QUrvuvGGbvoxGIEE515c1OugPGc2QN8/rCuKUBp1/ykOV89jYextOp+pB/R4qsTp1Pmo7XkLLGV4KgcO0jPKiiVQ0SfweHWwtsQkR8jxiQGLW4uiRB+mkaZob71D/vH2/XjS4mkU+Go3yPclUVjzaWLcaUQDordK7q9fr+R5+nWycjDoh+v0+Go1GflAQr9Pzo7DT0NTrdSwsLExs82TbOmHSSy+iMujtSbQcXHopr5c8LpfLmJ+fz70yrdd5SeNRq9Vw9dVX433Xvogb57t47jLwc58ZoB84aZL1bG1t4ezZs6gcXgZwGncvdVErZeilu1v5Op0OPvTcHK5q9PH3b1jHr973En7ykVtxpjuX853GeGNjYwIY6Hg7EHL6aXz57hG/T0PwIZkK9VHb4H8CFK4F8z6NToWMEJcLKIMaZSTdBCRqCPQkSfZDgQNBuC4p6HXlmeZJ+HHa7B8POOMcUGVKMKjKl+PjZRZd4cA6NCYKLHTZIjZeamzIAx1Dly+9n3LEeTuNdgexGgnSpD7eE6JbAa/f52ckcHz0PgUhbDfLdo/Wpy5Ufqp8aN9V1lxf+GfySWVPlwyUTz4eReDd+eTyoQ5yCBz4uPq485rbt5AD6oBNn/Wtyg4I3EZdif28ogOgfOI4MgohJSVQlVgsqdCVRIgO/S30P5SAFKo/NPjK/AMHDmAwGODcuXMzrfu4wDj9pE0FSelhGIqKdzgcH3c8Pz+/Z2ubrhty4o5Go4lEtiTZXZZgvWy72+2iXq9PJL0pKiXNBAh6XLAWzaAfnXkCw5UTKB++CdmriZaDlRcwePmxCZ7QIDA5it6oTtjQGM7NzeE7r+ngHUfOozsAfui/j7C1+8rNPTJCvly8eBH79+/H8xsV3LLYx13LPTwyrOU8J48+8MQyjtT7ePNVO/iX97yA/+3hm7DWHd9Xr9exvLyMbreLVqu1R374XRWyyqWONz0glwHdEkleaVKtK0ZgN7FRj5JO0xTNZnNifz2VtYbxCTorlQrq9XpeH+ngEds0GsyVYR/pzbFPnU4nlzNGOZrNZm40GEnIsmzikC3KLeujTHgoXPnLxEtPtmQfyF/9I6+Vjxp5YfH6Zn0rMLDX2fFohc4DNTJav463RnzcEHvbIW/ajZI6aR7VUFBCw0P50K2ZurWboJLt8SRHjVxwHH35gv1S3Ubdp/eyr4yW6RIQI3esk4mc7Ks7paH54yBXDT5/0wiEgzGXM408qK52Q67ywBKKpPnyhuth0u86x6NFBLb6nOsc8nQagJia46ANOmqKobIYgtGwkApPrF5HREVFBWzafQ6AtA39fXt7e6b2XdGo4Ol1ot9Zd3kAu2G5kCejiqLf72N9fR3NZnPPewr0fhUOKl/lR0hgdC08ZCx1fbfzyQ9g/pZvQbZ4DJ3zJ9B/6VFkr04+ffkNPSZVXDFUTr7dcfUifvr68Zu5fvmvMjx6bhCk2Sfzzs4OVldX8c2dJdyyeBGvWW7hscuNiUSrwWCAVgf4xa8fwu+8YYB793fx6695ET/65WvRHo77Njc3h/n5+Xw5JwSktH32Q8EC+R4yRiF50WhRKESvY6S0cFupel+sh4qVoICyQiUOTJ7uSMVFUKBgQddbk2Scf6TGXellW57Lw0RnPSiIa9JpmuaH+AwGg/zUyFqtlhstggTOfwUvykcF2qrgY4X9VJ2hv4fG3gFKbE45WAgV11FqzMj/2HJLTLcB8cODXCfrcd0qu6yD25Z5L3UEcxw0CsPlPn7nWAwGg4lIa6lUmtjum6ZpDg4JItUuqDyxft+WqEtAoeKgQOVVEyYVLMWKt6EyExtT/d2BLfvtY8TPoTpZ3Ca6I+ty4W0UlcKZ46hFEWGIECqYmCFVRjmTtAN6f8iYaCcdlTpTvLh37X+ku1Kp4PLly1hdXZ3KxBBdsft40Ae/q4LWDGU95ZFK0/tMxaweGZVJKDFLQ6Ksh4ZTDZT+6f0+uYLKL8swfPlxjJ78OAYvPQqIULOPHn7WiRortWoZv/La81isDvHpUxn+3df27ikP8Z28u3TpEr65OQ8AePd1W3jDwS2k2H0DI2VofaeHn/jCAZzeLuOOxS7+xWtewWjQy9f/m83mBG9dVn3NlHwjWGi32xPRBqXTf3N++AQPeSFU6A7SVMF67ozutdf1Y8qRy4IaXY4psHskfavVyuVJEyVZJ7eDsmjimnprlUoFc3Nz+S4JRkZCYEgNhI6F80z5xd80DK86zkP0IWXtBjr0e+i7etF8ToGP61alg3N2mrOk7Sh9SqcuF8TmubfNdgnifMlDzwXhdcq82wYeR01dpm8BVr1IuhhhCxly1y8qH6SB8q3jyGPMNb+L8qTyUwQaQrKlO9nUtnBe6dizftYVsom8x/MvQiA1ZoMVfMbye6Yt1QBTgIN7hGpkPHTqht6VuHcqZDjUoKnC08/+TN6RNJ0wwkUldg/r1/DXtLpCyjxkFIqKAjE3FmqkyG/ex0nCvxBPgd1xdOTKia0hOipo7gJgu6pIWRThs25fitHiQs8JHBr/nM4kw9tuAP7wHT28ZmkbF3aAH/n43vCa8tnbz7IMrZ1tvO3AGQDA8YUR3v/QRfzOm1ZQSpDnegBjpXd+a4Af+dx+rHVTvOloG7943yqSBHlInR6Rj4tOOgfGIYCqxeeP8keNfgwc6dhRUYbkhqCUwFR3e8TGjGOj9SktpJNK2JWvG3ZGF9zzzbJxjgPBHL1UTWxTwKt1qqHQPA1e0yU18jYELJS/HiL+HykhL9U93KK8CDX8mqjs8z4E4hUYaCGvQsshmoStdHNs9T0OutWXkQAdV6WZfXE50s/8Thnl75RrnilCPaSAlzJPoBPiE/vE5G6NNhK0cG7oPbOMfdCJkr65TWNftO9uP0L8YV9C19z2+j2qm5SuGK1FZaYcB/0fyzbVDpD4UEccVbswebshkBFDYyFDEmLMtOeASSEv2lHiikfXk7UUDYQDJn9GDRA/M3yryxgM4fItg0xI1LfQqRfFUKFODj0y2Pum48d7NQuftHiYmApMQ42c+FwPZbia9SdJgnIpxUf+DvDQVSM0yuPfz21nWG3vXVoKTTbl4VuuHeL2Rf4GzFWAe5a7eOPRNj53rpHTx76c2hzhx/9qP/7zm1fxnuNbONsq44PPLeWhVF1HD42vjl3M89WikQreq/kpXof2l4qZcsfnHGhoaJsGgCF/jTixbio4VcTaPqMXOs4+v5QGlyG2q/k3uiTKvihA0PbVeVEe8prOJ5Xb0LKre2P6TEhnhIoCbZdP5VEoCqAgPhRSTpIkTxxVsMS57GvVISCiYIHFQbvWof0hbdN4r3NYnQneMzG/Jb8gBEYVkDLqoFFTFs5bPsN7fYmCy4M613kf5UyX7EL8ixl1H1+dl34fdUin09mjuzimrM/nZIgO3qP88utu4zQa5Pycpcz8ropYCNaFzSeJ3qsMdOFUoZiGdqZ1sgg1hYCFgxwiXGam66QM9WdamdYf75MiUwA58uUaonr+iqbpQS4tLeVCqWFGYDIM6grZDUbMOLOoR6z9UEXAZzXcqCCp0+lE3yPyXddneOBogqa8XfzmZeCtNyT45Mn42l7ot/uOAI1yBshm0XoJuLG5g78YVic8M/L30UsJfu5Li/itN67jp+5cw2J1iK1+ikfOAn/0yOTLiLSoYi2iyWkOgW1gMmEqFNGhsuSR08wRCIFhNT5Jkky8ZlsNCw/RUaVPryzUF4JI3cUD7J2r3OnBMPdgMJgAtmr8CXyZSKm00NtU8OzgxkPSrjjJZ9VtsYO+XM+FFLe3ob9pZMXBgwIsdwa0Hwow1Mh49CREk9PA+/R+0v+kTgMAACAASURBVOJGSOVD5cKNDuUmTXffYqlgXNv0fns/Q/aCfafTobKiW5ud16zbAWFo3mqEwh0ln4P+ng3tp0dmtR7ddur8c7p0LEMg2Nv1HCj/TKDk9tl5Nk1fzRRxUCaEFFvIqLiAxjwmb8sJ1oSwENoretYLmawAxdGY1t1sNrG5ubnn95ghBWZ/+YzSo99pzPWwEg3xs/AeYFcZA8iTjejJ8TfSxHoYkQiFtBWk0CiFohN8Rj0RDwOSH+55shCYse+Kpu85nKFRBtTYN8rAvYeBT5zYu8PA69by+AWgNQAWdm0U2oMMD788XpNn7gLDlJVKBY1GA59bqeD9j43wC6/dxD+8aRMZgPbNwD+4uYy/9QdDDEdhABmjyX+PAVBX5ED4NErey6U1LmElSTLBWx0PXSfW5QNd/+U41+v1PVt6aaQ9wXN+fn7i7bnqharSGo1G+SFuOh9pDFSB6nHYqmxZN2WcekoBS2hOK71Kj+4a4DPkhesNvU8Nt7fl+orPeXQgpIOUDyonupwQOorf9STncWjucdydp6yDcz7LsomEWndIFBxRt7hxcvDLeVar1faATcql6lIHTVzS4tt6tYTkzu2D6j1GPdlXvqyN9zhfyHvdTq+608Gytx26zw036yvSFz6WIbDoUSYFm3q/AulZytRdFVpioS6dVNoJRYTKPBc4flbUrZNaB8zpchpVgENrwh6+CilvJtJcunQpqKiddn6fBl4cdKkwqmLwNSznLYvepzskNjY20O128zXJarWaG4B2ux2M8mgf+JkKlXzkbpCifnLSuyIoAn6qKBnt6ff7ePxChvYgwfyEsQeeWJnk3SzC/ulTGb52LsODV+2+YfPhcxk+/nwfpfImRqPRxLZX8q5er+N8bw790SYq6RjCzFWAB68C3n5zCR97fm80iiVmuLTfakj8+RCfvK+uvBSoOdikIYnxS5UJMLkN0b1g1uNr7Fpo2BS8pGmay6YCItKnEQ8aCCo7tlmtVvPnSYMqPy+uiJ1eBenOfwVd/M452mw2AWBie67LuM91BfS+/FIEMHm/ggXmGHjCn8+LWBKc/1ejqHqB857LoA58VEcz2sX1ezXguqSq9DYajYkxV/3v+RQqf6RRc0QISJiAq0vrqi9Jx3A4RL1eR6PRmAA3fI73KEiNLUUr4A0Bfx9jHQuPOvgY6vJFbCz9N5V7XwJU3l7pMgUw48mRjqZDAMCVmoZhQhn7+pwCBm1TFaGH4rzDISUdoimE0kKF7cWu67NFbcbaUUHnd04AV4Rpmk4k6rghplAxfEuvn/yr1Wq46aabcPHiRZw7dy6nhydVaj80wVSVLb0CnVxqOFhUiblS0gnOZ9RbUxBaKpXwZy8O8fA54MGrsglj/+lT01G31jUajTBCgnd/eIS33gDcezjBEytjMDHKgGGvh42NDfR6PTSbzfyExE6ng3q9jtuXeijZkI4jHwk+/kL8kCHNkQmBAPY/BF6L+qbPq7L3+cW5px5TEeBjnbokpuFoNRhu2DQBV+e+jrN6N1ReWofPOY4f/4eOutaIgBoxB1Axnqo8quw4LSFAwBc5+VKm6rOQQSA/dEzdYPCzfvdEUBq1UMRA+8f7eU8IlChNGm1kYfRKo8/aN+UPwQMBlhppBV6UARo132XA+kgzz/agx6z8UBDDerXfTqcChO3t7TzvwGVDi0fDvF7Xdz5X3W56PapzfR7HdIwW1yHucKot5/2huotsHkshcNAOxCoLMUOfD90fM/IxQ+yTK2acWRSJhmgN9TFWZwxozAIoZhkIHTwie4IIJuFl2eTx11QWHqJjJjqVLdH35uYmvvGNb+R5D7plSZGoRiRIE18cpKFwTiDfecJ7qUw1d4G/6VY8V9YOHEcZ8D1/PDb29xzChLEPlRhwJZ9H2XiJ4xMn9k7C4XCInZ0ddLvdPGmT4fjHL2Ro35hgrrLb8Djysftd8zmK5osrBac9BjDV4Oh3jiHXfZV/GqZWha1b8DiOBGt+PDU9TG3T81rUMMe2EupOB99FoEtaygPSrfk8CkJpPDyfw9d5vbhhZZseUVUg4PrJnaEQAAwBKP4eMroh+vw3B4EuS24cFVhNS2zXJRu9R418DOCEIs6UCy5BxfqrER3vh4MvTQ5VvnAsVO95fpfS6omb7L/eF1pyKLKDDiAoT24jQ3YsBubInxAg1ATPonF1HoUAjstt0fwBZow4kEglRhVSLCLBoqhTJ5v/5p1XhrMO93idSV5igMCXA0LPKR26U4BCFhrMWYsbmdFo8jRBToBmszkhgGrkPaM9hJqzLMvfXsl7+YbJ0N5wDQkSODDZSZE8gD1HTtNQ1Wq1iZMBsyzLjwHmy4xqtRoajQbq9XoOVgg2JugHjf1sPNWxCBnwIqOufGUSYJqm+PAa8PePZ3jd0d3Ix1fPZvjUyfjSC3k6K10h+vSz5ySwKMijR8axUkMf2vLHz3oQFg0yE+AIXOkZ6to+t0qyrlBEST0/5jR4iFQNc5Ik+RKJLpNp6Jm0cknL18/VCLmRCfVf/7unTSPvkQud/25wtE8h0OB6LuTgqG50mjkuCl5cjzo9WldMT3v7/EydEjL+of7rLhlg9zyD3CEYTa7vk0d6do2DHafLZYaggsC4aI67XdE8F73m/PKiy6sh21UEFJQO/T123UtIr4WWHBwEsC3KD/vt16eVmU+OdOYUKeZQB9kxX4tTYj287XQAk+jd0VOMBqcDCL/ONFYcbSvNs7Tp7fuzKqCq8MgrngAYa4cTl4lC6lmq0VZ6mJik11XJKM29Xi9/V4F6LW7ISqUSut1uvv/evRcNqVLx65kIHH/3XpTHRWPAexSMhXhWNOZucPj9HX8EvO3GBPceTvD4hRE+fQp5YqR6RDHjpP2LtRmSa6VZk874Gyc9x5AJY/puCVUe+k4BFhoiTbIFMHHUOP84tr4tUJex1HAzYqF98nvpOfHUSY4dwYYvP/CsANLKhEzKPPvtvFd5iOmLIqCpc7fIMGmbriM4H3QpRWkI6ZVYWx7JUUOqpSiHJmawtK/+DAGdjgfljKfWetSJdCrNTEokH3Rp0fWRng+h5x+40ScvQkszamcIMLUvvIc88FytkM5mG8ovbTs0LvzukVctoTEPAYnYGPpY+r0A9tCpc2xamQocYmuwCgTUq/CGNSREwn2tzJGjT1a9jx1VpjuK1ckYUwqupN2gh4y7/neloNe8jiLEqTwLeTX+wiMPp2rR0KgKBT1DBU1MLmN2cChcSN56FEInjfaZdQC7BsONhtJKQ+VbykJ8ck8yxnf1XkKyFJuQqsxDRZc5YmA5BoB0LGK083PIqGXZbtLXNKCk2yV54qK+NCrLdreusaRpirm5uYmliiTZ3aqp23+zLMPy8jJ2dnbyV2+zv3xW190ZsdK8CRp61Qc6tgqw9PQ9tj8ajfJkXw3VMqmZbXpU0IGxKnWV5xDwU3Co4xLSGTGgGjLqujzgbbr+URqoQ/1Zb9f7EzI+Xn8I8GtCK8ec7zdRmcmyydNxWQhOgd0IV5btdVrIa9KiS7W6Y4dzXIGERoVdp7FOtkOHJU3TfEu4ygmvheacy4sC6yJZcCMfGmfymzQ7wFS9ouNYBDxjts3ng28cKCpTcxxCxLHs378fSZLg/Pnze55zJvrzZICGYFUJaWJWDFR4nbE1xdC9Slfoeox5PgixZ4rq9qJruGpoKey6Tkn+0JiSj96eel2uYHRisB0mVnq4jnSxjdA6oHtNuuwQQrih4rLGzyHlGbtHjRfp0Wf8XpbQspMWzdUIGSLlh7ZbVIoAjNcdoyvGT+UD/zzzXGlQwOoyoOOeZRk2NzdRq9XQbDbR6XRyr1ETIzXkrJGFUP9V3vUFXKEt4No3HUvdNsh7CIqVTy5j7JeuecfuVV66LOm81fb9M+9V77ZoTriceb1Ztvv+l1CiYAiIxXSnPqtr58DYePPcDd7H9hqNxh5w6flNrEPlinzwiBiwm6ul/eCx0Oqo8rMuaVEf6XIjx1kjnOS71kv6qAsJcELOD9t3HRiTG+d9Ef993qq8hcbPZULlKqb7HFS6Xp+mv2Y6AIrFJ/DW1tYEIUXFEY4SrEaMQutKQO93Rvqk5nMagimiaxqTikqo7yo0oes+0LqsoJOXE4gCrCcC+tIRFT4FvdPp7AEeIeWhdPikVv7peqOCOwUVrGM0Gk2EmAlM3GA56FMF4rR6uFUnrvIhNNahCet9Lrqf9DnPVU59rFXGQzJWBEyVBn1bpd/nyw2xJR5VnEq/Xgspbx17VWTMX1HDrPv8AeT5Oqrk+Tzv4THQNB6etBk7Lpn3qMHWlyw56NJ+q75g9j8NGBPqnEde1ICqV+i6KEZ7KDLrsqP1TAMXofZihivmVaqOcCOin5UvGsqn3vaIqM5fGmef51qnRue8PQV4/K66UmWBO16UVgXFoW3MvO5jEtMReo3PhQ6zcz3j4+6fi3iu50f4cpB/1v+uI0MgtEjOvFwRcHCl5qFK76wbhpCwegmhqxhic3Dhv89SYvdqxMPLlYCNmMCwbQotBZ4AgkpR15NVAfN9Eln2/9N2Jj2SJMmVFvfYl6rO6qlBg2wS4JwGvPHn88BfQRBzmEMPMOwGurqrOiszY1/c55B4Fp89f6JmUcVRIBDmZmqqoqKyPBVdbP5J7aq3OV+e+U9gttm8LXja7+dhcO2ppjPxk+KkMPrg0GazmT7prDlOT/z2BZXNw24uS3xGQ+pgJhnhJJOsvwN2qe4lGU8ymwBjArpp7p1OSeWzHNJFh9wZHznHqsNRiKYQmJfypDz6e339eoIktw8zDE3HrF02bI+ctd7hglhO80hOBYLZH+S5T306X7WAM4WrtSbEp8qq3sAqAY2XT3DNd905joAEZYdywylZT+QRI4/Oo1H9Tof++7ZPTj154kCPbVZ7CEA9cZrSaXCdc/13PnjEgfnSgKSrk9Orzm/nJ/NQ9zjwGvFd5ThQc1nytpLmRBPtfLJ1yTayHAHoUVo1VcHf6gwuGmGYxg06nzMcxPLTaIAGk8KRDKnP/yivC2yHuFLq5uaTYU6OytuTeOuCzfAS+cyV5ETNMphc9cyQItcxsE7VpblI3Vd40HlQ9bbwkgIth6H5S7WDp0dyOoRfbNzv306vpOKkaRc3GqpTK+opR2nEKVpVj8tQp0TsRyYqn+rz0U0qLyF8HwlQjkYRBD2XnAiYqY80mncd09oAOkkZdwLW3W43ffyL/SiZU0Rhv387xU9JgFayoH6TfmpunCNIGSo38mdnZ1O5cvD80JK3T/RxcSRtB50OT9jkZ9IdeHgUNNmvZPBpA7hGhM7e+1P3PUrIfF43I0J0LKn/mSjDpM3bSACXEuvgQlvWyz8m9VUqLwFx2km3rxcXF3V5eVl3d3ezXQPit+u9IlSs131DN8VGHvKavynzaU0f63a+d+DBy1U5XgfPxOh47zSovQ7OUnpXxIHGVwaGRHROMiVXvnSvQ+k0uGkkwoazA5bAgreF73f0eN3+fqKfvOJKeQqu77mmIVP76LBkcOSwlRjy4zUNq0cSOIqXMRAYSGCKTqSqZguepJxqE+nnVj7KVRJ0/Zay8CuMibfsr9SHjvRHfe7ha+enj3aZWC55yjYlXeDvNEpQ33InBOeZZbx9WlDTRl6nnLgbV/+QmfIqH3dXELTxA0Z69vT0NG3J5IeG/Auwyv/6+jod/V01Pw/A+cRBie/1Z18xlK4Fwz5aVBv5rtqiMgSIfEpK/wnKNM3oYIegNgEB9nc3Qnan6Hn4ftV84aPe9/bRjquvz8/PZ/0+sqla95IGebxWNNSnIGjj6XN0nownAgd9fC6BM5al9zjF4jLjdsj1n+12HfNBgudP152dSO8kGg+2sjdyyUS54YCbA4GU3g0cqg5PwksCzhEEldLnrnzuSR2ZwjzsnNR4CkfqbP5f086q+ZRFZ+Q7Z6U0Qq9cxMb6VaYiDirHgRZBEueP2Y7RVxxlcPWuh+RpSL2MJAcprOnG0BVO+Rm10DMqroyRKzhpcsXgMyL17v30Lnd96F4a/aidfi+VuYZu0uh18V0pPPvejYgDwqr5Ub1pusTvdTIvIMcRvPpRBok811ke5CVp1D1fBMkoIiNwooEyRgBKxyi6/F06K7ZdyRc/pr5kn/BZ4h+BK23WSA7cseiac/x6JpCVbEdqJ6MxHqaWIxaAc1q5IFnHPWvK050m++L+/n4GHli/2kXafU0V5eL19bW+fPlST09PkyxqS3KSFfJf68jS1lbvx9TPSklvZD86+96VR31PUy2s00ERF9un9qb3GRFjGV1adY6DEkN+ScCJWOn8icLYQKJCR2mJMUlhOb/pDil1hguDv8f6fSSQAILyMc8SP72tKbzI8L+mH6gobvyr3j4KpDKdHoWzZVg+f/48a1fn2GWwXWm32+2sfuct+ai8PmLpwNBIxlKfqZ4uvE+wQxq9XO8Hb4PrwwjNJ56yTJendJ/laErg7u5u5shGRizJrOuL958MdJcobwQePCNCQMa30abFhyzPwUoHQl1vqmq2wt7BYeKpy5JPTzpQU6IMs38Jgro+IN86sOpTKsmWuTNmO5hIlw+Akt6m93e73QQeZDsEVBygVr2BVq+H9es/7SHlk8BBeQVQ3LmJxru7u0mGNpv5Cbler+srd56RH1qMmOQl2SfaSILjxFe/dqDJMpk6uWIZnj/dU34CDUbjRmn1tyrWGPNEOBup594YAoC0KLFD2h0tI0DQKaHXlRSL+TulT3WznT7yVkjZR2lHR0d1eXk5nRypL15SoaRM3EakhZD39/dTXoaVt9uvK+DlhIjGNRVBMKA+obGWgCkaQmdxdnZWT09PB2c4CNRoHYXqVcRDbWdYvAMyI4DZKZPkN/VJ6qt0z5OPcJU8HOptSfrhq7Ld4atPeCy58ghkkgafY5asaX0I6efHrHiAmI+UyDOOlnluAkO+fk9gk4MIlic6PQrJ9qs9PO2SvOa9EZBk/hGAVH+m+8rvQHMNoGNyx++gOpWrawe0us+zV5jXR6/JgXm7HMRwobbLdOegFI2iYxdNykO7L5vjCxUT6OT7es5oC3mo3+xT6gqBluv2SA6YXLb9mdPNd3zNlv4YEXB/Qp6RT7KtKj9NHbHd/J8AIdOqiEOHjv0epxtcoareRgSO3mgwvNO8PmcGn3nonIzpaE7tocHo+NGBB3dQ6X11ONFw1Tzkx8WFp6enkzOumo+aqYhHR0d1dXV1EO6ls6cy6iRIAgtNa8gZqZ3aLUF6ubZB5V1eXtbp6ekUjlZd+g6GeHB+fl7X19fTjg6fnklGzUdintL0FvsxyUYCGenagYZ+++jRnZDo7mSaefg+yxTo0ty9t9NH9dpxQ0MsIFD1tmhW4FEL1Cj/BAMqV/3/+vo62yZKUMnpBX6uWHmOjo5mx1lXve37V7sEej2SJ+Oq3zyxUHSoPNGZ+th5n/rMHZT3bVcWnanLkjt3BwqjvIkOPaPdc9pdbp2uDmjzGT9YVTX/toRHEeXwHUhrQCAecQ7ddUM2XoMqtzsOZMjDZFc9uX3m7h7pmujhLjRfU5V4xtSByA5YjqKhtCEjoNY990GT2xeXiRHgrloRcVBn+LxSZyipQCm86wS6kK1x/I7akkPplDY9H9XnyUfDqXx3Fl4vkSTPZvB6n5+f6/7+Pq6Q50hd6enpaTot0MGNOzp9CVJlaDWyH09N4yDQ59MNutY20MvLywlUuFOVkXt8fKyrq6tptTanVjoA4PWnfu14TR74c42aOdpPhpvypue+2CwpbNIV/53CzXzORWFuRHXYjdLp6WldXV1NzpOhYO5vf3h4mMAegYB48vj4OFsfc3x8XJeXlwdncuz3X+erJTtK6l/xSUb4+vq6vv/++0lWb29v649//OO0w4YRKIWfBYw3m6/bgH2QIr50UQY6FgchBESeP507kPohAQ3l6Rx1R6e/67Io+fOda3LyBIHivZz3yGaxftpw7oLhIESyL+ApZ59Ak+SUTp1bz9W/kmNt5VUdnIKlPPvURFVNW4DdZ7G/GdXin3bu0OfJXq1J7g95vQRomFxG3I4mwOf36QMIuEkP66MsLaXFiAO/PEfCGPZyVOuN0T0ZjzQ3TEGg40s08T8T58ZUpivdiFbl01+3rY4jm0RbV35He8dD0p5oTSg0hZgIZES3701PzlK/X15eJmMtB5PartElQUaiRWU/Pz9PoMhHJfobhZu7PmR7kuOn0siR/cM//EP98MMP9fHjxwPZSe0kf1JKdI3yd2WM2pjkYr//Oj+pBWoMWXu0T/0lsOcHyzi9ikhp+oxf0vSFa1U1Hf/sYO/09LTOz88nwPLtt9/W8/Nz/elPf5p9OM11WXSpfZp24bTXfr+fpsu8L6QfKkv84w4Pym5aTOrOaKl/XZ8JNJPz9rL126dgWB/LGIWYO1DKegisRKv6XREvtUPbdcUbJX7gTvSqv6jPm83bVlil7fZtRb+ilsqvqKvbYj8o7PX1dRrEcFsi13jJFwn0EIAkXSGPEt8Sj316LQ1cuiTZTwNK8naUHESk92lD3M+P0hBaeMQgNVzMUSg0CbXK4Zw287nx8SkHb5D+0ildVfM94QnBL6G+UR7VOwIN6bfTLzo5j+thNv3344MZGu7o887vAJPy8fwHJkaECPpIIxE96+DaB3+m8kiHG05vY5rT7pI7h05xqqo+fPhQ//Iv/zJtOVNdqj/Jv8sgFdHBmP919I5o9CRdoQ7yPYFDHz1QH/WOn9FBYOFt07SC6hUIkAMmvznPTGehbZkyjCcnJ/Xdd9/NZNv5TDpkH3zXBfuL8ukgknR5SN2d9JIdSn3YyS9p6iKX1G3pm9saAgjSorb7Z8YpwyOdcVuvtry+fj2J9vHxcbJ96kM9Jy+fn58nmdKfgFyathO9dPj6Tf6RH/rjFBfLUz6eYCtQRf/y9PRUDw8PdXd3dzBF1k2JdPdGPmCtfrMs+tYE+pJspvqpA5SdZBvXgIaqBeCgCt1gK8nx0WA4EwkYOuK22219++239eHDh9nzzoGLJtbB8pw53ibO96Y2j0a5qSP5TP+XwImMuwyuvuqnUdRSuCghURos/tY1BYdGVEbYecqoEj8aQxo6fvjIx8+qJ7AgjWx7QvLJqYzSGiX49OlT/eu//mv9+c9/PnAybpQ93Mu0pIAuF0lpPY3k9+rqqq6urur8/Hx2uBb7sIv8qD46KP3JOTDcyxE9F8Q6TYogsU4fEcpI0wnROdJZJtpJM0GqAwsHtM4fvc+DxNS+Uf+kfnaQyfq8boK+ro26nwYAuu/6x2uWv1ZHHPQuTQmSz24vSbcDbPYTp5mPjo6mb18ov3+DJCX2l+TQgSIBM+2a3vf1Y0qU8c6ud3z+JfbJAR9tLvuY/et6mOijP2U5CQitScOpCi1MUeeKERTODx8+1OfPn6eQKPOIGIIKTkWwkQpZfvny5WAk4ajdQQURpxrfOXeNko6Pjyfj5UxW1MPr3O/fVnqPgEV6L+VTGX6wDfmk8xXSR2N4sp/aVjV32jJUPGJa/KFTUF6VSaFiOwQijo+PZx+MkTFX2NePN95s3rZxef+rjYmPDkY75N8BTO+LpPyfP38+qJd1JvlLv1mHt0XldMrpetIlGt2Xl5fpq5aPj4+z0KaDX8kGw+2UTYIF0brZzKfrOKet93a73Wx6gfPDopfOZb//OpXy8ePHuri4qKurqyk0TedNmdGhUVwUnfpByQ2uO2l3KOQ/p0m7fmZ+9nfSfTqqFHVzEOLROdbjdXJahQO0JOPJqXU0u5PxKQbykfrhAwGvh3KlOhg9SPxcWjDvciz5Uv96VIYAgSeeqnyBGbXZgUTSzc7+kKf83ZWT2pXK03PxmiCo6vAQMwKkBIRd59bQNwQOyYGy0ufn5/r06dMshE0BHo2a6bB2u139+OOP9dNPP81ONOzQGIWB5anz/TAL5jk7O6vf//73dXl5Wf/7f//v2f5kJQocy6FidTR4fa6gqU1XV1f18vJSNzc3B3yWE+Z7Pi1EwdBiMuXjOy7ccjbM44ub5Cio4OS38hPNKzzoNPOrcyrDF9R5+xPv3Lg5X9lPClu+J7EsD/Mmh6F33Dm4URultQrLujRSV+RPozXKp7dJ23W5QpzOR8Z1v9/XxcXFBBSdVvbF6+vr7DRKGWDJgxv219fX+vTpU1V9nQ+/urqqjx8/Hkz77Ha7aWdG1dtokIZReRleJs1JF1x2yHvaMPYxjXOyT5QFDi50vzu/wm1EpwvJMSXeitaliCWBnLefv3Xv/Py87u7uZvndpmhBo8Beojnd49oagUSVzzUyiYdqr8tXAlmUFX4UjYs0PbKanCp5nYAXUycjo3t8z4EUecv2sK1unwQYmI9t83Z1NDEtLo70SIM6RgRwtamcjFe+BpF26xVEB/Mm5XJH1aE8RVHYjkRr+pIgy6NgJpq6e3y22XxdHPTzzz/P8nOulTSx/jSiYAi3qg6Mt36zTEehTIwkpK1IychosZN+62NbulablZJTEl85OvERD0fW3ajAFSfxLSUP0bphpTFhtOg9zl9KTCDmfHDjR8NAhyaAxC2OVTUDZT4Nxe1wBPucumK5VW9RCxp3lcupNkay0mBDjvXLly91c3MzyToHHJI5LfJUXTL2Hi1LPJN86F2fnnTD24Wpkx1w3WdkzbeLp3fd4XiZiT7WRT3vZDo5Mm8f7aYihgQU6hP1gXSXZ4fwfYE9b4fzRIBXkVDlc16zfIFeLtJkHxMwsh2uAx4R4y4h1ufA6temriwHY+KP5ERyr10mDohcFkm3A0/Wk8AJ84zSu46c5qr3JJAJNDCxk5OQJBTH5Aac7zHKMHIUT09P9Yc//OFgd0fVfFQi5NnR8F8lTLvd21cLha65YJIgoutcR5pMNGrcEkeHnPrM54m9rzgCcOCV8tLROXhR8pEeDYMbVxqrLjnITWCLyXlKA1JVsxC9kn/EYIdYxQAAIABJREFUycFUqmdNcuCb5I59mEYcDFszROtlCyg4UKUMuGzRCSeHTboIOlUX20hddZ6lkSuNpRwbd3WQTw44mVifwE+SFbdRCVASNLht83rSe84Pz+8DLto7p0d6zmmS1BbRy4+epb7UlnD/eu/5+fnBCYMChjpyumuX+pGRqi6vZEYH15Fm9THf12CFO4VGvuXi4mJawJkis0l/XV5HIC31d6JDkWT/1of6WotUO4efppLYhsRnr2OtX1t1ciQrovPvCHI0lJB3p5j8vaYRTg/fd6Su6/ShFJYl2kcGpOrNkSwZpiU0t9/vD1bAK4RWVTNhYTl0HFJoLTZTfoEQPeeI1MO5oo1bmHgI1P39/axuChtH3qKDNHCRnkAMoxPOswSUZBA7ni4ZeOc58+na62VyxXR6xVOO0GXIWI/ki2kEllUH+1JAQPd8NM33XB8pK6QnOXLyykdBXkfV4fyqEvuOQEcRLV8wKIeX6mBfuQEkbWy7+sG3yOndtLbBZSTR4G3kfQ6SRBtlLNlH3ksOhjrfyTZ3snROz/tM7/BjXCybkUG9J7tE/qU6kw0WnbR5AkiSzd1uN4sciMdqf7cehfaHuka5V+RCZciGShZdBlJa46fYphSB8/7njj3KiNfJ8p2OTm70fgLTPhW3NL276rPaNBZd0nPPk4SboaGu3q4z3CGkfOosR4VL5Xsbl4x5VU1fY+vSWgRHZy+HfXZ2NqFsbVOqelsYpyTlOz8/n04M1POXl5dZeFg0X19fz466VvnaSsXtsULCrqQ8qnizedufT4WlwjBCwdX3cqwUXv5PC7OYRso9yuvvJecpfo+Mod7Vb4+QjOjpkgMNGXc5Jxp31cdtbRqFa71J1Vt4meedqH1MMqKcq3djwrCvywoNv+hR3qqand0h4EAny5GkypXccTrF5/ipvz64YdndQMNtV5rGc0PtDn4EVslfBwgp6ZlHeb1t+nPgIpkgz7x9Ko/y1Dkj0tWBkpSoG6xDzyi/vkCWJ99KrhwUkhfkCfmtBeY890N5dDaJ7KC3OdXjTnrECwJmJu/3NMWQ1qokwEL9eo+/4+A3AZUuDYEDV2l32+S8s9wws0E0xEuIJnUEGbPEUNXFkc5SYse5UUrpPU7A3/MpG81j6Z4cuYy9rrl/meHZx8fH6VsVVECOhGnIdaDTzc3NrA+lOJoH3+/3024I7n7gFIvSy8tLffPNN9OR07wvdC+6np+f6/r6uvb7/eyUya5f+J8C3intksPmCMYdER21jxb5fhqV0Hn5fQcbXUqAhvedDskAT++rqoPR02azmeRK7ZQMiQ9Vb47Nd+con+s6HQ91iODj8fHxYE5cv7kWg0CcDlY2SCcjcm2I8ok+LrZTuepLboHmSNDXOznPk71x4NCBRfJVfPNr0ejTTl4fI0u+cN1BEQFFktdkm9lWlSdbwPb4YVAsj1uDJQ+SRf329TiSQ0UFJKfqF8kRT9GVLfTILz9uRX2mbhKwVH2NnjD6ud1uZwMj8lT/xae0m43vUQYpK53dSrYq2Q7xkbLq8uv0M1+KZiz5PKUhcPA5XUc43vgk6I7EJXRrna4SjQANHREa83Q0KY0cFYUwPVPqVg53+XlvaVRS9QawtFLZpyx8dCXH4SMUghPVeX9/X1dXV1M5AhR6R6ich/1IsT2ypLY8PT3V4+NjnZ+fzxZIkg8aRVTV1C7ufKDCknYvI4WBRzx3/qd7kiO1VSDKRxjedzRITueItmQ8RoBZhjONjOVsNb/MHRail98L0Vbap6en6RwIyZto0IE44rfK1hws+0bOeL/fT1/v5IJN8lJ1fvfdd/Xy8jJth9VCOQGB3W43Rb/Oz8/rm2++melAMnzqOx6aRoNII861RCpPPOyMOtvrgKFLDjoIhqreHA4drdrjdYo+Ti+kkaY7Bx+oOJ/Vf2ybg2i2Rw6chzWprwkICSr4zZKqt/M9RJNk5vz8vB4fH6cjzxU9I3ilsySdVTUtziRoYnsELjkY9sGsBmscoLi8aSrF9cDT2gGD2xj2BftVMtLVTYDpssSyXW5c3kZpCBwcKSfH7M8kAGw0EaII7BB151AdTaewMjtINBFccMSaUsewxMw0qmT+bj6Lid9H4GieCi3hZbjXjYuShN/nq3zlvoTPlZBt9ffdsSZEy7o4vZCcvDtbGQf1G42oK0aao/N+GRnzFHIX//S/m0N24+w8GNXNdlB53anR2bFMOjrqkOsTI1I+eqdecMSmhWQ0lKKZQJqhYg+5V80Xizrw5Pa3zebrdzM+f/48LUrjfDbBkqbWvv/++7q5uakff/zxwBCKRsmRH5/t/eB96wBV7zFEnvrZedX1PQdOtKNOtztVTx6qrzq0jU6DHJycCaOBiigwVK38HIzd3t7O6jw5OZnAJ/tit9tNUUzKBncEEKjphEnRzd8CKAIPLy9v32QRLfwAl3h2eno6O6NHNCtqSsAiGtjnao/qZhm8ph54dDKlbiqh67f0jLaDU2nuowTmVG+yYwnQuN3p0qpdFV4BK5UgaIUtD4OhIyNhLNMbM6qfQsr/XEFMmqoOt3kudW56RiM5olOJxqEDQ6Jb6z24KMkdY0KUbKOQulKamkk8kLHSO2vbKMDjydEx63OZIa+YTyPqbrdEAi4qWyPN5CzYJpdn52vV/DAiB2sOoJdGFAl40nh2dKb7Hj5VuwmqZDQIEOgcOOUlw6m1KR0QVhtojFmWnJ4MO+uW86dNeHl5qY8fP07fNXDHx1Hj+fl5ff/999PH05R85O62gCA6yeVol5jeSVt9E2Dwd7t+7PTDy/RQOtubFne7rXEd0bW+4+H6wykQAiX99ugVQRDX3khGXD+enp7q7OxsBnKUlyF8rq+SLvPbFd5mAn/l0w4JDiIckKl8gWyBJQJFHzwk/1eV7S1p9DTyPaPkYDndX3rfaUgDljVp8RyHDpWzci44ocAmA51GU+k5G0JH5/fccEhpKOxLijzqdArl6AtpDOeRxg4Rij4uQKPyOuInCnfe0qGxbv72MJx4za/OMfxIQ0BF3+3e1jYkJCvlOz09nY0+/UM2SciPjo7qm2++qZubm4MFp2xvAhVU9gTSquYRtOSwKe90POl5Kn/U3ym/l9W948banQwXrvpInY7IHZPLIxdVjiJmek/ragTYGO7lKFD3yXctxGVi2JgRtg8fPtSHDx+m9ieHoLzUoRRlSfYs9bmvC2AfOVjrImsqm87S9TZFREfJ7V6ybdQR7+/b29uDZ0kOnWZ3vtrCKLvHwYvzlfQxQp3aVfVVrgQcNf2qfnW6WA9PjEx6JMDq0y58rrayLwjGnV+jPnMaHNyxDUuJMrXmPbcFXfIB0ZqIbdUK4KDC+duJ99MXRwg+AY/ut993J5nyaVeB05z+0wCMRtAdyvfUjUQ7B6ERmsJnPP5UQupzz1IibsPz70yobK7Ap9CyXC400/ykHL7e0eJIJTnos7OzWV/s9/upDYy6CEg4D3wL4X6/n04iZQifz/nf+alrGbDRoWL7/Xxr6kh21T6PxnRGwIFBml+mcXU9c5o8b9ITbtHkNJT+J8eqxJ0LBCNpGoX0CNBqDQNp9PA5QZ0cjcqkY1C7mf/8/HwCGlrERp5x4MKBg8BLt6aK7UphdPZ7AgyitYtw8R1GEFwXWYbbjwSCVU6yi6mdGk2nKU6vI5XreU5PT+vs7OxgapVt8UFbZ+t5P/E28ZPPuKZFv/XHBeLeJjpWByWdH+r6+T3JwV5aM5aS0+T2NYGxtWWRNt9x1aXF7ZgSBBc0R7JO+NJoq2oeqWB40RvI8r1c5vetNq6sqW3n5+cH2xuX6E5pCXl2RoACX3UY9vI5PUUGyHfuruCCNqU02tntdtOR0x7e95Adt4IyibdUPM0X+pwfD9chLXTuXEvhfNI7biR1j8ZhCcR6X0mBBZq4lZDvq70OIBLNXl8HKn0UzGfOa/9cNJOf1qcoj/pC/NfCxqOjt88Jcyul5OL8/Hy2yFWJAEWjTfGObXGwJJB8dnZW5+fn0yLNtOVR/Sln/uc//7k+f/5c+/3bwks5h+QYVObaaSDlS+H6BFy7wUgqOzl08VqjafLAoxdKnUwkkJpo9jMLJOOKOFbVQXRI9GgRs/i83b4dK+881iBIciodUl/qHoGdR/d80JDAlEdBGY2mLeU7tJec0vJpGdllRoPJY+cv7xMYuu1xOyFeqb5u4ODvuk9esj8p+TTfCLCltCrikK595KRr/WfDiJDVEfxNoVL5FHCVwf8ENWQkRxedQSadS6CBqPuXpqV3KbjdFkDSzqkEdzyuBB7Wo5Mmr7oRAgGKJ+9nOQKe1ub9zr6X86AjTo5ez1JKtDEC1jlr3lO0h899FOUOylPnqPg8lZmMgxs+PXt8fGxlu2p++pumlJw3HN1zSuLh4WGmjwKodGDeh5INndTnpwrudm8LMMU/HZ1LZ5EcBIH/brerL1++TPxwe5H4yHRychJ3yHh/JIBHXvtI31NnJ7x9JycnkyPm7g/V1dXPa3fane50tkS2VXxWXgFK0rzb7aaIofRbaxHcF1TVtBCSR5N3iYDXR/w+kNT0p55pKszlRvrP6VbXXdVzdnZW+/1+kn+2w51rSp2PTHY7yQa3ny4l9U+KoCRfl4BF6i/KlGQjRSZndC8RyoI9OWPJYCrhbvf1rPNvv/22fvzxx+k5y09Gvis/dQZRGwFFop33tDiLbV4DEv5/gQmuOfA6Eriqms8NU5B80ajo9rC0K4ze9f7w/kqjIpXr4ND/lN/nI7t5RtKfrruRltNHI6kRVxr1dKkrd2Sw9TytgUlOzw1okuM00uGRuQz1JyPjTpsAnfvSRXcyxHRWkhf1g74J4984eXx8nPE5AT8CErVf9ynPHQhT+6vmJw2Sl4xE8l0vcymlMlIeXvt6kGTjRmBdfx5RJVB3+jq6KJ/cokjbLZCgL+KKT3TIkqmnp6fZeTKiy22FZOTo6GgCnWmNEvuakS39Fiismp/k69MV5J34/vr6Wo+Pj7XdbieQTBrcNrF/Ei+VP00NexnKow+H6X4nC8kmsi2pv5NcUK4cTLmdGqXFr2N2SIVEd1MULshUeoal3RDREDga8kYmcNMBhiVnP3rWCcDSe2vTZrOZrQ9g+T5ylLKpXl3ra4keopMzkEJx8Zl46PPhql8jB+9XrrNQYgiW7ZAccWW9T1GoXDkoj0KQT6Qj3WdyJWJeyZ2PYtzYuNKl+ehRctkdAR6Xa9Kb9KLqbf0AP8ymtjkAZOSOuucgwvV25BwdeFbNjzNn+ZxOlLGWfDOPh2LJO4KfpIPJ2PuibZe1tQ7W00gGki3kvVH0yR1CCt+n90Y0eMjdUwK2KoOHhvl/OloBI49KsV4CFU7TeFvoYOmU+ZxraxKg4jkOPjBQVE785amqXXJaOxu0pCfej2zTqIyltFYe/b7boV8VceA0gJzTw8PDcLuf8lfVTHh2u1395S9/efeIjqurVb4z3o3pkiKljureXVJM5UkhTiYPu/n7Dw8PU/RDAq+Q5mYz/1CQFjSKrtfX1/rmm2+mrZ1UEB4MtN1u6/r6ujabzbTPWfk8bKq+v7i4qJOTk9m+aNXp0yoXFxfTgknvIzk3JYZqffSZHKfPRYoGHuKiMkbXPmrmtAABjPdP5zho0P095ReNBICdsfQ6mdff02/JCcGAb3MjH2lMldenNshXlSEeMTpDGaXc0IDTIal+jWBFG6dhqt62zWkLH+V6s9lMe/XT9JHaJvmgfHE0zeQRMh/9ug1iXbrXyZ5+p8GR0zD67eA31ak2p2cuc2mNhJfr8pPkUnl9XUu65j0H4+J7VcU2SP64gE+2Us9FE/vT+4l5STt9DWV3pKN+vaTXztNUZurb9A71bVSn+04vw9+VrI7Squ2YFxcX9T//5/+sqqr/+I//qLu7u9ps3lave2U+YpaR6BYtjYScSeX49ILq9DCXp/eg86r3raJdQnpLHeGjPtV9fn4+KRT5qpCvQMXT01N9++230wp35pXwHx0dTQvfpHAMOdJ5Kix4f38/+yJdVU11+rcqjo6+HiTk21YVCSE/zs7OJhDDsmlgl/hHEOD/acTcgTCELwep9RZ6nmQ0jVoYHh31rcpIqTNuul6SQ54DonCyH3KjMrU7QbqgvFqnQHDo30PRiEwhZt2nseY9GmD2Cb+5wn7Y7b7OpfO0SJ2AqZMEJcuaCiHf3SmoPgdK6sdOZ90gO4AQX5MhZz/yvoMXDzmPEh3sCGTyL5XtACA9T06Lu3JEB6dFlVcRRcoGBxiMHnCtDSN9aYpWefwoa6dfNk752Mfsf4JCj4ASWHYDiAQWEwBb8jddHyXQwPqZOhAyArGkzW1l1Tq/t7jGQQX/7ne/m1Y2S/BfX19nx8+yQx3Rypl0jFG5HramwXZn5R1J4OJK0HVOp+wsL3VMQm8dD9meLtH4EgQ9Pz/X2dnZwe4KR+KanxQocGMjhb29va3b29vZLgLSmuiUQsqx0FGSlru7uwPwRnopkFzRn1YUO/+W7jkvKT8+UqQz80VRiW96J9VNXkhOE/8SGKqagxQfbXi4MOkNjfN2u62Hh4c6Pz+v6+vrqZ2cIlK0SvS8vLzU1dXV7PsmAqo8zIkRAPFDferbgTWoOD09nY0QxR/fGaIPutEOHB8f19XV1Wzx3NPT0wRayCsHcqJPIIfOQPzujLP6waMtntSnae5+VK47liQTzKOpxZSHu4AkC13kU33Kbaeuw5x65NSmtrgTAKSPZykyTdpVBn2EeMbjqQk6mVdluy74lDfr9ciHA3FG59xnqV/1vZ00TTcCb16f2/9ka7rEstR3LPPXJraH/TgC1UqrtmPe3NzUv/3bv03GhIzh18uobAz1dA7TldJDeVSuDv2RAa6w2irmdaZ2LvGhe3cpjYCJb8Gko/O2Oa8odBJu5zURftXbnJ7eu7y8nJ22xgObaBClSKIrHcOqduiEuCVeyWlpyiIBh6Rco75a6lvykuHz9A4NWVUdOHddJzSfUpcvAUt3XJ2RYf26lmOWI6BTUd9JzyQzLy8v0wCA89UcsTM8LEdA48s2MOwssOlyTT4QKDH8LKeiiBXbyC11jKjt9/vJ6KcopNOqvqXNUXLw4NENtwvd4MBle43hp+PlOx2QUZ7OWboeELAn/SLNj4+PU5RX5eubEl7+6+tr3d3dzfJut9vZFKbS8/Nz3d/fzyJPcuzuaGVbmCiXXAip7ePOO9kwffdH9pfrHNjnin6tWSw4AhVdYp961HVUlgOUTu4SfW6zuujCUnmLR07TuKhAInYaIXY0t3wRLYlJFDaVRyRLpXYmraHZRxXOiKWpg65cljVirtPboVCtPNbqYB8xEA1z9EEhF0onKpfR8TBhAiedQ1JeLlZbK6S+/kH/vW3kxYiP6Z4bQ9ZHBfEyZHDSmgM6OR/tkT+8Hil6alcCAUsOgQ62aj6f7Gs89MfTTtVeN6ZcN0DZ6AAS97c7yBddlD0BEtFAfiqvvnmg6IXq1PSLple4fdBHsdRn6QbBj8uZ25e1fcF3O/1JYJd0ECi5s+A7PhBwR+HRQm9PiliJJx4pIB/Ztx5R0nvPz8/T1BWnO31wIjo0iPNTaRX9Ul1Vb0fou/w5jyi3Dw8PBxFN55v8kPiquqkDsnW73dddG4o6bLfz0289dZEePve+6kCqyw55o3anvEzU3wTWUx1uT0dp1bcqEnEemnSBpaOhI9e7CU37boB0nRSdDReTyegRg/9/pTUOVnwRr/iVyKr5aFd/HFUxr39R0o01hc8FUXUxAsIogKISfv67t0/AT4h+KS0JtiNr550SDQjLcwDkcqg8NCy6x50rdHYjAJsU0Ol1EJXaJvl1EK5y1FcJIJMO9dvIuKTpOOcjnZSva2KS4ZXTrzo8b0DtU7suLi6mQ9j4RdXX19e6v7+fRnyKiHFxpoAFow56Vw5vCQQw7Xa72eej2T8eyk3ldn0soOV6NRq8uP1z55lAW3KuqV9TtI0gwSMtnczLwXfTeOSLnz3TfcSLMrk0VUwaHFAmv0G5SGCcYE39xKnAlHyQ0qVuAKFnPGeEIM6j+V39zif3zwkUqu5kf/9LgYMLEv87YxUG//jx4wyNURE9/Ms8RLi8V3U4D9bNMzpASaOPEQM9rTVApKNzJGyP5vpcmTh6Sw7bIzcCCeKNjKD+y6jrGUcJGvn5tIkLkZctGtRf3BIoerm4Sk5A89ouG97fydESQNJ5ytkmRWKfJGfL9okmjdZHhpF1JUA7ooOpe99HKtQftVfhV/JL0SsmHjxU9bZKnX+UJZ7+58CExl39we9WkI96rvUJ+i26r66u6tOnTwe80BHTVTV9NZG7c5KTEE102AlIsj1pTjxFKxjhGzlpliM+U7ZTf3byOJrqJW2sPz1jfQkIJNsu+VNkgfKRQDntkh+qR3utP496kucdsKa9dzuje9vtti4vL2cRKgddBC8pSuPvjYCB9x1p9+iA+06/9vJGgMPzu01QYhscLHVytwSEVk1VOJGc76w6PGNcRte3t7ADXJBUdqck7lB+raN3Rr8XFHhZo/qSYPE+eaLyuG5B7aVSKXF+UIY1KZMjTncYXBglnvCeFqaybH1Rke3RqXLeXqFmRaOI5HnSpBtr0UOjSwCk36P+2O/fvqng77IffD3DGplIINrp97JcaV3++dsjJEoEfJvNZvrokO6rD2iATk5O6vr6eipDnykmT7hegHwVb7TugMaKgETTIaSZgHaz2UwnAAoc3NzcTGunKBdyQJIRyrrzggvxfAudG0zqvueTnHQAtHP0BCTJNrkj7eyX9E7tSs6cZfA+f49sWnIa/i7pubq6qpeXl2nn0ciZacqVzirJcGo/dzssJYLXBKhJI6MNblc6B0nbO0qJH4mnS20Zla883l+jchNdnfyk5DbV07s/q00Dq0SkKCenhW/8roIMgne4l6865WD8IzXJEHiiMZEh7NJ7OngtwOiQfSpLPCUo8nDiSBh9JMD7/hEVKZyPghQq8+iMjLf+VLdHhGRsCXTcGIkOXevUNAIbjUpdqd3oJ6XoeOWgi7zo1o24XC0hf0f1/nzpXfGavF+TxA9FrDgi19G7VW8RiOvr63p8fJzmqKVfBG/sU4E2gkp+BE1JvGNfql53hIo07Pdfjwfm9l2Vy8VtBJwqhwZddfo6HiXPS5DkzzntQZvhoJrlsGzl9TyJLqdfbRD/fBU9nSN1KtXZgRKvlylFN3QSpKaTqH+q3wH31dVVVX1dVKnpTeq/ZEXRDK5HEU3usAU4Xf9Tm1RPihTSAWtaRh/sYps2m83s420pjRxv12du99N7DhbdFhL4kj9e14jeFAGiLVwCTEPgQMX1RroyKh8J3m63s/PFfSTA9xPi9emPhJDTCJX5vR4mH3F48k72ju/q8fuOFr18omF3XC6AEiS2nYAjtZGL1XTPIxOqm4tYWV6inQZBjohzzR0/3NB4nmSQ+bv7tkhSLk7n0Kl6P+r50ogqySkVlr89/5LsJNrSCDDpgXjCj6bRCLszrno7hItgj21RNIE0EVi4ofW+532eFNqBK+9nDxXzfV93QsOc7Ik/9+R9SAcl0KI8PLws9SOT6+/I2RC4sv9cz3mUc1duis64HUpA26OPijRst9spwkjHRJslAKpdVX7+C8GBeKu1WuS7t407rxi9dtDEPLRFtGv0ZfqvI69VHqcxmDrb8J7UgUc+V5LsOUDkc7/ndHYAkvLl+TsdYVr1rQoXFBqIZBDVyJubm2mEojltLlhKiNAJT3M1uk+aEqNY10hp2Jn+nILq5S+lJXTpebS6XELLqQQphM5p4Hazqpp4K+egPvLz5+k4iLLVVhkl5y0/yyvB4+hIPOQX9uS4fX84+eELYt34d87Ww7iJp8kw8j06TM8nflBuWK5+c0TO9QOsrwNgTmMKTXd5dY8jYOoVnavuvb6+1u3t7czQk16W4+V6fzgfOe/v8sMBg3hGOj05OCKNlHme6cIIY+J/aiPv+z06Jm8fF2yOpjrf42RYTgd+XBdczsWfZLdVTqKx44WSf6zKt/iyjzlC73jPMsgn2gAHMKpPfPGoi+771K7q9AXGos/lheCtG4yxPUtggn3EP8+Tkmyn1hu53ku/l6YVSG/XH37vVwGHFDJlwxXe7gjkqEBK5tuomJYIJrpNzo31d8nRm7fRFS05qER7ojUpfqpnv99P84dyQCcnJ3VxcVFVVff39/X4+FgvLy9TeN+Vd7fbTac2chTp2zEFPhT2404ChbAFFPjVSEUUeAAUpztOTk5mi9HY9wl0cdTkc4md4/R+cudEAOROjE6+62uPhDioYjtomHiiXaLTy0rPPFpHHvi7NEC+HoXrAmRcdrvddEIkjbHzgCBTIWTPo/K4W0d9yZ0eDv5UpuTEt+T5kdJsn6Ie3JLZ2Z10zx1yp7sdqOvkie+lkWySHbdv7PvOsShfkoEuksJnSoxUdrbW13ewLvZZAlhuSztb7vwZ2VLJB22LL/x1wOgA0O+nPmC7fJH5mjZ46nS9K6d7pt1GqQy3Z2vqGwFc91mjtHjkNBXFjbUMBe+7MeQhGr5KnWFxnwNKCpQWvaTkBmJksFVu137lozAuMVV5OmOR8jFMzmOBz8/PZ2CJq98ZRdDBS4rwKL8cPVcQ6zRKRhGUX0Iqg6B5cU51VNXBQUI6yvq7776bytFzgiK18ezsrM7Pz2dTHAlQ6pprNTxSRUDJ9wRgUnSKxppzmlVv8/I+4qAjTfLp84MJMLJNlHW+o8N1+E0Sl1m2Ybvd1uPj43TPv/THL1VqMaR06eLiYrZn3rdRqnyuMdAgQLzR7guCN+6HpwM9Ovp6uqk+uy3bsNnMzyXgLhHRwiOvVQd1XXUy0pLslxvKDuDTMLOvXR46J8z3HADyN+1ol5J9VZ0EW8kp+jO2qcuv69PT00meeA6DwB75weii8lfNv2ujvJI5DVBkM/jcZUf6nOhLVSfKAAAgAElEQVT2Rb3O56qado0xUqQ+drDLMp0vXT8kHrpuk18uE14G7VoCW5yycZuUeNQlyoUPYLq0uMbBR1pKYrqjcOalwWGn0ADrHoUsNbhTDDZc14mJ/nxJUVNK5aTknfmecvW+ojk6cc2f0zHS6CtCQKPthk6CzCNr9dxDd9oS545fz3mtqSF+9EjtI98FXs7Pz+v4+Hi2iI/JHT5Bg4cynfcdb9kON0py2J8/f57uC6y5jLEfxFOVySkOf+40ydhx18Hr6+vkWH2dDxPnfDmtpW88EPxtNm+nRupPU1vffPPNRJfAqBy6PpFMGsV/XWurJA3k6elpXV5ezmTu9PS0Tk9P6+rqqr777rt6fn6u29vb+vTp02zOVTZit9tNkTaBBUVOBD41/07bkqZAU3LAIFp9/USnw6MBB+tm2V63R3WSc0lt8fKTvWGZpMnz6FmKSNCG68hvOXu3BfovGSYIkB6Rdz5lpXsO/PwcDLZD7RbQ57Z2DkRUv/RBsp38BHf0/FenNX6H7SNQ8vc6+WM9a8GD6lvrE1dPVThKYmV0RBIYNVhzM3R0+t3Nk6Y6+VvXySkQyPiz9N8ZmxQ3OafRu3yP33cYJX4EzPNyri4hTCkdAZiDMylVmrd3IMC+kYOR8mulsfOi6quifvnyZVLMDmGzLoa3yTcHAORrQv9si4NX0uGGmnn1fQWCLoIwr4u/XXZlzNiH3ciEB9iIj3/7299mdJI3lImqtyiBRulPT0/TccB0oqqD0036iBn7TH8MDyuqQcNLp+LvqB6NVjVF9t/+23+rb7/9dqpLYELg0Z2swIOS79LwnSiSKd+JlQB0kjPKVmdH1J6RY0l2UmXyP+0R9a+zXyO6Un3d72S7XLaVT0dIczfO6enpBCir3tabCFywHZp6dV1PW7z5tVVGA6q+fguHkQGdPSM5IEDQgIjggSeUqkwBUwIU9nHaaTJKaktaX5L82VK/+DSXy4HLayrf5WIkl9LvpbR6O2aqnIaYnUNh4HGldIBsPEPuqe40EmBj+btDZ7xHZnXK+h5hGeVXWGxpFOQOIY003ch0zzunq/KpZAQbnKbwcumokhI4fR2No+RhOV17vynvklKwDKcx0X90dFS3t7cH8sOP/Hh5pMWfjSIfqk/5VKcMRTeCTOXQaTN8T6MjGWR4WfU8Pz9PEQqVJ6O53++niIKO3z07OzsYlVfVDLRqROr0CkjIRmh9jM5xIMAlnzgNRHDg89vkh69VGTlTAibyR9fK4451lFJZHCH7lmuVr35cGnCwnZQd3qt6i+L61Io7GIEhl39+K6TqDaheXl7W2dlZ3dzcRL6rbH3t1IGh+j9NLXGqQrLIvAIIkjXWKXlVebrWVFfVfPu4LzLUfZa7xh90YJC2fen95Lv0bAQa1vqrDlxuNpuDqadRWlzj0BXkQicmczRK1O8jPZYrxNg5WB+9ptGbl8lrvZ9Wn6YO6TqBBojGoEOQNM40TN55rlAUOIIAB1FUeD33bW9SLDoOhuyq5n3TRX045905Lyqm8000p8QRQzKWznfy3GkQ/Twi2flBwKj2bzabaeGpJxpT/k98Eh0uH8kJORByBzOa+6bMbDab2cJBje45BZT0yoGm6KSRpqHe7/fTolofOEjO5PR0IBX58/LyUjc3N9MWbdWjqQhOu/Cz4F3f07ZInn0AkoCt84AOw3ncjRy9bSObwT51utkWRpw64M9ynVaVWVUHzlTluq3x+0nOExh4eXmp29vb2RoVgjjvK8mznD15yTb4egO9m8A6I196n/2jPCqDZ5VU1cFWY0awRDcB3tqU5GgECkQDbX1a8LlUT1eu85nPVA7rWpK9qpXbMUlocpZVdTCSWUJDbnTTx3PIRKFANcxBhjvvjlGOAum4l3gwQmJrRyGuKAq1ccGOz9NJoLXu4ejoaDpAh0rDNQs0pFwwpJFeCoH5aYE+EqFjktIRwLAP2E4eAsa2kx+cDnFeJaPGctwp00DrmvOpnjgtM+oz72MHUi5THbpnuS5/7ItEJw0hgYUMjcpiuFgGySMSqpPz1ey7pP8+AKDhrvqqq999912dn5/XTz/9NMmLVod//vx52uu/338djWo6k9EwrsVgmyW3Pg9PvruD7gz5qG/oOFxP3N7wmfMtgQ4m9Y1PCy85BbfFXj+BoNOiqI7y0sGm5FFkp93p6oC15FTrC5YccmfHO5ut6BUBsOwi6fS2Ukckg1X9eruur0lH8jPM3/Xv0roFlp383sjOdD6K/bhG9qpWTlVUHS6sS3Plek6mpXUSvq1Hfx5ZYGO7UbXusXxekwkSDC835R0xeakTPHUG5eTkpC4vL+vh4WF2VC8VarRY1A3k3d3d7HRH/XHtBOf29Hu/309RiRSCVuiPqJhnQ5A+lUueckW+0na7PfhoVjJCzvNkjPza2+/InQro/eJ95Hl8O2Byruna77lhp4GR8UpTIw6gVI6ApEbrJycn0/579bGMqspkKJj8oAHmok06adLFXTGvr1/Piri/v5+tR5AD1kmRMuj7/X5afEv9lHNTdILzzW57vL9djn9pSvLVgarufSXS5qkDOHyeZMCjIV4nnYlHN0Z2Vvc4rUKeUq8Y4ePAxsum7nJbsKJanK7z5FutO/olfwQo3l8JCCqlSId/9KsDEonn/s6Sz0gAl/Zx5G/XTIMocTfdEjDq0mrg4AUSJfvWtYSyR3NF7rAdqYk52sb1008/zcr2cjqHQqfH950mLsrpEFyqf22S0az6ekgW59iSk1trpFz5OJfIVfAuyFJ8jTw9n397gk40hbgYXegOJ+EWLdHajfhdFrzdvCYPEx/Se6LHR14ODlwmui/8Jbq9zjQ64L3UTi9P+dmPAoD8hLaSjzQJBHyhn6YZHSBKVjjfzAjYZrOZ7XSgI6EDUP+zLVrUpvb4UcdcvEleejsTcOjs0iitcegq2+9LH+mwO+OepnFHyXXL5Yq2mfwW7xR5YuSWIIEATTKjM2IIJGmbq97k6+zsbLZd23kpGeX3TVRumlKTzVZEVc/TNJLa5FNd3j96xm3eCRgnAMD3U9+nKTOWMaLHQRzL4nMHZGuc/VJi/y+lVVMVSYEoLI6AO9Sl+2mePoEHvvv6+jpbAetlOz0dYzrBYAfQ6HXGgfe6TiMtScCZRwbaEbFHAOjcuGda+RNAU7lcf+JKrbYzOqD6U9sdCXf8ET/lGJznpNX7skPiXR1V+ZPBLIvXLD8BhvQ++yflSTqiax9BLLWLZcrgsn2MCrDvNS1Ax+BTXypjv3/b+qvnrJOOOgE3jxK68fMwvBLlj4vf2H7utHIHpTyaRhNt3jbviwTAlqY23FB736Wy1a5U5mgQlZJHx5zHXk46qIkjdem5QCDBhfJxelKLYrW+hWW7zaHjdl4ILGy327q6upoiYmltlDvD/X4/OxqaU2SkW/qherw8yrFk8OzsbDYtRnvS9a1SJyui0wF5Aqy8532rc1akz5yKFl+TPI3oTqBa7V4bqXtXxIEVSTAUdlQjKKxUfhLffSnO0ZQzlCOSZHjJgMQwpyO1q2oOaEZOomr93BWf+zt0rlyPsN/PPwK02Wzq8vJyigBoe5Hadnx8PNuypP3IqlPrEjhNwPb54SlC+jzrgXUlgeSpbmqX6uVcI3ebdKNrByWd83cH4f3voDQlOknvr+4dvsu8HSjo7idZ6t6ncaNuSXY4YvdRj/KNwuW69nUDVYcRF26F9HIJZujY1wKmzWYzCxOnfOIFI4hyHmtHe6J/lFyOkq4nGfX39bwDNWvSSH6YJ4EL0s+zWcQrrpPhf3conW4QSHSAUU5VB5wlIO3gyEErgWTqU4KZqjfg5QulCbTZ/iQ/axPt8enpad3c3By0y9uQ+EQe//a3v63r6+v6y1/+Ul++fJkdcUDfMQK1SzRz/Zrb1JRWAYc0kuIxsLrXKY/e18giGXoaHw/L6FooOe3TdkeShKoTMhpdz9e9k5THHYjP/ye+6vnDw8OkbFr7wBMASdvz8/M0p6i9zHpHi82q3k6JVNJq9/Pz8zo7O6svX77MnMH9/f2UV/PkOo1Sq6dFw8PDw2wPv+ioqgNw52tSTk5OZguuOkPcgTHdJ+pWkgwlwEFwQGfj6170TgKeTp8rfXKMdLwpjRwJn3HLop5pmiAZVuVRaJifFWfEi3Qxb9V8y6hkTvklI1rMq9NAHx8f6+eff56dQileqfzT09Mpr6Y+CJAZpiU/OG3hI8S0FZX2ZJSWAGInoyPDnIBGZ+CXBh6eJ4Fovs//BADJMSRHQ/A5qsPvi99JL6repj1/+umnmV04OjqaDruTHSI4dLvOtnn9qS81CKJNcFuRIjt6dwlcssz9/utJug8PDxH0uH+hHaPP2++/nqHxww8/1G63qw8fPtR3331Xf/nLX+rTp08HoEv0p7ODkk9zn+lljdIicEjCIcY4MZ3i+SglLeDj6JaN8P2/+/3XY5g5snY6uxFCapto0nfkk+F3A9SVxw5J+8s9L/80qt9sNpNxvr6+nr4wp3nA29vbWWhZeeU86JDFVzl8HeCjkwUfHh6mcKFoEG2kRyvgXZm0LkLgRoCEqJ3ghTRfXFzU6enpRNOof/jbR9BL77GvumkcymHq23R/Td6Ojo7mznnQ2SQwLAMlOVZbtXpd5XJ7pqIVOonR6eRct8CHrzbfbDZ1cXFR19fXdX19XRcXF/X4+FiPj4+zb5GIHh0axLoEIkWbZIVfRJQdUF8JMPtUpzuRzeYtdO38HTnbNQBi6d573l+Tt7uu6j8ESJ4kh5tkyX9TNpw/kiFGLBgBUuKUUxcx3u/nx91XvQ1AOGBkX6sNAp5pXY34Qyfp9KquxHv3ceTDKPl6HJbTvc+oDnXty5cv9fj4WFdXV/WP//iP9bvf/a4eHh4mvfcBFO0/2zCSIb6/po2LaxxYqaO/VIkzSUnAgI30fK7kHtpUGRKM9xxYQTqcNh5py/a6wDlydIMuQ6dFXRzBsxy2n8/Z0c/PzzOnTvrFI97TdwhUNulUktG9ubmpb7/9djru2RPBnE7/81EbjYfa//z8XNfX11NEhOFuyowWxp2fn8+2eTKvJ39OuXA5JX8Sek7gsONB6me9242qEvDkdaq7azNHSalcjdQVgdNRzwKQ7DdOT3GO+PLysqpqimxJLiTHOhr8y5cvM0N1cXFRv/3tb+uf/umf6je/+c1Ux+XlZf3nf/7ntM+fa3IEhp+enurh4aHu7+8nXbu6upr66/j4uB4eHqbIhXRetGgazh0CF/51fZ/47KDD+2QEFLv+43tL9SZ5HqXkzFI9BG5+33VYtsadrss7BxFcvCfeS5/13PVCO3/IUwEA0apyOY3Aukkvd/UQYCYfxTL5SW8Hos7bpcR2uL6PQEjqa0bmBcReXl7q6empfvzxx+mbG2ka0m3VWvo5gFqTVn3kSn905N5wdWRVDsmSIDrD1MF0rhQ8zo8zBD+i21GXX/MdKoaDBxncBDyYpAC3t7ezslm3b2vydqsejqyqaho98vPZRJnX19dRAFJ/+YFbpJ/5qcSkwT9pPOp70qHE0Cn7NxniJcc7UvSEtnm/G325sfN+8j5NbVybOsfCMhM4ot6J74pMKUokp6v3ON30+vpaT09PdXV1NZPt7XY7RaWurq7q6uqqzs/P6/r6uj5+/Dj7+ub9/X29vr7WN998M0UVvv/++/r48eMMOEveFKEi6Hp6eqrj4+O6ubmZnSXiH1KrquljauQ1ZdUP8Em2gPe9nOR43ebx2ZKTZ1+xLt4bvTtqhw8QEmiuOlyz1QFc54PA3Ovra93c3MwGGdoqK93n4IEnN2o3hNO833+NWvOocX5h10EzP/y33+9nXw8WDfrPxcFqB+VK5cuO8qNpHtn6pWsdvB87u+W2zQcj7m/u7u7q8+fP0xqVBBw7WzIa0HSy0KV3TVWIqS58MkbffffdFFpxB6nf7px98WSKMqjzVY6mKZwJI+PuzGLeTjgcNFUdhr2SQaAypQ5wxCyDqtAc+dEBLIKZqre99ESrmntOW+2437kzfrpPdMswH6ecOFeuckm/80TKzHuUERpKb7PPuyYee2SIdRCYMs/atAQcl0DA6F3mS7LJNuuPIVf1gy9mYwSC4CHN/5+enk7RhOvr6wk4XF1dVVXV3/72t/r8+XM9Pz/X5eXlpO/ir9Y+qB/5LQ1FovjBLb0r0ONz2vzzRbmuJ2kRX/eb9ymTVTWT7dQ3+u/3uzrSs1E7HCB2bXBnT/nm+pRuvZXy8znt9NPTU93f38/WHUhueFiX+odnMrAPuZCWtiHZXto/AgmX67Ozs9kz1smBJe2s6FFZvkBTB1NJfp0+1zPvR+8X6lcCbSny3Dl0TQPyPnWjq6NL9JOkURG/UVq9q4KCUZU/gHV7exsr9JHkkkNVfaxbHZUMnecdGYjkLEZoK3UqFcbvpXfSffGFB+RUzefGGAbkfR2Kkxyr18MFi8yXPtBDMMByyHMqEhXVF7GNDCUNHPeF+wlvKbrj86c0XCMgkejStFK31mIkI2scxnsBib/XvZ/kVTLoxpi0aVtXcqgafZ2entZvfvObGbDVlMNf//rX+uGHH6adPprK+vHHH+vz5891eXl5ALa9P29ubqbPtHP/Pp0Wjb94wEhFBxSpg2x/sj8uK26Aqw53iQmUL4EJPaO9Sf3mfZDKJKjp7BrzOk+SjUj2jY6OIN7PcKGjloPxwR9tl8pU//BMCI2aSa9Pm3Q6sNvtpgXaBCcEqszb8UvtJFDfbt++2ZFS6nf3a6Tdo9ZuB91x0+4nIOntSNe/NKmOUUS/auVUhVLa48kGK/Skd1nOqHwXbs+j8tWxrHtk0PmbipHmpr0DvW4CjiSIfP+9I1kqmha36b4UV39adKZ3VA8XUOqeRne+AE6KQfAhxdMiOCm7jyJIm9Y+0OhypK9nCmkqEc3r7+TkpD58+FA//fTTDMl3gIDPEmpP+bxfnU5/vmSol+6tVeQ1ADa9w+kjLUpNwFzG1Ked9Jvzu5pH3e129cc//rF+85vf1OXlZZ2fn9ePP/44W5MiGfvrX/9a//7v/16///3v6+Liou7u7uqnn36aFlCLht1uV7e3t/X4+DjJq+hiEmiQ3FFe0tHkfM9D9x2wdpmgHnAajeefUNaSXC31XWcP3Emkchh5TSnZ0DQididFx8a1IcynSJE+Y+5gMIEwRjtIn6Y9VK/eYX46WZWnqCzBkNbhiCda95JoIn8IBMk/B7DkF32V8qf1Zx5pTnaF0V7S5mV1Nq1La/3NmjKW6lt9AFSHfNxI6T0f9VTNFUSdtoSkWabec4Wgwi8xrnMKaYTnRo8K5caDhiYh5QRodI/RBib9ZqSFi3vIh9fX17q7uzsI1ZJuTjfIALAM0sxrHzmSZzzR7fX1dVrsxvZRScizu7u7aVT5+vpaP//8c3R+nSC7HHK05IrbAczdbv7ZZj77tUqYRh9dGzqAxLKSfIt3OtNDvCaYo3wSRGotBOuUbAgU/u1vf6uff/55Vh5pEjj905/+VH/605/q/Py89vv9tF6B7dfIlKvBUxhd9/XZZhrpDrgnhyp++SJK519yCnp/KY0GLmsHDR1o6PKnNrwnUT998W3qY+6Wuru7mwFPOXUONEQj+1dJC6O1W2wExOjgacsSOGbfEQgv8a+LYKVy3XekvnZe+j2+u1b3E/3Jv7ynnFH5a9K7pioYJia68pAeU3LQvJ8E2N9fg7xGhplz5t55oomGbQQenIbkJIlaacQT7VS+5BwoJKSRdXRps9nMVhy74aUyMtTL0anOZ+Dn0Z3PGpFxOyvzuAH2byjs9/Ptn0npPKU+lIwSWMloOc10lHx/DWp/r6F2MNYZfpehjmYlRmy4AGy/3892WrgjUD9rvYDAHuv2rclJv5lXfPeIFxNXvovvsik6OEyy6CvfZSPY7mSkBaI9Mpn0auladXnq5MMNemf7yDt/f1RHmnNPNJAWlpX+u9Omk5dj//DhQ11dXdX/+T//J9pp6psiljw0ztck6R2d3SA58bVdkint7OJ5JaJbETS2m2cM+YCCvBGAkaw62O5426VukMK1PqTdB3lJbjog4DbFQcMaO5batda2vevkyLQ1xp3pCPG8B1Uxf3q+toEULApYMiLpU7SuZJ0hcaOQhKJrF8NifM66udKXC4w6BKpyZKiJwAkWnA/uzNVeBw4OItnOVF6iqxtBJwPrit8ZVvZzUuQ1spWu9Y63iX2zlDq5TTSNykt8ED+11Y35uqgS80im2P/vSXynOw9F+WhAqRsE7nzutoXRSr5DoJ6c9lJE0vnzHh7QNrgMeblLYKxLvjvC62eZI9lnW51+5tlut9OW6f/8z/+s3W43bQVUGbSHvM/DxiiHHlHkwl5upfVdW9p5k6aMBVjIHy7OJV986kTgRTojB0+Q5gB1JBeJr7TR5HECviOHz8E6877HHzK5flWtA6dVK6YqkrA5M2iwVfnZ2Vnd3d1FBOyO0eea3IAuGeUldOVI2juA97skZah6Gzl1QCT99nve0UudxYVv3J7pe4898XPdShIORmJIg6NiTWswsiSlS+3oABDzehiTho7K0Dkxlp3mZVkWf/O6M7CeOIfq9a9dzzICDUuAemQU0pRgByAFcrx+tePo6Gja7dDNpadEo+0RMDeibGuyBxwdjpyj/jsg4LkiI7C5BD5/SXJZ7uhNC//4v+OT88GvSQNtXrItdKKqx2VRiyNvb29niwUdILG9fEb74rLhUQPl0/orlSNw6PbC7RHBvNdDUMr2CsRSDhglSbrlvs95Rpl0/6hrto18H0WPve9og1lesiWiSWuDuqkx2ssln/su4JAqcSey2XydE/vtb39bLy8v0/yxr/h2A9/Vof8diqvqld2Nemc8U7v5Xx2seWR+Ztrp1zWFnOUpPJyOBO3o4CpbKZLX3/WVLyQjSu2Ak4f2El0OBDnKd0dLZWS5mgYhGKKCkaeJJspH5+yWFKBrX9d+3lsjRy4badSr+3onvbd2VEE9VBkc+XHVuk95uTNJbRY9bB+3tMkouRFj/bzPZz59Qflyo+q7mLwda/iVZGktaFiTL8meR6u6cigrXSTD9bCql8kExHQ/0am8GjT4wIN52LbN5vCz2nLcbi8JRBTt1YJad9DKT/6lwU+yqT6YSYMUX6DqayT4XrL7iX8jJ60k3ox8oMup608X8fWkk1tvbm5muyZotxWhXkpDy5caTWazc2m4Hx4e6ocffvhagQlZatjIMKbRU3p3lN8RfmckRmjr+Pi4vv/++/rnf/7n+vDhQxxd0Gh5yNSFmGizU1w90wJEGftuNe4IPHUnjbEcByDJUOl6RIOAgOpQ2NL5fnR0VJeXlwfOjoidvEigJ/1ONCf+pt9dJIpRDfbvEjBx45P0wJ1s2grW/e70iWsekn6541F4mKDNDQjz+7viUzJeneEnz9kerZWQHHEXh/qiqmar7AWmff3De4GAt61r/6jsJUfROfGORwTjVfO1LeSJ+MXfHPmSrz4V1NHkgNZlyHWauur0UlaSLNKX0F6m8hMQ6Hia5N/bk54vAQOvIz1LNkh5d7vdpOsOKFMdrieM9Ps6w2THz87O6p/+6Z8OjkxI4GtJb961xoHOMhFIw8HK07zJaIFfEgq/zwaTJkeP6YCjTiC4hmMkzEt7XP3wGCXxgN+acGFxgz5qf3L2fs0vqfFd0UMeMcw7SiqLq53Zv3Q+ek5AQHm5vb2dRRuYZ0mRnH8jAOm8cb4pEfCM2q5EALgUaqR8Skbd4CyBkSWjxDL5vwuPyylTl3St75nw7AeW4XqVoinJWPNdXXcLrN1uONhNRtflptu15HSyPI/IeFv8PfFtqfz3JJcFdwxO3wiwMTGC4fxkOf7eyFmOUnLQyc55XyaaRD/BVJK7lEa2rZsqHpWbQJDeUWSY13rmW0Z1f+T31tojp4/PP336VP/rf/2vg7M5lGQL1kQcVp/j4B0uA0/iGeaQUHuYmk7CU1JwN4JKEiqeec6FVXzHV912TqNz5vv915Xjf/nLX+qvf/1rnGbw+Te9n7Yhsg61Y7vdTkeuarua7nNU5Tzw30npycMOeadEg+jlpXl/1uVznVoR7ce4esisa5u30duxZDi8//2dJedCueK9JEdMCTSTN5ymYbluGNkGbxPbov7kjgbXY9cHliOHud1up4W4MnzJSXtyZ9DRrXsMx3f5032NnkcjLb2bFow6LR6NS+UtOU7pa+KJ/x6B4TRA0DV3DXW6S6De6VHXd15GB+hcdzhy5lk+PhDoAD4jIAR8jDal1E1Tu4wmXlAGu0WBSb/5Xkoujwm4OeDsQB79VWqX06TkgLPqLepMPhPA+dTYKC0Ch0ScE5U6zwlz50XiODpNDBh1AmlaUsZEj3dMUijRl+aFGMb2PJ5k0P3YXD73FcujDhVQWxIif5Yc3mazicdT8x2PEo0Wh/p7AkV0amvm05m6hX2eRnLQ1bXbff1qqD4fTqVWmWmdjhxTokVtZzsZAUtz10tApKNf5aTpRdIgeUk0b7fb2bQSgYtkc6SDS/SxrQkMvaccOukEhr1tcmzULxrNVNfIYakNDkK9btouAsTOWez38xGfOxkvM/3nQOo9fZVsdrIXbjO7SGUXOSQdfvBToottYlpaGF5VBzLs/KI8JjnyfCOZGDnvkR9z/+gRoeTjurRk+7wvmG9N+UqrFkdy4RsXwOhPSMYFbcRwMqQDEcojRJg6htMLHi7Xn69eJcMYKfD8VCRnMo2xG0PnH+msetvD7Pxwh8qpANHki3h87p31pv70tASayBcfyWjKxfniyq65vFSmG6ERHd4Olzd/Nylu93y/3x98zZTPPdTv9SbZFI/0m+UReCXjQGBBfrk+UWYptz6C17v8ainrFGjQn8Ce8vpi3M7QOw9SWjL2S/KoNIrEJAeeHFeimXon3hJ4dXW7nfB+8OjhqH1dBCaFuD0yxbwJnF1gc8YAACAASURBVLuOupwlGpSXNs1l2tuTnH0a5HQOOwGPxO8OtHt7vN5fm9ifyenSZ6aU9FP3nR+c7vBFjG6DOsCylDrbk9JixIGhdidyu93WxcVF3d7eRudFYpYOu0j3qjISHTnGxHQPQ6a/kUDSeFZ9NR7n5+f1/Pw8O/kwJUYF3KDotwBYtx6BUQ0uNFKZvgPBeehtcp6TnvcImdejfnYl2u/3Bx818nL4e8mxJDr+K/Kmtu/3b9Nhat9aHnXGMM3JusxRbjvD6ivVk574f+qi2qS99Fx8q89pv7y81OfPnw++jZLkdAQUvJ2s/z36nOSu67e1YNQHPco/AiQsb7S2g3SIt2v0ILUhJQeyDgKS45VNWhrls4yubqe9A9Cer7NTXb963/A+B1buhJMc/FIw4REmpyO1ZWnnled3+fOFi+rjNJBOgzZPCUwnELlE9+qpiqQ0Wty2ZvSRUHFSnA7pdI7NjU+nCCPD0YEGGnuGmAUUxGih/jWKmO7JsaZQJj+oxfeSofMoSKfEHYBZk0bhR9FNmjj/qTnz1MdrAEA3n7nm/Y5v7ymDh2CxzFF9fq9zBuQZp6j4nDrk+kAw6ZEHj2zIIJEO7dw5Ozur09PT6ejoz58/TwtYpWsuM64/I6Pt/zteOOhhXVx41uVJMsq2p+ig/lPfxVsvOzlB9hFPTqRtGzkuvS99WSNnbux5pgbrdr6MIia8n/psBHLS9M0ojQCe9yP/j8BKl1JbunzJRqjtnWz5Ndf7kc5RvZ5GICcNNnSdfAEjxqm8TqdTWtxVQSGmU/AKHF0xlELik5K5EtNA+f1RI5fQJNcDJCfq/6nwPtK/v7+fhOM9o1DvZIEQb4tfM/lcO51IN6XDRKPxHtCgskZ89nRycjK10ds6qiMp2ZpFO0xLgHFtGYo0vZdXXX94iFHXlL2uDzuHmu7R8TkQVpnSQ30K++LiYjoG+KeffqovX760u16cNsmhz1v7vn6+o2vfrsv1FJ2THrV/dO3TkymPh6FHqaOpcxjeLtrW98o43+cC3wQ61jqsJfuR+oXPOuf03rSkb87Dzm+MUpItBywpL5MfrU19WLNYNj1PoKWj33ne8WBp189SXUyLwMFBQ8dU3/boDeqY0Slnx9z3juz9OY05t5/4KMSdVzrwyUNknUNlvXqP9Oq/A6+q+dwy6+gAj3iqstKWskSj0z5CxyNj6iMBfgch5ev67L/C4afy1yzYSsmnhxLap0HVfV/s6ou1OEJQOR4udF75aKIDwyyPOszpRzkcTU9cXFxUVdXHjx/r8+fPB6DWdZp8TDscUvhUdXLbsqZJtEB3NEXJ6Z4EikmL80C/fY2B67CvX0rGmXSRP93aFMoA20de8j7f484Wyi9lqFvzUTW3LR347+hyHnWJNs75kvg1AoFMS7aC/cm6uvqX6tE7qe2JJ127WI7f429fY9fl5X3/OJnzYwQ8EiDyNYK/eqqCc59UqgQIOoCQynUlYeqQnhuAtckNmZKuU2REh8toa1HXgXrWKZu3YZSSgiQH6EatM2LKO1L4kVL+Uj4vGRg5jjWRmiWjMXpvzTtrwJIMk4dhuehW+dIcofddAh1diNd1KyXWudkcrifyfKJd75ycnNTx8XFdX1/X+fl5ffz4sb58+dJ+c8IdHetmnrR4jKDHbQV5yjIpy6xXBi8BJk6tENSRp9QNd6w+iBilVL/zXzQ7uPI8LE/33Igz3wg0jJxV57xTf3tbyTPtltIJwXSuzmdvRzciZ136YFVVzT5vrucu350d62SYv9MODD3zlGS3qg78S9pxoumkVKaXt4aO7tmaRN18j61djDhwhbEWiaWFKFQGF4iE3FyZE+BICC+tRF9KS+VyhbsUUOcNLNVBw5imVs7OzqY9584Dz5uMSWqD069O91Fs6gcHHamukQCvARprwAAN6Kh+peQUf2kaofrU9m70y373yE5yXFTQzonJGXbOhdcdTUys3yMYjECcn5/X6elpVVXd3t5Oi1l9ek+0jmhhW+hExEd3nt4XLy8vs08uM6+DzQSMR6Fq72faLM/TDRCSkXaAk/RRz0by3q0FG4FaXrsDWAMESNvoeQJIx8fHdXV1Vc/Pz5NuejTMd6IkEJGAjORTZ8BsNpvZYWSUrZF9Gtk6PZe8nZ+f1/39fT09PUXd8cT+Ja+1c450Uq9JZweEOr+Vfi8BDG9vd1/0LE33LAIHNiadiJiYlhYT8bfyezgxOSnvmJFTGqGvzmAruULzdEeW4cYsLbLqOqbrjK7doyRh3u12B3Nsaxw3y1l67rxzOrwNS8IsXutQHm7VTEbSefoeZNy1bS34TIo9ksdkzDx8Tge6pOROS2c4/Lfq8xGPT4ftdl+3yj49PdXDw0PtdrvZJ67ZnjSdkhxT129Vh+d/kBYZa9HJqILK8+2klE+94889uR1IdLq8KV8aJSeDzz7vogFJ731B2y9JqU0sj/WNdDXpPsvd7b5+W0Jy0zlxp8G3one6qHvaJi3+SybW2CSvx9ul3zpfR4CZNDiQ7/yht2MJFBBcJgDCAYmi/vQ9I5kd+d1RWmtbF89xYGFS+s1mczCiUj4aSzZ25MxVFzuUnecLLfn+GuVih+hDVQ8PD7N6RavuOb183gGjtFrbt7F19LmQJaPifKl6O13NQQPp9XYoXwrJdUAu0eT//T0mL2+3200LJ+XARvzxOW0ek53q8vdHBia1kffTu91HlpbWr3SL8jwa4Nc0mnTcHd1Oi6/FYZkCn4+PjwfGi21XeYygJSeVIgUES0xpXQT7lfT4uSGJRucP+delbvTL3643dH7OI+d1Nz2T1lHw9xLd3oYke0uOIPVd58S9LN9llMpLzxJ//dr55O9st9s6PT092IHi5bJOylmyjdpeT3/nc/96l32VPlGg9wmAE086cEW9djnvoh8j0NbxyHlVdXgmUkqLEQcesOREkiAq+BpHwjK6+0nAfkl5fP/o6Kj+7u/+rv7v//2/0/oFL8MBgoSDI3s3dp3g+or0zjiMHLPT507K84o2buX0spdGNu6MOgSbDMzot5JGtlyYugSwSJfeYb+M6HEHl0CYt7MzNB3A8LA5ld7pY5t9rQTpJU1dX/FjTx3/O2fkTjd9GKubenR6k0EkT5iHZS4dpe4ONsnLaPGf8y/ZlY73TMk5kC6vr+Nz10/UzY6GlJwHHSBxelPEy2WWZXQnRFIeOr4syY/y0MaPTip9enqappNHdj/Z1ZRSX9F2Jn0nyEqAS3ZqFCnogC/pcLu11M6UfMCS8ornVYf+3tOqiENnPNwIsHEOLBKRTESVnQCm9zqHnZ7t9/u6u7urP/7xj9NcmdPJVd1M2+02htTZZjeECUx1xkvP9Ned8MffnTNXcqH399KCPBrYRHeiueP5SJD3+/3sWwipr0hrcgSJj53Bdj7w3SWQpOepX1lHN1XktGqUr3KJ8JmXK/87w5BG9x45c97pvk9bJD4lGaHj9m+xON/5zOf+3a6kxbIui0luFTEZOduR0/DvlDjPSAvBeJpySXWltU+pbPZ9V25nS9UnDhpEK/N6eXpO4CGeaPGjQvhOm9sY9jV55NEvp9/bqXwd7apbSdNynZMdOcxONrq81IMk58m38HlXp/SJvHLgnejr5KVr0xq7ObLdVe/8OiYr9XmqqnE4zMtRSnNja8pYypOEUXXoDAa2Sb+1OphCq9GxI0E3aqOFTZ0xchpH60MIrpZAg9OZBEFC6p/IdmVnWUkxHUQxdQKo/M/Pz9P3EUZraLyNLy8v0Qg6aBiBhS65IdU7o+OGvc0j8EDZEiBVXd0UjB8ORtnztrgjHoGkNSnpypIxS6NeN5pp+qLTEdcztsv7fi2YHcks+zxNtxLYefkEZg6GOt4rf/pWTNcW3ktHWKf1GEkn3I55Oj4+ni0WdxvAvwRQOzl1utxxpjxLNtR542kkGynvKCrovNxutxOfUv5RO6g3zkNOY3a8HNnZ1O5RkjyN0mLEwUPBRPwjhUxKmYTUHVQSQr3LepTHR4FuiJIj4YiJo6AUUaGRIzpPSsKvwo2cVuJzd/+9zonvygl5XiJlX2Tk/O3oS7xxGhJd+u2gLEWsHKAtCb2DmyW6O4fF+5QVd6DksdPngI9JURauQqejYVtovJj8VDrWl3Si45WupQvb7fbgw2nqD9kCzf12X7EVr9wIdjTQYTgPPSqieny6gsbdbUCiz+1TOq/C5YM0u52iQR85C090GB4xIH/oiHhstd51HieH09Wta8q5eK15fwJ1B3HqD9cDtwkJRLJ+yuAouW2QH1gCaKnO4+Pj2u/nh7wl2U/PCP7J6wTueO1+wenjOkK+162V4P+Ux+sY6WIaNKa0+gAoEd4tulubElr1kdxS4krTBDyYEgChwPMZQ2vutLryvW2iT3PFEspRJGFNHW6c/JmDFbWHI9gutOZ90tGVnrNt/HTxCEjQ4ep3d6ZDR48rZ0drZ6QSTekZnZqeKw8P5yJvR4aR92UguIBq1F72vxuXLo14SsCgcH9VTREgJemFL/RNBpLTMMlgLYG/rlw+U1mUbbWjc9ykQbzzBYvefwkc+PMENru2MNI0ksFOf46Pj+v09HR2pkiymUt663zkO+QfR86uA0pcmM2y3dZ00zodD3w7oz/3353+kibPc3JyMm2/HIErBykOPKmTbKuDDqebfi9Fqbv2jABY1/ZRGoH7Lq0CDkzcWUHC6Mh1T4YtOagOBSXU6kquMv1UReXn/5FDTs8oFG7oOgfl6eTkpK6ururl5aUeHx+jwVwCD05jAjJLxqEzROqrFCr2PL56nvX4HHyiqWpuVH2UTSDXLfDr2kiZSuDJafJ3u2epPgcGlOsko16mrzvwsskf7yunVYBQ/Eo6mehwh6jnivg8PDxMU0aiw8FN0hnKCME8HXkyhm5gfQX6yClQRqvqYETs9sjLE7hn/8ghq3wvz8tieWl7IMGN94vLeZL7tMZJNrWT8wQQ9H536Jr3T+fkeV98Sl/59fUfXeSj4y/1yYHgyD4sOUg+18Du4eFhNj3UyTrrJ4287gAff7udoOw7b51H1MeONrcdHR9GYGENIFm9OFIVSnA1ukxEeWOTMx45LP7uGtc995W53p4RAnT6qw5XOPtoJXWQDOd2+7ZlSPfXoDoKEOlyhaTgdfxhGHypTudZUh433t2i2Kp52KsbtTN1Yf/ULtI9kpOON2sMt8ti107mdVlUEg+SfKU2peRRGjrHFCp2OigHBGuvr6/18PBQ+/2+Hh8f6+npafpSa0oOBkg7jXCaRlE7vP18tqRbpIMgwO2Mv+c8Fn2Xl5d1fX1dP//882ybNuvoZKyzd2p/AkJ6z20Jn6X08vIyW2vlBwwlp+WgizLgUz+eL02BuJOjzHX69x5HT7nunOCS7i7RQbvsCxkJHJxO719e6wyIkbz6e764swMra0FAx4+17/nzUVoVcUiKk4jrVtiqDO8MKm8nJD6XyryuFKrDQYq3pxNYr78zQokGXj89PU3CSeVbSwsNgY/C07zyKLHeZDC632mLnPPb6XBQwXrVN67AKWqRRu6dAnb883z8zXIIxtz4LAFW5mUdfoS52qp0dHRUZ2dndXd3F8vy/kprMbr+cLkXjwgsCCb3+7fjtH1OlTSlkzBZZweARs5f0560DV0/p/fd4CfnkvSZfN5uvx6b/N//+3+vT58+HaxzSjqaeMh8nPv2d326go58VK/6QO85YGR5zkfyUHlYRjd9Mpp+4RbgqjfA6HI+ck7kHUFW13bvG9GS6uhk5+joqE5PT2u/389AGN/rFqg6D/R/tM7JdYZySX/YtZ1ljHTJaRv5rpSXyYFTSqt2VYxQI/NUHTqYEYpiuItl0Jl0B/zofXWc7o/CxaSva493vNNOo6ByPAS42+0m9Cmj7M450eY0JKGjMr53rUmH0unc3BCnfKTNr1k2DXbV2xoIGip+BjgtcHKFS3x6T/udJgewo3Jp5FI+Bw1et5IM1sgIJIef+J/4QkOWZCT1V1XNQuAjh+byybx0cCyb+pJoSsbLQQrbQ9lzcN3pmgMLRYGOjo7qxx9/PDjXJTnhJSO+RnYcqHpZSU75LI2IqbteFu2jy9PIrrt8jeyHgw/JgdftbRZ9DrqY1E+JH05X1w5vk6aQU3tZT3qX7V/iofcF3+U2YIJR5eVUcafHvyaNQNevOsehS+7oJYg0GB5GS8Tx2p0XnYiY5gYpIbrU0R2IYEqG1GnjPZ/CID16nj6Q5eUkZXe6HJ26Q6WRdSV3RU553RjT8Y8McKqLBmDkKJiHCzdVtofl1yrniJej597n/iwZmSQznbP21K0CHy2y7IxZl9ygJzDi7U2jDc9HmVP9NII+Ck4y6m3pwKHrt9Pk116m3+OUkcq8vb09+IhZVzbvL9GwBA5SPa4ztIf69HlVHTi+kR10mUzAoZOjke2kbXI9TyAz2SdFLrSuhu9zhwUXaip1C0PJR16L1sfHx9jXXfuTvrk99p1MbLPK6cp3IME2j2xx126nI9WpenRGh5exZEN/EXBQ4ug+daI702QUPHWnhTG/M8cPzdDz0W4L0jiqZ00H8PwBCsrS+2vqoIF2o9K1zwFXSh3A4HMHAl1d/C2H72E40qX8NBSOtt3wjJJPeXQpAQIHn6zfUwcWEg+Tc2Sdo3b5czfyS8DW+00GyKdQuj5Ni+Moz27AVZZG026UeW8kO37Pdw50U0r8z8hHcuZOy+vra93d3S2OsLw+T+7Qks0btXUkE5TP6+vr6dsinr/7VLgSp32TPUkgTtfc2t3xwuvuZHa73U47d15fX2frDBwMcdQ90qeOb0y+ZsyT171ke7jWrwvtd4DRaeE1owzdOiEvy+8v0Z/autbeVq0EDmwURyQSqCQgnIbgwg+f4yPx2lObRjzdKKjq7YNUqqND3CwjoXDR0QmQo1jmcQPgK8pHqUO/dBjJaFLpvQ00DAlMEd0K7XIemwh/NALVcx6U46uUVa94TnqcN8lpLaUlhU+rmHWffOqcvbfFZctl6T30sozkZBwk+PWSY6o63L48ooFleb8nI8Z3fFrRp3TYJsql81764892u91sUbY7OJbNemmnkuwmu5SMMp1oav9IdsQPlef2wQ13Kmu329VPP/10AADJL7XFI7fSS5a/5Pg7UCpaVBejTA4YPG02m7q8vKyLi4v69OnTNNrlQl1v84getcVla5Tf3yG/lZbm+QmkOhAwAoas20899fdHdke08gA9tyfJtohup73jl6chcHB07kzg79Goj47PR6ICC/v9fkLRRJksQ0zwRnq57gBoBPlMDo+O241ZoqHjFZU/0ds5xLWdRSPp9CVF8HZ39V1cXNTp6Wl9/vx5Mko8Bz5FOJZoTIvdVEZSWKLrNUZ0lJLTZf0JLPHdZFBTWckoJGXtnD/LSU4/ySzLdpDlIFG6RCPhDrnqTc8JDHzdgLfZk9uD1MYOYLn+prrS6Mv1gfe8TzlPnupJi+86IJn62hewpv+8Zr84qGPepNd+WFHS883m6wf9dFQ05dwB0siujNaUME/K1znfy8vLGQ/TYlGnlcDR9YF2YwkwrEn0dyNb8B795n+/diCq9iyt66Ad6NZAjHiRno9sJ9PidkwKOgtmHv2XoKQPYiUkRqTMMlRfCnHTMY8a1z13Q+u0uQKNIh1uBBKtzssR/SMjTQeeHFZqP9vQGe2qt6/cqT8SEl2KFOz3h4vieK6/Ayol0rQGmHTJDS/pTHOwXv+SsemcIhU3rcZeA0I6Ze0WYXo5HWBg2QLjCXjTSHdOLzk26jrL6Jy3v9vJktPm/OHUhbe9W6cgcNCBCneiabcP8/sI29MS2GV9pN/lNNkR5yMTnYjm8vmMNLlzT79Tu9yGpXxuM5RX9+7u7mZl0kYwH+VKayE4fZtkjPLS9Q+fe2KEnD6gi4a6bVuSC5d7DmYoX2l6z9taVQfrQ5TS4M1Bodb2uG1cAl6LUxWjUx3dKWjuyoklIb51xRWMzFJj3rsFcZTXO9XLdgefykyjABf2TsBcuEa0LxmfUSRgu/26HbRbwa/3NBoh/WsR+whE6rkc6nv6bSmNjFUCgGlOPpXTGQjva7/HkVBH3xqwm9q5Jk8CY4ymsR1uwPnM+57t4Yhcebsv5napA3BuGzza4cCBRtZpr6rhPD75Rv4tTTWRN3LODDF7345+E3ikelKb/brL44B/KaJB3df7Xfm0nb7V0u0m5UzXkskvX77MplAITskr2mh3gkvAxduwlNg/3pYOwNPRp/tOb4pK+YBMvO3alvSUNI/axSSddllcO1W86rPaZIILthinxspo+Vy63js7O6v9/ut2mIS4yYQRWk/O8D3OzpW6E4JR+TTE6ohUZtXbyXYJJVO4kgNf6sgOkEgwaLBUZ6JV/eYG2fnlvCDfeF/fNeAcO2lO5aoM7hPnWoT0Hvsh0dg5hU4p/Xop7ff72Va+DlB1yafK2H8yJMqnPHRirguUOY+GdTKcjGMCWzQ07FPXHT5nOdvttr799tt6fX2tm5ubA5kfRQxoTI+Pj2f9yqk1d5TOH9Ls4MRlyW2e67zu8zedcAIQ3IKs/LSdyRYlGep4lWgagULXqcSXTu9Soizp3ITX19dpjcXz8/NiWc6PLqLo74zAG3nmTtePy2f0ME2DJwDJJH+QDuni/2TbXM5IV8erUfI6/Vmy90tl/qpdFazYhTiNvpVPDoWNYLim6nChFYUnOam1Rp7luTIkJJfayeROmfclWO7Y9b8DMek6pRSeYplSUE8uHM5Pfz7i7Yhn7H/xQr85iqg6nJoi7eQZR6M00I6al+bMuzZ1YGLUF0t95oZhKTm/Rgrv/H8P4Ozkb8mgq3yCUt/OOJIJ/4x1mgZzXVN/06iq/zXV5nPvqY1u+DvnkiIy6Xhltks06/0OsDJK2yU6TtI9yt85U2+/aEiy5bKsvhKPO+fl77NPGfVkNEiDTT9CW/SSl7R1Hh1Jzq67N1qLcnJyUtvtdjYIGNmJEQ8SqGN5XbnuE73c96ZRPe/xNZ5WLY4kw535TL7AioZN99MRn67w3liey59QvMp5T3Ijpf9dOazb63NapCAvLy91dnY240eid80UwXueueP0NqZEQ+wpGWSV63X4/KCPvs7Ozqa9w/f395HGjganJSHzrr3vBZapnSP5IJ3kA/nhZbgz41RJR4NHbZZAjZfLukagJBm4jsf87Q7fZWe3+7ozQLT7mQoJnHPnlusfF/+RdtqcNHJXmYpscSCTHCkdrssXQUACEy6Hcpoaqaa5aJeNrn8SjV1i+9hfPrhRWZp+4wFt3fSU1y3+a12C0yD+n52d1ePj40Ee1UUgIj4RpDqIHCU6dO8XtUtHr3f2zmUwbRVNINjpcHnxOhNo8HcuLi5qt/t6LsWatjtd/M9y/X5KixEHGRuODtzwdQoqA5W2LyVB84a6ofYw03ucwpKB7WhgW1LeTmH4jkKTBFbvMQwU2E6gU/ucRv8/WnxXNQeCKSTuNDu9DDVKFp6fn+v09LROTk7q6elpmsJhGxPfk0PxuhNQ6Po9Gd+1/TBKDgL0nk/defkjp0GZ6tquRANK8OJ18N1ufptOP61LUN+yj5Pe0oE6+HbA6zxKdcsZeZTBDbvT6+0/OTmp3/72t1VV9ec//7ntW73no0gOaLy92iJOe9lFZcmLJQBNepK+u/6wj7ttf8mxbbfbgxNxOSjs6GLddKriFftYZzkkWeF958fSaJ60rkn7/dtW1RTpZvvdgb/H99BOu59w8LPWt619/h5QsCbPInCQIKZvRnB6QY33CIUjHTbCRyOak+WcbgIJnSP1+yMldMRJZlHZ1Kbu88Wd4aexdoXlKDQZvQ4Vezs7Q5mmcka0p/LpFBK9XWKf+UhKwEH9PCpDdLmiEox4cp6I3iXw0IFC5uMzti85dB9xVx1GChIQYl9289sdbZ3TcR4mJzCSA3+P7yfepUhXl6QbtCFuO5z3jDwmfjB5eJs81+E9/+N//I/6wx/+EHmU5ILAKE1Pus6Sfl377iOCi2TTXKY7/XIaPHU2yKeAdCaLosOMoiVQkupy0OKDR73z/Pw8nHKt+rp98/HxcaInTVknHqSU7CUBQ2cnmFf/eTIw8zkISHpUNV6j4jqcbL1HbJ1e9y3M69OgtK2ibZTedQCUCvYtWJvN5sA56n4SNC/X0Zc3ZKkzRZuDi5RPaY1z9dDcKG9XdxLKtKZgjUImAdV/py0ZDzdsycAlwNV9/KjjxxLvKbQpTOp1OK0MXS8BmZFxG7Vjqa8ps/q9tFYk3ev6tOorkPav0PqiP73jBj+1Ock8V9UnndJ7PkgQ+FMeLhDz0S3l02XWgZ0bXbVXMsgR/lLfLj1/fHysP/zhD/Xp06eYV3WoLR3vXWfS/vvOuY6SnvuakCUZ0rWPkDk90jlafbtD69BYLsFSAkTpHpMOKdLofrvdTtfJhind399HR+YAkyDdo9Pkk9sbB22j6GonJ13+xAP3EdSFpai66+EaGt1+dmkN/UpD4JAYzxOz1FlitjeMAurhTDawKm9LcQfmzpW/dY67wt+O0vke62NdTBI+GlZfpOPp5ORk9g6dicrs+NwJQAeCOp6seZ7yeRoh2FEbOrBCvh8dHcUv043qSMI/Upruns+NLrVrlJLMsC+XoipsE3+rHIZrkxNyI+IRPAeDvE/5HBmWBBZpXNl2jua7NtM2kMaqPEXBdiXHyEiY2wo6cfJc5Tw/P9cPP/xwYMtUti8udsfZyWLntDhy93fcBnjkzsvqHB/7XIM8t7N67vVvt1+307+8vNTj4+Nk8zStsN9/HWU7r5aS8rO8qvk2S7bLIwlp4CL6fY0M63TalgBKx1fWPbIVyU57vQ58vT6BNvHKdZM25fT0dLa+IQEG/va1TrxH3Uxt8LT6s9p+ZKsXvuT8nJDUgRQAHtaSjGe31iKhtkRvol//eZokDZLPx3tK23KScRPNScA6OpeQzuhCWAAAIABJREFUJR1O117SVHU4p+3C5AL3X5U2m83BV0OTsLvB7Bxbxzfm8fp1f43h4zuJ1tE1adB9GUJFCMR7P3QojZxYjjsFla385I2PcJTSaYp8J43wyYMuIuhtqHo7nGgJgJIOtsHXSy2teXH9cPtRVbNogoC/Bh4cHa5xvqRb+fj+yP44aKDTl2ywDzs+sq6kG77uyJMOjeKz4+Pj6VPUGjxRd0l38g90TrTpbIc71Y63TOwHArL3JNa3281PMk5+x99l6nyD05W+b8F319jx/f7tC5+JzpFdo49zu8R+GaUhcOA8t4SGhPtcrlc6OsZVxCufz0cmh5KOCFa5+/3X08jS6X2JsYnhFCDPz/dG/NL7zvgUCu7o9Hsd8Er/vW36LUPoc72J/uRsWJbXo/JSv5B+Xd/f3x/srknlj0Ca50k8T3lTHjeiyUGmUUPijbc10d5Fu9Ii4rQosUvsA5fTFGb3ulhOMtzUi7SQiyCB+Tsak+ySJgc75G8np3K2PHSMACCBeI/ceJn6r3Z3zpnJp1tEB9vnfeWDlc3m684GRQHSVwy9Tjl08psAxp2t981+f7hA8OHhoV5eXqbIg8r0sLtAhey+6GablU/t09c+PfpAGpP96YBYGhR1fen1cLut83gJAI6AjgN1yqX7GvKV9xNNrLuzvSmP+C5ZSYOTX7XGwZXTGaMGcgSlHQQSMG8wD7VZ4xiYHCHp+vj4uC4uLurm5uaAfuZLKTkHdmZCfksIVAosBXGjPRI+r8uvvV1dGzq6aTh9fUHnWLzeET/SPR9pjhZEdXWsoWeUktFwHq1xqGu+QJjoYv1LYLC7t9TepbxL8jsq1w32CPDReAuw8jcd2Kis1CeJfgcunY6N1nFI730aYckAsz99irazP+60nBaPJsiG+EmgiQddSuDL25/aq6RjjTV9I3o2m8Mdd/qvnS+pfPXTyclJCzzJb7WdoN0PSEu8TjziwDa9RzpIQ9efa/2X3k3vsY6uPAesXk5n21IbNcXR9fdSWn0AlAMHGQQi9ZOTkzo5OZlWe15cXEyhrzS1IGL152F9ZyYROeeBqt5OjnMmjZzh6N4SE5Py851kpDzU6snpdYPrdSVl7+hn/yUw4ztZlox3oj21g8/YP660nnSPocPEc84bd45xjYMetdGNu8tZ56hY1y+haURXckYjBzwq251R1xaWlehPC7u6SEdytKP28hkBOh2XO6k0APDoAunlPHyyQ6TTF62mQ4yW1nWNgKrXyRG8ACx5r3dSnysErzyjo8Jdl/QOp4FVptcnx+7rw9RXvvCSdXBdmJJA+Ha7nebzKWOjr5SOwBplIMl+B84IKjn9tqRnjPowrQELTpv/TjZxCah6Prelo+lHpdWTQmmxxtHR0RRq2my+hj8uLy8PkK2udfxoh+rJYAIEIsGkXK+vr3V/fz9bROOov0vK62j5l86XiRc0FD5FQP7xmfIrpTCSrt1Isi7+Jl1OK+/zeGpvx0iIkjJ4yJyGjoawo4n1X19f19///d9HGhyQelpDe5KRBPj4DoGuO7MEipfSe/jbvbO2ne7EUjn+POlDMlieaDOq3lbsc+S8lkddW0i3nnu4Xvd96tTrpvPzNvAz9AQNp6enE39oH/WX1hOkNrtBZz7pT5q28vUWnd3ic2+z1z8Cmg60aKcZeZZf4PSHwAEHQs/Pz/X09BTp3m63dXFxMeuX5BA70KBpno4Xa+180pE1U89sRxpsvKdOvefPl2gY6Yjfo57+qjUOrJDCz5ECCby7u5udvPXw8DDL5/NddKT/j7cz243kSNK1ZZK5catN6lGrG/MC5/1fYq4Gg7nRzKB70FJLraVUxS0zuWWeC+IPfvGnmUew+uA4QJCMxd3c3JbfzJcgkuUzzuT9ft+daEZHRyGuOs0BdCXJDMjYkimiyunpaTw9PXW8IGgQHVSkyqFW7bA+zTFGvOxT54eDqrUbnpZjmU7zrz62AExFv7/L/ysULECYRQZfAu5Ik/O1ApxVVNBy6kTxfm/oXaevKk6r8zEzGmxbusJvJ/h8uEdLWZusK+tj5iizj+e5nfF1TzT2PM2wKhwzjq1Hmy5ztAm8l8m4z+WzziEZytp0flH2+f2WCvSx76Kvaqfqkz+nwjHjlBwPitrvXw5TYvtqjzveSKdsGMdT4IPjrXc8+PS62LYO43I7p+2hmf3J+JE9MwS2slK9M9Qu23bdyuQ0swXiA+WHftanr6vSBA5cvOgVTiaTg/PLSSyLG1HPXDhqzt6vHCvnvdzw6F0JJY2eC0K14O01pRWBOmghUmebs9msu94CL94WlXgyeVmhz7Pmxa9KYDPeZzRozHRcLLNCLYfnPFfh355FuL+/750dX9HdAm9ZO65kDoSydsaUDHxV9QwZn8qQVG1mQGHIIFJv9OPOJqIvbzLkLXpZX0VvBTo5NqTD7YY/T5Dc6iPf82lAN6jOS77vc+E8HdZpzWQi07sMnLrDbJ2rkrWTrcvJSmaTnS+Z/vr/XDzJe5VtUN2alvTpEALbh4eH3nRSVo/a2m635a4h5+s/q+OtOir7NPRORPuQqKG/HUT4eh7vRyb7VWkCB62kdYRTMY0GpWWkMkVtgQ+fx9bf7uwzBldI0dPpDkxajMsMgqM6Dc7d3V2sVqvuc7LkrdMk45PNh1V0sK/eT/bRf3vbfs8XmrFvUlyCk+xgmaxkspM58IzGIQfrz7aMgd9vGfaxJeNx1eZk8jy1V+1lr/SHcqpnfYrOadIzcq4sqsezBZIfd4J8T7+rOVGXlYj+SvIsGnY5y/qie5RznxLhPTkj0sNj4Lkoks4/kzuBen2d0+fmMwDHa+5U9d0W8l7Ft4OqP6xHf2eHTume600mp27LVKcvgMz0xh0WZckzqxkwF08d9N3f3/fS5g4aXCbVNjPRbuN9OqnlN7wM2aHXlDFALrvXoi0DDl4PfWfE4TqgsSBq8CNXPif4/v37WK/XsV6ve8KrRvk8056uWI5ovYOZsOtH6f/b29ueEcrqUxmz4MPbzkBJhfBYN4Vfws5BceFm6pTgoZWGJQ00aKR3t9t1aTqm+jKaHWhERC91qDp10BazUUr3VVMhTmtGAxXZHezYQofymlKNo/53UDhUT/WMX3dDOlZpI/pbnV33xoK3obaqhbyTyaR3bHgG9lyHVFxfNe2osdtut81MWwY0WoZU8pDN6XqhTu73L59adj2R/mZfcK2md/gu+5AtElb7ctzkdQayqvn2TN+z6b3MxjpI88WAHHPaDd3nGRQRL7aEdkj8Vv3ZlKl4ke3QcKd3fHwcy+WyC9h8war308GF82NM0bPZGpQvqW9se36tpfPqJwFm5i9fY3cHT470c8v9YCZ3rovFojtWVHN/PlAVYZx7cUfC/7VrYwg0VNGQ+pXRUw2AFJg0eT8yBLvfv3wiOmvD+6rB9YxIVnzAs+c8g0HjQaPlSpjVp3e1AJZje3x8HPf3973IpGXUh6YEhkAGx8+fbUXAGcBrKZ4bOT9uvXpnDMDwKM7fyZxEdt/pabWdGYYhw+lGXPQwcHB6VBjxep8kB/P5PObzeSwWi3h6euoicN/u7fwQDZTXIb4ro0DZ9SwIx9z55X2RvvoYZWn0LIDKimcSFMAxS5nxOau30mMGLd62nyPgtsHbFcjKgkbdX61W3XZOz7LJftC/qL3pdNqBABUGM8ykLRaLWCwWsV6vD2ilfumeMupZv8bonoO37N1WqfS3eo70u82o/JHLQ2bzM5A7VAYXRx4fH8f5+Xl8+vQpHh4e4tOnTwfKIwHRKtbFYhFXV1dxenoaDw8PsV6vOyb7NiJ3wtm8J4GKQAnv+d+qp4WgKuefPVM5uqyu7J745MbDaZVTkhJuNptBY8jiNDjtNPhD77VOydztdr21B4qM5vN5d+Q3++70sM7XCmxWhgDHmPfGPsvfLcA2pq6h91rGrFWfP+eZqwzcer3V2Hl/n56eDsDU2H5JFu/v77vV9QIStBeuyyzMarbGpnLYdMxjdJj8kM5mtsaB+piFvFVWRHzyaQfniQMBB2lD4JKO3rc6ZmBENKluTcne3NwcLIS/vr6O2Wx2cCgUecTpB05JsB0vzIDoA3oKWrM1ZxHRBYDcceE2qWUbsrU2mXOvSiWfPj4VGMiuZYctsng7/KnWBrXKYMbh/v4+Pn78mKJdH5Tdbhebzab3Hfe3b9/G4+NjLwWpjurwDyKfDOVnjMiYkhkAIl8q5msMvitOS7CqexkoIpAgL7NphaxkhrFFT4ZAWZfXk43v4+Nj99EZj3I8i1O1wVLNV1bP63ol5EN8q+QrqyMDBq8BJlXdldH+EiDD91XcSXl00gLRGV36Yb2tzEvmQLN69ZwyF5pWu7i4iMViER8/fuzJVTZf731zEKFnfU2U16H+ufxmDl/PuENzQJKBrYpftGGihVMn2fMck5bstICi0yZeeZ0EFA6WOI768XN2tCOEX7j0qU231dluLj3va2z0vLI/0+nzEeJ3d3fdWiIFQ76wkvJSgQ32VbKffW8nk7+MfgIub2MsgKU/8cPBPNOv5/x/Htr4mtIEDoogPX3E3yw0MrvdLm5vb+P4+Lj7LKobHxkMXiMi1SBnncqQdzZgYtYYxvigVcaZ7QwZSSpixTvRqNSkg7SWQ82MUoYqaYDGoOKs/v1+39GmqJDKr9PlWnVUbbTKlwC1MW0NzXtnfHaj7cqf1TN0PevLWNCc0eo0V6dZDr2vwikJ6faYCDobG17zNRSi9U9/+lN888038W//9m9d2vk14LIaN3+Wa4vo6FtOXhkQPTd2zUDFA5cl0uAOzuvK1j1ktDg9FQ99PRv/ll1ShklOWXU9PT31Prjk2zUXi0XnwJWV1LoH8VOLVvf7/cEHxpxe8cYBmhymMqICFAIEzJBl/R9jc+mfKnDBOtxHEKRWbXhxv8T/fbqOdWV230u2OHfIXjSBw9dffx0fP37srSnInGdEHy0qcoh4Pud8uVx2AIGOlCVz/kJCWSSQAZmMSZ7i07NDQKKFJDOUyDb9PU+zOY2OvscucvNonfW6oXf6sj7oWpbaJi38CBDPXvcswFDqrGX0WwAue97bcdDkdXpk0FKwzNE5T4bm+jOgm/WV9zwiI83i/xBfND76qqHT1HKUThf7OgTkWuPL/vgurMlkEr/++mvc3t52JwV6372dit8u727Aq/crUMRnMzvoID3TsaoP1fQh5cD51zL03lfagwxAkDYCQ615kPzQVrnu6CAntqXx1anCAgd3d3edn9D0wmQyifl8Hufn53Fzc9P7iBO3ZLK/XHfmUyfsJ0+rrOy066iPXUS+CDLTbX8v8xFjgEIG9LwNjZfbFu8D/ZDeEQhy+9WiLWIAOFxeXsa7d+9isVjE58+fexXSeNCICZ3q7/l8fhDx+BoFCneG7LKPgWSlUrCW4mXOxEvLEOq9IUa74XXDox+fd2v1txJSOXQHSBmdmePkdadVhoOLzLLFYRE131mvg53M6L6miI/cxuXGpgKNYwFb5mBb84OVMg8VPxCH7bZWcIuHkgPey8ZkCPz6Vr9MhiqQ4YVtVZm1X375JSaTSbeQTnIn3cjOkGD9Q/KTTQFk72SONdMR/p3xMpt/zp4nf/VO67lq0bOK7+BwOvW/AwIvWr/kJz/6uQusz4HZ3d1drNfrcmeF6rm7u4vFYhGr1aoDI+IhZcEzUHqfW8RFSxaUeclAWGb3h+xSBVazZypAMOZ+BjSZWeHz3qZPa1RgtFWawOH29rYzXJ6WpbPn7/l8Hsvl8rny4+O4uLiIz58/91JSzggSTCGmcLVQIP8WkqKS838fjGogMjr5+zXFBzwTDDrOFrjxetkHPq96HHRVbWbKTxDDEynZPt+tQImKRw3Vc0OlUqzsGVfEllOpFmCNaYMly5BlypwBCo4/HYenIyvn7dflfCl7lPfM4Xj/VO8YYDdkZFsASnQpcuUxxtTlqt9OVyZnQwDHHY1+c94/4wGjPq7ZIh98vKsFmW5XM/nK6s3qcefltkWLCGk3+S4XGWpMdM8Pr/NpZ/GCJ+fy7IyMrv3++QRi8ZS8pk7JUWbTDtQZ/da6O45r1n6l03wuu+8+yG1yq1SAoZJX+kX3y963zI/5sxnAHPJxg4sjt9vtAfIV0RIMOQ9FBTrrYbvdxvfff99bqOGF81sqQouMSPgzZiDGFKEv73P1fmUIM6dQvZfd19GqXCzKLUv+vtPsU0gR/SOn3SBUi8T0t8bi6Ogolstl3N/fd7zXyZZsy/nFxWx0OBGHIM75N1QcqFQy5av9M2fOo3ErR+x/V4UOIQOooj0DPa2xyBziGHAjPjFFmxngMWsVCCS13S2blqoAZFZXBcb1P2WHDsR5NTQ2Y53BGNkTrxxksw431DTsramnjGbW6dkF/qZ9btWV9Uc/5DsBELdPKijUZwX8dNpMtt1Rsc8+7uKv233WVf0vOjJeVIDZ+ZXxLrvuvCUtma5WY9wamzFF7zoNpK1aI6h7mZ0bQ1MTOFDQebxwRF9Yucr28vIybm9ve0LCRZCZ06JgEYz4YGToqYWSqOgtw1AZ80oR+ExGR/asZxP8HaUDT09P4+7u7gCh09AT2asNzRM6rQQZAnabzaY3N0gh0nvknQ5fmU6nsVwuYzabdcZD/RCNPIac6x+YvZBDE02ZTIwBb5mzZxukg/VpLHh6oLeXydXQOIuX1cEz2TteH6+3Foh5vVkbpMHnnqVnvkCZY8+IkuuTyA8692qqh3WqZB+6yrJxlPvsnn80y/vufMkybC2+0qHpnh/FH5Gfg5LZNm+nkqmWXeEzQ4beadE4ce2X+qg5b/2tgEFy4FsseXpmtsUyoh9EkE+eTVOhTGROnjbFMzZub/k3M1djwHLlC7yP1dj5/QyEuN3IbJDrmoNOH7usuAySB0M+tCpN4EAiiVo4x6T7NBxa9OJMcgORGQ4+T0DCTmZKmXW+FRWpEGHzXS/elhvR7FkaYBphR9xaZawszZs3b7o9z3d3d71vp0uZ1Ya+SCpe8QhcLUASLVp4lO1+4Bjz41hameyCr0hkOn3e9qQdOOyj0oPklwOd1o4Zv9ZyxNV7asuNitOjUoHTlpL7fT9xc6wytvqS1aOtVBp7/tBYTyaTbmFaRHSRpOuoxnK5XHYgUPflHG5vb3vtc4Gs3uFv1usG+/HxMR4eHjpQSdCpH93L0tvqmwyntsd5v7JARQDP6/K//RrrysBHZvMyOcrez8aYIJfOwt/L+svflbyzaMyyA5pEL3dVSN/1jjt270fmM1yv1E42Zl74fKbTdKwRMXrbYQUUsuJjNgbsuQ3JQIGDI5cjvnd8fByr1Squrq4O2s76K32UfZYejgGrKqOAQ0T0KvYDfuT03blQYJ1w/aZQ8IhXoUQCikrxqoHmdSneUD8zBXdQkQ2kA6FW3ZVSPD09xXq9jul0Gqenpwf7jjOlVoRwenp6gKz5cShtpzo7OzswQpPJpAMIu93LyZWr1SoiXsZei5eurq56GYfZbBanp6ddG4xqeJpkxDPQOT8/L3mUjWWmUGNLtj5G9DATkY1NFZmQb37NI5shRXRDwHe97/6e3mVan2sD3ChrL73mhhl5+rQSs34RL/vwPftF4CC5uru767ZVS4Z1ONxk8rzocbfbdWBCtNJJ8m+9p4OFqDPiO7NHuu7O3402HQ95XI1ZBtxUWk65kueqeFanCmwo2z7+ma5kWRmCfXf6sscEnOKx2uGpuHJG3r7Tx/b5fzaVM5/PDzLHlFXKOadYJRe0RaqX6zp0LTtyYGxxp1/dI50cO9qdzMdUtkC8lt9wnlNPSc9isYivvvqqe/7333/v7L/KEA9GAYfWvJAap9BlxphKm9XD4ttuKFCZQgw5E9WRMUYOP4ssKufmwu907Pf73toCOvSs75pCkDLI4M5ms+5bF4zE/AwFOmsWAjPd22633bcmPPVIAVUkuFwue/uzdc8NpdZUZFkd8oVR5lAq3vn7JaUFKKsdJ18CUNheFlW8hkZG8Ezt8n+NqbJK0+nz10rpaCkXTCc/PT11u52YkdK99XrdyxgootGx4uzbZrPp6lC78/k8IqJntLVATo5HB8Atl8suQ8Po6ejoqDs5VdsytbKfIIV8kkyNCRB8rLLnKptQBUitNjOnNAbc6BqdZrWWhIBrbGSteoZsstthZidlO5gBo25rvCR/DFzUL9Eu26DMhu/oIb2sdzabdfRR1mkDJY/KmNAeyYeprSEb4LJA2rK/W/wfshG0/RH96R/xTzbAaXNgqWDu48ePvZ1xLR+flVGf1XZk6MeRRuQrfdVpMqg6G1zPZszSoH+JQW8ZBv6dXWMZUnx/JwNPGV0cKKWQFPEr63B3d9cDIUKNnFvmHmW2rf3TaoepYSksFV9jFNFfuMqPEc3n8wNwRKHmVrL9ft/rkwSVNA0Z4LEOeEzJxpvjQHo8osscCut1GW3No2fvO1Ct5n69PRpMjhNpVgbp9PQ07u/v4/379/Hw8BCbzSbW63UvO6V3OZfvXybkAmbJnnZDSO6cx5pmU50R0QEeOXwB2u122+3j18/JyUnM5/OeoRMvIl6Oj+ZiUOct+dICeHzexz0LNjIQ4PR5yZ6rHI/bWcoaZeI1euI8yWjY7/dxc3PT45f0mc5INAkwKKtEMMMpvPv7+w4QHh0dddsv6WcEXu/u7npjzjQ7+6HDpSgzCn44jjqaWgDI6dTvIQBa2XTSxL+pi9n1VpG8CVCJTgXZfuBWRhN1T2czEVSQpn8KOHgE20JX2TMSChamRYcY5im7LylZ6lUD8NpFMm5kPPPghrqinc6I9x4eHnrG7/r6+iBTIjQv1EwQUPVZkYCUhU5C9KgvigK5eFInvhFQMNVMw+BrRggo5CB0ncLu85rqh3j1GifsfXP++L3qGY1PZkgqeeTYjqFNsuiAoNUXFmWlFD1prCP6C9Gm02k37rp/enraTUcxuyUAK+fPDGCWkicwlOzqGiMh1ccprcfHx1gsFl3f1c+Hh4cuEhQ/Hx8fO9nU8wQBWebQ+TY0buqj6/NQGQINmexkduE1hal/OVi3KWPqiHjRP+3wEj2KyPUsnZ4vcJXNUFAj8LBYLHr2V2PFHwUTi8Wi6wOnSnhSpWcIpEMVeJcfopMVyMh8lDJrzh/ypWVPWIZ85muAXgasMttVBbFq3/UhA6j/FHBw1O7X/P/KQaowtTJGuDn3mTmWMaWat8miDt7L+lHR7TzKUHsWAbFdP7RJH/3JCucROQfIupnO2m633Ry12vJ5L0VRNBQRL8KpQ1menp667whIuTVOmkLx7JQMvSsfsxCuAK8x2q0ypAhDqL8CC0P0jZVxn9et6MvqlUzSgHN+2eWMC20vLy9jsVjEmzdvIiLiX/7lX+Ls7Cx+//33+PHHH3uyQucgmZvP5913ACQjnoEi0GYEKDAqeaNBnEwmcXp62gHcDKSLbz4nT4dcOWrJYzY2pLc1vpRxBy+vdf6ZXXhNaTmFse1XxbObXOStwMvBlhw7dVpj5eBbIEVTV1x7w6LpN9WtfjPTwX549MwoXaWautbfrYClZVMqoJCNcSVfGb1Ou/eXOqjnM1pcbrPgaYwMNYHD+fl5XF9f94jwxpwANuxK4XVk87Zehpis0upwi0kRhzsrhtrxv73PbsyoVBUA8gVQzlPWrTqpzMoKkM9SQo8UXKjUnmjQ1AgX3xAkbLfb3ry0nFcmrEwB+jgLzEwmky4yZR3+N9/9kjIEQF2GModA58L3WFpK6MBoDDjy9llkfH0NjRfKgQy1shBap6CFtso+cH0NaZ9On7flysBdX1/3otJM12TU7u/vD75c6DycTCZxcnIS6/W6l6EiSKaRjHj5doqAUeb43R55obNg2jp7nvLv/XRbl7XDOr8EJLscjrVfXgg8q/eVPYp4+SYFp8V8HY6v0WGaneOu9RCqU7rpsszMhWSI98kTTbmqfa718PHlO9W6NX83a7f1Xvb+lwZE1Xu+BqKikeNEmvy9fxo4qCEuNPHokIPhKInFHaHe1TsyWkSJWSerwWsZ68zotpjMyES0OAquBCkDWOqHL1hi1OR8E08obOSP3lOdjvIz463CemX8HYnyuf1+3xlmnSbKxWkq2qKZte99lNFValJnV5BeAo0vBQzimxsRlsy5U6k4pjKg1Z7poXpb8pnR7n+7rGl+1leSUxY4VSCZ0Y+mOTabTfz444/ds/P5vDPkolnjocyFDK5S0f4NE8mWFmRJZvzIea6vkYwpw6V+aqpLtPFja1pQqfVAzlc32C3gSH61xojBxmTSP6yuKtk4O2DKnvex92xhqy9DesNUveb7OfU0mbysTWFGNAN+CgB0Jo2iYH9OOnl/f99NralPzJS6vdC7DHQIanUt46H4pnoVGGkcPXBzXW2NaxU4eMn8BP+mbfdn+K5n7Qn+Mpvl9bfaHmtnm8BB2YassxEvDlWD1do5EHEoFER+XmSoyMyxg5cZ5+z5sUzy6MPbG6JJ83cR/WyLIj+BgFZWgLSoOEJnu+Stgw9XTNKp9nVdDv7u7i5+//33g3corDwbQG3RoYgH+/1zGpqr6jWlQj5X0R6NT6tkALe6Xz2T8fW1RXW3os+qkJ9uSAhG6XzFcxWmZTkFsd/vewvUyFeCycrgcFurHICeYVTowUXmhJm92mw2HQCQbGh9xNnZWRd1npycxPn5eex2z1/i1Za0obGoxmCMTrNonZHS7LQpGfAcKpmTzeQmixSrPn1JkRzwbAbJiuhj4KJrx8fHHWDgUefkr6+7kS0ggHEHP5/Pe0GJ+sepbwUzAgPqgy8UpN3i9K2P25f6kDF8HwpkWBcdu/gtkOO2iHqm4sGk9y2rd0xpAoeIPnOyCJm/GQGLqIh+xE5BovMield0u9lsOga9Vgm9D6SHxZ1HtrAvQ3FVyYyQnCoLDb5+JOSK1hjxsy7f9aDiQIsHMOm+nuG0gJ7hSmVeC3gGAAAgAElEQVSeR7Db7book+lJLl7MQKKcjyIy9kN1amyzT9VWBr1ywl5aMlOhfzo63iMPX2OUK3mtopnWtawORl2K8NwgqU8exblRUt+0/kDOW2Pou2VYDxehsR3RzuDC5UXZsgwUs35tFVUd2+02ttttt9DS6x0TTPAa7ZLrfsZ7OaZqmui1UVyLtpYj86CjqodAnHaAzzGooDNmX32RdEQczLGrPbXD3xprTq9KrnwKgXXxb5dz2lACLtIooO3BiS/yHjte7pDHllYQM/Qe6dbahsxHMJPiUxlZxkrvcE1TqwwCh4j84BAahrHoLHuOEY6e0XMecXp6jPcqtF4ZDzHSHWhE9DIAlYHP3huLVCnUqscjFu2z5wFKjNoItJx3oo90MDXn29nUZ0aDMtQEMF4Xx6dC0BpbOSM9q/MAFMUw8+LO+ksLx1PKkznkTCYp19k4v5aG1vUhY5+tzaDjcoPHzENEfy5ZfNDUoArrl4xx1TojNGYaJIOSQ+mUDLvPfxPosK90BOyHfmtbndZjeMCS6YDqqiLDzJawP37dy+PjY7dV0QuzL2OnyL6kZPR6Ed8FAvj9IfLBnYavTeL1iNwvaIGj3vPoWu9UPJEc6kwOz8KyLf3O9NT1IZvGpazMZrNYrVbdovQs2/kaUOGF9XDbst/zktlwyj/1if2STrjdqPxvBsZaZXCNgzfsc6feaS6Q6RrBgR+Ojumc1VkuiFJdNEA+6JVhz2jju5lSqH/cOujrEyaTSTeA2eB7tMW+6G8q7v39fVfXdDqN7XYbq9WqOwiHUzsSmpOTk64tCon4PZvN4vb2tovqharn83n33REV1SmFjTj8wJUiCtEiIEAAFvESUTICZTQh4ZRM0LkwqsmAX1V8DBjhZONBQ0vZo6EkTRy/zBFVxqSSA97L3s/AaFanxllTQI+Pj72dCBpPgQAdzKR72h9Pp+4LDiNeVm0r48AUNgGn+K4xpW751Ad10PsroOkRlvriHydzm9LiK69n4+a2w+WP77ptVBHtQ2NYyXhFdyZ/XndWCC4I3hmNeka4AiTUlwygSRZ4IBPb9YyuaKCNm0wmnU2ij9F7PtZZ9pOy6LSzbf0sFot4+/ZtXF1dHTzrfazGaWgMVOdrprxdbrhYPaOD4xDRBxaua+4PeX2oDGYcaEh8ntQXlZBwEZp10NG8HIyi7N1ud3AgjTpDB0njREFXnXSEZCYdVgY4lBJtRSDVyt6sUMCpBETC+ptpWG5vzASW84x0IKvVqvt+xC+//NKLAjQ3TODCbVabzab77oQcCecqmRmRY6ET4fSDnJNAiPaZn5ycdMZB/GQGJ0PKYwtTxxyvzAiSt24sCRZ9emKswaiAzxAgcsWlYdR9jh1laD6f9xaZqh3fjy/jTqMheeIH0yQDHkWSTp4cyYV25LnaI9jWSZCcpqIsE3ienZ3F5eXlwZRfNhZfKj+sy9O7Q22S1545oWzT+WcOZEx7r3VY6g93nHAq0UGcxlj3ub6MwJFOiWu4FGiIFwJ9sm1+VgTBg+y1siIemdPGiybRyecFdt1uR0QsFotOvna75xNJee7IED8zoOc+pDUWY4sHLZyWcN+aTaGSPxFxEPw6L53PrfKqA6CquXUn1hWEnc8MMJ38n/70p9hut/Hjjz+miNwdKMEAhYlgQ4LJ+a2KOQIVbJuIbYwDyQaQWRd/VspIY0eHwHQfB5pzhRcXF/Hu3bv47bff4urqKk5PT3vf/pAx5cE6TO86MtezvlpXfePRxqSF/VMdUlApsn8Ui9EO+eLj3xozRhl63+XPDQ774mMhsOUpTrWXlSpK4TsZeHZadc3TtJRb/a3UvYCcvl7Kg5e0hfbp6akzkjLS0g3qtr6XIiO/2Wy6rXAE4HJG1Pfj4+PuuyWqV/JxdXXVZb90ginBp8rT01P3BdeIiJOTk25xHHmszJU7YLcX1fhlPM/GhO9VQJCFMqNpFumA7zpiwJDR7O28Fgy53FFXmO3ze7IrGmtlsggkdI/fD+F6E54O63rou1AIVJwHPOVRtJEO7vJQ4MLMtwNt1b/f7zud0TSF3+e0jMuRaKE8jh0PvU/bpt8+jeR+gIFZVXcm45W/YjDAvrfK4AFQTlBGAB0ZHTbve2Yiq5dHgWaoqkWfZ0F0TUpJp5EBEtWXOa+IwygmQ7IZb3Q/27Hgz7iBkqH3NQa+nU2p3c1mEzc3N52x+vz5c0+YCUYyHjpd3E5FhMp1F3K0VDRXILUrBX94eOhFHc4H0lbxNnMILDw90Q1ilrqrnHclD1nJwLH3ibQ7GPNCOeZ6A91j3TKayu4QeBA0cycAHa87NMqJQB+BZtZfrcnZ7/exWq06Xvv8KQGNZNznbZmJWK/XsV6vu0hRYJSAteI1wWy2vqIqLdniM5Ud4TXPCpHXDrZbIHnIJnJ89/vDE2Kz/hHcSX/puLRNWu3qWemv7KKCBE5niR72Uz+083pHQEOAkoGOshbq03K57PrCXR++BfTo6Kjb1ktaNR28XC7jzZs3sVqt4qeffuqydT6lk9lMXfdpzWxcquutwIg+jH6VOloV9yd8z/keMf7LoSqDH7mqjARLFpFSGCtDymcjnlHt999/3w22hIbts00Jk9YbaIU12/B2xzgCXqcSaX5VhSkgR4xOgzsL9YGoNXMi/J8GeLvdxnK57H60NuLDhw+xXC7j48ePvc+sql13nGxTPF2tVgfggNGv/ievFcGSXhkl/+AM04rZtMIQ2nW+ZPeoVFk6lu3ReOqav6PrY+kSb6vsnPPedSXLLrgxcLnxdQWiR7zW/7rmHznztpUN4Ep1Oj53ysxq6V32QXVx+oMAgNMb1EHRqakYRmL+sSvRUgFk18HMHhCI+HRmNo5eL69xPtrrUsbmNeCU0wvZuit+NIxrl5wHDLToILlAWudiaNpSWSfaZLUrMCD6ZZPv7+87IEueanzULtc5cN0N7Y4+5S274dNi7sD1vuRRQFlH9V9cXMRXX30Vi8Ui/vKXv3RH/Ot9/u3reNSu2hmSj1ZxWaRzV6GutWSX9JBW9y+UVYHMLNtTlUHg4KglQ0UUNnaWTobGo9WOUNC7d+/i6uoq3QGgumV8/vznP8dms4nvv/++S9u20i8VU2hcaajVPwp7xAvqvbm5aSJH0qzfDrIWi0X3vjts9kW80Dy0IsyTk5MOSf/666/dR0xYT8TLFwxZr89jRrws8KIQ8m8ZD9/HTUHVscQ+nUS6WgrX4qGeye7LYGQK1gImjDJo3Ct6WgrGMa7AYHbd05SkIXN6DmZb/CVvmCXyPjmo4ZcNqdOkVQB+Op12ztDrJljkmR7OMwdABGEETFx/xf4x65i1ofczQ+v1VgFIxtOW08+AX1Y/QasX0ZYB7oiXnVhyvs5D2pfK+VQ6R3urTJGD0YjonH41NZv1VVnITB88EtbzBJwqzEjQhvO52WzWfaPlj3/8Y5yfn8e///u/x8ePHzv5FTiiXBB8Z/7I7ST7UPEge1Z1tQr9hv4WDzNw4TaD9kTtOS+HyuDiSG+YxYW/ZRCFkCvwEPGy+2K323WL+jj47gB43j0RYcThEc5OV9YnRZ5SEj0zm83iw4cP8enTp1iv151hu729Paibxr5yNB4BqnBeWHVkqSrtkJhMJrFerzsn/enTp7i6uuqcuiI0GnjRwYV/OnmPOyjEQ6ZYNQ6kT6e/iTZGMBpTd8IOzPz/yklnmZwxJXMcnpp3J832fJyG2uKzDl55T7x1HujZDGhRrqQDXMio+3L2qlvPybj4WBA4yjlk2Tv9zRQnv5BJOXUecs0I+c3oUXVni1y9DuqR+qJ6KK9Os/fH9V11jSkOsmgPfCzVDiNZ5+sQ+MgcrPorMKYvT3rJQDfp5+fQdc+zhKyDAIT6rzVMmnpW8emv/X7fOyfCARh30Mjm+QJb9csBoTv9iOdFkaenp/Hu3bv4+uuv4/j4OP7jP/6j++5ONlaUMdnNCvT5+6QvAwj+d1an6K+AJLO3st2UeQeD1PXKd7UCOpXBxZGOkjPlygYxUwDeY30qXJNA4isUrAVUf/3rXw9QePUOS0afG7b9/nmHA1d0sw9VX3St4o07Fxq5SiAZ5emaMg/b7bY7DtqLI0kJF+urIgQ5kEw5vR9aKKf2BFycpsnk5XPM5GFVxhrxzPlWSuuI3Ouo2m7dG9MP1u/Pu2Nz8MmzLvScpvWkO3TAkmcZXM/+VdNF+mw6F8eKdk/lcoHskFHVjg/u4skCid1u10XP6rf6oVMGnZ/ihXjDDAnXh7jccvqA99wGVOM1NJXhvOB2ZfadWcGh0gLOml5wu81SybifteDramRvlPIXuKNcqV49o77pt8aDwJZr0NS++MqgxDMl6qPkMAvWBKim02mcnJzE27dv45tvvolffvklvv/++7i9ve3kje/6Sb9ss1oLkAFSLxnIfE1xEMDgLQP40l++Kxo4JcT7Y+gaPVXhhLcUxRlNxfTVwxlwoMFzI8p2OddEZOlzXa3+kF5GSBTkx8fHuLy8HG0cKv6wfo/ElJLzdHkWGfC6eKSzIGi8M8WnY1fhmHikRiWWA1KdzDxk9fv4sz3Smc3ZDvHZFUhtcaV19q6e87ldFRpA3ePitgwQk55M+Uiz86IFRLx4al79FPCTAc+2lKkvHqHLeGvNg+ibTqe9NQ6iPZs2yeiiHEe86CgXbrpu89PvmotmMEEjqHFxMM5nRCd3dmS8d+Pp4y8a/b0sc9ACmq7LfP61TsTl8PHxsXcGQauwX9QTjq2uC/xLrvSug6+Il++b6H3pY0T/LBwtnN1utz3g4NMQ/O6FdFB+QdMmk8nLCcMR0X18jc/Sl5yfn8dsNovff/+9kymteRBIYZZ0v9/H7e3twaLLTG8rvlPOCIazcfTAYsxYRvR3tjBb56CVIE8/WSZzyBYN7qpgBf4FuqojRPtEjvybhQqYKT5/829GaDKcnNvPGFApOgVXz3lkk72XAZqq+GBxflpRo3irKRg6WNXhQu4LlsQbnyagY6dDpxPI+OX81nMOQBwIOq+Gnskcq0qW/apArAMs0k9g+hrjncmf0+rOdEw0mhkjH4usbf3N/fHMOtD4V0Xjx49kiTcZsCNdGR9ZqD8Eat4nd0Cz2SzevHkT+/0+Pn/+3AMKqotG3GlittLBwFBE72NBJ8nxGWPQq+I8qBzQkD3J2q/eq+rieEe8ZJD0d8SLbBA8Ou3iuWya2qOd199axC4d8W9LZDZFNBBkEPQKZMjeZR/g2++fM8fX19fx5s2bODs7i4joonXRMp/P4/z8PFarVUfT3/72t/jtt98OMtqVDLT4TQDPqcDMjniQlMmwA/mI4a9f0teSJm+vVQaBAzvAA3uqyt0J0SCxQ+wwjQrfcSXLhEq/uSdZxnQMjXqfQq9tZXQ4FBJfn5BFEqQxcwAycvq92Wy6BYlM08oZ6H1OM2gu8eLiIq6urg4URdseHbBwLFmoQFI09p988rHkolQ5L6bDqezMYmQRGf/2PmX/OwDKSpUK9rH01HlrPpo0UIY9IsscUiabTF9nDsVpoIHW//P5PN6+fRuLxSJ++OGHDgDwIDT/7QslVY9kkzS4PJM2RucEA+SNO3NlNfSpZgJe/hBAaCzppMgXH2fJZov3fJ8//mzl7F9TMh5mwdKY4g6DRxK3HAHbYxRP2hz4Utd0j6DDp15II79+rEif6XXxwaexqFuUUy645nSarpEG+oeff/45ZrNZ/PGPf4yrq6u4vb3tdqbd3NzEw8NDF7yJDk6PVbyv+Fy941M7rh/sh7dFAEU+834WgPs4Vm2NKaO3Y0b00yHsLIuENyIXPP52oVFhNEPh8rka0ikUq/s+58NnszpEw/n5eVxcXMSPP/7Yi5jc0dGoZY4k448rnt5nCnC1WsW7d+9it9vF5eVlb5GaeCBgMZ/P4/T0NO7v72Oz2XR1MNXnWyS56pr9Yv+kqDzKWIKqNRWathBA0PHUiloYqdHA82uCDu48svVSgYMKXNCREwA4kOXivAp8uMxmbTsg9bSgxs/fr+TU6854cnR0FKenp11/3r9/H8fHx/HDDz/0Frly8Zzo2m63PQCrMVXqVtc15tz2pnFnvSoEAaJZUaPbBoFITkf8/vvvPfkSP6TjmtKoFnF51iED7gSblKtsnRTBSjaG/z9LZvtcVnynTVZH5vDYLw+W2BaBf0Yb+cnAh8FEpk8EJPrfD7HTO/qbcuCZJhaBjuvr6/jrX/8aP/30U2cLLy8vO/niAVbiAafwnN7XAscsg9wqbssyWXY5F88r+5EFYN7WkIyP2lWhyjJ044PkApUpbpZ21m9nbCZYLJwz0rNKOXldFU1sV8LjC70IGihUlfBkSlUJieakjo6O4u3bt12aTHNr3G2iutT+zc1Nt0hU0Yb3U05A70iBHRgqCpCi0Ck4D7itczKZdEZeCzQFIHe7XXfE9P39fe8DL66INM6VclHIaTSzZ1iqOXH2xfuoZzwLkYFPyUQGpJ3P3i+niQd+jWlbx4h/++23ERHx3XffdbITEd1UFlPKAgoEbwSecv665scEizZ3EBp3jQvnyrPV3PpbCzKpW/t9/8RVygfHzwGKH5DmMpaBMvK2kj2uA2mV1lhnz2b2rvV8Boiogz6VXIEnp439Z/bV7T6/W6Mx13d1fIElHX7EC3gQQOUOEI59RHT98XFhZln+5vj4OBaLRSfTPg3A4OHx8bE3pc2tl3om2wHogUcV4LSut+77WHjWxoMSPccf2qwWgK78t+r2vnsZ9XVMb2yoOAomo90BZkSzHr9X0cDUjFLndLgZCmPf9J5OSePAZdkLZlMy8JIhxQqw0DnxgBsZ26q/OmDFHR0LQZHQtKI/KglpVtHKaPJC9dzf38dqteqcA89rYJQ6nU7j9PS0S31fXl520zK+gIcCnxn2bLy8tMAcAZe3q355ew4OKoeTgeVKvl3Z3QGTTndiLj/r9TqOjo7izZs3cXR0FP/93//dyXAlO0oHS3YptwIYdOSiKQOmynzpwDCd8peBEqbQVS/PHiBIEBCOiF42rcVb9c0doI+dO0r2h7we4yiGxj0DN+p7y562nEtl9MUv8WDIqVHmsqksjQu/ccJ+cZpPQcZ+v+99r4bZS+1u0DZN2QkCVNbLjCD7pTFlACQ7RJ3iZ+Epu7Jfolt9ltz61ISPZ0v+WqUF3qpnI3IwSXmspvArWXXf9CVl+DNYfDiZf20VV6rK+apwUJiqdIZpgD0NTwctheDah9bAUWFoLLN33Phlfcv6yv76NI5Ai85hkGLR0Yn/9/f3vY8WqT2mjwUICITIG6eV90UPD5GhQmsekCk8onqCIi2GEv1alESekIeVcdZ1ouFMgT1dyTFy8Kt7cpYOBMgrN2rZGFd9cLpVJNs04OxntlvBnZgc7vHxcXz//fdxd3fX01PWo7YkJ5Rxl3XSrLH0Z6WDs9ksTk5OuikO1x2OjZzH09NT3N/f9+ST8q7PHC8Wi+5wNE4pERAwHe4G38ebhTRSN9VvAmGBLV3n2LWK6pRj1bHZmV3L3s1sbWV/b29vD86WGQIP6q9opG4RNBDEOY9lu25vb3v1ERBERHe2w9HRUXz99dfxpz/9Kb7++usuqJA8iTdq5+zsrPsGi4IUOX/vl87c+eqrr2IymRx8mlt06Sht7phQm5THzL4PjXsW6Hypg87qU1+z/0lr1u6QzPnalaqMzjhkxKpxJ9odeEXodDrtjIL2HrMt37frBo5KqU7rus/xZQaEBtiNDI22OxLPXHh9WZt+L+vP09NTfPz4sYsiqzUAAhZcFDSZPH8KnNflFPWlOX9efVf2Yr1edydQesqRfBCtd3d3XYS5XC57C6S4yOny8rL7nDf5kKHljF/ON4ITR8+MSEQPox8+z3FU35xHvJ9NpTiYYF0txO/RM+vl4rDWfLCmlR4fH+Pnn3+OyeR5OsinXvi1y8Vi0ZO/rPjpf962ym73vIdcRxFzh8dk0l+LILAgYME1Nuo7HTafZyYi03+V6XR68N0Lfy4DXpWh9bZcV/lcNt5+f7FYxPHxcQfumC6v3qnq9HvV2hnvr9/Psl1uvyVrOnyJZzRE9Kd/tP5FckwdVH81lSzAoBNmlfkQTZwukW5Knimb6hcBccQzUNlsNgcLBT0oeHp6isVi0QMK9DtuO9z2/zOgYKgO8p3TL5UtaTn8zM/5/6p/qAweACWG+Xa/ijD/v0XEfv/yIZaqM/zN6IDX5Cj4FTo915pjJh0qdEr62yNBFy5GKm6UMufB6QIpBAVAKTZ++Y+OjfVoO5E+cuWfqo54Qf40dj7tI0XcbDbprhT2X/Qqejg6OortdtubB2fb19fXsd/v4+TkpFN8piNd2NnnbJEPeS5l8GkiBwR+jW3SsPiivqxNXeNYVs7M++VGK+LwoKeqH2xX98R7fjjMwTYBp/rmMsyiTJHqcKNLgCgnKCeQ6etk8jz/LuegI6ndcXO8t9ttbwsfp9McaPF6tgW1AvQO3NyR8lmNXzbd6U6mkhM5sdPT065f3PGR0e00sziPCcCqOsh3Bw0s7sAZyLiDVXsO6PWsrvmaG4FCfusim1unrfMsJ/lyd3cXy+Wyy+roUwB8zu2e2wmXkwo0OGj5f13U9mw2i7Ozs7i5uUmnoLL2RTPpF70C8xwX+gqOZasMZhyI/tm4p3EyNFt1jMUVvfW8DyqNPJkjYc8izCFEpmdptNknonKPZtVeZbz0W3VxTo5tEiAxco84XOFNXuh5KjPTj5w/Z5qP/NI7XH/AeiNeTlXztL33hWs/rq+vu4Nasq1YGYomj52XbpRoOH2c3bg66KPiVE6VfxPhe3FH6IaQDs6NWuWw+B4LFztq/BkJ8l0Za0Zg/OyxPy9nzamBDMwLbGqtTQaIaCs0NZE5CI2ZMilaN6F69AlkZbpcJ8csXPRCh8K23Oj6GBHcZsAks4HKhGgOPTvSu7J/3saQvR0DZClTtGVy4r57RXagmvq7u7vrgIC3TcB5d3cXHz9+7LYN+64ctaF2JLuelVbxAC8iYrvddlOkruvSB2ZVaS98bP9/gQUvshOPj4/x7bffdt9iymwPxzGjU33WAWyXl5eDbbdKEzgoOvAU7XT6vIr26emp+1aCM9hTsapPKdCIl+OM3ZA78bpGRE2HQXr1PNGZoykKvUcUvE8D78Yjez+bD+M9HwwarSxao6BLuB3EkQdVJsaL5inZPsEQHbscAo16pUgEL4xY3JnJMGVjyPoyXtJZOnDh3KjzluPj/CcI8fHKpiEyUMn7Gqvsy41ZHZIzKr3q8IW5GcjgDiKBAb6neshTZoR4fTJ5Pt3RnbDGVOOpZwk+PAol4OViR40H5c3XmKhPomO1WsVXX30Vy+UyPn361FsrociSdfu4DBXxhLbMp7KYaWH9tBWZDkoGd7tdl3KmTrksVZkpBwickqyAbIsXni2rsntaJ0AHS/vDKSitP1B92Tod7WrYbDZxcnLSAURf8yN+KmPJKbysL7vdLj59+hQ3NzcREZ1vchvtgQun9vRMxTP2/f9VqcC7aNntdnF2dtaTN/dHfI8y68GI1qEwG58FMP8UcFDxtQYREX/+859jv9/Hf/3Xf/WIpgA7QbqmnQM6JtnTRyo+gIwKI15SzDR6KnTGfiY3GVehbtKboXiPOvSbGYisT5UzoiOkAPuOBw40VwpXbbENz1K0io8l07Q+pt4XRiyZkhPUVQ7a+zxEo4+lKxPHzP92h+B9ceDb4lmmdNXZAGzD0+DqkztgNwSqy3ckZKArA5KSMT0vGjiHzH6IVmaTeGDTarWKiOhltGT8BDQcsHnER+Oue1pQKLk6OjqK8/PzOD4+jr///e+dYyHQd54PybxHa8zuufx73dn4UB5a4NGf57ZoD6yyktmGrLhtpk3IZHS323W7a6izDkJVD3fi6D5lTm1KXh8fH7sUfMYjyQEdXHV+B52kpnppV1y+mWHVOBOcZFOWPo3VKmOf8z7oXfbp5uYm/vM//zPNzme+j3WxPum6QBN9YFVPVQYPgGIH9PfT01P8/e9/P2ikiqoduWt7Fa/ToNMhZE7bi7fr9Kq4kvJ99cv7SUfhQkhavzTSodOTQRaN3L6m9QQy0lJIffVQRjNzFjJ63F6V8ZEGQe9l6VTv42v663zT+5nsaPyzdDGf8eucmvHo1h2DO+LJpD/V5FF0VjIQyv6qPvHfMws0qDTOi8Wiy/i4PGcAQn+zz1l/fRss36WM+Mp/9oeAVvPVMsBa/Z7Jo2cu3Q6I3x5Fb7fb+Mc//tHrC7eUuv56G86LTJ6dzxn/KuPqdRMwcAqkeo9/i26/xvoFEHXNZT/iZUqZ2SPvl8tKJkuyC8yc6L47ZOoJM4CUOQcvtDu+Vsnp5ceoaLdFH5/1RdLsl8Cx6Ga2yAOsscBTxfsn2rKxzt7jfepCVsR/8pD1eZsaD+lMS95bZRRwcKSt9JErW1VIUIZs+dsNPAfR66Jykl79T7Sq+46W+Z73nYPOtj3zQQVoTVe4UZfAcoEZ2+BHfnzFMPuqhWnr9brXlkcJjAyHvjeicWC2Ru9m22CzQ4uUxiZy5xSFf6WzKu6QWwAj4vDrfr6VMKtfv7MMz5B8qHjkrGstB5bpkOrg1rcMmCgyVeEJpKKR/dZ1GUzfOcP6soyZ8zObMlIqPlu/s9/3j752Z0be8jftjv7XNEbEy+FRVeDiIKvloP2daoxaJbNLVV+rwq3Q3p8x13gvk9NMRjRlxGt6nlmjrF7x0t9hmyo+nrqmcWVdlFPSS5oqe+x95jNOs2RTmbKsji8p1D233UPvtfwTSzZ9lo2P86daDzGmDE5VtBBv6/lMgSP6K9i9bk9raXU/hYlz/G4UvF39naV4WoPozK8iNAoFF2M6cnX0GJF/74LpUKVnmSqVw5Yzp+PVQTq8xm1T5DtTc3xWjl5RrvZO09nvdrveimgpr5TOQSIVhmOsZ1S3894VPLuue0xrcwlnjO0AACAASURBVEsg5codgfOe7YjGzOFkBo19VJ00SAQ0vnAsczCeKamA0snJSbe98vj4OC4vLw8Or5lOn7fKEhBEvHxsSDIiPgq8MtsgHfRokB9bo276Vmg9q2dEv84i8X7LiGtcxUfXQwFqnsPBujgGldPLUtI+PuxHZnN4n+96XdX/vC7nSUedve+OXf+zn1Vm0enN6CIwjOgDSY5TZv9YVwY++ZzkQDLoOwd8qoLtclw9mHE6RYtv74142VFWHXSV2R/aA/qibJykV/v9y+LgoTIWtJCeMbJC+8R3HCQPlcHFkWqkUoqqMxWAIDioUKGuMzVGhfJCh5mlV5kJcDrZXobQKgPhzCb9HCQa6gzg0FhIgXiPfeP3AsQb7pOXERVtVAy9o3MeSK/mG8l3LYjSORsR/U/B+jju9/tuy52K0t3L5bJTmqenp1gul+n23gocZOPAZykT2Rn9/mzmjHVfDkv8cQNJPuoZNxouH9l1z7AQwPnzmWNTX25vb7tx0rZcHeutjNXT01N3jTKhEx+ZcRAApPzQoGjs6ZTp0GX4nS+cQyYftUfd6xYt3l8HcgTjlX7RwFMGMn3nO74mhH2q5If1MPuY2cRMpisn5M+xCCyzDNlptsNsJmVOwI32gc7aF+QSbCwWi4PsE/VLOyk8w0e98LZ9LQLBMEEmnxeAZH+5OH8ymXQ2juC1xUtOsVV+ju8+Pj72pliyZ3hvLGigDmSOn9eq+jNZq+SbpQkcsnkTVex/eyo1myeisGXoxhXfDQVLNWASakb0ROO6xgjcSwUkWF82KO6wda0CLW54pQxuoFxZ9T6F3SMnPcu9+zSyig7Vrp7zlfNSQF90RkOh69y6K+Xyj9TwJDcXWip5Juhu3Cvh5jMOFCqjrXZ1YmFEdNsXI6Jbc6DTEW9vbw8O8HHaXBZkyEgX+07DnfXNHZBOv9P7NNy+4JF1CIzO5/POMNMQ0/mLbv1WZkoypzHWs8wguTMQ/UwHEzzo2fl83tGk59z5qw7PzHC8yS/2RfO74qP30//m+LYMvPfb10zxntuYyuhndi+zef5MRp8/4wGh80W2yTO8otfXRLmNpVwQjOgwuN1u18mv3vF1ClzHwUCHi3JFpzJQ3L7J7KGeVQAjfVedoplTfi5LFb/dJ7rOcRo5G6usuL11EMpx4vUxINVtKZ8dAg0RIz6r7XMzFdKez+fdoigpNQWxRUx1n3PT3p7e4293tD4d4MjTEWM2UKy/osHr8fcqJyFlU/psu912J/G5Y6YCSJk87e3zzZPJ5GDXin57liHiZSU8p0g8ktG4kL+q1/nElcvklUfVlQBnJcsYtJSkkp2MbvH57OwsLi4u4uPHj51hE3D45ptvYrFYxP/8z/9ERO1gMpnJnIFHv5kRqupn5EMZ0/2Hh4duKkOATe3IuHIPvbJeykpRnpyuxWLRGWCBCdKTLUxjBEhnxKkmyrL6IhAswENgyuLTYryuPsjJZOPG9micxWuWym6wHk6zVCCD/2fyoTHwMc763+JB1jZliO+SB4+PjwffmKh25/Brpg78aM/2+32XAVsul3F8fBxXV1e9IIP8EeCQrOlwMMkZ7aFojXj5SiunawmG2JbeUb26zynYoeBDJduF2BoLAl6WzLk7eHM5zPg31H5le1pl1FSFKs0Mu64vFov4P//n/8QPP/zQ+yS1olgNGN8n4yUYvJ8xSO9x3tgVmwrPd31lrzsYb4PFGepzfrqWRQ5efGDl4PU8j4hmGpF1UjF9UZv6KmXfbDYxn8+760qbkb8y5pqDkwJ626rj7u6ut4ffhU88uL297VKOAhwe7fA9L+QxnR7HxBW1BRyqQiN0f39/8BEu8fPs7Cx+//339LhgV2I5PBVGzASxLBVQYL1sS9d9HYnXk60lEX0yWqrD9ZD8ieh/TVCH8tzd3fXkilNuqjvbZeFAQW0x3Sw5kwPwbxSwLjpOBwzOL9qQjN+tkgHXLEhinyn3bJOgIeMNHTxtF0FJBmDGyj4BFYuDUeqbdMXBkf7WlFnEob7qc+5cUyNZdMCocWJGg+Blv9/3sgV6jtMc5IvsnMu8AGxEdIeLSU/dQTtoy0Cg2iJ/s0Jb0Rofr5tgw/2OB7EOBt2PDwGhrDSBA1NNqpiNkBCdBnZ9fd0Z8swAkUB2NItg+TcZIkYp6nHFZz1Mwaq4o8+ABIvTn0W9mRPLokcJNa+LPl9xLiVxHuh91cF5OTo7KRTn6isj52k/0SUZcIPF9RbiJcEL+alIxTMiLR57yYwmFydmdQwpK2VYzz8+PsbV1VX3sTHxdbfbxc3NTXz33XexXq8PIngHsz51lzkV/p8BtFYfvL80djTU2Yp0H19vx9P/uubgVGCA+kA5UB3qVxaJEZSpHB0dxXq97h3Lri/Bkq9jFz1nxtNLlTlyPuv/DPDxOvWN41yNf8YX8r6yjSxDmYasfwQHopXBR0R/d5SuM6OkoI9beEkjswUR0WWqJpNJd5qswAblRWOvOrhegv3l4ka9R9vpwIYOnbbRg5r9/uUAPJYWEFB7Y3hPOrL3XYb9euX4HRxkQCazf97HVmkCh9VqFdvttrcwxufS1cBms4nvvvuuR5gbQ0c9ZF6LaKI8GnJ+Wc+fp7Hgdf7mu9nioszpcx4+Eyj2mcaUxjjiJfqUM6UhzIyPHxHt/aUj8/SjC2jmoPQsx0QAwSMPXxgp5RM4oAFzB6r2I14AExc0urOlrHibTjvraAl+hsrdCZNOvaOz8rlAlXLGemVQs1Q/wQb7XE39ZM5Gskhwz8iMfVPWj/LlK8j5rK7511FFI8eU9UoOPCKTMfdPwPNZOgSeVqo0saJMTq+RZzT2AjTkvesAnWYFPKuSGegMkItur9cds9fFqRyVMaAyoycDIl5ke/zZ6fT5aHpm4ByYqb8aK60BUv+YSaZz1vvUfS5w1C4cHuakNrx9yYYfKEiAwz5yp0Y2JUsf5RmLbEpQY+YyX40NAeFQceDp98gbFQ9gPLPGuqrsyZAuNIGD7yXOjGxWKmTvjlhEC1l6W97BDB2zHl5XIdjJno94QbMtWl1AHK2zrcop+SC64aMj8m1JGYp0gEY6Mt6Td+J5JtA0pNn0Att3R0ZDQkfjY+MONxtzFp+aojNQ8SmxoeJy4o42+9x2Vjd5UrXtCpkZDX/GeeFyRUNIOjIDJaOsTzvf3t527zpg1XHybMezdnpntVod7BiiPFI+tOhRAEPj7zxTJsT7w332zjfpDk9apKw5mMyyKq8trnuZ48japUzpGZYW6M1AMXnsdimT8awdl3Hqu46R9jVnBGq6puOjRQenFPQcd1XRJshWzGazWC6X3dSpAhLR0Wqfu8qcb6SJJ5iqXYJNl3mNtfsKH48M7DuP+b8789bYV8EH63B+ZNlPFQ9oX6MHTeCgiN6BQOY0yPwMhdNRZXVkyuA7H1qDobr4w8hfjPKohYaxisQzUJLRWym00zGZTHqG0e/TAdIBU5nZfxp5jlU2NeAREMFHxlc9Ixq5RY791SIkTpt4vZQhgqMsgzUkxFQYyRYzY5kiVEpJEKJ6/cTGqlCOHYzyvuqu5KSieawDEN1Z5OG0kj4HDTKe2RQGDwNTO4wwKbN0ppxS8rUjTh8XpdExTyaTbutoZqw921UZTge1mTGu+OxF9sRlr7IRupbVm8kIdTqry+1H9T6fr/rkcqo63cF6ds1lgbrEjJt0XdkBtyOSOy1O/vDhQ/zyyy+97dHT6cshecz68n0HThxjjn9ml+S/OA3jmTpfmNvyX7LzasMzG/5uZZ/oN6p7orcKIjI5f+3UFsvgAVAtoiP681+cO42InhHwuionHfHSSY/esymCDFiQMbymqCtTsiyNU9GX0ZoVOnF36gQr2YBrNTx5IINOJ8f5Q62KlwJmkZvapnH3FfREwm74+RyVj5kJ8oWggHVm40+DlE1h+XM+BqJVfHHZpVwQ6Pr4ZbLA96tSpf28ZKvSM160ypfIpgz3zc1NBwKrdmhAORacD64cUWYMqce675ktN2jUdcqLAKrWddA5ZdOj7iR8eqYqFYhT8WBJfVL7kkEPplwuMzr8XgVu9IzrU2a3HYywH6zbnasHKhHRy+xIFrIAhD7BI3W2T1lbLBZxenraZfx8ysmDJ/avcsYZH7KivvvW1JaMe/G2ZrNZnJycxO3tbQocMnuW0UUZyPqT+a4MHLt9HZLzrAxux8yElhVrTilbFMP3OA/r95xp7BwdQisdz7YlzK0o2iMn1pE5Ja+HypLVR5Dgjli8kpFRek/bMieTl28VPDw8dAZSwCDiRRGPjo66LU005kK3RPJOJ/urNiKid2ofVzCTD1IsjqfSj/qf26OIuLMT7TIwlzluKpoDSE/Z8W/xgOlW0p85Nq4haDkYyhnllv3hPfIy6xOj5Ky4ofD3Ob4Ee9p6udu9LBzLpglcPukYlbHKeKj3NRbuvJk1o67wq5neLwcXbMv/Vp/4TouPfDYz3NV70s+ISD9ElUW5/ttlxG3EGONNHlYgPLORrh9a1Ej5iTg86ZS2zIMyjluWYVXQ4wsWfSz0s16vu63QdIJZ1O6Bl2jIAK+eYV84zaVnM+DF6dKM55mNEK8Y0GTr6bJCHvnUNu2EBywtwKN+uN7yWQchWRmdcfC/ferBBY6NZwKi5yonwTYzpfDsgzMrm5OlARR9PKKYay1adFXXOajeToYGicD3+5djdulkCbgk3HLIEsLdbtfbv+x06kcGztcCCLyId/pmuzIRnKcUDeS/81v9kpNhhoIGytcrOM9ED3mma7zvSpJlK7ig0ce3AsjZFArb8UJHRblsFbavwtR6qw6BS9GuraSkUVveJDMR0R0ZzuNvJ5NJJ1P64Tyzdsaw7zp9kovhuH5BWQFmwNgnHo+uMeGzzFz6Z9i540dj6iAhG7MMIPB/H9usPrXvYNmfowPK6nSaWjJfFZcdd+ZDbau4MxZ/M2Ct/3WN62ci+mvj+IzeVZZa91xuNptN/PLLL73zRCQb3Iau92kPdZ32ngBB+iDw7PbDA6VsDFSn+zG/r7+1cD1b25LVX4E91t2yVw7OaXOzbDFLltXPyqjPaqu4oVVD3GrDVDafySIRMoF1M4XMrYetNQiZ01GEQoflaNKRMvvkaR5PYXu6xxE7eeDo1iMMR6V8l226sxYIIFqn4aJB1RhkqVvd1+I5XZMxyACVR9qkk9fIe0bxrLdCuxlgaKFrHwffusqxahlZjY/Pqfu7VeH7DgT83TEgQ3xiP2XYdU/jzzGWEX18fIy7u7uOfk7buaOT/K/X655xpk6oTzLknBPPxpJ9zsZbQIKAlXw7Ojrqsm+kgXPQPv7OZx5vXfGfxrUaZzkdrsHiuxwnOjnqje6RXqdHJZOXDDjrXuUUxhTVLWfstl52SjKi61yzQNnSrhg5T55WKl5qfAVS9fVkAhf6Br7nfqLyBaJd77AflHG9K4dLfXdZ9mw1C0FsZkf4XqX3lEvPKpAnGZgbCs4rey263759m9Kk8irgQELp+LyT/tsjfabFfUCcGbqeIVe2z/fdkbBkDoOgxsEC6/CPo6itjA+kib9dsGls1ut197GqTFA4teGgyr81QUOrKQe+4zQKNAi5uxAy+nNF8n4T+OjkOY6N+Oxbzly43VE6cPPSMqhOJ3nv1/U/77lD8GeHSiUXLdBQ1csoW7sj7u/vu4+S8XshdMg07so6SD/9eUYv1RSBMhHij7bE6eRT9tPXnuhUPx75K5l7eno+fdY/3CbHwQDCAxbPLLFk3zFxXld2p3qHDtRLltKmfXMaKwDbAhJuz9Su28GKftcXjjO3u3Odmo4cJzASKNU4chGk1ssoY7DZbHq7KpQFoJ2iXaUT1FkeDFB9Cky2QjLEZ5iV88wCM3K00aI981Nuw/TM0dFRvH37NtbrdQ+AV/ru/sHlkHS2xpR2VjJG+8Uxzup4eno+IPD9+/dp/SqjpirYWXcYrowisJoHIsHOHCJKTynzGRVOifjgSSD9mqczeT+b8/E2aSTGLnTJUKvoo3A+PT2fyKh1Dor8SZ+2pOl0yel02ksxE5iIvvV63TsJcj6f94AJlU3RFI2aL3xU9KqIQAqUOVRFiB51O6+ztK7zy98n/UOOWWPgspRNT3kZciCkOwMinIMdU2dlHJw+AUON03a7jdPT095CtCz6pDOv2nAj5VvxSKdAAz9cxLlcz4JJlpXSphwzIyC53u12nWPSe6qLfXJb5cWBhJ7LAhA+7w5VQN1LBva9Xp+u8TH1911mW3X7e9U72RjSyeg6o3mNg85q8DGV49WuGTnpbLpD60JIC4NJ2iN+hVfXFIzQ/gu0iGaea5PZHMqm2mRwRT1wn7FYLDob/fj4mH7xkjLEMfSgzMeh+k3ZzpYCZPLv0xSuv1XZ7Xbxt7/9rfnM4OJINyAiiMwkExgdZO+zOFrWIPIksMzpOo16r0L+WfsVIHFw4SDI0RyNjt6jwKqdDLBQ4NmWGzIZ4slk0lvgpjnkiIjT09ODb09o33xE/zsUWQpS6UMa6IjnffpK64nm/X7fnRev8VI/6ISlWAJJnP5wfmT8cl75WGbj6QqXjQ/r8tXhrJvySXCX0cVSGRFXbBlngsMKdI41NhkAY5bIU73MQqgON6rkifNTgEF/V9ux9S7tgvSnAhkEFzR+GQ9YN3lQOXIC4UyOXAYo05Vtq9qS7PCTztlHvLxflZFv9Ul8GypON3ebkW5tt6XzpRMn4NA1TpnSDpAutx339/e9TCXlyadXfYwYrArkih+yndlBXLwf8bKlvFrAqPcXi0U3reLgV3Q8PT3F5eVlbzGx+EcfynHLiuvNULDB91SqrKo/r/tcelCVJnDwrTBURo9WKic8VFjvbDaLP/zhD7HZbOLq6iqdG3fkJSTsjjyjwR1/5shlINi/DGTox7MaEf1V1ZzjrAwBdygwyudx00ohSZkJMKbTaffNANIgZ03anBYqHx2D+D2dTg92S/BrhhHRRSG6786JaF73xbdq+oFjld0nPXqOBsMLU+9uYDMZZxEfNEXEtr1UgJSFKUM3iKyXsuryIborvSQAk3wQgO73+wPQoOvaBuf3+UEstU8HXAEclwFG3Q6cBBaenp6644j9UCe96+PcmsqqQFd1rxrnakxZh4+T+jWfz7sdUJeXlweHWbXsZSX/2TNZPW7zKCMRL9NffFfjsFwuD3ZlsV4GPJxmpVP2gEjBC+2310vQkEXODBjZvk67dL468BNdzIp4pjwDlfqUvQeVpL+apiIPMjvlwQXfo55Uzl+6lQGlIRkaY29VBjMOXhi50GhXRmOoZIjdEQ8Fkf87kzPD7wgvS7mqCClWoEL1OZpWYQThWQdfwKXn6UhlRHmfPNV9Bw2kR/1QO75oiePExV0R0XP++u1ZDNVDxeWCNSL/iDgAe9w1Qt62gB7/12/9zXR2hpIJFtiGI/Isbc9nKefenypiyCIEN3psw40Mf1d1zmazXlZH/6tfKtlUSdZfyZMveCa4pUPQoUzUG3dOKtxto377QUBsY71e92SWmTnvS/a/G+Cq6D4dfgZcW6CxMuT8fXR0FF999VWcnJzE9fX1wbOV0a5A9VBxeRqSJa9bIG69XvcAg9uJiJcFo5mT98JAT8e4UycIADU9QvvCqRPavLu7u0529H6WGafOZoEVZSALSr0f6ivtOdvL5DDjvd9zm8P7TrP048OHDzGdTuPq6irW63UPEGbg29sTT4ayVoNrHMYoXeaQM2ZlqRky4eHhIX788ceDurlyuqLLnYIroZhHA+rPaNBpSNxw0BG5weFAZ4LGe05XFi0xopNC0gjRSeuZDF1TsCkUet/5oveJqkk3FZIGPVtBLhTM8dzv9wfGQvR4P5wnAlPqx2TyvH1UX6usnLhHGwQf2Xw121f0wmwMafbiSuljWxnwypmLHjeo4p8WgHlKn/Vq66T6q2vMUGixon8iWzqoNggitLXNp0Oor3pnPp/3okg9Tx4q00FARJ65fjuYyMBmNr1Emc/edYCX0VGNk3jD/u/3zx8C/O2337psypBjzxwvr2X33Qm0QAb7JD7REXNK02027c5k8rKVV+tuIqJbS0VbGRG9KU3V61spyb8s00Y6VKfez7LAlBnqjNsg56Xq9KmFlj+qHHT2bFZ4n+1m9WkaRuOxXC7j8fEx3r59G3d3dwc+gvY1s0fHx8dxdnYW6/W6SeOojENlcNk5Oq/J5GXxEAcsM7I0HpPJ4SEvVfRCxXZ05k6Ljn4I6bEeRu58X3SrVIvMvK3MqBFBqy9KiZOfBA6qg1MWcsZOGx23BIw8IY8JKlSfA4dsXFrFZShTQt33cZED4jQK+c9FWP5BJq/TDTONDgER7zvgGnIaLC3HQn1idNTiocuNfns7vqOCPJBcHR8fx2KxSOfZBSp4cqnucyrIHTfbcfCq53l8sAqzavrR1BdlxvuejW1lZzLbUfFW1yijKpQvvsd2qSc+Zvf39/Hp06eDtL3X6f0YI2/sp8v/kI56oY7qGGn2nc5KdGps6eSp4+wDbV0GhiVrktWMFwSrBC/knwcyziv+dgft99hOVYcXD4CGisvo0NgRwOi5zWbTZRrcLzHY83b13NHRUZyfn/fsSFaawEFOhn+TgVzw4tEDHZ9SXkQ7bIMggJ2hI8sMBRVX7dPJMH3mgso2WDKDMOae+qLn/D0aU21VokN348jVyUobqw/sD5G2hIWRAx2eokPVQdRM3gm1TyaTbhpC/NQiL9bLvfwEWNyP71MZotnThqKbi7UI/MhPXaumGXwMKuCqfvnYOlhhcVnV81Xb/jeN2RAgoWy7cyY90+n0YKtz1lfJSZURY/FxIB9lbLM+iW9ZdiYzwk4v7UJGl0oGvNxWePaE8ijesX8Z71iv0+JOjfU4CGCQxeLvvsbhkA46HOdxRpff92fcuctuOBggj+gnuBZKdofZBb1DvnPcmRFjGxmY9ADJ+13xRH3kGSTHx8exXC7j7u6utz0z08FKVrjeoMqE8nnW6bKZjS0zdyoC/m6Lnccs7MfT01P88ssvg/SOOnJalTMdqQH1AdJ7QovsLMEEO+NIPhNICqMQLu+JuTSOFD5Ho6I3M+BEvRR2Ik8aG/3fYjb5QOM1mUx6x6uqLBaL7uQ+9nsymfTOPD86OoqTk5M4PT3taH56euq2bBIczOfzODk56e5TgbW4UrTOZrOYz+e9XRwEJT7dMpvNuohWfeRaCI5R66urjpBdtvgOSyYzlXGuDA//5srqIcc+5GSy952HXo8/mxk+6tjJyUmX/m7t/NDfWd88q+VBgK457c6XalG1AwHJhvSVYMHXwrScqdup6hm2F1EvinUa3a6NceqZka7ayehutTEECobeJ10ZyPDx8vMOsmwJi/iafXFYY+BjQWcX8ZLJYl0KQH3c/KCoxWLRHePvQK+aBnW7o8h7Pp93uyMqAJuN69HRUVxcXERExOXlZUS0d09UJRtr0snA5v7+vrepQM+MbUMlCyq8NIHDEIP9f6Z7JAiOfhxBsQ4aJL3D+vyLfRLilhOgYZKwUvgrAx0RvbUVGRJXXW6s3aC68VGh8fYtQL5TQXPUs9msW9UrNLvZbHrzhmo725kxmUy6LZYETtvttjdGnKfUeOm3fzVV6NzT1g5c9Jx2ZZC3qlv9ULZCaN/lJ1OmMYa05eR5nxkUtcmMTJbKzko19pVByBwTZVJtHh09Hwn95s2bjm/K/DioWywWXUQV8QICHSweHR11hzepDh41TX3VNj0BYMqdZElFWSqeGqhFlT5txYwWwbrAZkvPvPh12gK+r9++0DWzK84H/XZb5b8Juqr6q/60QHJWRwtEZPKvZ2h/mRGlo9f5COQTx0v1yBYoY6kFtTxPZjJ5Cc6YWVBbelay6+BV/dH6Ga2pEM339/cHGTj/do5kioGo7Ort7W2cnp72FhzTbjr/OH7a2n5+fh6r1apbMzAkq67/tI0OXPlb/cnOyCAQbsmA2uHvqjSBQxURefpWhFHYGP2Tqf5/xcgKYOhdoiJ3+HrW0aUjXP72PqrQeBExk7EUxAy56xlGMd5mpuhSQLUlkMCpiIwXHrlR2H3B2fHxcU+5iPDv7+87R545ZRlxOSs6nYjowIFoEwg4Pz/veJgpoOjkNQI/9t+LK5aPgfhS1cF3s7HKlM/Hn7R8Scl0w+s9Pj6Oi4uLOD4+juvr6+5ALu591/hHRG/Rmgz3fD7vPh+uesU/HsSkOW3KsBwF9XQ6nXY0ZE5SzkHywt0wlFd+ypkgRfvmW84v4yXH0sfP5dp/3OjKzvk74o364fJRRXFuuzKZG9M/r6/S2ex9ygnHMbOFWgDpdXC8OSXEhbSiizbItwhzXASEM38hueBOM331lXJLmdX7vjbC+6pnN5tNHB0dxWq1KjMYPj6kUwfvvX379iCIqt53vmb2xn1a9m5Gl9uQVj1Dtmv0rgo6Yp+jcmCQvU8k2eoA502J4DlgNDa676DB0Vlm1CtFqowMaXMHlSFGClFmILJUPHkpBZYR11RBBjy4RY51aCHcer0+mJuUQ1ZbLtg+LaH/ucbBAZQQL5XW6WRUTCDGcabyKxLNlLaFpjPn4PJWlQpYim/8W/yWgx3zHq9VBj6jVfzSeP32229xd3cXi8WiW9DofLy5uTn4RsNsNovVatWNmYqOA9ZY0XFHRCePu93z4WNKC6/X607W2A/JgE7Yo6zqmGHRq2c3m83BB7h0iir7zuIgxI8PJk0VIMt4N7R+xqPf6n4lc9kYV/WNMeqV3LrNoh1SpomZhKenp56zWy6X3XHiEf0gTNkrjsl6ve7ki7Q/PDykGSmdUcOsj5/HILqVWWBKfrPZHIBgZbhoZ3naqkCD5FC0cOpsvV7H2dnZwXkUmdxk4O/x8bHLxjLQqsYuk036DgeGmb2rSgY+Mj84JpM66lsVMvLz+TzevXsXnz9/7p2/TWLotH0eW9cqh+11ybGtVquY6DYG9QAAIABJREFUTCa9Q46qCJ7OiNdceSujnN2TclX9zRB/9r9o8IHhaXKeAvRdIUrhZQuAVGhYlb7yqRC9w736HDvyw+eZ9SGsyeRlvYVobAkyFUGRC0FSxUPV5WOejZ9nlHiPysds2pDCeXE5yaa9qvdcFiLGn/gnw6rnrq6uupS/VkEzvZsZCvHOjZ8c+Hw+jzdv3sR6ve4BDgI8FYEBRYaSSW3ppN4ow6GpLtXrxxdHvOxSorxut9vOaXlmz3koPmUGmnxg9sKnRP2wL45BxcPMCLdAA9/zsWE7reLtV/WyftfRo6Oj7qNGV1dXHQgg6BIwlPy1vvsR8fJdidVq1ZNzj9o1zgIlCkwi+lPFep92xrOsbof9yOvJ5OVcGtXB+j1ooX08Pz+Pm5ubDvTqXpXSJ/CU/a2CltY4075EHG5F9VkB3ats41BA4za/KqM/cqVBPzk5iY8fPx5U7IY5K45yMiPv0w8R0fuqnzvirG4OuD+XoW4HOD6QnFf2VGnlxNyR+znoKprz5VY18oBzVpz3833ubqBotMULrhFxerlGwoXT35GDUJTLxZrik/jCjxeR31RSN2xyJD6d4e+0DLuPjWTOp3kytO3ykY0p72f8zIx19kxVp/dHfDk/P4/379/H3//+9wOjSl7NZrM4OTnpRYLelhw0QeN8Po9//dd/jc1mE3/5y1/i5uamtxaBYyfnQMegOW2N+8XFRbcQ9/z8PCKeQYAyJZL9Sl/JAxlgf87HWPLLxbytQIHj5IDCbZQb8pYzcPnOnqmKy3cFpr0uPpfZSRWC1OPj43j79m0cHR1120WdtxEvhyzJGWeZQE5dUU4y0ELa3L478KvAWkS9mI916R0u9OT/KpR1/X91dRXv37/vplg1Pcjg2eVA/2sL7mw2S6crOG4Z7eRpJr+U/aou1VG9zzZbdbCMAg4i7O7uLv7yl7+UUR2FiYTICei3M5mCyf9pADiHWLXv9ekZRoZUmAytZfVSETnnT6VQn+mYMsdF5OcK6oLC1KHq9owEFc4XcvpiLVdm3dO48FAUjoEbSvGAX+n0Q1dUp8sCx8iVlHxipsUjaFeSStg5vlVWwB0B+zAGyfO6R3K8lhl+tt3KNrAPDw8P8fvvvx9M1bGPim7evXsXv/zyy0F9SvezfvF3vV7Hzz//HO/fv4+Tk5O4ublJ388MlmhgVHZ/fx8XFxdxdXUVDw8P3W6di4uLzkllPHGwQzkbmit2G5OtbaKTcjvg9sjpcHqzZ2gbxhbKciZ/rZLJYItmtzf7/b47Bpt2WkXBSjVetC1+JH2m+1nx82W4zVv3M54MyQVtbfY+6eOxAXrv/v4+Pn78GKvVKr766qs4OzuLk5OT+Omnn7o1Z85bFWVT3rx5E1dXVwe2qqIps3UegDhf3f6wZIH+mParMuoAKBLI+WlPlVAYM5RJ1KPBGVIuKqHey0pl0PnbjeUYx5Ipov4eYr7uyShnA8uUXxUB0cA5cqRB5JGvpNfHh2f/t/gzmfRTeQQE/Jvz2GxXxsblYL/f9w4YyRyg82yMrDjf6RBJF58haHF++Rh7yZzQWLAxdL+6fnt721sDpIwVeTOdTmO73cYPP/zQc8IEr+746QB+/PHHbguZZ8i4cM7PvtA10afFvPv982LL6+vrWK1WcXZ2FqvVKm5vb3vTj3Q8vigu4nDXlp7P5tH5dUQW0aZpsgqwVUCjNT6Zo26Nv49BC5R4PZlj8bqr+9JrLURVxufXX3/tAj/qbkR/y7tnumRz6PCzQKIKRnRN+sq1VVlgwbT/fv9yQBtpcHvJIEXZ2mz89b77g4eHh7i/v4/b29tuq+U333wTP/74Y29HGt9hHyKiW+je8mFuJ/0e+VnJbgWOsracXo3BUBm9HZPXKCxs1JnijplKkj3D4gNP4zxU3DBm19xJZv2tlE6KR0FmH7PiiwXZb19f4ClWp5Nbh1yR+Vz12xEs3yNdVHanW/1mRoBF17MMk69ncIXJxtiBKP+njPg7lVH2668FJDS6clQtRffC8XaeDBUaU0Vb4keWmZPseeZIdLoBnkwm3fYxORWuHbi4uIjz8/P46aefetmFbHy0rU3tCyxIzl0WxAsdT+2ghzx2nfKdMu586Ax4XoX6XtkF/5sH+3BM/CNgzt+szkwOs2f9/8yWZs/x/wxEiS83Nze9dR2TySROT0+7Z7XLyp0zecLpTuqllyxz4XZecsUt3twtxKJrkhkPZj0LLL0VSOIYUH4px6pLIP3m5iY+fPgQFxcXvd0f2TQWg7mxxe0u/3a7zfuVf6x8CenktSF7NAgcWKkiAV/d78aPAunMz4huXSOyYiQqg5alE70P2TUapKy/1bsVjbxeoTtXOgIvfao14gWZcoGjnuOOBgmy1l640dECxt1u17tPtE5apOyiS+lG71/mdFiXxoj7o/kO05rqXwZgVJRJ8YVV2XqEITTvbfh7BMbiBdPmdMrL5bLbavXbb7/11qJURp30uJPKjERWOH7iAffNc0yok+7gIw7BruqiAVWblEfZAtkFr4v2gaBG91Q8MiUNHqFlwNcBI9tUyYCtCukkb6SrWRuim/ZIbWbyVDn5MXaGzw7JiDuNjE+053LOAnd0nppS0oLFq6ur3tQpnSRlRvIoXeXiaz7Pr2NKZnlWgk+zLpfLiIguQ6X2uZWXOr3b7XpARnXRfnEbpmwVs7UOVMi/h4eH+Omnn+L9+/exWCy6A/zcCSvAEFiq5DUb08wmZaDSQU8GICrQULU5lHUY/a2K6XQaq9UqHh4eug8KsXDedAyDIl4cJBfQtYinEWmd5MU2qTQZTZUyV4URnRem170/3C5JQ7PbPS84urq66t7VtjaCIym6DuRRys3P/yf9WqhGkDKdTsvvOvhR0prfc6TLaHc6nXYRN/kpIOKLPgkmlS7MHB0NnX48w+WgMxtbN578O1OmTAbdCen+9fV1bLfbpmOqSuUEsv55cQcgOl1vsqhC77fq57viO9v4+PFjfP78uWfAWW8WdWV6xYCDoKK1hoH1tKahvP2M363pSbdhzsv5fN45EO+nt5fxuXVvzLi0VupX4+9/S7+n02n3W1sjF4tFd3jR58+fewe2sX7vB6crqz5KnhgAsQ/MEskmPDw8dLvr9EVNPevF7bDG06c8yA9mT7k+I8uISXa0xX21WsVyueyydATK+mDb58+f04xYVUij2zrnJ7M1tM9VoZ8Wb2hfxwDZSeuhDx8+7Bl5MLJlJOMGqULCLiCZk62iisxJZG1RaDzyGxqolEENJXY0y8HLolQpjH9KeLvd9ub8JXAXFxcHKF/7oOmUFR1w65xoYyaBQueLlyjUivY0f+6HMfkYapscP4pFAKJ0uju63W7XAxyq1wWf72SZooquSg4dCFUH+mTrH/icRzBVqejI7g89y+tK6Uf0t7pR/tQPgnPJhjtOAUHnP+XD55C5zoGOqOoDI8L9/uXDV6vVqltUp50cbD+bBhQNDpicdvbZQRDtm9NKPmbGupp+JT+cXj3n0zRjypAtYj/4Tib3/oxk5OjoKE5PT7sdMOv1OtbrdW8RYCUHviuMIJAy5oEM16PIdrA+6unJyUk8PDzEer3uznhQwJP1TwGKrnMNju7rf56zkIEiz7LTnp+cnHQn456ennZrIvRZ8pubm4MtrJnPEQ8qu5KNXet/vy66FZA632iDLy8vS4Eb3FXh81XulGWA3BhXTPGOZAbfnbE75aw+L1Wk4+0y6hmDtJyGiBcjQJ5ocDJj4fNwWd1Zf0W/Bl/pYo6Ro1qni8aThV9KZHaEqXplK5gOn0yep0t0KIvAhvqgT7vqfR05zWmAbN7SAZ87j2qsMkOelYzPlOFs+iR7vzWGVWnpBo2n6s8M4mQy6X0Cm8CBGSVlpbg3PiK6j/dwbYaAiA7OiXiZ287W0ejgHO4okjyQt2qfQItgRIdRqT0/5lzPVh8Lqsbbr7eyhZQHBhxuF+hEsveHSgYyxtqdrB3a5JatawFc3Z9Op3FychJnZ2edw+MH+ZgBJRBQdjSiD6gUdChIUTZDbUW8HDPvwJfHmRNg3d3dddMWen4+n8fp6Wnc3d11YIKAkZkLgSPxS7JKGa54705WduLh4SEuLy87m3xzc9MF2ev1uqdjlT6T5iHnn9Hm9wg+6OOkswo+HUBn4DMrg0dOiwgpE42UG1j+puKROGcEHTwdfQYQxoCGMfPLbN+NiUd/BC+kgTT5PH4VgYiXVDrxKOtrpvB6ngo1mbysEs9AF+unU2KRceYY8xsFRMJ6Vn14eHjoUnKq3/spoT09Pe0iU99j7zKiKIACznHJnL+Pl/fRx0M8qerNxjBTeP8/qyOjp+p7plfZe/pOCRf7sW1Fc3d3d3F0dBTffvttnJycxK+//hrX19cHNCl60pobrRifz+cHWbGI58zV3d1dBwQ1d00Ay5StQLN4LjB7c3PTnRaZgWouAHWQRZl1/SX/mELO9J56m4HUyjm7HWsZXuoE69C9Fk1VXZVc+7OVbGvsVqtVvH//PqbTafz222+9U0S5U0KBCzMLAnUKXtg/BjR+9Ll4wWyXMhX8loqe1yFix8fHsVqtugPIdBga6+a3KzjNIl3wzAP7NMZ/eAZhOn3ezaSpfAccLZvEOjheok02sJrKzWyn24/ZbBbffPNNLJfL+N///d/el4/VTgbWstIEDooSmEZyxLVYLGI2m8Vms+kxPUPqTGVR0d2R8lrG5MyIt9B2dt0dcwsRjo0mWu+5QfOV6v5BLab8CQD0PAXJjQuNsw7YkTHPeOL8kYL79AYVgXTyHkHibreLP/zhD/Hu3bs4Pj6O8/PzmM1m3Vkg2V59/SbwrMbFjYqu+Zjy/eqe6nDHlIHBMUalFTl4u9731gpsvqMjeWUkea6HnlUq+OnpKRaLRfzxj3+MP/zhD7HdblPgsFwu49tvv+1FTD///HMXobB+pq+VRpYTiug7ap3dEPFsV9brdVxfX/cyXeKZDobSWEyn0+7IaYLWCnQ5/yub4nJER5gBeNbtf7OOyvaoLy1gkclE5iyc/rE2yrOPXgQQNGWkaUh9t0HRPovkkLZAaXsPijS2pH8yOTxGWpG8bwd/fHzsMhzKtgngMhDRDxfZ6lnt6mGW1PmaZUFZKv80ZCPG2I7qPc/6i9ZMD/y35G673cbV1VV68qeeGTOFNrirwpF3huqzNH8WMYkgT6nr99DBLqyrdc9T+LpHJ+SOIHMkfK41X8n/q6jDnRLfl2FkijcDH0La4pUDC9an9hVxEpQReFDJaPRloNmepirYH5+O8QzTw8NDnJ2dxfn5eSwWiy6KUd98RXJmdDP0nPExG9vsGQccDjqIwB3RZ/VkNHmhfPj1CsiwkDYafkZyEdE7xMtl8OnpKT5+/BgfPnzoPsPOtsQLbvFUluj29vaAHu6ukkM6OzuL6+vrLgoVmOGXUfX//f19d7Il57bFewYWOjzKadDvLFJ0XlcG0dO17ohbWcxWe0NteXE5y2RO7dDW+VbgrLTkWHTpzI3z8/Mug7BcLuPz58+d3GWLvAn+VDT+PMdFYNTXk7C/PF8j6zdlLrPJLAJBmTOk7aJOVYED2/CxoXxkwUmm97rO35WM0UZn19l3BpP+zG63i8vLy1itVh04zOoaU5rAwbc70vGrw9zKU3VejpzfJhhCyVk9jp6yexGHyknQoHt0kCpO02QyieVy2aHUFp0uJFRSChZTq3Sy0+m0M6rOFxdIoe39ft9ND/jUAPms+wQeTNcKWIgu3wbqPFHbnr5UYcrv+vo6vvvuuzg9PY03b97E7e1trNfrNKquFIdjUwE8v+bvejvkKyPYLGJ2mc0MWkT0om9XXC4sfm3JgJGnGJllcoCq37vdLv7xj3/E2dlZurZkv39eqHt/f9/tGoiIzmFXxo9tSDZcbrQTiDZEbVAvnB7xm+uIKh4NATc+lxntMc5oCOCpb5PJ4UFr3qesjgyE+3P82z8CldXjTsyn5uiQNfVEGeC2bD/cKeuT36v0r6J5jEOl48/qzuy7ty0QlMlUi8asXi9fcn8MuCAdFcjw/x3UvHv3rlu4yTqYBR+i/1UHQFXzP1QOT2Pv9/vegpUhomg8WoJIpOegQUaIi2DoQOUcZSjcaNGBnJ2ddZFR5kSra75gjP3P/icN5GFLOWazWfdBovV63fVZ89P++Vu+6wLFdB0dhTtPZk64iI372qnwx8fHnSH69OlTR3fEi4OdzWZdqlPjSv44/dn1SsGyUhkn5xGR+xhalBLlGEuOfArH2/Sie56WJz38cqpkJUs/c3Hr9fV1fP/9993UGOXg8fExrq+vu/3pBPwOjB1w67cWXdJWaF5b515wGk3GW7KmSNXBN8GFCkGu8y0bJ8oz6a4Kx7I1BeFts+9Dz6ofnsnV+y2HnPUvsy38KF5Wp+uDdPHp6Smur697z1I3CQL9BNwKyLn9YaHscjqb72V95Poetakgid/V0DM+Lcz6pfO+yDyjkbzM9CF7x+/zfZ/WqeyE99XHx30xi45ToN54Jn5MGf2RKxZG707409NTFwXrJC85Fs5BuVOn4JMxziQ6VradMTejz1PTmePXvJdS61oglhnvrLjjcL5lz2eptMpJqux2u/j06VOPrxHRZXZ8e1RmVNS2Ox06uRaylcDLcVGJmPr2MdTfinQkIxUPsukt0lA5dtY1VCgz2eI1/l/JnSsuF3sNtT0EiHxaSk6B0TidsN71r6l+/vz5YF5XZbfbxU8//RSfP3+Os7OzmM/n3VqEjFaOgeaveQIhp9P+8Y9/xGaz6YCjpjQkq6KRO3kyUO58GyoOGtzguj2hc6vGme17NjOzYy16Kx3L3hkDNl03KBtqr5JH6bHGQLZEY8TMpIqidrfRFYjjYVGZg3ZH6mNAuyV5EYhWYUZVRc/yi6y+Fbtag0IA6eCrNb7siwNL3VdfvJ4xfiaTz0qGI57trXbLZO9VtvSg7ZbAfv31191NRpqeihMBRC4cBGc4o1N34i4wNCK+ZzwTPCJLTznTUIjGSkjOzs5iMnn+bLQvJHGjkDnmzMFF9CNI9ZPpfvHZeaviq+ddCNXXbKeHfmdI1iNiT2dmPMrGjGPDH/XdBZPHtRK0ybi5AmSRQgXmfO4xQ/r83697Rst/V7pDuaP8qowBMSpUcPIoc0wy4Bw/8t7fIZhnHZIjRl9uUN2QspBnokHvkw5mmFzWSRcBUNYOZSkrBLVZyQAJr1fyJRuzXC67fftZ20Pgg47I23I700qrV20JNLx9+7Y778W/cOx6TjlQfeovbYTzjXVKj3XdnaMyFe4k2c/MsSmjymezHRGkV/ZUgJnFg8kK6GdggX4xGw/ytgIbWd0ERhkdLiMcP/KZfNG9qkjXpZNffI4DD+2h8Op/DgIBgQRLQnF8fNxt5+LHRRz5urDrfx6Y5AwgE7MFOkSnimyZdiS44YD5/nYXjCy9WBkmT8GxTvGN9Wl7na+rEFrWuOg9P9VN/ZET5t59R59ybuSn6s+mOkRHK2ujPvJIV9VN5SAgFD16nw6FIHBIod04E9QMZU/0vCuil8wQsC4a2yydXrWfAZtqnpu0sPiHxtzwk24HDREv877Z59BVmEauIku+R/n3szsq4OfTRFmRrsjgVbwZAmocc3+3mkZgkaOhXGRAYExxGziW/uoa7+nDZRH5YVkuZxlQzrZH8zn+zYCNTp5OraJFdfjzPi3C990pZo5a8u3glnxzvavqVBnS8cwmjQliMrlUe6vVqneCJvnu/srb1nMO1jStE/FPHjmdITjPKpAJ2Vn9Hr1K+FqECQEuFosDZxfRj9r5jhtJNz5M5WbonErPNthX8iMrrJN9d0UjDdoepC1F0+k0zs/Pe/PQUhjOP2rvtRZVkkbOF9OZafEaIzAtXGP/BTq4oDWif/Ib39GYMlOy2+06oMPn+F16tk2hdYUhIPJ0oQODTPHcgFdjyOgjU0BX8Mrp+/TMkMxkYIXX3NDRQDhfsroJvvyYZC+tOdnK4JH2zChTBr3o+cpQe7veHuuonGhFZ0YbnZNvFfV6pWOsz+nP2s5orPqW1ZXJcvYOwYevVXFHT3nTb0bUmc1nXbS/rnP6nU3J+jv6v5p6U1uk3wFsBkYzG0A/RT5nNqjSYdHKgJR9yt7P9N1tRaVHHEvyl/41y2K7nAjIeQKANrUqg7sqWDhnmw0U33NjJUJJuAjU/xIS3dPaAqZMKZBUCrZFuilw2cC4ArEPLYWsBMsFx9tTP/1dndamLMP19XW3713vigc6jXEyed7ueHp6Gsvlspf29z7qns7dcLr58ZiI57E+OTnpntUY7Ha7uLi46A6K2e12cXV1Fbe3twf7rrXe5fT0tJObu7u7HiDScxy/zLCLphafMyXz5zPjK8XKsliZgntxoMRMz263KzM3PkZ+XX87ANbf/nGpatqAJ3WqDoJaFR7gxMKTI8UbgkbaBZ9KquhlttH7LzqzKdGqZLbFndFQHRxHt0VjHL63X4GYIQBbgSXe4332dYjerB4W8dyzha30vX8vRwGEy6PkxJ2ay4Oe0TkLcoac3maQwOCENHA6I+LlFFX6EtpVBzsVz/ieZ5BfU1r2qnpe7XDbKoGAgzb/u2pzNpt1U248k6kqr14cqQp9VaYjGzfCPm+la27E3Wh6dFmVDBzofUeQLQfOdkXX2JRVJnCtqJURo7Y/ab8855o85cc+Zmlf74fq0r765XLZKSG3CXLspIyk5f+29229jSTJ1VGUeNWl1a2enenBrNdYGDZswLABA/7rfjD86BevX/xieL3YXW9fZnq61a0bRZGUSPpBPqVThyeyij3zvXxQAILIYl4iIyMjTkZeKuJh+eEXv/hFPHv2rP7+/Pnz+NOf/lQbCwYC33zzTbx69Sr29vZiuVzGx48f48cff6xBBjb3QX4OEJRkj3q4n7UsN6OA/Dkt/3FaBza0Lzktv6SM316aOQwHXllHMr3CqRbQarVqhC8jHu51QF9imQD/1UCg32FgMZvu9Xr1TmxuIzsC9CNOVbCe4nc4AtQJI8XjEnsG2BhCfhkAc+SAlpLaCn6e9UepLs6j9qbkDFSHtE59lhn/7HtWHsa62hQc92b+scFWJwe8fMrU6/Ua0eKqqupLytguM3hgAI9y2YZB78CjRivVTjt7Dx1EO9jx67J5Zre1TxnQZBMA9z0DCq4/Ydvc0iO+Z+BF94uAd47UwgcwYC5R65XTqlzoNG0wnJhruDLNebkMXcJQo6kGX5/jM4ebIVxWQk7LgwZKybMmZ0RcvZxe26tIVpHiZrOJ2Wy2ZVh5EGWOC3JzG8P0pVfMJ4fjeQBj/ezw8DD29/frFw4x0kdUBHlxK+DV1dXW4MLd6Fh6ev78ef2mOFwx7DYsOcOvAEoNIHhSWbOh0mcgdx8FZKsgRPlSwz8cDuP4+DiOjo7qeyva1sm5b5R0YyP4x6kEOGWAA9YFbNrjfSMAHbiEiXmHce73+zEcDmve+RXXqB/HLlmXUS4vcekMETdHRkRjLwUIS1k8TjAO1MYg+qmbwNQZIk+XPsj6peSQIdc2sJABmq5ORH/TsVDiX9vCQFvT4j4Plh0iV7osDADKICMiaueOMgA8YJeGw2EcHBzE7e1tw9dgooLTPNyXo9Goft8FQGVENG6OBF8YD9ouvpYa9WJfD++zUvk7GTKx3W7rjzZSfwl+2Y6xDXMA0OVX/pAHkWNtZ0atEQc1sGwEwBgzx7tuMzTNz1Aeh65BGtXgQZId3ePvzvGzk+G0EY97NNzslEmFzs+dwWAkCH60E/mGR/69qpovDXJGEjN9rZ8HIcrSkCAj1b29vXj+/Hl9s+DNzU2tTCjr/v4+fvjhhxgOh/Hs2bPGHg6VwXK5jIuLi3j27Fl9mYzyg/qzHfHcPyxvtwaXRRt4RsKGXQen6g/3A/Oh39l5wjGenp7Gd999F7///e+3Zgr478pjoM6ydIAUMwVc2jMajbaOOUO3IF+ABSxbObk8f/68Nrqj0Sjev39fyxzLMQcHB3F5eVk7F6RnHWb5cHng5+7urgaV7GQQNcGmaux1Uv3OQGREM0r2JWAhcxKsI07fGNxqWc7+ZeCmqpq3NILUHnUFDLs4Moxz3Zy9Wq3qV1tz+VgG5UgSJgrsL1Auom+IYkEXue1Y4lO7sFwua5no8VLWBdSnY/j+/r6esCA8j/QAptrXDnhm/VACDTrmXblZfjf+Ob3aixKxfWCw6/Q5o9bNker0WLjcCAYLGhpBXnYyDlC08YJy8F/LB19Iw2vpnI+XTSK2d3Bz6ExReaYwADOZA+SyuOPQDn5r3Gq1qr+jbORDuE2RpwMxvBEUPLgIBiscws1VVcX19fXWbZ+YCfzud79rXF18fn6+ddY/IuLs7CwiIk5OTurra2ezWcNBMmV6oW10A8wZd/2dB0xb/W6wsj4oMOX14YODg7i6uooff/wx3WCn7dO2RjQBkg5obg8MMh9ZVKMZ0YxCsY6BAEKxFAHnPZ/PGwDz5cuXsVgsaiMc0TTkHPpl3cK9KPqOCuUXnweDQRweHsZms7EbpVXv8UyjD7s4TubJPWdDzVQ62ZGVpaAH4xNh+F14d47O8eAAcpd64OQZzLiTOehrjgho2cgDvWK7iImEyhP9yhOfXq9Xg1cnax27yMebufnUHgAb2qZ5kV/9QlcqTRjUp2a6U7J7kF/E9gRY9Y3rxmd9llHrUoUKHI5LX3HLIVCErdGhjDi5IcPhMAaDQX1Hup4dduiOjQsDEEaqjKDYaLGwVBHcWeyskzGz4nLa9mLAoPPGRjegESaOiK11cU4DvlU+6mh4WckBNgZZAAXT6bSIenFU9Pvvv6/5xexRUe/d3V18//338fnz53ptEY6JecGmJd7xr/Wi7x2Qw7s+eNOTgrMSCFTErb8rL1wGA0+Mkdvb23j37l19BC4ri/VTQXpEvkmXn7Huq9Nm0v0s2o6Ih5cZXV5exulmiRF7AAAgAElEQVTpaeONh6gTDvzHH3+sAaCWoeMXegfd501rGvYG4AWwwZJZiWeNgLoIqZP9l5Lmdf3WxQFwOk6rk4+SU+fJShsIds4b/zmiy8etmTe2q64cLZ+BA9JpPzr56Dh0up4BcCUFZc5Rsm1Q/6L2jNuR6daXkGuPRqUzuam/4zbhNywz8XuBuvRFRkXgwJXXGf7vLYfn5+cNdIPG9Xq9ePXqVcxmsxoQ4HcWNGYzr169ijdv3jSQK9Jy2UwOUbMB14gC6uM2RTQRJW9KBOkaOBs8RerOMbEc4TC5M91eEefMVUE4LcvEhTV1ECBcqANQZ9/ZoEF6Dkfz7XK8Bspl8DXEVbV9eVjpbDX3W6bsvFxTIuaTSQFoyVmrLFTf7u/v49OnT3UUhtvF5XMe3kPADpfzsiFWGZTazZGnLB1HAz9//hwREUdHR7FeN1+BDpAznU6tg9N3GWC8YLaqy2dK/BwTi9LGSKcL+sfUph9crqbVmVwXQ1ty5iDef5L1EesnPvMST6luXeZ1PKhj5PZ1ddJKDpg7YOXKdEuRrv62SDQTfuMNmlonb+xl3jJHzXZTo8BdSW0DnqEe3vyNdGrrXJv5Wa/Xi5OTk9omOZ/yswEHRYwRUa9bs6NiowMjxaG2iO1NZhEPG1r+8Ic/bL2f3dWvG0NUaO6PeePyHXJlY87LGwADGvqMeLzKF8/UOGtnan08W4AyQ0kY1KhT1zVwlKVImvllcMWDTaMWisid4XCoFjxA5gp4NJ9Sdh5elZ/1iR0V9E37iJ0J88ED3xmfEqmzYkeCtd3ZbLa1R8etf3OZDvhwNIPrxB+WrSK2L9yCk8eyA17BnYVawddisYj37983okQ6uwLwZWCACKMCPMiFo1IRYcEih4mxBo71bjXKavTU8LnNYF0oc2Tad+owHMBmB1UCBF3407SbzfaRdfAIfkvLcSUQWVVV/eoABiAuuuJOP7i0OCmBvRM8BrVvAYp0aZePC6sd0zGu5QLEs09TIM4AB+XqHiat+0v1S/vF+T/2Q/rfTX5YD7g+gP8XL17E1dVVPb5Up2EX2mxgETjotcWoBMqhO1D5HDivybuwqS5bcKcg3KsdlRlR/czC7Xq8BHndulpG7sx6qXw1PnyLJl+stNls6o1BPMj1nD3kozyrTLLIjUunSNw5f+4nlQdAllsSKPWd+87P2fm4cnWwMOnyDbeLf+8yYJzjUD7X6/XWi2R0Fu7a7vhgeXN90BONWvFSAL7DCCMdl6NLbqyDAAJu9oc8cC545iIiSIujoePxONbr7V3cbDfw4jMABuZDDR23VcEKnjves3Lc7zrGsjCyAw/us3PeJR1m0vrUefF4aavHfcZ3ANE2+8ZAEDZa7wxBuVjqjmjO0JlYZ1WerIvoEz7tUWofiMcCyyxbdkB7RqNRfUJJwa7TmRKxj3LP8Rn/eWwoKFJyvGw2m7i6uopvv/021uuHdxxxmxUcti3BtC5VaIPc6QdGY8PhsD4mhvSM3JyAwKxDqZmzcx2UIWuHqvg5Ox5uW0mAzsGWHB/vOueIgoIIbD7CwONQd1VVjX0PvJTh5MGbQzFYeY/FcDiM9XrdQOIM1BgYAtygjzAbwBIB0rMjwn0GXB7+XH9l8sNA5zV6F77jclxZnFaNGztMnSFmeuvkjpk9b+QDEFQApTqjv7Px53oHg0EcHBzEbDZrLAGpHCAfRBo0jS4Z8FhQPrOxxek0JK7lRjzseYHeaRptpzuGzC8zcs5B28CRHm6Xa4+CELUFGWhko87fUaY6cKf3Kje33OqIxy07cJRRIuXPgX3XTleGyj2zuTphZJvodJf/mAe22YhMu7HE9hF+yAFK1yfs10ajUfz5n/95vH79ut4QrLrpIk8qK6RvG/ssW9ZlBk9cjwKJ7Lf5fB6TySTOzs4a5TP4KYES0E4XQHEDmPAdZ2FxTl8HQ2bsObyim8FU+bBO6hBVBirYGEB5+HmGqDND1mUt3ZHeU4FycfwMTnWz2cTBwUF9cyPS4tidHoHDtdM6qHEWG/yOx+PGzFcVdzwe1/cBLBaLuL29tdcT4xIpGOXlctnYXc/AYTQaxWg0is3mIVR4c3NjbyZTZ6rOJuJxx78DfNoeRzoQHQjWgckGTfXXGSD0Ea/1q5HJ9DZztuq0IEfoMl/UpaFlNb5tYJcBVWkvAtK69mj/KGk0plQ+l4slC7UrrDMs68wROr65Hq2bnzv+sj7MPuO7c6zguwQaXL9FbM8WdWyU2oslWqQt2UhXN59M4IijAhqNvEFnXXREARGn1Wie8uTGMMbKZDKpj2WWiO0Q2vPixYv6VBDv88nkruW1kTsOqm1qA4Qg8I4o39XVVXz48GFrkzTrDfqo7bK1zsCBBc8Dhq8F7fUebp7Duhs3ko0YC8cJ2yEqRY4sGOR3/GodWhZIkS2Un42MXj6j+Z3T499cvVwXz8bn83kd0gVYwp8eF1qv13FwcNAoE2F9vi747u6uAUa4n549exbffPNNHSHAOjfzF/FgII6Pj2sQsl6vYzab1adRNGw9mUzqs9/YMFuK5DjUrP2tjimbafBz1jkuj/VZ+0lBLh9F4+fQf6wbIiLDSyv8jpCsvYjoAOzxmrEerY142Dyom1QRgWDwhjHK7dArxtG3uPESS4zL5bLmh2lvb6+uH2UgvUvLToMBp5MHh57hLBgUcd9o/3CfaL+CMjCkEwWUD35LZ/y7EuueAqCSLSuVx45VxwZvui21l9uGyYPygWgl2+ler9fwARFR9y3XyfrC/cb3KoA4uglAAp3SPsBFZVVVbV3DDF4hF5wA47skUB90SmWFcTOfz+NPf/pTDIfDmEwm9UVUHz9+3AKxbf3ENkOJZc5LLy5NacKE9gAE8PjRiB3LF2nb9LoIHHQgubeS4YIWKNHZ2Vl9jSw7Xd1cokJQ566D3a1TQzlYAWAoIyKm02kKPhwPzGsXch1YUgiEWbNZgM6Wlsulvc2S/yMtk77Olg37arXa2tSJdvD+CQyQ2WwWVVXVmw91JgHD4faSVFXVuOUNfQXA4U4ccNlMDuTxZxfBUKOcIX6VKQOE0uDkurQ81nm0lX/LytRxo0BZAQDAD/cBR2bg8HC7JM7N93q9xsvGIppr1DpeATTwG048RDyGaAGW+DQVymVdR/rBYNAADxi/fOU0v+9DnVFpGSID712Il0whT+4v1jnVPQW+Jb3JiNuAclyUVevjOrMx0gWEQA84PUAlOxb0eURzosXXlaN+yBQOHuXillU+Ao76V6tV43ZSAArWw16vV8+e1+t1jEajBj88OeC+VLvrJjM62bi6uor9/f16fwBO/Gi/6Wftp5Iu6m8KkJV3TqN+i8EZ5Kp6wABDx2eJWoED/jPz7Bxns1m9SxaoBsrnGomysjBxF4HzWhLnqaoqTk9P4+uvv65v7NMB6BwQ8nLIjGcsbsNkNmBRPpwjU7aJhpElPsMIaxkcVlIjwQaHowRIr46fZXJ7exu3t7eNSIKufWLg3dzcNJwGt4kHzmKxiOl0Wi9VcFu4b7qu5TIffILAgSl1IAo8NZqE/HBebU5GdY9lGhFbt96VwosMzDO0z0AQbbm9va0B3WAwqPtEjcz9/X28fPkyXr58Ga9fv47379/X76TgKBreHbG/vx8vX76M4+PjenzDkLPBXiwW9ZIJRwn0IjR+oyvqqqqqvunSzeThAO7u7honVNgG4TsflS4Zv67AAaCM9SQrJwMHajtLfJQAreqnki5rsPNnO8ttKTkt6IFGArAkqhFnHJVlW4PIs9qv29vbxh4r7WuWFcA2byDniLdGYGHvAHDhDNUXLRaLWpf45Vy8DK1jlcc3T+A0nI9+6LIMp3J3n7M0zBdPJNiPsXz5eTYRYblDriVq3RzJyBvPMFNARSooXUflvPpbRHNzpBso/D/b44B6b29v48cff4ybm5sUoWtH8Z/OYDidMxjcNuWd5aeDVmdJHJbr9/txcnLSmI2xrID83ToiZMROkPuBwRd/v76+jtevX8dXX31VL5FgDU+jF5eXlw3Dj+tpVV/m83l8+vQpDg4O6vPmGLi8X8DJFu1S2bOh1H4CnwraVNb83z3Dfz1eqvWrfjAfGTB0QFr7h3l2QJeXqDArQz9hqYnTV1UVJycn8fXXX8disYgPHz7Eer3eMu74DN3C/pTZbFbfsAdHxFdXc1uQTnnXC+OQnq8aBg9HR0f1215Zb5RYRrru7dLtSjpByQBDZmPUfmU2Ar+59PyfP0NfVG/4N93snPHKzgLp9aIwAInJZLIlJ51cRER99FaP8/OeKUSTFotF7bgPDw8jIuLm5qZxLJ7HlIIH3hvGF/i5+0sU9ABYsD1UwKOy5TIYLLi+7Ersf3T5lGUQ0dxPwWBe/SzyDgaDWkZZ+yArnvyXqBU4OCWGweA9BCxQ/JYZTzAPQudyyJLrVOfJQmFhRkRcXV3F5eXllqJxXRnpLFt3ACO/c3baTigVK70LFbKT0iOZvOeBDRi/ZW6zeTxPz3yhHO43DBQ1gPg+nU7j9vY2JpNJVFXVmB1ggAK1f/jwob7r/f7+vnFHACNbbLDE8ghkDKeVyZefc9sUNLKSw6miDtYR1TnuJ+0PpNXQuBpqB3ZUpsojP1MAgnxswBmIqT5zfuirAg3oHZzwyclJHBwcxPX19dZ+jYjHUwt4TTrAIeqAccZSmnN+pRmbypHHBPK7caWgV8vLxqM6410oc9xZmdrOrA2uXJajkx+3UZ2KI7ZlHOlEPnb0XK/ONhUQcyTJpQWPmBxwf3L72bYD8CKqMZ/Pre9hGYMf6IMDcavVqrFsqyAQ4EEnx44yOxHRjFbw71l5bkLAMtU6VR/U55V0QP0PA0TWB94U2SaLiB1PVaBwPh3AAsNMQ0Og6tRYoZlUAAcHB7Fareo36THCY+fEiqAzTWeEgUpVibkMhzgdYHAokztcO8EpFDvEiAeFv7q6ajzTvNz5qkBcJysiAIbuLdC8kDcTD2IuB6Fq1yZ2TLzmGfG47qZAAUs0+E03vDnwpQCVeeU+yECbOizWFxB0gnWuzTi4/nBOQ7+z/jCIdAaC5azE5bx+/bo+fYMd1m7PEsDdcrmsTz+4mwn5Nkd2PFk43C25aTpEO6bTaWMfDANON+ZRv96+qWAuM7CZ7FwfoVy3FMl5s7J2dU4OmPHvrgz0A5YaeIMt5+V+K/H3JaAL+VTf1WGtVqvGkhUmfRHbb7rNKFveg47xTBs2gaOTzK/Tr1K7Ih6jM45P2KzSeHf+RcG0I+ihA978mSfkDvRivLNt/UnAwTX2xYsXjWsrNXR8cHAQJycn8f79+y2kmyEoNFAd4O3t7VaDeTapBlwVlR0vI28328RnF+50M4HMMLpO5Oc8K8d3DdlrB6MtmXK6PRjMN1Np7SobLCprtNc9j9h+7wTSo+06QJU/7kMMct1Uiv9Ij5kD32aYyVLlxMYWdao8GWQ6g8i8lQADy1Tz8wxNdSfrS92P4QZ8VT28hOw3v/lNTCaTxkuBtFw4xOVyGR8/fox+vx+3t7f1UWs2MJwXMuPrxxVsMvhyjgqyv7q6ivl83uCFx33b/ikHXnYBDY4vLcON90wndIzsAh64bKe//Fzz6uRNeeZJmNpRnbQ4AKOAQ9fb1TmxbHjis7e3Z09WOCeqtiZbtmY7xTZA3wOkpzyczXYyUHlkPijCvzpey1Xw7+yQy8e8sq/QSB6e87JORPMoqy7JlminiMPd3V2cnZ010JouSSwWi/j06dMW6nEISpWAmd9sHnfA8h4IZ0w1XMb53Xq4U2h+7viKiC2npOUyZc5D5cXlqhJoebzbuQs6zIwzX6Lj8rBh0YEe4c/HM5WMH16IhTLxn503t99Ff7LyAQ550OmxMtdfWq/ba6OGUjf6sSyc8eXlO61fx4qr2xH6UvvIDXo8x0u3ED3UXeHslG9ubuoyh8Nh3SYd/xzC1nEK4mgl15c5U+yFKYEil7ck3y8hdZZarpatn9mh6vOuvDngona0xAfzywR95sgg9LzXe9hwy20EeOQJIaJi6EuMI33jpEalWX6IKiHP3d1d7O/vW7CpofzlctkAAFwu6ubJGY5FQ0ddtK4E7DSd2pYsndNdpxulupAvGzNsQ3QpSu0X64yuEJTaAuoEHJhpPmLDTHJYSI29GlI3ANhRuAGJjVq8dMGCwZ/WzwLk9R3dVKIGG7yxsecBoG3gzX7ZUkxEc78GG3y8c0AHEwj1YjDzrIpvb+Ryscse9WHWrhtg4IAYZGm4UPngi6nW6+YZd/6sEQYMdO1/lOuiJypz5xj0OwMJN6vgWQLKVMPDOqN6wRENTsO86vJC1g5n0DGmnAFQ3eF2Zy88AunyETswyImNPggzQm43ZOaO4jqjpuOJZ0ZcDvKyjqEM7hs1gvyndbeRc7xcPoMsNrptztrJxAFXrhO/s2xU/1w5XQCUy896yFFfHM/WiZkuG/V6zUvIIpqXN/E44I2NWq/aaN1DkemYOn/XTtZRbLjl8tC3pZm2+gqWCf/Xzy5K7oAQ857pcAY42iZz4B/9lwGQLmMlogU4uBmCa5AqgTqlDJVxB2i4TDthPB7H3/7t38b9/X38x3/8R9zc3DRm3RCkvt9BO4vTq1Jq3XxpBrc/U2AGUpkCOCeBXePI2+/3G8cxeXcxNiwC6WMWwKF8tEFRJM4d6x6H/f39GI/H9WwAF/noa6ohN75QKCLSDTXD4bA2/tipr86K8zlDx4OkNMsH6b4ElodSNpPREC+XreBAdUJ1pQ30cFs5X2ZkVHbOsLoxpMZBedalp4ycXmcgQYEYk3M2bAOc/vJnbSvX09YG1x59poba7cdyebvUlwFGxxe3Q4/DarpSeV3loX0AR9OVHBhgvviukK66hOfOlrL/yfhkPRqPx/biMU6XtUv7RCOIbA80rwOZJb+obWdyET1Ox3Zhs3lcAq2qKg4PDxu3ZlZV1TjxxOOuREXgkL0XXhvMRpKFpDMKNdR89pqfMwjgfBERFxcXW1chR2xf56womQXLa3slx54NRDcIs3wlY4x0fDsf0OnBwUEMh8PGDB1H73DjI5A0jjsyrdfr+hgdlAdXSrPsmSaTSb2O3ev1tm6Kg0L2er16NrLZPC4JKZDjNbWIx3PTAC8ZYFD5aBRK98KgPuThgY38XUnBSQYEIvxSHQjATh20Az3O+TEPTNz2qnpcQgAAVRAAYMkzZo7Iafv6/X49K+RIFoj5gQ5wFI37CjqJC6i4PyOivskPkwC0DeXysonjwxneXZ25yt6B16xcdRIlsOb6F+QcLJ4jD8aTgmGnoxk/+tyNP+gsgB3bbtUZpOcxqTadxxOfHANppDKiuUGaeXZgiZc78Z91UGXKSxaY8KB94FH1wU0U8BmTMR5zav+dbc70hNtSAiBq09jHuUkKyppOpw27qMvFjl9HO+1xUMbAHIe1mZyDZuFqJ6B8ZzwvLy/jN7/5Tf0eABYG0jk+WSkimgBjF5SuPJXko3LSTs0cDQbdev1wthk3cupAZEO92Wzqc9DOcPCA54GpS0lsqDEY+HXKLEN+Bmelyxyr1WprVz4GLG6TbDPyDqV3WbZgfVQwqoNOdY9D8SAeXM7gqmGJaIZqGSQ58K2kN7zpjAWgZDgc1joCndG9AbhREmAv4vEV5nw3AvpmPB7XTgMAjy/NgRwAMPioJvQB/b1cLmNv7+GtgqgbaTEOea8NgAunhRygj24Map/z8y7kJkJMzoC3UTbGnVNgu8BhbdSl4KXNZrnl1DZeeQzgLaZsU/T6eoDS0WjUuLeD+wp6Bn3BpIV1hv/zpAOAmO0eQKoCB46AYmyobkVEvRzsjrtnsoQt0Ch69l/HLHjiMdxl+UVBCtfDcnJlKHHU2IFMBahdqPXmSGdwFe3wBRpMum4E5rN1Hf3OIGO9XjeOUbpB5BynDgrmow14cJlZnUra2V3JzaAgf3a8kB8PYN2slJUN3viFWjBSi8WiBgponwIUfEYUBHXxcSQFJOo0eROUA6Gcl9OwQ27L60CFGlPVC9ZNdkRcJs/4dGbDMsYfnK+C2Ex/8JsesXJ8RDzsO5jP5/V9/b1e85QFQCUDv16vVztyGFc2irPZrNFGOJCI5mwSvPKrt+EUdDkKYxfpeDzxH8seDtTdNcH952TJmzazo3oZdQUFu/CDctvW4lm/9Hdnq3hM8AU//FuJL9cGdpS41A3vL4Hd4PxIF/EIFBFJ4jZEPB635eOBPJ55nxiDD9Q1Ho+3jhZWVVX7BZUn6xgDIB3jqFuvFmeb4aJC7JNQDttPFwV1/amkYEHtFI/BTDcYpLLtZ9Cm/GHc8CQjo043R6IiFQYYBhPO4KIcVuoSisKzklN3dbiO4A5kobnf9XmbEdDfuiqGaxdQM1+og3CtIl0MNnVA7NgY4fJv7NgV9d7e3sbV1VV9M9xyubQnL3DZE+uGnhPXPQmZnNz3iEcgygOZZzV8kZUOrGzNn/l0Ood8utHP6XnWNk7HgI5Jb/J0MmDjWBofiL5tNg83MOKNpQCW6G/MFsH/YrGoZ4rc9tVqFfP5vBHCxbto+I4ELhMyR9+jn9iA4W2oeI8MLprJQJSeKYdBYyCGmaP2J/R7b28v+v1+4w4YpTaQ0NW4l55l1MV5KLGjQN+yQ8/q7gqcIEvsccJFTDc3NzUwVb7xvhOeUCiQBd+8wRYTIga7DB4Q3UA7e71ezGazxmkLtE0jFvjPJzgArvjYJztL2JiI8lth22w7ynLpsu9d9FDHFJ6zzePx0pVH1A9Zoexnz54VeWpdqnCbI7WDGP3AoWRAAeW4/6xUnE/Xz7gsRpRK4JedJadXwKAKw4iNnQ47Yt5F7MpgPjOCAuOdDjB6Edv7MPb2tl9oxIMLhP7gGSiM/Xg83nJE6/U6zs/PYzqdNgaQgi1G2RzK1PVo127IC5EOTcMDQ9F0r9eLw8PD+r0FTqc4EpPJXsOGqtNcHud3wBMy4E1rur7q9AwOEH3G8uK0rL9aDoNbzKSqqqpfEMX8s07iM3SMdceto/PVwQp2GNQCKEXE1myF7QSXAf1CW9xeCY486GxOJyDgh3XU9a3KMPvNfeZn2ldcpo5HTucmLG0TDW4H5+M9TGqbeTzp3RfsZPAbX2M/HA7rSAKAJG531MkMgCTbGQYN4KGqmst2eM66zDzzxCri8Uiz1q3yQz3QZ+1LXo7UY6NqWzL74OpUoK82BOm6EG9gB6+ZjuhSio5Trt/5b/COidrd3V39ZuSMOu9xYAGWGs8GRAWr6bRRaICGLNnQaLmubH6WoTIOQ2VgwXWAznDQDl4/5jY6+WSzSJ71vnjxIjabTZydnW21C5vdMOPg9mj7GUny+p+TIQa6O3IL/jabzVYYkpVW28WOVX/PACTzxPxic2iWFlcpu4iUa48zDuqk+UQLRwK4HXrldxZeRx7W68whMG8M0LhMvhsBYXntC5SroLnEFxP0IXvxFwNFBY3cFpTB4Wq+2wJ8oh2oG33g9M45aJVpVyqlz/S1SxnqhLJ8rn/1d7dMp04A9WQARW3X/v5+HB0dRUTE+fl5Q/6sL9ADZ8fdKSR13G7ylfVVBk5dG1zbd+37CH+cUScmjj9dwmDwASChYDyrw4ELBVlMClLwnZcLFUiiv3RygegSA7cSdb7HQY0PM8Lp2Oi6zuDvXAacGgwKh1u6HA8B8QyGw5vMq/Ls2ltK4wAF38aXlevkANJQcL/fj1/+8pdxcXGx1YlcNw/C0nISh5OzfmEnpTOFiOaJA/4PveDQIn5HaFENjM78uTzom4LG6XTa0A0dVNfX11YvQW5GzW1n3WW5KWBl+bt6FJAw+FD5M28wOvyd+XB9pTMmlj/3gQPf6rh5SSAD3M6wsO7p5l1OA9DHeRlA4bsLu2fjkYE+PmeXmylljkHr0Qhom6Mq6WBWR6k8TZc50i6E8jEWsBQFYAfZlV4qxsthvEytIImP80OGCii4TLb9EbE1btj3KNhk+ZQix2qfGNigLVpnNvHR9vI4UNusfaWOW/uc+WC7zm1lvdQlEo5mIl0WsdMIMJedUaeXXOl/bqxDKV0RHxTIIUhWGhWU6ww2RllYNTPy3JlZmJ2fuRmOrrvvQhyKxcC9vLyM4XCYhqCYONynDsa1U9uD/6x0meF2qFjT6IDg/mPl1X7k2T5CZ1oW96XqDacp9UHGuyJ45ZPr5w14uvbs8juDwm3O+IVuwJhqqJeXrRQwMrDDZkikRZkcYgZgZeOs40MNctYfzrllERHud5Sn8lKZ4LfRaFSfSddNmZzfOehdKQMaXcAEUzaGVGcitgFa1hdchgPirgycYPn8+fPWkoHuPQAARV6WtS63MRBwIXbuX17WQnTRlYln3G6MQdxmyad/WLa81MYTS91IDJpMJrHZPLyzh+Wlkx21D2irOt0uuubGFttOLl/5VZvN35kntZ9cF/JpPRm1Rhy40VmoJGs8N8Y55MlkEsfHxzGfz+P6+nprpsBXjrLx5pkjKzcEpoZTHW6pEziNG3jcrn6/H5PJJK6uriwyLcnKGRpWyNlsFm/evGncpaF5MoOlqJYHZAYAMLjUALDTc/Vnhi3jOSPmC7KMeNQbDteXlNoZVu3HDOlruaxXru1cFi+vKXAotVejeEwMAvf39+P4+Dhubm7qF4uhbw8PD+tNagosQGw8USb2WTBw6PUeTl3wfgEnFz2/Dz3VvS5og9ulzQ6A5YnbUd0mUZbrZrNpbHZDndxP/DlzoF2J+ygDJFpuxjfPBp2DYHJjSgFoiWdHiDQsl8v65I3yy8ucVfV4Z4i+NRbAFProlrYwCcBRbPCGOxtQX7/fr4GgTjS03ZPJJAaDQSwWi7i9vW04R456K6DVa6+VABjY93CZqrfO5mZAtaR3HHXksYP8vATiZMJ+Em13E3PWG5SnUYc2vdr5HgcmZ3T1GRtTZQhHvw4PD+Pw8DAuLi62HCh/10Zr6AZ5WFnQ4XgGMA/voeoAACAASURBVJKFUx0p4sQzFyp2+bh8Z0gAgEajUePqaTaKjNDH43GtSFgvVseDMCTAAP7gXFTh1UgwSNO2oO28tKSAkWWvistp3SkGnjWog3aG2wGoUn90cRpsKFRWGbhSB+CMRwlYuv0FEY96zm+KZHr+/HmcnZ1tAW81mtyWiNiK6HC5w+Gw3nDJ+cEP9IU350Fmus9H282gSY0dyuC9LTpuHJh29fy/oBJg0M+Z/ilA1zzaXvyucuJxugv1er36Mrjz8/NG2dk4wrjUPoEtQLn4zo6X+VWHxaDh5OQkJpNJ/PDDD/VRUAUBvLwSEXFzc7O1pyDjm9vl+lDBk8ohAwPcPy5dlkefY8PyfD6vl4rQdrd3zoHUzIagLO2Dko8q0U5LFfrcNUQ/ZwYUNJ/PY7lcxmQyieFwWDtLCIx3sqvxYifjBqvrQN5tXerEzOizIx8Oh43Och3C8tM9COyIcMUzDPBoNIqIhzeEsjzW68fLofr9fj34MHNQpeLjUBEPzgKIWts3Ho9rowxQondIRESjXhwHwxE67ht81g2abctBTLpfAnl2MZaqGwo6XJ3cXgY3bKA4PfME5+lk7HaG8xokp2X+l8tlvXmNabVaxdu3b7dmR8yPGm0uV4E3ytBZpdJwOIyDg4M4Pz+vx5QLVzs7octVGSjki3p4DGnfKbhuc9ylse+ctqMsnOucCdfr7uhw4E37i/sUNrHf72/dreDqdnz2er24ublJ322iOrTZPBz/1WiIayPzny038EvR+v1+PHv2LMbjcf3mZX7xEgjHPDGpwjIby5TtJPOo/ouXQqBjmZy4DB6vpcmKygF7vRBxub29bYwxTtPv9+vfeM8Z/jOYcBMzJe0ffkMoRxpKkx6l1gugXEGqUGqQdQC7UKOWB2fIBhC32HHoyDXIGSf+rrOaLqhKf9cBEPGAdlkezphkRog7EmUDZUOp+e10nG65XDbOxuPKaUbpm83D3QwYYIiOHB4exmg0qmUKfpEOvAH9cn+AeIMTR10AHlQfkMbNmkv9qYOU7xfIAKIbzCWZM6EufVscHL62C2XxMoULlTtd4rZpGsc388zjys0iICOeCeqZdhhfXtpAGl1L5kus8Axn9k9OTuLq6qpOo5fooDwNXSP65cYh6p9MJrFaPd5AygDNRaW6UglA7FqWy+fKRV8fHBzUV8aXeGgDP+v1uvG+AZTl+FHHgMkHxruOQQaycGj60j0QLzWw03YAjPUVky7cKHl/fx+fP3+O6+vrOj1Hc7F8huv52Ylr+zJHynyyn1I+HcAGPzy+HLF9QvtGo1EcHR3Fy5cv45tvvomjo6P4r//6r/jtb3/bOAKL/sCV/zqenM0ogUMF1/gMsHB8fFyfQuM++lmBQ9ff1cBwA/U7K9hqtWrMhHu9h/c1nJ6exu9+97saEWoovQsYcIrhHHzX12bjN3ZkJdCA57zG7AY5rwPz9a4KmJAf/2ezWf1iLMgV8gKPuvzhZg58MyeAA/JiZoDBy+vPg8GgsUmP6e7uLhaLRQ1u3IxR5epkWHrmDK1zxKwzqN+FJzOQzHU5sMJGPWsTO283LvBfHa97twf6CQBOnYECNw4lw/HDKYAw62HjWlXNCAQMGsAqX08MHjj6xDOtiGjoJi+HID3qgK6yXFVeClS7TAq0LuarlFfHHZNzlA7wTadTO/bbnBe3Vx2C8sf6jf6uquYdChyd1LZx/2PvwmAwqN8RpMCVdQZLoXy3CQAA60lEc/n1/v4+ptNpzQt0OuJxEyTqZ4fpln04qgHfgiPs7Bh5LLJvKQEx7lMXeUR54OPw8DC+/fbb+Id/+If4u7/7u/jmm2/i06dPsdls4g9/+EPDPvPESu0TH/FWvvj0Skl3mE/VRR03bWPoi4BDqVB2oLzM4PJoCJjTbTab+PTpU5yfn29diwvisE0XlASCIrtOYMOQASOu35Xjfke9UGTu6CzsCWViIxDx+NIgRZvj8bi++fHi4qJ+hwUTH7PiOt3sFQOPj3HC+fMAhBFSB6COEBdQuVCf4wnfHWpW6uI0FGzyM25fybDrru22OtnI6XolA0YFBgCCEY+382k7+f0NbOzRFqTHMha+8+vWVT543wWMLPpZeUckgIGoXg4EHjQkmtkFBr3an226UkqXkY6rtrT6uQRa9D/bkgx8cDn6jMvgNF14ZwcasX3E2IEVRHh0EuXqxD4rBjYMLmAv9FQNh9/xG4AFgC3vo2I5sD6iPtTNp5BUfvyuI6TDeNOlg12AKHhFfgAVACkAr3fv3sV8Po8PHz5s+RL0EfOgSy+6DMz1sz4rOHLt4L1uGmVso87AwSmXU2j8d8JGObypUQc/KyrW7h0/UEZ2dqzsWif4YWHzLWE6sDN5aPtVYRV0IB0M8dHRUVxeXtpQOdfBHa+DIEO/w+Ew/v7v/z729/fjX//1X+vrdqFsqhjar3t7Dy9Owg5lJR6k+IP8NXTMilhV1Ra4cEqqMlMdwsx5s2kuWzgZMnFdjM7RZp3FcT6U54AkGzN3q6TywzNP1nEYHAZVg8EgxuNxfXeFA9b4v14/XKrE13IrsfG+vb21m3rV8PNsh3UI9SJUzm1hQItxrm9ZZcCkeoZ0DKQgI+0P1MGXr2XjN5ML6nLPVT78nI261uHGmfLA8lW7WRqnHCXJxo9zIpxXedYy4Kj5wjUdzxGPExuMbdhAXurgSQKOTDJv0BF8ZkeJOx3YxusJMZUTb4TkOjjKxRcgQa9wGkTLLjlTtlGaptfrxfPnz2N/fz/m83n80z/9U6zX65hMJvEXf/EXcX9/X9/OqfuTtG+0jTphLe1TQR4e2y4y7PKVqAgcePOFAw5t1IaUFRU5A66Kr+vJm80mJpNJnJ6exvn5eb1Gxo4NxPmYSorhDEjmZBRoIc1oNIrJZFKHovRiEy0nA2T8TGWAC5Levn1bn21XZO/q4jrZCEQ8vt4Yg03XpUsggNOpgVQHXNItvURmPB7XDotl0qZrPLsBqYFxRpTlp45LP5dkwtExJd3ghuUgRBQy2UAmDrRweoSLsUSh7ePvw+GwjkhgdqZRLw2f8mwIdfOslh0EvmeAD7rsDCi3B/qvZXUdy23p28jpnOOVn6mcMn3oUnapHv7Mzq+L7eaxwtE3dthcttvTxPZXy2SgwEurAIDQG3bqWhf8gE4++RZdntToOOajowcHBw2brHaD28X94/qKabFYxMXFRT35ZRt2cXERf/VXfxWnp6f1Ffqqn9lEROt29TOoZnlAJqpfbWDFURE4MGjIBroaVGdcoSQwiCA2SCwENXruM8qFY+P1L1eOEworRhYB0PwlYKOyAe3v78fp6WmcnZ3Fzc1Nw4g6Uv6cgXftvL29jf/8z/9sDNSI7d23pTpxz3xVVfWmnrOzs61zvtmMCv/59chwgtkMqTRTYjTNt0dmt7kxH/yb2/RT0hXk4z91AEwlsAriPlGDzHs/ILNdnAbXoTJkWTrDyN/39vbi9PQ0qqqKjx8/NgAXh5s5HKxGjuWs+wg4DfOXzbp4Fqpy5Iij27yXAUZNswu58c7PuhhllgE/L+miplPw6kLNbU4gs10gtlOZg+S1ftU5Vzf0xoEm7iM9fcJ9yGMHfQ/9AZDO6mB9RKTu+Pg47u/v00hwm4Pm/6Cqqhob0JnXz58/x29/+9v47rvvYjKZ1EvxOsEr9Zv7Xcc2bgJV/hUgOfpZgENGaniVcUZ6vH4FxljgHNLSgeQawUK4v7+PT58+NQwKU9uyQPZblt51hJMLaDqdxv/8z/80lkZcezJHmhHXzwZYiQdRVh6j9IjHTY2Qb8mxOur3+/HVV1/F/v5+vHv3buuOgRIfvAcFz9BGd/SMy2xzBLs4CtU/doZaFxtuTZ/pNO8XgNNGmsxgl/QV+dSA6zPOw58RcXr//n3jfg413I4w7lyoF6SzU+VdecocLUc8sPFSgZZ+3hUgtNGuesSf1SEqYFBAkZWl439X/nRPCvSR9bDEB/jmjb6qJwqWuZ3aXuwHwKSD+xlthC/h6MFgMGgsUWTLOc4GIjJ7cHAQR0dHcXNz03oUGZTZ/0x2eHZ/fx8XFxcxHA7jF7/4RUyn0/qkGsvP+cqsPm1XxOMpPbRdwWWmb6XoKKjTzZElJ9qGalEG34bFBliFoUYyE5huBOM1VHXwykvWFnx2Dhz/2RBrXicXPONIi9atwEnboEbfLb8A1WYgK+OT0/BfRNQb5ZgvEDtzB/oAOC4uLrbWwrlOJTdb534u5W0zvJkjcr9zW9iQqtHnvOA9u72R07IRRFnYna7ycsCDSUEGQImTZcm5Mnhg8MJ6gecqk2ztWR2d02tdl86iFGxUITfs2WDdyMbvLuTsAf9WctaZ7XFgxvUxl5Hlz/h1jiprv7ueOWJ7aVHb2zaOeUMkynOOSG0lIkbQJ92QyzrJ/c0+ZbN5jFK6UL22s6qq+i4hLJcMBoN6CQHtc/ZTqaQzqp+LxSI+ffpULyFyGTwxcTrllhtUptnEQ22ojnN+XqJW4NCGTrK0pZkDG4dSuoyH9Xq9dUGSS8cK1RXg6IBW4s10yrMaxTbKgEmmpO65C39rmpIhLQG3EinI4LwYvJeXl40jtm39izRtStuVxzZjrMA3q5cHMQNHdtI6WLX+Utn4TW+FbGsn8vIfE6/bspEoOSQ18AqWQIhC8SyJl8S0HgUxypN+djJDuTozY+PHfLbp0a5UGtddbFy2hKX5d7EhWf1cjgI75UH7Su1F2zFVvYlWlwUB8LKd+6wv+tm1D2WjXI1COgDLz9WR8rjACYjBYFCfGCqBhGy8Zs9ZtgAPukzpbPJPAcGOb+Ylk3OxnNLgevXq1QYV7MqwM9Bs4EozS0cqXMyu+VyxU8guyJ15y5ywOo5dnZ2rv423NlCla2LKO88MFaE7oMByxFphdqOac8IsP3znTUxs9Nv6xLXH1e0MtuZhI+6MkvLR1p/6m2sXAIXLy7oP4wfd0jX9Nj7YGGa6g9/5N6ff2MPAhr9NB7v0Eb6rru7t7aXjV3lwS0Gl+vHspxpaLkvr5DrYfmR94fJ14bPUB13bly0TubqYXx7XyrPTZacHHIHgzZHKRxdH1qVPtZwMhLSla/NX+pnz6nF7/MabJFkGbf5DQdguhLHGbXQ2QOni4iIVdOtxzJKylRrL6aEwmFFlnZh1Ai9x4LO+oAd5Ss4s41kHSqntbh2KlWIXAKE8w9nwUTkmHnBV9bjhVGXaVg+32w3EDExsNhu7/sl9x6BF98iUBkkG3pyBUR4zHeI26KZBLl/bWqoLeVjmpSW3zMlxW9mwOllmBjbjcxegpeVCBzN96SIv/S1zqm55wbUJMlK5qQ5kYKlL27tQ5vizsne1BZl8d3Eu2Vgp8d5GWZmspy6ixMRXJ2f9oTwy2MAzV34ml67PS3amrTwHFkr8sf1A/kyPHIBrA6SON1e+swkMKtqo9V0V+O9mbDrLUiTEDPGLSLjRGXrTcpxTcfUwz27tt6S03EEacsVzdUCDwSBevnwZh4eH8cMPP9Qv6spAUPYdZWZH67hO/CHq4o666WBmB8Xf0Sbla7NpnmjAb27jDudhcmHxNgI/ipA1TckQah87QKnLClq+6hqvK7JsnbErOTB1fvidb9V0t8BlTjLT9zZyMu0yFjU988FLg1wGflOZ8b0VypuCCuc02C5FRHqe/eegbMw6UrlwREnTKZjKnHrpeSmd9qtri5aTOVHVwcxWZW3SvuvSxi9x5i5/SQYleTjw6dqjTld/UxBQao/qlvN7HMkt+cSI7T0mPNFRW8RtLFGnt2NyofqiIV5CyASSOXmXBuWyEeLTEl2QZgnB4TsMNdJkwnOKAcOGYz8vXryI09PTWK1WcX19vXUKwYEVp8iOB/3M/OglOSU5RGyfb8ZrdVWp8WZEd7zNybKUpsSPK4uvf3X97cpXg4Q/BrZZdKoEJFE2D67SwGdH5srW2ZYbCy56pH3P5VXV4wuDnP46x56NvTZygEdllDmHqnp8pTL+Y6y4ejLjqU4pIrauzVbqondZvpJsMgetz9t2qLc5i1IbupbXlr703Dmt0tgBaSQOy2CZPHbhucSrc9gYK+xEu8o0sxUlO+DaoT4k619cfMX52IZx+WiL9glPErn9+NzmL9pk0xk44AVU/M4IblRXygTKIISZxk7XzebxVjA3yLQsGEoWqFuH5v8aoSgJEh1zc3MT//3f/x3Pnj2rlw2+lLoaKnWYJZDiygSP/E4BLgcXPmV8lQZM6XupXdoXvAaoOpaBT+2v0WhUvz746uqq3kiLcts2fWGA8T6RzcZvNNO2KIjQdjJpmFf1taoebx6tqseLc7K3G3I9zok5EFWSZ1vfZ/mZ1uvHO1z4vhXl2fV3qd7NpvmOlbbJRKnsDFDpBCLjKQNubcAFk5AueZSfUpq29LsACzcWMxDNup/NdF1fqc66DfSZ08v4UUetk5Gs/szmtfVLxovTOfQ96xbLzrWvBPJUt/W0CfPvosxcx08+jolK1+vHWw/39vbqs7PMRFsZbb/xPQ+gqqri6OgoFotF3NzctA4YXYN3SJHBRJshdMaAhbper2M2m8Xt7W0R0GR1tJFTFlbizAAz764uPh6r7VVwyEZN5VIy1G2GSdEzD3D+y0LwLjQOvvb392M4HMbLly/j6OgoJpNJvH37tr7itY0vbQt/Lr1UpjQLQ14Nw7edMKqqh/Pqk8kker1eTCaTuLq6aoCsLrKO8G+6LBk4/M5pNFKn44S/Y8Ml9Coiirdhdqk/A/4ZOWBaSqvp1Pm4cZC1IxuDrNv88ruu4MHxrHXrM+dIupbLQBbf3WfoeJfydmkLA2jN32bHWa6sSzoOuvLG/dPGL08+eOwpONLNqzx54PoVkKk+qm9rs8MOBPZ6vXSfHagzcOCriBlAOINRMp6cTplXYeA/39evBonL48aj0xSJcadw3V1IQz9ajtaRtbVkENrkp4PfKT2cvgNizsmwkmJmC6DIPPGO6BJ1AQ1ZPh3YXfZJZANsPB7HbDaLu7u7GI/HcXh4WEdZ2ow/P1dHz6/15bRtOpUBT+cIIQcM4mfPnsXJyUnc3NzExcVF4z0kyNNVTnpUzDlJ5kefOXkr8QvdMBa1bzPQxDJA+ewwuk5YuF+cIXVjg/Myab62vs6clJapzjiTgQOVGdB0bWCb2pa+5IQ5nabniG62LKZltrWLfcPe3l48f/48lstlXF5ebvGibdSynR5n7dN2OFmpjdV6ecKj75txoEU/Z0vpLhqgOs7tcaBJ8yovemGfUifgoI3C99L6ZNdysjQckuKQupt96mUhVdW8Zz0btMqzG+yO9OpepcFgEP1+v3HXv1OuTE4lwMUK4n7nMjitUw5Oh2WdXu/hZVmbzSZub28bm1rdkbhMDqrIbbyW2lsaxCVngAuser1evHz5Mo6Pj+Pm5qa+LS7rb4f8d9Frxw9/Z2eqFyepM9nb24vxeBwHBwdxcXFRv5KXz68rb+qcndHv0g4tC7xF5O8/iYjGmzp7vV699MV6o0smTvYgOI3JZBLz+Txub2+LbWDenQ5mhpX5c+OlNF7b5JrZH8jIRbAyp+p03Tmgks0rUZa/i+3uYt9K+Ur1DAaD+NWvfhVnZ2dxfX2d6mBmz9V2Ie16vW7s3SvxgHJKfiIL82vklnnS8pGev7Pt4LbBLvJRT26fgqkSQOM8Jer0dkxmnj+XECp+d8hT02toi4WheUoDkIUCQ8Vlc2heAYgDRu6763T+3+v1YjQaxXA4rI09bl/UutuIlaMEglweJ79MQSOisYZ+dHQUVVXVM2v+G41GsVqt7LWskPf+/n7jNc6OMqME+WibmbLZDJd5d3cXV1dXcX9/H3t7e3F+fh5fffVVPHv2rPGGPHUWKB9y130NCpjajKMaL4QrXd9yO/C3v78f4/E4Pn36FNfX1w0HjDKzpTcuv2Q8ka7tfDgceMm4cnvw0qK2t/dl30HYO7TZPExWMCkoRaMY4DjKjCa+83XMXRxmVj+TlsVLXl2cfQYQ8Zvq1C6OO2tjWzkKgFwbOK1Gu0DZc+YDN9Hidke8PIrbrLqOsvVUFP/OS0XKb6brzn45QKFADz4RSxcZuXJUxhgD2X4St3+CeVE9UV9WotZ3VaBAFRKTDk5ViK5oPHOO3FgVeHYBTkQzEoH2ZMrKdaliZcgf3zn8u9lsYn9/v75r3XV0F3KOoLSbOTPi+E2dlFOMwWAQ6/U6Pn78WG9I5bL4HfPqgHiQYvNbpj9tICZrQ2bseZCBeKMqriVeLBb1PoHSpkK0dTgcRq/Xa7zBrkQ68NTowGhgTLTtFQAtFouaBzZG/IIslTWMoRtLGW8lgox5/GV5sHt+NpsVx39myJTgNK6urtIlOEcs76xelyei7MhUhkiTbTjTspWPTLfaQITOuPWzcwoZOVvXlkYdNPPm6uJTXVpXVj8/Xy6XMZ1O42/+5m/i7u4u3rx50xj7mbwyQKCgnn/T9mTkbKoD66xPk8kkXrx4ET/88ENtK1GPs2VOTvo77IGClYxH1w6UVdpACuoccXCVlAZKJtBSHWrQHKLmZQLnPLqibBZwhjZLpA6NZ/jT6TQWi8VWGLpL21lWbXLN+MpAQqY8jISxaRLhYPCEtszn8+JtkpzHtbGtHS7aoLLQEz16WsaBCEQgNCysfY9Bvtk8vGL6+Pi4Pj3jHLCTI/OmxpJloqgfebB/CPsb9G2gnAcATaMkbc6xBGwyw4n+d+3QsvmosCu3NB5Y33Scgo8SsTN2Y8A5fqUsYlFydiXn7PK5F79lYFvTdamz5IDc7yWeOY/rzwzAZDypjcicpuabzWYxnU7jr//6r+PDhw9by1ZtAInLa6uLx1Mb0OSxqMvqeI5xvdlsYjKZpDarZFt5fLt9RigzswEl/dzFf3Y+jgmGs5mMS9+VCc3rHI8KQQWXlYX/LEgIlnkFadjXARh850HOaXEHQpuB2xWsdC3LATU12s65Xl9f29+Ql/eNtIW1ka60498NHCfTEuBx5UNPUR4c7/n5ecMQqJ5ynff393F9fV2Xt4vRZTCDdFyGW5rjzYPsMBGaHwwG9QZl3ZA1GAzqaBBeMa/AOpM/+IWs1CGp3pScCafrUp+SC7lmpCC7ra1uHGfgD+ROwJSIbWQXck4U3/XYodoYHRNdHU8XnrqATj4t09XeOz3hPJC1OkTON5vN4ocffojb29saeEFvu2zcRr0ou0ToR+xXywCnAvCsPhCO8OvJtjZ7h2cKUCLyDZP4n+ma2t2uEfFON0cyczCKmePo4tBLdWTPUL+rS2ckIIRMnTD0TZIsZLSRj9AwX4zqOI8rp0QZb8yTol/lI6Ic+cnKc7+1oXW8/AUh47a7DFBuV4JD5PCdzkq4Di5fBxOeO8PvjKPyu14/vCUSdwSoDjhjD+L1VDgT/k31yA1mPMPplvF4HP1+P5bL5dYYA5g4PDys6+I3bDpdVOfD4MXJVz93cVRcb5tRr6qqvlANr1fOKAMNDuh3KUPbgP5jHlw/OZkyqHOGG+m0jKxsrgOOTJcKe72Hu26qquq8tyir16VRnqqqamzEy6JJmawYIGg7nZw472q1infv3sX333/fANuqm216wA7byZ73CHAdujSI9DxeeXnagVX2Hdo+tXcsI33tObeF+eSJEfqH93loe/v9fnz77bex2Wzi+++/7/QujKKHV6GBdEOPOk4M/C7O0xEMCCMx/qwd4jY66mfOxycIHGLntPyu+UwZ9VlX0KA8aRlt5Oop5eti7CPCnuG9v79vnG5p46sLP5rHATDmLdMFNl6ZbjhyLwDT+pgX59z5u/vPZZXWDvl33kQLud/d3UW/34/Dw8M4PDys71GZz+dxc3MTV1dX8f79+3rz2GQyaezxaeOd2zgYDLbuFsjGXkluWm8pT0TUkZXSUpgba+h/fM8oazOXzQ6Z9dE5gaxsbRf/dzrlHKSbfJ2cnMSf/dmfNWwS8vb7/Tg+Prb3HCg/jjcmdUQqI3zWPWS7kgJA93uWj5cDuoBS/a9j0ekG6uGrCJx9KemC0zHlTWWtNiAbc+55aYMqxor26Wg0ir/8y7+M4+PjzvZ6p+OYuyB7Hpi7zAL0PxsGbGpT5Madp2jPOSCug/OocrDhLO1VUAVUQ+x+d/n0cxuSZ4Opx/N2Je1Tld1ms2mEB10a97zU75q3jX8uFxEhhPuy3enOYWaOreTUS/xkcsjqdDwiHV83y5Gk2WwWs9msob98twnGACINL168iLu7uzpC4cYununsh2eTu2z4c7rTZdwj3WKxqF9lXHJyGcjUmWIX4uipsw3Ko+tvrY/TqB1EOW3ydHqzWCy2NlIiHTb/6nX3WnbJQWsbeIaqS4gsq5LcsjGX2UGdsZd45LJKPqbtt1I69UXMJ7ebl3E5vePP7Q+BQ9coF8gBHZYj5Kb6gd91ksxL9/P5PN68eROvXr2KP/7xj/UdMSUqAodsAGbOWIlDQbs4M7chyW2UYuTJwnEOMFNuHRDaRtRRkkMbSFCF0fP3mTwzJQbxrvoszKz8lPoBvLS9LGh/f7+xnOCcS8mZapucMWhz4gBKbNRc2SVenNPbldqcpdsUyYbDtV15RNkcqtayme7v72M2m9XvIsHYYB6c82WQnBmqDBTrGGOH3PYuCTWsajOYLyWtv4sDUYOraVz5PzVN9vsuejedTmM6ndq63RgsAbAu8mK5s+zwjEPmal+zMZw5aqTXk2O7UAZGuN4u9s+9oVj1sbTMjHS8HJ6BMqQbjUbR7/cb18jznh8FoC4S4WyRtk19UsSDvXj79m3j6oA22um12pnQHUBgZ1nalaqNy54xSGCjp5vQXDkO4TmlVR5VAbRc5qdtvQ7pWRaZUnF6Z5hxK18JIfP3DBwpsVEoGV84sdJsVB1SG2V9nzn8rP2sh+okS+HJLzHkGZ/MV3aszxmS9frxIhoO16M/2sYRflutVrFYLGI4HKbAhJ2mMyYMMACB5QAAE4VJREFU1BUguHZzGgWyXdZMM/CY1cffFYBrXzqZ/Rw6qbJxzpPzKKDcZdnPtR3Pdt1B78pz9QIcKEBgB+/K3YW66FOpXAWsJV7aQIN+dgBG9wmoDpbamOnDcDiMX//61/GrX/0q/v3f/z0+fPiw5Scy+5LZra76gHTT6TRms1lnwFYEDgi/ZIUxAlViIxbRvOykjTKHikbuuh/AOdO2gQPitfPMUaoCaV0ZGOD8zti5z275QgGbltV1pyxvpCn1FRwcbxxVKhltTtMGULgs5pPTlcpH+iydOhtXX1a2GovSOMgAC75n/PHMQtf+ATLUcWFvhN6Gp3ywfBzPqKNtZlWSA4O2Uh9kRh5y1jcGZnWVnHVmT7S8rmAX5XRZ529zYlwvfmubfbPz0na7+ktHKB1fujyr92c4++/GU0bqfJVfTlNykI7aQF+J3Mk6PN+lXAcw2V7j2Xq9juFwGP/4j/8Y6/U6/uVf/qV+95HqYwZCMmoDjxGPEUFe5miTU1HjsVkJm2B0QyFIZ9KomP9KjigbqDxoer1efZVtNlAdSi05dKRhPnWG6AYGo26kcxu6OC2INzYpL4pcS8cAIXOs8fNvJTCnQIPp8PAwXr16VTSEkBHWUlkn3KmXEgBwYIfzqkHkTZAlNK15OX0b0CkNtC7A0LUve5aBCTgj3ujGv7tlB5THOn9/f188ppXxA1mz0XJ9p3Llkzau33VTn44jJjWaenoqc474r/LqAhq0nIyU/11J5Qo7m21sc8a8zbC7MkpAyqV3Nt/pi+phaaxlwLU0/li3eHKj8shsKkdknI/KyOmIc9xV9bCheDKZWCfvNiSy7tzd3cUf//jH+Od//ud48+aNXSrUvMp/Fz1UUIjv6pu7gKtixMG9Pz17K2BEc+bSFlblvBBSaZMSDCF/7zpoFcFr/RnY6DqAs3byoON69YVdzvHzGrHWn6FPfO7S8Y7m83l94ZC2Q40d/hgwweG5zao8gLVsDZnrc1DmxBwxv1xu1qfut6xM8MdAs01fdp0VOH6dbjpDpfU5g8o6x/mqyr/qt43nNqemDl8NoCPn4LuOeZevBFS/hDJe2sCn02FEdvjFchnfGGdcXld7yPnx3/U5p20DHa79JX4UEOIdJGwXtc1YNnGA1elUxGO0jjcN8hhSuai88T0b42y/1T9FbN9Hkclys9nE5eVl/Nu//Vvc3d1ZXtSGdRkT2fhyNoPzdLGxO105vQvSca8eVkFsNpvo9/uNEwEN5ihMWkKXGUrFb1nIlgcQf87KZIGqU9Md6Ay42JG6AapydW8C5f88oPUK7pJSaFtUXsvlMj5//rwFEvA79wfPLpm6LIuwLmCjpeZz5XA/cb+VjkRpn7Y5cUdqmPb29uL4+Diqqorz8/OddvGDHAhUPWAgxnyUnAX/pqdNuD/ZWWRG08nJ6a4z9i6/nt7I0pecpsqqRF0MZ6mtu1KbTcRvqoP39/fpy/D4M/eh2xxXakNma9juOZCKz26zoLbJ6UDWfraNq9Uqjo+P4/r6emv5U8cedEjv4YENyDZsZnLS504v2N660wkR0bh7RPUU0XKAAncMnCPImfwUPGTpHGnfcptKtiijInDAjmzdze0YUgPuwk+apqoqizJBCNnsauxLiEmVO3NQzLd+VkUCjwxQuB4e5Ow0dXNlxhvLEZ+xROHkkskqkwm3hdM5pK3t4vQlww7QobLBBUttiqrGpO0NpSgzM8ZZPsc79xmAHcaGgqsuTiP7zX1mI+sGu+Nd+4OXLJxzcLNXRwqONe2u4In57kK7lO/6umvf6NjLAEhGJUBUcmIlPrVu1mmN8rn8XLe2T/vdAfMut2GW2qLlY3M17iKBPXP8IA+iBgx02HZl9gjU5SVuPMZUfiBsTtelOW2nth3P4Sc4uuDArY59/Nc62myZAw0lsFDaDlDLoPjr/xXolifUESKtixC43dtshPleeuegM4Pm0pcGndbf9rurD//ZEGfOg8twyuQ2pfHAxnd2fvpGvZIj0lmJAiU9GeHWDZkvPoLJ9QBFa6QElK3J6xIVy0dlyfna2s584Y9f9RwR9QwPRqzXe3z9s6tPnffNzc3WcooaM8dLRs4Bs546A+OurkZerJvzuX6tX9dS+/1+fW313d1dGnHEMxeK7epcuxDLk3kojVGXl58pv9yuUp+5flUq1cffM561P9uAAMZr19MZHDHU9mUbZN3EjeXfBcxlNp2f4W27znYyP04XGDy02QvVHXaSbIvY9qqubzYPkfLb29utE0/uBJsC95OTkzg+Po63b9823v2ibcr0lds7GAxqAKLHOB04KOkUy+cnAwcQdwoLNzO0bcSCyN4O1zYoSqhQl0p24a3kjJ2BV+PilBzyK/GM/IyotfPhnEtycZtxsjZ0aXcpjQ5Y5zyZX5YVQv4XFxfFaFapHRnQUPm5ex9Y3ljycUsbDNq4bN10lW1u47K6/F6SNYNsnRXjfRX9fr8GSrPZrHiiQenw8DCm02mj/CzKoIaZZaEGsK39rt3OoStxH+mSkeoD59Fys7GtZbWNH6Rxe0hKhL6NiK1wteMFz/k31WsdH7o0lZ2y0HZmtqStPcxTBj75f6kcTZNtqHVp1CYjLcthNBrFcrlsbMLUdEyLxaIxPnivSMTjRmCMI7YP5+fncX19HfP5vFFXqT7XTj6UkPmDko9y8oIetvHQChzUEOszh/6YQVcWiI2g+30XNKtGzN2gpgZe87nveMZtZyXUWZvyg05wSDRzhOr0mHcuQ8vNdhxnBq8NWKkh6TLoXdvcoO31Hm4Bvby87HxMV6m0Bwf/M0DKlF16ov2sOubSl5xLSZ/bylYH4Zx2VVVxdHQUL1++jM1mE+/fv7dgisvh7/f393FxcVGXz5uj2cjqWi7605XvbjoEla785vRcrtuXUQIYbf3E9TvAqEDI7TnhzzxOS21y/PEdHhwN0zJLeoR7F7AE6NruZKcy0ef6X9NE5HuwoEtZux2P2k6W/Zf4CW6LLl+Ox+P49a9/HW/fvo3Pnz83+lKjitjAqhFytsVqK1XOfKOrtleBtusrjtTykmkpSsB5s9tFnY/LqAgcsk0crrIIj+r1ORPvdP25qNTgtvALSAXXxh/aoJsjwQ//rgNUnWrmNJCeZyU8EKBk7ODw3xm6LyU1Gm1rq1wnZIKQ+GKxsMsfXevW54z23fJYRDROjXQ18F0cfimNA7e7kDPurGOsV5PJJMbjccMwqWPPeAbgLlH2SnI2TGp4s8lEpusZKNLPbl9QJuNMhvqdy3HAM+vLrG4HQLLy9DXbEdvRWC3DOR3uQy7fjUVOV5rFl+x0yQlhs2NX0KCkfd6W14EszMyz8bxareLq6qp+qyzAAuSB6LWLYChp9LWNV0eZLrXZoza/tbe3F8PhML1SmvcUttnk1iunQc4gMKOYXaiz0kY5Y6MN1ZkMytbNM07Auyh32/OScnA6Z6DdrFDbqJt59Hdn1Fiuagy5HvfMrVe2ASSNCmVOB+lcHzJBRoPBoL7khHnh/lUC7+7WSpaX6i3rqjuzXDJqXdB35jC0nFK9nMfpA1O/349erxcHBwcxnU7rNt3d3cXZ2VmsVqv45S9/WS87YFc31rg5xJrNntThQe6QLwMFAJblctlwfqiH+wAb4tz4raoq+v1+zVcmG+5n7E/hjXNZBCNroy4xtYEbF9VT3jC+1VZkfEU0QUJJJ1V3uN28zMFvG1UZYm+Z8qzkgEdbO9qeZXV0eaaXUHEdbFNBGlXjsjAW5vN5vH79urFMwXoPXWXwwPW6PVyuz7Lxnckdf+z3+v1+RDSvnR+Px3F/f78VZVJ9xo2yjqAnaONPAg7MABtqdhIsLHYyKgznJJUyRKyAA8qzS/irK30JGnYGSUNqTll0zTzCRxTYmCgwU8PLRp7T4XcHQDLSul3bHSCEIVe+QPy6ai7PycqlcXti3EDjtmazAFeOc5pcnlLJ8GVOZpcyQLgkCPp1dXW1FVkAGHv58mV888039Uujnj9/Hl999VUsl8s4Pz+vnfTZ2VnMZrNYLpcNY+RmbpADG2/IZbFYbI0FFxGIiBiNRrG3t1fzynmyU1bus84M8RuXCR6wf4XDvMxfFzsC4NlVD9wSZhfKlkO61MnPoCclx1TiLXNwGbAvUdaObFw6HrJ+0nGa6a3mQfSR787IbLdG7Fz0gWXaFTC12RaXBxu5MRa//vrruLq6ik+fPjXKws3PDMLdsjA2WKJ8BUiOisABTHBIFIZZZwARzXUe59TVwZTqRR42DDzT4HL5t58DPDAP7hk6BMJ2Ro1RqlMMFypkxMyy5LJLBl2NQVVV9c56zCy5HTpzd7NxhBr1OCWMouORnVtVPawhrlarWl7Za5MzUrDkZh0qP06ftZnLZuoarlNSo6Hr0xmQzPI7wmzcjSd8Xi6X8fvf/z5OT0/rTV8IxeL4G266Q73O6GXgzBmV5XJpN+Vy+zm6kW3YdIDWGXJuN2yEWwpkueAz6kV0g+2athe8qlNxfeVsotafEedxJ3W0jzO5ad+5JTsGJs4RZ4CB6UvGhyMH5F2d/Jz/cwQN5ekSXgmEtekJ81La6Mn5Xd+XZNXVH/Z6D5dl7e/vN46xf/z4ccsXVVUVw+Ew7u7uGndjuLp4POKz3tuhtBNwUIellavgeODxoMZsmJWbUR13NpSDhe/ee/FzgYYunTgcDmM+n2+hT86P9rgXZDkQ4QZ4BoYyp+l+x1EdyF3lyps7mXfwwmm1fZqe283hcN0I5IyuAtCMnKFTXhVc8aaqUiQok+GuusX91yWy4/K7Ptc1cNUTtAHGAq/h1ugg0mVt5/KZHwdmlWfmSYEu/rs9Jgq4NQ/0Chu7qmr7pllHCsRVTgp2eMxl4KZEJd1yNhM87rL/ij+Xxg0vLZX2pvGzbExmbdCydp0QZE61NOYyIIN8OiZ03LMeMrjP7J8+y2yl6/uuoMB9V2e/2Wzq/QnQzcFgUE/K4G96vYdTIhzZBc/9fr8xiYQcEM3sEm2I6HiqghEX1hVZUG5vAzsbhAgZFTFIYICy2TyGA3Xwuo506Fz/MznkVUJj3G7Uh0003KFutuUMG4Mgp6BKzvGowdC2ZBvY8Fxn4pyH+4WXTbiPXBuqqqpDXuhvNdooO3s5VgkkqdNyjkWfq44448B5dH28ZIzwOz9za51a1y7UxXBmZTsgz+QMYebII5onJHhsg9zyBvJDv7guBXD8G35XHljvuC51Ppljge0Cv65PMxCBzw5MMO/9fj+q6mHpxqVjmeBzaU251L8gnWE7+5f9byubybU9k3sGMvg3HbNtPJVsealPOI36kxIvTlZq97gulb2Lxmp5uwI1+FCUjc3Q7969q+ucTCYxmUxivV437qZR38DjquvpDFDn45iogMPQQLS88Qm/MQHFsCNyxhz1MQrkGbHypM67bXBoh/NMmweddp6e73fr9wqGMoef3cBWcppZOvd7FpZzcnLfWZk00tPv9+tdueh3jiZhCQdG08ksMyhuwJYcXtv3Nnm2/ZYZB5Ujg41erxf9fr/RluVy2XpSoURZO0pgs9SmUhoH0ng8qLPDd95zpJvzIpqOTeXK5TKf2o8MPl0+8OHAi/Lu2s/52jaHlZxMv99vXMqjstMyOG9ps7TjgfnFM94kqmlKUQen813a3pYu45nrzL5rPs3LbdPlRQcKQW2TUa6PN5Bq+0t1uQ23beOvC4EPjKXLy8u4vLxs2P3VahUfP37ceuMlfDAueWNwDj+Lu2Dajsi3LlU4VAYmkIY/syMGo7pBR1GbU0bn0Fl4zBOnyxTGlY0dqYgi8O/Iw3XoQOV26Qy7TVFKA8+hUNeeNgerBj5D17qJi/udFQtOsKoeLhvC+jmU7ObmJuUhonnFKstCDaejrgYtkwPam8nNydBd4uL4RnhwOBzG8fFxLBaLGAwGMRgM4tOnTzGdTou8u3pVt7qASqaSDrZRm+PSsvf29uLo6Ciurq62AKfywLN+lKXLZSVgjDwR2/cGqLHO8pWeuwkLyub9GRoxQd75fL51GyAok2Xp9xKx7ePvrnyWj6urC1AqPXeOVYnTqE3iNDq+3G8ZX07n2Q4pfzzOsr7I7GaJV33WpW9VPiUfBpvASxTY6Ak7zGUAFBwcHMTJyUl8/vy5Pg6vk+YudmOnUxVQPIf62UEweplMJvUxEL65TxExE0cueFbLg1VfXJV1ID93N/9hkLNyKFApAZyI7atikZaBTFfS9M6Yauc6UIP+0LU9NTQgdk4w7qxQOAYEfvr9fnz33Xfx7t07e/6c+Uf41r3MTAEKPy8ZrAxItuXF7y6dlss6XzIMiDRMJpPY29uL09PTGA6H8eHDhwYg7UoK4vhFZrvoEqg0S/9SYnnc3d01LvICkEJ97mV30Ac3zhQEOMPOeVjHM2fW1dgz6YxMZ2c8WYnYfpcHnnG7OdrqnNEulDlJbSvk+SV1ZeVndlZt3pcA/lL52b4TV5+LUCmAUrmovXU87tKmXfxAZoucPPnYMu9t0Kgf6zp86OfPn+ulCZwsYZ/LV5OnvP5chuSJnuiJnuiJnuiJ/v+nblt5n+iJnuiJnuiJnuiJ4gk4PNETPdETPdETPdEO9AQcnuiJnuiJnuiJnqgzPQGHJ3qiJ3qiJ3qiJ+pMT8DhiZ7oiZ7oiZ7oiTrTE3B4oid6oid6oid6os70v3p/IYlcjP2yAAAAAElFTkSuQmCC\n" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" } + ], + "source": [ + "labels[0].plot(scale=0.5)" ] } - ] + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "collapsed_sections": [], + "name": "SLEAP - Data structures.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.12" + } + }, + "nbformat": 4, + "nbformat_minor": 0 } diff --git a/docs/notebooks/Interactive_and_realtime_inference.ipynb b/docs/notebooks/Interactive_and_realtime_inference.ipynb index 2460ccd51..4a3b612a2 100644 --- a/docs/notebooks/Interactive_and_realtime_inference.ipynb +++ b/docs/notebooks/Interactive_and_realtime_inference.ipynb @@ -1,18 +1,4 @@ { - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "name": "SLEAP - Interactive and realtime inference.ipynb", - "provenance": [], - "collapsed_sections": [] - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "accelerator": "GPU" - }, "cells": [ { "cell_type": "markdown", @@ -26,16 +12,16 @@ }, { "cell_type": "markdown", + "metadata": { + "id": "DpvQa3M3n7jC" + }, "source": [ "# Interactive and realtime inference\n", "\n", "For most workflows, using the [`sleap-track` CLI](https://sleap.ai/guides/cli.html#sleap-track) is probably the most convenient option, but if you're developing a custom application you can take advantage of SLEAP's inference API to use your trained models in your own custom scripts.\n", "\n", "In this notebook we will explore how to predict poses from raw images in pure Python, and do some basic benchmarking on a simulated realtime predictor that could be used to enable closed-loop experiments." - ], - "metadata": { - "id": "DpvQa3M3n7jC" - } + ] }, { "cell_type": "markdown", @@ -52,197 +38,47 @@ }, { "cell_type": "code", + "execution_count": 1, "metadata": { - "id": "BYxJ2rJOMW8B", "colab": { "base_uri": "https://localhost:8080/" }, + "id": "BYxJ2rJOMW8B", "outputId": "6ef53f4c-5074-4f41-8523-3d989a0f2844" }, - "source": [ - "# This should take care of all the dependencies on colab:\n", - "!pip uninstall -y opencv-python opencv-contrib-python && pip install sleap\n", - "\n", - "\n", - "# But to do it locally, we'd recommend the conda package (available on Windows + Linux):\n", - "# conda create -n sleap -c sleap -c conda-forge -c nvidia sleap" - ], - "execution_count": 1, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "Found existing installation: opencv-python 4.1.2.30\n", - "Uninstalling opencv-python-4.1.2.30:\n", - " Successfully uninstalled opencv-python-4.1.2.30\n", - "Found existing installation: opencv-contrib-python 4.1.2.30\n", - "Uninstalling opencv-contrib-python-4.1.2.30:\n", - " Successfully uninstalled opencv-contrib-python-4.1.2.30\n", - "Collecting sleap\n", - " Downloading sleap-1.2.2-py3-none-any.whl (62.0 MB)\n", - "\u001b[K |████████████████████████████████| 62.0 MB 17 kB/s \n", - "\u001b[?25hRequirement already satisfied: networkx in /usr/local/lib/python3.7/dist-packages (from sleap) (2.6.3)\n", - "Collecting rich==10.16.1\n", - " Downloading rich-10.16.1-py3-none-any.whl (214 kB)\n", - "\u001b[K |████████████████████████████████| 214 kB 51.1 MB/s \n", - "\u001b[?25hRequirement already satisfied: psutil in /usr/local/lib/python3.7/dist-packages (from sleap) (5.4.8)\n", - "Collecting segmentation-models==1.0.1\n", - " Downloading segmentation_models-1.0.1-py3-none-any.whl (33 kB)\n", - "Requirement already satisfied: seaborn in /usr/local/lib/python3.7/dist-packages (from sleap) (0.11.2)\n", - "Collecting jsmin\n", - " Downloading jsmin-3.0.1.tar.gz (13 kB)\n", - "Collecting attrs==21.2.0\n", - " Downloading attrs-21.2.0-py2.py3-none-any.whl (53 kB)\n", - "\u001b[K |████████████████████████████████| 53 kB 1.9 MB/s \n", - "\u001b[?25hCollecting opencv-python-headless<=4.5.5.62,>=4.2.0.34\n", - " Downloading opencv_python_headless-4.5.5.62-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (47.7 MB)\n", - "\u001b[K |████████████████████████████████| 47.7 MB 92 kB/s \n", - "\u001b[?25hCollecting pykalman==0.9.5\n", - " Downloading pykalman-0.9.5.tar.gz (228 kB)\n", - "\u001b[K |████████████████████████████████| 228 kB 67.2 MB/s \n", - "\u001b[?25hCollecting cattrs==1.1.1\n", - " Downloading cattrs-1.1.1-py3-none-any.whl (16 kB)\n", - "Requirement already satisfied: scikit-image in /usr/local/lib/python3.7/dist-packages (from sleap) (0.18.3)\n", - "Requirement already satisfied: numpy<=1.21.5,>=1.19.5 in /usr/local/lib/python3.7/dist-packages (from sleap) (1.21.5)\n", - "Requirement already satisfied: scipy<=1.7.3,>=1.4.1 in /usr/local/lib/python3.7/dist-packages (from sleap) (1.4.1)\n", - "Collecting jsonpickle==1.2\n", - " Downloading jsonpickle-1.2-py2.py3-none-any.whl (32 kB)\n", - "Requirement already satisfied: pyzmq in /usr/local/lib/python3.7/dist-packages (from sleap) (22.3.0)\n", - "Collecting scikit-video\n", - " Downloading scikit_video-1.1.11-py2.py3-none-any.whl (2.3 MB)\n", - "\u001b[K |████████████████████████████████| 2.3 MB 54.6 MB/s \n", - "\u001b[?25hRequirement already satisfied: pyyaml in /usr/local/lib/python3.7/dist-packages (from sleap) (3.13)\n", - "Requirement already satisfied: tensorflow<2.9.0,>=2.6.3 in /usr/local/lib/python3.7/dist-packages (from sleap) (2.8.0)\n", - "Requirement already satisfied: certifi<=2021.10.8,>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from sleap) (2021.10.8)\n", - "Requirement already satisfied: h5py<=3.6.0,>=3.1.0 in /usr/local/lib/python3.7/dist-packages (from sleap) (3.1.0)\n", - "Collecting PySide2<=5.14.1,>=5.13.2\n", - " Downloading PySide2-5.14.1-5.14.1-cp35.cp36.cp37.cp38-abi3-manylinux1_x86_64.whl (165.5 MB)\n", - "\u001b[K |████████████████████████████████| 165.5 MB 64 kB/s \n", - "\u001b[?25hRequirement already satisfied: imageio<=2.15.0 in /usr/local/lib/python3.7/dist-packages (from sleap) (2.4.1)\n", - "Collecting python-rapidjson\n", - " Downloading python_rapidjson-1.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.6 MB)\n", - "\u001b[K |████████████████████████████████| 1.6 MB 42.0 MB/s \n", - "\u001b[?25hCollecting qimage2ndarray<=1.8.3,>=1.8.2\n", - " Downloading qimage2ndarray-1.8.3-py3-none-any.whl (11 kB)\n", - "Requirement already satisfied: scikit-learn==1.0.* in /usr/local/lib/python3.7/dist-packages (from sleap) (1.0.2)\n", - "Collecting imgstore==0.2.9\n", - " Downloading imgstore-0.2.9-py2.py3-none-any.whl (904 kB)\n", - "\u001b[K |████████████████████████████████| 904 kB 70.2 MB/s \n", - "\u001b[?25hRequirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from sleap) (1.3.5)\n", - "Collecting imgaug==0.4.0\n", - " Downloading imgaug-0.4.0-py2.py3-none-any.whl (948 kB)\n", - "\u001b[K |████████████████████████████████| 948 kB 72.4 MB/s \n", - "\u001b[?25hRequirement already satisfied: matplotlib in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (3.2.2)\n", - "Requirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (1.15.0)\n", - "Requirement already satisfied: Pillow in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (7.1.2)\n", - "Collecting opencv-python\n", - " Downloading opencv_python-4.5.5.64-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (60.5 MB)\n", - "\u001b[K |████████████████████████████████| 60.5 MB 1.3 MB/s \n", - "\u001b[?25hRequirement already satisfied: Shapely in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (1.8.1.post1)\n", - "Requirement already satisfied: pytz in /usr/local/lib/python3.7/dist-packages (from imgstore==0.2.9->sleap) (2018.9)\n", - "Requirement already satisfied: python-dateutil in /usr/local/lib/python3.7/dist-packages (from imgstore==0.2.9->sleap) (2.8.2)\n", - "Requirement already satisfied: tzlocal in /usr/local/lib/python3.7/dist-packages (from imgstore==0.2.9->sleap) (1.5.1)\n", - "Requirement already satisfied: typing-extensions<5.0,>=3.7.4 in /usr/local/lib/python3.7/dist-packages (from rich==10.16.1->sleap) (3.10.0.2)\n", - "\u001b[33mWARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', ConnectionResetError(104, 'Connection reset by peer'))': /simple/colorama/\u001b[0m\n", - "Collecting colorama<0.5.0,>=0.4.0\n", - " Downloading colorama-0.4.4-py2.py3-none-any.whl (16 kB)\n", - "Requirement already satisfied: pygments<3.0.0,>=2.6.0 in /usr/local/lib/python3.7/dist-packages (from rich==10.16.1->sleap) (2.6.1)\n", - "Collecting commonmark<0.10.0,>=0.9.0\n", - " Downloading commonmark-0.9.1-py2.py3-none-any.whl (51 kB)\n", - "\u001b[K |████████████████████████████████| 51 kB 8.9 MB/s \n", - "\u001b[?25hRequirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn==1.0.*->sleap) (1.1.0)\n", - "Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn==1.0.*->sleap) (3.1.0)\n", - "Collecting keras-applications<=1.0.8,>=1.0.7\n", - " Downloading Keras_Applications-1.0.8-py3-none-any.whl (50 kB)\n", - "\u001b[K |████████████████████████████████| 50 kB 8.7 MB/s \n", - "\u001b[?25hCollecting image-classifiers==1.0.0\n", - " Downloading image_classifiers-1.0.0-py3-none-any.whl (19 kB)\n", - "Collecting efficientnet==1.0.0\n", - " Downloading efficientnet-1.0.0-py3-none-any.whl (17 kB)\n", - "Requirement already satisfied: cached-property in /usr/local/lib/python3.7/dist-packages (from h5py<=3.6.0,>=3.1.0->sleap) (1.5.2)\n", - "Collecting shiboken2==5.14.1\n", - " Downloading shiboken2-5.14.1-5.14.1-cp35.cp36.cp37.cp38-abi3-manylinux1_x86_64.whl (847 kB)\n", - "\u001b[K |████████████████████████████████| 847 kB 56.7 MB/s \n", - "\u001b[?25hRequirement already satisfied: PyWavelets>=1.1.1 in /usr/local/lib/python3.7/dist-packages (from scikit-image->sleap) (1.3.0)\n", - "Requirement already satisfied: tifffile>=2019.7.26 in /usr/local/lib/python3.7/dist-packages (from scikit-image->sleap) (2021.11.2)\n", - "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->imgaug==0.4.0->sleap) (3.0.7)\n", - "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->imgaug==0.4.0->sleap) (1.4.0)\n", - "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib->imgaug==0.4.0->sleap) (0.11.0)\n", - "Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.1.0)\n", - "Collecting tf-estimator-nightly==2.8.0.dev2021122109\n", - " Downloading tf_estimator_nightly-2.8.0.dev2021122109-py2.py3-none-any.whl (462 kB)\n", - "\u001b[K |████████████████████████████████| 462 kB 69.9 MB/s \n", - "\u001b[?25hRequirement already satisfied: astunparse>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.6.3)\n", - "Requirement already satisfied: gast>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (0.5.3)\n", - "Requirement already satisfied: google-pasta>=0.1.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (0.2.0)\n", - "Requirement already satisfied: protobuf>=3.9.2 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (3.17.3)\n", - "Requirement already satisfied: libclang>=9.0.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (13.0.0)\n", - "Requirement already satisfied: keras-preprocessing>=1.1.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.1.2)\n", - "Requirement already satisfied: wrapt>=1.11.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.14.0)\n", - "Requirement already satisfied: tensorflow-io-gcs-filesystem>=0.23.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (0.24.0)\n", - "Requirement already satisfied: setuptools in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (57.4.0)\n", - "Requirement already satisfied: opt-einsum>=2.3.2 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (3.3.0)\n", - "Requirement already satisfied: grpcio<2.0,>=1.24.3 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.44.0)\n", - "Requirement already satisfied: absl-py>=0.4.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.0.0)\n", - "Requirement already satisfied: tensorboard<2.9,>=2.8 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (2.8.0)\n", - "Requirement already satisfied: keras<2.9,>=2.8.0rc0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (2.8.0)\n", - "Requirement already satisfied: flatbuffers>=1.12 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (2.0)\n", - "Requirement already satisfied: wheel<1.0,>=0.23.0 in /usr/local/lib/python3.7/dist-packages (from astunparse>=1.6.0->tensorflow<2.9.0,>=2.6.3->sleap) (0.37.1)\n", - "Requirement already satisfied: google-auth<3,>=1.6.3 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.35.0)\n", - "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.3.6)\n", - "Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.4.6)\n", - "Requirement already satisfied: tensorboard-plugin-wit>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.8.1)\n", - "Requirement already satisfied: tensorboard-data-server<0.7.0,>=0.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.6.1)\n", - "Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.0.1)\n", - "Requirement already satisfied: requests<3,>=2.21.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (2.23.0)\n", - "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (4.8)\n", - "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.2.8)\n", - "Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (4.2.4)\n", - "Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.7/dist-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.3.1)\n", - "Requirement already satisfied: importlib-metadata>=4.4 in /usr/local/lib/python3.7/dist-packages (from markdown>=2.6.8->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (4.11.3)\n", - "Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata>=4.4->markdown>=2.6.8->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.7.0)\n", - "Requirement already satisfied: pyasn1<0.5.0,>=0.4.6 in /usr/local/lib/python3.7/dist-packages (from pyasn1-modules>=0.2.1->google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.4.8)\n", - "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.0.4)\n", - "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (2.10)\n", - "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.24.3)\n", - "Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.7/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.2.0)\n", - "Building wheels for collected packages: pykalman, jsmin\n", - " Building wheel for pykalman (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Created wheel for pykalman: filename=pykalman-0.9.5-py3-none-any.whl size=48462 sha256=b43fd016511642d3238f564a820ccced9855d44660a169c46474533d3cf57390\n", - " Stored in directory: /root/.cache/pip/wheels/6a/04/02/2dda6ea59c66d9e685affc8af3a31ad3a5d87b7311689efce6\n", - " Building wheel for jsmin (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Created wheel for jsmin: filename=jsmin-3.0.1-py3-none-any.whl size=13782 sha256=fd47efc594f3416388e6e074d4602a5b5559ce66e69e621778a182409f5a004c\n", - " Stored in directory: /root/.cache/pip/wheels/a4/0b/64/fb4f87526ecbdf7921769a39d91dcfe4860e621cf15b8250d6\n", - "Successfully built pykalman jsmin\n", - "Installing collected packages: keras-applications, tf-estimator-nightly, shiboken2, opencv-python, image-classifiers, efficientnet, commonmark, colorama, attrs, segmentation-models, scikit-video, rich, qimage2ndarray, python-rapidjson, PySide2, pykalman, opencv-python-headless, jsonpickle, jsmin, imgstore, imgaug, cattrs, sleap\n", - " Attempting uninstall: attrs\n", - " Found existing installation: attrs 21.4.0\n", - " Uninstalling attrs-21.4.0:\n", - " Successfully uninstalled attrs-21.4.0\n", - " Attempting uninstall: imgaug\n", - " Found existing installation: imgaug 0.2.9\n", - " Uninstalling imgaug-0.2.9:\n", - " Successfully uninstalled imgaug-0.2.9\n", - "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", - "datascience 0.10.6 requires folium==0.2.1, but you have folium 0.8.3 which is incompatible.\n", - "albumentations 0.1.12 requires imgaug<0.2.7,>=0.2.5, but you have imgaug 0.4.0 which is incompatible.\u001b[0m\n", - "Successfully installed PySide2-5.14.1 attrs-21.2.0 cattrs-1.1.1 colorama-0.4.4 commonmark-0.9.1 efficientnet-1.0.0 image-classifiers-1.0.0 imgaug-0.4.0 imgstore-0.2.9 jsmin-3.0.1 jsonpickle-1.2 keras-applications-1.0.8 opencv-python-4.5.5.64 opencv-python-headless-4.5.5.62 pykalman-0.9.5 python-rapidjson-1.6 qimage2ndarray-1.8.3 rich-10.16.1 scikit-video-1.1.11 segmentation-models-1.0.1 shiboken2-5.14.1 sleap-1.2.2 tf-estimator-nightly-2.8.0.dev2021122109\n" + "\u001b[31mERROR: Cannot uninstall opencv-python 4.6.0, RECORD file not found. Hint: The package was installed by conda.\u001b[0m\u001b[31m\n", + "\u001b[0m\u001b[31mERROR: Cannot uninstall shiboken2 5.15.6, RECORD file not found. You might be able to recover from this via: 'pip install --force-reinstall --no-deps shiboken2==5.15.6'.\u001b[0m\u001b[31m\n", + "\u001b[0m" ] } + ], + "source": [ + "# This should take care of all the dependencies on colab:\n", + "!pip uninstall -qqq -y opencv-python opencv-contrib-python\n", + "!pip install -qqq \"sleap[pypi]>=1.3.3\"\n", + "\n", + "\n", + "# But to do it locally, we'd recommend the conda package (available on Windows + Linux):\n", + "# conda create -n sleap -c sleap -c conda-forge -c nvidia sleap" ] }, { "cell_type": "markdown", - "source": [ - "Import SLEAP to make sure it installed correctly and print out some information about the system:" - ], "metadata": { "id": "qjfoeOZvpV8o" - } + }, + "source": [ + "Import SLEAP to make sure it installed correctly and print out some information about the system:" + ] }, { "cell_type": "code", + "execution_count": 2, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -250,31 +86,38 @@ "id": "jftAOyvvuQeh", "outputId": "5c415dbc-7ecf-46db-8271-c17cc89552a4" }, - "source": [ - "import sleap\n", - "sleap.disable_preallocation() # This initializes the GPU and prevents TensorFlow from filling the entire GPU memory\n", - "sleap.versions()\n", - "sleap.system_summary()" - ], - "execution_count": 2, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "INFO:numexpr.utils:NumExpr defaulting to 2 threads.\n", - "SLEAP: 1.2.2\n", - "TensorFlow: 2.8.0\n", + "SLEAP: 1.3.2\n", + "TensorFlow: 2.7.0\n", "Numpy: 1.21.5\n", - "Python: 3.7.13\n", - "OS: Linux-5.4.144+-x86_64-with-Ubuntu-18.04-bionic\n", + "Python: 3.7.12\n", + "OS: Linux-5.15.0-78-generic-x86_64-with-debian-bookworm-sid\n", "GPUs: 1/1 available\n", " Device: /physical_device:GPU:0\n", " Available: True\n", " Initalized: False\n", " Memory growth: True\n" ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-09-01 13:56:37.731425: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:56:37.735933: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:56:37.736867: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n" + ] } + ], + "source": [ + "import sleap\n", + "sleap.disable_preallocation() # This initializes the GPU and prevents TensorFlow from filling the entire GPU memory\n", + "sleap.versions()\n", + "sleap.system_summary()" ] }, { @@ -290,54 +133,79 @@ }, { "cell_type": "code", + "execution_count": 3, "metadata": { - "id": "sDIF3RKdM86u", "colab": { "base_uri": "https://localhost:8080/" }, + "id": "sDIF3RKdM86u", "outputId": "5d435b70-d296-4e19-b1b1-0cd9d509e9f3" }, - "source": [ - "!curl -L --output video.mp4 https://storage.googleapis.com/sleap-data/reference/flies13/190719_090330_wt_18159206_rig1.2%4015000-17560.mp4\n", - "!curl -L --output centroid_model.zip https://storage.googleapis.com/sleap-data/reference/flies13/centroid.fast.210504_182918.centroid.n%3D1800.zip\n", - "!curl -L --output centered_instance_id_model.zip https://storage.googleapis.com/sleap-data/reference/flies13/td_id.fast.v2.210519_111253.multi_class_topdown.n%3D1800.zip\n", - "!ls -lah" - ], - "execution_count": 3, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ " % Total % Received % Xferd Average Speed Time Time Time Current\n", " Dload Upload Total Spent Left Speed\n", - "100 81.3M 100 81.3M 0 0 119M 0 --:--:-- --:--:-- --:--:-- 119M\n", + "100 81.3M 100 81.3M 0 0 23.7M 0 0:00:03 0:00:03 --:--:-- 23.7M\n", " % Total % Received % Xferd Average Speed Time Time Time Current\n", " Dload Upload Total Spent Left Speed\n", - "100 6223k 100 6223k 0 0 23.2M 0 --:--:-- --:--:-- --:--:-- 23.2M\n", + "100 6223k 100 6223k 0 0 30.2M 0 --:--:-- --:--:-- --:--:-- 30.3M\n", " % Total % Received % Xferd Average Speed Time Time Time Current\n", " Dload Upload Total Spent Left Speed\n", - "100 32.2M 100 32.2M 0 0 62.4M 0 --:--:-- --:--:-- --:--:-- 62.4M\n", - "total 120M\n", - "drwxr-xr-x 1 root root 4.0K Apr 3 23:33 .\n", - "drwxr-xr-x 1 root root 4.0K Apr 3 23:31 ..\n", - "-rw-r--r-- 1 root root 33M Apr 3 23:33 centered_instance_id_model.zip\n", - "-rw-r--r-- 1 root root 6.1M Apr 3 23:33 centroid_model.zip\n", - "drwxr-xr-x 4 root root 4.0K Mar 23 14:21 .config\n", - "drwxr-xr-x 1 root root 4.0K Mar 23 14:22 sample_data\n", - "-rw-r--r-- 1 root root 82M Apr 3 23:33 video.mp4\n" + "100 32.2M 100 32.2M 0 0 14.5M 0 0:00:02 0:00:02 --:--:-- 14.5M\n", + "total 1.1G\n", + "drwxrwxr-x 5 talmolab talmolab 4.0K Sep 1 13:56 .\n", + "drwxrwxr-x 10 talmolab talmolab 4.0K Aug 31 15:43 ..\n", + "-rw-rw-r-- 1 talmolab talmolab 82M May 20 2021 190719_090330_wt_18159206_rig1.2@15000-17560.mp4.1\n", + "-rw-rw-r-- 1 talmolab talmolab 1.6M May 20 2021 190719_090330_wt_18159206_rig1.2@15000-17560.slp\n", + "-rw-rw-r-- 1 talmolab talmolab 1.6M May 20 2021 190719_090330_wt_18159206_rig1.2@15000-17560.slp.1\n", + "drwxrwxr-x 2 talmolab talmolab 4.0K Jun 20 10:00 analysis_example\n", + "-rw-rw-r-- 1 talmolab talmolab 713K Jun 20 10:00 Analysis_examples.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 33M Sep 1 13:56 centered_instance_id_model.zip\n", + "-rw-rw-r-- 1 talmolab talmolab 6.1M May 20 2021 'centroid.fast.210504_182918.centroid.n=1800.zip'\n", + "-rw-rw-r-- 1 talmolab talmolab 6.1M May 20 2021 'centroid.fast.210504_182918.centroid.n=1800.zip.1'\n", + "-rw-rw-r-- 1 talmolab talmolab 6.1M Sep 1 13:56 centroid_model.zip\n", + "drwxrwxr-x 4 talmolab talmolab 4.0K Sep 1 13:30 dataset\n", + "-rw-rw-r-- 1 talmolab talmolab 481K Sep 1 13:49 Data_structures.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 661K Aug 31 12:52 fly_clip.mp4\n", + "-rw-rw-r-- 1 talmolab talmolab 4.1K Jun 20 10:00 index.rst\n", + "-rw-rw-r-- 1 talmolab talmolab 197K Sep 1 13:53 Interactive_and_realtime_inference.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 120K Aug 31 12:25 Interactive_and_resumable_training.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 620M Aug 31 12:14 labels.pkg.slp\n", + "-rw-rw-r-- 1 talmolab talmolab 1.6M Aug 31 12:05 labels_with_images.pkg.slp\n", + "-rw-rw-r-- 1 talmolab talmolab 158K Aug 31 12:35 Model_evaluation.ipynb\n", + "drwxrwxr-x 4 talmolab talmolab 4.0K Sep 1 13:39 models\n", + "-rw-rw-r-- 1 talmolab talmolab 157K Aug 31 12:52 Post_inference_tracking.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 412K Aug 31 12:52 predictions.slp\n", + "-rw-rw-r-- 1 talmolab talmolab 422K Aug 31 12:52 retracked.slp\n", + "-rw-rw-r-- 1 talmolab talmolab 30M May 20 2021 'td_fast.210505_012601.centered_instance.n=1800.zip'\n", + "-rw-rw-r-- 1 talmolab talmolab 30M May 20 2021 'td_fast.210505_012601.centered_instance.n=1800.zip.1'\n", + "-rw-rw-r-- 1 talmolab talmolab 30M May 20 2021 'td_fast.210505_012601.centered_instance.n=1800.zip.2'\n", + "-rw-rw-r-- 1 talmolab talmolab 78M May 6 2021 test.pkg.slp\n", + "-rw-rw-r-- 1 talmolab talmolab 89M Sep 1 13:42 trained_models.zip\n", + "-rw-rw-r-- 1 talmolab talmolab 94K Sep 1 13:44 Training_and_inference_on_an_example_dataset.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 12K Aug 31 11:39 Training_and_inference_using_Google_Drive.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 82M Sep 1 13:56 video.mp4\n" ] } + ], + "source": [ + "!curl -L --output video.mp4 https://storage.googleapis.com/sleap-data/reference/flies13/190719_090330_wt_18159206_rig1.2%4015000-17560.mp4\n", + "!curl -L --output centroid_model.zip https://storage.googleapis.com/sleap-data/reference/flies13/centroid.fast.210504_182918.centroid.n%3D1800.zip\n", + "!curl -L --output centered_instance_id_model.zip https://storage.googleapis.com/sleap-data/reference/flies13/td_id.fast.v2.210519_111253.multi_class_topdown.n%3D1800.zip\n", + "!ls -lah" ] }, { "cell_type": "markdown", - "source": [ - "**Note:** These zip files just have the contents of standard SLEAP model folders that are generated during training." - ], "metadata": { "id": "0edP4yp7PMJy" - } + }, + "source": [ + "**Note:** These zip files just have the contents of standard SLEAP model folders that are generated during training." + ] }, { "cell_type": "markdown", @@ -354,32 +222,45 @@ }, { "cell_type": "code", - "source": [ - "predictor = sleap.load_model([\"centroid_model.zip\", \"centered_instance_id_model.zip\"], batch_size=16)" - ], + "execution_count": 4, "metadata": { "id": "cC7IKtPDOktW" }, - "execution_count": 4, - "outputs": [] + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-09-01 13:57:04.806004: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX512F FMA\n", + "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n", + "2023-09-01 13:57:04.807011: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:57:04.807970: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:57:04.808962: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:57:05.103658: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:57:05.104377: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:57:05.105059: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:57:05.106019: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1525] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 21129 MB memory: -> device: 0, name: NVIDIA RTX A5000, pci bus id: 0000:01:00.0, compute capability: 8.6\n" + ] + } + ], + "source": [ + "predictor = sleap.load_model([\"centroid_model.zip\", \"centered_instance_id_model.zip\"], batch_size=16)" + ] }, { "cell_type": "markdown", + "metadata": { + "id": "w7xGANT7PfmL" + }, "source": [ "This function handles all the logic of loading trained models, reading the configurations used to train them, and constructs inference models that also include non-trainable operations like peak finding and instance grouping.\n", "\n", "Next, we'll load a video that we want to use for inference. SLEAP `Video` objects don't actually load the whole video into memory, they just provide a common numpy-like interface for reading from different file formats:" - ], - "metadata": { - "id": "w7xGANT7PfmL" - } + ] }, { "cell_type": "code", - "source": [ - "video = sleap.load_video(\"video.mp4\")\n", - "video.shape, video.dtype" - ], + "execution_count": 5, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -387,199 +268,128 @@ "id": "CJ9-vuddPelx", "outputId": "9f09d46d-6808-471e-9aed-92a408b97b06" }, - "execution_count": 5, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "((2560, 1024, 1024, 1), dtype('uint8'))" ] }, + "execution_count": 5, "metadata": {}, - "execution_count": 5 + "output_type": "execute_result" } + ], + "source": [ + "video = sleap.load_video(\"video.mp4\")\n", + "video.shape, video.dtype" ] }, { "cell_type": "markdown", - "source": [ - "Our predictor is pretty flexible. It can handle a variety of different input formats, all of which will return a `Labels` object that contains all of our predictions:" - ], "metadata": { "id": "O3xA6cuTQ6sG" - } + }, + "source": [ + "Our predictor is pretty flexible. It can handle a variety of different input formats, all of which will return a `Labels` object that contains all of our predictions:" + ] }, { "cell_type": "code", - "source": [ - "# Load frames to a numpy array.\n", - "imgs = video[:100]\n", - "print(f\"imgs.shape: {imgs.shape}\")\n", - "\n", - "# Predict on numpy array.\n", - "predictions = predictor.predict(imgs)\n", - "predictions" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 68, - "referenced_widgets": [ - "d6ca46c1a214448098ad47270939d0c2", - "64f2d6a13449451190f6a01f3312235b" - ] - }, - "id": "IdhwFe1dRG2K", - "outputId": "f5b7d30c-4fad-48b6-9652-c83933c9adf8" - }, "execution_count": 6, + "metadata": {}, "outputs": [ { - "output_type": "display_data", "data": { - "text/plain": [ - "Output()" - ], "application/vnd.jupyter.widget-view+json": { + "model_id": "0cc2e3a471764285a58d023906ba1f7a", "version_major": 2, - "version_minor": 0, - "model_id": "d6ca46c1a214448098ad47270939d0c2" - } + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "imgs.shape: (100, 1024, 1024, 1)\n" ] }, { - "output_type": "display_data", - "data": { - "text/plain": [ - "" - ], - "text/html": [ - "
\n"
-            ]
-          },
-          "metadata": {}
-        },
-        {
-          "output_type": "display_data",
-          "data": {
-            "text/plain": [
-              "\n"
-            ],
-            "text/html": [
-              "
\n",
-              "
\n" - ] - }, - "metadata": {} - }, - { - "output_type": "execute_result", - "data": { - "text/plain": [ - "Labels(labeled_frames=100, videos=1, skeletons=1, tracks=2)" - ] - }, - "metadata": {}, - "execution_count": 6 - } - ] - }, - { - "cell_type": "code", - "source": [ - "# Predict on the entire video with parallelizable loading/preprocessing:\n", - "predictions = predictor.predict(video)\n", - "predictions" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 51, - "referenced_widgets": [ - "0e9d4c257a4d4c45b02337a0e038e45e", - "fb2df858b0a444edb4b0f429743abd9f" + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-09-01 13:57:13.455046: I tensorflow/stream_executor/cuda/cuda_dnn.cc:366] Loaded cuDNN version 8201\n" ] }, - "id": "McsFHqx0Q6F0", - "outputId": "a648dac3-6e78-4fbd-e4b1-91389ead143d" - }, - "execution_count": 7, - "outputs": [ { - "output_type": "display_data", - "data": { - "text/plain": [ - "Output()" - ], - "application/vnd.jupyter.widget-view+json": { - "version_major": 2, - "version_minor": 0, - "model_id": "0e9d4c257a4d4c45b02337a0e038e45e" - } - }, - "metadata": {} + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-09-01 13:57:15.358483: I tensorflow/stream_executor/cuda/cuda_blas.cc:1774] TensorFloat-32 will be used for the matrix multiplication. This will only be logged once.\n" + ] }, { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "
\n"
-            ]
+            ],
+            "text/plain": []
           },
-          "metadata": {}
+          "metadata": {},
+          "output_type": "display_data"
         },
         {
-          "output_type": "display_data",
           "data": {
-            "text/plain": [
-              "\n"
-            ],
             "text/html": [
               "
\n",
               "
\n" + ], + "text/plain": [ + "\n" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "execute_result", "data": { "text/plain": [ - "Labels(labeled_frames=2560, videos=1, skeletons=1, tracks=2)" + "Labels(labeled_frames=100, videos=1, skeletons=1, tracks=2)" ] }, + "execution_count": 6, "metadata": {}, - "execution_count": 7 + "output_type": "execute_result" } + ], + "source": [ + "# Load frames to a numpy array.\n", + "imgs = video[:100]\n", + "print(f\"imgs.shape: {imgs.shape}\")\n", + "\n", + "# Predict on numpy array.\n", + "predictions = predictor.predict(imgs)\n", + "predictions" ] }, { "cell_type": "markdown", - "source": [ - "We can then inspect the results of our predictor:" - ], "metadata": { "id": "E8Qm3Y8ERrFb" - } + }, + "source": [ + "We can then inspect the results of our predictor:" + ] }, { "cell_type": "code", - "source": [ - "# Visualize a frame.\n", - "predictions[100].plot(scale=0.25)" - ], + "execution_count": 8, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -588,27 +398,26 @@ "id": "MhPh8uwaRFfT", "outputId": "29e5ae1f-bf9d-44ea-a2fe-573b51faaf67" }, - "execution_count": 8, "outputs": [ { - "output_type": "display_data", "data": { + "image/png": "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", "text/plain": [ "
" - ], - "image/png": "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\n" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" } + ], + "source": [ + "# Visualize a frame.\n", + "predictions[100].plot(scale=0.25)" ] }, { "cell_type": "code", - "source": [ - "# Inspect the contents of a single frame.\n", - "labeled_frame = predictions[100]\n", - "labeled_frame.instances" - ], + "execution_count": 9, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -616,27 +425,28 @@ "id": "Xyz5qfrFR3Cd", "outputId": "203d483f-6e1b-4e1e-ff89-0dc62488edad" }, - "execution_count": 9, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "[PredictedInstance(video=Video(filename=video.mp4, shape=(2560, 1024, 1024, 1), backend=MediaVideo), frame_idx=100, points=[head: (212.5, 427.0, 0.94), thorax: (252.0, 433.1, 0.95), abdomen: (288.6, 439.3, 0.68), wingL: (304.5, 443.3, 0.88), wingR: (306.2, 435.8, 0.68), forelegL4: (216.2, 445.5, 0.88), forelegR4: (216.1, 410.0, 0.90), midlegL4: (244.4, 471.3, 0.90), midlegR4: (256.6, 408.9, 0.86), hindlegL4: (275.0, 459.2, 0.89), hindlegR4: (292.3, 412.0, 0.81), eyeL: (220.0, 438.0, 0.84), eyeR: (223.8, 417.5, 0.91)], score=0.99, track=Track(spawned_on=0, name='female'), tracking_score=0.00),\n", " PredictedInstance(video=Video(filename=video.mp4, shape=(2560, 1024, 1024, 1), backend=MediaVideo), frame_idx=100, points=[head: (313.7, 432.6, 0.87), thorax: (348.9, 427.9, 1.00), abdomen: (378.9, 425.8, 0.83), wingL: (397.0, 428.7, 0.89), wingR: (394.9, 420.7, 0.74), forelegL4: (307.4, 446.4, 0.88), forelegR4: (306.5, 422.5, 0.89), midlegL4: (341.6, 474.2, 0.97), midlegR4: (332.6, 386.3, 0.97), hindlegL4: (378.9, 458.8, 0.92), hindlegR4: (387.7, 394.8, 0.88), eyeL: (323.7, 442.1, 0.96), eyeR: (320.7, 420.8, 0.88)], score=0.99, track=Track(spawned_on=0, name='male'), tracking_score=0.00)]" ] }, + "execution_count": 9, "metadata": {}, - "execution_count": 9 + "output_type": "execute_result" } + ], + "source": [ + "# Inspect the contents of a single frame.\n", + "labeled_frame = predictions[100]\n", + "labeled_frame.instances" ] }, { "cell_type": "code", - "source": [ - "# Convert an instance to a numpy array:\n", - "labeled_frame[0].numpy()" - ], + "execution_count": 10, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -644,10 +454,8 @@ "id": "FDMcaIwtR7he", "outputId": "df3ead74-4505-4680-de86-2dbd531145e1" }, - "execution_count": 10, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "rec.array([[212.51400757, 426.97024536],\n", @@ -655,7 +463,7 @@ " [288.64355469, 439.3086853 ],\n", " [304.53396606, 443.33477783],\n", " [306.20336914, 435.77227783],\n", - " [216.24688721, 445.4755249 ],\n", + " [216.24688721, 445.47549438],\n", " [216.14550781, 409.98342896],\n", " [244.39497375, 471.31561279],\n", " [256.61740112, 408.89056396],\n", @@ -666,30 +474,30 @@ " dtype=float64)" ] }, + "execution_count": 10, "metadata": {}, - "execution_count": 10 + "output_type": "execute_result" } + ], + "source": [ + "# Convert an instance to a numpy array:\n", + "labeled_frame[0].numpy()" ] }, { "cell_type": "markdown", + "metadata": { + "id": "c6kRMZDYSKIp" + }, "source": [ "What if we don't want or need the inference results wrapped in the SLEAP structures?\n", "\n", "By using the low-level inference model, we can actually go directly from image to numpy arrays of our results:" - ], - "metadata": { - "id": "c6kRMZDYSKIp" - } + ] }, { "cell_type": "code", - "source": [ - "imgs = video[:16] # batch of 16 images\n", - "\n", - "predictions = predictor.inference_model.predict(imgs, numpy=True)\n", - "predictions" - ], + "execution_count": 11, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -697,199 +505,30 @@ "id": "pWo_bG1HSJaJ", "outputId": "d22e30e9-13ae-466b-d94c-ce787c96a818" }, - "execution_count": 11, "outputs": [ { - "output_type": "execute_result", + "name": "stdout", + "output_type": "stream", + "text": [ + "4/4 [==============================] - 2s 176ms/step\n" + ] + }, + { "data": { "text/plain": [ - "{'centroid_vals': array([[0.9455479 , 0.8394836 ],\n", - " [0.95911187, 0.85253626],\n", - " [0.9596152 , 0.8630471 ],\n", - " [0.9252076 , 0.9757867 ],\n", - " [0.9740962 , 0.9668303 ],\n", - " [0.98455054, 0.95724756],\n", - " [0.91053814, 0.9752301 ],\n", - " [0.88006395, 0.99431276],\n", - " [0.9113332 , 1.0001038 ],\n", - " [0.9698767 , 0.9948529 ],\n", - " [0.96454954, 0.9799493 ],\n", - " [0.9614236 , 1.0046192 ],\n", - " [0.9535493 , 0.99878174],\n", - " [0.9474647 , 0.98374265],\n", - " [0.9781825 , 0.9867112 ],\n", - " [0.98339975, 0.9842536 ]], dtype=float32),\n", - " 'centroids': array([[[271.8735 , 436.4811 ],\n", - " [355.93707, 435.63477]],\n", - " \n", - " [[272.0215 , 436.42197],\n", - " [356.2099 , 435.4682 ]],\n", - " \n", - " [[272.23578, 436.31976],\n", - " [356.61108, 435.4756 ]],\n", - " \n", - " [[356.57007, 433.15857],\n", - " [272.7147 , 435.9847 ]],\n", - " \n", - " [[356.93347, 432.73026],\n", - " [272.7111 , 435.8055 ]],\n", - " \n", - " [[356.86227, 432.03918],\n", - " [272.64484, 435.49347]],\n", - " \n", - " [[357.0275 , 431.29968],\n", - " [272.49817, 435.54977]],\n", - " \n", - " [[359.29578, 431.42874],\n", - " [272.1338 , 435.81354]],\n", - " \n", - " [[359.7555 , 429.4507 ],\n", - " [272.2437 , 435.95605]],\n", - " \n", - " [[359.9807 , 428.4453 ],\n", - " [272.04776, 436.2247 ]],\n", - " \n", - " [[360.3565 , 427.81192],\n", - " [271.94632, 437.30673]],\n", - " \n", - " [[360.8997 , 427.5365 ],\n", - " [272.4532 , 436.9694 ]],\n", - " \n", - " [[361.10843, 427.52646],\n", - " [272.42938, 436.09125]],\n", - " \n", - " [[361.59042, 425.5916 ],\n", - " [272.44873, 435.94284]],\n", - " \n", - " [[364.18994, 425.5058 ],\n", - " [272.18735, 436.0978 ]],\n", - " \n", - " [[364.8356 , 425.49683],\n", - " [272.1019 , 436.49136]]], dtype=float32),\n", - " 'instance_peak_vals': array([[[0.9913698 , 0.9798432 , 0.755395 , 0.45440078, 0.49718782,\n", - " 0.82649314, 0.8982548 , 0.7941463 , 0.8178157 , 0.05604962,\n", - " 0.06407703, 0.8860661 , 0.9635323 ],\n", - " [0.9033977 , 0.25969282, 0.63431203, 0.83960074, 0.76130724,\n", - " 0.04938019, 0.8405748 , 0.8820077 , 0.8816873 , 0.8243383 ,\n", - " 0.33521542, 0.843406 , 0.8127705 ]],\n", - " \n", - " [[0.9598928 , 0.9734157 , 0.67664635, 0.35409918, 0.49767363,\n", - " 0.8832786 , 0.9271228 , 0.79897636, 0.7574272 , 0.04437801,\n", - " 0.06204455, 0.86091673, 0.89724076],\n", - " [0.88144 , 0.43337217, 0.6627725 , 0.83882016, 0.7175109 ,\n", - " 0.08318386, 0.7553143 , 0.8750135 , 0.89725804, 0.8539097 ,\n", - " 0.87049586, 0.84071857, 0.8853135 ]],\n", - " \n", - " [[0.9277582 , 0.9876474 , 0.71884066, 0.36052445, 0.5332413 ,\n", - " 0.8968105 , 0.9209892 , 0.8180278 , 0.6177353 , 0.03119754,\n", - " 0.07055765, 0.83666456, 0.86083984],\n", - " [0.8386838 , 0.5882865 , 0.7205018 , 0.79034203, 0.70366687,\n", - " 0.21814364, 0.7629925 , 0.85078365, 0.88240033, 0.889361 ,\n", - " 0.855937 , 0.83885545, 0.9163793 ]],\n", - " \n", - " [[0.9318245 , 1.005442 , 0.70377296, 0.44777974, 0.5514284 ,\n", - " 0.8751964 , 0.8788199 , 0.7378154 , 0.60576206, 0.06517099,\n", - " 0.145257 , 0.81688404, 0.88855964],\n", - " [0.8562528 , 0.86021775, 0.82891434, 0.5004723 , 0.8896506 ,\n", - " 0.1508227 , 0.57128006, 0.8668301 , 0.94244254, 0.8910252 ,\n", - " 0.9375358 , 0.92730594, 0.8518941 ]],\n", - " \n", - " [[0.93351734, 0.98755234, 0.6618066 , 0.55908614, 0.5017102 ,\n", - " 0.89124554, 0.8839096 , 0.77439624, 0.5733776 , 0.06467963,\n", - " 0.12731154, 0.81659895, 0.9002954 ],\n", - " [0.9238624 , 0.8279646 , 0.7274185 , 0.8509916 , 0.91163963,\n", - " 0.21640284, 0.41097188, 0.9234465 , 0.8912649 , 0.8676514 ,\n", - " 0.91081864, 0.9236754 , 0.9313458 ]],\n", - " \n", - " [[0.96605366, 0.9777925 , 0.67958933, 0.5347009 , 0.49430045,\n", - " 0.89868015, 0.88998073, 0.82294536, 0.49898368, 0.1423007 ,\n", - " 0.1347502 , 0.846156 , 0.8986051 ],\n", - " [0.8971774 , 0.85703975, 0.74316317, 0.87278455, 0.9055221 ,\n", - " 0.19766904, 0.3356636 , 0.89383155, 0.8715803 , 0.8314053 ,\n", - " 0.92693067, 0.94992954, 0.8578277 ]],\n", - " \n", - " [[0.92144465, 0.98048437, 0.65757245, 0.4610521 , 0.57402426,\n", - " 0.88368344, 0.89460254, 0.8111973 , 0.50101817, 0.24979569,\n", - " 0.16411611, 0.83694774, 0.9241577 ],\n", - " [0.89160013, 0.8712998 , 0.72397256, 0.88281846, 0.7020805 ,\n", - " 0.16116247, 0.36204454, 0.8973186 , 0.8997571 , 0.5167517 ,\n", - " 0.89034295, 0.98887867, 0.8843883 ]],\n", - " \n", - " [[0.89794546, 0.97743154, 0.5481075 , 0.52363163, 0.570176 ,\n", - " 0.8288712 , 0.9113766 , 0.9194614 , 0.57585603, 0.07603604,\n", - " 0.21255916, 0.90180147, 0.9266095 ],\n", - " [0.9199309 , 0.8616993 , 0.78142613, 0.77502143, 0.8532426 ,\n", - " 0.14189675, 0.5463987 , 0.8761284 , 0.9354262 , 0.5091697 ,\n", - " 0.8713986 , 0.862072 , 0.91699666]],\n", - " \n", - " [[0.9048965 , 0.96337247, 0.6176863 , 0.6120858 , 0.53412384,\n", - " 0.8082984 , 0.914149 , 0.8100912 , 0.7064674 , 0.07797385,\n", - " 0.28660813, 0.9255539 , 0.9081667 ],\n", - " [0.9197771 , 0.89081717, 0.769785 , 0.85063875, 0.82405925,\n", - " 0.22763878, 0.7375746 , 0.95731395, 0.95667887, 0.7197969 ,\n", - " 0.87627506, 0.8575353 , 0.8765893 ]],\n", - " \n", - " [[0.9522317 , 0.96551776, 0.728644 , 0.58902043, 0.56121 ,\n", - " 0.7050669 , 0.94214785, 0.39777142, 0.7715537 , 0.617287 ,\n", - " 0.06328648, 1.0118883 , 0.8866795 ],\n", - " [0.9031525 , 0.90114677, 0.7290425 , 0.84665924, 0.855581 ,\n", - " 0.35440993, 0.8101314 , 0.93183535, 0.91998935, 0.9771715 ,\n", - " 0.8836143 , 0.86114466, 0.88294595]],\n", - " \n", - " [[0.9387202 , 0.97103214, 0.6380678 , 0.89064 , 0.6806271 ,\n", - " 0.9067394 , 0.89928854, 0.40190598, 0.7516978 , 0.5388293 ,\n", - " 0.30325472, 0.8661613 , 0.8647857 ],\n", - " [0.9355016 , 0.9346907 , 0.7350116 , 0.8936991 , 0.7947871 ,\n", - " 0.29464447, 0.9174315 , 0.8810758 , 0.89442706, 0.97276264,\n", - " 0.92083865, 0.84369785, 0.94922733]],\n", - " \n", - " [[0.914409 , 0.9727311 , 0.64372706, 0.85304916, 0.6125537 ,\n", - " 0.89858156, 0.89086455, 0.33406293, 0.76246554, 0.64882785,\n", - " 0.18051788, 0.9338125 , 0.903689 ],\n", - " [0.9286875 , 0.93761635, 0.79485124, 0.8181616 , 0.76288086,\n", - " 0.3038448 , 0.8355305 , 0.83106405, 0.91892713, 0.9376198 ,\n", - " 0.94770956, 0.85123426, 0.9446316 ]],\n", - " \n", - " [[0.94501513, 0.95821375, 0.7855571 , 0.7544449 , 0.58367 ,\n", - " 0.8593804 , 0.9449818 , 0.6194321 , 0.7035531 , 0.22808488,\n", - " 0.24900919, 0.981288 , 0.92618316],\n", - " [0.93841255, 0.9422814 , 0.80968684, 0.8445455 , 0.7991051 ,\n", - " 0.49167132, 0.77814525, 0.6231524 , 0.9319882 , 0.9570072 ,\n", - " 0.95540494, 0.9207019 , 0.8778761 ]],\n", - " \n", - " [[0.93817955, 0.9492211 , 0.7767393 , 0.8758958 , 0.38491583,\n", - " 0.88775396, 0.9298349 , 0.8082794 , 0.69305503, 0.1668036 ,\n", - " 0.26728866, 0.9830228 , 0.9346242 ],\n", - " [0.909315 , 0.9609095 , 0.840956 , 0.83797425, 0.8743328 ,\n", - " 0.82546026, 0.32881746, 0.54940474, 0.96532434, 0.98827827,\n", - " 0.85375595, 0.95603913, 0.93167067]],\n", - " \n", - " [[0.9048101 , 0.9246041 , 0.7558464 , 0.80823594, 0.47512585,\n", - " 0.86846614, 0.9260269 , 0.8822637 , 0.7126984 , 0.15086724,\n", - " 0.22018576, 0.9016736 , 0.90536344],\n", - " [0.91812086, 0.9669677 , 0.78534484, 0.88368094, 0.7989964 ,\n", - " 0.6972392 , 0.51700455, 0.8321577 , 0.9426196 , 0.9527976 ,\n", - " 0.9190021 , 0.9706677 , 0.9077022 ]],\n", - " \n", - " [[0.9391487 , 0.93520033, 0.85189587, 0.72796357, 0.6884538 ,\n", - " 0.8768974 , 0.9508925 , 0.6879569 , 0.7112255 , 0.70129263,\n", - " 0.6031595 , 0.8761619 , 0.9142955 ],\n", - " [0.8932256 , 0.9750102 , 0.7894063 , 0.8651795 , 0.7224442 ,\n", - " 0.8268989 , 0.45971498, 0.93260354, 0.9202294 , 0.94214976,\n", - " 0.88344055, 0.9803063 , 0.8976606 ]]], dtype=float32),\n", - " 'instance_peaks': array([[[[234.2223 , 430.62558],\n", - " [271.50427, 436.13205],\n", - " [309.87225, 436.65012],\n", - " [324.12576, 438.39148],\n", - " [320.34717, 435.95013],\n", - " [246.42339, 450.67798],\n", - " [242.37634, 413.81458],\n", - " [285.56247, 460.2276 ],\n", - " [273.45126, 406.51892],\n", + "{'instance_peaks': array([[[[234.2224 , 430.62598],\n", + " [271.5043 , 436.13202],\n", + " [309.87125, 436.64966],\n", + " [324.12512, 438.3908 ],\n", + " [320.3458 , 435.9504 ],\n", + " [246.42352, 450.67786],\n", + " [242.37636, 413.81458],\n", + " [285.5624 , 460.22766],\n", + " [273.45117, 406.51895],\n", " [ nan, nan],\n", " [ nan, nan],\n", - " [241.9709 , 442.32263],\n", - " [245.46785, 421.90225]],\n", + " [241.9716 , 442.32303],\n", + " [245.46788, 421.90228]],\n", " \n", " [[319.80017, 435.48407],\n", " [351.93695, 434.0301 ],\n", @@ -906,19 +545,19 @@ " [328.1667 , 423.94733]]],\n", " \n", " \n", - " [[[234.36911, 430.38037],\n", + " [[[234.36913, 430.38037],\n", " [271.65576, 436.0479 ],\n", - " [311.67505, 437.0108 ],\n", - " [324.4831 , 438.1426 ],\n", - " [322.2054 , 435.06854],\n", - " [246.43256, 450.61487],\n", - " [242.39862, 413.8269 ],\n", - " [285.56503, 460.0099 ],\n", - " [273.78204, 406.4644 ],\n", + " [311.6751 , 437.00995],\n", + " [324.48315, 438.1421 ],\n", + " [322.20544, 435.06784],\n", + " [246.43257, 450.61487],\n", + " [242.3986 , 413.8269 ],\n", + " [285.565 , 460.00977],\n", + " [273.78204, 406.46442],\n", " [ nan, nan],\n", " [ nan, nan],\n", - " [242.11815, 442.0634 ],\n", - " [245.55441, 421.72803]],\n", + " [242.11816, 442.0634 ],\n", + " [245.55441, 421.7281 ]],\n", " \n", " [[320.03793, 435.2389 ],\n", " [353.87274, 434.77695],\n", @@ -949,33 +588,33 @@ " [242.26588, 441.80545],\n", " [245.77664, 420.7662 ]],\n", " \n", - " [[320.46982, 435.25452],\n", - " [354.89542, 434.93198],\n", - " [372.2558 , 433.46106],\n", - " [394.40723, 479.57962],\n", - " [400.3011 , 431.9626 ],\n", - " [306.98218, 449.3156 ],\n", + " [[320.46994, 435.2546 ],\n", + " [354.89484, 434.93176],\n", + " [372.25574, 433.46127],\n", + " [394.40717, 479.5797 ],\n", + " [400.30173, 431.96054],\n", + " [306.9821 , 449.3157 ],\n", " [308.8817 , 421.52148],\n", - " [325.98843, 474.91672],\n", + " [325.98843, 474.9167 ],\n", " [332.17917, 385.04684],\n", - " [363.03186, 473.50638],\n", + " [363.0318 , 473.50616],\n", " [391.05493, 396.85666],\n", - " [329.1689 , 445.0495 ],\n", - " [328.89993, 423.52527]]],\n", - " \n", - " \n", - " [[[234.65546, 429.69464],\n", - " [272.38306, 435.6884 ],\n", - " [311.04346, 437.86926],\n", - " [324.80878, 437.3788 ],\n", - " [322.84747, 433.93933],\n", - " [246.71854, 451.2873 ],\n", - " [242.57391, 413.58414],\n", - " [286.16397, 461.83658],\n", - " [272.8733 , 406.21573],\n", + " [329.16904, 445.04953],\n", + " [328.89996, 423.52533]]],\n", + " \n", + " \n", + " [[[234.65547, 429.6946 ],\n", + " [272.38303, 435.68842],\n", + " [311.04352, 437.86963],\n", + " [324.80847, 437.3792 ],\n", + " [322.84747, 433.93973],\n", + " [246.71852, 451.2873 ],\n", + " [242.57388, 413.58414],\n", + " [286.164 , 461.83655],\n", + " [272.8726 , 406.21753],\n", " [ nan, nan],\n", " [ nan, nan],\n", - " [242.4386 , 441.46246],\n", + " [242.43861, 441.46246],\n", " [245.25829, 420.48416]],\n", " \n", " [[320.7713 , 433.55927],\n", @@ -1054,7 +693,7 @@ " [[[234.15704, 429.3947 ],\n", " [272.1558 , 435.1859 ],\n", " [310.46423, 435.5753 ],\n", - " [324.42407, 437.18857],\n", + " [324.42407, 437.18854],\n", " [322.80786, 433.41486],\n", " [246.72241, 450.9671 ],\n", " [242.64005, 413.65726],\n", @@ -1072,11 +711,11 @@ " [402.97113, 431.12497],\n", " [ nan, nan],\n", " [312.74753, 421.16742],\n", - " [325.3774 , 474.7351 ],\n", + " [325.3774 , 474.73508],\n", " [331.5342 , 384.97403],\n", " [378.56894, 469.3632 ],\n", " [388.81372, 393.89886],\n", - " [330.641 , 439.67197],\n", + " [330.641 , 439.67194],\n", " [329.04425, 418.99023]]],\n", " \n", " \n", @@ -1094,8 +733,8 @@ " [240.58961, 440.1936 ],\n", " [244.4464 , 420.00543]],\n", " \n", - " [[322.69318, 430.96204],\n", - " [358.8828 , 430.98035],\n", + " [[322.69318, 430.96207],\n", + " [358.88284, 430.98035],\n", " [379.26816, 431.0259 ],\n", " [405.7312 , 449.5473 ],\n", " [405.13306, 431.02057],\n", @@ -1130,7 +769,7 @@ " [405.74594, 429.27792],\n", " [315.46356, 441.38046],\n", " [309.48642, 421.8147 ],\n", - " [325.63013, 474.81934],\n", + " [325.63016, 474.81934],\n", " [331.73767, 385.03244],\n", " [399.19778, 461.1395 ],\n", " [388.32227, 394.00305],\n", @@ -1138,32 +777,32 @@ " [330.20728, 418.03998]]],\n", " \n", " \n", - " [[[232.59995, 427.9426 ],\n", - " [271.68756, 435.92496],\n", - " [309.74353, 438.45377],\n", - " [322.3493 , 441.9495 ],\n", - " [322.39355, 436.099 ],\n", - " [246.09337, 450.45764],\n", - " [242.33101, 413.80396],\n", - " [284.40045, 460.55066],\n", - " [273.6091 , 406.4331 ],\n", - " [286.35364, 459.99496],\n", + " [[[232.59984, 427.94275],\n", + " [271.68756, 435.925 ],\n", + " [309.74356, 438.45367],\n", + " [322.3493 , 441.94934],\n", + " [322.39355, 436.09885],\n", + " [246.09349, 450.45755],\n", + " [242.331 , 413.8041 ],\n", + " [284.40057, 460.55066],\n", + " [273.6091 , 406.43307],\n", + " [286.35394, 459.9949 ],\n", " [ nan, nan],\n", - " [240.04811, 440.10532],\n", - " [244.36139, 419.95685]],\n", + " [240.04814, 440.10544],\n", + " [244.36105, 419.95673]],\n", " \n", " [[322.50397, 428.86414],\n", " [359.65952, 428.01282],\n", " [381.80063, 428.2879 ],\n", " [407.9239 , 446.02728],\n", " [406.27682, 428.24774],\n", - " [317.4234 , 444.4193 ],\n", + " [317.42343, 444.4193 ],\n", " [308.38232, 422.35754],\n", " [325.6553 , 474.45853],\n", " [331.8156 , 384.7812 ],\n", " [399.62988, 456.58368],\n", " [388.52002, 394.27118],\n", - " [332.3299 , 438.7801 ],\n", + " [332.3299 , 438.78006],\n", " [330.43085, 417.03174]]],\n", " \n", " \n", @@ -1254,22 +893,22 @@ " [332.6642 , 419.31372]]],\n", " \n", " \n", - " [[[232.83435, 428.2637 ],\n", + " [[[232.83435, 428.26373],\n", " [272.11572, 435.61078],\n", - " [312.17938, 439.66312],\n", - " [322.83755, 442.15845],\n", - " [324.40564, 435.64343],\n", + " [312.17926, 439.66278],\n", + " [322.83746, 442.15924],\n", + " [324.40552, 435.6441 ],\n", " [225.87045, 451.41144],\n", " [242.64131, 413.59937],\n", - " [285.06653, 460.35504],\n", - " [273.84183, 406.37183],\n", + " [285.06647, 460.35507],\n", + " [273.84183, 406.3719 ],\n", " [ nan, nan],\n", - " [322.4148 , 422.6127 ],\n", - " [240.42722, 440.2208 ],\n", - " [244.4097 , 419.95215]],\n", + " [322.41534, 422.61237],\n", + " [240.42723, 440.2208 ],\n", + " [244.4097 , 419.95218]],\n", " \n", " [[327.3499 , 431.52005],\n", - " [361.313 , 425.36264],\n", + " [361.313 , 425.36267],\n", " [389.47607, 423.60114],\n", " [411.6601 , 435.50894],\n", " [409.51843, 419.6943 ],\n", @@ -1289,7 +928,7 @@ " [322.19714, 443.71683],\n", " [324.71207, 434.39133],\n", " [224.85786, 451.4593 ],\n", - " [242.5914 , 413.65204],\n", + " [242.5914 , 413.65207],\n", " [285.67142, 461.77646],\n", " [273.7307 , 406.5118 ],\n", " [ nan, nan],\n", @@ -1298,7 +937,7 @@ " [243.82819, 420.339 ]],\n", " \n", " [[328.47983, 431.74188],\n", - " [363.9317 , 425.2397 ],\n", + " [363.93173, 425.2397 ],\n", " [390.49423, 423.05255],\n", " [413.68115, 433.6671 ],\n", " [410.5454 , 419.09042],\n", @@ -1339,36 +978,214 @@ " [388.68896, 394.04962],\n", " [340.75934, 441.0198 ],\n", " [335.4428 , 419.33124]]]], dtype=float32),\n", - " 'instance_scores': array([[0.9953146 , 0.99476504],\n", - " [0.9959341 , 0.99526805],\n", - " [0.9959078 , 0.99451363],\n", - " [0.99573493, 0.993386 ],\n", + " 'instance_peak_vals': array([[[0.9914025 , 0.9798533 , 0.7552497 , 0.45417705, 0.49756864,\n", + " 0.8265212 , 0.89824754, 0.7941327 , 0.81785023, 0.05611448,\n", + " 0.06403984, 0.88647026, 0.96359974],\n", + " [0.9033977 , 0.25969282, 0.6343123 , 0.8396003 , 0.7613073 ,\n", + " 0.04938014, 0.84057474, 0.8820076 , 0.8816869 , 0.8243384 ,\n", + " 0.33521563, 0.8434063 , 0.8127704 ]],\n", + " \n", + " [[0.9598888 , 0.97341204, 0.6766811 , 0.35414153, 0.49778372,\n", + " 0.883279 , 0.9271338 , 0.7989652 , 0.7574282 , 0.04437362,\n", + " 0.06203796, 0.8609162 , 0.89723104],\n", + " [0.8814398 , 0.43337214, 0.6627722 , 0.8388201 , 0.71751094,\n", + " 0.08318384, 0.7553143 , 0.8750135 , 0.8972577 , 0.85390973,\n", + " 0.87049603, 0.84071857, 0.8853136 ]],\n", + " \n", + " [[0.9277581 , 0.9876475 , 0.71884066, 0.36052382, 0.53324103,\n", + " 0.89681005, 0.92098916, 0.8180281 , 0.6177351 , 0.0311976 ,\n", + " 0.07055778, 0.83666444, 0.8608399 ],\n", + " [0.8386477 , 0.58817774, 0.72051835, 0.7902795 , 0.7041355 ,\n", + " 0.2181147 , 0.76299024, 0.8507803 , 0.8824023 , 0.8892915 ,\n", + " 0.8559173 , 0.83882904, 0.9163557 ]],\n", + " \n", + " [[0.9318335 , 1.0054291 , 0.7037247 , 0.44776785, 0.55141157,\n", + " 0.8751741 , 0.8788193 , 0.7378067 , 0.6061791 , 0.06516132,\n", + " 0.145283 , 0.81688696, 0.88854957],\n", + " [0.85625255, 0.86021763, 0.82891417, 0.5004723 , 0.8896506 ,\n", + " 0.15082283, 0.57127994, 0.86683005, 0.94244254, 0.8910252 ,\n", + " 0.9375356 , 0.92730576, 0.8518939 ]],\n", + " \n", + " [[0.9335175 , 0.98755246, 0.66180676, 0.5590857 , 0.5017098 ,\n", + " 0.89124495, 0.8839093 , 0.77439654, 0.5733776 , 0.0646795 ,\n", + " 0.12731166, 0.816599 , 0.90029544],\n", + " [0.9238624 , 0.8279644 , 0.7274184 , 0.8509916 , 0.9116395 ,\n", + " 0.21640316, 0.4109717 , 0.92344654, 0.8912647 , 0.8676515 ,\n", + " 0.91081876, 0.9236755 , 0.9313457 ]],\n", + " \n", + " [[0.9660537 , 0.97779256, 0.6795893 , 0.5347014 , 0.49429995,\n", + " 0.89868015, 0.88998085, 0.82294524, 0.49898362, 0.14230077,\n", + " 0.13475017, 0.8461558 , 0.89860517],\n", + " [0.8971772 , 0.85703963, 0.743163 , 0.87278444, 0.90552235,\n", + " 0.19766915, 0.33566353, 0.89383173, 0.87157995, 0.83140534,\n", + " 0.92693084, 0.9499294 , 0.85782766]],\n", + " \n", + " [[0.9214447 , 0.9804845 , 0.6575725 , 0.46105212, 0.5740245 ,\n", + " 0.88368326, 0.89460224, 0.81119704, 0.50101817, 0.24979575,\n", + " 0.16411652, 0.83694774, 0.9241573 ],\n", + " [0.8916 , 0.87129986, 0.7239725 , 0.8828186 , 0.7020806 ,\n", + " 0.16116264, 0.36204475, 0.8973187 , 0.8997571 , 0.51675177,\n", + " 0.89034307, 0.98887885, 0.88438815]],\n", + " \n", + " [[0.8979453 , 0.97743154, 0.5481076 , 0.523632 , 0.570176 ,\n", + " 0.8288708 , 0.9113763 , 0.9194614 , 0.575856 , 0.07603623,\n", + " 0.21255928, 0.9018014 , 0.9266098 ],\n", + " [0.91993105, 0.8616991 , 0.781426 , 0.7750215 , 0.85324234,\n", + " 0.14189687, 0.5463986 , 0.8761287 , 0.93542594, 0.50916994,\n", + " 0.87139845, 0.8620718 , 0.9169966 ]],\n", + " \n", + " [[0.90489644, 0.9633726 , 0.6176859 , 0.6120859 , 0.53412354,\n", + " 0.8082982 , 0.9141492 , 0.8100913 , 0.7064677 , 0.07797408,\n", + " 0.28660768, 0.9255538 , 0.9081669 ],\n", + " [0.9197768 , 0.89081717, 0.7697851 , 0.850639 , 0.8240589 ,\n", + " 0.2276387 , 0.7375747 , 0.9573141 , 0.95667875, 0.7197965 ,\n", + " 0.8762751 , 0.8575352 , 0.8765895 ]],\n", + " \n", + " [[0.9522048 , 0.96551245, 0.72864616, 0.5890152 , 0.561211 ,\n", + " 0.7051566 , 0.9421855 , 0.39786857, 0.7715297 , 0.6171893 ,\n", + " 0.06328589, 1.0118455 , 0.886791 ],\n", + " [0.9031525 , 0.9011465 , 0.7290425 , 0.84665924, 0.85558087,\n", + " 0.35440978, 0.8101312 , 0.931835 , 0.91998947, 0.9771716 ,\n", + " 0.88361436, 0.8611444 , 0.88294595]],\n", + " \n", + " [[0.93872 , 0.97103214, 0.63806784, 0.89063996, 0.68062663,\n", + " 0.9067393 , 0.89928836, 0.40190646, 0.75169766, 0.5388288 ,\n", + " 0.30325472, 0.86616135, 0.864786 ],\n", + " [0.9355017 , 0.93469065, 0.73501164, 0.89369905, 0.794787 ,\n", + " 0.29464462, 0.91743165, 0.88107586, 0.89442694, 0.97276276,\n", + " 0.9208387 , 0.8436978 , 0.9492276 ]],\n", + " \n", + " [[0.91440874, 0.97273135, 0.64372706, 0.85304886, 0.6125536 ,\n", + " 0.89858156, 0.89086473, 0.33406225, 0.7624657 , 0.64882857,\n", + " 0.18051867, 0.93381244, 0.90368915],\n", + " [0.9286875 , 0.93761605, 0.7948513 , 0.81816167, 0.7628807 ,\n", + " 0.30384466, 0.83553046, 0.83106405, 0.9189269 , 0.93762034,\n", + " 0.94770956, 0.8512343 , 0.9446315 ]],\n", + " \n", + " [[0.9450149 , 0.9582136 , 0.78555703, 0.7544447 , 0.58366936,\n", + " 0.85938 , 0.94498163, 0.6194322 , 0.7035529 , 0.22808443,\n", + " 0.24900974, 0.981288 , 0.92618316],\n", + " [0.93841267, 0.9422818 , 0.80968696, 0.8445456 , 0.7991047 ,\n", + " 0.4916717 , 0.77814513, 0.6231525 , 0.93198806, 0.9570074 ,\n", + " 0.95540506, 0.9207018 , 0.8778759 ]],\n", + " \n", + " [[0.9381855 , 0.94920886, 0.77673894, 0.87591183, 0.3847992 ,\n", + " 0.88775337, 0.92982674, 0.8082221 , 0.6930795 , 0.16653292,\n", + " 0.26732486, 0.9830136 , 0.93462956],\n", + " [0.9093149 , 0.96090955, 0.8409559 , 0.83797425, 0.8743328 ,\n", + " 0.82546026, 0.32881752, 0.5494046 , 0.9653242 , 0.9882784 ,\n", + " 0.85375595, 0.95603913, 0.9316707 ]],\n", + " \n", + " [[0.9048104 , 0.92460406, 0.75584614, 0.8082359 , 0.47512543,\n", + " 0.8684657 , 0.9260271 , 0.8822638 , 0.71269846, 0.1508674 ,\n", + " 0.22018598, 0.9016738 , 0.90536344],\n", + " [0.918121 , 0.96696764, 0.78534484, 0.883681 , 0.798996 ,\n", + " 0.69723856, 0.5170047 , 0.8321578 , 0.9426196 , 0.9527973 ,\n", + " 0.91900206, 0.9706679 , 0.90770215]],\n", + " \n", + " [[0.9391487 , 0.9352003 , 0.85189575, 0.72796327, 0.6884535 ,\n", + " 0.8768972 , 0.9508924 , 0.6879568 , 0.71122557, 0.7012927 ,\n", + " 0.6031595 , 0.87616193, 0.91429555],\n", + " [0.8932258 , 0.97501004, 0.78940654, 0.8651793 , 0.72244436,\n", + " 0.82689875, 0.4597148 , 0.93260366, 0.9202296 , 0.94214964,\n", + " 0.8834407 , 0.98030627, 0.8976605 ]]], dtype=float32),\n", + " 'instance_scores': array([[0.9953135 , 0.99476504],\n", + " [0.99593395, 0.99526805],\n", + " [0.9959078 , 0.9945123 ],\n", + " [0.99573624, 0.993386 ],\n", " [0.99603134, 0.99172956],\n", " [0.99564207, 0.9916197 ],\n", " [0.9947187 , 0.9915406 ],\n", " [0.9940315 , 0.98916876],\n", " [0.99394447, 0.98962784],\n", - " [0.99446183, 0.9910501 ],\n", + " [0.9944642 , 0.9910501 ],\n", " [0.99155337, 0.9933716 ],\n", - " [0.9916019 , 0.9933977 ],\n", + " [0.9916019 , 0.9933976 ],\n", " [0.9932473 , 0.9932013 ],\n", - " [0.99207497, 0.9946308 ],\n", + " [0.9920751 , 0.9946308 ],\n", " [0.991653 , 0.99465877],\n", " [0.99162734, 0.99486005]], dtype=float32),\n", - " 'n_valid': array([2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], dtype=int32)}" + " 'centroids': array([[[271.8735 , 436.4811 ],\n", + " [355.93707, 435.63477]],\n", + " \n", + " [[272.0215 , 436.42197],\n", + " [356.2099 , 435.4682 ]],\n", + " \n", + " [[272.23578, 436.31976],\n", + " [356.61108, 435.4756 ]],\n", + " \n", + " [[356.57007, 433.15857],\n", + " [272.7147 , 435.9847 ]],\n", + " \n", + " [[356.93347, 432.73026],\n", + " [272.7111 , 435.8055 ]],\n", + " \n", + " [[356.86227, 432.03918],\n", + " [272.64484, 435.49347]],\n", + " \n", + " [[357.0275 , 431.29968],\n", + " [272.49817, 435.54977]],\n", + " \n", + " [[359.29578, 431.42874],\n", + " [272.1338 , 435.81354]],\n", + " \n", + " [[359.7555 , 429.4507 ],\n", + " [272.2437 , 435.95605]],\n", + " \n", + " [[359.9807 , 428.4453 ],\n", + " [272.04776, 436.2247 ]],\n", + " \n", + " [[360.3565 , 427.81192],\n", + " [271.94632, 437.30673]],\n", + " \n", + " [[360.8997 , 427.5365 ],\n", + " [272.4532 , 436.9694 ]],\n", + " \n", + " [[361.10843, 427.52646],\n", + " [272.42938, 436.09125]],\n", + " \n", + " [[361.59042, 425.5916 ],\n", + " [272.44873, 435.94284]],\n", + " \n", + " [[364.18994, 425.5058 ],\n", + " [272.18735, 436.0978 ]],\n", + " \n", + " [[364.8356 , 425.49683],\n", + " [272.1019 , 436.49136]]], dtype=float32),\n", + " 'centroid_vals': array([[0.94554764, 0.83948356],\n", + " [0.9591119 , 0.8525362 ],\n", + " [0.95961505, 0.86304706],\n", + " [0.9252076 , 0.97578657],\n", + " [0.974096 , 0.9668305 ],\n", + " [0.9845507 , 0.9572475 ],\n", + " [0.9105379 , 0.97522974],\n", + " [0.880064 , 0.9943127 ],\n", + " [0.911333 , 1.0001038 ],\n", + " [0.9698766 , 0.9948527 ],\n", + " [0.96454924, 0.9799493 ],\n", + " [0.96142364, 1.0046191 ],\n", + " [0.95354944, 0.9987816 ],\n", + " [0.94746464, 0.98374254],\n", + " [0.97818244, 0.98671097],\n", + " [0.9833999 , 0.98425347]], dtype=float32),\n", + " 'n_valid': array([2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])}" ] }, + "execution_count": 11, "metadata": {}, - "execution_count": 11 + "output_type": "execute_result" } + ], + "source": [ + "imgs = video[:16] # batch of 16 images\n", + "\n", + "predictions = predictor.inference_model.predict(imgs, numpy=True)\n", + "predictions" ] }, { "cell_type": "code", - "source": [ - "for key, value in predictions.items():\n", - " print(f\"'{key}': {value.shape} ({value.dtype})\")" - ], + "execution_count": 12, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -1376,11 +1193,10 @@ "id": "k4ms3mUAX_ww", "outputId": "4ea4fc9f-bdbc-4c2d-da9e-68cfc734f22c" }, - "execution_count": 12, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "'instance_peaks': (16, 2, 13, 2) (float32)\n", "'instance_peak_vals': (16, 2, 13) (float32)\n", @@ -1390,23 +1206,32 @@ "'n_valid': (16,) (int32)\n" ] } + ], + "source": [ + "for key, value in predictions.items():\n", + " print(f\"'{key}': {value.shape} ({value.dtype})\")" ] }, { "cell_type": "markdown", + "metadata": { + "id": "sDKsqAEVOogD" + }, "source": [ "## 4. Realtime performance\n", "\n", "Now that we know how to do inference with different types of outputs, let's try to use that to build a simulated \"realtime\" application with timing.\n", "\n", "First, we'll create a class that simulates a camera grabber API that provides a sequence of pre-loaded frames." - ], - "metadata": { - "id": "sDKsqAEVOogD" - } + ] }, { "cell_type": "code", + "execution_count": 13, + "metadata": { + "id": "_vKMoT_oYcgZ" + }, + "outputs": [], "source": [ "from time import perf_counter\n", "import numpy as np\n", @@ -1431,24 +1256,37 @@ " idx = self.frame_counter % len(self.frames)\n", " self.frame_counter += 1\n", " return self.frames[idx]\n" - ], - "metadata": { - "id": "_vKMoT_oYcgZ" - }, - "execution_count": 13, - "outputs": [] + ] }, { "cell_type": "markdown", - "source": [ - "Then, we'll define a simply acquisition loop, in which we repeatedly grab a frame and perform inference to time how long it takes." - ], "metadata": { "id": "3-ctjg4wkxit" - } + }, + "source": [ + "Then, we'll define a simply acquisition loop, in which we repeatedly grab a frame and perform inference to time how long it takes." + ] }, { "cell_type": "code", + "execution_count": 14, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "ExhVDw_AaOJq", + "outputId": "3531b16e-4c0b-4e9f-a09c-9004105b469b" + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "First inference time: 886.2 ms\n", + "Inference times: 63.1 +- 1.2 ms\n" + ] + } + ], "source": [ "recording_duration = 100 # session length in frames\n", "\n", @@ -1476,46 +1314,20 @@ "first_inference_time, inference_times = inference_times[0], inference_times[1:]\n", "print(f\"First inference time: {first_inference_time:.1f} ms\")\n", "print(f\"Inference times: {inference_times.mean():.1f} +- {inference_times.std():.1f} ms\")" - ], - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "ExhVDw_AaOJq", - "outputId": "3531b16e-4c0b-4e9f-a09c-9004105b469b" - }, - "execution_count": 14, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "First inference time: 2181.9 ms\n", - "Inference times: 28.8 +- 2.6 ms\n" - ] - } ] }, { "cell_type": "markdown", - "source": [ - "After the first batch, our inference latencies go way down and we can see how they vary over time:" - ], "metadata": { "id": "WtbC0_3ek8I-" - } + }, + "source": [ + "After the first batch, our inference latencies go way down and we can see how they vary over time:" + ] }, { "cell_type": "code", - "source": [ - "import matplotlib.pyplot as plt\n", - "\n", - "plt.figure(figsize=(10, 4), dpi=120, facecolor=\"w\")\n", - "plt.plot(inference_times, \".\")\n", - "plt.xlabel(\"Time (frames)\")\n", - "plt.ylabel(\"Inference latency (ms)\")\n", - "plt.grid(True);" - ], + "execution_count": 15, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -1524,28 +1336,31 @@ "id": "R1uQIpjma5nJ", "outputId": "92a06b58-9250-482a-e645-86bb4cc5647a" }, - "execution_count": 15, "outputs": [ { - "output_type": "display_data", "data": { + "image/png": "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MImVK1fqwoULmjhxok6dOqWXX35Zw4YNU+/evZWcnKxnnnlGaWlpWrBggf70pz9p6dKlZce+8847euihh9S3b1/99a9/1dmzZ5WYmKjf/OY32rNnzxUX3Pv222914cIFdevWrawtJCRE77zzjmbOnKn8/HzNnj1bktSxY0edO3dOkrRs2TIVFhZq3Lhxql+/voKDg5WXl6fFixdrxIgReuSRR3TmzBktWbJEffv21a5du9S1a1eXX/OQIUO0b98+TZw4Ua1atdKJEye0adMmHTlyxOZ96d69uyRp+/btio6Orsk/IQAAzmMFAAAu99hjj1kr+zX80EMPWVu2bFn2959++skqyRoSEmLNzc0ta586dapVkvX666+3FhUVlbWPGDHCWq9ePWthYaHVarVaz5w5Y23cuLH1kUcesTlPVlaWtVGjRuXaL7d48WKrJOsPP/xQbltsbKy1U6dONm2l8QYFBVlPnDhhs624uNh6/vx5m7acnBxrWFiYdcyYMS6/5pycHKsk65w5c674HpSqV6+eNS4urlr7AgBQmxhmDwCASQwdOlSNGjUq+/tNN90kSRo1apTq1q1r037hwgVlZGRIkjZt2qTc3FyNGDFCP//8c9lPnTp1dNNNN1W5gv4vv/wiSbrqqqvsinfIkCEKCQmxaatTp07ZvPmSkhKdOnVKxcXFuuGGG7R7926XX7O/v7/q1aun5ORk5eTkVHlNV111lX7++We73gcAAGoDw+wBADCJy7/2rbTIbdGiRYXtpcVpamqqpEuL1VUkKCioWue32rlYX+vWrStsX758uV599VUdOHBARUVFV9y/tq+5fv36+utf/6onn3xSYWFhuvnmm3X33Xdr9OjRFX4FndVqZfE7AIAhUMwDAGASderUsau9tPguKSmRdGkOeUUF6q97uCty9dVXS7pUKDdv3rza8fr7+5drW7FihR5++GENGjRITz31lEJDQ1WnTh3Nnj1b6enp5fZ3xTVPnjxZAwYM0Pr16/Xpp58qPj5es2fP1r///e9yc+Nzc3PVpEmTSq4YAADXoZgHAMDDRUZGSpJCQ0NtVqSvrg4dOkiSfvrpJ1133XUOxbJ27Vq1adNGH374oU0Pd0JCgkOvezl7rzkyMlJPPvmknnzySaWmpqpr16569dVXtWLFirJ9MjIydOHCBXXs2NGpsQIAUBPMmQcAwMP17dtXQUFBmjVrls2w9lInT5684vHdu3dXvXr19M033zgcS2mP+q+H7H/11VfasWOHw6/9a9W95rNnz6qwsNBmW2RkpBo2bKjz58/btH/77beSpFtvvdWpsQIAUBP0zAMA4OGCgoKUmJioBx98UN26ddPw4cMVEhKiI0eO6OOPP9Ztt92mN954o9Lj/fz8dOedd2rz5s2aMWOGQ7Hcfffd+vDDD3Xvvfeqf//++umnn7Ro0SJFRUUpPz/fodf+tepe88GDB3XHHXdo2LBhioqKUt26dbVu3TplZ2dr+PDhNq+5adMmRURE8LV0AABDoJgHAMALjBw5UuHh4XrppZc0Z84cnT9/Xtdcc4169Oih3//+91UeP2bMGA0ZMkRHjx4tt/icPR5++GFlZWUpKSlJn376qaKiorRixQqtWbNGycnJNX7dilTnmlu0aKERI0bos88+0zvvvKO6deuqQ4cOev/99zVkyJCy1yopKdEHH3ygsWPHsgAeAMAQLFZ7l6YFAABe5+LFi4qKitKwYcP0wgsvuDscl1u/fr1Gjhyp9PR0NWvWzN3hAABAMQ8AAKrnvffeU1xcnI4cOaLAwEB3h+NSt9xyi3r06KGXX37Z3aEAACCJYh4AAAAAANNhNXsAAAAAAEyGYh4AAAAAAJOhmAcAAAAAwGQo5gEAAAAAMBmKeQAAAAAATIZiHgAAAAAAk6GYBwAAAADAZCjmAQAAAAAwGYp5AAAAAABMhmIeAAAAAACToZgHAAAAAMBkKOYBAAAAADAZinkAAAAAAEzm/wGXWVTpL/UcNAAAAABJRU5ErkJggg==", "text/plain": [ "
" - ], - "image/png": "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52PkxX379tWmTZsqXb9lyxb17du3RvuOi4uTj4+PkpKSlJCQoNmzZ+vaa6/VunXr9Nhjj9W0ZAC4ovCwIK1NuEUx3cLU6epAxXQL09qEWxQexv18AAAA8ByGeuZtNtsV1587d06+vr412veoUaPKJtVzROvWrausCwCuJDwsSPPv6+HuMgAAAIBKORzmjx49WjaUXZLS0tL02WefldvuzJkzWrRokX7zm98YKhAAAAAAANhzOMy/9dZbmjZtmiwWiywWi2bMmKEZM2aU285ms8nX11eLFi1ySqEAAAAAAOAih8P8vffeq65du8pms1X+mpwAACAASURBVOnee+9VYmKibrvtNrttLBaLAgIC1L17d4WGhjqtWAAAAAAAUIMw37lzZ3Xu3FnSxV766OhotW7d2tl1AQAAAACAShiaAG/s2LHOqgMAAAAAAFSToTAvSUVFRVqzZo2+/vpr5eTkqLS01G69xWLR0qVLjR4GAAAAAAD8j6Ew/8MPP6hv3746cuSImjRpopycHDVr1kxnzpxRSUmJgoODZbVanVUrAAAAAACQ5GPkxU8++aRycnK0a9cuHThwQDabTatWrVJ+fr5efvll+fv76+OPP3ZWrQAAAAAAQAbD/L/+9S9NmDBBkZGR8vG5uCubzaaGDRvqySef1J133qlHH33UKYUCAAAAAICLDIX5s2fPls1kHxQUJIvFopycnLL1ffr00Y4dOwwVCAAAAAAA7BkK861atVJGRoYkqV69emrRooV27dpVtj41NVV+fn7GKgQAAAAAAHYMTYB3xx13aN26dXrhhRckSb///e/1l7/8RadPn1ZpaaneeecdjRkzximFAgAAAACAiwyF+aefflpffPGFzp07p4YNG2rKlCnKzMzU6tWr5evrq9/97neaPXu2s2oFAAAAAAAyGOZbtWqlVq1alf3dz89PS5Ys0ZIlSwwXBgAAAAAAKmbonnkAAAAAAFD7HOqZnz59usMHsFgsmjp1qsOvAwAAAAAAFXMozL/44osOH4AwDwAAAACAczkU5ktLS11VBwAAAAAAqCbumQcAAAAAwGQI8wAAAAAAmAxhHgAAAAAAkyHMAwAAAABgMoR5AAAAAABMhjAPAAAAAIDJOC3MHzt2THv37lVBQYGzdgkAAAAAACpgOMyvW7dOnTp10rXXXquePXtq9+7dkqSTJ0+qR48e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AAAAwGYo5gEAAAAAsBmKeQAAAAAAbIZiHgAAAAAAm6GYt6H8/HzNnj1bzZo1U2BgoHr16qXk5GRPhwUvt2/fPiUkJCgmJkZBQUGKiopSfHy80tPTy2x78OBBDRo0SMHBwQoLC9MDDzygH3/80QNRA79YsGCBfHx81LFjxzKP/fe//9Udd9yh+vXrKyIiQjNmzFBubq4HooS3+/rrr3XfffcpLCxM9evXV8eOHfXSSy85bUO+wioOHz6sMWPGKDIyUvXr11f79u01b948XblyxWk7chZmy83N1dy5czVo0CCFhYXJx8dHb7/9drnbunrdWlJSoiVLlqh169aqV6+eOnXqpPfff79G98OvRl8dNWLixIlav369Zs6cqZtvvllvv/22fv/732vHjh264447PB0evNTixYu1a9cujRo1Sp06dVJ2draWLVumbt26ac+ePY4CKTMzU/369VNoaKgWLlyo3NxcPfPMM/r222+Vmpoqf39/D+8JvFFmZqYWLlxY7u/G7t+/X3feeac6dOig5557TpmZmXrmmWd0+PBhffrppx6IFt7qX//6l+Li4tS1a1c98cQTCg4O1tGjR5WZmenYhnyFVWRkZKhnz54KDQ1VQkKCwsLCtHv3bs2dO1dfffWVNm/eLImchWecPXtW8+bNU1RUlDp37qyUlJRyt6vOdevf/vY3LVq0SFOmTFGPHj20efNmjRs3Tj4+PhozZkzN7IgBW9m7d68hyVi6dKmj7erVq0abNm2M3r17ezAyeLtdu3YZ+fn5Tm3p6elGQECAcf/99zvapk2bZgQGBho//PCDoy05OdmQZKxatcq0eIFfGz16tDFgwAAjNjbWiImJcXps8ODBRtOmTY2LFy862l577TVDkrFt2zazQ4WXunjxotGkSRNj+PDhRnFxcYXbka+wigULFhiSjAMHDji1T5gwwZBknDt3zjAMchaekZeXZ5w6dcowDMPYt2+fIcl46623ymzn6nVrZmamUbduXWP69OmOtpKSEqNv375GZGSkUVRUVCP7wTB7m1m/fr18fX01depUR1u9evU0efJk7d69WxkZGR6MDt6sT58+ZXrVb775ZsXExOjgwYOOto8++kj33nuvoqKiHG133XWX2rVrp7Vr15oWL1Dq888/1/r16/XCCy+UeSwnJ0fJyckaP368QkJCHO0TJkxQcHAwOQvT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AAAAm6GYBwAAAADAZijmAQAAAACwGYp5AAAAAABshmIeAAAAAACboZgHAAAAAMBmKOYBALCYiRMnqlWrVp4Oo4y1a9cqLCxMubm5jraioiI9/vjjatGiherUqaNhw4Z5MMKac/vtt+vxxx/3dBgAADj4eToAAAC8gY+Pj0vb7dixo4YjuTbFxcWaO3euEhMTFRwc7Gh/8803tXTpUs2cOVPdunVTVFSUB6OsObNnz9b48eP16KOPKiIiwtPhAAAgH8MwDE8HAQBAbZeUlOT093fffVfJyclavXq1U/vdd9+tsLAwlZSUKCAgwMwQK7Vp0yaNGDFCGRkZat68uaN9zJgx+uKLL5SZmenB6GpeSUmJmjdvrilTpmjevHmeDgcAAIp5AAA8ISEhQa+88ors8s/w0KFDde7cOe3cudOpfcCAATpz5owOHDhQ6fOLiopUUlIif3//mgyzRiUmJmrLli06duyYyyMtAACoKcyZBwDAYn47Z/748ePy8fHRM888o1deeUU33XST6tevr3vuuUcZGRkyDEPz589XZGSkAgMDHYX3b3366afq27evgoKC1KBBAw0ZMkTfffddlfHk5eVp69atuuuuu8rEtGPHDn333Xfy8fGRj4+PUlJSnOJ94YUX1KZNGwUEBOj7779XQUGBnnzySXXv3l2hoaEKCgpS3759y0wvMHOfs7Oz9dBDDykyMlIBAQFq2rSphg4dquPHjzttd/fdd+uHH37Q/v37qzxmAADUNObMAwBgE2vWrFFBQYESExN17tw5LVmyRPHx8RowYIBSUlI0e/ZsHTlyRC+//LIee+wxvfnmm47nrl69Wg8++KAGDhyoxYsX68qVK1qxYoXuuOMOpaWlVbrg3ldffaWCggJ169bN0RYeHq7Vq1drwYIFys3N1dNPPy1J6tChg65evSpJeuutt5SXl6epU6cqICBAYWFhysnJ0euvv66xY8dqypQpunTpkt544w0NHDhQqamp6tKli+n7PHLkSH333XdKTExUq1atdObMGSUnJ+vEiRNOx6V79+6SpF27dqlr167X9BkCAOA2BgAAMN306dONiv4ZfvDBB42WLVs6/n7s2DFDkhEeHm5cuHDB0T5nzhxDktG5c2ejsLDQ0T527FjD39/fyMvLMwzDMC5dumQ0bNjQmDJlitP7ZGdnG6GhoWXaf+v11183JBnffvttmcdiY2ONmJgYp7bSeENCQowzZ844PVZUVGTk5+c7tZ0/f95o0qSJMWnSJNP3+fz584YkY+nSpZUeg1L+/v7GtGnTXNoWAICaxDB7AABsYtSoUQoNDXX8vVevXpKk8ePHy8/Pz6m9oKBAWVlZkqTk5GRduHBBY8eO1dmzZx1/fH191atXrypX0P/pp58kSTfccEO14h05cqTCw8Od2nx9fR3z5ktKSnTu3DkVFRXptttu09dff236PgcGBsrf318pKSk6f/58lft0ww036OzZs9U6DgAA1ASG2QMAYBO//dm30iK3RYsW5baXFqeHDx+W9PNideUJCQlx6f2Nai7W17p163Lb33nnHT377LM6dOiQCgsLK92+pvc5ICBAixcv1qxZs9SkSRPdfvvtuvfeezVhwoRyf4LOMAwWvwMAWALFPAAANuHr61ut9tLiu6SkRNLPc8jLK1B/3cNdnkaNGkn6uVCOjIx0Od7AwMAybUlJSZo4caKGDRumv/zlL2rcuLF8fX319NNP6+jRo2W2N2OfZ86cqbi4OG3atEnbtm3TE088oaefflr//ve/y8yNv3Dhgm688cYK9hgAAPNQzAMAUMu1adNGktS4cWOnFeld1b59e0nSsWPHdOutt15XLOvXr9dNN92kDRs2OPVwz50797pe97equ89t2rTRrFmzNGvWLB0+fFhdunTRs88+q6SkJMc2WVlZKigoUIcOHdwaKwAA14I58wAA1HIDBw5USEiIFi5c6DSsvdSPP/5Y6fO7d+8uf39/ffnll9cdS2mP+q+H7O/du1e7d+++7tf+NVf3+cqVK8rLy3N6rE2bNmrQoIHy8/Od2r/66itJUp8+fdwaKwAA14KeeQAAarmQkBCtWLFCDzzwgLp166YxY8YoPDxcJ06c0CeffKLf/e53WrZsWYXPr1evnu655x5t375d8+bNu65Y7r33Xm3YsEHDhw/XkCFDdOzYMa1cuVLR0dHKzc29rtf+NVf3OT09XXfeeafi4+MVHR0tPz8/bdy4UadPn9aYMWOcXjM5OVlRUVH8LB0AwBIo5gEA8ALjxo1Ts2bNtGjRIi1dulT5+flq3ry5+vbtq4ceeqjK50+aNEkjR45URkZGmcXnqmPixInKzs7WqlWrtG3bNkVHRyspKUnr1q1TSkrKNb9ueVzZ5xYtWmjs2LH67LPPtHr1avn5+al9+/Zau3atRo4c6XitkpISffTRR5o8eTIL4AEALMHHqO7StAAAwOsUFxcrOjpa8fHxmj9/vqfDMd2mTZs0btw4HT16VE2bNvV0OAAAUMwDAADXfPjhh5o2bZpOnDih4OBgT4djqt69e6tv375asmSJp0MBAEASxTwAAAAAALbDavYAAAAAANgMxTwAAAAAADZDMQ8AAAAAgM1QzAMAAAAAYDMU8wAAAAAA2AzFPAAAAAAANkMxDwAAAACAzVDMAwAAAABgMxTzAAAAAADYDMU8AAAAAAA2QzEPAAAAAIDNUMwDAAAAAGAz/weHASkds2i19QAAAABJRU5ErkJggg==\n" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "plt.figure(figsize=(10, 4), dpi=120, facecolor=\"w\")\n", + "plt.plot(inference_times, \".\")\n", + "plt.xlabel(\"Time (frames)\")\n", + "plt.ylabel(\"Inference latency (ms)\")\n", + "plt.grid(True);" ] }, { "cell_type": "code", - "source": [ - "plt.figure(figsize=(6, 4), dpi=120, facecolor=\"w\")\n", - "plt.hist(inference_times, bins=30)\n", - "plt.xlabel(\"Inference latency (ms)\")\n", - "plt.ylabel(\"PDF\");" - ], + "execution_count": 16, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -1554,19 +1369,50 @@ "id": "ubgokqC4ct5m", "outputId": "03fea67b-5c92-413f-f841-5c9464be08a6" }, - "execution_count": 16, "outputs": [ { - "output_type": "display_data", "data": { + "image/png": "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W2/p6NGjFbJfLy+vYkcp33jjjWIfA1N4Tt4fs/Xp00e1a9fWjBkzlJeXVyGZBg8eLGNMsSNqUvEjqiNGjFBmZqYeeeQRZWdnX/bq4kJdu3bVrl27KvzPx/3+7WNJql69ulq2bCljTLH12bFjh7p161ah+wfcGUcIAVSoESNGaMmSJRo3bpySkpLUvXt35efn66efftKSJUv05ZdfqlOnTqU+xsyZM5WUlKQuXbpozJgxatmypU6dOqUdO3Zo3bp1OnXq1BVl8vT01Jtvvqn+/furXbt2evDBBxUWFqaffvpJu3fv1pdffilJmj9/vm6++Wa1bt1aY8aMUePGjXX8+HFt3rxZhw8f1g8//HBF+73rrru0aNEiBQQEqGXLltq8ebPWrVunoKAgu3nt2rWTl5eXZs2apdOnT8vHx0e33nqrbDab3nzzTY0YMUIdOnTQsGHDFBwcrIMHD2rNmjXq3r275s2bd0WZevfurREjRuj111/Xvn371LdvXxUUFGjDhg3q3bu33Z+aa9++vVq1alV0oVCHDh3KtI+BAwfq+eef1zfffKM77rjjivKV5o477lBoaKi6d++ukJAQJScna968eerXr59q1apVNG/79u06deqUBg4cWGH7BtwdhRBAhfL09NSnn36q1157Te+//75WrlypGjVqqHHjxnrsscd0ww03XPYxQkJCtHXrVsXHx2vFihVKSEhQUFCQIiIiNGvWrHLl6tOnj5KSkhQXF6dXXnlFBQUFuv766zVmzJiiOS1bttS2bdsUFxenxMREnTx5UjabTe3bt9e0adOueJ9z586Vl5eXFi9erJycHHXv3l3r1q0rdo5iaGioFixYoBdffFGjR49Wfn6+kpKSZLPZdN9996levXqaOXOmXn75ZeXm5uraa6/VLbfcogcffLBca7Fw4UK1adNG7777rp588kkFBASoU6dOJR5RGzlypJ566qkr+jvVHTt2VJs2bbRkyZIKLYSPPPKIFi9erFdffVXZ2dmqX7++Jk6cqGeffdZu3tKlS9WwYcNLXowDoDgPcyVnXQMALGXu3Ll6/PHHlZqaWuzq4NIsWrRIf/nLX3Tw4MEK/fOGl5Obm6tGjRppypQpeuyxxxy2X6Cq4xxCAECJjDF699131bNnzysqg5J0//33q2HDhpo/f34lpSvZwoULVa1atWKfxwigdBwhBADYOXv2rD777DMlJSXpnXfe0apVqzRgwABnxwJQiSiEAAA7qampCg8PV506dRQdHa3p06c7OxKASkYhBAAAsDjOIQQAALA4CiEAAIDFUQgBAAAsjkIIAABgcRRCAAAAi6MQAgAAWByFEAAAwOIohAAAABZHIQQAALA4CiEAAIDF/X89JV70R2n8uAAAAABJRU5ErkJggg==", "text/plain": [ "
" - ], - "image/png": "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y9q7d6/NOoYOHaqSJUva1CrJWu++fft04sQJvfLKK3b3aFosFklScnKyNm3apL59++rq1avWbV68eFGdOnXS0aNHFR8fn+v+383T09P637du3dLFixcVEhIiX19fu33IyoYNG5SSkqIBAwbYzIObm5uaNWuW5T19uf3dVqxYIYvFokmTJtmNvTMXPj4+6tGjh/71r39ZHzrJyMjQ559/rvDwcJUuXTrHui9evKiyZctmu/zFF1+0/rebm5saN24swzA0bNgwa7uvr69q1KhhU7uvr6/OnDmj3bt357h9SSpbtqxu3LhhPcML4H+KO7sAAK7nzn1wdytbtqwuXbqU69ijR4/q0KFDduPvSExMtHkfHBxs8z4pKUkpKSn64IMP7C63ZreOqlWr2tUqyVrvsWPHJEl16tTJtu7Y2FgZhqGJEydq4sSJ2W63cuXK2a7jXjdu3NA777yjxYsXKz4+3ubp38uXL+c6/ujRo5JkDd738vb2tnlv5u927NgxVapUSeXKlctx20OGDNHnn3+ubdu2qXXr1tq4caPOnz9v+uuYjByedL737+Xj4yMPDw9VqFDBrv3ixYvW93/5y1+0ceNGNW3aVCEhIerYsaOef/55Pfnkk9lu/04gBvA/hEcADufm5pbnsZmZmapbt65mz56d5fKgoCCb93efnbszXpIGDRqkiIiILNdRr149m/fZ1ZtTgLnXne2OGzcu2wdCQkJCTK9PkkaNGqXFixfrlVdeUYsWLeTj4yOLxaL+/ftbt2empiVLliggIMBuefHitv8T8CB/t3t16tRJFStW1CeffKLWrVvrk08+UUBAgDp06JDr2PLly+f4fzSyqtPM37BWrVr67bff9M0332jt2rVasWKFoqOj9eabbyoqKspm3KVLl1SqVCm7zxcAwiOAAubRRx/Vzz//rPbt2+fprI+fn5/KlCmjjIwMU0HFbE2StH///mzXWb16dUlSiRIlHLbd5cuXKyIiwuap4bS0NKWkpNj0y26e7tTt7+/v0LlYt26dkpOTczz76Obmpueff14xMTGaPn26vvzySw0fPtxUQK1Zs6ZOnDjhkHrvVbp0afXr10/9+vXTzZs39dxzz+ntt9/WG2+8IQ8PD2u/EydOWB86AmCLex4BFCh9+/ZVfHy8Fi1aZLfsxo0bunbtWo7j3dzc1KtXL61YscLuaV/p98va96tRo0YKDg7WnDlz7ILbnTNb/v7+atu2rd5//30lJCQ4ZLtubm52Zz/nzZtn99U5d+4hvLe2Tp06ydvbW1OnTtWtW7ccUlOvXr1kGIbdmTrJ/kzt4MGDdenSJb300ktKTU3N9SnrO1q0aKH9+/c7/CcC776ELUklS5ZU7dq1ZRiG3fzs3btXLVu2dOj2AVfBmUcABcrgwYO1bNkyjRw5Ups3b9aTTz6pjIwMHT58WMuWLdO6devUuHHjHNcxbdo0bd68Wc2aNdPw4cNVu3ZtJScna+/evdq4caOSk5Pvq6ZixYppwYIF6tatmxo0aKChQ4cqMDBQhw8f1oEDB7Ru3TpJ0nvvvadWrVqpbt26Gj58uKpXr67z589rx44dOnPmjH7++ef72m7Xrl21ZMkS+fj4qHbt2tqxY4c2btyo8uXL2/Rr0KCB3NzcNH36dF2+fFnu7u56+umn5e/vrwULFmjw4MFq1KiR+vfvLz8/P506dUpr1qzRk08+qfnz599XTe3atdPgwYP197//XUePHlVYWJgyMzO1bds2tWvXzubnBBs2bKg6depYH4Jq1KiRqW306NFDf/vb37R161Z17NjxvurLSceOHRUQEKAnn3xSFStW1KFDhzR//nx16dJFZcqUsfb78ccflZycrB49ejhs24ArITwCKFCKFSumL7/8Uu+++67++c9/atWqVSpVqpSqV6+uMWPG6PHHH891HRUrVtSuXbs0efJkrVy5UtHR0SpfvrxCQ0M1ffr0PNXVqVMnbd68WVFRUZo1a5YyMzP16KOPavjw4dY+tWvX1p49exQVFaWYmBhdvHhR/v7+atiwod5888373ubcuXPl5uampUuXKi0tTU8++aQ2btxod09lQECAFi5cqHfeeUfDhg1TRkaGNm/eLH9/fz3//POqVKmSpk2bphkzZig9PV2VK1fWU089paFDh+ZpLhYvXqx69erpo48+0p///Gf5+PiocePGWZ6pGzJkiF5//fX7+t3yJ554QvXq1dOyZcscGh5feuklLV26VLNnz1ZqaqqqVKmi0aNH6//+7/9s+n3xxReqWrVqtg8aAUWdxbifO8IBALgPc+fO1dixYxUXF2f3lHROlixZoj/96U86deqUQ3/CMjfp6emqVq2axo8frzFjxuTbdoHChHseAQAPhWEY+uijj9SmTZv7Co6SNHDgQFWtWlXvvffeQ6oua4sXL1aJEiXsvu8SwP9w5hEA4FDXrl3T6tWrtXnzZi1atEhfffWVunfv7uyyADgI4REA4FBxcXEKDg6Wr6+vIiMj9fbbbzu7JAAORHgEAACAadzzCAAAANMIjwAAADCN8AgAAADTCI8AAAAwjfAIAAAA0wiPAAAAMI3wCAAAANMIjwAAADCN8AgAAADTCI8AAAAw7f8DuyUs8IaOgHwAAAAASUVORK5CYII=\n" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" } + ], + "source": [ + "plt.figure(figsize=(6, 4), dpi=120, facecolor=\"w\")\n", + "plt.hist(inference_times, bins=30)\n", + "plt.xlabel(\"Inference latency (ms)\")\n", + "plt.ylabel(\"PDF\");" ] } - ] + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "collapsed_sections": [], + "name": "SLEAP - Interactive and realtime inference.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.12" + } + }, + "nbformat": 4, + "nbformat_minor": 0 } diff --git a/docs/notebooks/Interactive_and_resumable_training.ipynb b/docs/notebooks/Interactive_and_resumable_training.ipynb index 92435724a..f30f036f3 100644 --- a/docs/notebooks/Interactive_and_resumable_training.ipynb +++ b/docs/notebooks/Interactive_and_resumable_training.ipynb @@ -1,19 +1,4 @@ { - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "name": "SLEAP - Interactive and resumable training.ipynb", - "provenance": [], - "collapsed_sections": [], - "machine_shape": "hm" - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "accelerator": "GPU" - }, "cells": [ { "cell_type": "markdown", @@ -27,6 +12,9 @@ }, { "cell_type": "markdown", + "metadata": { + "id": "DpvQa3M3n7jC" + }, "source": [ "# Interactive and resumable training\n", "\n", @@ -35,10 +23,7 @@ "If you'd like to customize the training process, however, you can use SLEAP's low-level training functionality interactively. This allows you to define scripts that train models according to your own workflow, for example, to **resume training** on an already trained model. Another possible application would be to train a model using **transfer learning**, where a pretrained model can be used to initialize the weights of the new model.\n", "\n", "In this notebook we will explore how to set up a training job and train a model for multiple rounds without the GUI or CLI." - ], - "metadata": { - "id": "DpvQa3M3n7jC" - } + ] }, { "cell_type": "markdown", @@ -55,196 +40,47 @@ }, { "cell_type": "code", + "execution_count": 4, "metadata": { - "id": "BYxJ2rJOMW8B", "colab": { "base_uri": "https://localhost:8080/" }, + "id": "BYxJ2rJOMW8B", "outputId": "d2230650-4e45-46f3-ff8f-dbe271bb9eb9" }, - "source": [ - "# This should take care of all the dependencies on colab:\n", - "!pip uninstall -y opencv-python opencv-contrib-python && pip install sleap\n", - "\n", - "\n", - "# But to do it locally, we'd recommend the conda package (available on Windows + Linux):\n", - "# conda create -n sleap -c sleap -c conda-forge -c nvidia sleap" - ], - "execution_count": 1, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "Found existing installation: opencv-python 4.1.2.30\n", - "Uninstalling opencv-python-4.1.2.30:\n", - " Successfully uninstalled opencv-python-4.1.2.30\n", - "Found existing installation: opencv-contrib-python 4.1.2.30\n", - "Uninstalling opencv-contrib-python-4.1.2.30:\n", - " Successfully uninstalled opencv-contrib-python-4.1.2.30\n", - "Collecting sleap\n", - " Downloading sleap-1.2.2-py3-none-any.whl (62.0 MB)\n", - "\u001b[K |████████████████████████████████| 62.0 MB 1.3 MB/s \n", - "\u001b[?25hRequirement already satisfied: certifi<=2021.10.8,>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from sleap) (2021.10.8)\n", - "Requirement already satisfied: tensorflow<2.9.0,>=2.6.3 in /usr/local/lib/python3.7/dist-packages (from sleap) (2.8.0)\n", - "Requirement already satisfied: pyzmq in /usr/local/lib/python3.7/dist-packages (from sleap) (22.3.0)\n", - "Collecting jsonpickle==1.2\n", - " Downloading jsonpickle-1.2-py2.py3-none-any.whl (32 kB)\n", - "Requirement already satisfied: scikit-learn==1.0.* in /usr/local/lib/python3.7/dist-packages (from sleap) (1.0.2)\n", - "Collecting opencv-python-headless<=4.5.5.62,>=4.2.0.34\n", - " Downloading opencv_python_headless-4.5.5.62-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (47.7 MB)\n", - "\u001b[K |████████████████████████████████| 47.7 MB 85 kB/s \n", - "\u001b[?25hCollecting rich==10.16.1\n", - " Downloading rich-10.16.1-py3-none-any.whl (214 kB)\n", - "\u001b[K |████████████████████████████████| 214 kB 49.1 MB/s \n", - "\u001b[?25hRequirement already satisfied: numpy<=1.21.5,>=1.19.5 in /usr/local/lib/python3.7/dist-packages (from sleap) (1.21.5)\n", - "Requirement already satisfied: imageio<=2.15.0 in /usr/local/lib/python3.7/dist-packages (from sleap) (2.4.1)\n", - "Collecting scikit-video\n", - " Downloading scikit_video-1.1.11-py2.py3-none-any.whl (2.3 MB)\n", - "\u001b[K |████████████████████████████████| 2.3 MB 38.3 MB/s \n", - "\u001b[?25hRequirement already satisfied: h5py<=3.6.0,>=3.1.0 in /usr/local/lib/python3.7/dist-packages (from sleap) (3.1.0)\n", - "Collecting cattrs==1.1.1\n", - " Downloading cattrs-1.1.1-py3-none-any.whl (16 kB)\n", - "Collecting python-rapidjson\n", - " Downloading python_rapidjson-1.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.6 MB)\n", - "\u001b[K |████████████████████████████████| 1.6 MB 39.3 MB/s \n", - "\u001b[?25hCollecting imgaug==0.4.0\n", - " Downloading imgaug-0.4.0-py2.py3-none-any.whl (948 kB)\n", - "\u001b[K |████████████████████████████████| 948 kB 40.4 MB/s \n", - "\u001b[?25hRequirement already satisfied: networkx in /usr/local/lib/python3.7/dist-packages (from sleap) (2.6.3)\n", - "Requirement already satisfied: seaborn in /usr/local/lib/python3.7/dist-packages (from sleap) (0.11.2)\n", - "Collecting pykalman==0.9.5\n", - " Downloading pykalman-0.9.5.tar.gz (228 kB)\n", - "\u001b[K |████████████████████████████████| 228 kB 52.8 MB/s \n", - "\u001b[?25hRequirement already satisfied: pyyaml in /usr/local/lib/python3.7/dist-packages (from sleap) (3.13)\n", - "Collecting PySide2<=5.14.1,>=5.13.2\n", - " Downloading PySide2-5.14.1-5.14.1-cp35.cp36.cp37.cp38-abi3-manylinux1_x86_64.whl (165.5 MB)\n", - "\u001b[K |████████████████████████████████| 165.5 MB 76 kB/s \n", - "\u001b[?25hCollecting attrs==21.2.0\n", - " Downloading attrs-21.2.0-py2.py3-none-any.whl (53 kB)\n", - "\u001b[K |████████████████████████████████| 53 kB 2.3 MB/s \n", - "\u001b[?25hRequirement already satisfied: psutil in /usr/local/lib/python3.7/dist-packages (from sleap) (5.4.8)\n", - "Collecting imgstore==0.2.9\n", - " Downloading imgstore-0.2.9-py2.py3-none-any.whl (904 kB)\n", - "\u001b[K |████████████████████████████████| 904 kB 39.4 MB/s \n", - "\u001b[?25hCollecting jsmin\n", - " Downloading jsmin-3.0.1.tar.gz (13 kB)\n", - "Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from sleap) (1.3.5)\n", - "Collecting segmentation-models==1.0.1\n", - " Downloading segmentation_models-1.0.1-py3-none-any.whl (33 kB)\n", - "Requirement already satisfied: scipy<=1.7.3,>=1.4.1 in /usr/local/lib/python3.7/dist-packages (from sleap) (1.4.1)\n", - "Requirement already satisfied: scikit-image in /usr/local/lib/python3.7/dist-packages (from sleap) (0.18.3)\n", - "Collecting qimage2ndarray<=1.8.3,>=1.8.2\n", - " Downloading qimage2ndarray-1.8.3-py3-none-any.whl (11 kB)\n", - "Requirement already satisfied: Shapely in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (1.8.1.post1)\n", - "Requirement already satisfied: Pillow in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (7.1.2)\n", - "Requirement already satisfied: matplotlib in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (3.2.2)\n", - "Collecting opencv-python\n", - " Downloading opencv_python-4.5.5.64-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (60.5 MB)\n", - "\u001b[K |████████████████████████████████| 60.5 MB 1.4 MB/s \n", - "\u001b[?25hRequirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (1.15.0)\n", - "Requirement already satisfied: pytz in /usr/local/lib/python3.7/dist-packages (from imgstore==0.2.9->sleap) (2018.9)\n", - "Requirement already satisfied: python-dateutil in /usr/local/lib/python3.7/dist-packages (from imgstore==0.2.9->sleap) (2.8.2)\n", - "Requirement already satisfied: tzlocal in /usr/local/lib/python3.7/dist-packages (from imgstore==0.2.9->sleap) (1.5.1)\n", - "Collecting colorama<0.5.0,>=0.4.0\n", - " Downloading colorama-0.4.4-py2.py3-none-any.whl (16 kB)\n", - "Requirement already satisfied: typing-extensions<5.0,>=3.7.4 in /usr/local/lib/python3.7/dist-packages (from rich==10.16.1->sleap) (3.10.0.2)\n", - "Requirement already satisfied: pygments<3.0.0,>=2.6.0 in /usr/local/lib/python3.7/dist-packages (from rich==10.16.1->sleap) (2.6.1)\n", - "Collecting commonmark<0.10.0,>=0.9.0\n", - " Downloading commonmark-0.9.1-py2.py3-none-any.whl (51 kB)\n", - "\u001b[K |████████████████████████████████| 51 kB 6.5 MB/s \n", - "\u001b[?25hRequirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn==1.0.*->sleap) (1.1.0)\n", - "Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn==1.0.*->sleap) (3.1.0)\n", - "Collecting keras-applications<=1.0.8,>=1.0.7\n", - " Downloading Keras_Applications-1.0.8-py3-none-any.whl (50 kB)\n", - "\u001b[K |████████████████████████████████| 50 kB 6.0 MB/s \n", - "\u001b[?25hCollecting image-classifiers==1.0.0\n", - " Downloading image_classifiers-1.0.0-py3-none-any.whl (19 kB)\n", - "Collecting efficientnet==1.0.0\n", - " Downloading efficientnet-1.0.0-py3-none-any.whl (17 kB)\n", - "Requirement already satisfied: cached-property in /usr/local/lib/python3.7/dist-packages (from h5py<=3.6.0,>=3.1.0->sleap) (1.5.2)\n", - "Collecting shiboken2==5.14.1\n", - " Downloading shiboken2-5.14.1-5.14.1-cp35.cp36.cp37.cp38-abi3-manylinux1_x86_64.whl (847 kB)\n", - "\u001b[K |████████████████████████████████| 847 kB 39.4 MB/s \n", - "\u001b[?25hRequirement already satisfied: tifffile>=2019.7.26 in /usr/local/lib/python3.7/dist-packages (from scikit-image->sleap) (2021.11.2)\n", - "Requirement already satisfied: PyWavelets>=1.1.1 in /usr/local/lib/python3.7/dist-packages (from scikit-image->sleap) (1.3.0)\n", - "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib->imgaug==0.4.0->sleap) (0.11.0)\n", - "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->imgaug==0.4.0->sleap) (1.4.0)\n", - "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->imgaug==0.4.0->sleap) (3.0.7)\n", - "Requirement already satisfied: tensorflow-io-gcs-filesystem>=0.23.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (0.24.0)\n", - "Requirement already satisfied: flatbuffers>=1.12 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (2.0)\n", - "Requirement already satisfied: astunparse>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.6.3)\n", - "Requirement already satisfied: opt-einsum>=2.3.2 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (3.3.0)\n", - "Requirement already satisfied: protobuf>=3.9.2 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (3.17.3)\n", - "Collecting tf-estimator-nightly==2.8.0.dev2021122109\n", - " Downloading tf_estimator_nightly-2.8.0.dev2021122109-py2.py3-none-any.whl (462 kB)\n", - "\u001b[K |████████████████████████████████| 462 kB 48.3 MB/s \n", - "\u001b[?25hRequirement already satisfied: google-pasta>=0.1.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (0.2.0)\n", - "Requirement already satisfied: tensorboard<2.9,>=2.8 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (2.8.0)\n", - "Requirement already satisfied: wrapt>=1.11.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.14.0)\n", - "Requirement already satisfied: setuptools in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (57.4.0)\n", - "Requirement already satisfied: keras-preprocessing>=1.1.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.1.2)\n", - "Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.1.0)\n", - "Requirement already satisfied: grpcio<2.0,>=1.24.3 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.44.0)\n", - "Requirement already satisfied: gast>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (0.5.3)\n", - "Requirement already satisfied: libclang>=9.0.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (13.0.0)\n", - "Requirement already satisfied: absl-py>=0.4.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.0.0)\n", - "Requirement already satisfied: keras<2.9,>=2.8.0rc0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (2.8.0)\n", - "Requirement already satisfied: wheel<1.0,>=0.23.0 in /usr/local/lib/python3.7/dist-packages (from astunparse>=1.6.0->tensorflow<2.9.0,>=2.6.3->sleap) (0.37.1)\n", - "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.3.6)\n", - "Requirement already satisfied: tensorboard-plugin-wit>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.8.1)\n", - "Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.0.1)\n", - "Requirement already satisfied: requests<3,>=2.21.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (2.23.0)\n", - "Requirement already satisfied: google-auth<3,>=1.6.3 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.35.0)\n", - "Requirement already satisfied: tensorboard-data-server<0.7.0,>=0.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.6.1)\n", - "Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.4.6)\n", - "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.2.8)\n", - "Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (4.2.4)\n", - "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (4.8)\n", - "Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.7/dist-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.3.1)\n", - "Requirement already satisfied: importlib-metadata>=4.4 in /usr/local/lib/python3.7/dist-packages (from markdown>=2.6.8->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (4.11.3)\n", - "Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata>=4.4->markdown>=2.6.8->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.7.0)\n", - "Requirement already satisfied: pyasn1<0.5.0,>=0.4.6 in /usr/local/lib/python3.7/dist-packages (from pyasn1-modules>=0.2.1->google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.4.8)\n", - "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.0.4)\n", - "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.24.3)\n", - "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (2.10)\n", - "Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.7/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.2.0)\n", - "Building wheels for collected packages: pykalman, jsmin\n", - " Building wheel for pykalman (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Created wheel for pykalman: filename=pykalman-0.9.5-py3-none-any.whl size=48462 sha256=dde739150408cee5e4cb98680575a79e9cf2574d606fea22d81dac69689e1b5f\n", - " Stored in directory: /root/.cache/pip/wheels/6a/04/02/2dda6ea59c66d9e685affc8af3a31ad3a5d87b7311689efce6\n", - " Building wheel for jsmin (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Created wheel for jsmin: filename=jsmin-3.0.1-py3-none-any.whl size=13782 sha256=28e30a78deeb41cb8a5a2a452ecd4209438e26a6f74af8de2e29a7da35b6fe93\n", - " Stored in directory: /root/.cache/pip/wheels/a4/0b/64/fb4f87526ecbdf7921769a39d91dcfe4860e621cf15b8250d6\n", - "Successfully built pykalman jsmin\n", - "Installing collected packages: keras-applications, tf-estimator-nightly, shiboken2, opencv-python, image-classifiers, efficientnet, commonmark, colorama, attrs, segmentation-models, scikit-video, rich, qimage2ndarray, python-rapidjson, PySide2, pykalman, opencv-python-headless, jsonpickle, jsmin, imgstore, imgaug, cattrs, sleap\n", - " Attempting uninstall: attrs\n", - " Found existing installation: attrs 21.4.0\n", - " Uninstalling attrs-21.4.0:\n", - " Successfully uninstalled attrs-21.4.0\n", - " Attempting uninstall: imgaug\n", - " Found existing installation: imgaug 0.2.9\n", - " Uninstalling imgaug-0.2.9:\n", - " Successfully uninstalled imgaug-0.2.9\n", - "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", - "datascience 0.10.6 requires folium==0.2.1, but you have folium 0.8.3 which is incompatible.\n", - "albumentations 0.1.12 requires imgaug<0.2.7,>=0.2.5, but you have imgaug 0.4.0 which is incompatible.\u001b[0m\n", - "Successfully installed PySide2-5.14.1 attrs-21.2.0 cattrs-1.1.1 colorama-0.4.4 commonmark-0.9.1 efficientnet-1.0.0 image-classifiers-1.0.0 imgaug-0.4.0 imgstore-0.2.9 jsmin-3.0.1 jsonpickle-1.2 keras-applications-1.0.8 opencv-python-4.5.5.64 opencv-python-headless-4.5.5.62 pykalman-0.9.5 python-rapidjson-1.6 qimage2ndarray-1.8.3 rich-10.16.1 scikit-video-1.1.11 segmentation-models-1.0.1 shiboken2-5.14.1 sleap-1.2.2 tf-estimator-nightly-2.8.0.dev2021122109\n" + "\u001b[31mERROR: Cannot uninstall opencv-python 4.6.0, RECORD file not found. Hint: The package was installed by conda.\u001b[0m\u001b[31m\n", + "\u001b[0m\u001b[31mERROR: Cannot uninstall shiboken2 5.15.6, RECORD file not found. You might be able to recover from this via: 'pip install --force-reinstall --no-deps shiboken2==5.15.6'.\u001b[0m\u001b[31m\n", + "\u001b[0m" ] } + ], + "source": [ + "# This should take care of all the dependencies on colab:\n", + "!pip uninstall -qqq -y opencv-python opencv-contrib-python\n", + "!pip install -qqq \"sleap[pypi]>=1.3.3\"\n", + "\n", + "\n", + "# But to do it locally, we'd recommend the conda package (available on Windows + Linux):\n", + "# conda create -n sleap -c sleap -c conda-forge -c nvidia sleap" ] }, { "cell_type": "markdown", - "source": [ - "Import SLEAP to make sure it installed correctly and print out some information about the system:" - ], "metadata": { "id": "qjfoeOZvpV8o" - } + }, + "source": [ + "Import SLEAP to make sure it installed correctly and print out some information about the system:" + ] }, { "cell_type": "code", + "execution_count": 5, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -252,23 +88,16 @@ "id": "jftAOyvvuQeh", "outputId": "f62974d2-51e7-47d8-defb-ab6f970c995f" }, - "source": [ - "import sleap\n", - "sleap.versions()\n", - "sleap.system_summary()" - ], - "execution_count": 2, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ - "INFO:numexpr.utils:NumExpr defaulting to 2 threads.\n", - "SLEAP: 1.2.2\n", - "TensorFlow: 2.8.0\n", + "SLEAP: 1.3.2\n", + "TensorFlow: 2.7.0\n", "Numpy: 1.21.5\n", - "Python: 3.7.13\n", - "OS: Linux-5.4.144+-x86_64-with-Ubuntu-18.04-bionic\n", + "Python: 3.7.12\n", + "OS: Linux-5.15.0-78-generic-x86_64-with-debian-bookworm-sid\n", "GPUs: 1/1 available\n", " Device: /physical_device:GPU:0\n", " Available: True\n", @@ -276,6 +105,11 @@ " Memory growth: None\n" ] } + ], + "source": [ + "import sleap\n", + "sleap.versions()\n", + "sleap.system_summary()" ] }, { @@ -293,47 +127,55 @@ }, { "cell_type": "code", + "execution_count": 6, "metadata": { - "id": "sDIF3RKdM86u", "colab": { "base_uri": "https://localhost:8080/" }, + "id": "sDIF3RKdM86u", "outputId": "9c267834-935c-4f90-bb77-c0f15814ba2a" }, - "source": [ - "# !curl -L --output labels.pkg.slp https://www.dropbox.com/s/b990gxjt3d3j3jh/210205.sleap_wt_gold.13pt.pkg.slp?dl=1\n", - "!curl -L --output labels.pkg.slp https://storage.googleapis.com/sleap-data/datasets/wt_gold.13pt/tracking_split2/train.pkg.slp\n", - "!ls -lah" - ], - "execution_count": 3, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ " % Total % Received % Xferd Average Speed Time Time Time Current\n", " Dload Upload Total Spent Left Speed\n", - "100 619M 100 619M 0 0 106M 0 0:00:05 0:00:05 --:--:-- 110M\n", - "total 620M\n", - "drwxr-xr-x 1 root root 4.0K Apr 3 23:48 .\n", - "drwxr-xr-x 1 root root 4.0K Apr 3 23:40 ..\n", - "drwxr-xr-x 4 root root 4.0K Mar 23 14:21 .config\n", - "-rw-r--r-- 1 root root 620M Apr 3 23:48 labels.pkg.slp\n", - "drwxr-xr-x 1 root root 4.0K Mar 23 14:22 sample_data\n" + "100 619M 100 619M 0 0 32.9M 0 0:00:18 0:00:18 --:--:-- 34.4M\n", + "total 622M\n", + "drwxrwxr-x 3 talmolab talmolab 4.0K Sep 1 14:23 .\n", + "drwxrwxr-x 10 talmolab talmolab 4.0K Aug 31 15:43 ..\n", + "drwxrwxr-x 2 talmolab talmolab 4.0K Jun 20 10:00 analysis_example\n", + "-rw-rw-r-- 1 talmolab talmolab 713K Jun 20 10:00 Analysis_examples.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 481K Sep 1 14:02 Data_structures.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 4.1K Jun 20 10:00 index.rst\n", + "-rw-rw-r-- 1 talmolab talmolab 179K Sep 1 13:58 Interactive_and_realtime_inference.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 120K Sep 1 14:21 Interactive_and_resumable_training.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 620M Sep 1 14:24 labels.pkg.slp\n", + "-rw-rw-r-- 1 talmolab talmolab 157K Sep 1 14:15 Model_evaluation.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 132K Sep 1 14:18 Post_inference_tracking.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 94K Sep 1 13:44 Training_and_inference_on_an_example_dataset.ipynb\n", + "-rw-rw-r-- 1 talmolab talmolab 12K Aug 31 11:39 Training_and_inference_using_Google_Drive.ipynb\n" ] } + ], + "source": [ + "# !curl -L --output labels.pkg.slp https://www.dropbox.com/s/b990gxjt3d3j3jh/210205.sleap_wt_gold.13pt.pkg.slp?dl=1\n", + "!curl -L --output labels.pkg.slp https://storage.googleapis.com/sleap-data/datasets/wt_gold.13pt/tracking_split2/train.pkg.slp\n", + "!ls -lah" ] }, { "cell_type": "code", - "source": [ - "TRAINING_SLP_FILE = \"labels.pkg.slp\"" - ], + "execution_count": 7, "metadata": { "id": "vbpBugZRp_S7" }, - "execution_count": 4, - "outputs": [] + "outputs": [], + "source": [ + "TRAINING_SLP_FILE = \"labels.pkg.slp\"" + ] }, { "cell_type": "markdown", @@ -350,9 +192,11 @@ }, { "cell_type": "code", + "execution_count": 8, "metadata": { "id": "Cqt1Bhp-OIsi" }, + "outputs": [], "source": [ "from sleap.nn.config import *\n", "\n", @@ -381,9 +225,7 @@ "\n", "# Setup how we want to save the trained model.\n", "cfg.outputs.run_name = \"baseline_model.topdown\"" - ], - "execution_count": 5, - "outputs": [] + ] }, { "cell_type": "markdown", @@ -410,6 +252,7 @@ }, { "cell_type": "code", + "execution_count": 9, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -417,20 +260,19 @@ "id": "enbK9O5Dv8Pd", "outputId": "0e36a6e2-a7e8-4d0f-e1d3-0d1b7abaf490" }, - "source": [ - "trainer = sleap.nn.training.Trainer.from_config(cfg)" - ], - "execution_count": 6, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "INFO:sleap.nn.training:Loading training labels from: labels.pkg.slp\n", "INFO:sleap.nn.training:Creating training and validation splits from validation fraction: 0.1\n", "INFO:sleap.nn.training: Splits: Training = 1440 / Validation = 160.\n" ] } + ], + "source": [ + "trainer = sleap.nn.training.Trainer.from_config(cfg)" ] }, { @@ -444,6 +286,7 @@ }, { "cell_type": "code", + "execution_count": 10, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -458,20 +301,37 @@ "id": "L8jNydTEwNA1", "outputId": "51828b8c-6d8b-4743-e9d2-9153f5b571c3" }, - "source": [ - "trainer.train()" - ], - "execution_count": 7, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "INFO:sleap.nn.training:Setting up for training...\n", "INFO:sleap.nn.training:Setting up pipeline builders...\n", "INFO:sleap.nn.training:Setting up model...\n", - "INFO:sleap.nn.training:Building test pipeline...\n", - "INFO:sleap.nn.training:Loaded test example. [6.047s]\n", + "INFO:sleap.nn.training:Building test pipeline...\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-09-01 14:24:11.775633: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX512F FMA\n", + "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n", + "2023-09-01 14:24:11.776555: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 14:24:11.777493: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 14:24:11.778196: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 14:24:12.055738: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 14:24:12.056597: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 14:24:12.057389: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 14:24:12.058046: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1525] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 21261 MB memory: -> device: 0, name: NVIDIA RTX A5000, pci bus id: 0000:01:00.0, compute capability: 8.6\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:sleap.nn.training:Loaded test example. [1.799s]\n", "INFO:sleap.nn.training: Input shape: (160, 160, 1)\n", "INFO:sleap.nn.training:Created Keras model.\n", "INFO:sleap.nn.training: Backbone: UNet(stacks=1, filters=16, filters_rate=2, kernel_size=3, stem_kernel_size=7, convs_per_block=2, stem_blocks=0, down_blocks=4, middle_block=True, up_blocks=2, up_interpolate=False, block_contraction=False)\n", @@ -481,6 +341,7 @@ "INFO:sleap.nn.training: [0] = CenteredInstanceConfmapsHead(part_names=['head', 'thorax', 'abdomen', 'wingL', 'wingR', 'forelegL4', 'forelegR4', 'midlegL4', 'midlegR4', 'hindlegL4', 'hindlegR4', 'eyeL', 'eyeR'], anchor_part='thorax', sigma=1.5, output_stride=4, loss_weight=1.0)\n", "INFO:sleap.nn.training: Outputs: \n", "INFO:sleap.nn.training: [0] = KerasTensor(type_spec=TensorSpec(shape=(None, 40, 40, 13), dtype=tf.float32, name=None), name='CenteredInstanceConfmapsHead/BiasAdd:0', description=\"created by layer 'CenteredInstanceConfmapsHead'\")\n", + "INFO:sleap.nn.training:Training from scratch\n", "INFO:sleap.nn.training:Setting up data pipelines...\n", "INFO:sleap.nn.training:Training set: n = 1440\n", "INFO:sleap.nn.training:Validation set: n = 160\n", @@ -490,132 +351,144 @@ "INFO:sleap.nn.training:Setting up outputs...\n", "INFO:sleap.nn.training:Created run path: models/baseline_model.topdown\n", "INFO:sleap.nn.training:Setting up visualization...\n", - "Unable to use Qt backend for matplotlib. This probably means Qt is running headless.\n", - "INFO:sleap.nn.training:Finished trainer set up. [10.4s]\n", + "INFO:sleap.nn.training:Finished trainer set up. [3.3s]\n", "INFO:sleap.nn.training:Creating tf.data.Datasets for training data generation...\n", - "INFO:sleap.nn.training:Finished creating training datasets. [29.5s]\n", + "INFO:sleap.nn.training:Finished creating training datasets. [16.2s]\n", "INFO:sleap.nn.training:Starting training loop...\n", - "Epoch 1/10\n", - "360/360 - 70s - loss: 0.0037 - head: 0.0029 - thorax: 0.0030 - abdomen: 0.0037 - wingL: 0.0041 - wingR: 0.0041 - forelegL4: 0.0037 - forelegR4: 0.0038 - midlegL4: 0.0041 - midlegR4: 0.0041 - hindlegL4: 0.0039 - hindlegR4: 0.0040 - eyeL: 0.0033 - eyeR: 0.0034 - val_loss: 0.0033 - val_head: 0.0017 - val_thorax: 0.0025 - val_abdomen: 0.0035 - val_wingL: 0.0039 - val_wingR: 0.0039 - val_forelegL4: 0.0033 - val_forelegR4: 0.0036 - val_midlegL4: 0.0040 - val_midlegR4: 0.0040 - val_hindlegL4: 0.0040 - val_hindlegR4: 0.0040 - val_eyeL: 0.0022 - val_eyeR: 0.0023 - lr: 1.0000e-04 - 70s/epoch - 194ms/step\n", + "Epoch 1/10\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-09-01 14:24:32.586040: I tensorflow/stream_executor/cuda/cuda_dnn.cc:366] Loaded cuDNN version 8201\n", + "2023-09-01 14:24:42.104556: I tensorflow/stream_executor/cuda/cuda_blas.cc:1774] TensorFloat-32 will be used for the matrix multiplication. This will only be logged once.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "360/360 - 12s - loss: 0.0037 - head: 0.0030 - thorax: 0.0030 - abdomen: 0.0036 - wingL: 0.0040 - wingR: 0.0040 - forelegL4: 0.0037 - forelegR4: 0.0038 - midlegL4: 0.0041 - midlegR4: 0.0041 - hindlegL4: 0.0039 - hindlegR4: 0.0040 - eyeL: 0.0035 - eyeR: 0.0035 - val_loss: 0.0033 - val_head: 0.0020 - val_thorax: 0.0029 - val_abdomen: 0.0030 - val_wingL: 0.0033 - val_wingR: 0.0034 - val_forelegL4: 0.0037 - val_forelegR4: 0.0036 - val_midlegL4: 0.0039 - val_midlegR4: 0.0039 - val_hindlegL4: 0.0037 - val_hindlegR4: 0.0038 - val_eyeL: 0.0029 - val_eyeR: 0.0027 - lr: 1.0000e-04 - 12s/epoch - 32ms/step\n", "Epoch 2/10\n", - "360/360 - 53s - loss: 0.0028 - head: 0.0013 - thorax: 0.0020 - abdomen: 0.0028 - wingL: 0.0031 - wingR: 0.0031 - forelegL4: 0.0032 - forelegR4: 0.0033 - midlegL4: 0.0039 - midlegR4: 0.0039 - hindlegL4: 0.0037 - hindlegR4: 0.0038 - eyeL: 0.0013 - eyeR: 0.0014 - val_loss: 0.0025 - val_head: 9.5906e-04 - val_thorax: 0.0013 - val_abdomen: 0.0023 - val_wingL: 0.0025 - val_wingR: 0.0025 - val_forelegL4: 0.0029 - val_forelegR4: 0.0030 - val_midlegL4: 0.0037 - val_midlegR4: 0.0038 - val_hindlegL4: 0.0037 - val_hindlegR4: 0.0038 - val_eyeL: 8.8668e-04 - val_eyeR: 9.7728e-04 - lr: 1.0000e-04 - 53s/epoch - 148ms/step\n", + "360/360 - 7s - loss: 0.0028 - head: 0.0013 - thorax: 0.0018 - abdomen: 0.0026 - wingL: 0.0027 - wingR: 0.0028 - forelegL4: 0.0032 - forelegR4: 0.0033 - midlegL4: 0.0038 - midlegR4: 0.0038 - hindlegL4: 0.0037 - hindlegR4: 0.0038 - eyeL: 0.0015 - eyeR: 0.0015 - val_loss: 0.0025 - val_head: 9.7323e-04 - val_thorax: 0.0011 - val_abdomen: 0.0026 - val_wingL: 0.0024 - val_wingR: 0.0026 - val_forelegL4: 0.0030 - val_forelegR4: 0.0030 - val_midlegL4: 0.0036 - val_midlegR4: 0.0037 - val_hindlegL4: 0.0038 - val_hindlegR4: 0.0037 - val_eyeL: 0.0012 - val_eyeR: 0.0012 - lr: 1.0000e-04 - 7s/epoch - 21ms/step\n", "Epoch 3/10\n", - "360/360 - 55s - loss: 0.0023 - head: 8.0222e-04 - thorax: 9.4507e-04 - abdomen: 0.0022 - wingL: 0.0022 - wingR: 0.0022 - forelegL4: 0.0027 - forelegR4: 0.0028 - midlegL4: 0.0035 - midlegR4: 0.0036 - hindlegL4: 0.0034 - hindlegR4: 0.0036 - eyeL: 8.5909e-04 - eyeR: 8.8003e-04 - val_loss: 0.0021 - val_head: 7.4704e-04 - val_thorax: 6.8354e-04 - val_abdomen: 0.0020 - val_wingL: 0.0018 - val_wingR: 0.0019 - val_forelegL4: 0.0024 - val_forelegR4: 0.0025 - val_midlegL4: 0.0031 - val_midlegR4: 0.0034 - val_hindlegL4: 0.0032 - val_hindlegR4: 0.0035 - val_eyeL: 7.6220e-04 - val_eyeR: 7.1808e-04 - lr: 1.0000e-04 - 55s/epoch - 154ms/step\n", + "360/360 - 7s - loss: 0.0022 - head: 8.0630e-04 - thorax: 6.7199e-04 - abdomen: 0.0022 - wingL: 0.0020 - wingR: 0.0021 - forelegL4: 0.0027 - forelegR4: 0.0027 - midlegL4: 0.0033 - midlegR4: 0.0035 - hindlegL4: 0.0034 - hindlegR4: 0.0035 - eyeL: 8.7345e-04 - eyeR: 8.4145e-04 - val_loss: 0.0020 - val_head: 8.6439e-04 - val_thorax: 5.9914e-04 - val_abdomen: 0.0020 - val_wingL: 0.0019 - val_wingR: 0.0020 - val_forelegL4: 0.0025 - val_forelegR4: 0.0024 - val_midlegL4: 0.0030 - val_midlegR4: 0.0031 - val_hindlegL4: 0.0030 - val_hindlegR4: 0.0031 - val_eyeL: 8.9466e-04 - val_eyeR: 9.5174e-04 - lr: 1.0000e-04 - 7s/epoch - 20ms/step\n", "Epoch 4/10\n", - "360/360 - 61s - loss: 0.0019 - head: 6.5537e-04 - thorax: 5.3996e-04 - abdomen: 0.0019 - wingL: 0.0018 - wingR: 0.0018 - forelegL4: 0.0023 - forelegR4: 0.0024 - midlegL4: 0.0027 - midlegR4: 0.0029 - hindlegL4: 0.0029 - hindlegR4: 0.0032 - eyeL: 7.4337e-04 - eyeR: 7.2396e-04 - val_loss: 0.0017 - val_head: 5.5193e-04 - val_thorax: 3.6303e-04 - val_abdomen: 0.0018 - val_wingL: 0.0016 - val_wingR: 0.0016 - val_forelegL4: 0.0020 - val_forelegR4: 0.0020 - val_midlegL4: 0.0023 - val_midlegR4: 0.0026 - val_hindlegL4: 0.0027 - val_hindlegR4: 0.0031 - val_eyeL: 6.5068e-04 - val_eyeR: 6.0169e-04 - lr: 1.0000e-04 - 61s/epoch - 169ms/step\n", + "360/360 - 7s - loss: 0.0018 - head: 6.7854e-04 - thorax: 4.6945e-04 - abdomen: 0.0020 - wingL: 0.0017 - wingR: 0.0018 - forelegL4: 0.0023 - forelegR4: 0.0023 - midlegL4: 0.0026 - midlegR4: 0.0027 - hindlegL4: 0.0028 - hindlegR4: 0.0029 - eyeL: 7.4546e-04 - eyeR: 6.9585e-04 - val_loss: 0.0018 - val_head: 7.7640e-04 - val_thorax: 5.3180e-04 - val_abdomen: 0.0020 - val_wingL: 0.0018 - val_wingR: 0.0018 - val_forelegL4: 0.0022 - val_forelegR4: 0.0022 - val_midlegL4: 0.0024 - val_midlegR4: 0.0025 - val_hindlegL4: 0.0026 - val_hindlegR4: 0.0026 - val_eyeL: 9.2650e-04 - val_eyeR: 9.0064e-04 - lr: 1.0000e-04 - 7s/epoch - 20ms/step\n", "Epoch 5/10\n", - "360/360 - 57s - loss: 0.0016 - head: 5.6982e-04 - thorax: 4.1064e-04 - abdomen: 0.0017 - wingL: 0.0016 - wingR: 0.0016 - forelegL4: 0.0020 - forelegR4: 0.0020 - midlegL4: 0.0021 - midlegR4: 0.0022 - hindlegL4: 0.0024 - hindlegR4: 0.0028 - eyeL: 6.5447e-04 - eyeR: 6.3768e-04 - val_loss: 0.0014 - val_head: 4.9811e-04 - val_thorax: 3.0411e-04 - val_abdomen: 0.0015 - val_wingL: 0.0014 - val_wingR: 0.0014 - val_forelegL4: 0.0017 - val_forelegR4: 0.0019 - val_midlegL4: 0.0018 - val_midlegR4: 0.0020 - val_hindlegL4: 0.0023 - val_hindlegR4: 0.0026 - val_eyeL: 5.9634e-04 - val_eyeR: 5.8405e-04 - lr: 1.0000e-04 - 57s/epoch - 157ms/step\n", + "360/360 - 7s - loss: 0.0015 - head: 5.8714e-04 - thorax: 4.0531e-04 - abdomen: 0.0017 - wingL: 0.0015 - wingR: 0.0015 - forelegL4: 0.0020 - forelegR4: 0.0019 - midlegL4: 0.0020 - midlegR4: 0.0021 - hindlegL4: 0.0023 - hindlegR4: 0.0024 - eyeL: 6.7827e-04 - eyeR: 6.2254e-04 - val_loss: 0.0015 - val_head: 6.5523e-04 - val_thorax: 4.4019e-04 - val_abdomen: 0.0016 - val_wingL: 0.0016 - val_wingR: 0.0015 - val_forelegL4: 0.0019 - val_forelegR4: 0.0020 - val_midlegL4: 0.0021 - val_midlegR4: 0.0020 - val_hindlegL4: 0.0021 - val_hindlegR4: 0.0021 - val_eyeL: 7.9871e-04 - val_eyeR: 7.8608e-04 - lr: 1.0000e-04 - 7s/epoch - 20ms/step\n", "Epoch 6/10\n", - "360/360 - 54s - loss: 0.0014 - head: 5.1206e-04 - thorax: 3.4952e-04 - abdomen: 0.0015 - wingL: 0.0014 - wingR: 0.0014 - forelegL4: 0.0017 - forelegR4: 0.0018 - midlegL4: 0.0017 - midlegR4: 0.0018 - hindlegL4: 0.0020 - hindlegR4: 0.0023 - eyeL: 6.0045e-04 - eyeR: 5.7847e-04 - val_loss: 0.0012 - val_head: 4.3860e-04 - val_thorax: 2.5352e-04 - val_abdomen: 0.0014 - val_wingL: 0.0013 - val_wingR: 0.0012 - val_forelegL4: 0.0015 - val_forelegR4: 0.0016 - val_midlegL4: 0.0014 - val_midlegR4: 0.0017 - val_hindlegL4: 0.0020 - val_hindlegR4: 0.0022 - val_eyeL: 5.1261e-04 - val_eyeR: 5.5203e-04 - lr: 1.0000e-04 - 54s/epoch - 151ms/step\n", + "360/360 - 7s - loss: 0.0013 - head: 5.3215e-04 - thorax: 3.5232e-04 - abdomen: 0.0016 - wingL: 0.0014 - wingR: 0.0014 - forelegL4: 0.0017 - forelegR4: 0.0018 - midlegL4: 0.0017 - midlegR4: 0.0018 - hindlegL4: 0.0020 - hindlegR4: 0.0021 - eyeL: 5.9826e-04 - eyeR: 5.6906e-04 - val_loss: 0.0013 - val_head: 5.3776e-04 - val_thorax: 3.7946e-04 - val_abdomen: 0.0014 - val_wingL: 0.0014 - val_wingR: 0.0013 - val_forelegL4: 0.0017 - val_forelegR4: 0.0018 - val_midlegL4: 0.0016 - val_midlegR4: 0.0017 - val_hindlegL4: 0.0017 - val_hindlegR4: 0.0018 - val_eyeL: 6.6378e-04 - val_eyeR: 6.5611e-04 - lr: 1.0000e-04 - 7s/epoch - 19ms/step\n", "Epoch 7/10\n", - "360/360 - 54s - loss: 0.0012 - head: 4.7131e-04 - thorax: 3.1231e-04 - abdomen: 0.0014 - wingL: 0.0012 - wingR: 0.0012 - forelegL4: 0.0016 - forelegR4: 0.0016 - midlegL4: 0.0015 - midlegR4: 0.0016 - hindlegL4: 0.0018 - hindlegR4: 0.0020 - eyeL: 5.7016e-04 - eyeR: 5.4539e-04 - val_loss: 0.0011 - val_head: 4.3133e-04 - val_thorax: 2.2694e-04 - val_abdomen: 0.0013 - val_wingL: 0.0011 - val_wingR: 0.0011 - val_forelegL4: 0.0014 - val_forelegR4: 0.0015 - val_midlegL4: 0.0013 - val_midlegR4: 0.0015 - val_hindlegL4: 0.0018 - val_hindlegR4: 0.0020 - val_eyeL: 5.5373e-04 - val_eyeR: 5.0355e-04 - lr: 1.0000e-04 - 54s/epoch - 149ms/step\n", + "360/360 - 7s - loss: 0.0012 - head: 4.8557e-04 - thorax: 3.1089e-04 - abdomen: 0.0014 - wingL: 0.0012 - wingR: 0.0012 - forelegL4: 0.0016 - forelegR4: 0.0016 - midlegL4: 0.0015 - midlegR4: 0.0016 - hindlegL4: 0.0018 - hindlegR4: 0.0019 - eyeL: 5.6096e-04 - eyeR: 5.3123e-04 - val_loss: 0.0012 - val_head: 5.2092e-04 - val_thorax: 3.4376e-04 - val_abdomen: 0.0014 - val_wingL: 0.0012 - val_wingR: 0.0012 - val_forelegL4: 0.0015 - val_forelegR4: 0.0017 - val_midlegL4: 0.0015 - val_midlegR4: 0.0015 - val_hindlegL4: 0.0017 - val_hindlegR4: 0.0017 - val_eyeL: 6.4288e-04 - val_eyeR: 6.0581e-04 - lr: 1.0000e-04 - 7s/epoch - 19ms/step\n", "Epoch 8/10\n", - "360/360 - 53s - loss: 0.0011 - head: 4.3369e-04 - thorax: 2.6750e-04 - abdomen: 0.0013 - wingL: 0.0011 - wingR: 0.0011 - forelegL4: 0.0015 - forelegR4: 0.0015 - midlegL4: 0.0014 - midlegR4: 0.0014 - hindlegL4: 0.0017 - hindlegR4: 0.0018 - eyeL: 5.2745e-04 - eyeR: 5.0480e-04 - val_loss: 0.0011 - val_head: 4.1774e-04 - val_thorax: 2.4407e-04 - val_abdomen: 0.0013 - val_wingL: 0.0011 - val_wingR: 0.0010 - val_forelegL4: 0.0013 - val_forelegR4: 0.0014 - val_midlegL4: 0.0012 - val_midlegR4: 0.0014 - val_hindlegL4: 0.0017 - val_hindlegR4: 0.0018 - val_eyeL: 6.2877e-04 - val_eyeR: 5.7243e-04 - lr: 1.0000e-04 - 53s/epoch - 148ms/step\n", + "360/360 - 7s - loss: 0.0011 - head: 4.3752e-04 - thorax: 2.7513e-04 - abdomen: 0.0013 - wingL: 0.0011 - wingR: 0.0011 - forelegL4: 0.0015 - forelegR4: 0.0015 - midlegL4: 0.0014 - midlegR4: 0.0014 - hindlegL4: 0.0017 - hindlegR4: 0.0017 - eyeL: 5.1807e-04 - eyeR: 4.9554e-04 - val_loss: 0.0011 - val_head: 5.6743e-04 - val_thorax: 3.5883e-04 - val_abdomen: 0.0014 - val_wingL: 0.0012 - val_wingR: 0.0011 - val_forelegL4: 0.0015 - val_forelegR4: 0.0016 - val_midlegL4: 0.0014 - val_midlegR4: 0.0014 - val_hindlegL4: 0.0015 - val_hindlegR4: 0.0015 - val_eyeL: 6.2925e-04 - val_eyeR: 6.5965e-04 - lr: 1.0000e-04 - 7s/epoch - 19ms/step\n", "Epoch 9/10\n", - "360/360 - 53s - loss: 0.0010 - head: 4.0425e-04 - thorax: 2.3597e-04 - abdomen: 0.0012 - wingL: 0.0010 - wingR: 0.0011 - forelegL4: 0.0014 - forelegR4: 0.0014 - midlegL4: 0.0013 - midlegR4: 0.0013 - hindlegL4: 0.0016 - hindlegR4: 0.0017 - eyeL: 5.0906e-04 - eyeR: 4.9227e-04 - val_loss: 0.0010 - val_head: 3.9088e-04 - val_thorax: 2.1458e-04 - val_abdomen: 0.0012 - val_wingL: 0.0010 - val_wingR: 9.4879e-04 - val_forelegL4: 0.0012 - val_forelegR4: 0.0013 - val_midlegL4: 0.0011 - val_midlegR4: 0.0014 - val_hindlegL4: 0.0016 - val_hindlegR4: 0.0017 - val_eyeL: 4.6829e-04 - val_eyeR: 4.7323e-04 - lr: 1.0000e-04 - 53s/epoch - 147ms/step\n", + "360/360 - 7s - loss: 0.0011 - head: 4.2635e-04 - thorax: 2.4829e-04 - abdomen: 0.0012 - wingL: 0.0010 - wingR: 0.0010 - forelegL4: 0.0015 - forelegR4: 0.0014 - midlegL4: 0.0013 - midlegR4: 0.0013 - hindlegL4: 0.0016 - hindlegR4: 0.0017 - eyeL: 5.0197e-04 - eyeR: 4.8384e-04 - val_loss: 0.0011 - val_head: 4.8699e-04 - val_thorax: 3.5631e-04 - val_abdomen: 0.0013 - val_wingL: 0.0011 - val_wingR: 0.0011 - val_forelegL4: 0.0014 - val_forelegR4: 0.0016 - val_midlegL4: 0.0013 - val_midlegR4: 0.0015 - val_hindlegL4: 0.0014 - val_hindlegR4: 0.0015 - val_eyeL: 6.1692e-04 - val_eyeR: 5.8370e-04 - lr: 1.0000e-04 - 7s/epoch - 19ms/step\n", "Epoch 10/10\n", - "360/360 - 55s - loss: 9.7632e-04 - head: 3.7896e-04 - thorax: 2.1828e-04 - abdomen: 0.0011 - wingL: 9.9185e-04 - wingR: 9.9033e-04 - forelegL4: 0.0014 - forelegR4: 0.0013 - midlegL4: 0.0012 - midlegR4: 0.0012 - hindlegL4: 0.0015 - hindlegR4: 0.0016 - eyeL: 4.7323e-04 - eyeR: 4.5868e-04 - val_loss: 9.2870e-04 - val_head: 3.3704e-04 - val_thorax: 1.5806e-04 - val_abdomen: 0.0010 - val_wingL: 9.5121e-04 - val_wingR: 9.2122e-04 - val_forelegL4: 0.0012 - val_forelegR4: 0.0014 - val_midlegL4: 0.0010 - val_midlegR4: 0.0012 - val_hindlegL4: 0.0015 - val_hindlegR4: 0.0016 - val_eyeL: 4.2130e-04 - val_eyeR: 4.1479e-04 - lr: 1.0000e-04 - 55s/epoch - 154ms/step\n", - "INFO:sleap.nn.training:Finished training loop. [9.4 min]\n", + "360/360 - 7s - loss: 9.8454e-04 - head: 3.9611e-04 - thorax: 2.2278e-04 - abdomen: 0.0012 - wingL: 9.4893e-04 - wingR: 9.5555e-04 - forelegL4: 0.0014 - forelegR4: 0.0014 - midlegL4: 0.0012 - midlegR4: 0.0012 - hindlegL4: 0.0015 - hindlegR4: 0.0016 - eyeL: 4.7396e-04 - eyeR: 4.4770e-04 - val_loss: 0.0010 - val_head: 4.9330e-04 - val_thorax: 2.9460e-04 - val_abdomen: 0.0013 - val_wingL: 9.5190e-04 - val_wingR: 9.9289e-04 - val_forelegL4: 0.0014 - val_forelegR4: 0.0015 - val_midlegL4: 0.0012 - val_midlegR4: 0.0012 - val_hindlegL4: 0.0014 - val_hindlegR4: 0.0014 - val_eyeL: 5.5512e-04 - val_eyeR: 5.3737e-04 - lr: 1.0000e-04 - 7s/epoch - 19ms/step\n", + "INFO:sleap.nn.training:Finished training loop. [1.3 min]\n", "INFO:sleap.nn.training:Deleting visualization directory: models/baseline_model.topdown/viz\n", "INFO:sleap.nn.training:Saving evaluation metrics to model folder...\n" ] }, { - "output_type": "display_data", "data": { - "text/plain": [ - "Output()" - ], "application/vnd.jupyter.widget-view+json": { + "model_id": "9864dea73605449cb08b26c938812cfb", "version_major": 2, - "version_minor": 0, - "model_id": "6b2a262ed72e4c659969f996ac889aa7" - } + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "
\n"
-            ]
+            ],
+            "text/plain": []
           },
-          "metadata": {}
+          "metadata": {},
+          "output_type": "display_data"
         },
         {
-          "output_type": "display_data",
           "data": {
-            "text/plain": [
-              "\n"
-            ],
             "text/html": [
               "
\n",
               "
\n" + ], + "text/plain": [ + "\n" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "INFO:sleap.nn.evals:Saved predictions: models/baseline_model.topdown/labels_pr.train.slp\n", "INFO:sleap.nn.evals:Saved metrics: models/baseline_model.topdown/metrics.train.npz\n", - "INFO:sleap.nn.evals:OKS mAP: 0.518988\n" + "INFO:sleap.nn.evals:OKS mAP: 0.508754\n" ] }, { - "output_type": "display_data", "data": { - "text/plain": [ - "Output()" - ], "application/vnd.jupyter.widget-view+json": { + "model_id": "243984a359bc41e9975653fa6206ac27", "version_major": 2, - "version_minor": 0, - "model_id": "973660ab9cb2472786b368a18db11c63" - } + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "
\n"
-            ]
+            ],
+            "text/plain": []
           },
-          "metadata": {}
+          "metadata": {},
+          "output_type": "display_data"
         },
         {
-          "output_type": "display_data",
           "data": {
-            "text/plain": [
-              "\n"
-            ],
             "text/html": [
               "
\n",
               "
\n" + ], + "text/plain": [ + "\n" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "INFO:sleap.nn.evals:Saved predictions: models/baseline_model.topdown/labels_pr.val.slp\n", "INFO:sleap.nn.evals:Saved metrics: models/baseline_model.topdown/metrics.val.npz\n", - "INFO:sleap.nn.evals:OKS mAP: 0.520377\n" + "INFO:sleap.nn.evals:OKS mAP: 0.477220\n" ] } + ], + "source": [ + "trainer.train()" ] }, { @@ -631,6 +504,7 @@ }, { "cell_type": "code", + "execution_count": 11, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -645,126 +519,121 @@ "id": "ENOiptvQwrtI", "outputId": "ccdec444-17ae-4040-9aa3-509086e3dc37" }, - "source": [ - "trainer.config.optimization.epochs = 3\n", - "trainer.train()" - ], - "execution_count": 8, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "INFO:sleap.nn.training:Creating tf.data.Datasets for training data generation...\n", - "INFO:sleap.nn.training:Finished creating training datasets. [29.4s]\n", + "INFO:sleap.nn.training:Finished creating training datasets. [17.1s]\n", "INFO:sleap.nn.training:Starting training loop...\n", "Epoch 1/3\n", - "360/360 - 57s - loss: 9.1732e-04 - head: 3.5629e-04 - thorax: 1.9609e-04 - abdomen: 0.0010 - wingL: 9.1318e-04 - wingR: 9.1330e-04 - forelegL4: 0.0013 - forelegR4: 0.0013 - midlegL4: 0.0011 - midlegR4: 0.0011 - hindlegL4: 0.0014 - hindlegR4: 0.0015 - eyeL: 4.4475e-04 - eyeR: 4.3944e-04 - val_loss: 9.2727e-04 - val_head: 3.8719e-04 - val_thorax: 1.5200e-04 - val_abdomen: 0.0011 - val_wingL: 9.3115e-04 - val_wingR: 8.9376e-04 - val_forelegL4: 0.0012 - val_forelegR4: 0.0012 - val_midlegL4: 9.9703e-04 - val_midlegR4: 0.0012 - val_hindlegL4: 0.0015 - val_hindlegR4: 0.0016 - val_eyeL: 4.5374e-04 - val_eyeR: 5.1839e-04 - lr: 1.0000e-04 - 57s/epoch - 158ms/step\n", + "360/360 - 7s - loss: 9.3201e-04 - head: 3.7118e-04 - thorax: 2.0303e-04 - abdomen: 0.0011 - wingL: 8.9319e-04 - wingR: 9.0134e-04 - forelegL4: 0.0013 - forelegR4: 0.0013 - midlegL4: 0.0011 - midlegR4: 0.0011 - hindlegL4: 0.0014 - hindlegR4: 0.0015 - eyeL: 4.4919e-04 - eyeR: 4.2012e-04 - val_loss: 9.4680e-04 - val_head: 3.9131e-04 - val_thorax: 2.4191e-04 - val_abdomen: 0.0010 - val_wingL: 8.9155e-04 - val_wingR: 8.9295e-04 - val_forelegL4: 0.0013 - val_forelegR4: 0.0014 - val_midlegL4: 0.0012 - val_midlegR4: 0.0012 - val_hindlegL4: 0.0013 - val_hindlegR4: 0.0013 - val_eyeL: 5.3658e-04 - val_eyeR: 5.0085e-04 - lr: 1.0000e-04 - 7s/epoch - 20ms/step\n", "Epoch 2/3\n", - "360/360 - 56s - loss: 8.7900e-04 - head: 3.4532e-04 - thorax: 1.7895e-04 - abdomen: 0.0010 - wingL: 8.7539e-04 - wingR: 8.8524e-04 - forelegL4: 0.0012 - forelegR4: 0.0012 - midlegL4: 0.0010 - midlegR4: 0.0010 - hindlegL4: 0.0014 - hindlegR4: 0.0014 - eyeL: 4.3484e-04 - eyeR: 4.2888e-04 - val_loss: 8.5310e-04 - val_head: 3.0429e-04 - val_thorax: 1.4837e-04 - val_abdomen: 0.0010 - val_wingL: 8.2237e-04 - val_wingR: 8.3093e-04 - val_forelegL4: 0.0011 - val_forelegR4: 0.0012 - val_midlegL4: 8.5634e-04 - val_midlegR4: 0.0011 - val_hindlegL4: 0.0014 - val_hindlegR4: 0.0015 - val_eyeL: 4.0362e-04 - val_eyeR: 3.8104e-04 - lr: 1.0000e-04 - 56s/epoch - 156ms/step\n", + "360/360 - 7s - loss: 8.8906e-04 - head: 3.6015e-04 - thorax: 1.9128e-04 - abdomen: 0.0010 - wingL: 8.5054e-04 - wingR: 8.5352e-04 - forelegL4: 0.0013 - forelegR4: 0.0013 - midlegL4: 0.0010 - midlegR4: 0.0011 - hindlegL4: 0.0014 - hindlegR4: 0.0014 - eyeL: 4.3093e-04 - eyeR: 4.0690e-04 - val_loss: 8.9501e-04 - val_head: 4.1907e-04 - val_thorax: 2.3487e-04 - val_abdomen: 0.0010 - val_wingL: 8.6145e-04 - val_wingR: 8.4151e-04 - val_forelegL4: 0.0013 - val_forelegR4: 0.0014 - val_midlegL4: 0.0010 - val_midlegR4: 0.0011 - val_hindlegL4: 0.0013 - val_hindlegR4: 0.0012 - val_eyeL: 5.2130e-04 - val_eyeR: 4.9293e-04 - lr: 1.0000e-04 - 7s/epoch - 19ms/step\n", "Epoch 3/3\n", - "360/360 - 56s - loss: 8.4466e-04 - head: 3.4540e-04 - thorax: 1.6180e-04 - abdomen: 9.6890e-04 - wingL: 8.4974e-04 - wingR: 8.5187e-04 - forelegL4: 0.0012 - forelegR4: 0.0012 - midlegL4: 9.5015e-04 - midlegR4: 9.8870e-04 - hindlegL4: 0.0013 - hindlegR4: 0.0014 - eyeL: 4.2245e-04 - eyeR: 4.0856e-04 - val_loss: 8.2153e-04 - val_head: 3.1832e-04 - val_thorax: 1.4803e-04 - val_abdomen: 9.4013e-04 - val_wingL: 8.4738e-04 - val_wingR: 8.4686e-04 - val_forelegL4: 0.0010 - val_forelegR4: 0.0011 - val_midlegL4: 8.5740e-04 - val_midlegR4: 0.0010 - val_hindlegL4: 0.0014 - val_hindlegR4: 0.0015 - val_eyeL: 3.7928e-04 - val_eyeR: 3.8285e-04 - lr: 1.0000e-04 - 56s/epoch - 156ms/step\n", - "INFO:sleap.nn.training:Finished training loop. [2.8 min]\n", + "360/360 - 7s - loss: 8.5396e-04 - head: 3.4440e-04 - thorax: 1.7180e-04 - abdomen: 9.9867e-04 - wingL: 8.1743e-04 - wingR: 8.2288e-04 - forelegL4: 0.0012 - forelegR4: 0.0012 - midlegL4: 9.7110e-04 - midlegR4: 0.0010 - hindlegL4: 0.0013 - hindlegR4: 0.0014 - eyeL: 4.1497e-04 - eyeR: 3.9294e-04 - val_loss: 8.8076e-04 - val_head: 3.7130e-04 - val_thorax: 2.4712e-04 - val_abdomen: 0.0010 - val_wingL: 8.2889e-04 - val_wingR: 8.5931e-04 - val_forelegL4: 0.0012 - val_forelegR4: 0.0014 - val_midlegL4: 9.9400e-04 - val_midlegR4: 0.0011 - val_hindlegL4: 0.0012 - val_hindlegR4: 0.0012 - val_eyeL: 4.9486e-04 - val_eyeR: 4.6961e-04 - lr: 1.0000e-04 - 7s/epoch - 19ms/step\n", + "INFO:sleap.nn.training:Finished training loop. [0.4 min]\n", "INFO:sleap.nn.training:Deleting visualization directory: models/baseline_model.topdown/viz\n", "INFO:sleap.nn.training:Saving evaluation metrics to model folder...\n" ] }, { - "output_type": "display_data", "data": { - "text/plain": [ - "Output()" - ], "application/vnd.jupyter.widget-view+json": { + "model_id": "f1bb0ee48431420d9cb6d99c4db4680d", "version_major": 2, - "version_minor": 0, - "model_id": "d49529f91f6d4090a7820b081094823d" - } + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "
\n"
-            ]
+            ],
+            "text/plain": []
           },
-          "metadata": {}
+          "metadata": {},
+          "output_type": "display_data"
         },
         {
-          "output_type": "display_data",
           "data": {
-            "text/plain": [
-              "\n"
-            ],
             "text/html": [
               "
\n",
               "
\n" + ], + "text/plain": [ + "\n" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "INFO:sleap.nn.evals:Saved predictions: models/baseline_model.topdown/labels_pr.train.slp\n", "INFO:sleap.nn.evals:Saved metrics: models/baseline_model.topdown/metrics.train.npz\n", - "INFO:sleap.nn.evals:OKS mAP: 0.551905\n" + "INFO:sleap.nn.evals:OKS mAP: 0.559100\n" ] }, { - "output_type": "display_data", "data": { - "text/plain": [ - "Output()" - ], "application/vnd.jupyter.widget-view+json": { + "model_id": "db5de880cd154476a097178972c8f0a3", "version_major": 2, - "version_minor": 0, - "model_id": "8291326df0b9435b8ba2298c8977778b" - } + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "
\n"
-            ]
+            ],
+            "text/plain": []
           },
-          "metadata": {}
+          "metadata": {},
+          "output_type": "display_data"
         },
         {
-          "output_type": "display_data",
           "data": {
-            "text/plain": [
-              "\n"
-            ],
             "text/html": [
               "
\n",
               "
\n" + ], + "text/plain": [ + "\n" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "INFO:sleap.nn.evals:Saved predictions: models/baseline_model.topdown/labels_pr.val.slp\n", "INFO:sleap.nn.evals:Saved metrics: models/baseline_model.topdown/metrics.val.npz\n", - "INFO:sleap.nn.evals:OKS mAP: 0.551469\n" + "INFO:sleap.nn.evals:OKS mAP: 0.529680\n" ] } + ], + "source": [ + "trainer.config.optimization.epochs = 3\n", + "trainer.train()" ] }, { @@ -789,6 +658,7 @@ }, { "cell_type": "code", + "execution_count": 12, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -796,23 +666,10 @@ "id": "NDL6ScTDxrso", "outputId": "f63c3ef8-97d0-4484-e951-b120dcbbffac" }, - "source": [ - "# Load config.\n", - "cfg = sleap.load_config(\"models/baseline_model.topdown\")\n", - "# cfg.outputs.run_name = \"new_folder\" # Set the run_name to a new value if you want the model to be saved to a different folder.\n", - "\n", - "# Create and initialize the trainer.\n", - "trainer = sleap.nn.training.Trainer.from_config(cfg)\n", - "trainer.setup()\n", - "\n", - "# Replace the randomly initialized weights with the saved weights.\n", - "trainer.keras_model.load_weights(\"models/baseline_model.topdown/best_model.h5\")" - ], - "execution_count": 9, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "INFO:sleap.nn.training:Loading training labels from: labels.pkg.slp\n", "INFO:sleap.nn.training:Creating training and validation splits from validation fraction: 0.1\n", @@ -821,7 +678,7 @@ "INFO:sleap.nn.training:Setting up pipeline builders...\n", "INFO:sleap.nn.training:Setting up model...\n", "INFO:sleap.nn.training:Building test pipeline...\n", - "INFO:sleap.nn.training:Loaded test example. [1.909s]\n", + "INFO:sleap.nn.training:Loaded test example. [0.925s]\n", "INFO:sleap.nn.training: Input shape: (160, 160, 1)\n", "INFO:sleap.nn.training:Created Keras model.\n", "INFO:sleap.nn.training: Backbone: UNet(stacks=1, filters=16, filters_rate=2.0, kernel_size=3, stem_kernel_size=7, convs_per_block=2, stem_blocks=0, down_blocks=4, middle_block=True, up_blocks=2, up_interpolate=False, block_contraction=False)\n", @@ -831,6 +688,7 @@ "INFO:sleap.nn.training: [0] = CenteredInstanceConfmapsHead(part_names=['head', 'thorax', 'abdomen', 'wingL', 'wingR', 'forelegL4', 'forelegR4', 'midlegL4', 'midlegR4', 'hindlegL4', 'hindlegR4', 'eyeL', 'eyeR'], anchor_part='thorax', sigma=1.5, output_stride=4, loss_weight=1.0)\n", "INFO:sleap.nn.training: Outputs: \n", "INFO:sleap.nn.training: [0] = KerasTensor(type_spec=TensorSpec(shape=(None, 40, 40, 13), dtype=tf.float32, name=None), name='CenteredInstanceConfmapsHead/BiasAdd:0', description=\"created by layer 'CenteredInstanceConfmapsHead'\")\n", + "INFO:sleap.nn.training:Training from scratch\n", "INFO:sleap.nn.training:Setting up data pipelines...\n", "INFO:sleap.nn.training:Training set: n = 1440\n", "INFO:sleap.nn.training:Validation set: n = 160\n", @@ -840,13 +698,26 @@ "INFO:sleap.nn.training:Setting up outputs...\n", "INFO:sleap.nn.training:Created run path: models/baseline_model.topdown\n", "INFO:sleap.nn.training:Setting up visualization...\n", - "INFO:sleap.nn.training:Finished trainer set up. [6.0s]\n" + "INFO:sleap.nn.training:Finished trainer set up. [2.2s]\n" ] } + ], + "source": [ + "# Load config.\n", + "cfg = sleap.load_config(\"models/baseline_model.topdown\")\n", + "# cfg.outputs.run_name = \"new_folder\" # Set the run_name to a new value if you want the model to be saved to a different folder.\n", + "\n", + "# Create and initialize the trainer.\n", + "trainer = sleap.nn.training.Trainer.from_config(cfg)\n", + "trainer.setup()\n", + "\n", + "# Replace the randomly initialized weights with the saved weights.\n", + "trainer.keras_model.load_weights(\"models/baseline_model.topdown/best_model.h5\")" ] }, { "cell_type": "code", + "execution_count": 13, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -861,126 +732,121 @@ "id": "HlGP3dYMy2NG", "outputId": "c32a4240-1abd-401b-caab-4d64bec8348d" }, - "source": [ - "trainer.config.optimization.epochs = 3\n", - "trainer.train()" - ], - "execution_count": 10, "outputs": [ { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "INFO:sleap.nn.training:Creating tf.data.Datasets for training data generation...\n", - "INFO:sleap.nn.training:Finished creating training datasets. [28.9s]\n", + "INFO:sleap.nn.training:Finished creating training datasets. [17.7s]\n", "INFO:sleap.nn.training:Starting training loop...\n", "Epoch 1/3\n", - "360/360 - 63s - loss: 8.2769e-04 - head: 3.4427e-04 - thorax: 1.6900e-04 - abdomen: 9.4941e-04 - wingL: 8.1514e-04 - wingR: 8.1826e-04 - forelegL4: 0.0012 - forelegR4: 0.0012 - midlegL4: 9.2980e-04 - midlegR4: 9.6439e-04 - hindlegL4: 0.0013 - hindlegR4: 0.0013 - eyeL: 4.2129e-04 - eyeR: 4.0767e-04 - val_loss: 7.8855e-04 - val_head: 3.2701e-04 - val_thorax: 1.8405e-04 - val_abdomen: 0.0010 - val_wingL: 7.3709e-04 - val_wingR: 7.1027e-04 - val_forelegL4: 0.0010 - val_forelegR4: 0.0011 - val_midlegL4: 9.3918e-04 - val_midlegR4: 9.0288e-04 - val_hindlegL4: 0.0012 - val_hindlegR4: 0.0013 - val_eyeL: 3.8746e-04 - val_eyeR: 3.3939e-04 - lr: 1.0000e-04 - 63s/epoch - 174ms/step\n", + "360/360 - 9s - loss: 8.3664e-04 - head: 3.5190e-04 - thorax: 1.7037e-04 - abdomen: 9.8467e-04 - wingL: 7.9929e-04 - wingR: 8.0385e-04 - forelegL4: 0.0012 - forelegR4: 0.0012 - midlegL4: 9.5228e-04 - midlegR4: 9.8510e-04 - hindlegL4: 0.0013 - hindlegR4: 0.0013 - eyeL: 4.0772e-04 - eyeR: 3.9413e-04 - val_loss: 8.7351e-04 - val_head: 4.0943e-04 - val_thorax: 1.7453e-04 - val_abdomen: 9.4413e-04 - val_wingL: 8.3617e-04 - val_wingR: 8.4860e-04 - val_forelegL4: 0.0012 - val_forelegR4: 0.0012 - val_midlegL4: 9.4441e-04 - val_midlegR4: 0.0011 - val_hindlegL4: 0.0014 - val_hindlegR4: 0.0014 - val_eyeL: 4.4847e-04 - val_eyeR: 4.4179e-04 - lr: 1.0000e-04 - 9s/epoch - 24ms/step\n", "Epoch 2/3\n", - "360/360 - 58s - loss: 7.9662e-04 - head: 3.2407e-04 - thorax: 1.5127e-04 - abdomen: 9.1911e-04 - wingL: 7.6866e-04 - wingR: 7.8884e-04 - forelegL4: 0.0011 - forelegR4: 0.0011 - midlegL4: 8.8560e-04 - midlegR4: 9.3151e-04 - hindlegL4: 0.0012 - hindlegR4: 0.0013 - eyeL: 4.1677e-04 - eyeR: 3.9983e-04 - val_loss: 7.3673e-04 - val_head: 2.8314e-04 - val_thorax: 1.1026e-04 - val_abdomen: 9.4263e-04 - val_wingL: 6.7871e-04 - val_wingR: 6.4992e-04 - val_forelegL4: 0.0011 - val_forelegR4: 0.0011 - val_midlegL4: 8.0315e-04 - val_midlegR4: 8.3331e-04 - val_hindlegL4: 0.0012 - val_hindlegR4: 0.0012 - val_eyeL: 3.4531e-04 - val_eyeR: 3.5707e-04 - lr: 1.0000e-04 - 58s/epoch - 162ms/step\n", + "360/360 - 7s - loss: 8.0541e-04 - head: 3.4627e-04 - thorax: 1.6070e-04 - abdomen: 9.4325e-04 - wingL: 7.7257e-04 - wingR: 7.7434e-04 - forelegL4: 0.0012 - forelegR4: 0.0012 - midlegL4: 8.9573e-04 - midlegR4: 9.3483e-04 - hindlegL4: 0.0013 - hindlegR4: 0.0013 - eyeL: 4.0939e-04 - eyeR: 3.8417e-04 - val_loss: 8.2339e-04 - val_head: 3.9561e-04 - val_thorax: 1.2637e-04 - val_abdomen: 8.6513e-04 - val_wingL: 7.1751e-04 - val_wingR: 7.5540e-04 - val_forelegL4: 0.0012 - val_forelegR4: 0.0012 - val_midlegL4: 8.5588e-04 - val_midlegR4: 0.0010 - val_hindlegL4: 0.0013 - val_hindlegR4: 0.0014 - val_eyeL: 4.8189e-04 - val_eyeR: 4.2402e-04 - lr: 1.0000e-04 - 7s/epoch - 20ms/step\n", "Epoch 3/3\n", - "360/360 - 58s - loss: 7.6463e-04 - head: 3.0854e-04 - thorax: 1.3497e-04 - abdomen: 8.9188e-04 - wingL: 7.4921e-04 - wingR: 7.5430e-04 - forelegL4: 0.0011 - forelegR4: 0.0011 - midlegL4: 8.3320e-04 - midlegR4: 8.7736e-04 - hindlegL4: 0.0012 - hindlegR4: 0.0013 - eyeL: 3.9640e-04 - eyeR: 3.7940e-04 - val_loss: 7.0126e-04 - val_head: 2.8905e-04 - val_thorax: 1.1305e-04 - val_abdomen: 9.0676e-04 - val_wingL: 6.4827e-04 - val_wingR: 6.2576e-04 - val_forelegL4: 0.0010 - val_forelegR4: 9.8253e-04 - val_midlegL4: 8.0471e-04 - val_midlegR4: 7.3788e-04 - val_hindlegL4: 0.0011 - val_hindlegR4: 0.0012 - val_eyeL: 3.1543e-04 - val_eyeR: 3.4044e-04 - lr: 1.0000e-04 - 58s/epoch - 161ms/step\n", - "INFO:sleap.nn.training:Finished training loop. [3.0 min]\n", + "360/360 - 7s - loss: 7.7741e-04 - head: 3.2087e-04 - thorax: 1.4398e-04 - abdomen: 9.1826e-04 - wingL: 7.4005e-04 - wingR: 7.5282e-04 - forelegL4: 0.0011 - forelegR4: 0.0011 - midlegL4: 8.6551e-04 - midlegR4: 8.9726e-04 - hindlegL4: 0.0012 - hindlegR4: 0.0013 - eyeL: 3.8423e-04 - eyeR: 3.7468e-04 - val_loss: 8.4657e-04 - val_head: 3.5649e-04 - val_thorax: 1.2162e-04 - val_abdomen: 8.9171e-04 - val_wingL: 7.9007e-04 - val_wingR: 8.2471e-04 - val_forelegL4: 0.0013 - val_forelegR4: 0.0013 - val_midlegL4: 8.1375e-04 - val_midlegR4: 9.8217e-04 - val_hindlegL4: 0.0014 - val_hindlegR4: 0.0013 - val_eyeL: 4.7370e-04 - val_eyeR: 4.2098e-04 - lr: 1.0000e-04 - 7s/epoch - 19ms/step\n", + "INFO:sleap.nn.training:Finished training loop. [0.4 min]\n", "INFO:sleap.nn.training:Deleting visualization directory: models/baseline_model.topdown/viz\n", "INFO:sleap.nn.training:Saving evaluation metrics to model folder...\n" ] }, { - "output_type": "display_data", "data": { - "text/plain": [ - "Output()" - ], "application/vnd.jupyter.widget-view+json": { + "model_id": "b94057057f6442c990c6fc548910a685", "version_major": 2, - "version_minor": 0, - "model_id": "c74d0a9e497146acaf8da36faf5f496a" - } + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "
\n"
-            ]
+            ],
+            "text/plain": []
           },
-          "metadata": {}
+          "metadata": {},
+          "output_type": "display_data"
         },
         {
-          "output_type": "display_data",
           "data": {
-            "text/plain": [
-              "\n"
-            ],
             "text/html": [
               "
\n",
               "
\n" + ], + "text/plain": [ + "\n" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "INFO:sleap.nn.evals:Saved predictions: models/baseline_model.topdown/labels_pr.train.slp\n", "INFO:sleap.nn.evals:Saved metrics: models/baseline_model.topdown/metrics.train.npz\n", - "INFO:sleap.nn.evals:OKS mAP: 0.597609\n" + "INFO:sleap.nn.evals:OKS mAP: 0.585451\n" ] }, { - "output_type": "display_data", "data": { - "text/plain": [ - "Output()" - ], "application/vnd.jupyter.widget-view+json": { + "model_id": "8f2e64c8d4d6457986ee8b43b47e2876", "version_major": 2, - "version_minor": 0, - "model_id": "bf6a847899a24fcea5f14409a7ee1c33" - } + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "display_data", "data": { - "text/plain": [ - "" - ], "text/html": [ "
\n"
-            ]
+            ],
+            "text/plain": []
           },
-          "metadata": {}
+          "metadata": {},
+          "output_type": "display_data"
         },
         {
-          "output_type": "display_data",
           "data": {
-            "text/plain": [
-              "\n"
-            ],
             "text/html": [
               "
\n",
               "
\n" + ], + "text/plain": [ + "\n" ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" }, { - "output_type": "stream", "name": "stdout", + "output_type": "stream", "text": [ "INFO:sleap.nn.evals:Saved predictions: models/baseline_model.topdown/labels_pr.val.slp\n", "INFO:sleap.nn.evals:Saved metrics: models/baseline_model.topdown/metrics.val.npz\n", - "INFO:sleap.nn.evals:OKS mAP: 0.621393\n" + "INFO:sleap.nn.evals:OKS mAP: 0.574921\n" ] } + ], + "source": [ + "trainer.config.optimization.epochs = 3\n", + "trainer.train()" ] }, { @@ -994,5 +860,32 @@ "The resulting model can be used as usual for inference on new data." ] } - ] + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "collapsed_sections": [], + "machine_shape": "hm", + "name": "SLEAP - Interactive and resumable training.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.12" + } + }, + "nbformat": 4, + "nbformat_minor": 0 } diff --git a/docs/notebooks/Model_evaluation.ipynb b/docs/notebooks/Model_evaluation.ipynb index 4c072d7e9..41ca6568c 100644 --- a/docs/notebooks/Model_evaluation.ipynb +++ b/docs/notebooks/Model_evaluation.ipynb @@ -24,17 +24,26 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 3, "metadata": { "id": "5bNDjxe1BZXV" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[1;31mE: \u001b[0mCould not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)\u001b[0m\n", + "\u001b[1;31mE: \u001b[0mUnable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?\u001b[0m\n" + ] + } + ], "source": [ - "!pip uninstall -y opencv-python opencv-contrib-python > /dev/null 2>&1\n", - "!pip install sleap > /dev/null 2>&1\n", - "!apt install tree > /dev/null 2>&1\n", - "!wget https://storage.googleapis.com/sleap-data/reference/flies13/td_fast.210505_012601.centered_instance.n%3D1800.zip > /dev/null 2>&1\n", - "!unzip -o -d \"td_fast.210505_012601.centered_instance.n=1800\" \"td_fast.210505_012601.centered_instance.n=1800.zip\" > /dev/null 2>&1" + "!pip uninstall -qqq -y opencv-python opencv-contrib-python\n", + "!pip install -qqq \"sleap[pypi]>=1.3.3\"\n", + "!apt -qq install tree\n", + "!wget -q https://storage.googleapis.com/sleap-data/reference/flies13/td_fast.210505_012601.centered_instance.n%3D1800.zip\n", + "!unzip -qq -o -d \"td_fast.210505_012601.centered_instance.n=1800\" \"td_fast.210505_012601.centered_instance.n=1800.zip\"" ] }, { @@ -53,7 +62,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 4, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -66,7 +75,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "td_fast.210505_012601.centered_instance.n=1800\n", + "\u001b[01;34mtd_fast.210505_012601.centered_instance.n=1800\u001b[00m\n", "├── best_model.h5\n", "├── initial_config.json\n", "├── labels_gt.test.slp\n", @@ -102,12 +111,12 @@ "- `best_model.h5`: The actual saved model and weights. This can be loaded with `tf.keras.model.load_model()` but it is recommended to use `sleap.load_model()` instead as it takes care of adding some additional inference-only procedures.\n", "- `training_config.json`: The configuration for the model training job, including metadata inferred during the training procedure. It can be loaded with `sleap.load_config()`.\n", "- `labels_gt.train.slp` and `labels_pr.train.slp`: These are SLEAP labels files containing the ground truth and predicted points for the training split. They do not contain the images, but can be used to retrieve the poses used.\n", - "- `labels_gt.train.slp` and `labels_pr.train.slp`: These are SLEAP labels files containing the ground truth and predicted points for the validation split. They do not contain the images, but can be used to retrieve the poses used." + "- `labels_gt.val.slp` and `labels_pr.val.slp`: These are SLEAP labels files containing the ground truth and predicted points for the validation split. They do not contain the images, but can be used to retrieve the poses used." ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 5, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -116,15 +125,23 @@ "outputId": "fedb9d7b-6dcc-4048-d030-eba38a006086" }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-09-01 14:13:14.982109: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-09-01 14:13:14.982120: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "SLEAP: 1.1.5\n", - "TensorFlow: 2.3.1\n", - "Numpy: 1.19.5\n", - "Python: 3.7.11\n", - "OS: Linux-5.4.104+-x86_64-with-Ubuntu-18.04-bionic\n" + "SLEAP: 1.3.1\n", + "TensorFlow: 2.8.4\n", + "Numpy: 1.21.6\n", + "Python: 3.7.12\n", + "OS: Linux-5.15.0-78-generic-x86_64-with-debian-bookworm-sid\n" ] } ], @@ -151,7 +168,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -216,7 +233,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -284,7 +301,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -322,7 +339,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -332,23 +349,14 @@ "outputId": "59d0c939-53a3-4580-cf0b-be85b58ad067" }, "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "INFO:numexpr.utils:NumExpr defaulting to 2 threads.\n" - ] - }, { "data": { - "image/png": "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AvW9KGVnndePn5YGDBjg6LIAAADgYA4LMElJSbrrrrsc1T0MoHpPGAAAAKCaXQLMrFmzah1//fXXt5yrVllZKbPZrCNHjmjy5MnN6vf69et644039PHHHysjI0N+fn6aMGGCli5dqp49e95RW3l5ebbP37KystSjRw9NmTJFixcvVpcuXep9rqioSCtWrNCWLVuUmpoqZ2dnBQcHa/To0Xrrrbfk7e3drHcEAAAAcJNdAsyHH35o+9lkMik5OVnJycm3fWbw4MFavnx5k/ssLS3VmDFjFBcXp8DAQD355JNKS0vTBx98oM8++0xxcXHq06dPo9rKycnRyJEjlZycrD59+mjy5MlKSkrSqlWr9MUXX+jgwYPy8/O75blz585p7NixOnfunPr06aOJEyeqrKxMZrNZ69at04IFCwgwAAAAgB3ZJcDs3btXkmS1WjVmzBhNmDBB//M//1PnvW5ubgoKClJoaGiz+ly2bJni4uI0cuRI7dq1yxYUVq5cqZ///OeaNWuW9u3b16i25s6dq+TkZE2dOlWbNm2Si8uNv5aXX35Zv//97zVv3rxaIU2SysrKNHHiRGVkZOjdd9/VT3/601rXT506VWfoAQAAANB0dgkwo0ePtv38H//xH4qMjKx1zt7Ky8u1Zs0aSdLatWtrjXLMmzdPf/nLXxQTE6OjR482uCdNZmamNm7cKDc3N61bt84WXiRp+fLl+vjjj7Vhwwb99re/VUBAgO3aqlWrZDab9Ytf/OKW8CJJgwYNau5rthvVK4pJUmpqqqzWKgdXBAAAAKOy+zJgH3zwQb3zX+xl//79KigoUHh4uIYOHXrL9WnTpkm6sddMQ3bu3KmqqipFRkaqe/futa65u7tr0qRJslgs2rFjR61rf/rTnyRJc+bMaeprdBg52ZnavjdJ0bGp2rLzsPLzCxxdEgAAAAzKYauQNceJEyckScOGDavzevX5xMREu7S1fv36Wm2dP39eycnJ6tWrl4KDg7V//35FRUWpoKBAYWFheuqpp9S3b987eqf2rnpFseysC44uBQAAAAbW7ADTp08fmUwm7d69W2FhYY2eOC/dmPCfkpJyx31mZGRIknr16lXn9erz6enpLdLWN998I0kKCgrSSy+9pHXr1tV6ZuHChXrzzTf185//vMH+AQAAADReswNMWlqaJKmioqLWcUsqKiqSJHl5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G8BoNBrq378/AaClS5eSRqMR8uLj48nKyopUKhXl5OQI6fn5+eTs7CwcAD99EH769Gmdg74rV67QtWvX9Po+fPgwyWQy8vHx0emXyLQAxhC1Wk1BQUEEgFavXi2kV1VVUUJCAlVWVuqUf/DgAQ0dOpQA0MmTJ3Xyli9fTgBoy5YtBvuqL4D5+OOPCQAFBATQvXv3hPScnBzy9/cnALRhwwaD261UKun06dNCemlpqRBUfvXVV41uP1FtAKV9bVevXq3zOv3666/Uq1cvEovFOgfi2gAGAI0YMYIKCgr02tW+Bl27djX4ur744osEgGbOnEkVFRVCelJSEimVShKLxToBLtGT9err60t37twxavu03nzzTQJAX375pcF8bQDzdBmNRiPUHTRokF69FStWEAB68cUXiYiopqaGgoODCQCtW7eu3vEEBgYSAEpLSzNpOxhjlocDGMYYMyNjA5jjx48L75Q/fVBPRBQZGUkAaNWqVULahx9+SAAoLCys2eOcNWsWAaArV67opDc3gHnppZcIAM2ePdvosRw9epQAUFxcnE56UwMYDw8PAmDwE6a9e/cKB+x1abf7nXfe0asLnpVoAAAKC0lEQVQTHx9vsJ/6JCQkEACKiooymL97924CQAsXLhTS6gYwP/74o8F62tfg6U9viIhSU1MJAKlUKsrPz9fLj4uLIwD06quv6qRr+/z222+N2ra6xo0bZzDw1NIGMCNHjtTLq6yspJ49exIASkpK0smrrq6mESNGEADauHEjrVq1igDQ2LFj9QLuurRrevfu3SZvC2PMskiM/7IZY4wxc0lKSgIATJ06FVKpVC9/9uzZ2L17t1AOAP773/8CAF577TWj+6moqMDhw4dx/vx55ObmorKyEgBw9epVAMCvv/6K/v37N3k76vrwww+xfft2DBs2DJs2bTJY5vLly/j++++RmZmJsrIyEBGKi4uFsTRXVlYWsrKy4OzsjLFjx+rlv/jii7C3t8etW7dw7949dO/eXSffUB0/Pz8AtecUGUN7vklkZKTB/ODgYADA+fPn9fJcXV0xdOjQBtsPDw/XS/vhhx8AAGFhYXB0dNTLnz17NtauXauznrREIhEmTpzYYJ+GPHjwAADg4ODQYLnp06frpUmlUkRHR2PdunVISkrCs88+K+SJxWJs374dgwYNwhtvvIHq6mo4OTlhy5Yt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", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAzAAAAG3CAYAAABrIrBSAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAABcSAAAXEgFnn9JSAABq80lEQVR4nO3deVzU1f4/8NcwMMMqiICALLKolCtqrpGGaWpXxbXMuqLdykrNn9282dUy9WZpWpZat74u3eyqNxVzz1QkUsF9Q8XYXVBAFtmXmfP7g2ZkZIABBoYPvJ6PB49mzvl8znl/Pnwa583nc86RCSEEiIiIiIiIJMDM1AEQEREREREZigkMERERERFJBhMYIiIiIiKSDCYwREREREQkGUxgiIiIiIhIMpjAEBERERGRZDCBISIiIiIiyWACQ0REREREksEEhoiIiIiIJIMJDBERERERSQYTGCIiIiIikgwmMEREREREJBlMYIiIiIiISDLMTR0AVc3V1RX5+fnw8vIydShEREREREaTkpICGxsb3L17t9b78g5ME5afn4/S0lJTh0FEREREZFSlpaXIz8+v0768A9OEae68xMTEmDgSIiIiIiLj6dy5c5335R0YIiIiIiKSDEknMIWFhfjggw/QsWNHWFpawt3dHdOnT8ft27dr1U5ERAQ++ugjPPfcc3B2doZMJkP79u1r3E+lUuHzzz9H165dYWVlBWdnZ0yaNAnXrl2r4xEREREREVF1ZEIIYeog6qKoqAhPP/00oqKi4ObmhqCgICQlJeHUqVNwdnZGVFQUfH19DWqrR48euHjxok6Zt7c3kpKSqtxHrVZjwoQJCAsLg4ODA4YMGYKMjAz89ttvsLKyQnh4OPr06VOfQ9TeWuMjZERERETUnNTne65k78AsXboUUVFR6N+/P27cuIFt27YhOjoaK1euRHp6OqZPn25wW8OGDcPSpUvxyy+/GHwSN2zYgLCwMHTo0AHXr1/H9u3bcezYMfz0008oKCjAlClTUFZWVtfDIyIiIiIiPSR5B6akpAQuLi7IycnBuXPnEBgYqFPfvXt3XLp0CWfOnEGvXr1q1fbdu3fh5uZW4x2Yxx9/HNeuXUNYWBhCQkJ06saMGYPdu3dj+/btGD9+fK36r4h3YIiIiIioOWpxd2COHz+OnJwc+Pn5VUpeAGDChAkAgD179jRI/4mJibh27RqsrKzw3HPPNXr/REREREQtlSQTGM14lZ49e+qt15RfunSpQfvv0qULLCwsGr1/IiIiIqKWSpLrwKSkpAAAPDw89NZrypOTkyXRf1XzYMfHx8PPz68OERIRERERNU+SvAOTl5cHALC2ttZbb2NjAwDIzc1tlv0TEREREbVUkrwD09xUNXipPiuUEhERERE1R5K8A2NrawsAKCgo0Fufn58PALCzs2uW/RMRERERtVSSTGC8vLwAALdu3dJbryn39vZulv0TEREREbVUkkxgunfvDgA4d+6c3npNebdu3Rq0/ytXrqC0tLTR+yciIiIiaqkkmcAMHDgQ9vb2iI+Px4ULFyrVb9++HQAwatSoBunfx8cHjz32GAoLC7Fv375G77+pUqlUiI2N1f6oVCpTh0REREREzYwkExiFQoGZM2cCAN566y3tmBMAWLVqFS5duoRBgwahV69e2vI1a9YgICAA8+fPN0oMc+fOBQDMmzcPaWlp2vKdO3di9+7d8Pf3x5gxY4zSl1TExcVh/U8R2BOZgPU/RSAuLs7UIRERERFRMyPZWcgWLFiAw4cP48SJE+jQoQOCgoKQnJyM6OhoODs7Y8OGDTrbZ2RkIDY2FqmpqZXa+r//+z/83//9HwBoHwlLTU1Fv379tNusW7dOZ+HM6dOnY//+/QgLC0NAQACGDBmCjIwMREREwMrKCps3b4a5uWRPb525uHrC3dPH1GEQERERUTMlyTswAGBpaYnw8HAsXLgQ1tbW2LVrF5KTkxEaGopz587B19fX4LZu3bqF6OhoREdHa8evlJSUaMuio6Px4MEDnX3MzMzw008/YeXKlXB3d8fevXtx+fJljB8/HmfOnEHfvn2NerxERERERATIhBDC1EGQfpp1YKpaJ6apiY2NxZ7IBLh7+uDOzUSMCvJFp06dTB0WERERETUx9fmeK9k7MERERERE1PIwgSEiIiIiIslgAkNERERERJLBBIaIiIiIiCSDCQwREREREUkGExgiIiIiIpIMJjBERERERCQZTGCIiIiIiEgymMAQEREREZFkMIEhIiIiIiLJYAJDRERERESSwQSGiIiIiIgkgwkMERERERFJBhMYIiIiIiKSDCYwREREREQkGUxgiIiIiIhIMpjAEBERERGRZDCBISIiIiIiyWACQ0REREREksEEhoiIiIiIJIMJDBER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33MleweGiIiIiIhaHiYwREREREQkGUxgiIiIiIhIMpjAEBERERGRZDCBISIiIiIiyWACQ0REREREksEEhoiIiIiIJIMJDBERERERSQYTGCIiIiIikgwmMEREREREJBlMYIiIiIiISDKYwBARERERkWQwgSEiIiIiIslgAkNERERERJLBBIaIiIiIiCSDCQwREREREUkGExgiIiIiIpIMJjBERERERCQZTGCIiIiIiEgymMAQEREREZFkMIEhIiIiIiLJYAJDRERERESSwQSGiIiIiIgkgwkMERERERFJBhMYIiIiIiKSDCYwREREREQkGUxgiIiIiIhIMpjAEBERERGRZDCBISIiIiIiyTA3dQDUsqlUKsTFxWnf+/v7Qy6XmzAiIiIiImrKmMCQScXFxWH9TxFwcfVE2t2beGUi0KlTJ1OHRURERERNFBMYMjkXV0+4e/qYOgwiIiIikgCOgSEiIiIiIslgAkNERERERJJh9ATmo48+wq1bt4zdLBERERERUcMkMD4+Phg1ahR2794NtVpt7C6IiIiIiKiFMnoCs3TpUnh5eWHfvn0YO3YsPD09sXDhQiQlJRm7K5IglUqF2NhY7U9CQgKEYJJLRERERIYxegLz/vvvIz4+HocOHcLEiRNx//59/Otf/4K/vz+GDx+OHTt2oKyszNjdkkRopk3eE5mAPZEJ2HHwNLKzc0wdFhERERFJRIMN4n/mmWewdetW3L59G5999hk6deqEQ4cOYdKkSfDw8MB7772HP/74o6G6pyZMM22yu6cPHJ3dTB0OEREREUlIg89C1qZNG8ydOxcxMTH4/fffMXnyZKSlpWHFihUICAjAkCFDEBYW1tBhkASo1SokJCRoHy9TqVSmDomIiIiImphGm0Y5Pj4ee/bswZEjR7RlHh4eCA8Px4QJE9CnTx/cvHmzscKhJigjLRU/h8dgT2QC1v8Ugbi4OFOHRERERERNTIMmMKWlpdi6dSuGDBmCjh074tNPP0VZWRnmzp2L69evIzk5GcePH8eIESNw5swZzJw5syHDIQlo4+wOd08fuLh6mjoUIiIiImqCzBui0WvXruG7777DDz/8gMzMTAghMGDAAMyYMQMTJ06EUqnUbtu/f3/s3bsX/fr1Q0REREOEQ0REREREzYTRE5gnn3wSJ0+ehBACrVq1whtvvIEZM2agS5cu1e7X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1QmMEOULZ65evVoEBgYKa2trYW1tLXr37i3Wrl0rysrKKm1v7ARGCCGys7PF0qVLRc+ePYWtra2wtLQU7du3F88++6xYu3atSE9Pr1UfhqzFk5GRId555x3h5+cnFAqFcHBwEMOGDdO7Jo4Q9UtghHiYJJ86dapSnSaBCQ8PF3v27BH9+/cX1tbWwt7eXowZM0bExMTobL9v3z4BQPj6+orc3NxK7V26dEkolUrRqlWrSr+n6dOnCwDi7NmzdT4WIpIOmRCNNO0LERERNSsXLlxAYGAgZs6cia+++kqnLjQ0FN9//z3Cw8OrHXxfX4WFhXB3d0fHjh0RHR3dYP0QUdPBMTBERERUJz169MDEiROxYcMG7firxvbNN98gOzsby5YtM0n/RNT4mMAQERFRnS1btgylpaVYvnx5o/ddWFiI5cuXY8SIEQgODm70/onINLgODBEREdWZn58fSkpKTNK3lZUVUlNTTdI3EZkOx8AQEREREZFk8BEyIiIiIiKSDCYwREREREQkGUxgiIiIiIhIMpjAEBERERGRZDCBISIiIiIiyWACQ0REREREksEEhoiIiIiIJIMJDBERERERSQYTGCIiIiIikgwmMEREREREJBlMYIiIiIiISDKYwBARERERkWQwgSEiIiIiIslgAkNERERERJLx/wG4oweOSu8ZPgAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, - "metadata": { - "tags": [] - }, + "metadata": {}, "output_type": "display_data" } ], @@ -373,7 +381,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 10, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -385,14 +393,12 @@ "outputs": [ { "data": { - "image/png": "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", + "image/png": "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hfv37yM6Ohq5ubmwt7fHtm3bIAhCg3wWREREREQthWwTGENDQxw7dgyffPIJtm7dit27d6NNmzYIDAzERx99VOUil/80ZswY5Obm4vjx4zh79iwyMjJgZGQEV1dXvP7663jrrbdgY2OjcYy7uztmz56NqKgoXLp0Cenp6TAwMIC7uzv8/f0RFBSE1q1b18dpExERERG1aIIoimJjB0HaeXp6AqhYJ4aIiIiImr/r16+jU6dOWLH+QLUXskxKjMe7rwxHbGws3N3d6zlCadTlPleWY2CIiIiIiKhlYgJDRERERESywQSGiIiIiIhkgwkMERERERHJBhMYIiIiIiKSDSYwREREREQkG0xgiIiIiIhINpjAEBERERGRbDCBISIiIiIi2WACQ0REREREssEEhoiIiIiIZIMJDBERERERyQYTGCIiIiIikg0mMEREREREJBtMYIiIiIiISDaYwBARERERkWwwgSEiIiIiItlgAkNERERERLLBBIaIiIiIiGSDCQwREREREckGExgiIiIiIpINJjBERERERCQbTGCIiIiIiEg2mMAQEREREZFsMIEhIiIiIiLZYAJDRERERESywQSGiIiIiIhkgwkMERERERHJBhMYIiIiIiKSDSYwREREREQkG7JOYAoLC7Fo0SK4u7vD0NAQtra2mD59Ou7du1ftNsrKyrB48WKMGDECzs7OMDMzg6GhIdzc3DBz5kwkJCRUeWx5eTlWrVqFp59+GkZGRrCyssKECRNw9epVKU6PiIiIiIj+QbYJTFFREfz8/PDRRx8hLy8PAQEB6NChAzZu3AgfHx/cunWr2u0sWbIEf/zxB2xsbDBs2DAMHToUJSUl+Oabb+Dl5YVz585VOk6pVGL8+PEIDg5GYmIiRowYAU9PT4SGhqJHjx44c+aM1KdMRERERNTiyTaBWbZsGaKiouDr64vr16/jl19+wenTp/HFF18gNTUV06dPr1Y7hoaGOHHiBDIzMxEZGYnt27djz549uHXrFubOnYucnBy88cYblY4LCQnBrl274ObmhmvXriE0NBTh4eHYvn07CgoKMHnyZJSVlUl92kRERERELZosE5iSkhKsWbMGAPD111/D1NRUXRccHAwvLy9EREQgOjr6iW3p6emhT58+0NPT0yjX1dXFRx99BENDQ0RHRyM7O1ujfuXKlQCA5cuXo3379urysWPHYuTIkbh58yb27NlT63MkIiIiIqLKZJnAREZGIjs7Gy4uLvDx8alUP27cOADAvn376tSPIAjQ1dWFIAhQKBTq8vj4eFy9ehVGRkYYMWJEvfVPRERERESaZJnAXLx4EQDQrVs3rfWq8piYmFr3IYoiPvvsM+Tn52PgwIEwMjKq1H+XLl2gr69fL/0TEREREVFlek/epem5c+cOAMDe3l5rvar8cTOIaTNnzhw8ePAAOTk5iImJQVxcHDp37oz169fXa/+enp5ay+Pi4uDi4lLd8ImIiIiImj1ZJjB5eXkAAGNjY631JiYmAIDc3Nwatbtjxw7ExcWpt728vLBlyxY4OTk1SP9ERERERPR4skxg6svNmzcBAGlpaYiOjsb8+fPRvXt3fP/995g6dWq99XvlyhWt5VU9mSEiIiIiaqlkOQZGNetYQUGB1vr8/HwAgJmZWa3at7S0xNChQ3HkyBFYW1tjxowZuHv3boP1T0RERERE2skygXFwcAAAJCYmaq1XlTs6OtapH3Nzc/j7+6OwsBC///57g/dPRERERESaZJnAeHt7AwDOnz+vtV5V7uXlVee+LC0tAQCpqamV+r98+TJKS0vrtX8iIiIiInpIlglMnz59YG5ujri4OFy4cKFSfWhoKADA39+/zn1FREQAgMZsYE5OTujcuTMKCwsRFhZWr/0TEREREdFDskxgFAoF3nzzTQDArFmz1GNOAGDlypWIiYlB//790b17d3X5mjVr4OHhgXnz5mm0FRYWhpMnT1bqo6CgAPPnz0dERASsra0xbNgwjfrg4GAAwPvvv4+UlBR1+c6dO7F37164uroiICCg7idLRERERERqsp2FbMGCBTh8+DBOnjwJNzc39O3bFwkJCTh9+jSsrKwQEhKisX9aWhpiY2ORlJSkUX727FksWbIEdnZ26Nq1K8zNzZGcnIwLFy4gIyMD5ubm2LZtm3rgvsr06dNx4MAB7Nq1Cx4eHhg0aBDS0tIQEREBIyMjbNmyBXp6sv14iYiIiIiaJFk+gQEAQ0NDHDt2DAsXLoSxsTF2796NhIQEBAYG4vz583B2dq5WO2PGjEFwcDBsbW1x9uxZbNu2DWfPnoWjoyPmzZuHq1evom/fvpWO09HRwfbt2/HFF1/A1tYW+/fvx6VLlzB27FicO3cOPXv2lPqUiYiIiIhaPEEURbGxgyDtVOvAVLVODBERERE1L9evX0enTp2wYv0B2Ng7PfkAAEmJ8Xj3leGIjY2Fu7t7PUcojbrc58r2CQwREREREbU8TGCIiIiIiEg2mMAQEREREZFsMIEhIiIiIiLZYAJDRERERESywQSGiIiIiIhkgwkMERERERHJBhMYIiIiIiKSDSYwREREREQkG0xgiIiIiIhINpjAEBERERGRbDCBISIiIiIi2WACQ0REREREssEEhoiIiIiIZIMJDBERERERyQYTGCIiIiIikg0mMEREREREJBtMYIiIiIiISDaYwBARERERkWwwgSEiIiIiItlgAkNERERERLLBBIaIiIiIiGSDCQwREREREckGExgiIiIiIpINJjBERERERCQbTGCIiIiIiEg2mMAQEREREZFsMIEhIiIiIiLZYAJDRERERESyIesEprCwEIsWLYK7uzsMDQ1ha2uL6dOn4969e9VuIysrC1u3bsXEiRPh5OQEhUIBMzMz9OzZE6tXr0ZpaanW4wIDAyEIQpVf69atk+o0iYiIiIjob3qNHUBtFRUVwc/PD1FRUbCxsUFAQABu376NjRs3Yv/+/YiKioKzs/MT21mxYgU+/vhjCIKArl27omfPnkhNTUVkZCTOnDmD0NBQ/PbbbzA2NtZ6/NChQ2FtbV2pvFOnTnU+RyIiIiIi0iTbBGbZsmWIioqCr68vDh06BFNTUwDAypUr8c4772D69OkIDw9/YjsmJiZ4//33MWvWLDg4OKjLb9y4geeffx4nTpzAsmXL8J///Efr8XPnzsWAAQOkOCUiIiIiInoCWb5CVlJSgjVr1gAAvv76a3XyAgDBwcHw8vJCREQEoqOjn9jWvHnz8Nlnn2kkLwDg5uaGTz/9FADw008/SRg9ERERERHVliwTmMjISGRnZ8PFxQU+Pj6V6seNGwcA2LdvX5368fb2BgDcv3+/Tu0QEREREZE0ZPkK2cWLFwEA3bp101qvKo+JialTP7du3QIArWNcVHbu3IkdO3agvLwcTk5O8Pf3h4eHR536JSIiIiIi7WSZwNy5cwcAYG9vr7VeVZ6QkFCnflavXg0ACAgIqHKfr776SmN7zpw5mDFjBlavXg09PVl+vERERERETZYs77Dz8vIAoMqZwUxMTAAAubm5te5j3bp1OHz4MCwsLDB37txK9T4+PvD19YWfnx/s7e2RnJyMgwcPYsGCBVi7di0UCgVWrVpVrb48PT21lsfFxcHFxaXW50BERERE1NzIcgxMfTt+/DiCgoIgCAJCQkJga2tbaZ+goCC8/vrrcHNzg5GREZycnDBz5kwcP34cCoUCa9aswd27dxsheiIiIiKi5kuWT2BUs44VFBRorc/PzwcAmJmZ1bjty5cvIyAgACUlJfjyyy8xevToGh3v6emJkSNHIjQ0FEeOHEFgYOATj7ly5UqVbRERERER0UOyfAKjmvI4MTFRa72q3NHRsUbtxsfHY8iQIcjMzMTixYvx1ltv1So+Nzc3AEBSUlKtjiciIiIiIu1kmcCopjc+f/681npVuZeXV7XbTEpKwuDBg5GUlISgoCB8+OGHtY4vMzMTwMOxOEREREREJA1ZJjB9+vSBubk54uLicOHChUr1oaGhAAB/f/9qtZeZmYmhQ4ciLi4O06ZNq/bge22Ki4sRFhYGoOppnomIiIiIqHZkmcAoFAq8+eabAIBZs2apx7wAwMqVKxETE4P+/fuje/fu6vI1a9bAw8MD8+bN02iroKAAI0aMwKVLlzBhwgR8//33EAThsf1fu3YNmzdvRnFxsUZ5amoqXnzxRdy9exfe3t7o06dPXU+ViIiIiIgeIctB/ACwYMECHD58GCdPnoSbmxv69u2LhIQEnD59GlZWVggJCdHYPy0tDbGxsZXGpcyfPx+nTp2Crq4u9PT08O9//1trf5s2bVL/nJycjClTpiAoKAg9evSAlZUV7t+/j+joaOTm5sLe3h7btm17YiJEREREREQ1I9sExtDQEMeOHcMnn3yCrVu3Yvfu3WjTpg0CAwPx0UcfVbnI5T+pxquUl5dj69atVe73aALj7u6O2bNnIyoqCpcuXUJ6ejoMDAzg7u4Of39/BAUFoXXr1nU6PyIiIiIiqkwQRVFs7CBIO9U0ylVNs0xEREREzcv169fRqVMnrFh/ADb2TtU6JikxHu++MhyxsbFwd3ev5wilUZf7XMnHwCxZsqTK6Y2JiIiIiIjqol4SGCcnJ/j7+2Pv3r1QKpVSd0FERERERC2U5AnMsmXL4ODggLCwMIwePRodOnTAwoULcfv2bam7IiIiIiKiFkbyBOaDDz5AXFwcDh06hPHjxyM9PR0ff/wxXF1dMWzYMOzYsQNlZWVSd0tERERERC1Ava0D8/zzz+Pnn3/GvXv3sGLFCnTq1AmHDh3ChAkTYG9vj7lz5+LGjRv11T0RERERETVD9b6QZdu2bREcHIwrV67gxIkTmDhxIlJSUvD555/Dw8MDgwYNwq5du+o7DCIiIiIiagbqPYFRiYuLw759+3DkyBF1mb29PY4dO4Zx48bh2Wefxd27dxsqHCIiIiIikqF6TWBKS0vx888/Y9CgQXB3d8dnn32GsrIyBAcH49q1a0hISEBkZCReeOEFnDt3Dm+++WZ9hkNERERERDKnVx+NXr16Fd9//z02b96MjIwMiKKI3r1744033sD48eNhYGCg3tfX1xf79+9Hr169EBERUR/hEBERERFRMyF5AvPcc8/h1KlTEEURrVq1wowZM/DGG2+gS5cujz3O09MTZ8+elTocIiIiIiJqRiRPYE6ePIlu3brhjTfewKRJk2BsbFyt41555RX069dP6nCIiIiIiKgZkTyBOXv2LLp3717j43x9feHr6yt1OERERERE1IxIPog/LCwMe/fufeJ++/btw9KlS6XunoiIiIiImjHJE5jFixdj9+7dT9xv7969WLJkidTdExERERFRM9Zg68D8U3l5OXR0Gq17IiIiIiKSoUbLIK5cuYLWrVs3VvdERERERCRDkgzinz59usb2iRMnKpWplJWVITY2FufOncOoUaOk6J6IiIiIiFoISRKYTZs2qX8WBAE3b97EzZs3H3uMl5cXPv/8cym6JyIiIiKiFkKSBObYsWMAAFEU4efnh2HDhmHOnDla91UoFLC1tYWjo6MUXRMRERERUQsiSQLTv39/9c9Tp05F3759NcqIiIiIiIikIPlClhs3bpS6SSIiIiIiIgCNOAsZERERERFRTdX5CYyzszMEQcDhw4fh5OQEZ2fnah8rCALi4uLqGgIREREREbUQdU5gbt++DQAoLS3V2CYiIiIiIpJanRMYpVL52G0iIiIiIiKpcAwMERERERHJBhMYIiIiIiKSDSYwREREREQkG3UeA6Orq1vrYwVBQFlZWV1DICIiIiKiFqLOCUyHDh0gCIIUsRARERERET2WZNMoN4bCwkJ88skn+Pnnn3Hnzh20adMGw4YNw0cffQQ7O7tqtZGVlYUDBw5g3759iIqKwr1792BgYICnnnoKkyZNwsyZM6Gvr6/12PLycnz55ZcICQnBzZs3YWpqioEDB2LJkiXo3LmzlKdKRERERESQ8RiY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8OABBEGAr68v9PX1pe6eiIiIiIiaMcnHwCxbtgz379/H0qVLcffuXbzwwgsQBAGRkZFISkpCeHg4PDw8IAgCDh48KHX3RERERETUjEmewPz6669wcnLCggULtNb369cPhw4dwp9//omPPvpI6u6JiIiIiKgZkzyBuXfvHrp27are1tXVBQAUFxery+zs7DBw4EBs27ZN6u6JiIiIiKgZkzyBadWqlca2hYUFgIrE5lGGhoaVyoiIiIiIiB5H8gTGwcEBd+7cUW936dIFAHDgwAF1WUFBASIjI2FjYyN190RERERE1IxJPguZn58fVq9ejdTUVFhZWWHkyJEwMTHBe++9h8TERNjZ2WHLli148OABZsyYIXX3RERERETUjEmewEyePBl3797FX3/9hf79+6NNmzb49ttvMW3aNCxfvhyCIEAURXh6euLjjz+WunsiIiIiImrGJE9gvL298dNPP2mUTZw4EX369MGBAweQmZkJd3d3jBw5kuvAEBERERFRjUiewFTFwcEBb7zxRkN1R0REREREzVCDJDCZmZkAKmYkEwShIbokIiIiIqJmSPJZyFT27t2LIUOGwNTUFJaWlrC0tISZmRmGDBmCPXv21Fe3RERERETUjEmewIiiiOnTp2P06NE4fPgwCgoKYG5uDnNzcxQUFODw4cMYM2YMAgMDIYqi1N0TEREREVEzJnkCs3r1amzatAk2Njb45ptvkJWVhYyMDGRkZCA7Oxvr1q2DjY0NNm/ejNWrV0vdPRERERERNWOSJzDfffcdjI2Ncfz4cbz++uto1aqVus7MzAyvvfYajh8/DiMjI3z33XdSd09ERERERM2Y5AlMfHw8Bg0aBCcnpyr3cXJywqBBgxAfHy9190REREREslRersTJvzLhMzwYFxNKcfjMHVy8kYrSMmVjh9akSD4LmZWVFRQKxRP309fXh6WlpdTdExERERHJTnp2IT7fEo0rt9Jh59EPmfkigEKkZhUiITkXvTyt0a6NcWOH2SRI/gRm9OjROHr0qHrqZG0yMjJw9OhRjBo1SuruiYiIiIhk5cqtdMxeGYErt9K11ucXluLIubu4fqfq++uWRPIEZtmyZXB2doafnx+OHj1aqf7YsWMYPHgwXFxc8J///Efq7omIiIiIZCM5PR9LN0QhK69YXXY/NhJu1rrw6Ngajy6heD42BRk5RY0Q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tGvXTv3ZPfXUU/jzzz8RGhqKmJgYODs74/PPP1evKfJP5ubm6NatG4DqDd6fMGEC9u7dC11dXezZsweJiYkICAjAqVOn4OPjU2n/b7/9Fj/++CN8fHwQERGBffv2oV27dvj4449x9OhRGBsb1+0DeYzu3btjy5YteOqpp3Do0CFs2LABGzZs0Drj1qOGDRuGsLAwvP322+jQoQMuXLiAbdu2ISoqCh06dEBwcDCuXLkCPz+/eotdSnv27MH8+fNhZWWFgwcPIjo6Gi+++CKioqJgYWEhaV+2trbYs2cPevXqpX5at2HDBq1TQas+P3t7e63JNRE1HYL4pJdriYhIEt988w1mzpyJ5cuX47333mvscJqku3fvwsnJCR06dMCtW7eqHEQdGBiIH374AceOHVP/FZ+oLj755BN88MEH+PDDD7F48eLGDoeIHoNPYIiIGohqtfSGXL9Fbj799FOUl5dj1qxZnAGKGkxOTg6++uorKBQKvj5GJAMcA0NEVM++/PJL7Nq1S/2ef3XX6WgpYmNj8fnnnyM+Ph5Hjx6Fvb29elYoovq0ceNGRERE4I8//kBSUhJmz57NwftEMsAnMERE9ezo0aOIiopC3759ceDAAfWK5lQhKSkJGzZswKlTp9CvXz+EhYXxM6IGERERgR9++AF5eXmYNWvWY6dVJ6Kmg2NgiIiIiIhINvgEhoiIiIiIZIMJDBERERERyQYTGCIiIiIikg0mMEREREREJBtMYIiIiIiISDaYwBARERERkWwwgSEiIiIiItlgAkNERERERLLBBIaIiIiIiGSDCQwREREREckGExgiIiIiIpINJjBERERERCQbTGCIiIiIiEg2mMAQEREREZFs/D80F3amM7TEAQAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, - "metadata": { - "tags": [] - }, + "metadata": {}, "output_type": "display_data" } ], @@ -417,7 +423,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 11, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -429,14 +435,12 @@ "outputs": [ { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] }, - "metadata": { - "tags": [] - }, + "metadata": {}, "output_type": "display_data" } ], @@ -462,7 +466,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 12, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -500,13 +504,13 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 13, "metadata": { "id": "YHCLd3pkRhGT" }, "outputs": [], "source": [ - "!wget https://storage.googleapis.com/sleap-data/datasets/wt_gold.13pt/tracking_split2/test.pkg.slp > /dev/null 2>&1" + "!wget -q https://storage.googleapis.com/sleap-data/datasets/wt_gold.13pt/tracking_split2/test.pkg.slp" ] }, { @@ -520,11 +524,76 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 14, "metadata": { "id": "OMXHY-7YRyTB" }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-09-01 14:14:04.208933: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:936] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 14:14:04.209734: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-09-01 14:14:04.209771: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcublas.so.11'; dlerror: libcublas.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-09-01 14:14:04.209801: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcublasLt.so.11'; dlerror: libcublasLt.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-09-01 14:14:04.209829: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcufft.so.10'; dlerror: libcufft.so.10: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-09-01 14:14:04.209859: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcurand.so.10'; dlerror: libcurand.so.10: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-09-01 14:14:04.209886: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcusolver.so.11'; dlerror: libcusolver.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-09-01 14:14:04.209912: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcusparse.so.11'; dlerror: libcusparse.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-09-01 14:14:04.209939: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudnn.so.8'; dlerror: libcudnn.so.8: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:\n", + "2023-09-01 14:14:04.209945: W tensorflow/core/common_runtime/gpu/gpu_device.cc:1850] Cannot dlopen some GPU libraries. Please make sure the missing libraries mentioned above are installed properly if you would like to use GPU. Follow the guide at https://www.tensorflow.org/install/gpu for how to download and setup the required libraries for your platform.\n", + "Skipping registering GPU devices...\n", + "2023-09-01 14:14:04.245745: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX512F FMA\n", + "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "061ef3f7278a47bbbe199d38ccd6be37", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-09-01 14:14:07.317060: W tensorflow/core/grappler/costs/op_level_cost_estimator.cc:690] Error in PredictCost() for the op: op: \"CropAndResize\" attr { key: \"T\" value { type: DT_UINT8 } } attr { key: \"extrapolation_value\" value { f: 0 } } attr { key: \"method\" value { s: \"bilinear\" } } inputs { dtype: DT_UINT8 shape { dim { size: 4 } dim { size: 1024 } dim { size: 1024 } dim { size: 1 } } } inputs { dtype: DT_FLOAT shape { dim { size: -2 } dim { size: 4 } } } inputs { dtype: DT_INT32 shape { dim { size: -2 } } } inputs { dtype: DT_INT32 shape { dim { size: 2 } } } device { type: \"CPU\" vendor: \"GenuineIntel\" model: \"103\" frequency: 3600 num_cores: 16 environment { key: \"cpu_instruction_set\" value: \"AVX SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2\" } environment { key: \"eigen\" value: \"3.4.90\" } l1_cache_size: 49152 l2_cache_size: 524288 l3_cache_size: 16777216 memory_size: 268435456 } outputs { dtype: DT_FLOAT shape { dim { size: -2 } dim { size: -27 } dim { size: -28 } dim { size: 1 } } }\n", + "2023-09-01 14:14:07.320224: W tensorflow/core/grappler/costs/op_level_cost_estimator.cc:690] Error in PredictCost() for the op: op: \"CropAndResize\" attr { key: \"T\" value { type: DT_FLOAT } } attr { key: \"extrapolation_value\" value { f: 0 } } attr { key: \"method\" value { s: \"bilinear\" } } inputs { dtype: DT_FLOAT shape { dim { size: -42 } dim { size: -43 } dim { size: -44 } dim { size: 1 } } } inputs { dtype: DT_FLOAT shape { dim { size: -10 } dim { size: 4 } } } inputs { dtype: DT_INT32 shape { dim { size: -10 } } } inputs { dtype: DT_INT32 shape { dim { size: 2 } } } device { type: \"CPU\" vendor: \"GenuineIntel\" model: \"103\" frequency: 3600 num_cores: 16 environment { key: \"cpu_instruction_set\" value: \"AVX SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2\" } environment { key: \"eigen\" value: \"3.4.90\" } l1_cache_size: 49152 l2_cache_size: 524288 l3_cache_size: 16777216 memory_size: 268435456 } outputs { dtype: DT_FLOAT shape { dim { size: -10 } dim { size: -48 } dim { size: -49 } dim { size: 1 } } }\n" + ] + }, + { + "data": { + "text/html": [ + "
\n"
+            ],
+            "text/plain": []
+          },
+          "metadata": {},
+          "output_type": "display_data"
+        },
+        {
+          "data": {
+            "text/html": [
+              "
\n",
+              "
\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "predictor = sleap.load_model(\"td_fast.210505_012601.centered_instance.n=1800\")\n", "labels_gt = sleap.load_file(\"test.pkg.slp\")\n", @@ -542,7 +611,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 15, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -557,7 +626,7 @@ "text": [ "Error distance (50%): 0.8984147543126978\n", "Error distance (90%): 2.197896466395166\n", - "Error distance (95%): 3.148422807907632\n", + "Error distance (95%): 3.1484228079076315\n", "mAP: 0.797836431061851\n", "mAR: 0.8782499999999999\n" ] @@ -585,7 +654,16 @@ "name": "python3" }, "language_info": { - "name": "python" + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.12" } }, "nbformat": 4, diff --git a/docs/notebooks/Post_inference_tracking.ipynb b/docs/notebooks/Post_inference_tracking.ipynb index 20e835138..239176bdb 100644 --- a/docs/notebooks/Post_inference_tracking.ipynb +++ b/docs/notebooks/Post_inference_tracking.ipynb @@ -1,20 +1,4 @@ { - "nbformat": 4, - "nbformat_minor": 0, - "metadata": { - "colab": { - "name": "SLEAP - Post-inference tracking.ipynb", - "provenance": [], - "collapsed_sections": [] - }, - "kernelspec": { - "name": "python3", - "display_name": "Python 3" - }, - "language_info": { - "name": "python" - } - }, "cells": [ { "cell_type": "markdown", @@ -28,6 +12,9 @@ }, { "cell_type": "markdown", + "metadata": { + "id": "gQXmUCj9ljP3" + }, "source": [ "# Post-inference tracking\n", "\n", @@ -38,40 +25,31 @@ "In this notebook, we will explore how to re-run the tracking given an existing predictions SLP file.\n", "\n", "**Note:** Tracking does not run on the GPU, so this notebook can be run locally on your computer without the hassle of uploading your data if desired." - ], - "metadata": { - "id": "gQXmUCj9ljP3" - } + ] }, { "cell_type": "markdown", + "metadata": { + "id": "WL67LNf10hev" + }, "source": [ "## 1. Setup SLEAP\n", "\n", "Run this cell first to install SLEAP. If you get a dependency error in subsequent cells, just click **Runtime** → **Restart runtime** to reload the packages.\n" - ], - "metadata": { - "id": "WL67LNf10hev" - } + ] }, { "cell_type": "markdown", - "source": [ - "### Install" - ], "metadata": { "id": "UtfcHSZCDnvS" - } + }, + "source": [ + "### Install" + ] }, { "cell_type": "code", - "source": [ - "# This should take care of all the dependencies on colab:\n", - "!pip uninstall -y opencv-python opencv-contrib-python && pip install sleap\n", - "\n", - "# But to do it locally, we'd recommend the conda package (available on Windows + Linux):\n", - "# conda create -n sleap -c sleap -c conda-forge -c nvidia sleap" - ], + "execution_count": 1, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -79,187 +57,28 @@ "id": "HH0weH9f-T1N", "outputId": "d6f69d8d-9aed-4793-c346-2ab60f110316" }, - "execution_count": 1, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "Found existing installation: opencv-python 4.1.2.30\n", - "Uninstalling opencv-python-4.1.2.30:\n", - " Successfully uninstalled opencv-python-4.1.2.30\n", - "Found existing installation: opencv-contrib-python 4.1.2.30\n", - "Uninstalling opencv-contrib-python-4.1.2.30:\n", - " Successfully uninstalled opencv-contrib-python-4.1.2.30\n", - "Collecting sleap\n", - " Downloading sleap-1.2.2-py3-none-any.whl (62.0 MB)\n", - "\u001b[K |████████████████████████████████| 62.0 MB 19 kB/s \n", - "\u001b[?25hCollecting pykalman==0.9.5\n", - " Downloading pykalman-0.9.5.tar.gz (228 kB)\n", - "\u001b[K |████████████████████████████████| 228 kB 21.7 MB/s \n", - "\u001b[?25hRequirement already satisfied: certifi<=2021.10.8,>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from sleap) (2021.10.8)\n", - "Requirement already satisfied: h5py<=3.6.0,>=3.1.0 in /usr/local/lib/python3.7/dist-packages (from sleap) (3.1.0)\n", - "Collecting opencv-python-headless<=4.5.5.62,>=4.2.0.34\n", - " Downloading opencv_python_headless-4.5.5.62-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (47.7 MB)\n", - "\u001b[K |████████████████████████████████| 47.7 MB 1.4 MB/s \n", - "\u001b[?25hCollecting jsonpickle==1.2\n", - " Downloading jsonpickle-1.2-py2.py3-none-any.whl (32 kB)\n", - "Requirement already satisfied: pyyaml in /usr/local/lib/python3.7/dist-packages (from sleap) (3.13)\n", - "Requirement already satisfied: scikit-learn==1.0.* in /usr/local/lib/python3.7/dist-packages (from sleap) (1.0.2)\n", - "Collecting imgstore==0.2.9\n", - " Downloading imgstore-0.2.9-py2.py3-none-any.whl (904 kB)\n", - "\u001b[K |████████████████████████████████| 904 kB 44.2 MB/s \n", - "\u001b[?25hRequirement already satisfied: networkx in /usr/local/lib/python3.7/dist-packages (from sleap) (2.6.3)\n", - "Requirement already satisfied: pyzmq in /usr/local/lib/python3.7/dist-packages (from sleap) (22.3.0)\n", - "Requirement already satisfied: scipy<=1.7.3,>=1.4.1 in /usr/local/lib/python3.7/dist-packages (from sleap) (1.4.1)\n", - "Requirement already satisfied: psutil in /usr/local/lib/python3.7/dist-packages (from sleap) (5.4.8)\n", - "Requirement already satisfied: pandas in /usr/local/lib/python3.7/dist-packages (from sleap) (1.3.5)\n", - "Collecting segmentation-models==1.0.1\n", - " Downloading segmentation_models-1.0.1-py3-none-any.whl (33 kB)\n", - "Collecting rich==10.16.1\n", - " Downloading rich-10.16.1-py3-none-any.whl (214 kB)\n", - "\u001b[K |████████████████████████████████| 214 kB 53.6 MB/s \n", - "\u001b[?25hRequirement already satisfied: numpy<=1.21.5,>=1.19.5 in /usr/local/lib/python3.7/dist-packages (from sleap) (1.21.5)\n", - "Collecting qimage2ndarray<=1.8.3,>=1.8.2\n", - " Downloading qimage2ndarray-1.8.3-py3-none-any.whl (11 kB)\n", - "Collecting python-rapidjson\n", - " Downloading python_rapidjson-1.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.6 MB)\n", - "\u001b[K |████████████████████████████████| 1.6 MB 21.9 MB/s \n", - "\u001b[?25hCollecting attrs==21.2.0\n", - " Downloading attrs-21.2.0-py2.py3-none-any.whl (53 kB)\n", - "\u001b[K |████████████████████████████████| 53 kB 1.6 MB/s \n", - "\u001b[?25hRequirement already satisfied: tensorflow<2.9.0,>=2.6.3 in /usr/local/lib/python3.7/dist-packages (from sleap) (2.8.0)\n", - "Requirement already satisfied: scikit-image in /usr/local/lib/python3.7/dist-packages (from sleap) (0.18.3)\n", - "Collecting cattrs==1.1.1\n", - " Downloading cattrs-1.1.1-py3-none-any.whl (16 kB)\n", - "Collecting jsmin\n", - " Downloading jsmin-3.0.1.tar.gz (13 kB)\n", - "Collecting scikit-video\n", - " Downloading scikit_video-1.1.11-py2.py3-none-any.whl (2.3 MB)\n", - "\u001b[K |████████████████████████████████| 2.3 MB 61.6 MB/s \n", - "\u001b[?25hRequirement already satisfied: imageio<=2.15.0 in /usr/local/lib/python3.7/dist-packages (from sleap) (2.4.1)\n", - "Requirement already satisfied: seaborn in /usr/local/lib/python3.7/dist-packages (from sleap) (0.11.2)\n", - "Collecting PySide2<=5.14.1,>=5.13.2\n", - " Downloading PySide2-5.14.1-5.14.1-cp35.cp36.cp37.cp38-abi3-manylinux1_x86_64.whl (165.5 MB)\n", - "\u001b[K |████████████████████████████████| 165.5 MB 69 kB/s \n", - "\u001b[?25hCollecting imgaug==0.4.0\n", - " Downloading imgaug-0.4.0-py2.py3-none-any.whl (948 kB)\n", - "\u001b[K |████████████████████████████████| 948 kB 27.9 MB/s \n", - "\u001b[?25hRequirement already satisfied: six in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (1.15.0)\n", - "Collecting opencv-python\n", - " Downloading opencv_python-4.5.5.64-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (60.5 MB)\n", - "\u001b[K |████████████████████████████████| 60.5 MB 1.1 MB/s \n", - "\u001b[?25hRequirement already satisfied: Shapely in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (1.8.1.post1)\n", - "Requirement already satisfied: Pillow in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (7.1.2)\n", - "Requirement already satisfied: matplotlib in /usr/local/lib/python3.7/dist-packages (from imgaug==0.4.0->sleap) (3.2.2)\n", - "Requirement already satisfied: tzlocal in /usr/local/lib/python3.7/dist-packages (from imgstore==0.2.9->sleap) (1.5.1)\n", - "Requirement already satisfied: python-dateutil in /usr/local/lib/python3.7/dist-packages (from imgstore==0.2.9->sleap) (2.8.2)\n", - "Requirement already satisfied: pytz in /usr/local/lib/python3.7/dist-packages (from imgstore==0.2.9->sleap) (2018.9)\n", - "Collecting colorama<0.5.0,>=0.4.0\n", - " Downloading colorama-0.4.4-py2.py3-none-any.whl (16 kB)\n", - "Requirement already satisfied: pygments<3.0.0,>=2.6.0 in /usr/local/lib/python3.7/dist-packages (from rich==10.16.1->sleap) (2.6.1)\n", - "Collecting commonmark<0.10.0,>=0.9.0\n", - " Downloading commonmark-0.9.1-py2.py3-none-any.whl (51 kB)\n", - "\u001b[K |████████████████████████████████| 51 kB 5.9 MB/s \n", - "\u001b[?25hRequirement already satisfied: typing-extensions<5.0,>=3.7.4 in /usr/local/lib/python3.7/dist-packages (from rich==10.16.1->sleap) (3.10.0.2)\n", - "Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn==1.0.*->sleap) (3.1.0)\n", - "Requirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn==1.0.*->sleap) (1.1.0)\n", - "Collecting efficientnet==1.0.0\n", - " Downloading efficientnet-1.0.0-py3-none-any.whl (17 kB)\n", - "Collecting image-classifiers==1.0.0\n", - " Downloading image_classifiers-1.0.0-py3-none-any.whl (19 kB)\n", - "Collecting keras-applications<=1.0.8,>=1.0.7\n", - " Downloading Keras_Applications-1.0.8-py3-none-any.whl (50 kB)\n", - "\u001b[K |████████████████████████████████| 50 kB 6.3 MB/s \n", - "\u001b[?25hRequirement already satisfied: cached-property in /usr/local/lib/python3.7/dist-packages (from h5py<=3.6.0,>=3.1.0->sleap) (1.5.2)\n", - "Collecting shiboken2==5.14.1\n", - " Downloading shiboken2-5.14.1-5.14.1-cp35.cp36.cp37.cp38-abi3-manylinux1_x86_64.whl (847 kB)\n", - "\u001b[K |████████████████████████████████| 847 kB 43.5 MB/s \n", - "\u001b[?25hRequirement already satisfied: PyWavelets>=1.1.1 in /usr/local/lib/python3.7/dist-packages (from scikit-image->sleap) (1.3.0)\n", - "Requirement already satisfied: tifffile>=2019.7.26 in /usr/local/lib/python3.7/dist-packages (from scikit-image->sleap) (2021.11.2)\n", - "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->imgaug==0.4.0->sleap) (3.0.7)\n", - "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib->imgaug==0.4.0->sleap) (0.11.0)\n", - "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->imgaug==0.4.0->sleap) (1.4.0)\n", - "Requirement already satisfied: gast>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (0.5.3)\n", - "Requirement already satisfied: setuptools in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (57.4.0)\n", - "Requirement already satisfied: libclang>=9.0.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (13.0.0)\n", - "Requirement already satisfied: tensorflow-io-gcs-filesystem>=0.23.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (0.24.0)\n", - "Requirement already satisfied: astunparse>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.6.3)\n", - "Requirement already satisfied: opt-einsum>=2.3.2 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (3.3.0)\n", - "Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.1.0)\n", - "Requirement already satisfied: keras<2.9,>=2.8.0rc0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (2.8.0)\n", - "Requirement already satisfied: wrapt>=1.11.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.14.0)\n", - "Requirement already satisfied: keras-preprocessing>=1.1.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.1.2)\n", - "Requirement already satisfied: google-pasta>=0.1.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (0.2.0)\n", - "Collecting tf-estimator-nightly==2.8.0.dev2021122109\n", - " Downloading tf_estimator_nightly-2.8.0.dev2021122109-py2.py3-none-any.whl (462 kB)\n", - "\u001b[K |████████████████████████████████| 462 kB 49.8 MB/s \n", - "\u001b[?25hRequirement already satisfied: protobuf>=3.9.2 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (3.17.3)\n", - "Requirement already satisfied: tensorboard<2.9,>=2.8 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (2.8.0)\n", - "Requirement already satisfied: flatbuffers>=1.12 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (2.0)\n", - "Requirement already satisfied: absl-py>=0.4.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.0.0)\n", - "Requirement already satisfied: grpcio<2.0,>=1.24.3 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.9.0,>=2.6.3->sleap) (1.44.0)\n", - "Requirement already satisfied: wheel<1.0,>=0.23.0 in /usr/local/lib/python3.7/dist-packages (from astunparse>=1.6.0->tensorflow<2.9.0,>=2.6.3->sleap) (0.37.1)\n", - "Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.4.6)\n", - "Requirement already satisfied: tensorboard-plugin-wit>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.8.1)\n", - "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.3.6)\n", - "Requirement already satisfied: tensorboard-data-server<0.7.0,>=0.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.6.1)\n", - "Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.0.1)\n", - "Requirement already satisfied: requests<3,>=2.21.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (2.23.0)\n", - "Requirement already satisfied: google-auth<3,>=1.6.3 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.35.0)\n", - "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (4.8)\n", - "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.2.8)\n", - "Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (4.2.4)\n", - "Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.7/dist-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.3.1)\n", - "Requirement already satisfied: importlib-metadata>=4.4 in /usr/local/lib/python3.7/dist-packages (from markdown>=2.6.8->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (4.11.3)\n", - "Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata>=4.4->markdown>=2.6.8->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.7.0)\n", - "Requirement already satisfied: pyasn1<0.5.0,>=0.4.6 in /usr/local/lib/python3.7/dist-packages (from pyasn1-modules>=0.2.1->google-auth<3,>=1.6.3->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (0.4.8)\n", - "Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (2.10)\n", - "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.0.4)\n", - "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests<3,>=2.21.0->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (1.24.3)\n", - "Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.7/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard<2.9,>=2.8->tensorflow<2.9.0,>=2.6.3->sleap) (3.2.0)\n", - "Building wheels for collected packages: pykalman, jsmin\n", - " Building wheel for pykalman (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Created wheel for pykalman: filename=pykalman-0.9.5-py3-none-any.whl size=48462 sha256=5de7d8c6487261ac5359426edf6b9d6ff977786a758424aaa6462a743fae77e4\n", - " Stored in directory: /root/.cache/pip/wheels/6a/04/02/2dda6ea59c66d9e685affc8af3a31ad3a5d87b7311689efce6\n", - " Building wheel for jsmin (setup.py) ... \u001b[?25l\u001b[?25hdone\n", - " Created wheel for jsmin: filename=jsmin-3.0.1-py3-none-any.whl size=13782 sha256=353b91b543700f74d4c7801c636ff32de6e99c9578162db575ea8d5e0b29d64e\n", - " Stored in directory: /root/.cache/pip/wheels/a4/0b/64/fb4f87526ecbdf7921769a39d91dcfe4860e621cf15b8250d6\n", - "Successfully built pykalman jsmin\n", - "Installing collected packages: keras-applications, tf-estimator-nightly, shiboken2, opencv-python, image-classifiers, efficientnet, commonmark, colorama, attrs, segmentation-models, scikit-video, rich, qimage2ndarray, python-rapidjson, PySide2, pykalman, opencv-python-headless, jsonpickle, jsmin, imgstore, imgaug, cattrs, sleap\n", - " Attempting uninstall: attrs\n", - " Found existing installation: attrs 21.4.0\n", - " Uninstalling attrs-21.4.0:\n", - " Successfully uninstalled attrs-21.4.0\n", - " Attempting uninstall: imgaug\n", - " Found existing installation: imgaug 0.2.9\n", - " Uninstalling imgaug-0.2.9:\n", - " Successfully uninstalled imgaug-0.2.9\n", - "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n", - "datascience 0.10.6 requires folium==0.2.1, but you have folium 0.8.3 which is incompatible.\n", - "albumentations 0.1.12 requires imgaug<0.2.7,>=0.2.5, but you have imgaug 0.4.0 which is incompatible.\u001b[0m\n", - "Successfully installed PySide2-5.14.1 attrs-21.2.0 cattrs-1.1.1 colorama-0.4.4 commonmark-0.9.1 efficientnet-1.0.0 image-classifiers-1.0.0 imgaug-0.4.0 imgstore-0.2.9 jsmin-3.0.1 jsonpickle-1.2 keras-applications-1.0.8 opencv-python-4.5.5.64 opencv-python-headless-4.5.5.62 pykalman-0.9.5 python-rapidjson-1.6 qimage2ndarray-1.8.3 rich-10.16.1 scikit-video-1.1.11 segmentation-models-1.0.1 shiboken2-5.14.1 sleap-1.2.2 tf-estimator-nightly-2.8.0.dev2021122109\n" - ] - } + "outputs": [], + "source": [ + "# This should take care of all the dependencies on colab:\n", + "!pip uninstall -qqq -y opencv-python opencv-contrib-python\n", + "!pip install -qqq \"sleap[pypi]>=1.3.3\"\n", + "\n", + "# But to do it locally, we'd recommend the conda package (available on Windows + Linux):\n", + "# conda create -n sleap -c sleap -c conda-forge -c nvidia sleap" ] }, { "cell_type": "markdown", - "source": [ - "### Test" - ], "metadata": { "id": "d10pcIu70oLb" - } + }, + "source": [ + "### Test" + ] }, { "cell_type": "code", - "source": [ - "#@title SLEAP and system versions: { display-mode: \"form\" }\n", - "import sleap\n", - "sleap.versions()\n", - "sleap.system_summary()" - ], + "execution_count": 2, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -267,34 +86,63 @@ "id": "WBGKYmLj9Zc2", "outputId": "8f044c67-3abe-4b8b-8552-db2b5c756c7c" }, - "execution_count": 1, "outputs": [ { + "name": "stderr", "output_type": "stream", + "text": [ + "2023-09-01 14:17:16.250591: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:/home/talmolab/micromamba/envs/sleap_jupyter/lib:\n", + "2023-09-01 14:17:16.250602: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n" + ] + }, + { "name": "stdout", + "output_type": "stream", "text": [ - "INFO:numexpr.utils:NumExpr defaulting to 2 threads.\n", - "SLEAP: 1.2.2\n", - "TensorFlow: 2.8.0\n", - "Numpy: 1.21.5\n", - "Python: 3.7.13\n", - "OS: Linux-5.4.144+-x86_64-with-Ubuntu-18.04-bionic\n", + "SLEAP: 1.3.1\n", + "TensorFlow: 2.8.4\n", + "Numpy: 1.21.6\n", + "Python: 3.7.12\n", + "OS: Linux-5.15.0-78-generic-x86_64-with-debian-bookworm-sid\n", "GPUs: None detected.\n" ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2023-09-01 14:17:17.389239: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:936] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 14:17:17.390139: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:/home/talmolab/micromamba/envs/sleap_jupyter/lib:\n", + "2023-09-01 14:17:17.390188: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcublas.so.11'; dlerror: libcublas.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:/home/talmolab/micromamba/envs/sleap_jupyter/lib:\n", + "2023-09-01 14:17:17.390230: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcublasLt.so.11'; dlerror: libcublasLt.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:/home/talmolab/micromamba/envs/sleap_jupyter/lib:\n", + "2023-09-01 14:17:17.390267: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcufft.so.10'; dlerror: libcufft.so.10: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:/home/talmolab/micromamba/envs/sleap_jupyter/lib:\n", + "2023-09-01 14:17:17.390306: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcurand.so.10'; dlerror: libcurand.so.10: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:/home/talmolab/micromamba/envs/sleap_jupyter/lib:\n", + "2023-09-01 14:17:17.390345: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcusolver.so.11'; dlerror: libcusolver.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:/home/talmolab/micromamba/envs/sleap_jupyter/lib:\n", + "2023-09-01 14:17:17.390383: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcusparse.so.11'; dlerror: libcusparse.so.11: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:/home/talmolab/micromamba/envs/sleap_jupyter/lib:\n", + "2023-09-01 14:17:17.390421: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudnn.so.8'; dlerror: libcudnn.so.8: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /home/talmolab/micromamba/envs/sleap_jupyter/lib/python3.7/site-packages/cv2/../../lib64:/home/talmolab/micromamba/envs/sleap_jupyter/lib:\n", + "2023-09-01 14:17:17.390425: W tensorflow/core/common_runtime/gpu/gpu_device.cc:1850] Cannot dlopen some GPU libraries. Please make sure the missing libraries mentioned above are installed properly if you would like to use GPU. Follow the guide at https://www.tensorflow.org/install/gpu for how to download and setup the required libraries for your platform.\n", + "Skipping registering GPU devices...\n" + ] } + ], + "source": [ + "#@title SLEAP and system versions: { display-mode: \"form\" }\n", + "import sleap\n", + "sleap.versions()\n", + "sleap.system_summary()" ] }, { "cell_type": "markdown", + "metadata": { + "id": "hYBojEjY9qyr" + }, "source": [ "# 2. Setup data\n", "Here we're downloading an existing `.slp` file with predictions and the corresponding `.mp4` video.\n", "\n", "You should replace this with Google Drive mounting if running this on Google Colab, or simply skip it altogether and just set the paths below if running locally." - ], - "metadata": { - "id": "hYBojEjY9qyr" - } + ] }, { "cell_type": "code", @@ -306,91 +154,35 @@ "id": "akfAyAo-9cAd", "outputId": "456bd33c-c1f6-4d57-dc37-a58ef8717472" }, - "outputs": [ - { - "output_type": "stream", - "name": "stdout", - "text": [ - "--2022-04-04 00:10:34-- https://github.com/talmolab/sleap-tutorial-uo/blob/main/data/fly_clip.mp4?raw=true\n", - "Resolving github.com (github.com)... 13.114.40.48\n", - "Connecting to github.com (github.com)|13.114.40.48|:443... connected.\n", - "HTTP request sent, awaiting response... 302 Found\n", - "Location: https://github.com/talmolab/sleap-tutorial-uo/raw/main/data/fly_clip.mp4 [following]\n", - "--2022-04-04 00:10:34-- https://github.com/talmolab/sleap-tutorial-uo/raw/main/data/fly_clip.mp4\n", - "Reusing existing connection to github.com:443.\n", - "HTTP request sent, awaiting response... 302 Found\n", - "Location: https://raw.githubusercontent.com/talmolab/sleap-tutorial-uo/main/data/fly_clip.mp4 [following]\n", - "--2022-04-04 00:10:34-- https://raw.githubusercontent.com/talmolab/sleap-tutorial-uo/main/data/fly_clip.mp4\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.108.133, 185.199.109.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected.\n", - "HTTP request sent, awaiting response... 200 OK\n", - "Length: 676194 (660K) [application/octet-stream]\n", - "Saving to: ‘fly_clip.mp4’\n", - "\n", - "fly_clip.mp4 100%[===================>] 660.35K --.-KB/s in 0.05s \n", - "\n", - "2022-04-04 00:10:36 (12.1 MB/s) - ‘fly_clip.mp4’ saved [676194/676194]\n", - "\n", - "--2022-04-04 00:10:36-- https://github.com/talmolab/sleap-tutorial-uo/blob/main/data/predictions.slp?raw=true\n", - "Resolving github.com (github.com)... 52.69.186.44\n", - "Connecting to github.com (github.com)|52.69.186.44|:443... connected.\n", - "HTTP request sent, awaiting response... 302 Found\n", - "Location: https://github.com/talmolab/sleap-tutorial-uo/raw/main/data/predictions.slp [following]\n", - "--2022-04-04 00:10:37-- https://github.com/talmolab/sleap-tutorial-uo/raw/main/data/predictions.slp\n", - "Reusing existing connection to github.com:443.\n", - "HTTP request sent, awaiting response... 302 Found\n", - "Location: https://raw.githubusercontent.com/talmolab/sleap-tutorial-uo/main/data/predictions.slp [following]\n", - "--2022-04-04 00:10:37-- https://raw.githubusercontent.com/talmolab/sleap-tutorial-uo/main/data/predictions.slp\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.108.133, 185.199.109.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected.\n", - "HTTP request sent, awaiting response... 200 OK\n", - "Length: 420976 (411K) [application/octet-stream]\n", - "Saving to: ‘predictions.slp’\n", - "\n", - "predictions.slp 100%[===================>] 411.11K --.-KB/s in 0.04s \n", - "\n", - "2022-04-04 00:10:38 (9.66 MB/s) - ‘predictions.slp’ saved [420976/420976]\n", - "\n" - ] - } - ], + "outputs": [], "source": [ - "!wget -O fly_clip.mp4 https://github.com/talmolab/sleap-tutorial-uo/blob/main/data/fly_clip.mp4?raw=true\n", - "!wget -O predictions.slp https://github.com/talmolab/sleap-tutorial-uo/blob/main/data/predictions.slp?raw=true" + "!wget -q -O fly_clip.mp4 https://github.com/talmolab/sleap-tutorial-uo/blob/main/data/fly_clip.mp4?raw=true\n", + "!wget -q -O predictions.slp https://github.com/talmolab/sleap-tutorial-uo/blob/main/data/predictions.slp?raw=true" ] }, { "cell_type": "code", - "source": [ - "PREDICTIONS_FILE = \"predictions.slp\"" - ], + "execution_count": 4, "metadata": { "id": "gQSc_ZjFnHl9" }, - "execution_count": 2, - "outputs": [] + "outputs": [], + "source": [ + "PREDICTIONS_FILE = \"predictions.slp\"" + ] }, { "cell_type": "markdown", - "source": [ - "# 3. Track" - ], "metadata": { "id": "9z5rbej_-_Ea" - } + }, + "source": [ + "# 3. Track" + ] }, { "cell_type": "code", - "source": [ - "# Load predictions\n", - "labels = sleap.load_file(PREDICTIONS_FILE)\n", - "\n", - "# Here I'm removing the tracks so we just have instances without any tracking applied.\n", - "for instance in labels.instances():\n", - " instance.track = None\n", - "labels.tracks = []\n", - "labels" - ], + "execution_count": 5, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -398,31 +190,45 @@ "id": "MhHCTkdr-wTz", "outputId": "2e286994-eb4c-4648-c6b9-ab3e7d0cc605" }, - "execution_count": 3, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "Labels(labeled_frames=1350, videos=1, skeletons=1, tracks=0)" ] }, + "execution_count": 5, "metadata": {}, - "execution_count": 3 + "output_type": "execute_result" } + ], + "source": [ + "# Load predictions\n", + "labels = sleap.load_file(PREDICTIONS_FILE)\n", + "\n", + "# Here I'm removing the tracks so we just have instances without any tracking applied.\n", + "for instance in labels.instances():\n", + " instance.track = None\n", + "labels.tracks = []\n", + "labels" ] }, { "cell_type": "markdown", - "source": [ - "Here we create a tracker with the options we want to experiment with. You can [read more about tracking in the documentation](https://sleap.ai/guides/proofreading.html#tracking-methods) or the parameters in the [`sleap-track` CLI help](https://sleap.ai/guides/cli.html#sleap-track)." - ], "metadata": { "id": "hwFC2WYWBQXe" - } + }, + "source": [ + "Here we create a tracker with the options we want to experiment with. You can [read more about tracking in the documentation](https://sleap.ai/guides/proofreading.html#tracking-methods) or the parameters in the [`sleap-track` CLI help](https://sleap.ai/guides/cli.html#sleap-track)." + ] }, { "cell_type": "code", + "execution_count": 6, + "metadata": { + "id": "AgDVuL-u9_iv" + }, + "outputs": [], "source": [ "# Create tracker\n", "tracker = sleap.nn.tracking.Tracker.make_tracker_by_name(\n", @@ -451,32 +257,20 @@ " clean_instance_count=0,\n", " clean_iou_threshold=None,\n", ")" - ], - "metadata": { - "id": "AgDVuL-u9_iv" - }, - "execution_count": 4, - "outputs": [] + ] }, { "cell_type": "markdown", - "source": [ - "Next we'll actually run the tracking on each frame. This might take a bit longer when using the `\"flow\"` method." - ], "metadata": { "id": "EfMhLxWcBqBg" - } + }, + "source": [ + "Next we'll actually run the tracking on each frame. This might take a bit longer when using the `\"flow\"` method." + ] }, { "cell_type": "code", - "source": [ - "tracked_lfs = []\n", - "for lf in labels:\n", - " lf.instances = tracker.track(lf.instances, img=lf.image)\n", - " tracked_lfs.append(lf)\n", - "tracked_labels = sleap.Labels(tracked_lfs)\n", - "tracked_labels" - ], + "execution_count": 7, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -484,36 +278,41 @@ "id": "q-EE7r0pBpfD", "outputId": "eabfe089-b122-494d-c41e-996b0243ab71" }, - "execution_count": 5, "outputs": [ { - "output_type": "execute_result", "data": { "text/plain": [ "Labels(labeled_frames=1350, videos=1, skeletons=1, tracks=2)" ] }, + "execution_count": 7, "metadata": {}, - "execution_count": 5 + "output_type": "execute_result" } + ], + "source": [ + "tracked_lfs = []\n", + "for lf in labels:\n", + " lf.instances = tracker.track(lf.instances, img=lf.image)\n", + " tracked_lfs.append(lf)\n", + "tracked_labels = sleap.Labels(tracked_lfs)\n", + "tracked_labels" ] }, { "cell_type": "markdown", + "metadata": { + "id": "OjUvwRzWCJ_G" + }, "source": [ "# 4. Inspect and save\n", "\n", "Let's see the results and save out the tracked predictions." - ], - "metadata": { - "id": "OjUvwRzWCJ_G" - } + ] }, { "cell_type": "code", - "source": [ - "tracked_labels[0].plot(scale=0.25)" - ], + "execution_count": 8, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -522,25 +321,25 @@ "id": "g-ia6hYGCXZX", "outputId": "2652a6e2-6f63-4b81-dd54-d8a01c6c25a4" }, - "execution_count": 6, "outputs": [ { - "output_type": "display_data", "data": { + "image/png": "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", "text/plain": [ "
" - ], - "image/png": "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\n" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" } + ], + "source": [ + "tracked_labels[0].plot(scale=0.25)" ] }, { "cell_type": "code", - "source": [ - "tracked_labels[100].plot(scale=0.25)" - ], + "execution_count": 9, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -549,30 +348,57 @@ "id": "nDMnJFmFCszY", "outputId": "90b984e6-b6bb-468b-eb66-2b0537758c44" }, - "execution_count": 7, "outputs": [ { - "output_type": "display_data", "data": { + "image/png": "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", "text/plain": [ "
" - ], - "image/png": "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\n" + ] }, - "metadata": {} + "metadata": {}, + "output_type": "display_data" } + ], + "source": [ + "tracked_labels[100].plot(scale=0.25)" ] }, { "cell_type": "code", - "source": [ - "tracked_labels.save(\"retracked.slp\")" - ], + "execution_count": 10, "metadata": { "id": "D3YMi3C0C0uh" }, - "execution_count": 8, - "outputs": [] + "outputs": [], + "source": [ + "tracked_labels.save(\"retracked.slp\")" + ] } - ] + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "SLEAP - Post-inference tracking.ipynb", + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.12" + } + }, + "nbformat": 4, + "nbformat_minor": 0 } diff --git a/docs/notebooks/Training_and_inference_on_an_example_dataset.ipynb b/docs/notebooks/Training_and_inference_on_an_example_dataset.ipynb index a397089d5..4e26cb286 100644 --- a/docs/notebooks/Training_and_inference_on_an_example_dataset.ipynb +++ b/docs/notebooks/Training_and_inference_on_an_example_dataset.ipynb @@ -40,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -49,10 +49,20 @@ "id": "DUfnkxMtLcK3", "outputId": "a6340ef1-eaac-42ef-f8d4-bcc499feb57b" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[31mERROR: Cannot uninstall opencv-python 4.6.0, RECORD file not found. Hint: The package was installed by conda.\u001b[0m\u001b[31m\n", + "\u001b[0m\u001b[31mERROR: Cannot uninstall shiboken2 5.15.6, RECORD file not found. You might be able to recover from this via: 'pip install --force-reinstall --no-deps shiboken2==5.15.6'.\u001b[0m\u001b[31m\n", + "\u001b[0m" + ] + } + ], "source": [ - "!pip uninstall -y opencv-python opencv-contrib-python\n", - "!pip install sleap" + "!pip uninstall -qqq -y opencv-python opencv-contrib-python\n", + "!pip install -qqq \"sleap[pypi]>=1.3.3\"" ] }, { @@ -67,7 +77,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 24, "metadata": { "colab": { "base_uri": "https://localhost:8080/" @@ -75,7 +85,53 @@ "id": "fm3cU1Bc0tWc", "outputId": "c0ac5677-e3c5-477c-a2f7-44d619208b22" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "E: Could not open lock file /var/lib/dpkg/lock-frontend - open (13: Permission denied)\n", + "E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), are you root?\n", + "--2023-09-01 13:30:33-- https://github.com/talmolab/sleap-datasets/releases/download/dm-courtship-v1/drosophila-melanogaster-courtship.zip\n", + "Resolving github.com (github.com)... 192.30.255.113\n", + "Connecting to github.com (github.com)|192.30.255.113|:443... connected.\n", + "HTTP request sent, awaiting response... 302 Found\n", + "Location: https://objects.githubusercontent.com/github-production-release-asset-2e65be/263375180/16df8d00-94f1-11ea-98d1-6c03a2f89e1c?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230901%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230901T203033Z&X-Amz-Expires=300&X-Amz-Signature=b9b0638744af3144affdc46668c749128bd6c4f23ca2a1313821c7bbcd54ccdd&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=263375180&response-content-disposition=attachment%3B%20filename%3Ddrosophila-melanogaster-courtship.zip&response-content-type=application%2Foctet-stream [following]\n", + "--2023-09-01 13:30:33-- https://objects.githubusercontent.com/github-production-release-asset-2e65be/263375180/16df8d00-94f1-11ea-98d1-6c03a2f89e1c?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230901%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20230901T203033Z&X-Amz-Expires=300&X-Amz-Signature=b9b0638744af3144affdc46668c749128bd6c4f23ca2a1313821c7bbcd54ccdd&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=263375180&response-content-disposition=attachment%3B%20filename%3Ddrosophila-melanogaster-courtship.zip&response-content-type=application%2Foctet-stream\n", + "Resolving objects.githubusercontent.com (objects.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", + "Connecting to objects.githubusercontent.com (objects.githubusercontent.com)|185.199.108.133|:443... connected.\n", + "HTTP request sent, awaiting response... 200 OK\n", + "Length: 111973079 (107M) [application/octet-stream]\n", + "Saving to: ‘dataset.zip’\n", + "\n", + "dataset.zip 100%[===================>] 106.79M 63.0MB/s in 1.7s \n", + "\n", + "2023-09-01 13:30:35 (63.0 MB/s) - ‘dataset.zip’ saved [111973079/111973079]\n", + "\n", + "Archive: dataset.zip\n", + " creating: dataset/drosophila-melanogaster-courtship/\n", + " inflating: dataset/drosophila-melanogaster-courtship/.DS_Store \n", + " creating: dataset/__MACOSX/\n", + " creating: dataset/__MACOSX/drosophila-melanogaster-courtship/\n", + " inflating: dataset/__MACOSX/drosophila-melanogaster-courtship/._.DS_Store \n", + " inflating: dataset/drosophila-melanogaster-courtship/20190128_113421.mp4 \n", + " inflating: dataset/__MACOSX/drosophila-melanogaster-courtship/._20190128_113421.mp4 \n", + " inflating: dataset/drosophila-melanogaster-courtship/courtship_labels.slp \n", + " inflating: dataset/__MACOSX/drosophila-melanogaster-courtship/._courtship_labels.slp \n", + " inflating: dataset/drosophila-melanogaster-courtship/example.jpg \n", + " inflating: dataset/__MACOSX/drosophila-melanogaster-courtship/._example.jpg \n", + "\u001b[01;34mdataset\u001b[00m\n", + "├── \u001b[01;34mdrosophila-melanogaster-courtship\u001b[00m\n", + "│   ├── \u001b[01;32m20190128_113421.mp4\u001b[00m\n", + "│   ├── \u001b[01;32mcourtship_labels.slp\u001b[00m\n", + "│   └── \u001b[01;35mexample.jpg\u001b[00m\n", + "└── \u001b[01;34m__MACOSX\u001b[00m\n", + " └── \u001b[01;34mdrosophila-melanogaster-courtship\u001b[00m\n", + "\n", + "3 directories, 3 files\n" + ] + } + ], "source": [ "!apt-get install tree\n", "!wget -O dataset.zip https://github.com/talmolab/sleap-datasets/releases/download/dm-courtship-v1/drosophila-melanogaster-courtship.zip\n", @@ -105,11 +161,382 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 25, "metadata": { "id": "QKf6qzMqNBUi" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:sleap.nn.training:Versions:\n", + "SLEAP: 1.3.2\n", + "TensorFlow: 2.7.0\n", + "Numpy: 1.21.5\n", + "Python: 3.7.12\n", + "OS: Linux-5.15.0-78-generic-x86_64-with-debian-bookworm-sid\n", + "INFO:sleap.nn.training:Training labels file: dataset/drosophila-melanogaster-courtship/courtship_labels.slp\n", + "INFO:sleap.nn.training:Training profile: /home/talmolab/sleap-estimates-animal-poses/pull-requests/sleap/sleap/training_profiles/baseline.centroid.json\n", + "INFO:sleap.nn.training:\n", + "INFO:sleap.nn.training:Arguments:\n", + "INFO:sleap.nn.training:{\n", + " \"training_job_path\": \"baseline.centroid.json\",\n", + " \"labels_path\": \"dataset/drosophila-melanogaster-courtship/courtship_labels.slp\",\n", + " \"video_paths\": [\n", + " \"dataset/drosophila-melanogaster-courtship/20190128_113421.mp4\"\n", + " ],\n", + " \"val_labels\": null,\n", + " \"test_labels\": null,\n", + " \"base_checkpoint\": null,\n", + " \"tensorboard\": false,\n", + " \"save_viz\": false,\n", + " \"zmq\": false,\n", + " \"run_name\": \"courtship.centroid\",\n", + " \"prefix\": \"\",\n", + " \"suffix\": \"\",\n", + " \"cpu\": false,\n", + " \"first_gpu\": false,\n", + " \"last_gpu\": false,\n", + " \"gpu\": \"auto\"\n", + "}\n", + "INFO:sleap.nn.training:\n", + "INFO:sleap.nn.training:Training job:\n", + "INFO:sleap.nn.training:{\n", + " \"data\": {\n", + " \"labels\": {\n", + " \"training_labels\": null,\n", + " \"validation_labels\": null,\n", + " \"validation_fraction\": 0.1,\n", + " \"test_labels\": null,\n", + " \"split_by_inds\": false,\n", + " \"training_inds\": null,\n", + " \"validation_inds\": null,\n", + " \"test_inds\": null,\n", + " \"search_path_hints\": [],\n", + " \"skeletons\": []\n", + " },\n", + " \"preprocessing\": {\n", + " \"ensure_rgb\": false,\n", + " \"ensure_grayscale\": false,\n", + " \"imagenet_mode\": null,\n", + " \"input_scaling\": 0.5,\n", + " \"pad_to_stride\": null,\n", + " \"resize_and_pad_to_target\": true,\n", + " \"target_height\": null,\n", + " \"target_width\": null\n", + " },\n", + " \"instance_cropping\": {\n", + " \"center_on_part\": null,\n", + " \"crop_size\": null,\n", + " \"crop_size_detection_padding\": 16\n", + " }\n", + " },\n", + " \"model\": {\n", + " \"backbone\": {\n", + " \"leap\": null,\n", + " \"unet\": {\n", + " \"stem_stride\": null,\n", + " \"max_stride\": 16,\n", + " \"output_stride\": 2,\n", + " \"filters\": 16,\n", + " \"filters_rate\": 2.0,\n", + " \"middle_block\": true,\n", + " \"up_interpolate\": true,\n", + " \"stacks\": 1\n", + " },\n", + " \"hourglass\": null,\n", + " \"resnet\": null,\n", + " \"pretrained_encoder\": null\n", + " },\n", + " \"heads\": {\n", + " \"single_instance\": null,\n", + " \"centroid\": {\n", + " \"anchor_part\": null,\n", + " \"sigma\": 2.5,\n", + " \"output_stride\": 2,\n", + " \"loss_weight\": 1.0,\n", + " \"offset_refinement\": false\n", + " },\n", + " \"centered_instance\": null,\n", + " \"multi_instance\": null,\n", + " \"multi_class_bottomup\": null,\n", + " \"multi_class_topdown\": null\n", + " },\n", + " \"base_checkpoint\": null\n", + " },\n", + " \"optimization\": {\n", + " \"preload_data\": true,\n", + " \"augmentation_config\": {\n", + " \"rotate\": true,\n", + " \"rotation_min_angle\": -15.0,\n", + " \"rotation_max_angle\": 15.0,\n", + " \"translate\": false,\n", + " \"translate_min\": -5,\n", + " \"translate_max\": 5,\n", + " \"scale\": false,\n", + " \"scale_min\": 0.9,\n", + " \"scale_max\": 1.1,\n", + " \"uniform_noise\": false,\n", + " \"uniform_noise_min_val\": 0.0,\n", + " \"uniform_noise_max_val\": 10.0,\n", + " \"gaussian_noise\": false,\n", + " \"gaussian_noise_mean\": 5.0,\n", + " \"gaussian_noise_stddev\": 1.0,\n", + " \"contrast\": false,\n", + " \"contrast_min_gamma\": 0.5,\n", + " \"contrast_max_gamma\": 2.0,\n", + " \"brightness\": false,\n", + " \"brightness_min_val\": 0.0,\n", + " \"brightness_max_val\": 10.0,\n", + " \"random_crop\": false,\n", + " \"random_crop_height\": 256,\n", + " \"random_crop_width\": 256,\n", + " \"random_flip\": false,\n", + " \"flip_horizontal\": true\n", + " },\n", + " \"online_shuffling\": true,\n", + " \"shuffle_buffer_size\": 128,\n", + " \"prefetch\": true,\n", + " \"batch_size\": 4,\n", + " \"batches_per_epoch\": null,\n", + " \"min_batches_per_epoch\": 200,\n", + " \"val_batches_per_epoch\": null,\n", + " \"min_val_batches_per_epoch\": 10,\n", + " \"epochs\": 200,\n", + " \"optimizer\": \"adam\",\n", + " \"initial_learning_rate\": 0.0001,\n", + " \"learning_rate_schedule\": {\n", + " \"reduce_on_plateau\": true,\n", + " \"reduction_factor\": 0.5,\n", + " \"plateau_min_delta\": 1e-08,\n", + " \"plateau_patience\": 5,\n", + " \"plateau_cooldown\": 3,\n", + " \"min_learning_rate\": 1e-08\n", + " },\n", + " \"hard_keypoint_mining\": {\n", + " \"online_mining\": false,\n", + " \"hard_to_easy_ratio\": 2.0,\n", + " \"min_hard_keypoints\": 2,\n", + " \"max_hard_keypoints\": null,\n", + " \"loss_scale\": 5.0\n", + " },\n", + " \"early_stopping\": {\n", + " \"stop_training_on_plateau\": true,\n", + " \"plateau_min_delta\": 1e-08,\n", + " \"plateau_patience\": 20\n", + " }\n", + " },\n", + " \"outputs\": {\n", + " \"save_outputs\": true,\n", + " \"run_name\": \"courtship.centroid\",\n", + " \"run_name_prefix\": \"\",\n", + " \"run_name_suffix\": null,\n", + " \"runs_folder\": \"models\",\n", + " \"tags\": [],\n", + " \"save_visualizations\": true,\n", + " \"keep_viz_images\": true,\n", + " \"zip_outputs\": false,\n", + " \"log_to_csv\": true,\n", + " \"checkpointing\": {\n", + " \"initial_model\": false,\n", + " \"best_model\": true,\n", + " \"every_epoch\": false,\n", + " \"latest_model\": false,\n", + " \"final_model\": false\n", + " },\n", + " \"tensorboard\": {\n", + " \"write_logs\": false,\n", + " \"loss_frequency\": \"epoch\",\n", + " \"architecture_graph\": false,\n", + " \"profile_graph\": false,\n", + " \"visualizations\": true\n", + " },\n", + " \"zmq\": {\n", + " \"subscribe_to_controller\": false,\n", + " \"controller_address\": \"tcp://127.0.0.1:9000\",\n", + " \"controller_polling_timeout\": 10,\n", + " \"publish_updates\": false,\n", + " \"publish_address\": \"tcp://127.0.0.1:9001\"\n", + " }\n", + " },\n", + " \"name\": \"\",\n", + " \"description\": \"\",\n", + " \"sleap_version\": \"1.3.2\",\n", + " \"filename\": \"/home/talmolab/sleap-estimates-animal-poses/pull-requests/sleap/sleap/training_profiles/baseline.centroid.json\"\n", + "}\n", + "INFO:sleap.nn.training:\n", + "2023-09-01 13:30:38.827290: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:30:38.831845: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:30:38.832633: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "INFO:sleap.nn.training:Auto-selected GPU 0 with 22980 MiB of free memory.\n", + "INFO:sleap.nn.training:Using GPU 0 for acceleration.\n", + "INFO:sleap.nn.training:Disabled GPU memory pre-allocation.\n", + "INFO:sleap.nn.training:System:\n", + "GPUs: 1/1 available\n", + " Device: /physical_device:GPU:0\n", + " Available: True\n", + " Initalized: False\n", + " Memory growth: True\n", + "INFO:sleap.nn.training:\n", + "INFO:sleap.nn.training:Initializing trainer...\n", + "INFO:sleap.nn.training:Loading training labels from: dataset/drosophila-melanogaster-courtship/courtship_labels.slp\n", + "INFO:sleap.nn.training:Creating training and validation splits from validation fraction: 0.1\n", + "INFO:sleap.nn.training: Splits: Training = 134 / Validation = 15.\n", + "INFO:sleap.nn.training:Setting up for training...\n", + "INFO:sleap.nn.training:Setting up pipeline builders...\n", + "INFO:sleap.nn.training:Setting up model...\n", + "INFO:sleap.nn.training:Building test pipeline...\n", + "2023-09-01 13:30:39.755154: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX512F FMA\n", + "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n", + "2023-09-01 13:30:39.756024: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:30:39.757213: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:30:39.758315: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:30:40.089801: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:30:40.090652: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:30:40.091464: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:30:40.092164: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1525] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 21084 MB memory: -> device: 0, name: NVIDIA RTX A5000, pci bus id: 0000:01:00.0, compute capability: 8.6\n", + "INFO:sleap.nn.training:Loaded test example. [1.326s]\n", + "INFO:sleap.nn.training: Input shape: (512, 512, 3)\n", + "INFO:sleap.nn.training:Created Keras model.\n", + "INFO:sleap.nn.training: Backbone: UNet(stacks=1, filters=16, filters_rate=2.0, kernel_size=3, stem_kernel_size=7, convs_per_block=2, stem_blocks=0, down_blocks=4, middle_block=True, up_blocks=3, up_interpolate=True, block_contraction=False)\n", + "INFO:sleap.nn.training: Max stride: 16\n", + "INFO:sleap.nn.training: Parameters: 1,953,393\n", + "INFO:sleap.nn.training: Heads: \n", + "INFO:sleap.nn.training: [0] = CentroidConfmapsHead(anchor_part=None, sigma=2.5, output_stride=2, loss_weight=1.0)\n", + "INFO:sleap.nn.training: Outputs: \n", + "INFO:sleap.nn.training: [0] = KerasTensor(type_spec=TensorSpec(shape=(None, 256, 256, 1), dtype=tf.float32, name=None), name='CentroidConfmapsHead/BiasAdd:0', description=\"created by layer 'CentroidConfmapsHead'\")\n", + "INFO:sleap.nn.training:Training from scratch\n", + "INFO:sleap.nn.training:Setting up data pipelines...\n", + "INFO:sleap.nn.training:Training set: n = 134\n", + "INFO:sleap.nn.training:Validation set: n = 15\n", + "INFO:sleap.nn.training:Setting up optimization...\n", + "INFO:sleap.nn.training: Learning rate schedule: LearningRateScheduleConfig(reduce_on_plateau=True, reduction_factor=0.5, plateau_min_delta=1e-08, plateau_patience=5, plateau_cooldown=3, min_learning_rate=1e-08)\n", + "INFO:sleap.nn.training: Early stopping: EarlyStoppingConfig(stop_training_on_plateau=True, plateau_min_delta=1e-08, plateau_patience=20)\n", + "INFO:sleap.nn.training:Setting up outputs...\n", + "INFO:sleap.nn.training:Created run path: models/courtship.centroid\n", + "INFO:sleap.nn.training:Setting up visualization...\n", + "INFO:sleap.nn.training:Finished trainer set up. [3.5s]\n", + "INFO:sleap.nn.training:Creating tf.data.Datasets for training data generation...\n", + "INFO:sleap.nn.training:Finished creating training datasets. [5.4s]\n", + "INFO:sleap.nn.training:Starting training loop...\n", + "Epoch 1/200\n", + "2023-09-01 13:30:49.814560: I tensorflow/stream_executor/cuda/cuda_dnn.cc:366] Loaded cuDNN version 8201\n", + "2023-09-01 13:31:07.940585: I tensorflow/stream_executor/cuda/cuda_blas.cc:1774] TensorFloat-32 will be used for the matrix multiplication. This will only be logged once.\n", + "200/200 - 20s - loss: 2.5945e-04 - val_loss: 1.5190e-04 - lr: 1.0000e-04 - 20s/epoch - 99ms/step\n", + "Epoch 2/200\n", + "200/200 - 11s - loss: 1.2513e-04 - val_loss: 9.5694e-05 - lr: 1.0000e-04 - 11s/epoch - 57ms/step\n", + "Epoch 3/200\n", + "200/200 - 11s - loss: 9.6987e-05 - val_loss: 6.8224e-05 - lr: 1.0000e-04 - 11s/epoch - 57ms/step\n", + "Epoch 4/200\n", + "200/200 - 12s - loss: 8.1486e-05 - val_loss: 5.0657e-05 - lr: 1.0000e-04 - 12s/epoch - 58ms/step\n", + "Epoch 5/200\n", + "200/200 - 11s - loss: 7.2174e-05 - val_loss: 5.3859e-05 - lr: 1.0000e-04 - 11s/epoch - 55ms/step\n", + "Epoch 6/200\n", + "200/200 - 11s - loss: 5.9181e-05 - val_loss: 7.0259e-05 - lr: 1.0000e-04 - 11s/epoch - 55ms/step\n", + "Epoch 7/200\n", + "200/200 - 11s - loss: 4.9353e-05 - val_loss: 4.9832e-05 - lr: 1.0000e-04 - 11s/epoch - 57ms/step\n", + "Epoch 8/200\n", + "200/200 - 11s - loss: 3.8997e-05 - val_loss: 4.4787e-05 - lr: 1.0000e-04 - 11s/epoch - 55ms/step\n", + "Epoch 9/200\n", + "200/200 - 11s - loss: 3.5596e-05 - val_loss: 6.5150e-05 - lr: 1.0000e-04 - 11s/epoch - 55ms/step\n", + "Epoch 10/200\n", + "200/200 - 12s - loss: 2.9256e-05 - val_loss: 3.8968e-05 - lr: 1.0000e-04 - 12s/epoch - 58ms/step\n", + "Epoch 11/200\n", + "200/200 - 11s - loss: 2.8572e-05 - val_loss: 3.5451e-05 - lr: 1.0000e-04 - 11s/epoch - 55ms/step\n", + "Epoch 12/200\n", + "200/200 - 11s - loss: 2.2156e-05 - val_loss: 4.8602e-05 - lr: 1.0000e-04 - 11s/epoch - 53ms/step\n", + "Epoch 13/200\n", + "200/200 - 11s - loss: 1.7656e-05 - val_loss: 4.1905e-05 - lr: 1.0000e-04 - 11s/epoch - 55ms/step\n", + "Epoch 14/200\n", + "200/200 - 11s - loss: 1.6440e-05 - val_loss: 3.6607e-05 - lr: 1.0000e-04 - 11s/epoch - 55ms/step\n", + "Epoch 15/200\n", + "200/200 - 11s - loss: 1.4415e-05 - val_loss: 4.1699e-05 - lr: 1.0000e-04 - 11s/epoch - 55ms/step\n", + "Epoch 16/200\n", + "200/200 - 11s - loss: 1.3589e-05 - val_loss: 3.5362e-05 - lr: 1.0000e-04 - 11s/epoch - 56ms/step\n", + "Epoch 17/200\n", + "200/200 - 11s - loss: 1.0888e-05 - val_loss: 2.1600e-05 - lr: 1.0000e-04 - 11s/epoch - 56ms/step\n", + "Epoch 18/200\n", + "200/200 - 11s - loss: 1.0426e-05 - val_loss: 3.6782e-05 - lr: 1.0000e-04 - 11s/epoch - 55ms/step\n", + "Epoch 19/200\n", + "200/200 - 11s - loss: 9.9092e-06 - val_loss: 3.8284e-05 - lr: 1.0000e-04 - 11s/epoch - 56ms/step\n", + "Epoch 20/200\n", + "200/200 - 11s - loss: 8.0018e-06 - val_loss: 2.9439e-05 - lr: 1.0000e-04 - 11s/epoch - 57ms/step\n", + "Epoch 21/200\n", + "200/200 - 11s - loss: 7.7977e-06 - val_loss: 2.8703e-05 - lr: 1.0000e-04 - 11s/epoch - 56ms/step\n", + "Epoch 22/200\n", + "\n", + "Epoch 00022: ReduceLROnPlateau reducing learning rate to 4.999999873689376e-05.\n", + "200/200 - 11s - loss: 6.5981e-06 - val_loss: 3.6030e-05 - lr: 1.0000e-04 - 11s/epoch - 55ms/step\n", + "Epoch 23/200\n", + "200/200 - 11s - loss: 4.6479e-06 - val_loss: 2.8081e-05 - lr: 5.0000e-05 - 11s/epoch - 55ms/step\n", + "Epoch 24/200\n", + "200/200 - 11s - loss: 4.2579e-06 - val_loss: 3.7954e-05 - lr: 5.0000e-05 - 11s/epoch - 55ms/step\n", + "Epoch 25/200\n", + "200/200 - 11s - loss: 3.9628e-06 - val_loss: 2.6399e-05 - lr: 5.0000e-05 - 11s/epoch - 56ms/step\n", + "Epoch 26/200\n", + "200/200 - 11s - loss: 3.6915e-06 - val_loss: 1.9973e-05 - lr: 5.0000e-05 - 11s/epoch - 56ms/step\n", + "Epoch 27/200\n", + "200/200 - 11s - loss: 3.4726e-06 - val_loss: 3.5831e-05 - lr: 5.0000e-05 - 11s/epoch - 55ms/step\n", + "Epoch 28/200\n", + "200/200 - 11s - loss: 3.2110e-06 - val_loss: 2.7290e-05 - lr: 5.0000e-05 - 11s/epoch - 56ms/step\n", + "Epoch 29/200\n", + "200/200 - 11s - loss: 3.3421e-06 - val_loss: 3.1827e-05 - lr: 5.0000e-05 - 11s/epoch - 56ms/step\n", + "Epoch 30/200\n", + "200/200 - 11s - loss: 3.3472e-06 - val_loss: 3.4653e-05 - lr: 5.0000e-05 - 11s/epoch - 56ms/step\n", + "Epoch 31/200\n", + "\n", + "Epoch 00031: ReduceLROnPlateau reducing learning rate to 2.499999936844688e-05.\n", + "200/200 - 11s - loss: 3.1221e-06 - val_loss: 2.7741e-05 - lr: 5.0000e-05 - 11s/epoch - 56ms/step\n", + "Epoch 32/200\n", + "200/200 - 11s - loss: 2.5739e-06 - val_loss: 3.2486e-05 - lr: 2.5000e-05 - 11s/epoch - 55ms/step\n", + "Epoch 33/200\n", + "200/200 - 11s - loss: 2.5589e-06 - val_loss: 3.3135e-05 - lr: 2.5000e-05 - 11s/epoch - 56ms/step\n", + "Epoch 34/200\n", + "200/200 - 11s - loss: 2.4215e-06 - val_loss: 2.8923e-05 - lr: 2.5000e-05 - 11s/epoch - 56ms/step\n", + "Epoch 35/200\n", + "200/200 - 11s - loss: 2.4033e-06 - val_loss: 2.8776e-05 - lr: 2.5000e-05 - 11s/epoch - 56ms/step\n", + "Epoch 36/200\n", + "200/200 - 11s - loss: 2.3358e-06 - val_loss: 2.5874e-05 - lr: 2.5000e-05 - 11s/epoch - 56ms/step\n", + "Epoch 37/200\n", + "200/200 - 11s - loss: 2.2922e-06 - val_loss: 3.6051e-05 - lr: 2.5000e-05 - 11s/epoch - 55ms/step\n", + "Epoch 38/200\n", + "\n", + "Epoch 00038: ReduceLROnPlateau reducing learning rate to 1.249999968422344e-05.\n", + "200/200 - 11s - loss: 2.1278e-06 - val_loss: 2.4898e-05 - lr: 2.5000e-05 - 11s/epoch - 55ms/step\n", + "Epoch 39/200\n", + "200/200 - 11s - loss: 2.0474e-06 - val_loss: 2.8901e-05 - lr: 1.2500e-05 - 11s/epoch - 56ms/step\n", + "Epoch 40/200\n", + "200/200 - 11s - loss: 2.0612e-06 - val_loss: 3.7469e-05 - lr: 1.2500e-05 - 11s/epoch - 56ms/step\n", + "Epoch 41/200\n", + "200/200 - 11s - loss: 1.8414e-06 - val_loss: 2.8496e-05 - lr: 1.2500e-05 - 11s/epoch - 56ms/step\n", + "Epoch 42/200\n", + "200/200 - 11s - loss: 2.0196e-06 - val_loss: 3.5206e-05 - lr: 1.2500e-05 - 11s/epoch - 56ms/step\n", + "Epoch 43/200\n", + "200/200 - 11s - loss: 1.8551e-06 - val_loss: 2.6483e-05 - lr: 1.2500e-05 - 11s/epoch - 56ms/step\n", + "Epoch 44/200\n", + "200/200 - 11s - loss: 1.9705e-06 - val_loss: 2.4643e-05 - lr: 1.2500e-05 - 11s/epoch - 55ms/step\n", + "Epoch 45/200\n", + "\n", + "Epoch 00045: ReduceLROnPlateau reducing learning rate to 6.24999984211172e-06.\n", + "200/200 - 11s - loss: 1.9136e-06 - val_loss: 2.8379e-05 - lr: 1.2500e-05 - 11s/epoch - 56ms/step\n", + "Epoch 46/200\n", + "200/200 - 11s - loss: 1.7911e-06 - val_loss: 4.0055e-05 - lr: 6.2500e-06 - 11s/epoch - 56ms/step\n", + "Epoch 00046: early stopping\n", + "INFO:sleap.nn.training:Finished training loop. [8.7 min]\n", + "INFO:sleap.nn.training:Deleting visualization directory: models/courtship.centroid/viz\n", + "INFO:sleap.nn.training:Saving evaluation metrics to model folder...\n", + "\u001b[2KPredicting... \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[35m100%\u001b[0m ETA: \u001b[36m0:00:00\u001b[0m \u001b[31m33.7 FPS\u001b[0m31m51.9 FPS\u001b[0m31m52.6 FPS\u001b[0mFPS\u001b[0m\n", + "\u001b[?25hINFO:sleap.nn.evals:Saved predictions: models/courtship.centroid/labels_pr.train.slp\n", + "INFO:sleap.nn.evals:Saved metrics: models/courtship.centroid/metrics.train.npz\n", + "INFO:sleap.nn.evals:OKS mAP: 0.725241\n", + "\u001b[2KPredicting... \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[35m100%\u001b[0m ETA: \u001b[36m0:00:00\u001b[0m \u001b[31m7.3 FPS\u001b[0m0:00:01\u001b[0m \u001b[31m184.6 FPS\u001b[0mm\n", + "\u001b[?25hINFO:sleap.nn.evals:Saved predictions: models/courtship.centroid/labels_pr.val.slp\n", + "INFO:sleap.nn.evals:Saved metrics: models/courtship.centroid/metrics.val.npz\n", + "INFO:sleap.nn.evals:OKS mAP: 0.870526\n" + ] + } + ], "source": [ "!sleap-train baseline.centroid.json \"dataset/drosophila-melanogaster-courtship/courtship_labels.slp\" --run_name \"courtship.centroid\" --video-paths \"dataset/drosophila-melanogaster-courtship/20190128_113421.mp4\"" ] @@ -125,11 +552,361 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 26, "metadata": { "id": "ufbULTDw4Hbh" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "INFO:sleap.nn.training:Versions:\n", + "SLEAP: 1.3.2\n", + "TensorFlow: 2.7.0\n", + "Numpy: 1.21.5\n", + "Python: 3.7.12\n", + "OS: Linux-5.15.0-78-generic-x86_64-with-debian-bookworm-sid\n", + "INFO:sleap.nn.training:Training labels file: dataset/drosophila-melanogaster-courtship/courtship_labels.slp\n", + "INFO:sleap.nn.training:Training profile: /home/talmolab/sleap-estimates-animal-poses/pull-requests/sleap/sleap/training_profiles/baseline_medium_rf.topdown.json\n", + "INFO:sleap.nn.training:\n", + "INFO:sleap.nn.training:Arguments:\n", + "INFO:sleap.nn.training:{\n", + " \"training_job_path\": \"baseline_medium_rf.topdown.json\",\n", + " \"labels_path\": \"dataset/drosophila-melanogaster-courtship/courtship_labels.slp\",\n", + " \"video_paths\": [\n", + " \"dataset/drosophila-melanogaster-courtship/20190128_113421.mp4\"\n", + " ],\n", + " \"val_labels\": null,\n", + " \"test_labels\": null,\n", + " \"base_checkpoint\": null,\n", + " \"tensorboard\": false,\n", + " \"save_viz\": false,\n", + " \"zmq\": false,\n", + " \"run_name\": \"courtship.topdown_confmaps\",\n", + " \"prefix\": \"\",\n", + " \"suffix\": \"\",\n", + " \"cpu\": false,\n", + " \"first_gpu\": false,\n", + " \"last_gpu\": false,\n", + " \"gpu\": \"auto\"\n", + "}\n", + "INFO:sleap.nn.training:\n", + "INFO:sleap.nn.training:Training job:\n", + "INFO:sleap.nn.training:{\n", + " \"data\": {\n", + " \"labels\": {\n", + " \"training_labels\": null,\n", + " \"validation_labels\": null,\n", + " \"validation_fraction\": 0.1,\n", + " \"test_labels\": null,\n", + " \"split_by_inds\": false,\n", + " \"training_inds\": null,\n", + " \"validation_inds\": null,\n", + " \"test_inds\": null,\n", + " \"search_path_hints\": [],\n", + " \"skeletons\": []\n", + " },\n", + " \"preprocessing\": {\n", + " \"ensure_rgb\": false,\n", + " \"ensure_grayscale\": false,\n", + " \"imagenet_mode\": null,\n", + " \"input_scaling\": 1.0,\n", + " \"pad_to_stride\": null,\n", + " \"resize_and_pad_to_target\": true,\n", + " \"target_height\": null,\n", + " \"target_width\": null\n", + " },\n", + " \"instance_cropping\": {\n", + " \"center_on_part\": null,\n", + " \"crop_size\": null,\n", + " \"crop_size_detection_padding\": 16\n", + " }\n", + " },\n", + " \"model\": {\n", + " \"backbone\": {\n", + " \"leap\": null,\n", + " \"unet\": {\n", + " \"stem_stride\": null,\n", + " \"max_stride\": 16,\n", + " \"output_stride\": 4,\n", + " \"filters\": 24,\n", + " \"filters_rate\": 2.0,\n", + " \"middle_block\": true,\n", + " \"up_interpolate\": true,\n", + " \"stacks\": 1\n", + " },\n", + " \"hourglass\": null,\n", + " \"resnet\": null,\n", + " \"pretrained_encoder\": null\n", + " },\n", + " \"heads\": {\n", + " \"single_instance\": null,\n", + " \"centroid\": null,\n", + " \"centered_instance\": {\n", + " \"anchor_part\": null,\n", + " \"part_names\": null,\n", + " \"sigma\": 2.5,\n", + " \"output_stride\": 4,\n", + " \"loss_weight\": 1.0,\n", + " \"offset_refinement\": false\n", + " },\n", + " \"multi_instance\": null,\n", + " \"multi_class_bottomup\": null,\n", + " \"multi_class_topdown\": null\n", + " },\n", + " \"base_checkpoint\": null\n", + " },\n", + " \"optimization\": {\n", + " \"preload_data\": true,\n", + " \"augmentation_config\": {\n", + " \"rotate\": true,\n", + " \"rotation_min_angle\": -15.0,\n", + " \"rotation_max_angle\": 15.0,\n", + " \"translate\": false,\n", + " \"translate_min\": -5,\n", + " \"translate_max\": 5,\n", + " \"scale\": false,\n", + " \"scale_min\": 0.9,\n", + " \"scale_max\": 1.1,\n", + " \"uniform_noise\": false,\n", + " \"uniform_noise_min_val\": 0.0,\n", + " \"uniform_noise_max_val\": 10.0,\n", + " \"gaussian_noise\": false,\n", + " \"gaussian_noise_mean\": 5.0,\n", + " \"gaussian_noise_stddev\": 1.0,\n", + " \"contrast\": false,\n", + " \"contrast_min_gamma\": 0.5,\n", + " \"contrast_max_gamma\": 2.0,\n", + " \"brightness\": false,\n", + " \"brightness_min_val\": 0.0,\n", + " \"brightness_max_val\": 10.0,\n", + " \"random_crop\": false,\n", + " \"random_crop_height\": 256,\n", + " \"random_crop_width\": 256,\n", + " \"random_flip\": false,\n", + " \"flip_horizontal\": true\n", + " },\n", + " \"online_shuffling\": true,\n", + " \"shuffle_buffer_size\": 128,\n", + " \"prefetch\": true,\n", + " \"batch_size\": 4,\n", + " \"batches_per_epoch\": null,\n", + " \"min_batches_per_epoch\": 200,\n", + " \"val_batches_per_epoch\": null,\n", + " \"min_val_batches_per_epoch\": 10,\n", + " \"epochs\": 200,\n", + " \"optimizer\": \"adam\",\n", + " \"initial_learning_rate\": 0.0001,\n", + " \"learning_rate_schedule\": {\n", + " \"reduce_on_plateau\": true,\n", + " \"reduction_factor\": 0.5,\n", + " \"plateau_min_delta\": 1e-08,\n", + " \"plateau_patience\": 5,\n", + " \"plateau_cooldown\": 3,\n", + " \"min_learning_rate\": 1e-08\n", + " },\n", + " \"hard_keypoint_mining\": {\n", + " \"online_mining\": false,\n", + " \"hard_to_easy_ratio\": 2.0,\n", + " \"min_hard_keypoints\": 2,\n", + " \"max_hard_keypoints\": null,\n", + " \"loss_scale\": 5.0\n", + " },\n", + " \"early_stopping\": {\n", + " \"stop_training_on_plateau\": true,\n", + " \"plateau_min_delta\": 1e-08,\n", + " \"plateau_patience\": 10\n", + " }\n", + " },\n", + " \"outputs\": {\n", + " \"save_outputs\": true,\n", + " \"run_name\": \"courtship.topdown_confmaps\",\n", + " \"run_name_prefix\": \"\",\n", + " \"run_name_suffix\": null,\n", + " \"runs_folder\": \"models\",\n", + " \"tags\": [],\n", + " \"save_visualizations\": true,\n", + " \"keep_viz_images\": true,\n", + " \"zip_outputs\": false,\n", + " \"log_to_csv\": true,\n", + " \"checkpointing\": {\n", + " \"initial_model\": false,\n", + " \"best_model\": true,\n", + " \"every_epoch\": false,\n", + " \"latest_model\": false,\n", + " \"final_model\": false\n", + " },\n", + " \"tensorboard\": {\n", + " \"write_logs\": false,\n", + " \"loss_frequency\": \"epoch\",\n", + " \"architecture_graph\": true,\n", + " \"profile_graph\": false,\n", + " \"visualizations\": true\n", + " },\n", + " \"zmq\": {\n", + " \"subscribe_to_controller\": false,\n", + " \"controller_address\": \"tcp://127.0.0.1:9000\",\n", + " \"controller_polling_timeout\": 10,\n", + " \"publish_updates\": false,\n", + " \"publish_address\": \"tcp://127.0.0.1:9001\"\n", + " }\n", + " },\n", + " \"name\": \"\",\n", + " \"description\": \"\",\n", + " \"sleap_version\": \"1.3.2\",\n", + " \"filename\": \"/home/talmolab/sleap-estimates-animal-poses/pull-requests/sleap/sleap/training_profiles/baseline_medium_rf.topdown.json\"\n", + "}\n", + "INFO:sleap.nn.training:\n", + "2023-09-01 13:39:43.324520: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:39:43.329181: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:39:43.329961: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "INFO:sleap.nn.training:Auto-selected GPU 0 with 23056 MiB of free memory.\n", + "INFO:sleap.nn.training:Using GPU 0 for acceleration.\n", + "INFO:sleap.nn.training:Disabled GPU memory pre-allocation.\n", + "INFO:sleap.nn.training:System:\n", + "GPUs: 1/1 available\n", + " Device: /physical_device:GPU:0\n", + " Available: True\n", + " Initalized: False\n", + " Memory growth: True\n", + "INFO:sleap.nn.training:\n", + "INFO:sleap.nn.training:Initializing trainer...\n", + "INFO:sleap.nn.training:Loading training labels from: dataset/drosophila-melanogaster-courtship/courtship_labels.slp\n", + "INFO:sleap.nn.training:Creating training and validation splits from validation fraction: 0.1\n", + "INFO:sleap.nn.training: Splits: Training = 134 / Validation = 15.\n", + "INFO:sleap.nn.training:Setting up for training...\n", + "INFO:sleap.nn.training:Setting up pipeline builders...\n", + "INFO:sleap.nn.training:Setting up model...\n", + "INFO:sleap.nn.training:Building test pipeline...\n", + "2023-09-01 13:39:44.254912: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX512F FMA\n", + "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n", + "2023-09-01 13:39:44.255468: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:39:44.256291: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:39:44.257158: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:39:44.546117: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:39:44.546866: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:39:44.547533: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:39:44.548184: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1525] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 21151 MB memory: -> device: 0, name: NVIDIA RTX A5000, pci bus id: 0000:01:00.0, compute capability: 8.6\n", + "INFO:sleap.nn.training:Loaded test example. [1.684s]\n", + "INFO:sleap.nn.training: Input shape: (144, 144, 3)\n", + "INFO:sleap.nn.training:Created Keras model.\n", + "INFO:sleap.nn.training: Backbone: UNet(stacks=1, filters=24, filters_rate=2.0, kernel_size=3, stem_kernel_size=7, convs_per_block=2, stem_blocks=0, down_blocks=4, middle_block=True, up_blocks=2, up_interpolate=True, block_contraction=False)\n", + "INFO:sleap.nn.training: Max stride: 16\n", + "INFO:sleap.nn.training: Parameters: 4,311,877\n", + "INFO:sleap.nn.training: Heads: \n", + "INFO:sleap.nn.training: [0] = CenteredInstanceConfmapsHead(part_names=['head', 'thorax', 'abdomen', 'wingL', 'wingR', 'forelegL4', 'forelegR4', 'midlegL4', 'midlegR4', 'hindlegL4', 'hindlegR4', 'eyeL', 'eyeR'], anchor_part=None, sigma=2.5, output_stride=4, loss_weight=1.0)\n", + "INFO:sleap.nn.training: Outputs: \n", + "INFO:sleap.nn.training: [0] = KerasTensor(type_spec=TensorSpec(shape=(None, 36, 36, 13), dtype=tf.float32, name=None), name='CenteredInstanceConfmapsHead/BiasAdd:0', description=\"created by layer 'CenteredInstanceConfmapsHead'\")\n", + "INFO:sleap.nn.training:Training from scratch\n", + "INFO:sleap.nn.training:Setting up data pipelines...\n", + "INFO:sleap.nn.training:Training set: n = 134\n", + "INFO:sleap.nn.training:Validation set: n = 15\n", + "INFO:sleap.nn.training:Setting up optimization...\n", + "INFO:sleap.nn.training: Learning rate schedule: LearningRateScheduleConfig(reduce_on_plateau=True, reduction_factor=0.5, plateau_min_delta=1e-08, plateau_patience=5, plateau_cooldown=3, min_learning_rate=1e-08)\n", + "INFO:sleap.nn.training: Early stopping: EarlyStoppingConfig(stop_training_on_plateau=True, plateau_min_delta=1e-08, plateau_patience=10)\n", + "INFO:sleap.nn.training:Setting up outputs...\n", + "INFO:sleap.nn.training:Created run path: models/courtship.topdown_confmaps\n", + "INFO:sleap.nn.training:Setting up visualization...\n", + "INFO:sleap.nn.training:Finished trainer set up. [3.2s]\n", + "INFO:sleap.nn.training:Creating tf.data.Datasets for training data generation...\n", + "INFO:sleap.nn.training:Finished creating training datasets. [5.9s]\n", + "INFO:sleap.nn.training:Starting training loop...\n", + "Epoch 1/200\n", + "2023-09-01 13:39:54.940083: I tensorflow/stream_executor/cuda/cuda_dnn.cc:366] Loaded cuDNN version 8201\n", + "2023-09-01 13:40:00.337645: I tensorflow/stream_executor/cuda/cuda_blas.cc:1774] TensorFloat-32 will be used for the matrix multiplication. This will only be logged once.\n", + "200/200 - 8s - loss: 0.0108 - head: 0.0073 - thorax: 0.0067 - abdomen: 0.0111 - wingL: 0.0125 - wingR: 0.0126 - forelegL4: 0.0111 - forelegR4: 0.0108 - midlegL4: 0.0127 - midlegR4: 0.0128 - hindlegL4: 0.0131 - hindlegR4: 0.0131 - eyeL: 0.0082 - eyeR: 0.0083 - val_loss: 0.0087 - val_head: 0.0033 - val_thorax: 0.0039 - val_abdomen: 0.0089 - val_wingL: 0.0105 - val_wingR: 0.0106 - val_forelegL4: 0.0091 - val_forelegR4: 0.0091 - val_midlegL4: 0.0123 - val_midlegR4: 0.0116 - val_hindlegL4: 0.0128 - val_hindlegR4: 0.0116 - val_eyeL: 0.0045 - val_eyeR: 0.0045 - lr: 1.0000e-04 - 8s/epoch - 38ms/step\n", + "Epoch 2/200\n", + "200/200 - 4s - loss: 0.0064 - head: 0.0019 - thorax: 0.0029 - abdomen: 0.0057 - wingL: 0.0061 - wingR: 0.0073 - forelegL4: 0.0075 - forelegR4: 0.0078 - midlegL4: 0.0092 - midlegR4: 0.0092 - hindlegL4: 0.0099 - hindlegR4: 0.0102 - eyeL: 0.0025 - eyeR: 0.0025 - val_loss: 0.0061 - val_head: 0.0015 - val_thorax: 0.0024 - val_abdomen: 0.0049 - val_wingL: 0.0056 - val_wingR: 0.0078 - val_forelegL4: 0.0079 - val_forelegR4: 0.0067 - val_midlegL4: 0.0086 - val_midlegR4: 0.0089 - val_hindlegL4: 0.0093 - val_hindlegR4: 0.0081 - val_eyeL: 0.0037 - val_eyeR: 0.0032 - lr: 1.0000e-04 - 4s/epoch - 19ms/step\n", + "Epoch 3/200\n", + "200/200 - 3s - loss: 0.0048 - head: 8.9048e-04 - thorax: 0.0019 - abdomen: 0.0036 - wingL: 0.0041 - wingR: 0.0051 - forelegL4: 0.0063 - forelegR4: 0.0066 - midlegL4: 0.0076 - midlegR4: 0.0076 - hindlegL4: 0.0076 - hindlegR4: 0.0080 - eyeL: 0.0015 - eyeR: 0.0015 - val_loss: 0.0058 - val_head: 0.0014 - val_thorax: 0.0021 - val_abdomen: 0.0044 - val_wingL: 0.0051 - val_wingR: 0.0070 - val_forelegL4: 0.0072 - val_forelegR4: 0.0063 - val_midlegL4: 0.0088 - val_midlegR4: 0.0085 - val_hindlegL4: 0.0097 - val_hindlegR4: 0.0079 - val_eyeL: 0.0038 - val_eyeR: 0.0032 - lr: 1.0000e-04 - 3s/epoch - 16ms/step\n", + "Epoch 4/200\n", + "200/200 - 3s - loss: 0.0041 - head: 7.6417e-04 - thorax: 0.0015 - abdomen: 0.0028 - wingL: 0.0035 - wingR: 0.0041 - forelegL4: 0.0058 - forelegR4: 0.0060 - midlegL4: 0.0066 - midlegR4: 0.0064 - hindlegL4: 0.0066 - hindlegR4: 0.0070 - eyeL: 0.0013 - eyeR: 0.0012 - val_loss: 0.0048 - val_head: 7.6555e-04 - val_thorax: 0.0013 - val_abdomen: 0.0034 - val_wingL: 0.0042 - val_wingR: 0.0065 - val_forelegL4: 0.0063 - val_forelegR4: 0.0064 - val_midlegL4: 0.0069 - val_midlegR4: 0.0071 - val_hindlegL4: 0.0080 - val_hindlegR4: 0.0062 - val_eyeL: 0.0028 - val_eyeR: 0.0026 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 5/200\n", + "200/200 - 3s - loss: 0.0034 - head: 6.1233e-04 - thorax: 0.0012 - abdomen: 0.0023 - wingL: 0.0028 - wingR: 0.0032 - forelegL4: 0.0052 - forelegR4: 0.0054 - midlegL4: 0.0052 - midlegR4: 0.0051 - hindlegL4: 0.0057 - hindlegR4: 0.0058 - eyeL: 0.0011 - eyeR: 0.0011 - val_loss: 0.0044 - val_head: 9.3809e-04 - val_thorax: 0.0012 - val_abdomen: 0.0027 - val_wingL: 0.0032 - val_wingR: 0.0048 - val_forelegL4: 0.0062 - val_forelegR4: 0.0053 - val_midlegL4: 0.0068 - val_midlegR4: 0.0063 - val_hindlegL4: 0.0067 - val_hindlegR4: 0.0065 - val_eyeL: 0.0035 - val_eyeR: 0.0032 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 6/200\n", + "200/200 - 3s - loss: 0.0028 - head: 5.5957e-04 - thorax: 9.3519e-04 - abdomen: 0.0019 - wingL: 0.0023 - wingR: 0.0025 - forelegL4: 0.0045 - forelegR4: 0.0045 - midlegL4: 0.0040 - midlegR4: 0.0040 - hindlegL4: 0.0047 - hindlegR4: 0.0048 - eyeL: 0.0010 - eyeR: 9.7287e-04 - val_loss: 0.0038 - val_head: 7.6837e-04 - val_thorax: 9.9723e-04 - val_abdomen: 0.0027 - val_wingL: 0.0025 - val_wingR: 0.0046 - val_forelegL4: 0.0058 - val_forelegR4: 0.0049 - val_midlegL4: 0.0054 - val_midlegR4: 0.0058 - val_hindlegL4: 0.0057 - val_hindlegR4: 0.0065 - val_eyeL: 0.0023 - val_eyeR: 0.0022 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 7/200\n", + "200/200 - 3s - loss: 0.0024 - head: 4.7941e-04 - thorax: 7.5772e-04 - abdomen: 0.0017 - wingL: 0.0020 - wingR: 0.0022 - forelegL4: 0.0039 - forelegR4: 0.0041 - midlegL4: 0.0033 - midlegR4: 0.0033 - hindlegL4: 0.0039 - hindlegR4: 0.0040 - eyeL: 9.3055e-04 - eyeR: 8.9191e-04 - val_loss: 0.0036 - val_head: 6.1078e-04 - val_thorax: 0.0010 - val_abdomen: 0.0023 - val_wingL: 0.0025 - val_wingR: 0.0039 - val_forelegL4: 0.0053 - val_forelegR4: 0.0058 - val_midlegL4: 0.0049 - val_midlegR4: 0.0056 - val_hindlegL4: 0.0054 - val_hindlegR4: 0.0049 - val_eyeL: 0.0026 - val_eyeR: 0.0024 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 8/200\n", + "200/200 - 3s - loss: 0.0020 - head: 4.4425e-04 - thorax: 6.8283e-04 - abdomen: 0.0014 - wingL: 0.0015 - wingR: 0.0017 - forelegL4: 0.0035 - forelegR4: 0.0035 - midlegL4: 0.0027 - midlegR4: 0.0026 - hindlegL4: 0.0033 - hindlegR4: 0.0033 - eyeL: 7.7111e-04 - eyeR: 7.2022e-04 - val_loss: 0.0035 - val_head: 7.1555e-04 - val_thorax: 9.1508e-04 - val_abdomen: 0.0022 - val_wingL: 0.0023 - val_wingR: 0.0033 - val_forelegL4: 0.0054 - val_forelegR4: 0.0049 - val_midlegL4: 0.0049 - val_midlegR4: 0.0052 - val_hindlegL4: 0.0052 - val_hindlegR4: 0.0051 - val_eyeL: 0.0025 - val_eyeR: 0.0025 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 9/200\n", + "200/200 - 3s - loss: 0.0017 - head: 3.8990e-04 - thorax: 5.4963e-04 - abdomen: 0.0012 - wingL: 0.0012 - wingR: 0.0014 - forelegL4: 0.0030 - forelegR4: 0.0031 - midlegL4: 0.0022 - midlegR4: 0.0022 - hindlegL4: 0.0027 - hindlegR4: 0.0027 - eyeL: 6.9041e-04 - eyeR: 6.7679e-04 - val_loss: 0.0034 - val_head: 5.6666e-04 - val_thorax: 7.9156e-04 - val_abdomen: 0.0023 - val_wingL: 0.0020 - val_wingR: 0.0041 - val_forelegL4: 0.0043 - val_forelegR4: 0.0048 - val_midlegL4: 0.0041 - val_midlegR4: 0.0051 - val_hindlegL4: 0.0053 - val_hindlegR4: 0.0052 - val_eyeL: 0.0024 - val_eyeR: 0.0026 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 10/200\n", + "200/200 - 3s - loss: 0.0015 - head: 3.6281e-04 - thorax: 5.2471e-04 - abdomen: 0.0010 - wingL: 0.0011 - wingR: 0.0012 - forelegL4: 0.0027 - forelegR4: 0.0028 - midlegL4: 0.0019 - midlegR4: 0.0019 - hindlegL4: 0.0023 - hindlegR4: 0.0024 - eyeL: 7.0986e-04 - eyeR: 6.9581e-04 - val_loss: 0.0024 - val_head: 4.8376e-04 - val_thorax: 6.2502e-04 - val_abdomen: 0.0016 - val_wingL: 0.0014 - val_wingR: 0.0027 - val_forelegL4: 0.0035 - val_forelegR4: 0.0033 - val_midlegL4: 0.0028 - val_midlegR4: 0.0041 - val_hindlegL4: 0.0036 - val_hindlegR4: 0.0038 - val_eyeL: 0.0015 - val_eyeR: 0.0016 - lr: 1.0000e-04 - 3s/epoch - 16ms/step\n", + "Epoch 11/200\n", + "200/200 - 3s - loss: 0.0013 - head: 3.1183e-04 - thorax: 4.7891e-04 - abdomen: 9.4567e-04 - wingL: 9.6811e-04 - wingR: 0.0011 - forelegL4: 0.0023 - forelegR4: 0.0025 - midlegL4: 0.0016 - midlegR4: 0.0016 - hindlegL4: 0.0020 - hindlegR4: 0.0021 - eyeL: 5.7635e-04 - eyeR: 5.3648e-04 - val_loss: 0.0028 - val_head: 5.2940e-04 - val_thorax: 6.6554e-04 - val_abdomen: 0.0020 - val_wingL: 0.0013 - val_wingR: 0.0024 - val_forelegL4: 0.0041 - val_forelegR4: 0.0041 - val_midlegL4: 0.0034 - val_midlegR4: 0.0042 - val_hindlegL4: 0.0047 - val_hindlegR4: 0.0040 - val_eyeL: 0.0025 - val_eyeR: 0.0022 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 12/200\n", + "200/200 - 3s - loss: 0.0011 - head: 2.8863e-04 - thorax: 4.2604e-04 - abdomen: 8.0488e-04 - wingL: 8.1238e-04 - wingR: 8.5798e-04 - forelegL4: 0.0021 - forelegR4: 0.0021 - midlegL4: 0.0014 - midlegR4: 0.0014 - hindlegL4: 0.0017 - hindlegR4: 0.0018 - eyeL: 5.1007e-04 - eyeR: 4.5654e-04 - val_loss: 0.0031 - val_head: 8.1802e-04 - val_thorax: 7.9789e-04 - val_abdomen: 0.0018 - val_wingL: 0.0014 - val_wingR: 0.0028 - val_forelegL4: 0.0040 - val_forelegR4: 0.0048 - val_midlegL4: 0.0057 - val_midlegR4: 0.0037 - val_hindlegL4: 0.0053 - val_hindlegR4: 0.0050 - val_eyeL: 0.0020 - val_eyeR: 0.0018 - lr: 1.0000e-04 - 3s/epoch - 14ms/step\n", + "Epoch 13/200\n", + "200/200 - 3s - loss: 0.0010 - head: 2.8818e-04 - thorax: 4.1018e-04 - abdomen: 7.8027e-04 - wingL: 7.8017e-04 - wingR: 8.4529e-04 - forelegL4: 0.0019 - forelegR4: 0.0019 - midlegL4: 0.0013 - midlegR4: 0.0013 - hindlegL4: 0.0015 - hindlegR4: 0.0016 - eyeL: 4.6272e-04 - eyeR: 4.3265e-04 - val_loss: 0.0026 - val_head: 3.5806e-04 - val_thorax: 6.6352e-04 - val_abdomen: 0.0017 - val_wingL: 0.0015 - val_wingR: 0.0037 - val_forelegL4: 0.0036 - val_forelegR4: 0.0042 - val_midlegL4: 0.0034 - val_midlegR4: 0.0032 - val_hindlegL4: 0.0041 - val_hindlegR4: 0.0047 - val_eyeL: 0.0013 - val_eyeR: 0.0013 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 14/200\n", + "200/200 - 3s - loss: 9.4029e-04 - head: 2.8339e-04 - thorax: 3.6739e-04 - abdomen: 7.0118e-04 - wingL: 7.4831e-04 - wingR: 7.1158e-04 - forelegL4: 0.0017 - forelegR4: 0.0017 - midlegL4: 0.0012 - midlegR4: 0.0011 - hindlegL4: 0.0014 - hindlegR4: 0.0015 - eyeL: 4.2793e-04 - eyeR: 4.1400e-04 - val_loss: 0.0024 - val_head: 3.4292e-04 - val_thorax: 7.1119e-04 - val_abdomen: 0.0014 - val_wingL: 0.0013 - val_wingR: 0.0028 - val_forelegL4: 0.0030 - val_forelegR4: 0.0043 - val_midlegL4: 0.0031 - val_midlegR4: 0.0030 - val_hindlegL4: 0.0039 - val_hindlegR4: 0.0038 - val_eyeL: 0.0017 - val_eyeR: 0.0015 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 15/200\n", + "200/200 - 3s - loss: 7.8295e-04 - head: 2.3028e-04 - thorax: 3.3006e-04 - abdomen: 5.9391e-04 - wingL: 5.8825e-04 - wingR: 6.0989e-04 - forelegL4: 0.0015 - forelegR4: 0.0015 - midlegL4: 9.6945e-04 - midlegR4: 9.3611e-04 - hindlegL4: 0.0011 - hindlegR4: 0.0012 - eyeL: 3.4493e-04 - eyeR: 3.1164e-04 - val_loss: 0.0019 - val_head: 4.4152e-04 - val_thorax: 5.4500e-04 - val_abdomen: 0.0013 - val_wingL: 0.0012 - val_wingR: 0.0026 - val_forelegL4: 0.0024 - val_forelegR4: 0.0037 - val_midlegL4: 0.0024 - val_midlegR4: 0.0024 - val_hindlegL4: 0.0030 - val_hindlegR4: 0.0030 - val_eyeL: 0.0011 - val_eyeR: 0.0011 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 16/200\n", + "200/200 - 3s - loss: 7.3208e-04 - head: 2.3573e-04 - thorax: 3.0631e-04 - abdomen: 5.5007e-04 - wingL: 5.3431e-04 - wingR: 5.9773e-04 - forelegL4: 0.0013 - forelegR4: 0.0014 - midlegL4: 9.1004e-04 - midlegR4: 8.7803e-04 - hindlegL4: 0.0010 - hindlegR4: 0.0011 - eyeL: 3.3279e-04 - eyeR: 2.9841e-04 - val_loss: 0.0023 - val_head: 3.5381e-04 - val_thorax: 7.0128e-04 - val_abdomen: 0.0015 - val_wingL: 0.0013 - val_wingR: 0.0022 - val_forelegL4: 0.0031 - val_forelegR4: 0.0041 - val_midlegL4: 0.0033 - val_midlegR4: 0.0028 - val_hindlegL4: 0.0036 - val_hindlegR4: 0.0033 - val_eyeL: 0.0017 - val_eyeR: 0.0014 - lr: 1.0000e-04 - 3s/epoch - 14ms/step\n", + "Epoch 17/200\n", + "200/200 - 3s - loss: 6.3161e-04 - head: 2.0100e-04 - thorax: 2.8088e-04 - abdomen: 4.9153e-04 - wingL: 4.7586e-04 - wingR: 4.9866e-04 - forelegL4: 0.0011 - forelegR4: 0.0012 - midlegL4: 7.6100e-04 - midlegR4: 8.0266e-04 - hindlegL4: 8.9697e-04 - hindlegR4: 8.9149e-04 - eyeL: 2.8189e-04 - eyeR: 2.7208e-04 - val_loss: 0.0018 - val_head: 2.8070e-04 - val_thorax: 5.1903e-04 - val_abdomen: 0.0011 - val_wingL: 9.8509e-04 - val_wingR: 0.0025 - val_forelegL4: 0.0022 - val_forelegR4: 0.0026 - val_midlegL4: 0.0025 - val_midlegR4: 0.0021 - val_hindlegL4: 0.0031 - val_hindlegR4: 0.0031 - val_eyeL: 0.0011 - val_eyeR: 9.7838e-04 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 18/200\n", + "200/200 - 3s - loss: 5.7844e-04 - head: 1.9896e-04 - thorax: 2.9112e-04 - abdomen: 4.7495e-04 - wingL: 4.5591e-04 - wingR: 4.5877e-04 - forelegL4: 0.0011 - forelegR4: 0.0012 - midlegL4: 6.9042e-04 - midlegR4: 6.6195e-04 - hindlegL4: 7.9452e-04 - hindlegR4: 7.6819e-04 - eyeL: 2.5989e-04 - eyeR: 2.4763e-04 - val_loss: 0.0018 - val_head: 3.1925e-04 - val_thorax: 6.0394e-04 - val_abdomen: 0.0012 - val_wingL: 9.0835e-04 - val_wingR: 0.0019 - val_forelegL4: 0.0022 - val_forelegR4: 0.0029 - val_midlegL4: 0.0026 - val_midlegR4: 0.0024 - val_hindlegL4: 0.0033 - val_hindlegR4: 0.0022 - val_eyeL: 0.0015 - val_eyeR: 0.0011 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 19/200\n", + "200/200 - 3s - loss: 5.1323e-04 - head: 1.8346e-04 - thorax: 2.5475e-04 - abdomen: 4.2159e-04 - wingL: 4.3027e-04 - wingR: 3.9814e-04 - forelegL4: 9.5814e-04 - forelegR4: 9.9765e-04 - midlegL4: 5.9968e-04 - midlegR4: 5.8423e-04 - hindlegL4: 6.7869e-04 - hindlegR4: 6.9121e-04 - eyeL: 2.4343e-04 - eyeR: 2.3077e-04 - val_loss: 0.0021 - val_head: 3.3346e-04 - val_thorax: 5.9007e-04 - val_abdomen: 0.0014 - val_wingL: 0.0013 - val_wingR: 0.0031 - val_forelegL4: 0.0026 - val_forelegR4: 0.0036 - val_midlegL4: 0.0029 - val_midlegR4: 0.0021 - val_hindlegL4: 0.0037 - val_hindlegR4: 0.0036 - val_eyeL: 0.0011 - val_eyeR: 9.4254e-04 - lr: 1.0000e-04 - 3s/epoch - 14ms/step\n", + "Epoch 20/200\n", + "200/200 - 3s - loss: 4.7991e-04 - head: 1.7328e-04 - thorax: 2.2397e-04 - abdomen: 4.2417e-04 - wingL: 3.9313e-04 - wingR: 3.9871e-04 - forelegL4: 8.8547e-04 - forelegR4: 8.9704e-04 - midlegL4: 5.3515e-04 - midlegR4: 5.8294e-04 - hindlegL4: 6.5212e-04 - hindlegR4: 6.2828e-04 - eyeL: 2.2438e-04 - eyeR: 2.2012e-04 - val_loss: 0.0014 - val_head: 2.7034e-04 - val_thorax: 4.7978e-04 - val_abdomen: 9.7903e-04 - val_wingL: 8.6477e-04 - val_wingR: 0.0020 - val_forelegL4: 0.0018 - val_forelegR4: 0.0024 - val_midlegL4: 0.0019 - val_midlegR4: 0.0018 - val_hindlegL4: 0.0024 - val_hindlegR4: 0.0022 - val_eyeL: 9.9423e-04 - val_eyeR: 8.4541e-04 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 21/200\n", + "200/200 - 3s - loss: 4.4100e-04 - head: 1.6076e-04 - thorax: 2.4080e-04 - abdomen: 3.8343e-04 - wingL: 3.6759e-04 - wingR: 3.7489e-04 - forelegL4: 8.1060e-04 - forelegR4: 8.1600e-04 - midlegL4: 4.7288e-04 - midlegR4: 5.2695e-04 - hindlegL4: 5.6401e-04 - hindlegR4: 6.3519e-04 - eyeL: 1.9033e-04 - eyeR: 1.8954e-04 - val_loss: 0.0018 - val_head: 2.5764e-04 - val_thorax: 5.8718e-04 - val_abdomen: 0.0011 - val_wingL: 9.6939e-04 - val_wingR: 0.0019 - val_forelegL4: 0.0022 - val_forelegR4: 0.0026 - val_midlegL4: 0.0025 - val_midlegR4: 0.0026 - val_hindlegL4: 0.0032 - val_hindlegR4: 0.0028 - val_eyeL: 0.0014 - val_eyeR: 0.0011 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 22/200\n", + "200/200 - 3s - loss: 3.7738e-04 - head: 1.4725e-04 - thorax: 2.0905e-04 - abdomen: 3.2447e-04 - wingL: 3.2224e-04 - wingR: 3.0585e-04 - forelegL4: 6.2169e-04 - forelegR4: 6.7379e-04 - midlegL4: 4.5061e-04 - midlegR4: 4.3931e-04 - hindlegL4: 5.1129e-04 - hindlegR4: 5.2449e-04 - eyeL: 1.9372e-04 - eyeR: 1.8213e-04 - val_loss: 0.0015 - val_head: 2.2947e-04 - val_thorax: 5.4640e-04 - val_abdomen: 9.8293e-04 - val_wingL: 8.6663e-04 - val_wingR: 0.0013 - val_forelegL4: 0.0018 - val_forelegR4: 0.0027 - val_midlegL4: 0.0021 - val_midlegR4: 0.0019 - val_hindlegL4: 0.0027 - val_hindlegR4: 0.0022 - val_eyeL: 0.0013 - val_eyeR: 0.0010 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 23/200\n", + "200/200 - 3s - loss: 3.6084e-04 - head: 1.4440e-04 - thorax: 2.0277e-04 - abdomen: 3.0561e-04 - wingL: 3.0192e-04 - wingR: 2.8845e-04 - forelegL4: 6.3221e-04 - forelegR4: 6.7722e-04 - midlegL4: 3.9143e-04 - midlegR4: 4.3545e-04 - hindlegL4: 5.1985e-04 - hindlegR4: 4.5058e-04 - eyeL: 1.7636e-04 - eyeR: 1.6468e-04 - val_loss: 0.0015 - val_head: 2.9639e-04 - val_thorax: 4.6412e-04 - val_abdomen: 0.0011 - val_wingL: 9.0466e-04 - val_wingR: 0.0021 - val_forelegL4: 0.0015 - val_forelegR4: 0.0025 - val_midlegL4: 0.0018 - val_midlegR4: 0.0016 - val_hindlegL4: 0.0029 - val_hindlegR4: 0.0022 - val_eyeL: 8.7357e-04 - val_eyeR: 7.0067e-04 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 24/200\n", + "200/200 - 3s - loss: 3.4886e-04 - head: 1.4382e-04 - thorax: 1.9157e-04 - abdomen: 3.2551e-04 - wingL: 3.0634e-04 - wingR: 3.0727e-04 - forelegL4: 6.3863e-04 - forelegR4: 6.0904e-04 - midlegL4: 3.5949e-04 - midlegR4: 4.1201e-04 - hindlegL4: 4.2893e-04 - hindlegR4: 4.8121e-04 - eyeL: 1.6669e-04 - eyeR: 1.6464e-04 - val_loss: 0.0022 - val_head: 3.2159e-04 - val_thorax: 7.2743e-04 - val_abdomen: 0.0014 - val_wingL: 0.0011 - val_wingR: 0.0027 - val_forelegL4: 0.0025 - val_forelegR4: 0.0037 - val_midlegL4: 0.0033 - val_midlegR4: 0.0020 - val_hindlegL4: 0.0043 - val_hindlegR4: 0.0031 - val_eyeL: 0.0017 - val_eyeR: 0.0012 - lr: 1.0000e-04 - 3s/epoch - 14ms/step\n", + "Epoch 25/200\n", + "\n", + "Epoch 00025: ReduceLROnPlateau reducing learning rate to 4.999999873689376e-05.\n", + "200/200 - 3s - loss: 3.0444e-04 - head: 1.2563e-04 - thorax: 1.7247e-04 - abdomen: 2.6934e-04 - wingL: 2.5754e-04 - wingR: 2.4728e-04 - forelegL4: 5.8390e-04 - forelegR4: 5.3959e-04 - midlegL4: 3.3003e-04 - midlegR4: 3.6432e-04 - hindlegL4: 4.0270e-04 - hindlegR4: 3.5518e-04 - eyeL: 1.5609e-04 - eyeR: 1.5365e-04 - val_loss: 0.0017 - val_head: 2.5420e-04 - val_thorax: 5.5809e-04 - val_abdomen: 0.0011 - val_wingL: 9.6708e-04 - val_wingR: 0.0022 - val_forelegL4: 0.0018 - val_forelegR4: 0.0033 - val_midlegL4: 0.0025 - val_midlegR4: 0.0017 - val_hindlegL4: 0.0031 - val_hindlegR4: 0.0031 - val_eyeL: 9.8718e-04 - val_eyeR: 8.0263e-04 - lr: 1.0000e-04 - 3s/epoch - 15ms/step\n", + "Epoch 26/200\n", + "200/200 - 3s - loss: 2.3368e-04 - head: 1.1149e-04 - thorax: 1.5177e-04 - abdomen: 2.1763e-04 - wingL: 2.2159e-04 - wingR: 1.9396e-04 - forelegL4: 3.8234e-04 - forelegR4: 3.8248e-04 - midlegL4: 2.7555e-04 - midlegR4: 2.8653e-04 - hindlegL4: 2.7842e-04 - hindlegR4: 2.8074e-04 - eyeL: 1.3157e-04 - eyeR: 1.2374e-04 - val_loss: 0.0017 - val_head: 2.1815e-04 - val_thorax: 5.0063e-04 - val_abdomen: 0.0011 - val_wingL: 8.2248e-04 - val_wingR: 0.0020 - val_forelegL4: 0.0019 - val_forelegR4: 0.0035 - val_midlegL4: 0.0022 - val_midlegR4: 0.0016 - val_hindlegL4: 0.0031 - val_hindlegR4: 0.0022 - val_eyeL: 0.0013 - val_eyeR: 9.8071e-04 - lr: 5.0000e-05 - 3s/epoch - 14ms/step\n", + "Epoch 27/200\n", + "200/200 - 3s - loss: 2.0711e-04 - head: 9.7513e-05 - thorax: 1.4018e-04 - abdomen: 2.0210e-04 - wingL: 1.8693e-04 - wingR: 1.7399e-04 - forelegL4: 3.1753e-04 - forelegR4: 3.7613e-04 - midlegL4: 2.2838e-04 - midlegR4: 2.4643e-04 - hindlegL4: 2.4471e-04 - hindlegR4: 2.4706e-04 - eyeL: 1.1696e-04 - eyeR: 1.1452e-04 - val_loss: 0.0011 - val_head: 1.7855e-04 - val_thorax: 3.7885e-04 - val_abdomen: 7.0074e-04 - val_wingL: 6.4821e-04 - val_wingR: 0.0012 - val_forelegL4: 0.0012 - val_forelegR4: 0.0017 - val_midlegL4: 0.0014 - val_midlegR4: 0.0013 - val_hindlegL4: 0.0019 - val_hindlegR4: 0.0018 - val_eyeL: 8.8941e-04 - val_eyeR: 7.0606e-04 - lr: 5.0000e-05 - 3s/epoch - 15ms/step\n", + "Epoch 28/200\n", + "200/200 - 3s - loss: 1.9539e-04 - head: 9.4716e-05 - thorax: 1.3617e-04 - abdomen: 1.8547e-04 - wingL: 1.8173e-04 - wingR: 1.6716e-04 - forelegL4: 3.2783e-04 - forelegR4: 3.1060e-04 - midlegL4: 2.2172e-04 - midlegR4: 2.2648e-04 - hindlegL4: 2.3846e-04 - hindlegR4: 2.2823e-04 - eyeL: 1.1204e-04 - eyeR: 1.0944e-04 - val_loss: 0.0012 - val_head: 1.9505e-04 - val_thorax: 3.8105e-04 - val_abdomen: 7.7888e-04 - val_wingL: 6.8985e-04 - val_wingR: 0.0016 - val_forelegL4: 0.0015 - val_forelegR4: 0.0020 - val_midlegL4: 0.0017 - val_midlegR4: 0.0011 - val_hindlegL4: 0.0022 - val_hindlegR4: 0.0019 - val_eyeL: 9.1223e-04 - val_eyeR: 7.0778e-04 - lr: 5.0000e-05 - 3s/epoch - 15ms/step\n", + "Epoch 29/200\n", + "200/200 - 3s - loss: 1.8262e-04 - head: 9.2364e-05 - thorax: 1.3126e-04 - abdomen: 1.7625e-04 - wingL: 1.7494e-04 - wingR: 1.5998e-04 - forelegL4: 3.0159e-04 - forelegR4: 2.9470e-04 - midlegL4: 1.9773e-04 - midlegR4: 2.0446e-04 - hindlegL4: 2.0576e-04 - hindlegR4: 2.1560e-04 - eyeL: 1.1218e-04 - eyeR: 1.0720e-04 - val_loss: 0.0015 - val_head: 2.2535e-04 - val_thorax: 4.8031e-04 - val_abdomen: 9.5428e-04 - val_wingL: 7.7468e-04 - val_wingR: 0.0016 - val_forelegL4: 0.0017 - val_forelegR4: 0.0025 - val_midlegL4: 0.0021 - val_midlegR4: 0.0018 - val_hindlegL4: 0.0029 - val_hindlegR4: 0.0019 - val_eyeL: 0.0013 - val_eyeR: 9.6936e-04 - lr: 5.0000e-05 - 3s/epoch - 15ms/step\n", + "Epoch 30/200\n", + "200/200 - 3s - loss: 1.7461e-04 - head: 8.9617e-05 - thorax: 1.2428e-04 - abdomen: 1.7234e-04 - wingL: 1.6780e-04 - wingR: 1.5580e-04 - forelegL4: 2.7324e-04 - forelegR4: 2.8042e-04 - midlegL4: 1.9090e-04 - midlegR4: 2.0420e-04 - hindlegL4: 1.9914e-04 - hindlegR4: 2.0318e-04 - eyeL: 1.0518e-04 - eyeR: 1.0386e-04 - val_loss: 0.0015 - val_head: 1.9058e-04 - val_thorax: 4.9603e-04 - val_abdomen: 0.0011 - val_wingL: 9.7566e-04 - val_wingR: 0.0018 - val_forelegL4: 0.0016 - val_forelegR4: 0.0028 - val_midlegL4: 0.0022 - val_midlegR4: 0.0015 - val_hindlegL4: 0.0028 - val_hindlegR4: 0.0028 - val_eyeL: 9.9699e-04 - val_eyeR: 8.3721e-04 - lr: 5.0000e-05 - 3s/epoch - 15ms/step\n", + "Epoch 31/200\n", + "200/200 - 3s - loss: 1.7064e-04 - head: 8.7373e-05 - thorax: 1.2365e-04 - abdomen: 1.6765e-04 - wingL: 1.5656e-04 - wingR: 1.4505e-04 - forelegL4: 2.7352e-04 - forelegR4: 2.6274e-04 - midlegL4: 1.9639e-04 - midlegR4: 1.9628e-04 - hindlegL4: 2.0323e-04 - hindlegR4: 1.9917e-04 - eyeL: 1.0639e-04 - eyeR: 1.0032e-04 - val_loss: 0.0011 - val_head: 1.7938e-04 - val_thorax: 3.6727e-04 - val_abdomen: 7.7820e-04 - val_wingL: 6.4437e-04 - val_wingR: 0.0014 - val_forelegL4: 0.0014 - val_forelegR4: 0.0020 - val_midlegL4: 0.0016 - val_midlegR4: 0.0010 - val_hindlegL4: 0.0021 - val_hindlegR4: 0.0016 - val_eyeL: 8.0607e-04 - val_eyeR: 6.6172e-04 - lr: 5.0000e-05 - 3s/epoch - 16ms/step\n", + "Epoch 32/200\n", + "\n", + "Epoch 00032: ReduceLROnPlateau reducing learning rate to 2.499999936844688e-05.\n", + "200/200 - 4s - loss: 1.6547e-04 - head: 8.6407e-05 - thorax: 1.1578e-04 - abdomen: 1.6160e-04 - wingL: 1.5752e-04 - wingR: 1.4326e-04 - forelegL4: 2.5855e-04 - forelegR4: 2.8317e-04 - midlegL4: 1.7880e-04 - midlegR4: 1.8021e-04 - hindlegL4: 1.9743e-04 - hindlegR4: 1.8831e-04 - eyeL: 1.0074e-04 - eyeR: 9.9381e-05 - val_loss: 0.0012 - val_head: 1.9257e-04 - val_thorax: 3.7361e-04 - val_abdomen: 7.0451e-04 - val_wingL: 7.8240e-04 - val_wingR: 0.0015 - val_forelegL4: 0.0014 - val_forelegR4: 0.0020 - val_midlegL4: 0.0016 - val_midlegR4: 0.0011 - val_hindlegL4: 0.0020 - val_hindlegR4: 0.0019 - val_eyeL: 8.9328e-04 - val_eyeR: 7.3886e-04 - lr: 5.0000e-05 - 4s/epoch - 18ms/step\n", + "Epoch 33/200\n", + "200/200 - 3s - loss: 1.4767e-04 - head: 8.0575e-05 - thorax: 1.1097e-04 - abdomen: 1.4927e-04 - wingL: 1.4112e-04 - wingR: 1.3113e-04 - forelegL4: 2.1913e-04 - forelegR4: 2.1998e-04 - midlegL4: 1.6045e-04 - midlegR4: 1.6535e-04 - hindlegL4: 1.8091e-04 - hindlegR4: 1.7343e-04 - eyeL: 9.5387e-05 - eyeR: 9.2035e-05 - val_loss: 0.0014 - val_head: 1.9046e-04 - val_thorax: 4.6921e-04 - val_abdomen: 9.4087e-04 - val_wingL: 7.5647e-04 - val_wingR: 0.0015 - val_forelegL4: 0.0015 - val_forelegR4: 0.0025 - val_midlegL4: 0.0020 - val_midlegR4: 0.0015 - val_hindlegL4: 0.0026 - val_hindlegR4: 0.0021 - val_eyeL: 0.0013 - val_eyeR: 0.0010 - lr: 2.5000e-05 - 3s/epoch - 16ms/step\n", + "Epoch 34/200\n", + "200/200 - 3s - loss: 1.4506e-04 - head: 7.9790e-05 - thorax: 1.0771e-04 - abdomen: 1.5052e-04 - wingL: 1.4143e-04 - wingR: 1.2485e-04 - forelegL4: 2.2486e-04 - forelegR4: 2.1619e-04 - midlegL4: 1.6584e-04 - midlegR4: 1.6250e-04 - hindlegL4: 1.6521e-04 - hindlegR4: 1.6717e-04 - eyeL: 9.1550e-05 - eyeR: 8.8112e-05 - val_loss: 0.0013 - val_head: 1.8689e-04 - val_thorax: 3.7203e-04 - val_abdomen: 9.3770e-04 - val_wingL: 7.0190e-04 - val_wingR: 0.0019 - val_forelegL4: 0.0015 - val_forelegR4: 0.0023 - val_midlegL4: 0.0016 - val_midlegR4: 0.0012 - val_hindlegL4: 0.0025 - val_hindlegR4: 0.0022 - val_eyeL: 8.0213e-04 - val_eyeR: 6.5036e-04 - lr: 2.5000e-05 - 3s/epoch - 15ms/step\n", + "Epoch 35/200\n", + "200/200 - 3s - loss: 1.3911e-04 - head: 7.9674e-05 - thorax: 1.0668e-04 - abdomen: 1.4330e-04 - wingL: 1.3906e-04 - wingR: 1.2752e-04 - forelegL4: 1.9657e-04 - forelegR4: 1.9577e-04 - midlegL4: 1.5228e-04 - midlegR4: 1.5642e-04 - hindlegL4: 1.6610e-04 - hindlegR4: 1.6394e-04 - eyeL: 9.1523e-05 - eyeR: 8.9620e-05 - val_loss: 0.0013 - val_head: 1.7511e-04 - val_thorax: 4.2162e-04 - val_abdomen: 9.5009e-04 - val_wingL: 6.7908e-04 - val_wingR: 0.0013 - val_forelegL4: 0.0015 - val_forelegR4: 0.0023 - val_midlegL4: 0.0018 - val_midlegR4: 0.0014 - val_hindlegL4: 0.0027 - val_hindlegR4: 0.0019 - val_eyeL: 0.0012 - val_eyeR: 9.8818e-04 - lr: 2.5000e-05 - 3s/epoch - 16ms/step\n", + "Epoch 36/200\n", + "200/200 - 3s - loss: 1.3697e-04 - head: 7.5207e-05 - thorax: 1.0507e-04 - abdomen: 1.3913e-04 - wingL: 1.3497e-04 - wingR: 1.2511e-04 - forelegL4: 1.9152e-04 - forelegR4: 2.0264e-04 - midlegL4: 1.5207e-04 - midlegR4: 1.5519e-04 - hindlegL4: 1.6368e-04 - hindlegR4: 1.5869e-04 - eyeL: 9.0233e-05 - eyeR: 8.7055e-05 - val_loss: 0.0013 - val_head: 1.8066e-04 - val_thorax: 4.6591e-04 - val_abdomen: 9.9582e-04 - val_wingL: 7.2600e-04 - val_wingR: 0.0012 - val_forelegL4: 0.0015 - val_forelegR4: 0.0022 - val_midlegL4: 0.0019 - val_midlegR4: 0.0015 - val_hindlegL4: 0.0028 - val_hindlegR4: 0.0018 - val_eyeL: 0.0012 - val_eyeR: 9.6224e-04 - lr: 2.5000e-05 - 3s/epoch - 15ms/step\n", + "Epoch 37/200\n", + "200/200 - 3s - loss: 1.3638e-04 - head: 7.6822e-05 - thorax: 1.0531e-04 - abdomen: 1.4107e-04 - wingL: 1.4047e-04 - wingR: 1.2177e-04 - forelegL4: 1.9564e-04 - forelegR4: 1.7970e-04 - midlegL4: 1.5364e-04 - midlegR4: 1.5089e-04 - hindlegL4: 1.6647e-04 - hindlegR4: 1.6322e-04 - eyeL: 9.0198e-05 - eyeR: 8.7722e-05 - val_loss: 0.0017 - val_head: 2.3218e-04 - val_thorax: 5.3881e-04 - val_abdomen: 0.0011 - val_wingL: 0.0010 - val_wingR: 0.0019 - val_forelegL4: 0.0021 - val_forelegR4: 0.0028 - val_midlegL4: 0.0025 - val_midlegR4: 0.0016 - val_hindlegL4: 0.0033 - val_hindlegR4: 0.0029 - val_eyeL: 0.0015 - val_eyeR: 0.0012 - lr: 2.5000e-05 - 3s/epoch - 16ms/step\n", + "Epoch 00037: early stopping\n", + "INFO:sleap.nn.training:Finished training loop. [2.0 min]\n", + "INFO:sleap.nn.training:Deleting visualization directory: models/courtship.topdown_confmaps/viz\n", + "INFO:sleap.nn.training:Saving evaluation metrics to model folder...\n", + "\u001b[2KPredicting... \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[35m100%\u001b[0m ETA: \u001b[36m0:00:00\u001b[0m \u001b[31m39.3 FPS\u001b[0m31m48.8 FPS\u001b[0m31m49.5 FPS\u001b[0mFPS\u001b[0m\n", + "\u001b[?25hINFO:sleap.nn.evals:Saved predictions: models/courtship.topdown_confmaps/labels_pr.train.slp\n", + "INFO:sleap.nn.evals:Saved metrics: models/courtship.topdown_confmaps/metrics.train.npz\n", + "INFO:sleap.nn.evals:OKS mAP: 0.899237\n", + "\u001b[2KPredicting... \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[35m100%\u001b[0m ETA: \u001b[36m0:00:00\u001b[0m \u001b[31m14.2 FPS\u001b[0m0:00:01\u001b[0m \u001b[31m270.2 FPS\u001b[0mm\n", + "\u001b[?25hINFO:sleap.nn.evals:Saved predictions: models/courtship.topdown_confmaps/labels_pr.val.slp\n", + "INFO:sleap.nn.evals:Saved metrics: models/courtship.topdown_confmaps/metrics.val.npz\n", + "INFO:sleap.nn.evals:OKS mAP: 0.691378\n" + ] + } + ], "source": [ "!sleap-train baseline_medium_rf.topdown.json \"dataset/drosophila-melanogaster-courtship/courtship_labels.slp\" --run_name \"courtship.topdown_confmaps\" --video-paths \"dataset/drosophila-melanogaster-courtship/20190128_113421.mp4\"" ] @@ -145,7 +922,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 27, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -159,23 +936,31 @@ "name": "stdout", "output_type": "stream", "text": [ - "models/\n", - "├── courtship.centroid\n", + "\u001b[01;34mmodels/\u001b[00m\n", + "├── \u001b[01;34mcourtship.centroid\u001b[00m\n", "│   ├── best_model.h5\n", "│   ├── initial_config.json\n", "│   ├── labels_gt.train.slp\n", "│   ├── labels_gt.val.slp\n", + "│   ├── labels_pr.train.slp\n", + "│   ├── labels_pr.val.slp\n", + "│   ├── metrics.train.npz\n", + "│   ├── metrics.val.npz\n", "│   ├── training_config.json\n", "│   └── training_log.csv\n", - "└── courtship.topdown_confmaps\n", + "└── \u001b[01;34mcourtship.topdown_confmaps\u001b[00m\n", " ├── best_model.h5\n", " ├── initial_config.json\n", " ├── labels_gt.train.slp\n", " ├── labels_gt.val.slp\n", + " ├── labels_pr.train.slp\n", + " ├── labels_pr.val.slp\n", + " ├── metrics.train.npz\n", + " ├── metrics.val.npz\n", " ├── training_config.json\n", " └── training_log.csv\n", "\n", - "2 directories, 12 files\n" + "2 directories, 20 files\n" ] } ], @@ -195,11 +980,117 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 28, "metadata": { "id": "CLtjtq9E1Znr" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Started inference at: 2023-09-01 13:42:03.066840\n", + "Args:\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'data_path'\u001b[0m: \u001b[32m'dataset/drosophila-melanogaster-courtship/20190128_113421.mp4'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'models'\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'models/courtship.centroid'\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'models/courtship.topdown_confmaps'\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'frames'\u001b[0m: \u001b[32m'0-100'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'only_labeled_frames'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'only_suggested_frames'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'output'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'no_empty_frames'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'verbosity'\u001b[0m: \u001b[32m'rich'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'video.dataset'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'video.input_format'\u001b[0m: \u001b[32m'channels_last'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'video.index'\u001b[0m: \u001b[32m''\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'cpu'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'first_gpu'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'last_gpu'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'gpu'\u001b[0m: \u001b[32m'auto'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'max_edge_length_ratio'\u001b[0m: \u001b[1;36m0.25\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'dist_penalty_weight'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'batch_size'\u001b[0m: \u001b[1;36m4\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'open_in_gui'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'peak_threshold'\u001b[0m: \u001b[1;36m0.2\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'max_instances'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.tracker'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.target_instance_count'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.pre_cull_to_target'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.pre_cull_iou_threshold'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.post_connect_single_breaks'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.clean_instance_count'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.clean_iou_threshold'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.similarity'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.match'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.robust'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.track_window'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.min_new_track_points'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.min_match_points'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.img_scale'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.of_window_size'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.of_max_levels'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.save_shifted_instances'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.kf_node_indices'\u001b[0m: \u001b[3;35mNone\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'tracking.kf_init_frame_count'\u001b[0m: \u001b[3;35mNone\u001b[0m\n", + "\u001b[1m}\u001b[0m\n", + "\n", + "2023-09-01 13:42:03.098811: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:42:03.103255: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:42:03.103982: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "INFO:sleap.nn.inference:Auto-selected GPU 0 with 23050 MiB of free memory.\n", + "Versions:\n", + "SLEAP: 1.3.2\n", + "TensorFlow: 2.7.0\n", + "Numpy: 1.21.5\n", + "Python: 3.7.12\n", + "OS: Linux-5.15.0-78-generic-x86_64-with-debian-bookworm-sid\n", + "\n", + "System:\n", + "GPUs: 1/1 available\n", + " Device: /physical_device:GPU:0\n", + " Available: True\n", + " Initalized: False\n", + " Memory growth: True\n", + "\n", + "Video: dataset/drosophila-melanogaster-courtship/20190128_113421.mp4\n", + "2023-09-01 13:42:03.157392: I tensorflow/core/platform/cpu_feature_guard.cc:151] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX2 AVX512F FMA\n", + "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n", + "2023-09-01 13:42:03.158019: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:42:03.158864: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:42:03.159656: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:42:03.455402: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:42:03.456138: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:42:03.456803: I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:939] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero\n", + "2023-09-01 13:42:03.457464: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1525] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 21145 MB memory: -> device: 0, name: NVIDIA RTX A5000, pci bus id: 0000:01:00.0, compute capability: 8.6\n", + "\u001b[2KPredicting... \u001b[38;5;237m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[35m 0%\u001b[0m ETA: \u001b[36m-:--:--\u001b[0m \u001b[31m?\u001b[0m2023-09-01 13:42:07.038687: I tensorflow/stream_executor/cuda/cuda_dnn.cc:366] Loaded cuDNN version 8201\n", + "\u001b[2KPredicting... \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[35m100%\u001b[0m ETA: \u001b[36m0:00:00\u001b[0m \u001b[31m51.9 FPS\u001b[0m[0m \u001b[31m126.4 FPS\u001b[0m FPS\u001b[0mFPS\u001b[0m\n", + "\u001b[?25hFinished inference at: 2023-09-01 13:42:10.842469\n", + "Total runtime: 7.775644779205322 secs\n", + "Predicted frames: 101/101\n", + "Provenance:\n", + "\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'model_paths'\u001b[0m: \u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'models/courtship.centroid/training_config.json'\u001b[0m,\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[32m'models/courtship.topdown_confmaps/training_config.json'\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'predictor'\u001b[0m: \u001b[32m'TopDownPredictor'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'sleap_version'\u001b[0m: \u001b[32m'1.3.2'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'platform'\u001b[0m: \u001b[32m'Linux-5.15.0-78-generic-x86_64-with-debian-bookworm-sid'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'command'\u001b[0m: \u001b[32m'/home/talmolab/micromamba/envs/s0/bin/sleap-track dataset/drosophila-melanogaster-courtship/20190128_113421.mp4 --frames 0-100 -m models/courtship.centroid -m models/courtship.topdown_confmaps'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'data_path'\u001b[0m: \u001b[32m'dataset/drosophila-melanogaster-courtship/20190128_113421.mp4'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'output_path'\u001b[0m: \u001b[32m'dataset/drosophila-melanogaster-courtship/20190128_113421.mp4.predictions.slp'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'total_elapsed'\u001b[0m: \u001b[1;36m7.775644779205322\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'start_timestamp'\u001b[0m: \u001b[32m'2023-09-01 13:42:03.066840'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[32m'finish_timestamp'\u001b[0m: \u001b[32m'2023-09-01 13:42:10.842469'\u001b[0m\n", + "\u001b[1m}\u001b[0m\n", + "\n", + "Saved output: dataset/drosophila-melanogaster-courtship/20190128_113421.mp4.predictions.slp\n" + ] + } + ], "source": [ "!sleap-track \"dataset/drosophila-melanogaster-courtship/20190128_113421.mp4\" --frames 0-100 -m \"models/courtship.centroid\" -m \"models/courtship.topdown_confmaps\"" ] @@ -215,7 +1106,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 29, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -229,11 +1120,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "dataset/drosophila-melanogaster-courtship\n", - "├── 20190128_113421.mp4\n", + "\u001b[01;34mdataset/drosophila-melanogaster-courtship\u001b[00m\n", + "├── \u001b[01;32m20190128_113421.mp4\u001b[00m\n", "├── 20190128_113421.mp4.predictions.slp\n", - "├── courtship_labels.slp\n", - "└── example.jpg\n", + "├── \u001b[01;32mcourtship_labels.slp\u001b[00m\n", + "└── \u001b[01;35mexample.jpg\u001b[00m\n", "\n", "0 directories, 4 files\n" ] @@ -254,11 +1145,41 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 30, "metadata": { "id": "-jbVP_s06hMh" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Labeled frames: 101\n", + "Tracks: 0\n", + "Video files:\n", + " dataset/drosophila-melanogaster-courtship/20190128_113421.mp4\n", + " labeled frames: 101\n", + " labeled frames from 0 to 100\n", + " user labeled frames: 0\n", + " tracks: 1\n", + " max instances in frame: 2\n", + "Total user labeled frames: 0\n", + "\n", + "Provenance:\n", + " model_paths: ['models/courtship.centroid/training_config.json', 'models/courtship.topdown_confmaps/training_config.json']\n", + " predictor: TopDownPredictor\n", + " sleap_version: 1.3.2\n", + " platform: Linux-5.15.0-78-generic-x86_64-with-debian-bookworm-sid\n", + " command: /home/talmolab/micromamba/envs/s0/bin/sleap-track dataset/drosophila-melanogaster-courtship/20190128_113421.mp4 --frames 0-100 -m models/courtship.centroid -m models/courtship.topdown_confmaps\n", + " data_path: dataset/drosophila-melanogaster-courtship/20190128_113421.mp4\n", + " output_path: dataset/drosophila-melanogaster-courtship/20190128_113421.mp4.predictions.slp\n", + " total_elapsed: 7.775644779205322\n", + " start_timestamp: 2023-09-01 13:42:03.066840\n", + " finish_timestamp: 2023-09-01 13:42:10.842469\n", + " args: {'data_path': 'dataset/drosophila-melanogaster-courtship/20190128_113421.mp4', 'models': ['models/courtship.centroid', 'models/courtship.topdown_confmaps'], 'frames': '0-100', 'only_labeled_frames': False, 'only_suggested_frames': False, 'output': None, 'no_empty_frames': False, 'verbosity': 'rich', 'video.dataset': None, 'video.input_format': 'channels_last', 'video.index': '', 'cpu': False, 'first_gpu': False, 'last_gpu': False, 'gpu': 'auto', 'max_edge_length_ratio': 0.25, 'dist_penalty_weight': 1.0, 'batch_size': 4, 'open_in_gui': False, 'peak_threshold': 0.2, 'max_instances': None, 'tracking.tracker': None, 'tracking.target_instance_count': None, 'tracking.pre_cull_to_target': None, 'tracking.pre_cull_iou_threshold': None, 'tracking.post_connect_single_breaks': None, 'tracking.clean_instance_count': None, 'tracking.clean_iou_threshold': None, 'tracking.similarity': None, 'tracking.match': None, 'tracking.robust': None, 'tracking.track_window': None, 'tracking.min_new_track_points': None, 'tracking.min_match_points': None, 'tracking.img_scale': None, 'tracking.of_window_size': None, 'tracking.of_max_levels': None, 'tracking.save_shifted_instances': None, 'tracking.kf_node_indices': None, 'tracking.kf_init_frame_count': None}\n" + ] + } + ], "source": [ "!sleap-inspect dataset/drosophila-melanogaster-courtship/20190128_113421.mp4.predictions.slp" ] @@ -274,11 +1195,41 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 31, "metadata": { "id": "Ej2it8dl_BO_" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " adding: models/ (stored 0%)\n", + " adding: models/courtship.topdown_confmaps/ (stored 0%)\n", + " adding: models/courtship.topdown_confmaps/labels_pr.val.slp (deflated 74%)\n", + " adding: models/courtship.topdown_confmaps/metrics.val.npz (deflated 0%)\n", + " adding: models/courtship.topdown_confmaps/labels_pr.train.slp (deflated 67%)\n", + " adding: models/courtship.topdown_confmaps/labels_gt.val.slp (deflated 72%)\n", + " adding: models/courtship.topdown_confmaps/initial_config.json (deflated 73%)\n", + " adding: models/courtship.topdown_confmaps/training_log.csv (deflated 55%)\n", + " adding: models/courtship.topdown_confmaps/metrics.train.npz (deflated 0%)\n", + " adding: models/courtship.topdown_confmaps/labels_gt.train.slp (deflated 61%)\n", + " adding: models/courtship.topdown_confmaps/best_model.h5 (deflated 8%)\n", + " adding: models/courtship.topdown_confmaps/training_config.json (deflated 88%)\n", + " adding: models/courtship.centroid/ (stored 0%)\n", + " adding: models/courtship.centroid/labels_pr.val.slp (deflated 82%)\n", + " adding: models/courtship.centroid/metrics.val.npz (deflated 1%)\n", + " adding: models/courtship.centroid/labels_pr.train.slp (deflated 79%)\n", + " adding: models/courtship.centroid/labels_gt.val.slp (deflated 73%)\n", + " adding: models/courtship.centroid/initial_config.json (deflated 74%)\n", + " adding: models/courtship.centroid/training_log.csv (deflated 57%)\n", + " adding: models/courtship.centroid/metrics.train.npz (deflated 0%)\n", + " adding: models/courtship.centroid/labels_gt.train.slp (deflated 61%)\n", + " adding: models/courtship.centroid/best_model.h5 (deflated 7%)\n", + " adding: models/courtship.centroid/training_config.json (deflated 88%)\n" + ] + } + ], "source": [ "# Zip up the models directory\n", "!zip -r trained_models.zip models/\n", @@ -299,7 +1250,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 33, "metadata": { "id": "gdXCYnRV_omC" }, @@ -343,7 +1294,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.12" + "version": "3.7.12" } }, "nbformat": 4, diff --git a/docs/notebooks/Training_and_inference_using_Google_Drive.ipynb b/docs/notebooks/Training_and_inference_using_Google_Drive.ipynb index 26e836a32..1e871861d 100644 --- a/docs/notebooks/Training_and_inference_using_Google_Drive.ipynb +++ b/docs/notebooks/Training_and_inference_using_Google_Drive.ipynb @@ -37,7 +37,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -46,10 +46,20 @@ "id": "DUfnkxMtLcK3", "outputId": "988097ae-e996-4b81-eb06-ec85aa0b2d9d" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[31mERROR: Cannot uninstall opencv-python 4.6.0, RECORD file not found. Hint: The package was installed by conda.\u001b[0m\u001b[31m\n", + "\u001b[0m\u001b[31mERROR: Cannot uninstall shiboken2 5.15.6, RECORD file not found. You might be able to recover from this via: 'pip install --force-reinstall --no-deps shiboken2==5.15.6'.\u001b[0m\u001b[31m\n", + "\u001b[0m" + ] + } + ], "source": [ - "!pip uninstall -y opencv-python opencv-contrib-python\n", - "!pip install sleap" + "!pip uninstall -qqq -y opencv-python opencv-contrib-python\n", + "!pip install -qqq \"sleap[pypi]>=1.3.3\"" ] }, { @@ -356,7 +366,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.12" + "version": "3.7.12" } }, "nbformat": 4, diff --git a/docs/utils.py b/docs/utils.py index 2d5bf1969..141189601 100644 --- a/docs/utils.py +++ b/docs/utils.py @@ -23,7 +23,7 @@ def find_source_file(obj, root_obj): # Get relative filename fn = os.path.relpath( inspect.getsourcefile(obj), - start=os.path.dirname(os.path.dirname(root_obj.__file__)) + start=os.path.dirname(os.path.dirname(root_obj.__file__)), ).replace("\\", "/") return fn @@ -32,7 +32,7 @@ def find_source_lines(obj): # Find line numbers source_code, from_line = inspect.getsourcelines(obj) to_line = from_line + len(source_code) - 1 - + return from_line, to_line @@ -40,14 +40,14 @@ def resolve(module, fullname): if fullname == "": # Submodule specified, just infer path from the module name. return module.replace(".", "/") + ".py" - + # Search for member within module. member = find_member(sys.modules[module], fullname) - + if member is None: # Member not found, so we won't be linking this. return None - + try: fn = find_source_file(member, sleap) except TypeError: @@ -56,4 +56,3 @@ def resolve(module, fullname): from_line, to_line = find_source_lines(member) return f"{fn}#L{from_line}-L{to_line}" - diff --git a/environment.yml b/environment.yml index 433092fd3..d8f752759 100644 --- a/environment.yml +++ b/environment.yml @@ -1,23 +1,52 @@ +# Use this environment file if your computer has a nvidia GPU and runs Windows or Linux. + name: sleap +channels: + - conda-forge + - nvidia + - sleap + - anaconda + dependencies: - - python=3.7 - - conda-forge::numpy>=1.19.5,<=1.21.5 - # - conda-forge::tensorflow>=2.6.3,<=2.7.1 - - conda-forge::pyside2>=5.13.2,<=5.14.1 - - conda-forge::h5py=3.1.0 - - conda-forge::scipy>=1.4.1,<=1.7.3 - - pillow=8.4.0 - - shapely=1.7.1 - - conda-forge::pandas - - ffmpeg - - cudatoolkit=11.3.1 - - cudnn=8.2.1 - - nvidia::cuda-nvcc=11.3 - # - sleap::tensorflow=2.7.0 - # - sleap::pyside2=5.14.1 - - qtpy>=2.0.1 - - conda-forge::pip!=22.0.4 - - pip: - - "--editable=." - - "--requirement=./dev_requirements.txt" + # Packages SLEAP uses directly + - conda-forge::attrs >=21.2.0 + - conda-forge::cattrs ==1.1.1 + - conda-forge::imageio-ffmpeg # Required for imageio to read/write videos with ffmpeg + - conda-forge::jsmin + - conda-forge::jsonpickle ==1.2 + - conda-forge::networkx + - anaconda::numpy >=1.19.5,<1.23.0 + - conda-forge::opencv <4.9.0 + - conda-forge::h5py <=3.7.0 + - conda-forge::pandas + - conda-forge::pip + - conda-forge::pillow #>=8.3.1,<=8.4.0 + - conda-forge::psutil + - conda-forge::pykalman + - conda-forge::pyside2 >=5.12 # To ensure application works correctly with QtPy. + - conda-forge::python ~=3.7 # Run into _MAX_WINDOWS_WORKERS not found if == + - conda-forge::python-rapidjson + - conda-forge::pyyaml + - conda-forge::pyzmq + - conda-forge::qtpy >=2.0.1 + - conda-forge::rich + - conda-forge::scipy >=1.4.1,<=1.9.0 + - conda-forge::scikit-image + - conda-forge::scikit-learn ==1.0 + - conda-forge::scikit-video + - conda-forge::seaborn + - sleap/label/dev::tensorflow ==2.7.0 # TODO: Switch to main label when updated + - conda-forge::tensorflow-hub # Pinned in meta.yml, but no problems here... yet + - conda-forge::qudida + - conda-forge::albumentations + - conda-forge::ndx-pose <0.2.0 + + # Packages required by tensorflow to find/use GPUs + - conda-forge::cudatoolkit ==11.3.1 + # "==" results in package not found + - conda-forge::cudnn=8.2.1 + - nvidia::cuda-nvcc=11.3 + + - pip: + - "--editable=.[conda_dev]" diff --git a/environment_build.yml b/environment_build.yml index 3f00fecba..b7d6c1ac2 100644 --- a/environment_build.yml +++ b/environment_build.yml @@ -1,24 +1,12 @@ -name: sleap +name: sleap_ci + +channels: + - conda-forge + - anaconda dependencies: - - python=3.7 - - conda-forge::numpy=1.19.5 - - sleap::tensorflow=2.6.3 - - conda-forge::pyside2=5.13.2 - - conda-forge::h5py=3.1.0 - - conda-forge::scipy=1.7.3 - - pillow=8.4.0 - - shapely=1.7.1 - - conda-forge::pandas - - ffmpeg - # - cudatoolkit=11.3.1 - # - cudnn=8.2.1 - # - nvidia::cuda-nvcc=11.3 - - qtpy>=2.0.1 - - conda-build=3.21.7 + # Needed for the build + - conda-build - anaconda-client - conda-verify - - conda-forge::pip!=22.0.4 - - pip: - - "." - - "--requirement=./dev_requirements.txt" \ No newline at end of file + - twine diff --git a/environment_m1.yml b/environment_m1.yml deleted file mode 100644 index 1002cbd4f..000000000 --- a/environment_m1.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: sleap - -channels: - - conda-forge - - defaults - -dependencies: - - python=3.9 - - shapely=1.7.1 - - conda-forge::h5py=3.6.0 - - conda-forge::numpy=1.22.3 - - scipy=1.7.3 - - apple::tensorflow-deps=2.9.0 - - conda-forge::pyside2=5.15.5 - - conda-forge::opencv=4.6.0 - - qtpy>=2.0.1 - - pip - - pip: - - "--editable=./" - - "--requirement=./dev_requirements.txt" \ No newline at end of file diff --git a/environment_mac.yml b/environment_mac.yml index 21e403992..2026154fa 100644 --- a/environment_mac.yml +++ b/environment_mac.yml @@ -1,16 +1,44 @@ +# Use this file if your computer runs Mac OS X or Apple Silicon. + name: sleap +channels: + - conda-forge + - anaconda + dependencies: -- python=3.7 -- pillow=8.4.0 -- shapely=1.7.1 -- ffmpeg -- qtpy>=2.0.1 -- anaconda-client -- conda-verify -- conda-forge::pip!=22.0.4 -- pip: - - tensorflow==2.7.0 - - pyside2==5.14.1 - - "--editable=./" - - "--requirement=./dev_requirements.txt" + # Packages SLEAP uses directly + - conda-forge::attrs >=21.2.0 + - conda-forge::importlib-metadata <7.1.0 + - conda-forge::cattrs ==1.1.1 + - conda-forge::h5py + - conda-forge::imageio-ffmpeg # Required for imageio to read/write videos with ffmpeg + - conda-forge::jsmin + - conda-forge::jsonpickle ==1.2 + - conda-forge::keras <2.10.0,>=2.9.0rc0 # Required by tensorflow-macos + - conda-forge::networkx <3.3 + - anaconda::numpy >=1.19.5,<1.23.0 + - conda-forge::opencv + - conda-forge::pandas + - conda-forge::pip + - conda-forge::pillow + - conda-forge::psutil + - conda-forge::pykalman + - conda-forge::pyside2 >=5.12 # To ensure application works correctly with QtPy. + - conda-forge::python ~=3.9 + - conda-forge::python-rapidjson + - conda-forge::pyyaml + - conda-forge::pyzmq + - conda-forge::qtpy >=2.0.1 + - conda-forge::rich + - conda-forge::scipy >=1.4.1,<=1.9.0 + - conda-forge::scikit-image + - conda-forge::scikit-learn ==1.0 + - conda-forge::scikit-video + - conda-forge::seaborn + # - conda-forge::tensorflow-hub # pulls in tensorflow cpu from conda-forge + - conda-forge::qudida + - conda-forge::albumentations + - conda-forge::ndx-pose <0.2.0 + - pip: + - "--editable=.[conda_dev]" \ No newline at end of file diff --git a/environment_no_cuda.yml b/environment_no_cuda.yml index df1f4d437..721c27fca 100644 --- a/environment_no_cuda.yml +++ b/environment_no_cuda.yml @@ -1,23 +1,47 @@ -name: sleap +# Use this environment file if your computer does not have a nvidia GPU and runs Windows +# or Linux. This environment file has exactly the same dependencies listed as +# environment.yaml, minus the packages required by tensorflow to find/use GPUs. + +name: sleap_ci + +channels: + - conda-forge + - sleap + - anaconda dependencies: - - python=3.7 - - conda-forge::numpy>=1.19.5,<=1.21.5 - # - conda-forge::tensorflow>=2.6.3,<=2.7.1 - - conda-forge::pyside2>=5.13.2,<=5.14.1 - - conda-forge::h5py=3.1.0 - - conda-forge::scipy>=1.4.1,<=1.7.3 - - pillow=8.4.0 - - shapely=1.7.1 - - conda-forge::pandas - - ffmpeg - # - cudatoolkit=11.3.1 - # - cudnn=8.2.1 - # - nvidia::cuda-nvcc=11.3 - # - sleap::tensorflow=2.7.0 - # - sleap::pyside2=5.14.1 - - qtpy>=2.0.1 - - conda-forge::pip!=22.0.4 - - pip: - - "--editable=." - - "--requirement=./dev_requirements.txt" + # Packages SLEAP uses directly + - conda-forge::attrs >=21.2.0 + - conda-forge::cattrs ==1.1.1 + - conda-forge::imageio-ffmpeg # Required for imageio to read/write videos with ffmpeg + - conda-forge::jsmin + - conda-forge::jsonpickle ==1.2 + - conda-forge::networkx + - anaconda::numpy >=1.19.5,<1.23.0 + - conda-forge::opencv <4.9.0 + - conda-forge::pandas + - conda-forge::pip + - conda-forge::pillow #>=8.3.1,<=8.4.0 + - conda-forge::psutil + - conda-forge::pykalman + - conda-forge::pyside2 >=5.12 # To ensure application works correctly with QtPy. + - conda-forge::python ~=3.7 # Run into _MAX_WINDOWS_WORKERS not found if == + - conda-forge::python-rapidjson + - conda-forge::pyyaml + - conda-forge::pyzmq + - conda-forge::qtpy >=2.0.1 + - conda-forge::rich + - conda-forge::scipy >=1.4.1,<=1.9.0 + - conda-forge::scikit-image + - conda-forge::scikit-learn ==1.0 + - conda-forge::scikit-video + - conda-forge::seaborn + # - sleap::tensorflow >=2.6.3,<2.11 # No windows GPU support for >2.10 + - sleap/label/dev::tensorflow ==2.7.0 + - conda-forge::tensorflow-hub + - conda-forge::qudida + - conda-forge::albumentations + - conda-forge::ndx-pose <0.2.0 + + - pip: + - "--editable=.[conda_dev]" \ No newline at end of file diff --git a/jupyter_requirements.txt b/jupyter_requirements.txt new file mode 100644 index 000000000..545f141a4 --- /dev/null +++ b/jupyter_requirements.txt @@ -0,0 +1,5 @@ +# This file contains the dependencies to be installed for jupyter lab support. + +ipykernel +ipywidgets +jupyterlab \ No newline at end of file diff --git a/pypi_requirements.txt b/pypi_requirements.txt new file mode 100644 index 000000000..775ce584e --- /dev/null +++ b/pypi_requirements.txt @@ -0,0 +1,50 @@ +# This file contains the full list of dependencies to be installed when only using pypi. +# This file should look very similar to the environment.yml file. Based on the logic in +# setup.py, the packages in requirements.txt will also be installed when running +# pip install sleap[pypi]. + +# These are also distributed through conda and not pip installed when using conda. +attrs>=21.2.0,<=21.4.0 +cattrs==1.1.1 +imageio +imageio-ffmpeg +# certifi>=2017.4.17,<=2021.10.8 +jsmin +jsonpickle==1.2 +networkx +numpy>=1.19.5,<1.23.0 +opencv-python>=4.2.0,<=4.7.0 +pandas +pillow>=8.3.1,<=8.4.0 +psutil +pykalman==0.9.5 +PySide2>=5.13.2,<=5.14.1; platform_machine != 'arm64' +PySide6; sys_platform == 'darwin' and platform_machine == 'arm64' +# Otherwise error: Microsoft Visual C++ 14.0 is required. +python-rapidjson <=1.10; sys_platform == 'win32' +python-rapidjson; sys_platform != 'win32' +pyyaml +pyzmq +qtpy>=2.0.1 +rich==10.16.1 +imgaug==0.4.0 +scipy>=1.4.1,<=1.9.0 +scikit-image +scikit-learn ==1.0.* +scikit-video +seaborn +tensorflow>=2.6.3,<2.9; platform_machine != 'arm64' +# tensorflow ==2.7.4; platform_machine != 'arm64' +tensorflow-hub<=0.14.0 +albumentations +ndx-pose<0.2.0 +# These dependencies are untested since we do not offer a wheel for apple silicon atm. +tensorflow-macos==2.9.2; sys_platform == 'darwin' and platform_machine == 'arm64' +tensorflow-metal==0.5.0; sys_platform == 'darwin' and platform_machine == 'arm64' + +# Dependencies of dependencies +# google-auth 2.23.0 has requirement urllib3<2.0 +urllib3<2.0 # Not a 'noticed' runtime-dependency +# tensorboard 2.11.2 has requirement protobuf<4,>=3.9.2 +# tensorflow 2.11.0 has requirement protobuf<3.20,>=3.9.2 +protobuf<3.20 # Makes GUI work in windows \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index a9cecb183..5db435ec8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,36 +1,12 @@ -numpy>=1.19.5,<1.23.0 -attrs>=21.2.0,<=21.4.0 -cattrs==1.1.1 -jsonpickle==1.2 -networkx -tensorflow>=2.6.3,<2.9.0; platform_machine != 'arm64' +# This file contains the minimal requirements to be installed via pip when using conda. + +# No conda packages for these +imgstore<0.3.0 # 0.3.3 results in https://github.com/O365/python-o365/issues/591 which is from https://github.com/regebro/tzlocal/issues/112 when tzlocal is v3.0 +nixio>=1.5.3 # Constrain put on by @jgrewe from G-Node +qimage2ndarray # ==1.9.0 +segmentation-models tensorflow-macos==2.9.2; sys_platform == 'darwin' and platform_machine == 'arm64' tensorflow-metal==0.5.0; sys_platform == 'darwin' and platform_machine == 'arm64' -h5py>=3.1.0,<=3.7.0 -python-rapidjson -opencv-python>=4.2.0,<=4.6.0 -# opencv-python-headless>=4.2.0.34,<=4.5.5.62 -pandas -psutil -PySide2>=5.13.2,<=5.14.1; platform_machine != 'arm64' -PySide2>=5.13.2,<=5.15.5; sys_platform == 'darwin' and platform_machine == 'arm64' -qtpy>=2.0.1 -pyzmq -pyyaml -pillow>=8.3.1,<=8.4.0 -imageio<=2.15.0 -imgaug==0.4.0 -scipy>=1.4.1,<=1.9.0 -scikit-image -scikit-learn==1.0.* -scikit-video -imgstore==0.2.9 -qimage2ndarray>=1.9.0 -jsmin -seaborn -pykalman==0.9.5 -segmentation-models==1.0.1 -rich==10.16.1 -certifi>=2017.4.17,<=2021.10.8 -pynwb -ndx-pose +tensorflow-hub==0.12.0; sys_platform == 'darwin' and platform_machine == 'arm64' + +pynwb>=2.3.3 # 2.0.0 required by ndx-pose, 2.3.3 fixes importlib-metadata incompatibility diff --git a/setup.py b/setup.py index 1af316128..a4815bd46 100644 --- a/setup.py +++ b/setup.py @@ -7,6 +7,7 @@ from os import path import re +import sys here = path.abspath(path.dirname(__file__)) @@ -26,13 +27,27 @@ def get_requirements(require_name=None): return f.read().strip().split("\n") +def combine_requirements(req_types): + return sum((get_requirements(req_type) for req_type in req_types), []) + + setup( name="sleap", version=sleap_version, setup_requires=["setuptools_scm"], - install_requires=get_requirements(), + install_requires=get_requirements(), # Minimal requirements if using conda. extras_require={ - "dev": get_requirements("dev"), + "conda_jupyter": get_requirements( + "jupyter" + ), # For conda install with jupyter lab + "conda_dev": combine_requirements( + ["dev", "jupyter"] + ), # For conda install with dev tools + "pypi": get_requirements("pypi"), # For pip install + "jupyter": combine_requirements( + ["pypi", "jupyter"] + ), # For pip install with jupyter lab + "dev": combine_requirements(["pypi", "dev", "jupyter"]), # For dev pip install }, description="SLEAP (Social LEAP Estimates Animal Poses) is a deep learning framework for animal pose tracking.", long_description=long_description, @@ -47,9 +62,9 @@ def get_requirements(require_name=None): url="https://sleap.ai", keywords="deep learning, pose estimation, tracking, neuroscience", license="BSD 3-Clause License", - packages=find_packages(exclude=["tensorflow"]), + packages=find_packages(exclude=["tensorflow", "tests", "tests.*", "docs"]), include_package_data=True, - entry_points={ + entry_points={ "console_scripts": [ "sleap-convert=sleap.io.convert:main", "sleap-render=sleap.io.visuals:main", diff --git a/sleap/config/frame_range_form.yaml b/sleap/config/frame_range_form.yaml new file mode 100644 index 000000000..3f01eade4 --- /dev/null +++ b/sleap/config/frame_range_form.yaml @@ -0,0 +1,13 @@ +main: + + - name: min_frame_idx + label: Minimum frame index + type: int + range: 1,1000000 + default: 1 + + - name: max_frame_idx + label: Maximum frame index + type: int + range: 1,1000000 + default: 1000 \ No newline at end of file diff --git a/sleap/config/labeled_clip_form.yaml b/sleap/config/labeled_clip_form.yaml index be0d64829..9236ad42b 100644 --- a/sleap/config/labeled_clip_form.yaml +++ b/sleap/config/labeled_clip_form.yaml @@ -18,6 +18,10 @@ main: label: Use GUI Visual Settings (colors, line widths) type: bool default: true + - name: background + label: Video Background + type: list + options: original,black,white,grey - name: open_when_done label: Open When Done Saving type: bool diff --git a/sleap/config/pipeline_form.yaml b/sleap/config/pipeline_form.yaml index ff32a8201..1bb930e58 100644 --- a/sleap/config/pipeline_form.yaml +++ b/sleap/config/pipeline_form.yaml @@ -4,7 +4,7 @@ training: label: Training/Inference Pipeline Type type: stacked default: "multi-animal bottom-up " - options: "multi-animal bottom-up,multi-animal top-down,single animal" + options: "multi-animal bottom-up,multi-animal top-down,multi-animal bottom-up-id,multi-animal top-down-id,single animal" multi-animal bottom-up: - type: text @@ -13,6 +13,14 @@ training: a "confidence map" head to predicts the nodes for an entire image and a "part affinity field" head to group the nodes into distinct animal instances.' + - label: Max Instances + name: max_instances + type: optional_int + help: Maximum number of instances per frame. + none_label: No max + default_disabled: true + range: 1,100 + default: 1 - name: model.heads.multi_instance.confmaps.sigma label: Sigma for Nodes @@ -45,6 +53,14 @@ training: locate and crop around each animal in the frame, and a "centered-instance confidence map" model for predicted node locations for each individual animal predicted by the centroid model.' + - label: Max Instances + name: max_instances + type: optional_int + help: Maximum number of instances per frame. + none_label: No max + default_disabled: true + range: 1,100 + default: 1 - default: 5.0 help: Spread of the Gaussian distribution of the confidence maps as a scalar float. @@ -79,6 +95,80 @@ training: name: model.heads.centered_instance.sigma type: double + multi-animal bottom-up-id: + - type: text + text: 'Multi-Animal Bottom-Up-Id Pipeline:
+ This pipeline uses single model with two output heads: a "confidence + map" head to predicts the nodes for an entire image and a "part + affinity field" head to group the nodes into distinct animal + instances. It also handles classification and tracking.' + + - name: model.heads.multi_class_bottomup.confmaps.sigma + label: Sigma for Nodes + type: double + default: 5.0 + help: Spread of the Gaussian distribution of the confidence maps as a scalar float. + Smaller values are more precise but may be difficult to learn as they have a + lower density within the image space. Larger values are easier to learn but + are less precise with respect to the peak coordinate. This spread is in units + of pixels of the model input image, i.e., the image resolution after any input + scaling is applied. + + - name: model.heads.multi_class_bottomup.class_maps.sigma + label: Sigma for Edges + type: double + default: 15.0 + help: Spread of the Gaussian distribution that weigh the part affinity fields + as a function of their distance from the edge they represent. Smaller values + are more precise but may be difficult to learn as they have a lower density + within the image space. Larger values are easier to learn but are less precise + with respect to the edge distance, so can be less useful in disambiguating between + edges that are nearby and parallel in direction. This spread is in units of + pixels of the model input image, i.e., the image resolution after any input + scaling is applied. + + multi-animal top-down-id: + - type: text + text: 'Multi-Animal Top-Down-Id Pipeline:
+ This pipeline uses two models: a "centroid" model to locate and crop + around each animal in the frame, and a "centered-instance confidence + map" model for predicted node locations for each individual animal + predicted by the centroid model. It also handles classification and + tracking.' + + - default: 5.0 + help: Spread of the Gaussian distribution of the confidence maps as a scalar float. + Smaller values are more precise but may be difficult to learn as they have a + lower density within the image space. Larger values are easier to learn but + are less precise with respect to the peak coordinate. This spread is in units + of pixels of the model input image, i.e., the image resolution after any input + scaling is applied. + label: Sigma for Centroids + name: model.heads.centroid.sigma + type: double + + - default: null + help: Text name of a body part (node) to use as the anchor point. If None, the + midpoint of the bounding box of all visible instance points will be used as + the anchor. The bounding box midpoint will also be used if the anchor part is + specified but not visible in the instance. Setting a reliable anchor point can + significantly improve topdown model accuracy as they benefit from a consistent + geometry of the body parts relative to the center of the image. + label: Anchor Part + name: model.heads.multi_class_topdown.confmaps.anchor_part + type: optional_list + + - default: 5.0 + help: Spread of the Gaussian distribution of the confidence maps as a scalar float. + Smaller values are more precise but may be difficult to learn as they have a + lower density within the image space. Larger values are easier to learn but + are less precise with respect to the peak coordinate. This spread is in units + of pixels of the model input image, i.e., the image resolution after any input + scaling is applied. + label: Sigma for Nodes + name: model.heads.multi_class_topdown.confmaps.sigma + type: double + single animal: - type: text text: 'Single Animal Pipeline:
@@ -121,6 +211,21 @@ training: options: ',RGB,grayscale' type: list +- type: text + text: 'ZMQ Options' + +- name: controller_port + label: Controller Port + type: int + default: 9000 + range: 1024,65535 + +- name: publish_port + label: Publish Port + type: int + default: 9001 + range: 1024,65535 + - type: text text: 'Output Options' @@ -181,6 +286,11 @@ training: type: bool default: true +- name: _keep_viz + label: Keep Prediction Visualization Images After Training + type: bool + default: false + - name: _predict_frames label: Predict On type: list @@ -197,7 +307,7 @@ inference: label: Training/Inference Pipeline Type type: stacked default: "multi-animal bottom-up " - options: "multi-animal bottom-up,multi-animal top-down,single animal,none" + options: "multi-animal bottom-up,multi-animal top-down,multi-animal bottom-up-id,multi-animal top-down-id,single animal,movenet-lightning,movenet-thunder,tracking-only" multi-animal bottom-up: - type: text @@ -206,6 +316,14 @@ inference: a "confidence map" head to predicts the nodes for an entire image and a "part affinity field" head to group the nodes into distinct animal instances.' + - label: Max Instances + name: max_instances + type: optional_int + help: Maximum number of instances per frame. + none_label: No max + default_disabled: true + range: 1,100 + default: 1 multi-animal top-down: - type: text @@ -214,6 +332,31 @@ inference: locate and crop around each animal in the frame, and a "centered-instance confidence map" model for predicted node locations for each individual animal predicted by the centroid model.' + - label: Max Instances + name: max_instances + type: optional_int + help: Maximum number of instances per frame. + none_label: No max + default_disabled: true + range: 1,100 + default: 1 + + multi-animal bottom-up-id: + - type: text + text: 'Multi-Animal Bottom-Up-Id Pipeline:
+ This pipeline uses single model with two output heads: a "confidence + map" head to predicts the nodes for an entire image and a "part + affinity field" head to group the nodes into distinct animal + instances. It also handles classification and tracking.' + + multi-animal top-down-id: + - type: text + text: 'Multi-Animal Top-Down-Id Pipeline:
+ This pipeline uses two models: a "centroid" model to locate and crop + around each animal in the frame, and a "centered-instance confidence + map" model for predicted node locations for each individual animal + predicted by the centroid model. It also handles classification and + tracking.' single animal: - type: text @@ -224,7 +367,31 @@ inference: For predicting on videos with more than one animal per frame, use a multi-animal pipeline (even if your training data has one instance per frame).' - none: + movenet-lightning: + - type: text + text: 'MoveNet Lightning Pipeline:
+ This pipeline uses a pretrained MoveNet Lightning model to predict the + nodes for an entire image and then groups all of these nodes into a single + instance. Lightning is intended for latency-critical applications. Note + that this model is intended for human pose estimation. There is no support + for videos containing more than one instance' + + movenet-thunder: + - type: text + text: 'MoveNet Thunder Pipeline:
+ This pipeline uses a pretrained MoveNet Thunder model to predict the nodes + for an entire image and then groups all of these nodes into a single + instance. Thunder is intended for applications that require high accuracy. + Note that this model is intended for human pose estimation. There is no + support for videos containing more than one instance' + + tracking-only: + +- name: batch_size + label: Batch Size + type: int + default: 4 + range: 1,512 - name: tracking.tracker label: Tracker (cross-frame identity) Method @@ -235,33 +402,44 @@ inference: none: flow: - - type: text - text: 'Pre-tracker data cleaning:' - - name: tracking.target_instance_count - label: Target Number of Instances Per Frame - type: optional_int - none_label: No target - default_disabled: true - range: 1,100 - default: 1 - - name: tracking.pre_cull_to_target - label: Cull to Target Instance Count - type: bool - default: false - - name: tracking.pre_cull_iou_threshold - label: Cull using IoU Threshold - type: double - default: 0.8 + # - type: text + # text: 'Pre-tracker data cleaning:' + # - name: tracking.target_instance_count + # label: Target Number of Instances Per Frame + # type: optional_int + # none_label: No target + # default_disabled: true + # range: 1,100 + # default: 1 + # - name: tracking.pre_cull_to_target + # label: Cull to Target Instance Count + # type: bool + # default: false + # - name: tracking.pre_cull_iou_threshold + # label: Cull using IoU Threshold + # type: double + # default: 0.8 - type: text text: 'Tracking with optical flow:
This tracker "shifts" instances from previous frames using optical flow before matching instances in each frame to the shifted instances from prior frames.' + # - name: tracking.max_tracking + # label: Limit max number of tracks + # type: bool + default: false + - name: tracking.max_tracks + label: Max number of tracks + type: optional_int + none_label: No limit + default_disabled: true + range: 1,100 + default: 1 - name: tracking.similarity label: Similarity Method type: list default: instance - options: instance,centroid,iou + options: "instance,normalized_instance,centroid,iou,object keypoint" - name: tracking.match label: Matching Method type: list @@ -271,10 +449,20 @@ inference: label: Elapsed Frame Window type: int default: 5 - - name: tracking.save_shifted_instance - label: Save shifted instances - type: bool - default: false + - name: tracking.robust + label: 'Robust quantile of similarity scores' + help: 'For a value between 0 and 1 (excluded), use a robust quantile + of the similarity scores to assign a track to an instance.
If equal to 1, + use the max similarity score (non-robust).' + type: optional_double + default_disabled: true + none_label: Use max (non-robust) + range: 0,1 + default: 0.95 + # - name: tracking.save_shifted_instances + # label: Save shifted instances + # type: bool + # default: false - type: text text: 'Kalman filter-based tracking:
Uses the above tracking options to track instances for an initial @@ -290,6 +478,22 @@ inference: label: Nodes to use for Tracking type: string default: 0,1,2 + - type: text + text: 'Object keypoint similarity options:
+ Only used if this similarity method is selected.' + - name: tracking.oks_errors + label: Keypoints errors in pixels + help: 'Standard error in pixels of the distance for each keypoint. + If the list is empty, defaults to 1. If singleton list, each keypoint has + the same error. Otherwise, the length should be the same as the number of + keypoints in the skeleton.' + type: string + default: + - name: tracking.oks_score_weighting + label: Use prediction score for weighting + help: 'Use prediction scores to weight the similarity of each keypoint' + type: bool + default: false - type: text text: 'Post-tracker data cleaning:' - name: tracking.post_connect_single_breaks @@ -298,32 +502,43 @@ inference: default: false simple: - - type: text - text: 'Pre-tracker data cleaning:' - - name: tracking.target_instance_count - label: Target Number of Instances Per Frame - type: optional_int - none_label: No target - default_disabled: true - range: 1,10 - default: 1 - - name: tracking.pre_cull_to_target - label: Cull to Target Instance Count - type: bool - default: false - - name: tracking.pre_cull_iou_threshold - label: Cull using IoU Threshold - type: double - default: 0.8 + # - type: text + # text: 'Pre-tracker data cleaning:' + # - name: tracking.target_instance_count + # label: Target Number of Instances Per Frame + # type: optional_int + # none_label: No target + # default_disabled: true + # range: 1,100 + # default: 1 + # - name: tracking.pre_cull_to_target + # label: Cull to Target Instance Count + # type: bool + # default: false + # - name: tracking.pre_cull_iou_threshold + # label: Cull using IoU Threshold + # type: double + # default: 0.8 - type: text text: 'Tracking:
This tracker assigns track identities by matching instances from prior frames to instances on subsequent frames.' + # - name: tracking.max_tracking + # label: Limit max number of tracks + # type: bool + # default: false + - name: tracking.max_tracks + label: Max number of tracks + type: optional_int + none_label: No limit + default_disabled: true + range: 1,100 + default: 1 - name: tracking.similarity label: Similarity Method type: list - default: iou - options: instance,centroid,iou + default: instance + options: "instance,normalized_instance,centroid,iou,object keypoint" - name: tracking.match label: Matching Method type: list @@ -333,6 +548,16 @@ inference: label: Elapsed Frame Window type: int default: 5 + - name: tracking.robust + label: 'Robust quantile of similarity scores' + help: 'For a value between 0 and 1 (excluded), use a robust quantile + of the similarity scores to assign a track to an instance.
If equal to 1, + use the max similarity score (non-robust).' + type: optional_double + default_disabled: true + none_label: Use max (non-robust) + range: 0,1 + default: 0.95 - type: text text: 'Kalman filter-based tracking:
Uses the above tracking options to track instances for an initial @@ -348,6 +573,22 @@ inference: label: Nodes to use for Tracking type: string default: 0,1,2 + - type: text + text: 'Object keypoint similarity options:
+ Only used if this similarity method is selected.' + - name: tracking.oks_errors + label: Keypoints errors in pixels + help: 'Standard error in pixels of the distance for each keypoint. + If the list is empty, defaults to 1. If singleton list, each keypoint has + the same error. Otherwise, the length should be the same as the number of + keypoints in the skeleton.' + type: string + default: + - name: tracking.oks_score_weighting + label: Use prediction score for weighting + help: 'Use prediction scores to weight the similarity of each keypoint' + type: bool + default: false - type: text text: 'Post-tracker data cleaning:' - name: tracking.post_connect_single_breaks diff --git a/sleap/config/shortcuts.yaml b/sleap/config/shortcuts.yaml index 53dc96814..e4eccea40 100644 --- a/sleap/config/shortcuts.yaml +++ b/sleap/config/shortcuts.yaml @@ -39,3 +39,4 @@ frame next medium step: Ctrl+Right frame prev medium step: Ctrl+Left frame next large step: Ctrl+Alt+Right frame prev large step: Ctrl+Alt+Left +export_analysis_current: Ctrl+Alt+E \ No newline at end of file diff --git a/sleap/config/suggestions.yaml b/sleap/config/suggestions.yaml index 55fe68eea..1440530fc 100644 --- a/sleap/config/suggestions.yaml +++ b/sleap/config/suggestions.yaml @@ -1,182 +1,200 @@ main: - -- name: method - label: Method - type: stacked - default: " " - options: " ,image features,sample,prediction score,velocity" - " ": - - sample: - - name: per_video - label: Samples Per Video - type: int - default: 20 - range: 1,3000 - - name: sampling_method - label: Sampling method - type: list - options: random,stride - default: stride - - "image features": - - name: per_video - label: Initial Samples Per Video - type: int - default: 200 - range: 1,3000 - - name: sample_method - label: Sampling method - type: list - options: random,stride - default: stride - - name: scale - label: Image Scale - type: double - default: 1.0 - - name: merge_video_features - label: Compute Features - type: list - options: per video,across all videos - default: per video - - name: feature_type - label: Image Feature Type - type: list - options: raw images,brisk,hog - default: raw images - - name: brisk_threshold - label: Brisk Keypoint Threshold - type: int - default: 40 - - name: vocab_size - label: Bag of Features Vocab Size - type: int - default: 20 - - name: pca_components - label: PCA Components - type: int - default: 5 - - name: n_clusters - label: K-Means Clusters - type: int - default: 5 - - name: per_cluster - label: Samples Per Cluster - type: int - default: 5 - - - strides: - - - name: per_video - label: Suggestions per video - type: int - default: 10 - range: 1,1000 - - random: - - - name: per_video - label: Suggestions per video - type: int - default: 10 - range: 1,1000 - -# pca: -# -# - name: clusters -# label: Number of clusters -# type: int -# default: 5 -# - name: per_cluster -# label: Samples per cluster -# type: int -# default: 5 -# - name: initial_samples -# label: Samples before clustering -# type: int -# default: 200 -# range: 10,1000 -# - name: pca_components -# label: Number of PCA components -# type: int -# default: 5 -# -# hog: -# -# - name: clusters -# label: Number of clusters -# type: int -# default: 5 -# - name: per_cluster -# label: Samples per cluster -# type: int -# default: 5 -# - name: sample_step -# label: Frame sampling step size -# type: int -# default: 5 -# - name: pca_components -# label: Number of PCA components -# type: int -# default: 5 -# -# brisk: -# -# - name: clusters -# label: Number of clusters -# type: int -# default: 5 -# - name: per_cluster -# label: Samples per cluster -# type: int -# default: 5 -# - name: initial_samples -# label: Samples before clustering -# type: int -# default: 200 -# range: 10,1000 -# - name: pca_components -# label: Number of PCA components -# type: int -# default: 5 - - "prediction score": - - - name: score_limit - label: Low score (lt) - type: double - default: 3.0 - range: 0,100 - - name: instance_limit - label: Instance count (gte) - type: int - default: 2 - range: 1,10 - - velocity: - - name: node - label: Node - type: list - - name: threshold - label: Velocity Threshold - type: double - default: 0.1 - range: 0.1,1.0 - - -- name: target - label: Target - type: stacked - options: "all videos,current video" - default: "all videos" - - # Type is stacked because this makes the boxes aligned. - - "all videos": - "current video": - -- name: generate_button - label: Generate Suggestions - type: button - default: main action + - name: method + label: Method + type: stacked + default: " " + options: " ,image features,sample,prediction score,velocity,frame chunk,max point displacement" + " ": + + sample: + - name: per_video + label: Samples Per Video + type: int + default: 20 + range: 1,3000 + - name: sampling_method + label: Sampling method + type: list + options: random,stride + default: stride + + "image features": + - name: per_video + label: Initial Samples Per Video + type: int + default: 200 + range: 1,3000 + - name: sample_method + label: Sampling method + type: list + options: random,stride + default: stride + - name: scale + label: Image Scale + type: double + default: 1.0 + - name: merge_video_features + label: Compute Features + type: list + options: per video,across all videos + default: per video + - name: feature_type + label: Image Feature Type + type: list + options: raw images,brisk,hog + default: raw images + - name: brisk_threshold + label: Brisk Keypoint Threshold + type: int + default: 40 + - name: vocab_size + label: Bag of Features Vocab Size + type: int + default: 20 + - name: pca_components + label: PCA Components + type: int + default: 5 + - name: n_clusters + label: K-Means Clusters + type: int + default: 5 + - name: per_cluster + label: Samples Per Cluster + type: int + default: 5 + + strides: + - name: per_video + label: Suggestions per video + type: int + default: 10 + range: 1,1000 + + random: + - name: per_video + label: Suggestions per video + type: int + default: 10 + range: 1,1000 + + "frame chunk": + - name: frame_from + label: From + type: int + default: 1 + range: 1, 1000 + - name: frame_to + label: To + type: int + default: 1000 + range: 1, 1000 + + # pca: + # + # - name: clusters + # label: Number of clusters + # type: int + # default: 5 + # - name: per_cluster + # label: Samples per cluster + # type: int + # default: 5 + # - name: initial_samples + # label: Samples before clustering + # type: int + # default: 200 + # range: 10,1000 + # - name: pca_components + # label: Number of PCA components + # type: int + # default: 5 + # + # hog: + # + # - name: clusters + # label: Number of clusters + # type: int + # default: 5 + # - name: per_cluster + # label: Samples per cluster + # type: int + # default: 5 + # - name: sample_step + # label: Frame sampling step size + # type: int + # default: 5 + # - name: pca_components + # label: Number of PCA components + # type: int + # default: 5 + # + # brisk: + # + # - name: clusters + # label: Number of clusters + # type: int + # default: 5 + # - name: per_cluster + # label: Samples per cluster + # type: int + # default: 5 + # - name: initial_samples + # label: Samples before clustering + # type: int + # default: 200 + # range: 10,1000 + # - name: pca_components + # label: Number of PCA components + # type: int + # default: 5 + + "prediction score": + - name: score_limit + label: Low score (lt) + type: double + default: 3.0 + range: 0,100 + - name: instance_limit_lower + label: Instance count at least + type: int + default: 1 + range: 0,10 + - name: instance_limit_upper + label: Instance count no more than + type: int + default: 2 + range: 0,10 + + velocity: + - name: node + label: Node + type: list + - name: threshold + label: Velocity Threshold + type: double + default: 0.1 + range: 0.1,1.0 + + "max point displacement": + - name: displacement_threshold + label: Maximum Displacement Threshold + type: int + default: 10 + range: 0,999 + + - name: target + label: Target + type: stacked + options: "all videos,current video" + default: "all videos" + + # Type is stacked because this makes the boxes aligned. + + "all videos": + "current video": + + - name: generate_button + label: Generate Suggestions + type: button + default: main action diff --git a/sleap/config/training_editor_form.yaml b/sleap/config/training_editor_form.yaml index d362e8cee..7d7972892 100644 --- a/sleap/config/training_editor_form.yaml +++ b/sleap/config/training_editor_form.yaml @@ -20,7 +20,7 @@ data: name: data.instance_cropping.crop_size type: optional_int none_label: Auto - range: 0,512 + range: 0,832 model: - default: unet @@ -44,7 +44,7 @@ model: label: Max Stride name: model.backbone.hourglass.max_stride type: list - options: 1,2,4,8,16,32,64 + options: 1,2,4,8,16,32,64,128 # - default: 4 # help: Determines the number of upsampling blocks in the network. # label: Output Stride @@ -81,7 +81,7 @@ model: label: Max Stride name: model.backbone.leap.max_stride type: list - options: 2,4,8,16,32,64 + options: 2,4,8,16,32,64,128 # - default: 1 # help: Determines the number of upsampling blocks in the network. # label: Output Stride @@ -190,7 +190,7 @@ model: label: Max Stride name: model.backbone.resnet.max_stride type: list - options: 2,4,8,16,32,64 + options: 2,4,8,16,32,64,128 # - default: 4 # help: Stride of the final output. If the upsampling branch is not defined, the # output stride is controlled via dilated convolutions or reduced pooling in the @@ -250,7 +250,7 @@ model: label: Max Stride name: model.backbone.unet.max_stride type: list - options: 2,4,8,16,32,64 + options: 2,4,8,16,32,64,128 # - default: 1 # help: Determines the number of upsampling blocks in the network. # label: Output Stride @@ -408,8 +408,117 @@ model: label: Loss Weight name: model.heads.multi_instance.pafs.loss_weight type: double + multi_class_topdown: + - default: 1.5 + help: Spread of the Gaussian distribution of the confidence maps as a scalar float. + Smaller values are more precise but may be difficult to learn as they have a + lower density within the image space. Larger values are easier to learn but + are less precise with respect to the peak coordinate. This spread is in units + of pixels of the model input image, i.e., the image resolution after any input + scaling is applied. + label: Sigma + name: model.heads.multi_class_topdown.confmaps.sigma + type: double + - default: 2 + help: The stride of the output confidence maps relative to the input image. This + is the reciprocal of the resolution, e.g., an output stride of 2 results in + confidence maps that are 0.5x the size of the input. Increasing this value can + considerably speed up model performance and decrease memory requirements, at + the cost of decreased spatial resolution. + label: Output Stride + name: model.heads.multi_class_topdown.confmaps.output_stride + type: list + options: 1,2,4,8,16,32,64 + - default: 1.0 + help: Scalar float used to weigh the loss term for this head during training. + Increase this to encourage the optimization to focus on improving this specific + output in multi-head models. + label: Loss Weight + name: model.heads.multi_class_topdown.confmaps.loss_weight + type: double + - default: 3 + help: Number of fully-connected layers before the classification output + layer. These can help in transforming general image features into + classification-specific features. + label: Fully Connected Layers + name: model.heads.multi_class_topdown.class_vectors.num_fc_layers + type: integer + - default: 64 + help: Number of units (dimensions) in the fully-connected layers before + classification. Increasing this can improve the representational capacity in + the pre-classification layers. + label: Fully Connected Units + name: model.heads.multi_class_topdown.class_vectors.num_fc_units + type: integer + - default: true + help: Whether to use global max pooling prior to flattening. + label: Global Pool + name: model.heads.multi_class_topdown.class_vectors.global_pool + type: bool + - default: 1.0 + help: Scalar float used to weigh the loss term for this head during + training. Increase this to encourage the optimization to focus on improving + this specific output in multi-head models. + label: Loss Weight + name: model.heads.multi_class_topdown.class_vectors.loss_weight + type: double + multi_class_bottomup: + - default: 5.0 + help: Spread of the Gaussian distribution of the confidence maps as a scalar float. + Smaller values are more precise but may be difficult to learn as they have a + lower density within the image space. Larger values are easier to learn but + are less precise with respect to the peak coordinate. This spread is in units + of pixels of the model input image, i.e., the image resolution after any input + scaling is applied. + label: Sigma + name: model.heads.multi_class_bottomup.confmaps.sigma + type: double + - default: 2 + help: The stride of the output confidence maps relative to the input image. This + is the reciprocal of the resolution, e.g., an output stride of 2 results in + confidence maps that are 0.5x the size of the input. Increasing this value can + considerably speed up model performance and decrease memory requirements, at + the cost of decreased spatial resolution. + label: Output Stride + name: model.heads.multi_class_bottomup.confmaps.output_stride + type: list + options: 1,2,4,8,16,32,64 + - default: 1.0 + help: Scalar float used to weigh the loss term for this head during training. + Increase this to encourage the optimization to focus on improving this specific + output in multi-head models. + label: Loss Weight + name: model.heads.multi_class_bottomup.confmaps.loss_weight + type: double + - default: 5.0 + help: Spread of the Gaussian distribution of the confidence maps as a scalar float. + Smaller values are more precise but may be difficult to learn as they have a + lower density within the image space. Larger values are easier to learn but + are less precise with respect to the peak coordinate. This spread is in units + of pixels of the model input image, i.e., the image resolution after any input + scaling is applied. + label: Sigma + name: model.heads.multi_class_bottomup.class_maps.sigma + type: double + - default: 16 + help: The stride of the output class maps relative to the input image. This + is the reciprocal of the resolution, e.g., an output stride of 2 results in + confidence maps that are 0.5x the size of the input. Increasing this value can + considerably speed up model performance and decrease memory requirements, at + the cost of decreased spatial resolution. + label: Output Stride + name: model.heads.multi_class_bottomup.class_maps.output_stride + type: list + options: 1,2,4,8,16,32,64 + - default: 2.0 + help: Scalar float used to weigh the loss term for this head during training. + Increase this to encourage the optimization to focus on improving this specific + output in multi-head models. + label: Loss Weight + name: model.heads.multi_class_bottomup.class_maps.loss_weight + type: double name: _heads_name - options: single_instance,centroid,centered_instance,multi_instance + options: single_instance,centroid,centered_instance,multi_instance,multi_class_topdown,multi_class_bottomup single_instance: - default: 5.0 help: Spread of the Gaussian distribution of the confidence maps as a scalar float. @@ -552,6 +661,7 @@ optimization: label: Batch Size name: optimization.batch_size type: int + range: 1,512 - default: 100 help: Maximum number of epochs to train for. Training can be stopped manually or automatically if early stopping is enabled and a plateau is detected. label: Epochs diff --git a/sleap/gui/app.py b/sleap/gui/app.py index 6827b5e33..8b711c806 100644 --- a/sleap/gui/app.py +++ b/sleap/gui/app.py @@ -1,5 +1,4 @@ -""" -Main GUI application for labeling, training/inference, and proofreading. +"""Main GUI application for labeling, training/inference, and proofreading. Each open project is an instance of :py:class:`MainWindow`. @@ -45,54 +44,51 @@ frame and instances listed in data view table. """ - -import re import os -import random import platform +import random +import re +import traceback +from logging import getLogger from pathlib import Path - from typing import Callable, List, Optional, Tuple +import sys +import subprocess from qtpy import QtCore, QtGui -from qtpy.QtCore import Qt, QEvent - -from qtpy.QtWidgets import QApplication, QMainWindow, QWidget, QDockWidget -from qtpy.QtWidgets import QVBoxLayout, QHBoxLayout, QGroupBox -from qtpy.QtWidgets import QLabel, QPushButton, QComboBox -from qtpy.QtWidgets import QMessageBox +from qtpy.QtCore import QEvent, Qt +from qtpy.QtWidgets import QApplication, QMainWindow, QMessageBox import sleap -from sleap.gui.dialogs.metrics import MetricsTableDialog -from sleap.skeleton import Skeleton -from sleap.instance import Instance, LabeledFrame -from sleap.io.dataset import Labels -from sleap.info.summary import StatisticSeries +from sleap.gui.color import ColorManager from sleap.gui.commands import CommandContext, UpdateTopic -from sleap.gui.widgets.video import QtVideoPlayer -from sleap.gui.widgets.slider import set_slider_marks_from_labels -from sleap.gui.dataviews import ( - GenericTableView, - VideosTableModel, - SkeletonNodesTableModel, - SkeletonEdgesTableModel, - SuggestionsTableModel, - LabeledFrameTableModel, - SkeletonNodeModel, -) -from sleap.util import parse_uri_path - from sleap.gui.dialogs.filedialog import FileDialog -from sleap.gui.dialogs.formbuilder import YamlFormWidget, FormBuilderModalDialog -from sleap.gui.shortcuts import Shortcuts +from sleap.gui.dialogs.formbuilder import FormBuilderModalDialog +from sleap.gui.dialogs.metrics import MetricsTableDialog from sleap.gui.dialogs.shortcuts import ShortcutDialog -from sleap.gui.state import GuiState -from sleap.gui.overlays.tracks import TrackTrailOverlay, TrackListOverlay -from sleap.gui.color import ColorManager from sleap.gui.overlays.instance import InstanceOverlay -from sleap.gui.release_checker import ReleaseChecker - +from sleap.gui.overlays.tracks import TrackListOverlay, TrackTrailOverlay +from sleap.gui.shortcuts import Shortcuts +from sleap.gui.state import GuiState +from sleap.gui.web import ReleaseChecker, ping_analytics +from sleap.gui.widgets.docks import ( + InstancesDock, + SkeletonDock, + SuggestionsDock, + VideosDock, +) +from sleap.gui.widgets.slider import set_slider_marks_from_labels +from sleap.gui.widgets.video import QtVideoPlayer +from sleap.info.summary import StatisticSeries +from sleap.instance import Instance +from sleap.io.dataset import Labels +from sleap.io.video import available_video_exts from sleap.prefs import prefs +from sleap.skeleton import Skeleton +from sleap.util import parse_uri_path, get_config_file + + +logger = getLogger(__name__) class MainWindow(QMainWindow): @@ -109,19 +105,27 @@ class MainWindow(QMainWindow): """ def __init__( - self, labels_path: Optional[str] = None, reset: bool = False, *args, **kwargs + self, + labels_path: Optional[str] = None, + labels: Optional[Labels] = None, + reset: bool = False, + no_usage_data: bool = False, + *args, + **kwargs, ): """Initialize the app. Args: labels_path: Path to saved :class:`Labels` dataset. reset: If `True`, reset preferences to default (including window state). + no_usage_data: If `True`, launch GUI without sharing usage data regardless + of stored preferences. """ super(MainWindow, self).__init__(*args, **kwargs) self.setAcceptDrops(True) self.state = GuiState() - self.labels = Labels() + self.labels = labels or Labels() self.commands = CommandContext( state=self.state, app=self, update_callback=self.on_data_update @@ -148,15 +152,28 @@ def __init__( self.state["edge style"] = prefs["edge style"] self.state["fit"] = False self.state["color predicted"] = prefs["color predicted"] + self.state["trail_length"] = prefs["trail length"] + self.state["trail_shade"] = prefs["trail shade"] self.state["marker size"] = prefs["marker size"] self.state["propagate track labels"] = prefs["propagate track labels"] self.state["node label size"] = prefs["node label size"] + self.state["share usage data"] = prefs["share usage data"] + self.state["skeleton_preview_image"] = None + self.state["skeleton_description"] = "No skeleton loaded yet" + if no_usage_data: + self.state["share usage data"] = False + self.state["clipboard_track"] = None + self.state["clipboard_instance"] = None + self.state.connect("marker size", self.plotFrame) self.state.connect("node label size", self.plotFrame) self.state.connect("show non-visible nodes", self.plotFrame) self.release_checker = ReleaseChecker() + if self.state["share usage data"]: + ping_analytics() + self._initialize_gui() if reset: @@ -166,8 +183,10 @@ def __init__( print("Restoring GUI state...") self.restoreState(prefs["window state"]) - if labels_path: - self.loadProjectFile(labels_path) + if labels_path is not None: + self.commands.loadProjectFile(filename=labels_path) + elif labels is not None: + self.commands.loadLabelsObject(labels=labels) else: self.state["project_loaded"] = False @@ -204,6 +223,9 @@ def closeEvent(self, event): prefs["edge style"] = self.state["edge style"] prefs["propagate track labels"] = self.state["propagate track labels"] prefs["color predicted"] = self.state["color predicted"] + prefs["trail length"] = self.state["trail_length"] + prefs["trail shade"] = self.state["trail_shade"] + prefs["share usage data"] = self.state["share usage data"] # Save preferences. prefs.save() @@ -243,15 +265,12 @@ def dragEnterEvent(self, event): event.acceptProposedAction() def dropEvent(self, event): - # Parse filenames filenames = event.mimeData().data("text/uri-list").data().decode() filenames = [parse_uri_path(f.strip()) for f in filenames.strip().split("\n")] exts = [Path(f).suffix for f in filenames] - VIDEO_EXTS = (".mp4", ".avi", ".h5") # TODO: make this list global - if len(exts) == 1 and exts[0].lower() == ".slp": if self.state["project_loaded"]: # Merge @@ -260,10 +279,16 @@ def dropEvent(self, event): # Load self.commands.openProject(filename=filenames[0], first_open=True) - elif all([ext.lower() in VIDEO_EXTS for ext in exts]): + elif all([ext.lower()[1:] in available_video_exts() for ext in exts]): # Import videos self.commands.showImportVideos(filenames=filenames) + else: + raise TypeError( + f"Invalid file type(s) dropped: {', '.join(exts)} \n" + f"Supported formats: .slp, .{', .'.join(available_video_exts())}" + ) + @property def labels(self) -> Labels: return self.state["labels"] @@ -294,7 +319,8 @@ def _create_video_player(self): self.player = QtVideoPlayer( color_manager=self.color_manager, state=self.state, context=self.commands ) - self.player.changedPlot.connect(self._after_plot_update) + self.player.changedPlot.connect(self._after_plot_change) + self.player.updatedPlot.connect(self._after_plot_update) self.player.view.instanceDoubleClicked.connect( self._handle_instance_double_click @@ -303,15 +329,34 @@ def _create_video_player(self): self.setCentralWidget(self.player) def switch_frame(video): - # Jump to last labeled frame + """Jump to last labeled frame""" last_label = self.labels.find_last(video) if last_label is not None: self.state["frame_idx"] = last_label.frame_idx else: self.state["frame_idx"] = 0 + def update_frame_chunk_suggestions(video): + """Set upper limit of frame_chunk spinbox to number frames in video.""" + method_layout = ( + self.suggestions_dock.suggestions_form_widget.form_layout.fields[ + "method" + ] + ) + frame_chunk_layout = method_layout.page_layouts["frame chunk"] + frame_to_spinbox = frame_chunk_layout.fields["frame_to"] + frame_from_spinbox = frame_chunk_layout.fields["frame_from"] + if video is not None: + frame_to_spinbox.setMaximum(video.num_frames) + frame_from_spinbox.setMaximum(video.num_frames) + self.state.connect( - "video", callbacks=[switch_frame, lambda x: self._update_seekbar_marks()] + "video", + callbacks=[ + switch_frame, + lambda x: self._update_seekbar_marks(), + update_frame_chunk_suggestions, + ], ) def _create_color_manager(self): @@ -332,7 +377,9 @@ def add_menu_item(menu, key: str, name: str, action: Callable): def connect_check(key): self._menu_actions[key].setCheckable(True) self._menu_actions[key].setChecked(self.state[key]) - self.state.connect(key, self._menu_actions[key].setChecked) + self.state.connect( + key, lambda checked: self._menu_actions[key].setChecked(checked) + ) # add checkable menu item connected to state variable def add_menu_check_item(menu, key: str, name: str): @@ -450,6 +497,20 @@ def add_submenu_choices(menu, title, options, key): lambda: self.commands.exportAnalysisFile(all_videos=True), ) + export_csv_menu = fileMenu.addMenu("Export Analysis CSV...") + add_menu_item( + export_csv_menu, + "export_csv_current", + "Current Video...", + self.commands.exportCSVFile, + ) + add_menu_item( + export_csv_menu, + "export_csv_all", + "All Videos...", + lambda: self.commands.exportCSVFile(all_videos=True), + ) + add_menu_item(fileMenu, "export_nwb", "Export NWB...", self.commands.exportNWB) fileMenu.addSeparator() @@ -457,6 +518,13 @@ def add_submenu_choices(menu, title, options, key): fileMenu, "reset prefs", "Reset preferences to defaults...", self.resetPrefs ) + add_menu_item( + fileMenu, + "open preference directory", + "Open Preferences Directory...", + self.openPrefs, + ) + fileMenu.addSeparator() add_menu_item(fileMenu, "close", "Quit", self.close) @@ -588,26 +656,34 @@ def prev_vid(): key="edge style", ) + # XXX add_submenu_choices( menu=viewMenu, title="Node Marker Size", - options=(1, 4, 6, 8, 12), + options=prefs["node marker sizes"], key="marker size", ) add_submenu_choices( menu=viewMenu, title="Node Label Size", - options=(6, 12, 18, 24, 36), + options=prefs["node label sizes"], key="node label size", ) + viewMenu.addSeparator() add_submenu_choices( menu=viewMenu, title="Trail Length", - options=(0, 10, 50, 100, 250), + options=TrackTrailOverlay.get_length_options(), key="trail_length", ) + add_submenu_choices( + menu=viewMenu, + title="Trail Shade", + options=tuple(TrackTrailOverlay.get_shade_options().keys()), + key="trail_shade", + ) viewMenu.addSeparator() add_menu_item( @@ -630,13 +706,17 @@ def prev_vid(): ) def new_instance_menu_action(): + """Determine which action to use when using Ctrl + I or menu Add Instance. + + We always add an offset of 10. + """ method_key = [ key for (key, val) in instance_adding_methods.items() if val == self.state["instance_init_method"] ] if method_key: - self.commands.newInstance(init_method=method_key[0]) + self.commands.newInstance(init_method=method_key[0], offset=10) labelMenu = self.menuBar().addMenu("Labels") add_menu_item( @@ -676,6 +756,19 @@ def new_instance_menu_action(): labelMenu.addSeparator() + labelMenu.addAction( + "Copy Instance", + self.commands.copyInstance, + Qt.CTRL | Qt.Key_C, + ) + labelMenu.addAction( + "Paste Instance", + self.commands.pasteInstance, + Qt.CTRL | Qt.Key_V, + ) + + labelMenu.addSeparator() + add_menu_item( labelMenu, "delete frame predictions", @@ -706,6 +799,12 @@ def new_instance_menu_action(): "Delete Predictions with Low Score...", self.commands.deleteLowScorePredictions, ) + add_menu_item( + labelMenu, + "delete max instance predictions", + "Delete Predictions beyond Max Instances...", + self.commands.deleteInstanceLimitPredictions, + ) add_menu_item( labelMenu, "delete frame limit predictions", @@ -740,13 +839,37 @@ def new_instance_menu_action(): ) self.delete_tracks_menu = tracksMenu.addMenu("Delete Track") self.delete_tracks_menu.setEnabled(False) + + self.delete_multiple_tracks_menu = tracksMenu.addMenu("Delete Multiple Tracks") + self.delete_multiple_tracks_menu.setToolTip( + "Delete either only 'Unused' tracks or 'All' tracks, and update instances. Instances are not removed." + ) + add_menu_item( - tracksMenu, + self.delete_multiple_tracks_menu, + "delete unused tracks", + "Unused", + lambda: self.commands.deleteMultipleTracks(delete_all=False), + ) + + add_menu_item( + self.delete_multiple_tracks_menu, "delete all tracks", - "Delete All Tracks", - self.commands.deleteAllTracks, - ).setToolTip( - "Delete all tracks and update instances. Instances are not removed." + "All", + lambda: self.commands.deleteMultipleTracks(delete_all=True), + ) + + tracksMenu.addSeparator() + + tracksMenu.addAction( + "Copy Instance Track", + self.commands.copyInstanceTrack, + Qt.CTRL | Qt.SHIFT | Qt.Key_C, + ) + tracksMenu.addAction( + "Paste Instance Track", + self.commands.pasteInstanceTrack, + Qt.CTRL | Qt.SHIFT | Qt.Key_V, ) tracksMenu.addSeparator() @@ -757,6 +880,8 @@ def new_instance_menu_action(): "Point Displacement (max)", "Primary Point Displacement (sum)", "Primary Point Displacement (max)", + "Tracking Score (mean)", + "Tracking Score (min)", "Instance Score (sum)", "Instance Score (min)", "Point Score (sum)", @@ -885,6 +1010,14 @@ def new_instance_menu_action(): self.state["prerelease_version_menu"].setEnabled(False) self.commands.checkForUpdates() + helpMenu.addSeparator() + usageMenu = helpMenu.addMenu("Improve SLEAP") + add_menu_check_item(usageMenu, "share usage data", "Share usage data") + usageMenu.addAction( + "What is usage data?", + lambda: self.commands.openWebsite("https://sleap.ai/help.html#usage-data"), + ) + helpMenu.addSeparator() helpMenu.addAction("Keyboard Shortcuts", self._show_keyboard_shortcuts_window) @@ -900,248 +1033,27 @@ def wrapped_function(*args): def _create_dock_windows(self): """Create dock windows and connect them to GUI.""" - def _make_dock(name, widgets=[], tab_with=None): - dock = QDockWidget(name) - dock.setObjectName(name + "Dock") - - dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) - - dock_widget = QWidget() - dock_widget.setObjectName(name + "Widget") - layout = QVBoxLayout() - - for widget in widgets: - layout.addWidget(widget) - - dock_widget.setLayout(layout) - dock.setWidget(dock_widget) - - self.addDockWidget(Qt.RightDockWidgetArea, dock) - self.viewMenu.addAction(dock.toggleViewAction()) - - if tab_with is not None: - self.tabifyDockWidget(tab_with, dock) - - return layout - - def _add_button(to, label, action, key=None): - key = key or label.lower() - btn = QPushButton(label) - btn.clicked.connect(action) - to.addWidget(btn) - self._buttons[key] = btn - return btn - - ####### Videos ####### - videos_layout = _make_dock("Videos") - self.videosTable = GenericTableView( - state=self.state, - row_name="video", - is_activatable=True, - model=VideosTableModel(items=self.labels.videos, context=self.commands), - ) - videos_layout.addWidget(self.videosTable) - - hb = QHBoxLayout() - _add_button(hb, "Toggle Grayscale", self.commands.toggleGrayscale) - _add_button(hb, "Show Video", self.videosTable.activateSelected) - _add_button(hb, "Add Videos", self.commands.addVideo) - _add_button(hb, "Remove Video", self.commands.removeVideo) - - hbw = QWidget() - hbw.setLayout(hb) - videos_layout.addWidget(hbw) - - ####### Skeleton ####### - skeleton_layout = _make_dock( - "Skeleton", tab_with=videos_layout.parent().parent() - ) - - gb = QGroupBox("Nodes") - vb = QVBoxLayout() - self.skeletonNodesTable = GenericTableView( - state=self.state, - row_name="node", - model=SkeletonNodesTableModel( - items=self.state["skeleton"], context=self.commands - ), - ) - vb.addWidget(self.skeletonNodesTable) - hb = QHBoxLayout() - _add_button(hb, "New Node", self.commands.newNode) - _add_button(hb, "Delete Node", self.commands.deleteNode) - - hbw = QWidget() - hbw.setLayout(hb) - vb.addWidget(hbw) - gb.setLayout(vb) - skeleton_layout.addWidget(gb) - - def _update_edge_src(): - self.skeletonEdgesDst.model().skeleton = self.state["skeleton"] - - gb = QGroupBox("Edges") - vb = QVBoxLayout() - self.skeletonEdgesTable = GenericTableView( - state=self.state, - row_name="edge", - model=SkeletonEdgesTableModel( - items=self.state["skeleton"], context=self.commands - ), - ) - - vb.addWidget(self.skeletonEdgesTable) - hb = QHBoxLayout() - self.skeletonEdgesSrc = QComboBox() - self.skeletonEdgesSrc.setEditable(False) - self.skeletonEdgesSrc.currentIndexChanged.connect(_update_edge_src) - self.skeletonEdgesSrc.setModel(SkeletonNodeModel(self.state["skeleton"])) - hb.addWidget(self.skeletonEdgesSrc) - hb.addWidget(QLabel("to")) - self.skeletonEdgesDst = QComboBox() - self.skeletonEdgesDst.setEditable(False) - hb.addWidget(self.skeletonEdgesDst) - self.skeletonEdgesDst.setModel( - SkeletonNodeModel( - self.state["skeleton"], lambda: self.skeletonEdgesSrc.currentText() - ) - ) - - def new_edge(): - src_node = self.skeletonEdgesSrc.currentText() - dst_node = self.skeletonEdgesDst.currentText() - self.commands.newEdge(src_node, dst_node) - - _add_button(hb, "Add Edge", new_edge) - _add_button(hb, "Delete Edge", self.commands.deleteEdge) - hbw = QWidget() - hbw.setLayout(hb) - vb.addWidget(hbw) - gb.setLayout(vb) - skeleton_layout.addWidget(gb) - - hb = QHBoxLayout() - _add_button(hb, "Load Skeleton", self.commands.openSkeleton) - _add_button(hb, "Save Skeleton", self.commands.saveSkeleton) - - hbw = QWidget() - hbw.setLayout(hb) - skeleton_layout.addWidget(hbw) - - ####### Suggestions ####### - suggestions_layout = _make_dock( - "Labeling Suggestions", tab_with=videos_layout.parent().parent() - ) - self.suggestionsTable = GenericTableView( - state=self.state, - is_sortable=True, - model=SuggestionsTableModel( - items=self.labels.suggestions, context=self.commands - ), - ) - - suggestions_layout.addWidget(self.suggestionsTable) - - hb = QHBoxLayout() - - _add_button( - hb, - "Add current frame", - self.process_events_then(self.commands.addCurrentFrameAsSuggestion), - "add current frame as suggestion", - ) - - _add_button( - hb, - "Remove", - self.process_events_then(self.commands.removeSuggestion), - "remove suggestion", - ) - - _add_button( - hb, - "Clear all", - self.process_events_then(self.commands.clearSuggestions), - "clear suggestions", - ) - - hbw = QWidget() - hbw.setLayout(hb) - suggestions_layout.addWidget(hbw) - - hb = QHBoxLayout() - - _add_button( - hb, - "Previous", - self.process_events_then(self.commands.prevSuggestedFrame), - "goto previous suggestion", - ) - - self.suggested_count_label = QLabel() - hb.addWidget(self.suggested_count_label) - - _add_button( - hb, - "Next", - self.process_events_then(self.commands.nextSuggestedFrame), - "goto next suggestion", - ) - - hbw = QWidget() - hbw.setLayout(hb) - suggestions_layout.addWidget(hbw) - - self.suggestions_form_widget = YamlFormWidget.from_name( - "suggestions", - title="Generate Suggestions", - ) - self.suggestions_form_widget.mainAction.connect( - self.process_events_then(self.commands.generateSuggestions) - ) - suggestions_layout.addWidget(self.suggestions_form_widget) - - def goto_suggestion(*args): - selected_frame = self.suggestionsTable.getSelectedRowItem() - self.commands.gotoVideoAndFrame( - selected_frame.video, selected_frame.frame_idx - ) - - self.suggestionsTable.doubleClicked.connect(goto_suggestion) - - self.state.connect("suggestion_idx", self.suggestionsTable.selectRow) - - ####### Instances ####### - instances_layout = _make_dock( - "Instances", tab_with=videos_layout.parent().parent() - ) - self.instancesTable = GenericTableView( - state=self.state, - row_name="instance", - name_prefix="", - model=LabeledFrameTableModel( - items=self.state["labeled_frame"], context=self.commands - ), - ) - instances_layout.addWidget(self.instancesTable) - - hb = QHBoxLayout() - _add_button(hb, "New Instance", lambda x: self.commands.newInstance()) - _add_button(hb, "Delete Instance", self.commands.deleteSelectedInstance) - - hbw = QWidget() - hbw.setLayout(hb) - instances_layout.addWidget(hbw) + self.videos_dock = VideosDock(self) + self.skeleton_dock = SkeletonDock(self, tab_with=self.videos_dock) + self.suggestions_dock = SuggestionsDock(self, tab_with=self.videos_dock) + self.instances_dock = InstancesDock(self, tab_with=self.videos_dock) # Bring videos tab forward. - videos_layout.parent().parent().raise_() + self.videos_dock.wgt_layout.parent().parent().raise_() def _load_overlays(self): """Load all standard video overlays.""" - self.overlays["track_labels"] = TrackListOverlay(self.labels, self.player) - self.overlays["trails"] = TrackTrailOverlay(self.labels, self.player) + self.overlays["track_labels"] = TrackListOverlay( + labels=self.labels, player=self.player + ) + self.overlays["trails"] = TrackTrailOverlay( + labels=self.labels, + player=self.player, + trail_shade=self.state["trail_shade"], + trail_length=self.state["trail_length"], + ) self.overlays["instance"] = InstanceOverlay( - self.labels, self.player, self.state + labels=self.labels, player=self.player, state=self.state ) # When gui state changes, we also want to set corresponding attribute @@ -1158,6 +1070,7 @@ def overlay_state_connect(overlay, state_key, overlay_attribute=None): ) overlay_state_connect(self.overlays["trails"], "trail_length") + overlay_state_connect(self.overlays["trails"], "trail_shade") overlay_state_connect(self.color_manager, "palette") overlay_state_connect(self.color_manager, "distinctly_color") @@ -1201,8 +1114,8 @@ def _update_gui_state(self): ) # todo: exclude predicted instances from count has_nodes_selected = ( - self.skeletonEdgesSrc.currentIndex() > -1 - and self.skeletonEdgesDst.currentIndex() > -1 + self.skeleton_dock.skeletonEdgesSrc.currentIndex() > -1 + and self.skeleton_dock.skeletonEdgesDst.currentIndex() > -1 ) control_key_down = QApplication.queryKeyboardModifiers() == Qt.ControlModifier @@ -1237,9 +1150,11 @@ def _update_gui_state(self): self._buttons["delete node"].setEnabled(has_selected_node) self._buttons["toggle grayscale"].setEnabled(has_video) self._buttons["show video"].setEnabled(has_selected_video) - self._buttons["remove video"].setEnabled(has_selected_video) + self._buttons["remove video"].setEnabled(has_video) self._buttons["delete instance"].setEnabled(has_selected_instance) - self.suggestions_form_widget.buttons["generate_button"].setEnabled(has_videos) + self.suggestions_dock.suggestions_form_widget.buttons[ + "generate_button" + ].setEnabled(has_videos) # Update overlays self.overlays["track_labels"].visible = ( @@ -1281,24 +1196,28 @@ def _has_topic(topic_list): self._update_track_menu() if _has_topic([UpdateTopic.video]): - self.videosTable.model().items = self.labels.videos + self.videos_dock.table.model().items = self.labels.videos if _has_topic([UpdateTopic.skeleton]): - self.skeletonNodesTable.model().items = self.state["skeleton"] - self.skeletonEdgesTable.model().items = self.state["skeleton"] - self.skeletonEdgesSrc.model().skeleton = self.state["skeleton"] - self.skeletonEdgesDst.model().skeleton = self.state["skeleton"] + self.skeleton_dock.nodes_table.model().items = self.state["skeleton"] + self.skeleton_dock.edges_table.model().items = self.state["skeleton"] + self.skeleton_dock.skeletonEdgesSrc.model().skeleton = self.state[ + "skeleton" + ] + self.skeleton_dock.skeletonEdgesDst.model().skeleton = self.state[ + "skeleton" + ] if self.labels.skeletons: - self.suggestions_form_widget.set_field_options( + self.suggestions_dock.suggestions_form_widget.set_field_options( "node", self.labels.skeletons[0].node_names ) if _has_topic([UpdateTopic.project, UpdateTopic.on_frame]): - self.instancesTable.model().items = self.state["labeled_frame"] + self.instances_dock.table.model().items = self.state["labeled_frame"] if _has_topic([UpdateTopic.suggestions]): - self.suggestionsTable.model().items = self.labels.suggestions + self.suggestions_dock.table.model().items = self.labels.suggestions if _has_topic([UpdateTopic.project_instances, UpdateTopic.suggestions]): # update count of suggested frames w/ labeled instances @@ -1316,7 +1235,7 @@ def _has_topic(topic_list): suggestion_status_text = ( f"{labeled_count}/{len(suggestion_list)} labeled ({prc:.1f}%)" ) - self.suggested_count_label.setText(suggestion_status_text) + self.suggestions_dock.suggested_count_label.setText(suggestion_status_text) if _has_topic([UpdateTopic.frame, UpdateTopic.project_instances]): self.state["last_interacted_frame"] = self.state["labeled_frame"] @@ -1328,21 +1247,31 @@ def plotFrame(self, *args, **kwargs): self.player.plot() - def _after_plot_update(self, player, frame_idx, selected_inst): + def _after_plot_update(self, frame_idx): + """Run after plot is updated, but stay on same frame.""" + overlay: TrackTrailOverlay = self.overlays["trails"] + overlay.redraw(self.state["video"], frame_idx) + + def _after_plot_change(self, player, frame_idx, selected_inst): """Called each time a new frame is drawn.""" - # Store the current LabeledFrame (or make new, empty object) - self.state["labeled_frame"] = self.labels.find( - self.state["video"], frame_idx, return_new=True - )[0] + # Store the current frame_idx and LabeledFrame (or make new, empty object) + self.state["frame_idx"] = frame_idx + self.state["labeled_frame"] = ( + self.labels.find(self.state["video"], frame_idx, return_new=True)[0] + if frame_idx is not None + else None + ) # Show instances, etc, for this frame for overlay in self.overlays.values(): - overlay.add_to_scene(self.state["video"], frame_idx) + overlay.redraw(self.state["video"], frame_idx) # Select instance if there was already selection if selected_inst is not None: player.view.selectInstance(selected_inst) + else: + self.state["instance"] = None if self.state["fit"]: player.zoomToFit() @@ -1364,19 +1293,21 @@ def updateStatusMessage(self, message: Optional[str] = None): if message is None: message = "" - if len(self.labels.videos) > 1: + if len(self.labels.videos) > 0 and current_video is not None: message += f"Video {self.labels.videos.index(current_video)+1}/" message += f"{len(self.labels.videos)}" message += spacer - message += f"Frame: {frame_idx+1:,}/{len(current_video):,}" + if current_video is not None: + message += f"Frame: {frame_idx+1:,}/{len(current_video):,}" + if self.player.seekbar.hasSelection(): start, end = self.state["frame_range"] message += spacer message += f"Selection: {start+1:,}-{end:,} ({end-start+1:,} frames)" message += f"{spacer}Labeled Frames: " - if current_video is not None and current_video in self.labels.videos: + if current_video is not None: message += str( self.labels.get_labeled_frame_count(current_video, "user") ) @@ -1409,7 +1340,7 @@ def updateStatusMessage(self, message: Optional[str] = None): message += f" [Hidden] Press '{hide_key}' to toggle." self.statusBar().setStyleSheet("color: red") else: - self.statusBar().setStyleSheet("color: black") + self.statusBar().setStyleSheet("") self.statusBar().showMessage(message) @@ -1422,80 +1353,42 @@ def resetPrefs(self): ) msg.exec_() - def loadProjectFile(self, filename: Optional[str] = None): - """ - Loads given labels file into GUI. - - Args: - filename: The path to the saved labels dataset. If None, - then don't do anything. - - Returns: - None: - """ - if len(filename) == 0: - return - - gui_video_callback = Labels.make_gui_video_callback( - search_paths=[os.path.dirname(filename)] - ) - - has_loaded = False - labels = None - if type(filename) == Labels: - labels = filename - filename = None - has_loaded = True + def openPrefs(self): + """Open preference file directory""" + pref_path = get_config_file("preferences.yaml") + # Make sure the pref_path is a directory rather than a file + if pref_path.is_file(): + pref_path = pref_path.parent + # Open the file explorer at the folder containing the preferences.yaml file + if sys.platform == "win32": + subprocess.Popen(["explorer", str(pref_path)]) + elif sys.platform == "darwin": + subprocess.Popen(["open", str(pref_path)]) else: - try: - labels = Labels.load_file(filename, video_search=gui_video_callback) - has_loaded = True - except ValueError as e: - print(e) - QMessageBox(text=f"Unable to load {filename}.").exec_() - - if has_loaded: - self.loadLabelsObject(labels, filename) - self.state["project_loaded"] = True - - def loadLabelsObject(self, labels: Labels, filename: Optional[str] = None): - """ - Loads a `Labels` object into the GUI, replacing any currently loaded. - - Args: - labels: The `Labels` object to load. - filename: The filename where this file is saved, if any. - - Returns: - None. - - """ - self.state["labels"] = labels - self.state["filename"] = filename - - self.commands.changestack_clear() - self.color_manager.labels = self.labels - self.color_manager.set_palette(self.state["palette"]) - - self._load_overlays() - - if len(self.labels.skeletons): - self.state["skeleton"] = self.labels.skeletons[0] - - # Load first video - if len(self.labels.videos): - self.state["video"] = self.labels.videos[0] - - self.on_data_update([UpdateTopic.project, UpdateTopic.all]) + subprocess.Popen(["xdg-open", str(pref_path)]) def _update_track_menu(self): """Updates track menu options.""" self.track_menu.clear() self.delete_tracks_menu.clear() + + # Create a dictionary mapping track indices to Qt.Key values + key_mapping = { + 0: Qt.Key_1, + 1: Qt.Key_2, + 2: Qt.Key_3, + 3: Qt.Key_4, + 4: Qt.Key_5, + 5: Qt.Key_6, + 6: Qt.Key_7, + 7: Qt.Key_8, + 8: Qt.Key_9, + 9: Qt.Key_0, + } for track_ind, track in enumerate(self.labels.tracks): key_command = "" if track_ind < 9: - key_command = Qt.CTRL + Qt.Key_0 + self.labels.tracks.index(track) + 1 + key_command = Qt.CTRL | key_mapping[track_ind] self.track_menu.addAction( f"{track.name}", lambda x=track: self.commands.setInstanceTrack(x), @@ -1505,7 +1398,7 @@ def _update_track_menu(self): f"{track.name}", lambda x=track: self.commands.deleteTrack(x) ) self.track_menu.addAction( - "New Track", self.commands.addTrack, Qt.CTRL + Qt.Key_0 + "New Track", self.commands.addTrack, Qt.CTRL | Qt.Key_0 ) def _update_seekbar_marks(self): @@ -1522,6 +1415,8 @@ def _set_seekbar_header(self, graph_name: str): "Point Displacement (max)": data_obj.get_point_displacement_series, "Primary Point Displacement (sum)": data_obj.get_primary_point_displacement_series, "Primary Point Displacement (max)": data_obj.get_primary_point_displacement_series, + "Tracking Score (mean)": data_obj.get_tracking_score_series, + "Tracking Score (min)": data_obj.get_tracking_score_series, "Instance Score (sum)": data_obj.get_instance_score_series, "Instance Score (min)": data_obj.get_instance_score_series, "Point Score (sum)": data_obj.get_point_score_series, @@ -1535,7 +1430,7 @@ def _set_seekbar_header(self, graph_name: str): else: if graph_name in header_functions: kwargs = dict(video=self.state["video"]) - reduction_name = re.search("\\((sum|max|min)\\)", graph_name) + reduction_name = re.search("\\((sum|max|min|mean)\\)", graph_name) if reduction_name is not None: kwargs["reduction"] = reduction_name.group(1) series = header_functions[graph_name](**kwargs) @@ -1762,8 +1657,12 @@ def _show_keyboard_shortcuts_window(self): ShortcutDialog().exec_() -def main(): - """Starts new instance of app.""" +def create_sleap_label_parser(): + """Creates parser for `sleap-label` command line arguments. + + Returns: + argparse.ArgumentParser: The parser. + """ import argparse @@ -1795,8 +1694,32 @@ def main(): const=True, default=False, ) + parser.add_argument( + "--no-usage-data", + help=("Launch the GUI without sharing usage data regardless of preferences."), + action="store_const", + const=True, + default=False, + ) - args = parser.parse_args() + return parser + + +def create_app(): + """Creates Qt application.""" + + app = QApplication([]) + app.setApplicationName(f"SLEAP v{sleap.version.__version__}") + app.setWindowIcon(QtGui.QIcon(sleap.util.get_package_file("gui/icon.png"))) + + return app + + +def main(args: Optional[list] = None, labels: Optional[Labels] = None): + """Starts new instance of app.""" + + parser = create_sleap_label_parser() + args = parser.parse_args(args) if args.nonnative: os.environ["USE_NON_NATIVE_FILE"] = "1" @@ -1807,15 +1730,26 @@ def main(): # https://stackoverflow.com/q/64818879 os.environ["QT_MAC_WANTS_LAYER"] = "1" - app = QApplication([]) - app.setApplicationName(f"SLEAP v{sleap.version.__version__}") - app.setWindowIcon(QtGui.QIcon(sleap.util.get_package_file("sleap/gui/icon.png"))) + app = create_app() - window = MainWindow(labels_path=args.labels_path, reset=args.reset) + window = MainWindow( + labels_path=args.labels_path, + labels=labels, + reset=args.reset, + no_usage_data=args.no_usage_data, + ) window.showMaximized() # Disable GPU in GUI process. This does not affect subprocesses. - sleap.use_cpu_only() + try: + sleap.use_cpu_only() + except RuntimeError: # Visible devices cannot be modified after being initialized + logger.warning( + "Running processes on the GPU. Restarting your GUI should allow switching " + "back to CPU-only mode.\n" + "Received the following error when trying to switch back to CPU-only mode:" + ) + traceback.print_exc() # Print versions. print() @@ -1831,6 +1765,4 @@ def main(): else: app.exec_() - -if __name__ == "__main__": - main() + pass diff --git a/sleap/gui/color.py b/sleap/gui/color.py index dee888144..6172d236d 100644 --- a/sleap/gui/color.py +++ b/sleap/gui/color.py @@ -170,7 +170,9 @@ def get_track_color(self, track: Union[Track, int]) -> ColorTupleType: Returns: (r, g, b)-tuple """ - track_idx = self.tracks.index(track) if isinstance(track, Track) else track + track_idx = track + if isinstance(track, Track): + track_idx = self.tracks.index(track) if track in self.tracks else None if track_idx is None: return (0, 0, 0) diff --git a/sleap/gui/commands.py b/sleap/gui/commands.py index da3c91617..fca982327 100644 --- a/sleap/gui/commands.py +++ b/sleap/gui/commands.py @@ -26,46 +26,47 @@ class which inherits from `AppCommand` (or a more specialized class such as for now it's at least easy to see where this separation is violated. """ -import attr +import logging import operator import os -import cv2 import re -import sys import subprocess - +import sys +import traceback from enum import Enum from glob import glob -from pathlib import PurePath, Path -from typing import Callable, Dict, Iterator, List, Optional, Type, Tuple +from pathlib import Path, PurePath +from typing import Callable, Dict, Iterator, List, Optional, Tuple, Type, Union, cast +import attr +import cv2 import numpy as np +from qtpy import QtCore, QtGui, QtWidgets -from qtpy import QtCore, QtWidgets, QtGui - -from qtpy.QtWidgets import QMessageBox, QProgressDialog - -from sleap.skeleton import Node, Skeleton -from sleap.instance import Instance, PredictedInstance, Point, Track, LabeledFrame -from sleap.io.video import Video -from sleap.io.convert import default_analysis_filename -from sleap.io.dataset import Labels -from sleap.io.format.adaptor import Adaptor -from sleap.io.format.ndx_pose import NDXPoseAdaptor from sleap.gui.dialogs.delete import DeleteDialog -from sleap.gui.dialogs.importvideos import ImportVideos from sleap.gui.dialogs.filedialog import FileDialog -from sleap.gui.dialogs.missingfiles import MissingFilesDialog -from sleap.gui.dialogs.merge import MergeDialog +from sleap.gui.dialogs.importvideos import ImportVideos +from sleap.gui.dialogs.merge import MergeDialog, ReplaceSkeletonTableDialog from sleap.gui.dialogs.message import MessageDialog -from sleap.gui.dialogs.query import QueryDialog -from sleap.gui.suggestions import VideoFrameSuggestions +from sleap.gui.dialogs.missingfiles import MissingFilesDialog +from sleap.gui.dialogs.frame_range import FrameRangeDialog from sleap.gui.state import GuiState - +from sleap.gui.suggestions import VideoFrameSuggestions +from sleap.instance import Instance, LabeledFrame, Point, PredictedInstance, Track +from sleap.io.convert import default_analysis_filename +from sleap.io.dataset import Labels +from sleap.io.format.adaptor import Adaptor +from sleap.io.format.csv import CSVAdaptor +from sleap.io.format.ndx_pose import NDXPoseAdaptor +from sleap.io.video import Video +from sleap.skeleton import Node, Skeleton +from sleap.util import get_package_file # Indicates whether we support multiple project windows (i.e., "open" opens new window) OPEN_IN_NEW = True +logger = logging.getLogger(__name__) + class UpdateTopic(Enum): """Topics so context can tell callback what was updated by the command.""" @@ -199,6 +200,7 @@ class CommandContext: def from_labels(cls, labels: Labels) -> "CommandContext": """Creates a command context for use independently of GUI app.""" state = GuiState() + state["labels"] = labels app = FakeApp(labels) return cls(state=state, app=app) @@ -245,9 +247,33 @@ def newProject(self): """Create a new project in a new window.""" self.execute(NewProject) - def openProject(self, filename: Optional[str] = None, first_open: bool = False): + def loadLabelsObject(self, labels: Labels, filename: Optional[str] = None): + """Loads a `Labels` object into the GUI, replacing any currently loaded. + + Args: + labels: The `Labels` object to load. + filename: The filename where this file is saved, if any. + + Returns: + None. + """ - Allows use to select and then open a saved project. + self.execute(LoadLabelsObject, labels=labels, filename=filename) + + def loadProjectFile(self, filename: Union[str, Labels]): + """Loads given labels file into GUI. + + Args: + filename: The path to the saved labels dataset or the `Labels` object. + If None, then don't do anything. + + Returns: + None + """ + self.execute(LoadProjectFile, filename=filename) + + def openProject(self, filename: Optional[str] = None, first_open: bool = False): + """Allows user to select and then open a saved project. Args: filename: Filename of the project to be opened. If None, a file browser @@ -303,7 +329,11 @@ def saveProjectAs(self): def exportAnalysisFile(self, all_videos: bool = False): """Shows gui for exporting analysis h5 file.""" - self.execute(ExportAnalysisFile, all_videos=all_videos) + self.execute(ExportAnalysisFile, all_videos=all_videos, csv=False) + + def exportCSVFile(self, all_videos: bool = False): + """Shows gui for exporting analysis csv file.""" + self.execute(ExportAnalysisFile, all_videos=all_videos, csv=True) def exportNWB(self): """Show gui for exporting nwb file.""" @@ -401,6 +431,10 @@ def removeVideo(self): """Removes selected video from project.""" self.execute(RemoveVideo) + def openSkeletonTemplate(self): + """Shows gui for loading saved skeleton into project.""" + self.execute(OpenSkeleton, template=True) + def openSkeleton(self): """Shows gui for loading saved skeleton into project.""" self.execute(OpenSkeleton) @@ -457,8 +491,12 @@ def deleteLowScorePredictions(self): """Gui for deleting instances below some score threshold.""" self.execute(DeleteLowScorePredictions) - def deleteFrameLimitPredictions(self): + def deleteInstanceLimitPredictions(self): """Gui for deleting instances beyond some number in each frame.""" + self.execute(DeleteInstanceLimitPredictions) + + def deleteFrameLimitPredictions(self): + """Gui for deleting instances beyond some frame number.""" self.execute(DeleteFrameLimitPredictions) def completeInstanceNodes(self, instance: Instance): @@ -471,6 +509,7 @@ def newInstance( init_method: str = "best", location: Optional[QtCore.QPoint] = None, mark_complete: bool = False, + offset: int = 0, ): """Creates a new instance, copying node coordinates as appropriate. @@ -480,6 +519,8 @@ def newInstance( init_method: Method to use for positioning nodes. location: The location where instance should be added (if node init method supports custom location). + mark_complete: Whether to mark the instance as complete. + offset: Offset to apply to the location if given. """ self.execute( AddInstance, @@ -487,6 +528,7 @@ def newInstance( init_method=init_method, location=location, mark_complete=mark_complete, + offset=offset, ) def setPointLocations( @@ -506,8 +548,17 @@ def setInstancePointVisibility(self, instance: Instance, node: Node, visible: bo ) def addUserInstancesFromPredictions(self): + """Create user instance from a predicted instance.""" self.execute(AddUserInstancesFromPredictions) + def copyInstance(self): + """Copy the selected instance to the instance clipboard.""" + self.execute(CopyInstance) + + def pasteInstance(self): + """Paste the instance from the clipboard as a new copy.""" + self.execute(PasteInstance) + def deleteSelectedInstance(self): """Deletes currently selected instance.""" self.execute(DeleteSelectedInstance) @@ -532,9 +583,17 @@ def deleteTrack(self, track: "Track"): """Delete a track and remove from all instances.""" self.execute(DeleteTrack, track=track) - def deleteAllTracks(self): + def deleteMultipleTracks(self, delete_all: bool = False): """Delete all tracks.""" - self.execute(DeleteAllTracks) + self.execute(DeleteMultipleTracks, delete_all=delete_all) + + def copyInstanceTrack(self): + """Copies the selected instance's track to the track clipboard.""" + self.execute(CopyInstanceTrack) + + def pasteInstanceTrack(self): + """Pastes the track in the clipboard to the selected instance.""" + self.execute(PasteInstanceTrack) def setTrackName(self, track: "Track", name: str): """Sets name for track.""" @@ -584,6 +643,76 @@ def do_action(context: CommandContext, params: dict): window.showMaximized() +class LoadLabelsObject(AppCommand): + @staticmethod + def do_action(context: "CommandContext", params: dict): + """Loads a `Labels` object into the GUI, replacing any currently loaded. + + Args: + labels: The `Labels` object to load. + filename: The filename where this file is saved, if any. + + Returns: + None. + """ + filename = params.get("filename", None) # If called with just a Labels object + labels: Labels = params["labels"] + + context.state["labels"] = labels + context.state["filename"] = filename + + context.changestack_clear() + context.app.color_manager.labels = context.labels + context.app.color_manager.set_palette(context.state["palette"]) + + context.app._load_overlays() + + if len(labels.skeletons): + context.state["skeleton"] = labels.skeletons[0] + + # Load first video + if len(labels.videos): + context.state["video"] = labels.videos[0] + + context.state["project_loaded"] = True + context.state["has_changes"] = params.get("changed_on_load", False) or ( + filename is None + ) + + # This is not listed as an edit command since we want a clean changestack + context.app.on_data_update([UpdateTopic.project, UpdateTopic.all]) + + +class LoadProjectFile(LoadLabelsObject): + @staticmethod + def ask(context: "CommandContext", params: dict): + filename = params["filename"] + + if len(filename) == 0: + return + + has_loaded = False + labels = None + if isinstance(filename, Labels): + labels = filename + filename = None + has_loaded = True + else: + gui_video_callback = Labels.make_gui_video_callback( + search_paths=[os.path.dirname(filename)], context=params + ) + try: + labels = Labels.load_file(filename, video_search=gui_video_callback) + has_loaded = True + except ValueError as e: + print(e) + QtWidgets.QMessageBox(text=f"Unable to load {filename}.").exec_() + + params["labels"] = labels + + return has_loaded + + class OpenProject(AppCommand): @staticmethod def do_action(context: "CommandContext", params: dict): @@ -600,9 +729,9 @@ def do_action(context: "CommandContext", params: dict): if do_open_in_new: new_window = context.app.__class__() new_window.showMaximized() - new_window.loadProjectFile(filename) + new_window.commands.loadProjectFile(filename) else: - context.app.loadProjectFile(filename) + context.loadProjectFile(filename) @staticmethod def ask(context: "CommandContext", params: dict) -> bool: @@ -629,7 +758,6 @@ def ask(context: "CommandContext", params: dict) -> bool: class ImportAlphaTracker(AppCommand): @staticmethod def do_action(context: "CommandContext", params: dict): - video_path = params["video_path"] if "video_path" in params else None labels = Labels.load_alphatracker( @@ -639,7 +767,7 @@ def do_action(context: "CommandContext", params: dict): new_window = context.app.__class__() new_window.showMaximized() - new_window.loadLabelsObject(labels=labels) + new_window.commands.loadLabelsObject(labels=labels) @staticmethod def ask(context: "CommandContext", params: dict) -> bool: @@ -669,12 +797,11 @@ def ask(context: "CommandContext", params: dict) -> bool: class ImportNWB(AppCommand): @staticmethod def do_action(context: "CommandContext", params: dict): - labels = Labels.load_nwb(filename=params["filename"]) new_window = context.app.__class__() new_window.showMaximized() - new_window.loadLabelsObject(labels=labels) + new_window.commands.loadLabelsObject(labels=labels) @staticmethod def ask(context: "CommandContext", params: dict) -> bool: @@ -702,7 +829,6 @@ def ask(context: "CommandContext", params: dict) -> bool: class ImportDeepPoseKit(AppCommand): @staticmethod def do_action(context: "CommandContext", params: dict): - labels = Labels.from_deepposekit( filename=params["filename"], video_path=params["video_path"], @@ -711,7 +837,7 @@ def do_action(context: "CommandContext", params: dict): new_window = context.app.__class__() new_window.showMaximized() - new_window.loadLabelsObject(labels=labels) + new_window.commands.loadLabelsObject(labels=labels) @staticmethod def ask(context: "CommandContext", params: dict) -> bool: @@ -751,14 +877,13 @@ def ask(context: "CommandContext", params: dict) -> bool: class ImportLEAP(AppCommand): @staticmethod def do_action(context: "CommandContext", params: dict): - labels = Labels.load_leap_matlab( filename=params["filename"], ) new_window = context.app.__class__() new_window.showMaximized() - new_window.loadLabelsObject(labels=labels) + new_window.commands.loadLabelsObject(labels=labels) @staticmethod def ask(context: "CommandContext", params: dict) -> bool: @@ -782,14 +907,13 @@ def ask(context: "CommandContext", params: dict) -> bool: class ImportCoco(AppCommand): @staticmethod def do_action(context: "CommandContext", params: dict): - labels = Labels.load_coco( filename=params["filename"], img_dir=params["img_dir"], use_missing_gui=True ) new_window = context.app.__class__() new_window.showMaximized() - new_window.loadLabelsObject(labels=labels) + new_window.commands.loadLabelsObject(labels=labels) @staticmethod def ask(context: "CommandContext", params: dict) -> bool: @@ -814,12 +938,11 @@ def ask(context: "CommandContext", params: dict) -> bool: class ImportDeepLabCut(AppCommand): @staticmethod def do_action(context: "CommandContext", params: dict): - labels = Labels.load_deeplabcut(filename=params["filename"]) new_window = context.app.__class__() new_window.showMaximized() - new_window.loadLabelsObject(labels=labels) + new_window.commands.loadLabelsObject(labels=labels) @staticmethod def ask(context: "CommandContext", params: dict) -> bool: @@ -857,7 +980,7 @@ def do_action(context: "CommandContext", params: dict): new_window = context.app.__class__() new_window.showMaximized() - new_window.loadLabelsObject(labels=merged_labels) + new_window.commands.loadLabelsObject(labels=merged_labels) @staticmethod def ask(context: "CommandContext", params: dict) -> bool: @@ -902,7 +1025,7 @@ def do_action(context: "CommandContext", params: dict): new_window = context.app.__class__() new_window.showMaximized() - new_window.loadLabelsObject(labels=labels) + new_window.commands.loadLabelsObject(labels=labels) @staticmethod def ask(context: "CommandContext", params: dict) -> bool: @@ -1005,12 +1128,30 @@ def ask(context: CommandContext, params: dict) -> bool: class ExportAnalysisFile(AppCommand): + export_formats = { + "SLEAP Analysis HDF5 (*.h5)": "h5", + "NIX for Tracking data (*.nix)": "nix", + } + export_filter = ";;".join(export_formats.keys()) + + export_formats_csv = { + "CSV (*.csv)": "csv", + } + export_filter_csv = ";;".join(export_formats_csv.keys()) + @classmethod def do_action(cls, context: CommandContext, params: dict): + from sleap.io.format.nix import NixAdaptor from sleap.io.format.sleap_analysis import SleapAnalysisAdaptor for output_path, video in params["analysis_videos"]: - SleapAnalysisAdaptor.write( + if params["csv"]: + adaptor = CSVAdaptor + elif Path(output_path).suffix[1:] == "nix": + adaptor = NixAdaptor + else: + adaptor = SleapAnalysisAdaptor + adaptor.write( filename=output_path, source_object=context.labels, source_path=context.state["filename"], @@ -1019,20 +1160,26 @@ def do_action(cls, context: CommandContext, params: dict): @staticmethod def ask(context: CommandContext, params: dict) -> bool: - def ask_for_filename(default_name: str) -> str: + def ask_for_filename(default_name: str, csv: bool) -> str: """Allow user to specify the filename""" + filter = ( + ExportAnalysisFile.export_filter_csv + if csv + else ExportAnalysisFile.export_filter + ) filename, selected_filter = FileDialog.save( context.app, caption="Export Analysis File...", dir=default_name, - filter="SLEAP Analysis HDF5 (*.h5)", + filter=filter, ) return filename # Ensure labels has labeled frames labels = context.labels + is_csv = params["csv"] if len(labels.labeled_frames) == 0: - return False + raise ValueError("No labeled frames in project. Nothing to export.") # Get a subset of videos if params["all_videos"]: @@ -1043,11 +1190,12 @@ def ask_for_filename(default_name: str) -> str: # Only use videos with labeled frames videos = [video for video in all_videos if len(labels.get(video)) != 0] if len(videos) == 0: - return False + raise ValueError("No labeled frames in video(s). Nothing to export.") # Specify (how to get) the output filename default_name = context.state["filename"] or "labels" fn = PurePath(default_name) + file_extension = "csv" if is_csv else "h5" if len(videos) == 1: # Allow user to specify the filename use_default = False @@ -1060,6 +1208,23 @@ def ask_for_filename(default_name: str) -> str: caption="Select Folder to Export Analysis Files...", dir=str(fn.parent), ) + export_format = ( + ExportAnalysisFile.export_formats_csv + if is_csv + else ExportAnalysisFile.export_formats + ) + if len(export_format) > 1: + item, ok = QtWidgets.QInputDialog.getItem( + context.app, + "Select export format", + "Available export formats", + list(export_format.keys()), + 0, + False, + ) + if not ok: + return False + file_extension = export_format[item] if len(dirname) == 0: return False @@ -1073,10 +1238,13 @@ def ask_for_filename(default_name: str) -> str: video=video, output_path=dirname, output_prefix=str(fn.stem), + format_suffix=file_extension, ) - filename = default_name if use_default else ask_for_filename(default_name) - # Check that filename is valid and create list of video / ouput paths + filename = ( + default_name if use_default else ask_for_filename(default_name, is_csv) + ) + # Check that filename is valid and create list of video / output paths if len(filename) != 0: analysis_videos.append(video) output_paths.append(filename) @@ -1128,7 +1296,10 @@ def do_action(context: CommandContext, params: dict): frames=list(params["frames"]), fps=params["fps"], color_manager=params["color_manager"], + background=params["background"], show_edges=params["show edges"], + edge_is_wedge=params["edge_is_wedge"], + marker_size=params["marker size"], scale=params["scale"], crop_size_xy=params["crop"], gui_progress=True, @@ -1140,7 +1311,6 @@ def do_action(context: CommandContext, params: dict): @staticmethod def ask(context: CommandContext, params: dict) -> bool: - from sleap.gui.dialogs.export_clip import ExportClipDialog dialog = ExportClipDialog() @@ -1164,17 +1334,15 @@ def ask(context: CommandContext, params: dict) -> bool: # makes mp4's that most programs can't open (VLC can). default_out_filename = context.state["filename"] + ".avi" - # But if we can write mpegs using sci-kit video, use .mp4 - # since it has trouble writing .avi files. - if VideoWriter.can_use_skvideo(): + if VideoWriter.can_use_ffmpeg(): default_out_filename = context.state["filename"] + ".mp4" - # Ask where use wants to save video file + # Ask where user wants to save video file filename, _ = FileDialog.save( context.app, caption="Save Video As...", dir=default_out_filename, - filter="Video (*.avi *mp4)", + filter="Video (*.avi *.mp4)", ) # Check if user hit cancel @@ -1185,6 +1353,7 @@ def ask(context: CommandContext, params: dict) -> bool: params["fps"] = export_options["fps"] params["scale"] = export_options["scale"] params["open_when_done"] = export_options["open_when_done"] + params["background"] = export_options["background"] params["crop"] = None @@ -1203,6 +1372,11 @@ def ask(context: CommandContext, params: dict) -> bool: params["color_manager"] = None params["show edges"] = context.state.get("show edges", default=True) + params["edge_is_wedge"] = ( + context.state.get("edge style", default="").lower() == "wedge" + ) + + params["marker size"] = context.state.get("marker size", default=4) # If user selected a clip, use that; otherwise include all frames. if context.state["has_frame_range"]: @@ -1214,7 +1388,11 @@ def ask(context: CommandContext, params: dict) -> bool: def export_dataset_gui( - labels: Labels, filename: str, all_labeled: bool = False, suggested: bool = False + labels: Labels, + filename: str, + all_labeled: bool = False, + suggested: bool = False, + verbose: bool = True, ) -> str: """Export dataset with image data and display progress GUI dialog. @@ -1222,10 +1400,15 @@ def export_dataset_gui( labels: `sleap.Labels` dataset to export. filename: Output filename. Should end in `.pkg.slp`. all_labeled: If `True`, export all labeled frames, including frames with no user - instances. - suggested: If `True`, include image data for suggested frames. + instances. Defaults to `False`. + suggested: If `True`, include image data for suggested frames. Defaults to + `False`. + verbose: If `True`, display progress dialog. Defaults to `True`. """ - win = QProgressDialog("Exporting dataset with frame images...", "Cancel", 0, 1) + if verbose: + win = QtWidgets.QProgressDialog( + "Exporting dataset with frame images...", "Cancel", 0, 1 + ) def update_progress(n, n_total): if win.wasCanceled(): @@ -1246,15 +1429,16 @@ def update_progress(n, n_total): save_frame_data=True, all_labeled=all_labeled, suggested=suggested, - progress_callback=update_progress, + progress_callback=update_progress if verbose else None, ) - if win.wasCanceled(): - # Delete output if saving was canceled. - os.remove(filename) - return "canceled" + if verbose: + if win.wasCanceled(): + # Delete output if saving was canceled. + os.remove(filename) + return "canceled" - win.hide() + win.hide() return filename @@ -1270,6 +1454,7 @@ def do_action(cls, context: CommandContext, params: dict): filename=params["filename"], all_labeled=cls.all_labeled, suggested=cls.suggested, + verbose=params.get("verbose", True), ) @staticmethod @@ -1399,7 +1584,6 @@ class GoNextSuggestedFrame(NavCommand): @classmethod def do_action(cls, context: CommandContext, params: dict): - next_suggestion_frame = context.labels.get_next_suggestion( context.state["video"], context.state["frame_idx"], cls.seek_direction ) @@ -1503,22 +1687,36 @@ class ToggleGrayscale(EditCommand): @staticmethod def do_action(context: CommandContext, params: dict): """Reset the video backend.""" - video: Video = context.state["video"] - try: - grayscale = video.backend.grayscale - video.backend.reset(grayscale=(not grayscale)) - except: - print( - f"This video type {type(video.backend)} does not support grayscale yet." - ) - @staticmethod - def ask(context: CommandContext, params: dict) -> bool: - """Check that video can be reset.""" + def try_to_read_grayscale(video: Video): + try: + return video.backend.grayscale + except: + return None + # Check that current video is set - if context.state["video"] is None: - return False - return True + if len(context.labels.videos) == 0: + raise ValueError("No videos detected in `Labels`.") + + # Intuitively find the "first" video that supports grayscale + grayscale = try_to_read_grayscale(context.state["video"]) + if grayscale is None: + for video in context.labels.videos: + grayscale = try_to_read_grayscale(video) + if grayscale is not None: + break + + if grayscale is None: + raise ValueError("No videos support grayscale.") + + for idx, video in enumerate(context.labels.videos): + try: + video.backend.reset(grayscale=(not grayscale)) + except: + print( + f"This video type {type(video.backend)} for video at index {idx} " + f"does not support grayscale yet." + ) class AddVideo(EditCommand): @@ -1571,7 +1769,6 @@ class ReplaceVideo(EditCommand): @staticmethod def do_action(context: CommandContext, params: dict) -> bool: - import_list = params["import_list"] for import_item, video in import_list: @@ -1627,7 +1824,7 @@ def _get_truncation_message(truncation_messages, path, video): # Warn user: newly added labels will be discarded if project is not saved if not context.state["filename"] or context.state["has_changes"]: - QMessageBox( + QtWidgets.QMessageBox( text=("You have unsaved changes. Please save before replacing videos.") ).exec_() return False @@ -1671,44 +1868,60 @@ def _get_truncation_message(truncation_messages, path, video): class RemoveVideo(EditCommand): - topics = [UpdateTopic.video] + topics = [UpdateTopic.video, UpdateTopic.suggestions, UpdateTopic.frame] @staticmethod def do_action(context: CommandContext, params: dict): - video = params["video"] - # Remove video - context.labels.remove_video(video) + videos = context.labels.videos + row_idxs = context.state["selected_batch_video"] + videos_to_be_removed = [videos[i] for i in row_idxs] - # Update view if this was the current video - if context.state["video"] == video: - if len(context.labels.videos) > 0: + # Remove selected videos in the project + for video in videos_to_be_removed: + context.labels.remove_video(video) + + # Update the view if state has the removed video + if context.state["video"] in videos_to_be_removed: + if len(context.labels.videos): context.state["video"] = context.labels.videos[-1] else: context.state["video"] = None + if len(context.labels.videos) == 0: + context.app.updateStatusMessage(" ") + @staticmethod def ask(context: CommandContext, params: dict) -> bool: - video = context.state["selected_video"] - if video is None: - return False + videos = context.labels.videos.copy() + row_idxs = context.state["selected_batch_video"] + video_file_names = [] + total_num_labeled_frames = 0 + for idx in row_idxs: + video = videos[idx] + if video is None: + return False + + # Count labeled frames for this video + n = len(context.labels.find(video)) - # Count labeled frames for this video - n = len(context.labels.find(video)) + if n > 0: + total_num_labeled_frames += n + video_file_names.append( + f"{video}".split(", shape")[0].split("filename=")[-1].split("/")[-1] + ) # Warn if there are labels that will be deleted - if n > 0: - response = QMessageBox.critical( + if len(video_file_names) >= 1: + response = QtWidgets.QMessageBox.critical( context.app, "Removing video with labels", - f"{n} labeled frames in this video will be deleted, " - "are you sure you want to remove this video?", - QMessageBox.Yes, - QMessageBox.No, + f"{total_num_labeled_frames} labeled frames in {', '.join(video_file_names)} will be deleted, " + "are you sure you want to remove the videos?", + QtWidgets.QMessageBox.Yes, + QtWidgets.QMessageBox.No, ) - if response == QMessageBox.No: + if response == QtWidgets.QMessageBox.No: return False - - params["video"] = video return True @@ -1727,8 +1940,7 @@ def load_skeleton(filename: str): @staticmethod def compare_skeletons( skeleton: Skeleton, new_skeleton: Skeleton - ) -> Tuple[List[str], List[str]]: - + ) -> Tuple[List[str], List[str], List[str]]: delete_nodes = [] add_nodes = [] if skeleton.node_names != new_skeleton.node_names: @@ -1738,7 +1950,12 @@ def compare_skeletons( delete_nodes = [node for node in base_nodes if node not in new_nodes] add_nodes = [node for node in new_nodes if node not in base_nodes] - return delete_nodes, add_nodes + # We want to run this even if the skeletons are the same + rename_nodes = [ + node for node in skeleton.node_names if node not in delete_nodes + ] + + return rename_nodes, delete_nodes, add_nodes @staticmethod def delete_extra_skeletons(labels: Labels): @@ -1760,12 +1977,34 @@ def delete_extra_skeletons(labels: Labels): labels.skeletons = skeletons_used @staticmethod - def ask(context: CommandContext, params: dict) -> bool: + def get_template_skeleton_filename(context: CommandContext) -> str: + """Helper function to get the template skeleton filename from dropdown. + + Args: + context: The `CommandContext`. + + Returns: + Path to the template skeleton shipped with SLEAP. + """ + + template = context.app.skeleton_dock.skeleton_templates.currentText() + filename = get_package_file(f"skeletons/{template}.json") + return filename + @staticmethod + def ask(context: CommandContext, params: dict) -> bool: filters = ["JSON skeleton (*.json)", "HDF5 skeleton (*.h5 *.hdf5)"] - filename, selected_filter = FileDialog.open( - context.app, dir=None, caption="Open skeleton...", filter=";;".join(filters) - ) + # Check whether to load from file or preset + if params.get("template", False): + # Get selected template from dropdown + filename = OpenSkeleton.get_template_skeleton_filename(context) + else: + filename, selected_filter = FileDialog.open( + context.app, + dir=None, + caption="Open skeleton...", + filter=";;".join(filters), + ) if len(filename) == 0: return False @@ -1778,27 +2017,26 @@ def ask(context: CommandContext, params: dict) -> bool: # Load new skeleton and compare new_skeleton = OpenSkeleton.load_skeleton(filename) - (delete_nodes, add_nodes) = OpenSkeleton.compare_skeletons( + (rename_nodes, delete_nodes, add_nodes) = OpenSkeleton.compare_skeletons( skeleton, new_skeleton ) if (len(delete_nodes) > 0) or (len(add_nodes) > 0): - # Warn about mismatching skeletons - title = "Replace Skeleton" - message = ( - "

Warning: Pre-existing skeleton found." - "

The following nodes will be deleted from all instances:" - f"
From base labels: {','.join(delete_nodes)}

" - "

The following nodes will be added to all instances:
" - f"From new labels: {','.join(add_nodes)}

" - "

Nodes can be deleted or merged from the skeleton editor after " - "merging labels.

" + # Allow user to link mismatched nodes + query = ReplaceSkeletonTableDialog( + rename_nodes=rename_nodes, + delete_nodes=delete_nodes, + add_nodes=add_nodes, ) - query = QueryDialog(title=title, message=message) query.exec_() # Give the okay to add/delete nodes - okay = bool(query.result()) + linked_nodes: Optional[Dict[str, str]] = query.result() + if linked_nodes is not None: + delete_nodes = list(set(delete_nodes) - set(linked_nodes.values())) + add_nodes = list(set(add_nodes) - set(linked_nodes.keys())) + params["linked_nodes"] = linked_nodes + okay = True params["delete_nodes"] = delete_nodes params["add_nodes"] = add_nodes @@ -1808,11 +2046,49 @@ def ask(context: CommandContext, params: dict) -> bool: @staticmethod def do_action(context: CommandContext, params: dict): + """Replace skeleton with new skeleton. + + Note that we modify the existing skeleton in-place to essentially match the new + skeleton. However, we cannot rename the skeleton since `Skeleton.name` is used + for hashing (see `Skeleton.name` setter). + + Args: + context: CommandContext + params: dict + filename: str + delete_nodes: List[str] + add_nodes: List[str] + linked_nodes: Dict[str, str] + + Returns: + None + """ + + # TODO (LM): This is a hack to get around the fact that we do some dangerous + # in-place operations on the skeleton. We should fix this. + def try_and_skip_if_error(func, *args, **kwargs): + """This is a helper function to try and skip if there is an error.""" + try: + func(*args, **kwargs) + except Exception as e: + tb_str = traceback.format_exception( + type(e), value=e, tb=e.__traceback__ + ) + logger.warning( + f"Recieved the following error while replacing skeleton:\n" + f"{''.join(tb_str)}" + ) # Load new skeleton filename = params["filename"] new_skeleton = OpenSkeleton.load_skeleton(filename) + # Description and preview image only used for template skeletons + new_skeleton.description = None + new_skeleton.preview_image = None + context.state["skeleton_description"] = new_skeleton.description + context.state["skeleton_preview_image"] = new_skeleton.preview_image + # Case 1: No skeleton exists in project if len(context.labels.skeletons) == 0: context.state["skeleton"] = new_skeleton @@ -1831,7 +2107,7 @@ def do_action(context: CommandContext, params: dict): add_nodes: List[str] = params["add_nodes"] else: # Otherwise, load new skeleton and compare - (delete_nodes, add_nodes) = OpenSkeleton.compare_skeletons( + (rename_nodes, delete_nodes, add_nodes) = OpenSkeleton.compare_skeletons( skeleton, new_skeleton ) @@ -1839,22 +2115,28 @@ def do_action(context: CommandContext, params: dict): for src, dst in skeleton.symmetries: skeleton.delete_symmetry(src, dst) + # Link mismatched nodes + if "linked_nodes" in params.keys(): + linked_nodes = params["linked_nodes"] + for new_name, old_name in linked_nodes.items(): + try_and_skip_if_error(skeleton.relabel_node, old_name, new_name) + # Delete nodes from skeleton that are not in new skeleton for node in delete_nodes: - skeleton.delete_node(node) + try_and_skip_if_error(skeleton.delete_node, node) # Add nodes that only exist in the new skeleton for node in add_nodes: - skeleton.add_node(node) + try_and_skip_if_error(skeleton.add_node, node) # Add edges skeleton.clear_edges() for src, dest in new_skeleton.edges: - skeleton.add_edge(src.name, dest.name) + try_and_skip_if_error(skeleton.add_edge, src.name, dest.name) # Add new symmetry for src, dst in new_skeleton.symmetries: - skeleton.add_symmetry(src.name, dst.name) + try_and_skip_if_error(skeleton.add_symmetry, src.name, dst.name) # Set state of context context.state["skeleton"] = skeleton @@ -2002,11 +2284,15 @@ def _confirm_deletion(context: CommandContext, lf_inst_list: List) -> bool: ) # Confirm that we want to delete - resp = QMessageBox.critical( - context.app, title, message, QMessageBox.Yes, QMessageBox.No + resp = QtWidgets.QMessageBox.critical( + context.app, + title, + message, + QtWidgets.QMessageBox.Yes, + QtWidgets.QMessageBox.No, ) - if resp == QMessageBox.No: + if resp == QtWidgets.QMessageBox.No: return False return True @@ -2017,6 +2303,8 @@ def _do_deletion(context: CommandContext, lf_inst_list: List[int]): lfs_to_remove = [] for lf, inst in lf_inst_list: context.labels.remove_instance(lf, inst, in_transaction=True) + if context.state["instance"] == inst: + context.state["instance"] = None if len(lf.instances) == 0: lfs_to_remove.append(lf) @@ -2159,7 +2447,7 @@ def ask(cls, context: CommandContext, params: dict) -> bool: return super().ask(context, params) -class DeleteFrameLimitPredictions(InstanceDeleteCommand): +class DeleteInstanceLimitPredictions(InstanceDeleteCommand): @staticmethod def get_frame_instance_list(context: CommandContext, params: dict): count_thresh = params["count_threshold"] @@ -2189,6 +2477,36 @@ def ask(cls, context: CommandContext, params: dict) -> bool: return super().ask(context, params) +class DeleteFrameLimitPredictions(InstanceDeleteCommand): + @staticmethod + def get_frame_instance_list(context: CommandContext, params: Dict): + """Called from the parent `InstanceDeleteCommand.ask` method. + + Returns: + List of instances to be deleted. + """ + instances = [] + # Select the instances to be deleted + for lf in context.labels.labeled_frames: + if lf.frame_idx < (params["min_frame_idx"] - 1) or lf.frame_idx > ( + params["max_frame_idx"] - 1 + ): + instances.extend([(lf, inst) for inst in lf.instances]) + return instances + + @classmethod + def ask(cls, context: CommandContext, params: Dict) -> bool: + current_video = context.state["video"] + dialog = FrameRangeDialog( + title="Delete Instances in Frame Range...", max_frame_idx=len(current_video) + ) + results = dialog.get_results() + if results: + params["min_frame_idx"] = results["min_frame_idx"] + params["max_frame_idx"] = results["max_frame_idx"] + return super().ask(context, params) + + class TransposeInstances(EditCommand): topics = [UpdateTopic.project_instances, UpdateTopic.tracks] @@ -2202,7 +2520,16 @@ def do_action(cls, context: CommandContext, params: dict): # Swap tracks for current and subsequent frames when we have tracks old_track, new_track = instances[0].track, instances[1].track if old_track is not None and new_track is not None: - frame_range = (context.state["frame_idx"], context.state["video"].frames) + if context.state["propagate track labels"]: + frame_range = ( + context.state["frame_idx"], + context.state["video"].frames, + ) + else: + frame_range = ( + context.state["frame_idx"], + context.state["frame_idx"] + 1, + ) context.labels.track_swap( context.state["video"], new_track, old_track, frame_range ) @@ -2245,6 +2572,7 @@ def do_action(context: CommandContext, params: dict): return context.labels.remove_instance(context.state["labeled_frame"], selected_inst) + context.state["instance"] = None class DeleteSelectedInstanceTrack(EditCommand): @@ -2262,6 +2590,7 @@ def do_action(context: CommandContext, params: dict): track = selected_inst.track context.labels.remove_instance(context.state["labeled_frame"], selected_inst) + context.state["instance"] = None if track is not None: # remove any instance on this track @@ -2367,12 +2696,55 @@ def do_action(context: CommandContext, params: dict): context.labels.remove_track(track) -class DeleteAllTracks(EditCommand): +class DeleteMultipleTracks(EditCommand): + topics = [UpdateTopic.tracks] + + @staticmethod + def do_action(context: CommandContext, params: dict): + """Delete either all tracks or just unused tracks. + + Args: + context: The command context. + params: The command parameters. + delete_all: If True, delete all tracks. If False, delete only + unused tracks. + """ + delete_all: bool = params["delete_all"] + if delete_all: + context.labels.remove_all_tracks() + else: + context.labels.remove_unused_tracks() + + +class CopyInstanceTrack(EditCommand): + @staticmethod + def do_action(context: CommandContext, params: dict): + selected_instance: Instance = context.state["instance"] + if selected_instance is None: + return + context.state["clipboard_track"] = selected_instance.track + + +class PasteInstanceTrack(EditCommand): topics = [UpdateTopic.tracks] @staticmethod def do_action(context: CommandContext, params: dict): - context.labels.remove_all_tracks() + selected_instance: Instance = context.state["instance"] + track_to_paste = context.state["clipboard_track"] + if selected_instance is None or track_to_paste is None: + return + + # Ensure mutual exclusivity of tracks within a frame. + for inst in selected_instance.frame.instances_to_show: + if inst == selected_instance: + continue + if inst.track is not None and inst.track == track_to_paste: + # Unset track for other instances that have the same track. + inst.track = None + + # Set the track on the selected instance. + selected_instance.track = context.state["clipboard_track"] class SetTrackName(EditCommand): @@ -2390,7 +2762,6 @@ class GenerateSuggestions(EditCommand): @classmethod def do_action(cls, context: CommandContext, params: dict): - if len(context.labels.videos) == 0: print("Error: no videos to generate suggestions for") return @@ -2413,11 +2784,20 @@ def do_action(cls, context: CommandContext, params: dict): else: params["videos"] = context.labels.videos - new_suggestions = VideoFrameSuggestions.suggest( - labels=context.labels, params=params - ) + try: + new_suggestions = VideoFrameSuggestions.suggest( + labels=context.labels, params=params + ) - context.labels.append_suggestions(new_suggestions) + context.labels.append_suggestions(new_suggestions) + except Exception as e: + win.hide() + QtWidgets.QMessageBox( + text=f"An error occurred while generating suggestions. " + "Your command line terminal may have more information about " + "the error." + ).exec_() + raise e win.hide() @@ -2437,7 +2817,7 @@ class RemoveSuggestion(EditCommand): @classmethod def do_action(cls, context: CommandContext, params: dict): - selected_frame = context.app.suggestionsTable.getSelectedRowItem() + selected_frame = context.app.suggestions_dock.table.getSelectedRowItem() if selected_frame is not None: context.labels.remove_suggestion( selected_frame.video, selected_frame.frame_idx @@ -2454,14 +2834,14 @@ def ask(context: CommandContext, params: dict) -> bool: # Warn that suggestions will be cleared - response = QMessageBox.warning( + response = QtWidgets.QMessageBox.warning( context.app, "Clearing all suggestions", "Are you sure you want to remove all suggestions from the project?", - QMessageBox.Yes, - QMessageBox.No, + QtWidgets.QMessageBox.Yes, + QtWidgets.QMessageBox.No, ) - if response == QMessageBox.No: + if response == QtWidgets.QMessageBox.No: return False return True @@ -2509,27 +2889,13 @@ def ask_and_do(cls, context: CommandContext, params: dict): class AddInstance(EditCommand): topics = [UpdateTopic.frame, UpdateTopic.project_instances, UpdateTopic.suggestions] - @staticmethod - def get_previous_frame_index(context: CommandContext) -> Optional[int]: - frames = context.labels.frames( - context.state["video"], - from_frame_idx=context.state["frame_idx"], - reverse=True, - ) - - try: - next_idx = next(frames).frame_idx - except: - return - - return next_idx - @classmethod def do_action(cls, context: CommandContext, params: dict): copy_instance = params.get("copy_instance", None) init_method = params.get("init_method", "best") location = params.get("location", None) mark_complete = params.get("mark_complete", False) + offset = params.get("offset", 0) if context.state["labeled_frame"] is None: return @@ -2537,6 +2903,250 @@ def do_action(cls, context: CommandContext, params: dict): if len(context.state["skeleton"]) == 0: return + ( + copy_instance, + from_predicted, + from_prev_frame, + ) = AddInstance.find_instance_to_copy_from( + context, copy_instance=copy_instance, init_method=init_method + ) + + new_instance = AddInstance.create_new_instance( + context=context, + from_predicted=from_predicted, + copy_instance=copy_instance, + mark_complete=mark_complete, + init_method=init_method, + location=location, + from_prev_frame=from_prev_frame, + offset=offset, + ) + + # Add the instance + context.labels.add_instance(context.state["labeled_frame"], new_instance) + + if context.state["labeled_frame"] not in context.labels.labels: + context.labels.append(context.state["labeled_frame"]) + + @staticmethod + def create_new_instance( + context: CommandContext, + from_predicted: Optional[PredictedInstance], + copy_instance: Optional[Union[Instance, PredictedInstance]], + mark_complete: bool, + init_method: str, + location: Optional[QtCore.QPoint], + from_prev_frame: bool, + offset: int = 0, + ) -> Instance: + """Create new instance.""" + + # Now create the new instance + new_instance = Instance( + skeleton=context.state["skeleton"], + from_predicted=from_predicted, + frame=context.state["labeled_frame"], + ) + + has_missing_nodes = AddInstance.set_visible_nodes( + context=context, + copy_instance=copy_instance, + new_instance=new_instance, + mark_complete=mark_complete, + init_method=init_method, + location=location, + offset=offset, + ) + + if has_missing_nodes: + AddInstance.fill_missing_nodes( + context=context, + copy_instance=copy_instance, + init_method=init_method, + new_instance=new_instance, + location=location, + ) + + # If we're copying a predicted instance or from another frame, copy the track + if hasattr(copy_instance, "score") or from_prev_frame: + copy_instance = cast(Union[PredictedInstance, Instance], copy_instance) + new_instance.track = copy_instance.track + + return new_instance + + @staticmethod + def fill_missing_nodes( + context: CommandContext, + copy_instance: Optional[Union[Instance, PredictedInstance]], + init_method: str, + new_instance: Instance, + location: Optional[QtCore.QPoint], + ): + """Fill in missing nodes for new instance. + + Args: + context: The command context. + copy_instance: The instance to copy from. + init_method: The initialization method. + new_instance: The new instance. + location: The location of the instance. + + Returns: + None + """ + + # mark the node as not "visible" if we're copying from a predicted instance without this node + is_visible = copy_instance is None or (not hasattr(copy_instance, "score")) + + if init_method == "force_directed": + AddMissingInstanceNodes.add_force_directed_nodes( + context=context, + instance=new_instance, + visible=is_visible, + center_point=location, + ) + elif init_method == "random": + AddMissingInstanceNodes.add_random_nodes( + context=context, instance=new_instance, visible=is_visible + ) + elif init_method == "template": + AddMissingInstanceNodes.add_nodes_from_template( + context=context, + instance=new_instance, + visible=is_visible, + center_point=location, + ) + else: + AddMissingInstanceNodes.add_best_nodes( + context=context, instance=new_instance, visible=is_visible + ) + + @staticmethod + def set_visible_nodes( + context: CommandContext, + copy_instance: Optional[Union[Instance, PredictedInstance]], + new_instance: Instance, + mark_complete: bool, + init_method: str, + location: Optional[QtCore.QPoint] = None, + offset: int = 0, + ) -> bool: + """Sets visible nodes for new instance. + + Args: + context: The command context. + copy_instance: The instance to copy from. + new_instance: The new instance. + mark_complete: Whether to mark the instance as complete. + init_method: The initialization method. + location: The location of the mouse click if any. + offset: The offset to apply to all nodes. + + Returns: + Whether the new instance has missing nodes. + """ + + if copy_instance is None: + return True + + has_missing_nodes = False + + # Calculate scale factor for getting new x and y values. + old_size_width = copy_instance.frame.video.shape[2] + old_size_height = copy_instance.frame.video.shape[1] + new_size_width = new_instance.frame.video.shape[2] + new_size_height = new_instance.frame.video.shape[1] + scale_width = new_size_width / old_size_width + scale_height = new_size_height / old_size_height + + # The offset is 0, except when using Ctrl + I or Add Instance button. + offset_x = offset + offset_y = offset + + # Using right click and context menu with option "best" + if (init_method == "best") and (location is not None): + reference_node = next( + (node for node in copy_instance if not node.isnan()), None + ) + reference_x = reference_node.x + reference_y = reference_node.y + offset_x = location.x() - (reference_x * scale_width) + offset_y = location.y() - (reference_y * scale_height) + + # Go through each node in skeleton. + for node in context.state["skeleton"].node_names: + # If we're copying from a skeleton that has this node. + if node in copy_instance and not copy_instance[node].isnan(): + # Ensure x, y inside current frame, then copy x, y, and visible. + # We don't want to copy a PredictedPoint or score attribute. + x_old = copy_instance[node].x + y_old = copy_instance[node].y + + # Copy the instance without scale or offset if predicted + if isinstance(copy_instance, PredictedInstance): + x_new = x_old + y_new = y_old + else: + x_new = x_old * scale_width + y_new = y_old * scale_height + + # Apply offset if in bounds + x_new_offset = x_new + offset_x + y_new_offset = y_new + offset_y + + # Default visibility is same as copied instance. + visible = copy_instance[node].visible + + # If the node is offset to outside the frame, mark as not visible. + if x_new_offset < 0: + x_new = 0 + visible = False + elif x_new_offset > new_size_width: + x_new = new_size_width + visible = False + else: + x_new = x_new_offset + if y_new_offset < 0: + y_new = 0 + visible = False + elif y_new_offset > new_size_height: + y_new = new_size_height + visible = False + else: + y_new = y_new_offset + + # Update the new instance with the new x, y, and visibility. + new_instance[node] = Point( + x=x_new, + y=y_new, + visible=visible, + complete=mark_complete, + ) + else: + has_missing_nodes = True + + return has_missing_nodes + + @staticmethod + def find_instance_to_copy_from( + context: CommandContext, + copy_instance: Optional[Union[Instance, PredictedInstance]], + init_method: bool, + ) -> Tuple[ + Optional[Union[Instance, PredictedInstance]], Optional[PredictedInstance], bool + ]: + """Find instance to copy from. + + Args: + context: The command context. + copy_instance: The `Instance` to copy from. + init_method: The initialization method. + + Returns: + The instance to copy from, the predicted instance (if it is from a predicted + instance, else None), and whether it's from a previous frame. + """ + from_predicted = copy_instance from_prev_frame = False @@ -2562,7 +3172,7 @@ def do_action(cls, context: CommandContext, params: dict): ) or init_method == "prior_frame": # Otherwise, if there are instances in previous frames, # copy the points from one of those instances. - prev_idx = cls.get_previous_frame_index(context) + prev_idx = AddInstance.get_previous_frame_index(context) if prev_idx is not None: prev_instances = context.labels.find( @@ -2587,71 +3197,26 @@ def do_action(cls, context: CommandContext, params: dict): from_prev_frame = True from_predicted = from_predicted if hasattr(from_predicted, "score") else None + from_predicted = cast(Optional[PredictedInstance], from_predicted) - # Now create the new instance - new_instance = Instance( - skeleton=context.state["skeleton"], - from_predicted=from_predicted, - frame=context.state["labeled_frame"], - ) - - has_missing_nodes = False - - # go through each node in skeleton - for node in context.state["skeleton"].node_names: - # if we're copying from a skeleton that has this node - if ( - copy_instance is not None - and node in copy_instance - and not copy_instance[node].isnan() - ): - # just copy x, y, and visible - # we don't want to copy a PredictedPoint or score attribute - new_instance[node] = Point( - x=copy_instance[node].x, - y=copy_instance[node].y, - visible=copy_instance[node].visible, - complete=mark_complete, - ) - else: - has_missing_nodes = True + return copy_instance, from_predicted, from_prev_frame - if has_missing_nodes: - # mark the node as not "visible" if we're copying from a predicted instance without this node - is_visible = copy_instance is None or (not hasattr(copy_instance, "score")) - - if init_method == "force_directed": - AddMissingInstanceNodes.add_force_directed_nodes( - context=context, - instance=new_instance, - visible=is_visible, - center_point=location, - ) - elif init_method == "random": - AddMissingInstanceNodes.add_random_nodes( - context=context, instance=new_instance, visible=is_visible - ) - elif init_method == "template": - AddMissingInstanceNodes.add_nodes_from_template( - context=context, - instance=new_instance, - visible=is_visible, - center_point=location, - ) - else: - AddMissingInstanceNodes.add_best_nodes( - context=context, instance=new_instance, visible=is_visible - ) + @staticmethod + def get_previous_frame_index(context: CommandContext) -> Optional[int]: + """Returns index of previous frame.""" - # If we're copying a predicted instance or from another frame, copy the track - if hasattr(copy_instance, "score") or from_prev_frame: - new_instance.track = copy_instance.track + frames = context.labels.frames( + context.state["video"], + from_frame_idx=context.state["frame_idx"], + reverse=True, + ) - # Add the instance - context.labels.add_instance(context.state["labeled_frame"], new_instance) + try: + next_idx = next(frames).frame_idx + except: + return - if context.state["labeled_frame"] not in context.labels.labels: - context.labels.append(context.state["labeled_frame"]) + return next_idx class SetInstancePointLocations(EditCommand): @@ -2851,6 +3416,48 @@ def do_action(cls, context: CommandContext, params: dict): context.labels.add_instance(context.state["labeled_frame"], new_instance) +class CopyInstance(EditCommand): + @classmethod + def do_action(cls, context: CommandContext, params: dict): + current_instance: Instance = context.state["instance"] + if current_instance is None: + return + context.state["clipboard_instance"] = current_instance + + +class PasteInstance(EditCommand): + topics = [UpdateTopic.frame, UpdateTopic.project_instances] + + @classmethod + def do_action(cls, context: CommandContext, params: dict): + base_instance: Instance = context.state["clipboard_instance"] + current_frame: LabeledFrame = context.state["labeled_frame"] + if base_instance is None or current_frame is None: + return + + # Create a new instance copy. + new_instance = Instance.from_numpy( + base_instance.numpy(), skeleton=base_instance.skeleton + ) + + if base_instance.frame != current_frame: + # Only copy the track if we're not on the same frame and the track doesn't + # exist on the current frame. + current_frame_tracks = [ + inst.track for inst in current_frame if inst.track is not None + ] + if base_instance.track not in current_frame_tracks: + new_instance.track = base_instance.track + + # Add to the current frame. + context.labels.add_instance(current_frame, new_instance) + + if current_frame not in context.labels.labels: + # Add current frame to labels if it wasn't already there. This happens when + # adding an instance to an empty labeled frame that isn't in the labels. + context.labels.append(current_frame) + + def open_website(url: str): """Open website in default browser. diff --git a/sleap/gui/dataviews.py b/sleap/gui/dataviews.py index a8750b35c..721bdc321 100644 --- a/sleap/gui/dataviews.py +++ b/sleap/gui/dataviews.py @@ -15,20 +15,17 @@ """ -from qtpy import QtCore, QtWidgets, QtGui - -import numpy as np import os - from operator import itemgetter +from pathlib import Path +from typing import Any, Callable, List, Optional -from typing import Any, Callable, Dict, List, Optional, Type +import numpy as np +from qtpy import QtCore, QtGui, QtWidgets -from sleap.gui.state import GuiState from sleap.gui.commands import CommandContext -from sleap.gui.color import ColorManager -from sleap.io.dataset import Labels -from sleap.instance import LabeledFrame, Instance +from sleap.gui.state import GuiState +from sleap.instance import LabeledFrame from sleap.skeleton import Skeleton @@ -74,7 +71,6 @@ def __init__( super(GenericTableModel, self).__init__() self.properties = properties or self.properties or [] self.context = context - self.items = items def object_to_items(self, item_list): @@ -89,7 +85,9 @@ def items(self): @items.setter def items(self, obj): if not obj: + self.beginResetModel() self._data = [] + self.endResetModel() return self.obj = obj @@ -132,7 +130,7 @@ def data(self, index: QtCore.QModelIndex, role=QtCore.Qt.DisplayRole): return None item = self.items[idx] - if role == QtCore.Qt.DisplayRole: + if role == QtCore.Qt.DisplayRole or role == QtCore.Qt.EditRole: if isinstance(item, dict) and key in item: return item[key] @@ -142,6 +140,13 @@ def data(self, index: QtCore.QModelIndex, role=QtCore.Qt.DisplayRole): elif role == QtCore.Qt.ForegroundRole: return self.get_item_color(self.original_items[idx], key) + elif role == QtCore.Qt.ToolTipRole: + if isinstance(item, dict) and key in item: + return item[key] + + if hasattr(item, key): + return getattr(item, key) + return None def setData(self, index: QtCore.QModelIndex, value: str, role=QtCore.Qt.EditRole): @@ -149,6 +154,18 @@ def setData(self, index: QtCore.QModelIndex, value: str, role=QtCore.Qt.EditRole if role == QtCore.Qt.EditRole: item, key = self.get_from_idx(index) + # If nothing changed of the item, return true. (Issue #1013) + if isinstance(item, dict): + item_value = item.get(key, None) + elif hasattr(item, key): + item_value = getattr(item, key) + else: + item_value = None + + if (item_value is not None) and (item_value == value): + return True + + # Otherwise set the item if self.can_set(item, key): self.set_item(item, key, value) self.dataChanged.emit(index, index) @@ -260,6 +277,11 @@ class GenericTableView(QtWidgets.QTableView): for some reason you need this to be different. For instance, the table of instances in the GUI sets this to "" so that the row for an instance is automatically selected when `state["instance"]` is set outside the table. + + "ellipsis_left" can be used to make the TableView truncate cell content on + the left instead of the right side. By default, the argument is set to + False, i.e. truncation on the right side, which is also the default for + QTableView. """ row_name: Optional[str] = None @@ -275,6 +297,8 @@ def __init__( name_prefix: Optional[str] = None, is_sortable: bool = False, is_activatable: bool = False, + ellipsis_left: bool = False, + multiple_selection: bool = False, ): super(GenericTableView, self).__init__() @@ -283,11 +307,19 @@ def __init__( self.name_prefix = name_prefix if name_prefix is not None else self.name_prefix self.is_sortable = is_sortable or self.is_sortable self.is_activatable = is_activatable or self.is_activatable + self.multiple_selection = multiple_selection self.setModel(model) + if ellipsis_left: + self.setTextElideMode(QtCore.Qt.ElideLeft) + self.setWordWrap(False) + self.horizontalHeader().setStretchLastSection(True) self.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) - self.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) + if self.multiple_selection: + self.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) + else: + self.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection) self.setSortingEnabled(self.is_sortable) self.doubleClicked.connect(self.activateSelected) @@ -340,16 +372,36 @@ def getSelectedRowItem(self) -> Any: not the converted dict. """ idx = self.currentIndex() + + if self.multiple_selection: + idx_temp = set([x.row() for x in self.selectedIndexes()]) + self.state[f"selected_batch_{self.row_name}"] = idx_temp + if not idx.isValid(): return None return self.model().original_items[idx.row()] class VideosTableModel(GenericTableModel): - properties = ("filename", "frames", "height", "width", "channels") - - def item_to_data(self, obj, item): - return {key: getattr(item, key) for key in self.properties} + properties = ( + "name", + "filepath", + "frames", + "height", + "width", + "channels", + ) + + def item_to_data(self, obj, item: "Video"): + data = {} + for property in self.properties: + if property == "name": + data[property] = Path(item.filename).name + elif property == "filepath": + data[property] = str(Path(item.filename).parent) + else: + data[property] = getattr(item, property) + return data class SkeletonNodesTableModel(GenericTableModel): @@ -373,13 +425,6 @@ def set_item(self, item, key, value): elif key == "symmetry": self.context.setNodeSymmetry(skeleton=self.obj, node=item, symmetry=value) - def get_item_color(self, item: Any, key: str): - if self.skeleton: - color = self.context.app.color_manager.get_item_color( - item, parent_skeleton=self.skeleton - ) - return QtGui.QColor(*color) - class SkeletonEdgesTableModel(GenericTableModel): """Table model for skeleton edges.""" @@ -396,14 +441,6 @@ def object_to_items(self, skeleton: Skeleton): ] return items - def get_item_color(self, item: Any, key: str): - if self.skeleton: - edge_pair = (item["source"], item["destination"]) - color = self.context.app.color_manager.get_item_color( - edge_pair, parent_skeleton=self.skeleton - ) - return QtGui.QColor(*color) - class LabeledFrameTableModel(GenericTableModel): """Table model for listing instances in labeled frame. diff --git a/sleap/gui/dialogs/export_clip.py b/sleap/gui/dialogs/export_clip.py index 312f9a807..f84766d18 100644 --- a/sleap/gui/dialogs/export_clip.py +++ b/sleap/gui/dialogs/export_clip.py @@ -11,16 +11,16 @@ def __init__(self): super().__init__(form_name="labeled_clip_form") - can_use_skvideo = VideoWriter.can_use_skvideo() + can_use_ffmpeg = VideoWriter.can_use_ffmpeg() - if can_use_skvideo: + if can_use_ffmpeg: message = ( "MP4 file will be encoded using " - "system ffmpeg via scikit-video (preferred option)." + "system ffmpeg via imageio (preferred option)." ) else: message = ( - "Unable to use ffpmeg via scikit-video. " + "Unable to use ffpmeg via imageio. " "AVI file will be encoding using OpenCV." ) diff --git a/sleap/gui/dialogs/filedialog.py b/sleap/gui/dialogs/filedialog.py index 395355355..ff394d191 100644 --- a/sleap/gui/dialogs/filedialog.py +++ b/sleap/gui/dialogs/filedialog.py @@ -8,13 +8,46 @@ import os, re, sys +from functools import wraps +from pathlib import Path +from typing import Callable from qtpy import QtWidgets +def os_specific_method(func) -> Callable: + """Check if native dialog should be used and update kwargs based on OS. + + Native Mac/Win file dialogs add file extension based on selected file type but + non-native dialog (used for Linux) does not do this by default. + """ + + @wraps(func) + def set_dialog_type(cls, *args, **kwargs): + is_linux = sys.platform.startswith("linux") + env_var_set = os.environ.get("USE_NON_NATIVE_FILE", False) + cls.is_non_native = is_linux or env_var_set + + if cls.is_non_native: + kwargs["options"] = kwargs.get("options", 0) + if not kwargs["options"]: + kwargs["options"] = QtWidgets.QFileDialog.DontUseNativeDialog + + # Make sure we don't send empty options argument + if "options" in kwargs and not kwargs["options"]: + del kwargs["options"] + + return func(cls, *args, **kwargs) + + return set_dialog_type + + class FileDialog: """Substitute for QFileDialog; see class methods for details.""" + is_non_native = False + @classmethod + @os_specific_method def open(cls, *args, **kwargs): """ Wrapper for `QFileDialog.getOpenFileName()` @@ -23,10 +56,10 @@ def open(cls, *args, **kwargs): Passes along everything except empty "options" arg. """ - cls._non_native_if_set(kwargs) return QtWidgets.QFileDialog.getOpenFileName(*args, **kwargs) @classmethod + @os_specific_method def openMultiple(cls, *args, **kwargs): """ Wrapper for `QFileDialog.getOpenFileNames()` @@ -35,10 +68,10 @@ def openMultiple(cls, *args, **kwargs): Passes along everything except empty "options" arg. """ - cls._non_native_if_set(kwargs) return QtWidgets.QFileDialog.getOpenFileNames(*args, **kwargs) @classmethod + @os_specific_method def save(cls, *args, **kwargs): """Wrapper for `QFileDialog.getSaveFileName()` @@ -46,11 +79,10 @@ def save(cls, *args, **kwargs): Passes along everything except empty "options" arg. """ - is_non_native = cls._non_native_if_set(kwargs) # The non-native file dialog doesn't add file extensions from the # file-type menu in the dialog, so we need to do this ourselves. - if is_non_native and "filter" in kwargs and "dir" in kwargs: + if cls.is_non_native and "filter" in kwargs and "dir" in kwargs: filename = kwargs["dir"] filters = kwargs["filter"].split(";;") if filters: @@ -60,19 +92,23 @@ def save(cls, *args, **kwargs): filename, filter = QtWidgets.QFileDialog.getSaveFileName(*args, **kwargs) # Make sure filename has appropriate file extension. - if is_non_native and filter: - # Get ext from selected filter (i.e., file type). - match = re.search("\\(\\*(\\.[a-z]+)", filter) - if match: - filter_ext = match[1] - - # If ext isn't already at end of filename, add it. - if filter_ext and not filename.endswith(filter_ext): + if cls.is_non_native and filter: + fn = Path(filename) + # Get extension from filter as list of "*.ext" + match = re.findall("\*(\.[a-zA-Z0-9]+)", filter) + if len(match) > 0: + # Add first filter extension if none of the filter extensions match + add_extension = True + for filter_ext in reversed(match): + if fn.suffix == filter_ext: + add_extension = False + if add_extension: filename = f"{filename}{filter_ext}" return filename, filter @classmethod + @os_specific_method def openDir(cls, *args, **kwargs): """Wrapper for `QFileDialog.getExistingDirectory()` @@ -81,20 +117,3 @@ def openDir(cls, *args, **kwargs): Passes along everything except empty "options" arg. """ return QtWidgets.QFileDialog.getExistingDirectory(*args, **kwargs) - - @staticmethod - def _non_native_if_set(kwargs) -> bool: - is_non_native = False - is_linux = sys.platform.startswith("linux") - env_var_set = os.environ.get("USE_NON_NATIVE_FILE", False) - - if is_linux or env_var_set: - is_non_native = True - kwargs["options"] = kwargs.get("options", 0) - kwargs["options"] |= QtWidgets.QFileDialog.DontUseNativeDialog - - # Make sure we don't send empty options argument - if "options" in kwargs and not kwargs["options"]: - del kwargs["options"] - - return is_non_native diff --git a/sleap/gui/dialogs/formbuilder.py b/sleap/gui/dialogs/formbuilder.py index b46fc6673..83385bcb4 100644 --- a/sleap/gui/dialogs/formbuilder.py +++ b/sleap/gui/dialogs/formbuilder.py @@ -27,11 +27,10 @@ want to add a new type of supported form field. """ -import yaml - from typing import Any, Dict, List, Optional, Text -from qtpy import QtWidgets, QtCore +import yaml +from qtpy import QtCore, QtWidgets from sleap.gui.dialogs.filedialog import FileDialog from sleap.util import get_package_file @@ -110,7 +109,7 @@ def from_name(cls, form_name: Text, *args, **kwargs) -> "YamlFormWidget": Returns: Instance of `YamlFormWidget` class. """ - yaml_path = get_package_file(f"sleap/config/{form_name}.yaml") + yaml_path = get_package_file(f"config/{form_name}.yaml") return cls(yaml_path, *args, **kwargs) @property @@ -579,7 +578,7 @@ def _make_file_button( def select_file(*args, x=field): filter = item.get("filter", "Any File (*.*)") filename, _ = FileDialog.open( - None, directory=None, caption="Open File", filter=filter + None, dir=None, caption="Open File", filter=filter ) if len(filename): x.setText(filename) @@ -588,7 +587,7 @@ def select_file(*args, x=field): elif item["type"].split("_")[-1] == "dir": # Define function for button to trigger def select_file(*args, x=field): - filename = FileDialog.openDir(None, directory=None, caption="Open File") + filename = FileDialog.openDir(None, dir=None, caption="Open File") if len(filename): x.setText(filename) self.valueChanged.emit() diff --git a/sleap/gui/dialogs/frame_range.py b/sleap/gui/dialogs/frame_range.py new file mode 100644 index 000000000..7165dd939 --- /dev/null +++ b/sleap/gui/dialogs/frame_range.py @@ -0,0 +1,42 @@ +"""Frame range dialog.""" +from qtpy import QtWidgets +from sleap.gui.dialogs.formbuilder import FormBuilderModalDialog +from typing import Optional + + +class FrameRangeDialog(FormBuilderModalDialog): + def __init__(self, max_frame_idx: Optional[int] = None, title: str = "Frame Range"): + + super().__init__(form_name="frame_range_form") + min_frame_idx_field = self.form_widget.fields["min_frame_idx"] + max_frame_idx_field = self.form_widget.fields["max_frame_idx"] + + if max_frame_idx is not None: + min_frame_idx_field.setRange(1, max_frame_idx) + min_frame_idx_field.setValue(1) + + max_frame_idx_field.setRange(1, max_frame_idx) + max_frame_idx_field.setValue(max_frame_idx) + + min_frame_idx_field.valueChanged.connect(self._update_max_frame_range) + max_frame_idx_field.valueChanged.connect(self._update_min_frame_range) + + self.setWindowTitle(title) + + def _update_max_frame_range(self, value): + min_frame_idx_field = self.form_widget.fields["min_frame_idx"] + max_frame_idx_field = self.form_widget.fields["max_frame_idx"] + + max_frame_idx_field.setRange(value, max_frame_idx_field.maximum()) + + def _update_min_frame_range(self, value): + min_frame_idx_field = self.form_widget.fields["min_frame_idx"] + max_frame_idx_field = self.form_widget.fields["max_frame_idx"] + + min_frame_idx_field.setRange(min_frame_idx_field.minimum(), value) + + +if __name__ == "__main__": + app = QtWidgets.QApplication([]) + dialog = FrameRangeDialog(max_frame_idx=100) + print(dialog.get_results()) diff --git a/sleap/gui/dialogs/importvideos.py b/sleap/gui/dialogs/importvideos.py index b9e3227bb..005b75082 100644 --- a/sleap/gui/dialogs/importvideos.py +++ b/sleap/gui/dialogs/importvideos.py @@ -32,11 +32,20 @@ ) from sleap.gui.widgets.video import GraphicsView -from sleap.io.video import Video +from sleap.io.video import ( + Video, + MediaVideo, + HDF5Video, + NumpyVideo, + ImgStoreVideo, + SingleImageVideo, + available_video_exts, +) from sleap.gui.dialogs.filedialog import FileDialog import h5py import qimage2ndarray +import cv2 from typing import Any, Dict, List, Optional @@ -66,11 +75,25 @@ def ask( messages = dict() if messages is None else messages if filenames is None: + + any_video_exts = " ".join(["*." + ext for ext in available_video_exts()]) + media_video_exts = " ".join(["*." + ext for ext in MediaVideo.EXTS]) + hdf5_video_exts = " ".join(["*." + ext for ext in HDF5Video.EXTS]) + numpy_video_exts = " ".join(["*." + ext for ext in NumpyVideo.EXTS]) + imgstore_video_exts = " ".join(["*." + ext for ext in ImgStoreVideo.EXTS]) + siv_video_exts = " ".join(["*." + ext for ext in SingleImageVideo.EXTS]) + filenames, filter = FileDialog.openMultiple( None, "Select videos to import...", # dialogue title ".", # initial path - "Any Video (*.h5 *.hd5v *.mp4 *.avi *.json);;HDF5 (*.h5 *.hd5v);;ImgStore (*.json);;Media Video (*.mp4 *.avi);;Any File (*.*)", + f"Any Video ({any_video_exts});;" + f"Media ({media_video_exts});;" + f"HDF5 ({hdf5_video_exts});;" + f"Numpy ({numpy_video_exts});;" + f"ImgStore ({imgstore_video_exts});;" + f"Single image ({siv_video_exts});;" + "Any File (*.*)", ) if len(filenames) > 0: @@ -112,7 +135,7 @@ def __init__( self.import_types = [ { "video_type": "hdf5", - "match": "h5,hdf5", + "match": ",".join(HDF5Video.EXTS), "video_class": Video.from_hdf5, "params": [ { @@ -131,16 +154,22 @@ def __init__( }, { "video_type": "mp4", - "match": "mp4,avi", + "match": ",".join(MediaVideo.EXTS), "video_class": Video.from_media, "params": [{"name": "grayscale", "type": "check"}], }, { "video_type": "imgstore", - "match": "json", + "match": ",".join(ImgStoreVideo.EXTS), "video_class": Video.from_filename, "params": [], }, + { + "video_type": "single_image", + "match": ",".join(SingleImageVideo.EXTS), + "video_class": Video.from_filename, + "params": [{"name": "grayscale", "type": "check"}], + }, ] outer_layout = QVBoxLayout() @@ -200,6 +229,18 @@ def __init__( button_layout.addWidget(all_channels_first_button) all_channels_last_button.clicked.connect(self.set_all_channels_last) all_channels_first_button.clicked.connect(self.set_all_channels_first) + if any( + [ + widget.import_type["video_type"] == "single_image" + for widget in self.import_widgets + ] + ): + all_grayscale_button = QPushButton("All grayscale") + all_rgb_button = QPushButton("All RGB") + button_layout.addWidget(all_grayscale_button) + button_layout.addWidget(all_rgb_button) + all_grayscale_button.clicked.connect(self.set_all_grayscale) + all_rgb_button.clicked.connect(self.set_all_rgb) cancel_button = QPushButton("Cancel") import_button = QPushButton("Import") @@ -549,18 +590,19 @@ def __init__(self, message: str = str(), *args, **kwargs): class VideoPreviewWidget(QWidget): """Widget to show video preview. Based on :class:`Video` class. - Args: + Attributes: video: the video to show - - Returns: - None. + max_preview_size: Maximum size of the preview images. Note: This widget is used by ImportItemWidget. """ - def __init__(self, video: Video = None, *args, **kwargs): + def __init__( + self, video: Video = None, max_preview_size: int = 256, *args, **kwargs + ): super(VideoPreviewWidget, self).__init__(*args, **kwargs) + self.max_preview_size = max_preview_size # widgets to include self.view = GraphicsView() self.video_label = QLabel() @@ -599,35 +641,19 @@ def plot(self, idx=0): # Get image data frame = self.video.get_frame(idx) + + # Re-size the preview image + height, width = frame.shape[:2] + img_length = max(height, width) + if img_length > self.max_preview_size: + ratio = self.max_preview_size / img_length + frame = cv2.resize(frame, None, fx=ratio, fy=ratio) + # Clear existing objects self.view.clear() + # Convert ndarray to QImage image = qimage2ndarray.array2qimage(frame) + # Display image self.view.setImage(image) - - -# if __name__ == "__main__": - -# app = QApplication([]) - -# # import_list = ImportVideos().ask() - -# filenames = [ -# "tests/data/videos/centered_pair_small.mp4", -# "tests/data/videos/small_robot.mp4", -# ] - -# messages = {"tests/data/videos/small_robot.mp4": "Testing messages"} - -# import_list = [] -# importer = ImportParamDialog(filenames, messages=messages) -# importer.accepted.connect(lambda: importer.get_data(import_list)) -# importer.exec_() - -# for import_item in import_list: -# vid = import_item["video_class"](**import_item["params"]) -# print( -# "Imported video data: (%d, %d), %d f, %d c" -# % (vid.width, vid.height, vid.frames, vid.channels) -# ) diff --git a/sleap/gui/dialogs/merge.py b/sleap/gui/dialogs/merge.py index ff0dca008..3dd90eb0e 100644 --- a/sleap/gui/dialogs/merge.py +++ b/sleap/gui/dialogs/merge.py @@ -2,20 +2,23 @@ Gui for merging two labels files with options to resolve conflicts. """ -import attr -from typing import Dict, List +import logging +from typing import Dict, List, Optional + +import attr +from qtpy import QtWidgets, QtCore from sleap.instance import LabeledFrame from sleap.io.dataset import Labels -from qtpy import QtWidgets, QtCore - USE_BASE_STRING = "Use base, discard conflicting new instances" USE_NEW_STRING = "Use new, discard conflicting base instances" USE_NEITHER_STRING = "Discard all conflicting instances" CLEAN_STRING = "Accept clean merge" +log = logging.getLogger(__name__) + class MergeDialog(QtWidgets.QDialog): """ @@ -301,6 +304,258 @@ def headerData( return None +class ReplaceSkeletonTableDialog(QtWidgets.QDialog): + """Qt dialog for handling skeleton replacement. + + Args: + rename_nodes: The nodes that will be renamed. + delete_nodes: The nodes that will be deleted. + add_nodes: The nodes that will be added. + skeleton_nodes: The nodes in the current skeleton. + new_skeleton_nodes: The nodes in the new skeleton. + + Attributes: + results_data: The results of the dialog. This is a dictionary with the keys + being the new node names and the values being the old node names. + delete_nodes: The nodes that will be deleted. + add_nodes: The nodes that will be added. + table: The table widget that displays the nodes. + + Methods: + add_combo_boxes_to_table: Add combo boxes to the table. + find_unused_nodes: Find unused nodes. + create_combo_box: Create a combo box. + get_table_data: Get the data from the table. + accept: Accept the dialog. + result: Get the result of the dialog. + + Returns: + If accepted, returns a dictionary with the keys being the new node names and the values being the + old node names. If rejected, returns None. + """ + + def __init__( + self, + rename_nodes: List[str], + delete_nodes: List[str], + add_nodes: List[str], + *args, + **kwargs, + ): + super().__init__(*args, **kwargs) + + # The only data we need + self.rename_nodes = rename_nodes + self.delete_nodes = delete_nodes + self.add_nodes = add_nodes + + # We want the skeleton nodes to be ordered with rename nodes first + self.skeleton_nodes = list(self.rename_nodes) + self.skeleton_nodes.extend(self.delete_nodes) + self.new_skeleton_nodes = list(self.rename_nodes) + self.new_skeleton_nodes.extend(self.add_nodes) + + self.results_data: Optional[Dict[str, str]] = None + + # Set table name + self.setWindowTitle("Replace Nodes") + + # Add table to dialog (if any nodes exist to link) + if (len(self.add_nodes) > 0) or (len(self.delete_nodes) > 0): + self.create_table() + else: + self.table = None + + # Add table and message to application + layout = QtWidgets.QVBoxLayout(self) + + # Dynamically create message + message = "

Warning: Pre-existing skeleton found." + if len(self.delete_nodes) > 0: + message += ( + "

The following nodes will be deleted from all instances:" + f"
From base labels: {', '.join(self.delete_nodes)}

" + ) + else: + message += "

No nodes will be deleted.

" + if len(self.add_nodes) > 0: + message += ( + "

The following nodes will be added to all instances:
" + f"From new labels: {', '.join(self.add_nodes)}

" + ) + else: + message += "

No nodes will be added.

" + if self.table is not None: + message += ( + "

Old nodes to can be linked to new nodes via the table below.

" + ) + + label = QtWidgets.QLabel(message) + label.setWordWrap(True) + layout.addWidget(label) + if self.table is not None: + layout.addWidget(self.table) + + # Add button to application + button = QtWidgets.QPushButton("Replace") + button.clicked.connect(self.accept) + layout.addWidget(button) + + # Set layout (otherwise nothing will be shown) + self.setLayout(layout) + + def create_table(self: "ReplaceSkeletonTableDialog") -> QtWidgets.QTableWidget: + """Create the table widget.""" + + self.table = QtWidgets.QTableWidget(self) + + if self.table is None: + return + + # Create QTable Widget to display skeleton differences + self.table.setColumnCount(2) + self.table.setRowCount(len(self.new_skeleton_nodes)) + self.table.setHorizontalHeaderLabels(["New", "Old"]) + self.table.verticalHeader().setVisible(False) + self.table.horizontalHeader().setSectionResizeMode( + QtWidgets.QHeaderView.Stretch + ) + self.table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers) + self.table.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) + self.table.setShowGrid(False) + self.table.setAlternatingRowColors(True) + + # Add data to table + column = 0 + for i, new_node in enumerate(self.new_skeleton_nodes): + row = i + self.table.setItem(row, column, QtWidgets.QTableWidgetItem(new_node)) + self.add_combo_boxes_to_table(init=True) + + def add_combo_boxes_to_table( + self: "ReplaceSkeletonTableDialog", + init: bool = False, + ): + """Adds combo boxes to table. + + Args: + init: If True, the combo boxes will be initialized with all + `self.delete_nodes`. If False, the combo boxes will be initialized with + all `self.delete_nodes` excluding nodes that have already been used by + other combo boxes. + """ + if self.table is None: + return + + for i in range(self.table.rowCount()): + # Get text from table item in column 1 + new_node_name = self.table.item(i, 0).text() + if init and (new_node_name in self.rename_nodes): + current_combo_text = new_node_name + else: + current_combo = self.table.cellWidget(i, 1) + current_combo_text = ( + current_combo.currentText() if current_combo else "" + ) + self.table.setCellWidget( + i, + 1, + self.create_combo_box(set_text=current_combo_text, init=init), + ) + + def find_unused_nodes(self: "ReplaceSkeletonTableDialog"): + """Finds set of nodes from `delete_nodes` that are not used by combo boxes. + + Returns: + List of unused nodes. + """ + if self.table is None: + return + + unused_nodes = set(self.skeleton_nodes) + for i in range(self.table.rowCount()): + combo = self.table.cellWidget(i, 1) + if combo is None: + break + elif combo.currentText() in unused_nodes: + unused_nodes.remove(combo.currentText()) + return list(unused_nodes) + + def create_combo_box( + self: "ReplaceSkeletonTableDialog", + set_text: str = "", + init: bool = False, + ): + """Creates combo box with unused nodes from `delete_nodes`. + + Args: + set_text: Text to set combo box to. + init: If True, the combo boxes will be initialized with all + `self.delete_nodes`. If False, the combo boxes will be initialized with + all `self.delete_nodes` excluding nodes that have already been used by + other combo boxes. + + Returns: + Combo box with unused nodes from `delete_nodes` plus an empty string and the + `set_text`. + """ + unused_nodes = self.delete_nodes if init else self.find_unused_nodes() + combo = QtWidgets.QComboBox() + combo.addItem("") + if set_text != "": + combo.addItem(set_text) + combo.addItems(sorted(unused_nodes)) + combo.setCurrentText(set_text) # Set text to current text + combo.currentTextChanged.connect( + lambda: self.add_combo_boxes_to_table(init=False) + ) + return combo + + def get_table_data(self: "ReplaceSkeletonTableDialog"): + """Gets data from table.""" + if self.table is None: + return {} + + data = {} + for i in range(self.table.rowCount()): + new_node = self.table.item(i, 0).text() + old_node = self.table.cellWidget(i, 1).currentText() + if (old_node != "") and (new_node != old_node): + data[new_node] = old_node + + # Sort the data s.t. skeleton nodes are renamed to new nodes first + data = dict( + sorted(data.items(), key=lambda item: item[0] in self.skeleton_nodes) + ) + + # This case happens if exclusively bipartite match (new) `self.rename_nodes` + # with set including (old) `self.delete_nodes` and `self.rename_nodes` + if len(data) > 0: + first_new_node, first_old_node = list(data.items())[0] + if first_new_node in self.skeleton_nodes: + # Reordering has failed! + log.debug(f"Linked nodes (new: old): {data}") + raise ValueError( + f"Cannot rename skeleton node '{first_old_node}' to already existing " + f"node '{first_new_node}'. Please rename existing skeleton node " + f"'{first_new_node}' manually before linking." + ) + return data + + def accept(self): + """Overrides accept method to return table data.""" + try: + self.results_data = self.get_table_data() + except ValueError as e: + QtWidgets.QMessageBox.critical(self, "Error", str(e)) + return # Allow user to fix error if possible instead of closing dialog + super().accept() + + def result(self): + """Overrides result method to return table data.""" + return self.get_table_data() if self.results_data is None else self.results_data + + def show_instance_type_counts(instance_list: List["Instance"]) -> str: """ Returns string of instance counts to show in table. @@ -316,23 +571,3 @@ def show_instance_type_counts(instance_list: List["Instance"]) -> str: ) user_count = len(instance_list) - prediction_count return f"{user_count} (user) / {prediction_count} (pred)" - - -if __name__ == "__main__": - - # file_a = "tests/data/json_format_v1/centered_pair.json" - # file_b = "tests/data/json_format_v2/centered_pair_predictions.json" - # file_a = "files/merge/a.h5" - # file_b = "files/merge/b.h5" - file_a = r"sleap_sandbox/skeleton_merge_conflicts/base_labels.slp" - # file_b = r"sleap_sandbox/skeleton_merge_conflicts/labels.renamed_node.slp") - # file_b = r"sleap_sandbox/skeleton_merge_conflicts/labels.new_node.slp" - file_b = r"sleap_sandbox/skeleton_merge_conflicts/labels.deleted_node.slp" - - base_labels = Labels.load_file(file_a) - new_labels = Labels.load_file(file_b) - - app = QtWidgets.QApplication() - win = MergeDialog(base_labels, new_labels) - win.show() - app.exec_() diff --git a/sleap/gui/dialogs/metrics.py b/sleap/gui/dialogs/metrics.py index 864a6adf0..884b373a9 100644 --- a/sleap/gui/dialogs/metrics.py +++ b/sleap/gui/dialogs/metrics.py @@ -120,10 +120,11 @@ def _show_model_params( if cfg_info is None: cfg_info = self.table_view.getSelectedRowItem() + cfg_getter = self._cfg_getter key = cfg_info.path if key not in model_detail_widgets: model_detail_widgets[key] = TrainingEditorWidget.from_trained_config( - cfg_info + cfg_info, cfg_getter ) model_detail_widgets[key].show() diff --git a/sleap/gui/dialogs/missingfiles.py b/sleap/gui/dialogs/missingfiles.py index 440a1a3eb..0451e09f9 100644 --- a/sleap/gui/dialogs/missingfiles.py +++ b/sleap/gui/dialogs/missingfiles.py @@ -234,10 +234,3 @@ def headerData( elif orientation == QtCore.Qt.Vertical: return section return None - - -# if __name__ == "__main__": -# app = QtWidgets.QApplication() -# win = MissingFilesDialog(["m:/centered_pair_small.mp4", "m:/small_robot.mp4"]) -# result = win.exec_() -# print(result) diff --git a/sleap/gui/learning/configs.py b/sleap/gui/learning/configs.py index 0bf22478e..74774ea00 100644 --- a/sleap/gui/learning/configs.py +++ b/sleap/gui/learning/configs.py @@ -1,23 +1,22 @@ """ Find, load, and show lists of saved `TrainingJobConfig`. """ -import attr import datetime -import h5py import os import re -import numpy as np from pathlib import Path +from typing import Any, Dict, List, Optional, Text + +import attr +import h5py +import numpy as np +from qtpy import QtCore, QtWidgets from sleap import Labels, Skeleton from sleap import util as sleap_utils from sleap.gui.dialogs.filedialog import FileDialog -from sleap.nn.config import TrainingJobConfig from sleap.gui.dialogs.formbuilder import FieldComboWidget - -from typing import Any, Dict, List, Optional, Text - -from qtpy import QtCore, QtWidgets +from sleap.nn.config import TrainingJobConfig @attr.s(auto_attribs=True, slots=True) @@ -404,7 +403,7 @@ def get_filtered_configs( """Returns filtered subset of loaded configs.""" base_config_dir = os.path.realpath( - sleap_utils.get_package_file("sleap/training_profiles") + sleap_utils.get_package_file("training_profiles") ) cfgs_to_return = [] @@ -474,7 +473,7 @@ def make_from_labels_filename( labels_model_dir = os.path.join(os.path.dirname(labels_filename), "models") dir_paths.append(labels_model_dir) - base_config_dir = sleap_utils.get_package_file("sleap/training_profiles") + base_config_dir = sleap_utils.get_package_file("training_profiles") dir_paths.append(base_config_dir) return cls(dir_paths=dir_paths, head_filter=head_filter) diff --git a/sleap/gui/learning/dialog.py b/sleap/gui/learning/dialog.py index 32b9b0add..bc26d826c 100644 --- a/sleap/gui/learning/dialog.py +++ b/sleap/gui/learning/dialog.py @@ -1,29 +1,27 @@ """ Dialogs for running training and/or inference in GUI. """ -import cattr -import os +import json import shutil -import atexit import tempfile from pathlib import Path +from typing import Dict, List, Optional, Text, cast + +import cattr +from qtpy import QtCore, QtGui, QtWidgets import sleap from sleap import Labels, Video from sleap.gui.dialogs.filedialog import FileDialog from sleap.gui.dialogs.formbuilder import YamlFormWidget -from sleap.gui.learning import runners, scopedkeydict, configs, datagen, receptivefield - -from typing import Dict, List, Optional, Text, Optional - -from qtpy import QtWidgets, QtCore - +from sleap.gui.learning import configs, datagen, receptivefield, runners, scopedkeydict # List of fields which should show list of skeleton nodes NODE_LIST_FIELDS = [ "data.instance_cropping.center_on_part", "model.heads.centered_instance.anchor_part", "model.heads.centroid.anchor_part", + "model.heads.multi_class_topdown.confmaps.anchor_part", ] @@ -75,7 +73,7 @@ def __init__( self.current_pipeline = "" - self.tabs = dict() + self.tabs: Dict[str, TrainingEditorWidget] = dict() self.shown_tab_names = [] self._cfg_getter = configs.TrainingConfigsGetter.make_from_labels_filename( @@ -84,6 +82,9 @@ def __init__( # Layout for buttons buttons = QtWidgets.QDialogButtonBox() + self.copy_button = buttons.addButton( + "Copy to clipboard", QtWidgets.QDialogButtonBox.ActionRole + ) self.save_button = buttons.addButton( "Save configuration files...", QtWidgets.QDialogButtonBox.ActionRole ) @@ -93,6 +94,7 @@ def __init__( self.cancel_button = buttons.addButton(QtWidgets.QDialogButtonBox.Cancel) self.run_button = buttons.addButton("Run", QtWidgets.QDialogButtonBox.ApplyRole) + self.copy_button.setToolTip("Copy configuration to the clipboard") self.save_button.setToolTip("Save scripts and configuration to run pipeline.") self.export_button.setToolTip( "Export data, configuration, and scripts for remote training and inference." @@ -122,12 +124,25 @@ def __init__( self.message_widget = QtWidgets.QLabel("") # Layout for entire dialog - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.tab_widget) - layout.addWidget(self.message_widget) - layout.addWidget(buttons_layout_widget) + content_widget = QtWidgets.QWidget() + content_layout = QtWidgets.QVBoxLayout(content_widget) - self.setLayout(layout) + content_layout.addWidget(self.tab_widget) + content_layout.addWidget(self.message_widget) + content_layout.addWidget(buttons_layout_widget) + + # Create the QScrollArea. + scroll_area = QtWidgets.QScrollArea() + scroll_area.setWidgetResizable(True) + scroll_area.setWidget(content_widget) + + scroll_area.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) + scroll_area.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) + + layout = QtWidgets.QVBoxLayout(self) + layout.addWidget(scroll_area) + + self.adjust_initial_size() # Default to most recently trained pipeline (if there is one) self.set_default_pipeline_tab() @@ -139,6 +154,7 @@ def __init__( self.connect_signals() # Connect actions for buttons + self.copy_button.clicked.connect(self.copy) self.save_button.clicked.connect(self.save) self.export_button.clicked.connect(self.export_package) self.cancel_button.clicked.connect(self.reject) @@ -150,6 +166,20 @@ def __init__( self.view_datagen ) + def adjust_initial_size(self): + # Get screen size + screen = QtGui.QGuiApplication.primaryScreen().availableGeometry() + + max_width = 1860 + max_height = 1150 + margin = 0.10 + + # Calculate target width and height + target_width = min(screen.width() - screen.width() * margin, max_width) + target_height = min(screen.height() - screen.height() * margin, max_height) + # Set the dialog's dimensions + self.resize(target_width, target_height) + def update_file_lists(self): self._cfg_getter.update() for tab in self.tabs.values(): @@ -279,7 +309,14 @@ def disconnect_signals(self): tab.valueChanged.disconnect() def make_tabs(self): - heads = ("single_instance", "centroid", "centered_instance", "multi_instance") + heads = ( + "single_instance", + "centroid", + "centered_instance", + "multi_instance", + "multi_class_topdown", + "multi_class_bottomup", + ) video = self.labels.videos[0] if self.labels else None @@ -305,6 +342,11 @@ def adjust_data_to_update_other_tabs(self, source_data, updated_data=None): elif "model.heads.centered_instance.anchor_part" in source_data: anchor_part = source_data["model.heads.centered_instance.anchor_part"] set_anchor = True + elif "model.heads.multi_class_topdown.confmaps.anchor_part" in source_data: + anchor_part = source_data[ + "model.heads.multi_class_topdown.confmaps.anchor_part" + ] + set_anchor = True # Use None instead of empty string/list anchor_part = anchor_part or None @@ -312,6 +354,9 @@ def adjust_data_to_update_other_tabs(self, source_data, updated_data=None): if set_anchor: updated_data["model.heads.centroid.anchor_part"] = anchor_part updated_data["model.heads.centered_instance.anchor_part"] = anchor_part + updated_data[ + "model.heads.multi_class_topdown.confmaps.anchor_part" + ] = anchor_part updated_data["data.instance_cropping.center_on_part"] = anchor_part def update_tabs_from_pipeline(self, source_data): @@ -350,13 +395,18 @@ def on_tab_data_change(self, tab_name=None): def get_most_recent_pipeline_trained(self) -> Text: recent_cfg_info = self._cfg_getter.get_first() + if recent_cfg_info and recent_cfg_info.head_name: + if recent_cfg_info.head_name in ("multi_class_topdown",): + return "top-down-id" if recent_cfg_info.head_name in ("centroid", "centered_instance"): return "top-down" - if recent_cfg_info.head_name in ("multi_instance"): + if recent_cfg_info.head_name in ("multi_instance",): return "bottom-up" - if recent_cfg_info.head_name in ("single_instance"): + if recent_cfg_info.head_name in ("single_instance",): return "single" + if recent_cfg_info.head_name in ("multi_class_bottomup",): + return "bottom-up-id" return "" def set_default_pipeline_tab(self): @@ -376,6 +426,8 @@ def add_tab(self, tab_name): "centroid": "Centroid Model Configuration", "centered_instance": "Centered Instance Model Configuration", "multi_instance": "Bottom-Up Model Configuration", + "multi_class_topdown": "Top-Down-Id Model Configuration", + "multi_class_bottomup": "Bottom-Up-Id Model Configuration", } self.tab_widget.addTab(self.tabs[tab_name], tab_labels[tab_name]) self.shown_tab_names.append(tab_name) @@ -393,6 +445,11 @@ def set_pipeline(self, pipeline: str): self.add_tab("centered_instance") elif pipeline == "bottom-up": self.add_tab("multi_instance") + elif pipeline == "top-down-id": + self.add_tab("centroid") + self.add_tab("multi_class_topdown") + elif pipeline == "bottom-up-id": + self.add_tab("multi_class_bottomup") elif pipeline == "single": self.add_tab("single_instance") self.current_pipeline = pipeline @@ -412,6 +469,43 @@ def merge_pipeline_and_head_config_data(self, head_name, head_data, pipeline_dat continue head_data[key] = val + @staticmethod + def update_loaded_config( + loaded_cfg: configs.TrainingJobConfig, tab_cfg_key_val_dict: dict + ) -> scopedkeydict.ScopedKeyDict: + """Update a loaded preset config with values from the training editor. + + Args: + loaded_cfg: A `TrainingJobConfig` that was loaded from a preset or previous + training run. + tab_cfg_key_val_dict: A dictionary with the values extracted from the training + editor GUI tab. + + Returns: + A `ScopedKeyDict` with the loaded config values overriden by the corresponding + ones from the `tab_cfg_key_val_dict`. + """ + # Serialize training config + loaded_cfg_hierarchical: dict = cattr.unstructure(loaded_cfg) + + # Clear backbone subfields since these will be set by the GUI + if ( + "model" in loaded_cfg_hierarchical + and "backbone" in loaded_cfg_hierarchical["model"] + ): + for k in loaded_cfg_hierarchical["model"]["backbone"]: + loaded_cfg_hierarchical["model"]["backbone"][k] = None + + loaded_cfg_scoped: scopedkeydict.ScopedKeyDict = ( + scopedkeydict.ScopedKeyDict.from_hierarchical_dict(loaded_cfg_hierarchical) + ) + + # Replace params exposed in GUI with values from GUI + for param, value in tab_cfg_key_val_dict.items(): + loaded_cfg_scoped.key_val_dict[param] = value + + return loaded_cfg_scoped + def get_every_head_config_data( self, pipeline_form_data ) -> List[configs.ConfigFileInfo]: @@ -422,23 +516,58 @@ def get_every_head_config_data( for tab_name in self.shown_tab_names: trained_cfg_info = self.tabs[tab_name].trained_config_info_to_use - if trained_cfg_info: - trained_cfg_info.dont_retrain = trained_cfg_info + if self.tabs[tab_name].use_trained and (trained_cfg_info is not None): cfg_info_list.append(trained_cfg_info) else: - + # Get config data from GUI tab_cfg_key_val_dict = self.tabs[tab_name].get_all_form_data() - self.merge_pipeline_and_head_config_data( head_name=tab_name, head_data=tab_cfg_key_val_dict, pipeline_data=pipeline_form_data, ) + scopedkeydict.apply_cfg_transforms_to_key_val_dict(tab_cfg_key_val_dict) + + if trained_cfg_info is None: + # Config could not be loaded, just use the values from the GUI + loaded_cfg_scoped: dict = tab_cfg_key_val_dict + else: + # Config was loaded, override with the values from the GUI + loaded_cfg_scoped = LearningDialog.update_loaded_config( + trained_cfg_info.config, tab_cfg_key_val_dict + ) + # Deserialize merged dict to object cfg = scopedkeydict.make_training_config_from_key_val_dict( - tab_cfg_key_val_dict + loaded_cfg_scoped ) + + if len(self.labels.tracks) > 0: + + # For multiclass topdown, the class vectors output stride + # should be the max stride. + backbone_name = scopedkeydict.find_backbone_name_from_key_val_dict( + tab_cfg_key_val_dict + ) + max_stride = tab_cfg_key_val_dict[ + f"model.backbone.{backbone_name}.max_stride" + ] + + # Classes should be added here to prevent value error in + # model since we don't add them in the training config yaml. + if cfg.model.heads.multi_class_bottomup is not None: + cfg.model.heads.multi_class_bottomup.class_maps.classes = [ + t.name for t in self.labels.tracks + ] + elif cfg.model.heads.multi_class_topdown is not None: + cfg.model.heads.multi_class_topdown.class_vectors.classes = [ + t.name for t in self.labels.tracks + ] + cfg.model.heads.multi_class_topdown.class_vectors.output_stride = ( + max_stride + ) + cfg_info = configs.ConfigFileInfo(config=cfg, head_name=tab_name) cfg_info_list.append(cfg_info) @@ -473,6 +602,7 @@ def get_selected_frames_to_predict( def get_items_for_inference(self, pipeline_form_data) -> runners.ItemsForInference: predict_frames_choice = pipeline_form_data.get("_predict_frames", "") + batch_size = pipeline_form_data.get("batch_size") frame_selection = self.get_selected_frames_to_predict(pipeline_form_data) frame_count = self.count_total_frames_for_selection_option(frame_selection) @@ -485,6 +615,7 @@ def get_items_for_inference(self, pipeline_form_data) -> runners.ItemsForInferen ) ], total_frame_count=frame_count, + batch_size=batch_size, ) elif predict_frames_choice.startswith("suggested"): items_for_inference = runners.ItemsForInference( @@ -494,6 +625,7 @@ def get_items_for_inference(self, pipeline_form_data) -> runners.ItemsForInferen ) ], total_frame_count=frame_count, + batch_size=batch_size, ) else: items_for_inference = runners.ItemsForInference.from_video_frames_dict( @@ -501,9 +633,24 @@ def get_items_for_inference(self, pipeline_form_data) -> runners.ItemsForInferen total_frame_count=frame_count, labels_path=self.labels_filename, labels=self.labels, + batch_size=batch_size, ) return items_for_inference + def _validate_id_model(self) -> bool: + """Make sure we have instances with tracks set for ID models.""" + if not self.labels.tracks: + message = "Cannot run ID model training without tracks." + return False + + found_tracks = False + for inst in self.labels.instances(): + if type(inst) == sleap.Instance and inst.track is not None: + found_tracks = True + break + + return found_tracks + def _validate_pipeline(self): can_run = True message = "" @@ -522,6 +669,15 @@ def _validate_pipeline(self): f"({', '.join(untrained)})." ) + # Make sure we have instances with tracks set for ID models. + if self.mode == "training" and self.current_pipeline in ( + "top-down-id", + "bottom-up-id", + ): + can_run = self.validate_id_model() + if not can_run: + message = "Cannot run ID model training without tracks." + # Make sure skeleton will be valid for bottom-up inference. if self.mode == "training" and self.current_pipeline == "bottom-up": skeleton = self.labels.skeletons[0] @@ -574,14 +730,11 @@ def view_datagen(self): datagen.show_datagen_preview(self.labels, config_info_list) self.hide() - def on_button_click(self, button): - if button == self.save_button: - self.save() - def run(self): """Run with current dialog settings.""" pipeline_form_data = self.pipeline_form_widget.get_form_data() + items_for_inference = self.get_items_for_inference(pipeline_form_data) config_info_list = self.get_every_head_config_data(pipeline_form_data) @@ -616,14 +769,38 @@ def run(self): win.setWindowTitle("Inference Results") win.exec_() + def copy(self): + """Copy scripts and configs to clipboard""" + + # Get all info from dialog + pipeline_form_data = self.pipeline_form_widget.get_form_data() + config_info_list = self.get_every_head_config_data(pipeline_form_data) + pipeline_form_data = json.dumps(pipeline_form_data, indent=2) + + # Format information for each tab in dialog + output = [pipeline_form_data] + for config_info in config_info_list: + config_info = config_info.config.to_json() + config_info = json.loads(config_info) + config_info = json.dumps(config_info, indent=2) + output.append(config_info) + output = "\n".join(output) + + # Set the clipboard text + clipboard = QtWidgets.QApplication.clipboard() + clipboard.setText(output) + def save( self, output_dir: Optional[str] = None, labels_filename: Optional[str] = None ): """Save scripts and configs to run pipeline.""" if output_dir is None: - models_dir = os.path.join(os.path.dirname(self.labels_filename), "/models") + labels_fn = Path(self.labels_filename) + models_dir = Path(labels_fn.parent, "models") output_dir = FileDialog.openDir( - None, directory=models_dir, caption="Select directory to save scripts" + None, + dir=models_dir.as_posix(), + caption="Select directory to save scripts", ) if not output_dir: @@ -796,16 +973,28 @@ def emitPipeline(self): def current_pipeline(self): pipeline_selected_label = self.pipeline_field.value() if "top-down" in pipeline_selected_label: - return "top-down" + if "id" not in pipeline_selected_label: + return "top-down" + else: + return "top-down-id" if "bottom-up" in pipeline_selected_label: - return "bottom-up" + if "id" not in pipeline_selected_label: + return "bottom-up" + else: + return "bottom-up-id" if "single" in pipeline_selected_label: return "single" return "" @current_pipeline.setter def current_pipeline(self, val): - if val not in ("top-down", "bottom-up", "single"): + if val not in ( + "top-down", + "bottom-up", + "single", + "top-down-id", + "bottom-up-id", + ): raise ValueError(f"Cannot set pipeline to {val}") # Match short name to full pipeline name shown in menu @@ -854,12 +1043,13 @@ def __init__( self._cfg_list_widget = None self._receptive_field_widget = None self._use_trained_model = None + self._resume_training = None self._require_trained = require_trained self.head = head yaml_name = "training_editor_form" - self.form_widgets = dict() + self.form_widgets: Dict[str, YamlFormWidget] = dict() for key in ("model", "data", "augmentation", "optimization", "outputs"): self.form_widgets[key] = YamlFormWidget.from_name( @@ -914,11 +1104,10 @@ def __init__( # If we have an object which gets a list of config files, # then we'll show a menu to allow selection from the list. - - if self._cfg_getter: + if self._cfg_getter is not None: self._cfg_list_widget = configs.TrainingConfigFilesWidget( cfg_getter=self._cfg_getter, - head_name=head, + head_name=cast(str, head), # Expect head to be a string require_trained=require_trained, ) self._cfg_list_widget.onConfigSelection.connect( @@ -928,27 +1117,33 @@ def __init__( layout.addWidget(self._cfg_list_widget) - # Add option for using trained model from selected config - if self._require_trained: - self._update_use_trained() - else: - self._use_trained_model = QtWidgets.QCheckBox("Use Trained Model") - self._use_trained_model.setEnabled(False) - self._use_trained_model.setVisible(False) - - self._use_trained_model.stateChanged.connect(self._update_use_trained) + if self._require_trained: + self._update_use_trained() + elif self._cfg_list_widget is not None: + # Add option for using trained model from selected config file + self._use_trained_model = QtWidgets.QCheckBox("Use Trained Model") + self._use_trained_model.setEnabled(False) + self._use_trained_model.setVisible(False) + self._resume_training = QtWidgets.QCheckBox("Resume Training") + self._resume_training.setEnabled(False) + self._resume_training.setVisible(False) - layout.addWidget(self._use_trained_model) + self._use_trained_model.stateChanged.connect(self._update_use_trained) + self._resume_training.stateChanged.connect(self._update_use_trained) - elif self._require_trained: - self._update_use_trained() + layout.addWidget(self._use_trained_model) + layout.addWidget(self._resume_training) layout.addWidget(self._layout_widget(col_layout)) self.setLayout(layout) @classmethod - def from_trained_config(cls, cfg_info: configs.ConfigFileInfo): - widget = cls(require_trained=True, head=cfg_info.head_name) + def from_trained_config( + cls, cfg_info: configs.ConfigFileInfo, cfg_getter: configs.TrainingConfigsGetter + ): + widget = cls( + require_trained=True, head=cfg_info.head_name, cfg_getter=cfg_getter + ) widget.acceptSelectedConfigInfo(cfg_info) widget.setWindowTitle(cfg_info.path_dir) return widget @@ -971,14 +1166,21 @@ def acceptSelectedConfigInfo(self, cfg_info: configs.ConfigFileInfo): self._load_config(cfg_info) has_trained_model = cfg_info.has_trained_model - if self._use_trained_model: + if self._use_trained_model is not None: + self._use_trained_model.setChecked(self._require_trained) self._use_trained_model.setVisible(has_trained_model) self._use_trained_model.setEnabled(has_trained_model) + # Redundant check (for readability) since this checkbox exists if the above does + if self._resume_training is not None: + self._use_trained_model.setChecked(False) + self._resume_training.setVisible(has_trained_model) + self._resume_training.setEnabled(has_trained_model) self.update_receptive_field() def update_receptive_field(self): data_form_data = self.form_widgets["data"].get_form_data() + model_cfg = scopedkeydict.make_model_config_from_key_val_dict( key_val_dict=self.form_widgets["model"].get_form_data() ) @@ -1014,17 +1216,64 @@ def _load_config(self, cfg_info: configs.ConfigFileInfo): # self._cfg_list_widget.setUserConfigData(cfg_form_data_dict) def _update_use_trained(self, check_state=0): - if self._require_trained: - use_trained = True - else: - use_trained = check_state == QtCore.Qt.CheckState.Checked + """Update config GUI based on _use_trained_model and _resume_training checkboxes. + + This function is called when either _use_trained_model or _resume_training checkbox + is checked/unchecked or when _require_trained is changed. + + If _require_trained is True, then we'll disable all fields. + If _use_trained_model is checked, then we'll disable all fields. + If _resume_training is checked, then we'll disable only the model field. + + Args: + check_state (int, optional): Check state of checkbox. Defaults to 0. Unused. + + Returns: + None + Side Effects: + Disables/Enables fields based on checkbox values (and _required_training). + """ + + # Check which checkbox changed its value (if any) + sender = self.sender() + + if sender is None: # If sender is None, then _required_training is True + pass + # Uncheck _resume_training checkbox if _use_trained_model is unchecked + elif (sender == self._use_trained_model) and ( + not self._use_trained_model.isChecked() + ): + self._resume_training.setChecked(False) + + # Check _use_trained_model checkbox if _resume_training is checked + elif (sender == self._resume_training) and self._resume_training.isChecked(): + self._use_trained_model.setChecked(True) + + # Update form widgets + use_trained_params = self.use_trained + use_model_params = self.resume_training for form in self.form_widgets.values(): - form.set_enabled(not use_trained) + form.set_enabled(not use_trained_params) - # If user wants to use trained model, then reset form to match config - if use_trained and self._cfg_list_widget: + if use_trained_params or use_model_params: cfg_info = self._cfg_list_widget.getSelectedConfigInfo() + + # If user wants to resume training, then reset only model form to match config + if use_model_params: + self.form_widgets["model"].set_enabled(False) + + # Set model form to match config + cfg = cfg_info.config + cfg_dict = cattr.unstructure(cfg) + model_dict = {"model": cfg_dict["model"]} + key_val_dict = scopedkeydict.ScopedKeyDict.from_hierarchical_dict( + model_dict + ).key_val_dict + self.set_fields_from_key_val_dict(key_val_dict) + + # If user wants to use trained model, then reset entire form to match config + if use_trained_params: self._load_config(cfg_info) self._set_head() @@ -1052,23 +1301,73 @@ def _set_backbone_from_key_val_dict(self, cfg_key_val_dict): self.set_fields_from_key_val_dict(dict(_backbone_name=backbone_name)) break + @property + def use_trained(self) -> bool: + if self._require_trained or ( + (self._use_trained_model is not None) + and self._use_trained_model.isChecked() + and (not self.resume_training) + ): + return True + + return False + + @property + def resume_training(self) -> bool: + if (self._resume_training is not None) and self._resume_training.isChecked(): + return True + return False + @property def trained_config_info_to_use(self) -> Optional[configs.ConfigFileInfo]: - use_trained = False - if self._require_trained: - use_trained = True - elif self._use_trained_model and self._use_trained_model.isChecked(): - use_trained = True + # If `TrainingEditorWidget` was initialized with a config getter, then + # we expect to have a list of config files + if self._cfg_list_widget is None: + return None + + selected_config_info: Optional[ + configs.ConfigFileInfo + ] = self._cfg_list_widget.getSelectedConfigInfo() + if (selected_config_info is None) or ( + not selected_config_info.has_trained_model + ): + return None + + trained_config_info = configs.ConfigFileInfo.from_config_file( + selected_config_info.path + ) + if self.use_trained: + trained_config_info.dont_retrain = True + else: + # Set certain parameters to defaults + trained_config = trained_config_info.config + trained_config.data.labels.validation_labels = None + trained_config.data.labels.test_labels = None + trained_config.data.labels.split_by_inds = False + trained_config.data.labels.skeletons = [] + trained_config.outputs.run_name = None + trained_config.outputs.run_name_prefix = "" + trained_config.outputs.run_name_suffix = None + + if self.resume_training: + # Get the folder path of trained config and set it as the output folder + trained_config_info.config.model.base_checkpoint = str( + Path(cast(str, trained_config_info.path)).parent + ) + else: + trained_config_info.config.model.base_checkpoint = None - if use_trained: - return self._cfg_list_widget.getSelectedConfigInfo() - return None + return trained_config_info @property def has_trained_config_selected(self) -> bool: + if self._cfg_list_widget is None: + return False + cfg_info = self._cfg_list_widget.getSelectedConfigInfo() if cfg_info and cfg_info.has_trained_model: return True + return False def get_all_form_data(self) -> dict: diff --git a/sleap/gui/learning/receptivefield.py b/sleap/gui/learning/receptivefield.py index 1d3a95e64..025f09ae9 100644 --- a/sleap/gui/learning/receptivefield.py +++ b/sleap/gui/learning/receptivefield.py @@ -1,19 +1,16 @@ """ Widget for previewing receptive field on sample image using model hyperparams. """ -from sleap import Video -from sleap.nn.config import ModelConfig -from sleap.gui.widgets.video import GraphicsView +from typing import Optional, Text import numpy as np +from qtpy import QtWidgets, QtGui, QtCore -from sleap import Skeleton +from sleap import Video, Track, Skeleton +from sleap.nn.config import ModelConfig +from sleap.gui.widgets.video import GraphicsView from sleap.nn.model import Model -from typing import Optional, Text - -from qtpy import QtWidgets, QtGui, QtCore - def compute_rf(down_blocks: int, convs_per_block: int = 2, kernel_size: int = 3) -> int: """ @@ -54,7 +51,9 @@ def receptive_field_info_from_model_cfg(model_cfg: ModelConfig) -> dict: ) try: - model = Model.from_config(model_cfg, Skeleton()) + # `Skeleton` and `Tracks` not important for receptive field computation, but + # required as check in `Model.from_config` + model = Model.from_config(model_cfg, skeleton=Skeleton(), tracks=[Track()]) except ZeroDivisionError: # Unable to create model from these config parameters return rf_info @@ -228,20 +227,3 @@ def _set_field_size(self, size: Optional[int] = None, scale: float = 1.0): self.box.setRect( scene_center.x(), scene_center.y(), scaled_box_size, scaled_box_size ) - - -def demo_receptive_field(): - app = QtWidgets.QApplication([]) - - video = Video.from_filename("tests/data/videos/centered_pair_small.mp4") - - win = ReceptiveFieldImageWidget() - win.setImage(video.get_frame(0)) - win._set_field_size(50) - - win.show() - app.exec_() - - -if __name__ == "__main__": - demo_receptive_field() diff --git a/sleap/gui/learning/runners.py b/sleap/gui/learning/runners.py index cf2fd5887..d0bb1f3ba 100644 --- a/sleap/gui/learning/runners.py +++ b/sleap/gui/learning/runners.py @@ -1,6 +1,5 @@ -""" -Run training/inference in background process via CLI. -""" +"""Run training/inference in background process via CLI.""" + import abc import attr import os @@ -41,8 +40,7 @@ def kill_process(pid: int): @attr.s(auto_attribs=True) class ItemForInference(abc.ABC): - """ - Abstract base class for item on which we can run inference via CLI. + """Abstract base class for item on which we can run inference via CLI. Must have `path` and `cli_args` properties, used to build CLI call. """ @@ -60,8 +58,7 @@ def cli_args(self) -> List[Text]: @attr.s(auto_attribs=True) class VideoItemForInference(ItemForInference): - """ - Encapsulate data about video on which inference should run. + """Encapsulate data about video on which inference should run. This allows for inference on an arbitrary list of frames from video. @@ -109,7 +106,8 @@ def cli_args(self): # -Y represents endpoint of [X, Y) range but inference cli expects # [X, Y-1] range (so add 1 since negative). - frame_int_list = [i + 1 if i < 0 else i for i in self.frames] + frame_int_list = list(set([i + 1 if i < 0 else i for i in self.frames])) + frame_int_list.sort(reverse=min(frame_int_list) < 0) # Assumes len of 2 if neg. arg_list.extend(("--frames", ",".join(map(str, frame_int_list)))) @@ -118,8 +116,7 @@ def cli_args(self): @attr.s(auto_attribs=True) class DatasetItemForInference(ItemForInference): - """ - Encapsulate data about frame selection based on dataset data. + """Encapsulate data about frame selection based on dataset data. Attributes: labels_path: path to the saved :py:class:`Labels` dataset. @@ -141,7 +138,7 @@ def path(self): @property def cli_args(self): - args_list = ["--labels", self.path] + args_list = [self.path] if self.frame_filter == "user": args_list.append("--only-labeled-frames") elif self.frame_filter == "suggested": @@ -155,6 +152,7 @@ class ItemsForInference: items: List[ItemForInference] total_frame_count: int + batch_size: int def __len__(self): return len(self.items) @@ -164,6 +162,7 @@ def from_video_frames_dict( cls, video_frames_dict: Dict[Video, List[int]], total_frame_count: int, + batch_size: int, labels: Labels, labels_path: Optional[str] = None, ): @@ -178,7 +177,9 @@ def from_video_frames_dict( video_idx=labels.videos.index(video), ) ) - return cls(items=items, total_frame_count=total_frame_count) + return cls( + items=items, total_frame_count=total_frame_count, batch_size=batch_size + ) @attr.s(auto_attribs=True) @@ -199,18 +200,8 @@ def make_predict_cli_call( ) -> List[Text]: """Makes list of CLI arguments needed for running inference.""" cli_args = ["sleap-track"] - cli_args.extend(item_for_inference.cli_args) - # TODO: encapsulate in inference item class - if ( - not self.trained_job_paths - and "tracking.tracker" in self.inference_params - and self.labels_filename - ): - # No models so we must want to re-track previous predictions - cli_args.extend(("--labels", self.labels_filename)) - # Make path where we'll save predictions (if not specified) if output_path is None: @@ -238,13 +229,26 @@ def make_predict_cli_call( optional_items_as_nones = ( "tracking.target_instance_count", + "tracking.max_tracks", "tracking.kf_init_frame_count", + "tracking.robust", + "max_instances", ) for key in optional_items_as_nones: if key in self.inference_params and self.inference_params[key] is None: del self.inference_params[key] + # Setting max_tracks to True means we want to use the max_tracking mode. + if "tracking.max_tracks" in self.inference_params: + self.inference_params["tracking.max_tracking"] = True + + # Hacky: Update the tracker name to include "maxtracks" suffix. + if self.inference_params["tracking.tracker"] in ("simple", "flow"): + self.inference_params["tracking.tracker"] = ( + self.inference_params["tracking.tracker"] + "maxtracks" + ) + # --tracking.kf_init_frame_count enables the kalman filter tracking # so if not set, then remove other (unused) args if "tracking.kf_init_frame_count" not in self.inference_params: @@ -253,13 +257,23 @@ def make_predict_cli_call( bool_items_as_ints = ( "tracking.pre_cull_to_target", + "tracking.max_tracking", "tracking.post_connect_single_breaks", + "tracking.save_shifted_instances", + "tracking.oks_score_weighting", ) for key in bool_items_as_ints: if key in self.inference_params: self.inference_params[key] = int(self.inference_params[key]) + remove_spaces_items = ("tracking.similarity",) + + for key in remove_spaces_items: + if key in self.inference_params: + value = self.inference_params[key] + self.inference_params[key] = value.replace(" ", "_") + for key, val in self.inference_params.items(): if not key.startswith(("_", "outputs.", "model.", "data.")): cli_args.extend((f"--{key}", str(val))) @@ -481,7 +495,6 @@ def write_pipeline_files( ) # And join them into a single call to inference inference_script += " ".join(cli_args) + "\n" - # Setup job params only_suggested_frames = False if type(item_for_inference) == DatasetItemForInference: @@ -496,9 +509,11 @@ def write_pipeline_files( "data_path": os.path.basename(data_path), "models": [Path(p).as_posix() for p in new_cfg_filenames], "output_path": prediction_output_path, - "type": "labels" - if type(item_for_inference) == DatasetItemForInference - else "video", + "type": ( + "labels" + if type(item_for_inference) == DatasetItemForInference + else "video" + ), "only_suggested_frames": only_suggested_frames, "tracking": tracking_args, } @@ -540,24 +555,33 @@ def run_learning_pipeline( """ save_viz = inference_params.get("_save_viz", False) + keep_viz = inference_params.get("_keep_viz", False) + + if "movenet" in inference_params["_pipeline"]: + trained_job_paths = [inference_params["_pipeline"]] + + else: + # Train the TrainingJobs + trained_job_paths = run_gui_training( + labels_filename=labels_filename, + labels=labels, + config_info_list=config_info_list, + inference_params=inference_params, + gui=True, + save_viz=save_viz, + keep_viz=keep_viz, + ) - # Train the TrainingJobs - trained_job_paths = run_gui_training( - labels_filename=labels_filename, - labels=labels, - config_info_list=config_info_list, - gui=True, - save_viz=save_viz, - ) + # Check that all the models were trained + if None in trained_job_paths.values(): + return -1 - # Check that all the models were trained - if None in trained_job_paths.values(): - return -1 + trained_job_paths = list(trained_job_paths.values()) inference_task = InferenceTask( labels=labels, labels_filename=labels_filename, - trained_job_paths=list(trained_job_paths.values()), + trained_job_paths=trained_job_paths, inference_params=inference_params, ) @@ -571,8 +595,10 @@ def run_gui_training( labels_filename: str, labels: Labels, config_info_list: List[ConfigFileInfo], + inference_params: Dict[str, Any], gui: bool = True, save_viz: bool = False, + keep_viz: bool = False, ) -> Dict[Text, Text]: """ Runs training for each training job. @@ -582,19 +608,28 @@ def run_gui_training( config_info_list: List of ConfigFileInfo with configs for training. gui: Whether to show gui windows and process gui events. save_viz: Whether to save visualizations from training. + keep_viz: Whether to keep prediction visualization images after training. Returns: Dictionary, keys are head name, values are path to trained config. """ trained_job_paths = dict() - + zmq_ports = None if gui: from sleap.gui.widgets.monitor import LossViewer from sleap.gui.widgets.imagedir import QtImageDirectoryWidget - # open training monitor window - win = LossViewer() + zmq_ports = dict() + zmq_ports["controller_port"] = inference_params.get("controller_port", 9000) + zmq_ports["publish_port"] = inference_params.get("publish_port", 9001) + + # Open training monitor window + win = LossViewer(zmq_ports=zmq_ports) + + # Reassign the values in the inference parameters in case the ports were changed + inference_params["controller_port"] = win.zmq_ports["controller_port"] + inference_params["publish_port"] = win.zmq_ports["publish_port"] win.resize(600, 400) win.show() @@ -658,10 +693,12 @@ def waiting(): # Run training trained_job_path, ret = train_subprocess( job_config=job, + inference_params=inference_params, labels_filename=labels_filename, video_paths=video_path_list, waiting_callback=waiting, save_viz=save_viz, + keep_viz=keep_viz, ) if ret == "success": @@ -800,9 +837,11 @@ def waiting_item(**kwargs): def train_subprocess( job_config: TrainingJobConfig, labels_filename: str, + inference_params: Dict[str, Any], video_paths: Optional[List[Text]] = None, waiting_callback: Optional[Callable] = None, save_viz: bool = False, + keep_viz: bool = False, ): """Runs training inside subprocess.""" run_path = job_config.outputs.run_path @@ -823,10 +862,16 @@ def train_subprocess( training_job_path, labels_filename, "--zmq", + "--controller_port", + str(inference_params["controller_port"]), + "--publish_port", + str(inference_params["publish_port"]), ] if save_viz: cli_args.append("--save_viz") + if keep_viz: + cli_args.append("--keep_viz") # Use cli arg since cli ignores setting in config if job_config.outputs.tensorboard.write_logs: diff --git a/sleap/gui/learning/scopedkeydict.py b/sleap/gui/learning/scopedkeydict.py index d10867ddc..aeeb790cf 100644 --- a/sleap/gui/learning/scopedkeydict.py +++ b/sleap/gui/learning/scopedkeydict.py @@ -2,7 +2,7 @@ Conversion between flat (form data) and hierarchical (config object) dicts. """ -from typing import Any, Dict, Optional, Text, Tuple +from typing import Any, Dict, Optional, Text, Tuple, Union import attr import cattr @@ -39,7 +39,7 @@ def set_hierarchical_key_val(cls, current_dict: dict, key: Text, val: Any): current_dict[key] = val else: top_key, *subkey_list = key.split(".") - if top_key not in current_dict: + if top_key not in current_dict or current_dict[top_key] is None: current_dict[top_key] = dict() subkey = ".".join(subkey_list) cls.set_hierarchical_key_val(current_dict[top_key], subkey, val) @@ -157,8 +157,12 @@ def resolve_strides_from_key_val_dict( "model.heads.centroid.output_stride", "model.heads.multi_instance.confmaps.output_stride", "model.heads.multi_instance.pafs.output_stride", + "model.heads.multi_class_topdown.confmaps.output_stride", + "model.heads.multi_class_bottomup.confmaps.output_stride", + "model.heads.multi_class_bottomup.class_maps.output_stride", ]: stride = key_val_dict.get(key, None) + if stride is not None: stride = int(stride) max_stride = ( @@ -174,7 +178,9 @@ def resolve_strides_from_key_val_dict( return max_stride, output_stride -def make_training_config_from_key_val_dict(key_val_dict: dict) -> TrainingJobConfig: +def make_training_config_from_key_val_dict( + key_val_dict: Union[dict, ScopedKeyDict] +) -> TrainingJobConfig: """ Make :py:class:`TrainingJobConfig` object from flat dictionary. @@ -183,9 +189,11 @@ def make_training_config_from_key_val_dict(key_val_dict: dict) -> TrainingJobCon Returns: The :py:class:`TrainingJobConfig` object. """ - apply_cfg_transforms_to_key_val_dict(key_val_dict) - cfg_dict = ScopedKeyDict(key_val_dict).to_hierarchical_dict() + if not isinstance(key_val_dict, ScopedKeyDict): + apply_cfg_transforms_to_key_val_dict(key_val_dict) + key_val_dict = ScopedKeyDict(key_val_dict) + cfg_dict = key_val_dict.to_hierarchical_dict() cfg = cattr.structure(cfg_dict, TrainingJobConfig) return cfg diff --git a/sleap/gui/overlays/base.py b/sleap/gui/overlays/base.py index 60b04de1d..879d12810 100644 --- a/sleap/gui/overlays/base.py +++ b/sleap/gui/overlays/base.py @@ -8,35 +8,80 @@ so that current frame must be redrawn). """ -from qtpy import QtWidgets +import abc +import logging +from typing import Sequence, Union, Optional, List import attr -import abc import numpy as np -from typing import Sequence, Union +from qtpy import QtWidgets +from qtpy.QtWidgets import QGraphicsItem from sleap import Labels, Video from sleap.gui.widgets.video import QtVideoPlayer from sleap.nn.data.providers import VideoReader from sleap.nn.inference import VisualPredictor +logger = logging.getLogger(__name__) + @attr.s(auto_attribs=True) class BaseOverlay(abc.ABC): - """ - Abstract base class for overlays. + """Abstract base class for overlays. Most overlays need rely on the `Labels` from which to get data and need the - `QtVideoPlayer` to which a `QGraphicsObject` item will be added, so these + `QtVideoPlayer` to which a `QGraphicsItem` will be added, so these attributes are included in the base class. + + Args: + labels: the `Labels` from which to get data + player: the `QtVideoPlayer` to which a `QGraphicsObject` item will be added + items: stores all `QGraphicsItem`s currently added to the player from this + overlay """ - labels: Labels = None - player: QtVideoPlayer = None + labels: Optional[Labels] = None + player: Optional[QtVideoPlayer] = None + items: Optional[List[QGraphicsItem]] = None @abc.abstractmethod def add_to_scene(self, video: Video, frame_idx: int): - pass + """Add items to scene. + + To use the `remove_from_scene` and `redraw` methods, keep track of a list of + `QGraphicsItem`s added in this function. + """ + # Start your method with: + self.items = [] + + # As items are added to the `QtVideoPlayer`, keep track of these items: + item = self.player.scene.addItem(...) + self.items.append(item) + + def remove_from_scene(self): + """Remove all items added to scene by this overlay. + + This method does not need to be called when changing the plot to a new frame. + """ + if self.items is None: + return + for item in self.items: + try: + self.player.scene.removeItem(item) + + except RuntimeError as e: # Internal C++ object (PySide2.QtWidgets.QGraphicsPathItem) already deleted. + logger.debug(e) + + # Stop tracking the items after they been removed from the scene + self.items = [] + + def redraw(self, video, frame_idx, *args, **kwargs): + """Remove all items from the scene before adding new items to the scene. + + This method does not need to be called when changing the plot to a new frame. + """ + self.remove_from_scene(*args, **kwargs) + self.add_to_scene(video, frame_idx, *args, **kwargs) @attr.s(auto_attribs=True) diff --git a/sleap/gui/overlays/tracks.py b/sleap/gui/overlays/tracks.py index d17907587..c5f091658 100644 --- a/sleap/gui/overlays/tracks.py +++ b/sleap/gui/overlays/tracks.py @@ -1,18 +1,16 @@ -""" -Track trail and track list overlays. -""" +"""Track trail and track list overlays.""" + +from typing import Dict, Iterable, List, Optional, Tuple + +import attr +from qtpy import QtCore, QtGui + from sleap.gui.overlays.base import BaseOverlay +from sleap.gui.widgets.video import QtTextWithBackground from sleap.instance import Track from sleap.io.dataset import Labels from sleap.io.video import Video from sleap.prefs import prefs -from sleap.gui.widgets.video import QtTextWithBackground - -import attr - -from typing import Iterable, List, Optional - -from qtpy import QtCore, QtGui @attr.s(auto_attribs=True) @@ -27,6 +25,8 @@ class TrackTrailOverlay(BaseOverlay): labels: The :class:`Labels` dataset from which to get overlay data. player: The video player in which to show overlay. trail_length: The maximum number of frames to include in trail. + trail_shade: A literal "Dark", "Normal", or "Bright" which determines the shade + of the trail color. Usage: After class is instantiated, call :meth:`add_to_scene(frame_idx)` @@ -34,10 +34,32 @@ class TrackTrailOverlay(BaseOverlay): """ trail_length: int = 0 + trail_shade: str = attr.ib( + default="Normal", validator=attr.validators.in_(["Dark", "Normal", "Light"]) + ) show: bool = True max_node_count: Optional[int] = None - def get_track_trails(self, frame_selection: Iterable["LabeledFrame"]): + def __attrs_post_init__(self): + """Initialize the shade options attribute after initalizing the instance.""" + + self.shade_options = self.get_shade_options() + + @classmethod + def get_length_options(cls): + if prefs["trail length"] != 0: + return (0, 10, 50, 100, 250, 500, prefs["trail length"]) + return (0, 10, 50, 100, 250, 500) + + @classmethod + def get_shade_options(cls): + """Return a dictionary with values to multiply each RGB value by.""" + + return {"Dark": 0.6, "Normal": 1.0, "Light": 1.25} + + def get_track_trails( + self, frame_selection: Iterable["LabeledFrame"] + ) -> Optional[Dict[Track, List[List[Tuple[float, float]]]]]: """Get data needed to draw track trail. Args: @@ -60,8 +82,8 @@ def get_track_trails(self, frame_selection: Iterable["LabeledFrame"]): nodes = nodes[:max_node_count] for frame in frame_selection: - - for inst in frame: + # Prefer user instances over predicted instances + for inst in frame.instances_to_show: if inst.track is not None: if inst.track not in all_track_trails: all_track_trails[inst.track] = [[] for _ in range(len(nodes))] @@ -85,9 +107,7 @@ def get_track_trails(self, frame_selection: Iterable["LabeledFrame"]): return all_track_trails def get_frame_selection(self, video: Video, frame_idx: int): - """ - Return `LabeledFrame` objects to include in trail for specified frame. - """ + """Return `LabeledFrame` objects to include in trail for specified frame.""" frame_selection = self.labels.find(video, range(0, frame_idx + 1)) frame_selection.sort(key=lambda x: x.frame_idx) @@ -97,8 +117,7 @@ def get_frame_selection(self, video: Video, frame_idx: int): def get_tracks_in_frame( self, video: Video, frame_idx: int, include_trails: bool = False ) -> List[Track]: - """ - Returns list of tracks that have instance in specified frame. + """Returns list of tracks that have instance in specified frame. Args: video: Video for which we want tracks. @@ -108,6 +127,7 @@ def get_tracks_in_frame( within trail_length). Returns: List of tracks. + """ if include_trails: @@ -125,17 +145,25 @@ def add_to_scene(self, video: Video, frame_idx: int): Args: video: current video frame_idx: index of the frame to which the trail is attached + """ + self.items = [] + if not self.show or self.trail_length == 0: return frame_selection = self.get_frame_selection(video, frame_idx) all_track_trails = self.get_track_trails(frame_selection) + if all_track_trails is None: + return for track, trails in all_track_trails.items(): - - color = QtGui.QColor(*self.player.color_manager.get_track_color(track)) + trail_color = tuple( + min(c * self.shade_options[self.trail_shade], 255) + for c in self.player.color_manager.get_track_color(track) + ) + color = QtGui.QColor(*trail_color) pen = QtGui.QPen() pen.setCosmetic(True) pen.setColor(color) @@ -166,7 +194,8 @@ def add_to_scene(self, video: Video, frame_idx: int): for segment in segments: pen.setWidthF(width) path = self.map_to_qt_path(segment) - self.player.scene.addPath(path, pen) + item = self.player.scene.addPath(path, pen) + self.items.append(item) width /= 2 @staticmethod @@ -183,9 +212,7 @@ def map_to_qt_path(point_list): @attr.s(auto_attribs=True) class TrackListOverlay(BaseOverlay): - """ - Class to show track number and names in overlay. - """ + """Class to show track number and names in overlay.""" text_box: Optional[QtTextWithBackground] = None diff --git a/sleap/gui/shortcuts.py b/sleap/gui/shortcuts.py index b81eabf05..37db5fb51 100644 --- a/sleap/gui/shortcuts.py +++ b/sleap/gui/shortcuts.py @@ -58,6 +58,7 @@ class Shortcuts(object): "frame prev medium step", "frame next large step", "frame prev large step", + "export_analysis_current", ) def __init__(self): diff --git a/sleap/gui/state.py b/sleap/gui/state.py index 63a904469..4c559ad0e 100644 --- a/sleap/gui/state.py +++ b/sleap/gui/state.py @@ -21,7 +21,7 @@ """ import inspect -from typing import Any, Callable, List, Union +from typing import Any, Callable, List, Union, Optional GSVarType = str @@ -43,6 +43,12 @@ def __init__(self): self._state_vars = dict() self._callbacks = dict() + def __repr__(self) -> str: + message = f"GuiState(" + for key in self._state_vars: + message += f"'{key}'={self.get(key)}, " + return f"{message[:-2]})" + def __getitem__(self, key: GSVarType) -> Any: """Gets value for key, or None if no value.""" return self.get(key, default=None) @@ -77,13 +83,15 @@ def toggle(self, key: GSVarType, default: bool = False): """Toggle boolean value for specified key.""" self[key] = not self.get(key, default=default) - def increment(self, key: GSVarType, step: int = 1, mod: int = 1, default: int = 0): + def increment( + self, key: GSVarType, step: int = 1, mod: Optional[int] = None, default: int = 0 + ): """Increment numeric value for specified key. Args: key: The key. step: What to add to current value. - mod: Wrap value (i.e., apply modulus) if not 1. + mod: Wrap value (i.e., apply modulus) if not None. default: Set value to this if there's no current value for key. Returns: @@ -91,14 +99,15 @@ def increment(self, key: GSVarType, step: int = 1, mod: int = 1, default: int = """ if key not in self._state_vars: self[key] = default - else: - new_value = self.get(key) + step + return + + new_value = self.get(key) + step - # take modulo of value if mod arg is not 1 - if mod != 1: - new_value %= mod + # Wrap the value if it's out of bounds. + if mod is not None: + new_value %= mod - self[key] = new_value + self[key] = new_value def increment_in_list( self, key: GSVarType, value_list: list, reverse: bool = False diff --git a/sleap/gui/suggestions.py b/sleap/gui/suggestions.py index 007c57caf..b85d6ac32 100644 --- a/sleap/gui/suggestions.py +++ b/sleap/gui/suggestions.py @@ -60,14 +60,18 @@ def suggest(cls, params: dict, labels: "Labels" = None) -> List[SuggestionFrame] image_features=cls.image_feature_based_method, prediction_score=cls.prediction_score, velocity=cls.velocity, + frame_chunk=cls.frame_chunk, + max_point_displacement=cls.max_point_displacement, ) method = str.replace(params["method"], " ", "_") if method_functions.get(method, None) is not None: return method_functions[method](labels=labels, **params) else: - print(f"No {method} method found for generating suggestions.") - return [] + raise ValueError( + f"No {'' if method == '_' else method + ' '}method found for " + "generating suggestions." + ) # Functions corresponding to "method" param @@ -82,7 +86,8 @@ def basic_sample_suggestion_method( ): """Method to generate suggestions randomly or by taking strides through video.""" suggestions = [] - sugg_idx_dict: Dict[Video, list] = {video: [] for video in videos} + sugg_idx_dict: Dict[Video, list] = {video: [] for video in labels.videos} + for sugg in labels.suggestions: sugg_idx_dict[sugg.video].append(sugg.frame_idx) @@ -171,17 +176,25 @@ def prediction_score( labels: "Labels", videos: List[Video], score_limit, - instance_limit, + instance_limit_upper, + instance_limit_lower, **kwargs, ): """Method to generate suggestions for proofreading frames with low score.""" score_limit = float(score_limit) - instance_limit = int(instance_limit) + instance_limit_upper = int(instance_limit_upper) + instance_limit_lower = int(instance_limit_lower) proposed_suggestions = [] for video in videos: proposed_suggestions.extend( - cls._prediction_score_video(video, labels, score_limit, instance_limit) + cls._prediction_score_video( + video, + labels, + score_limit, + instance_limit_upper, + instance_limit_lower, + ) ) suggestions = VideoFrameSuggestions.filter_unique_suggestions( @@ -192,29 +205,37 @@ def prediction_score( @classmethod def _prediction_score_video( - cls, video: Video, labels: "Labels", score_limit: float, instance_limit: int + cls, + video: Video, + labels: "Labels", + score_limit: float, + instance_limit_upper: int, + instance_limit_lower: int, ): lfs = labels.find(video) frames = len(lfs) - idxs = np.ndarray((frames), dtype="int") - scores = np.full((frames, instance_limit), 100.0, dtype="float") - # Build matrix with scores for instances in frames + # initiate an array filled with -1 to store frame index (starting from 0). + idxs = np.full((frames), -1, dtype="int") + for i, lf in enumerate(lfs): - # Scores from instances in frame - frame_scores = [inst.score for inst in lf if hasattr(inst, "score")] - # Just get the lowest scores - if len(frame_scores) > instance_limit: - frame_scores = sorted(frame_scores)[:instance_limit] - # Add to matrix - scores[i, : len(frame_scores)] = frame_scores - idxs[i] = lf.frame_idx + # Scores from visible instances in frame + pred_fs = lf.instances_to_show + frame_scores = np.array( + [inst.score for inst in pred_fs if hasattr(inst, "score")] + ) + # Gets the number of instances with scores lower than + n_qualified_instance = np.nansum(frame_scores <= score_limit) - # Find instances below score of - low_instances = np.nansum(scores < score_limit, axis=1) + if ( + n_qualified_instance >= instance_limit_lower + and n_qualified_instance <= instance_limit_upper + ): + # idxs saves qualified frame index at corresponding entry, otherwise the entry is -1 + idxs[i] = lf.frame_idx - # Find all the frames with at least low scoring instances - result = idxs[low_instances >= instance_limit].tolist() + # Finds non-negative entries in idxs + result = sorted(idxs[idxs >= 0].tolist()) return cls.idx_list_to_frame_list(result, video) @@ -272,6 +293,87 @@ def _velocity_video( return cls.idx_list_to_frame_list(frame_idxs, video) + @classmethod + def max_point_displacement( + cls, + labels: "Labels", + videos: List[Video], + displacement_threshold: float, + **kwargs, + ): + """Finds frames with maximum point displacement above a threshold.""" + + proposed_suggestions = [] + for video in videos: + proposed_suggestions.extend( + cls._max_point_displacement_video(video, labels, displacement_threshold) + ) + + suggestions = VideoFrameSuggestions.filter_unique_suggestions( + labels, videos, proposed_suggestions + ) + + return suggestions + + @classmethod + def _max_point_displacement_video( + cls, video: Video, labels: "Labels", displacement_threshold: float + ): + # Get numpy of shape (frames, tracks, nodes, x, y) + labels_numpy = labels.numpy(video=video, all_frames=True, untracked=False) + + # Return empty list if not enough frames + n_frames, n_tracks, n_nodes, _ = labels_numpy.shape + + if n_frames < 2: + return [] + + # Calculate displacements + diff = labels_numpy[1:] - labels_numpy[:-1] # (frames - 1, tracks, nodes, x, y) + euc_norm = np.linalg.norm(diff, axis=-1) # (frames - 1, tracks, nodes) + mean_euc_norm = np.nanmean(euc_norm, axis=-1) # (frames - 1, tracks) + + # Find frames where mean displacement is above threshold + threshold_mask = np.any( + mean_euc_norm > displacement_threshold, axis=-1 + ) # (frames - 1,) + frame_idxs = list( + np.argwhere(threshold_mask).flatten() + 1 + ) # [0, len(frames - 1)] + + return cls.idx_list_to_frame_list(frame_idxs, video) + + @classmethod + def frame_chunk( + cls, + labels: "Labels", + videos: List[Video], + frame_from: int, + frame_to: int, + **kwargs, + ): + """Add consecutive frame chunk to label suggestion""" + + proposed_suggestions = [] + + # Check the validity of inputs, frame_from <= frame_to + if frame_from > frame_to: + return proposed_suggestions + + for video in videos: + # Make sure when targeting all videos the from and to do not exceed frame number + if frame_from > video.num_frames: + continue + this_video_frame_to = min(frame_to, video.num_frames) + # Generate list of frame numbers + idx = list(range(frame_from - 1, this_video_frame_to)) + proposed_suggestions.extend(cls.idx_list_to_frame_list(idx, video)) + + suggestions = VideoFrameSuggestions.filter_unique_suggestions( + labels, videos, proposed_suggestions + ) + return suggestions + # Utility functions @staticmethod @@ -287,7 +389,7 @@ def filter_unique_suggestions( proposed_suggestions: List[SuggestionFrame], ) -> List[SuggestionFrame]: # Create log of suggestions that already exist - sugg_idx_dict: Dict[Video, list] = {video: [] for video in videos} + sugg_idx_dict: Dict[Video, list] = {video: [] for video in labels.videos} for sugg in labels.suggestions: sugg_idx_dict[sugg.video].append(sugg.frame_idx) diff --git a/sleap/gui/utils.py b/sleap/gui/utils.py new file mode 100644 index 000000000..4f8215706 --- /dev/null +++ b/sleap/gui/utils.py @@ -0,0 +1,28 @@ +"""Generic module containing utilities used for the GUI.""" + +import zmq +from typing import Optional + + +def is_port_free(port: int, zmq_context: Optional[zmq.Context] = None) -> bool: + """Checks if a port is free.""" + ctx = zmq.Context.instance() if zmq_context is None else zmq_context + socket = ctx.socket(zmq.REP) + address = f"tcp://127.0.0.1:{port}" + try: + socket.bind(address) + socket.unbind(address) + return True + except zmq.error.ZMQError: + return False + finally: + socket.close() + + +def select_zmq_port(zmq_context: Optional[zmq.Context] = None) -> int: + """Select a port that is free to connect within the given context.""" + ctx = zmq.Context.instance() if zmq_context is None else zmq_context + socket = ctx.socket(zmq.REP) + port = socket.bind_to_random_port("tcp://127.0.0.1") + socket.close() + return port diff --git a/sleap/gui/release_checker.py b/sleap/gui/web.py similarity index 77% rename from sleap/gui/release_checker.py rename to sleap/gui/web.py index f9607cd52..d753ea16e 100644 --- a/sleap/gui/release_checker.py +++ b/sleap/gui/web.py @@ -1,13 +1,13 @@ """Module for checking for new releases on GitHub.""" - import attr import pandas as pd import requests -from typing import List, Dict, Optional +from typing import List, Dict, Any REPO_ID = "talmolab/sleap" +ANALYTICS_ENDPOINT = "https://analytics.sleap.ai/ping" @attr.s(auto_attribs=True) @@ -144,3 +144,46 @@ def get_release(self, version: str) -> Release: "Check the page online for a full listing: " f"https://github.com/{self.repo_id}" ) + + +def get_analytics_data() -> Dict[str, Any]: + """Gather data to be transmitted to analytics backend.""" + import os + import sleap + import tensorflow as tf + from pathlib import Path + import platform + + return { + "sleap_version": sleap.__version__, + "python_version": platform.python_version(), + "tf_version": tf.__version__, + "conda_env": Path(os.environ.get("CONDA_PREFIX", "")).stem, + "platform": platform.platform(), + } + + +def ping_analytics(): + """Ping analytics service with anonymous usage data. + + Notes: + This only gets called when the GUI starts and obeys user preferences for data + collection. + + See https://sleap.ai/help.html#usage-data for more information. + """ + import threading + + analytics_data = get_analytics_data() + + def _ping_analytics(): + try: + response = requests.post( + ANALYTICS_ENDPOINT, + json=analytics_data, + ) + except (requests.ConnectionError, requests.Timeout): + pass + + # Fire and forget. + threading.Thread(target=_ping_analytics).start() diff --git a/sleap/gui/widgets/docks.py b/sleap/gui/widgets/docks.py new file mode 100644 index 000000000..bd20bf79a --- /dev/null +++ b/sleap/gui/widgets/docks.py @@ -0,0 +1,566 @@ +"""Module for creating dock widgets for the `MainWindow`.""" + +from typing import Callable, Iterable, List, Optional, Type, Union + +from qtpy import QtGui +from qtpy.QtCore import Qt +from qtpy.QtWidgets import ( + QComboBox, + QDockWidget, + QGroupBox, + QHBoxLayout, + QLabel, + QLayout, + QMainWindow, + QPushButton, + QTabWidget, + QVBoxLayout, + QWidget, +) + +from sleap.gui.dataviews import ( + GenericTableModel, + GenericTableView, + LabeledFrameTableModel, + SkeletonEdgesTableModel, + SkeletonNodeModel, + SkeletonNodesTableModel, + SuggestionsTableModel, + VideosTableModel, +) +from sleap.gui.dialogs.formbuilder import YamlFormWidget +from sleap.gui.widgets.views import CollapsibleWidget +from sleap.skeleton import Skeleton, SkeletonDecoder +from sleap.util import find_files_by_suffix, get_package_file + + +class DockWidget(QDockWidget): + """'Abstract' class for a dockable widget attached to the `MainWindow`.""" + + def __init__( + self, + name: str, + main_window: Optional[QMainWindow] = None, + model_type: Optional[ + Union[Type[GenericTableModel], List[Type[GenericTableModel]]] + ] = None, + widgets: Optional[Iterable[QWidget]] = None, + tab_with: Optional[QLayout] = None, + ): + # Create the dock and add it to the main window. + super().__init__(name) + self.name = name + self.main_window = main_window + self.setup_dock(widgets, tab_with) + + # Create the model and table for the dock. + self.model_type = model_type + if self.model_type is None: + self.model = None + self.table = None + else: + self.model = self.create_models() + self.table = self.create_tables() + + # Lay out the dock widget, adding/creating other widgets if needed. + self.lay_everything_out() + + @property + def wgt_layout(self) -> QVBoxLayout: + return self.widget().layout() + + def setup_dock(self, widgets, tab_with): + """Create a dock widget. + + Args: + widgets: The widgets to add to the dock. + tab_with: The `QLayout` to tabify the `DockWidget` with. + """ + + self.setObjectName(self.name + "Dock") + self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) + + dock_widget = QWidget() + dock_widget.setObjectName(self.name + "Widget") + layout = QVBoxLayout() + + widgets = widgets or [] + for widget in widgets: + layout.addWidget(widget) + + dock_widget.setLayout(layout) + self.setWidget(dock_widget) + + self.add_to_window(self.main_window, tab_with) + + def add_to_window(self, main_window: QMainWindow, tab_with: QVBoxLayout): + """Add the dock to the `MainWindow`. + + Args: + tab_with: The `QLayout` to tabify the `DockWidget` with. + """ + self.main_window = main_window + self.main_window.addDockWidget(Qt.RightDockWidgetArea, self) + self.main_window.viewMenu.addAction(self.toggleViewAction()) + + if tab_with is not None: + self.main_window.tabifyDockWidget(tab_with, self) + + def add_button(self, to: QLayout, label: str, action: Callable, key=None): + key = key or label.lower() + btn = QPushButton(label) + btn.clicked.connect(action) + to.addWidget(btn) + self.main_window._buttons[key] = btn + return btn + + def create_models(self) -> GenericTableModel: + """Create the model for the table in the dock (if any). + + Implement this in the subclass. + Ex: + self.model = self.model_type(items=[], context=self.main_window.commands) + + Returns: + The model. + """ + raise NotImplementedError + + def create_tables(self) -> GenericTableView: + """Add a table to the dock. + + Implement this in the subclass. + Ex: + self.table = GenericTableView( + state=self.main_window.state, + model=self.model or self.create_models(), + ) + self.wgt_layout.addWidget(self.table) + + Returns: + The table widget. + """ + raise NotImplementedError + + def lay_everything_out(self) -> None: + """Lay out the dock widget, adding/creating other widgets if needed. + + Implement this in the subclass. No example as this is extremely custom. + """ + raise NotImplementedError + + +class VideosDock(DockWidget): + """Dock widget for displaying video information.""" + + def __init__( + self, + main_window: Optional[QMainWindow] = None, + ): + super().__init__( + name="Videos", main_window=main_window, model_type=VideosTableModel + ) + + def create_models(self) -> VideosTableModel: + self.model = self.model_type( + items=self.main_window.labels.videos, context=self.main_window.commands + ) + return self.model + + def create_tables(self) -> GenericTableView: + if self.model is None: + self.create_models() + + main_window = self.main_window + self.table = GenericTableView( + state=main_window.state, + row_name="video", + is_activatable=True, + model=self.model, + ellipsis_left=True, + multiple_selection=True, + ) + + return self.table + + def create_video_edit_and_nav_buttons(self) -> QWidget: + """Create the buttons for editing and navigating videos in table.""" + main_window = self.main_window + + hb = QHBoxLayout() + self.add_button(hb, "Toggle Grayscale", main_window.commands.toggleGrayscale) + self.add_button(hb, "Show Video", self.table.activateSelected) + self.add_button(hb, "Add Videos", main_window.commands.addVideo) + self.add_button(hb, "Remove Video", main_window.commands.removeVideo) + hbw = QWidget() + hbw.setLayout(hb) + return hbw + + def lay_everything_out(self): + """Lay out the dock widget, adding/creating other widgets if needed.""" + self.wgt_layout.addWidget(self.table) + + video_edit_and_nav_buttons = self.create_video_edit_and_nav_buttons() + self.wgt_layout.addWidget(video_edit_and_nav_buttons) + + +class SkeletonDock(DockWidget): + """Dock widget for displaying skeleton information.""" + + def __init__( + self, + main_window: Optional[QMainWindow] = None, + tab_with: Optional[QLayout] = None, + ): + self.nodes_model_type = SkeletonNodesTableModel + self.edges_model_type = SkeletonEdgesTableModel + super().__init__( + name="Skeleton", + main_window=main_window, + model_type=[self.nodes_model_type, self.edges_model_type], + tab_with=tab_with, + ) + + def create_models(self) -> GenericTableModel: + main_window = self.main_window + self.nodes_model = self.nodes_model_type( + items=main_window.state["skeleton"], context=main_window.commands + ) + self.edges_model = self.edges_model_type( + items=main_window.state["skeleton"], context=main_window.commands + ) + return [self.nodes_model, self.edges_model] + + def create_tables(self) -> GenericTableView: + if self.model is None: + self.create_models() + + main_window = self.main_window + self.nodes_table = GenericTableView( + state=main_window.state, + row_name="node", + model=self.nodes_model, + ) + + self.edges_table = GenericTableView( + state=main_window.state, + row_name="edge", + model=self.edges_model, + ) + + return [self.nodes_table, self.edges_table] + + def create_project_skeleton_groupbox(self) -> QGroupBox: + """Create the groupbox for the project skeleton.""" + main_window = self.main_window + gb = QGroupBox("Project Skeleton") + vgb = QVBoxLayout() + + nodes_widget = QWidget() + vb = QVBoxLayout() + graph_tabs = QTabWidget() + + vb.addWidget(self.nodes_table) + hb = QHBoxLayout() + self.add_button(hb, "New Node", main_window.commands.newNode) + self.add_button(hb, "Delete Node", main_window.commands.deleteNode) + + hbw = QWidget() + hbw.setLayout(hb) + vb.addWidget(hbw) + nodes_widget.setLayout(vb) + graph_tabs.addTab(nodes_widget, "Nodes") + + def _update_edge_src(): + self.skeletonEdgesDst.model().skeleton = main_window.state["skeleton"] + + edges_widget = QWidget() + + vb = QVBoxLayout() + vb.addWidget(self.edges_table) + + hb = QHBoxLayout() + self.skeletonEdgesSrc = QComboBox() + self.skeletonEdgesSrc.setEditable(False) + self.skeletonEdgesSrc.currentIndexChanged.connect(_update_edge_src) + self.skeletonEdgesSrc.setModel(SkeletonNodeModel(main_window.state["skeleton"])) + hb.addWidget(self.skeletonEdgesSrc) + hb.addWidget(QLabel("to")) + self.skeletonEdgesDst = QComboBox() + self.skeletonEdgesDst.setEditable(False) + hb.addWidget(self.skeletonEdgesDst) + self.skeletonEdgesDst.setModel( + SkeletonNodeModel( + main_window.state["skeleton"], + lambda: self.skeletonEdgesSrc.currentText(), + ) + ) + + def new_edge(): + src_node = self.skeletonEdgesSrc.currentText() + dst_node = self.skeletonEdgesDst.currentText() + main_window.commands.newEdge(src_node, dst_node) + + self.add_button(hb, "Add Edge", new_edge) + self.add_button(hb, "Delete Edge", main_window.commands.deleteEdge) + hbw = QWidget() + hbw.setLayout(hb) + vb.addWidget(hbw) + edges_widget.setLayout(vb) + graph_tabs.addTab(edges_widget, "Edges") + vgb.addWidget(graph_tabs) + + hb = QHBoxLayout() + self.add_button(hb, "Load From File...", main_window.commands.openSkeleton) + self.add_button(hb, "Save As...", main_window.commands.saveSkeleton) + + hbw = QWidget() + hbw.setLayout(hb) + vgb.addWidget(hbw) + + # Add graph tabs to "Project Skeleton" group box + gb.setLayout(vgb) + return gb + + def create_templates_groupbox(self) -> QGroupBox: + """Create the groupbox for the skeleton templates.""" + main_window = self.main_window + + gb = CollapsibleWidget("Templates") + vb = QVBoxLayout() + hb = QHBoxLayout() + + skeletons_folder = get_package_file("skeletons") + skeletons_json_files = find_files_by_suffix( + skeletons_folder, suffix=".json", depth=1 + ) + skeletons_names = [json.name.split(".")[0] for json in skeletons_json_files] + self.skeleton_templates = QComboBox() + self.skeleton_templates.addItems(skeletons_names) + self.skeleton_templates.setEditable(False) + hb.addWidget(self.skeleton_templates) + self.add_button(hb, "Load", main_window.commands.openSkeletonTemplate) + hbw = QWidget() + hbw.setLayout(hb) + vb.addWidget(hbw) + + hb = QHBoxLayout() + self.skeleton_preview_image = QLabel("Preview Skeleton") + hb.addWidget(self.skeleton_preview_image) + hb.setAlignment(self.skeleton_preview_image, Qt.AlignLeft) + + self.skeleton_description = QLabel( + f'Description: {main_window.state["skeleton_description"]}' + ) + self.skeleton_description.setWordWrap(True) + hb.addWidget(self.skeleton_description) + hb.setAlignment(self.skeleton_description, Qt.AlignLeft) + + hbw = QWidget() + hbw.setLayout(hb) + vb.addWidget(hbw) + + def updatePreviewImage(preview_image_bytes: bytes): + + # Decode the preview image + preview_image = SkeletonDecoder.decode_preview_image(preview_image_bytes) + + # Create a QImage from the Image + preview_image = QtGui.QImage( + preview_image.tobytes(), + preview_image.size[0], + preview_image.size[1], + QtGui.QImage.Format_RGBA8888, # Format for RGBA images (see Image.mode) + ) + + preview_image = QtGui.QPixmap.fromImage(preview_image) + + self.skeleton_preview_image.setPixmap(preview_image) + + def update_skeleton_preview(idx: int): + skel = Skeleton.load_json(skeletons_json_files[idx]) + main_window.state["skeleton_description"] = ( + f"Description: {skel.description}

" + f"Nodes ({len(skel)}): {', '.join(skel.node_names)}" + ) + self.skeleton_description.setText(main_window.state["skeleton_description"]) + updatePreviewImage(skel.preview_image) + + self.skeleton_templates.currentIndexChanged.connect(update_skeleton_preview) + update_skeleton_preview(idx=0) + + gb.set_content_layout(vb) + return gb + + def lay_everything_out(self): + """Lay out the dock widget, adding/creating other widgets if needed.""" + templates_gb = self.create_templates_groupbox() + self.wgt_layout.addWidget(templates_gb) + + project_skeleton_groupbox = self.create_project_skeleton_groupbox() + self.wgt_layout.addWidget(project_skeleton_groupbox) + + +class SuggestionsDock(DockWidget): + """Dock widget for displaying suggestions.""" + + def __init__(self, main_window: QMainWindow, tab_with: Optional[QLayout] = None): + super().__init__( + name="Labeling Suggestions", + main_window=main_window, + model_type=SuggestionsTableModel, + tab_with=tab_with, + ) + + def create_models(self) -> SuggestionsTableModel: + self.model = self.model_type( + items=self.main_window.labels.suggestions, context=self.main_window.commands + ) + return self.model + + def create_tables(self) -> GenericTableView: + self.table = GenericTableView( + state=self.main_window.state, + is_sortable=True, + model=self.model, + ) + + # Connect some actions to the table + def goto_suggestion(*args): + selected_frame = self.table.getSelectedRowItem() + self.main_window.commands.gotoVideoAndFrame( + selected_frame.video, selected_frame.frame_idx + ) + + self.table.doubleClicked.connect(goto_suggestion) + self.main_window.state.connect("suggestion_idx", self.table.selectRow) + + return self.table + + def lay_everything_out(self) -> None: + self.wgt_layout.addWidget(self.table) + + table_edit_buttons = self.create_table_edit_buttons() + self.wgt_layout.addWidget(table_edit_buttons) + + table_nav_buttons = self.create_table_nav_buttons() + self.wgt_layout.addWidget(table_nav_buttons) + + self.suggestions_form_widget = self.create_suggestions_form() + self.wgt_layout.addWidget(self.suggestions_form_widget) + + def create_table_nav_buttons(self) -> QWidget: + main_window = self.main_window + hb = QHBoxLayout() + + self.add_button( + hb, + "Previous", + main_window.process_events_then(main_window.commands.prevSuggestedFrame), + "goto previous suggestion", + ) + + self.suggested_count_label = QLabel() + hb.addWidget(self.suggested_count_label) + + self.add_button( + hb, + "Next", + main_window.process_events_then(main_window.commands.nextSuggestedFrame), + "goto next suggestion", + ) + + hbw = QWidget() + hbw.setLayout(hb) + return hbw + + def create_suggestions_form(self) -> QWidget: + main_window = self.main_window + suggestions_form_widget = YamlFormWidget.from_name( + "suggestions", + title="Generate Suggestions", + ) + suggestions_form_widget.mainAction.connect( + main_window.process_events_then(main_window.commands.generateSuggestions) + ) + return suggestions_form_widget + + def create_table_edit_buttons(self) -> QWidget: + main_window = self.main_window + hb = QHBoxLayout() + + self.add_button( + hb, + "Add current frame", + main_window.process_events_then( + main_window.commands.addCurrentFrameAsSuggestion + ), + "add current frame as suggestion", + ) + + self.add_button( + hb, + "Remove", + main_window.process_events_then(main_window.commands.removeSuggestion), + "remove suggestion", + ) + + self.add_button( + hb, + "Clear all", + main_window.process_events_then(main_window.commands.clearSuggestions), + "clear suggestions", + ) + + hbw = QWidget() + hbw.setLayout(hb) + return hbw + + +class InstancesDock(DockWidget): + """Dock widget for displaying instances.""" + + def __init__(self, main_window: QMainWindow, tab_with: Optional[QLayout] = None): + super().__init__( + name="Instances", + main_window=main_window, + model_type=LabeledFrameTableModel, + tab_with=tab_with, + ) + + def create_models(self) -> LabeledFrameTableModel: + self.model = self.model_type( + items=self.main_window.state["labeled_frame"], + context=self.main_window.commands, + ) + return self.model + + def create_tables(self) -> GenericTableView: + self.table = GenericTableView( + state=self.main_window.state, + row_name="instance", + name_prefix="", + model=self.model, + ) + return self.table + + def lay_everything_out(self) -> None: + self.wgt_layout.addWidget(self.table) + + table_edit_buttons = self.create_table_edit_buttons() + self.wgt_layout.addWidget(table_edit_buttons) + + def create_table_edit_buttons(self) -> QWidget: + main_window = self.main_window + + hb = QHBoxLayout() + self.add_button( + hb, "New Instance", lambda x: main_window.commands.newInstance(offset=10) + ) + self.add_button( + hb, "Delete Instance", main_window.commands.deleteSelectedInstance + ) + + hbw = QWidget() + hbw.setLayout(hb) + return hbw diff --git a/sleap/gui/widgets/monitor.py b/sleap/gui/widgets/monitor.py index 93bc483e9..fff8a0327 100644 --- a/sleap/gui/widgets/monitor.py +++ b/sleap/gui/widgets/monitor.py @@ -1,20 +1,590 @@ """GUI for monitoring training progress interactively.""" -import numpy as np -from time import perf_counter -from sleap.nn.config.training_job import TrainingJobConfig -import zmq -import jsonpickle import logging -from typing import Optional -from qtpy import QtCore, QtWidgets, QtGui -from qtpy.QtCharts import QtCharts +from time import perf_counter +from typing import Dict, Optional, Tuple + import attr +import jsonpickle +import numpy as np +import zmq +from matplotlib.collections import PathCollection +import matplotlib.transforms as mtransforms +from qtpy import QtCore, QtWidgets +from sleap.gui.utils import is_port_free, select_zmq_port +from sleap.gui.widgets.mpl import MplCanvas +from sleap.nn.config.training_job import TrainingJobConfig logger = logging.getLogger(__name__) +class LossPlot(MplCanvas): + """Matplotlib canvas for diplaying training and validation loss curves.""" + + def __init__( + self, + width: int = 5, + height: int = 4, + dpi: int = 100, + log_scale: bool = True, + ignore_outliers: bool = False, + ): + super().__init__(width=width, height=height, dpi=dpi) + + self._log_scale: bool = log_scale + + self.ignore_outliers = ignore_outliers + + # Initialize the series for the plot + self.series: dict = {} + COLOR_TRAIN = (18, 158, 220) + COLOR_VAL = (248, 167, 52) + COLOR_BEST_VAL = (151, 204, 89) + + # Initialize scatter series for batch training loss + self.series["batch"] = self._init_series( + series_type=self.axes.scatter, + name="Batch Training Loss", + color=COLOR_TRAIN + (48,), + border_color=(255, 255, 255, 25), + ) + + # Initialize line series for epoch training loss + self.series["epoch_loss"] = self._init_series( + series_type=self.axes.plot, + name="Epoch Training Loss", + color=COLOR_TRAIN + (255,), + line_width=3.0, + ) + + # Initialize line series for epoch validation loss + self.series["val_loss"] = self._init_series( + series_type=self.axes.plot, + name="Epoch Validation Loss", + color=COLOR_VAL + (255,), + line_width=3.0, + zorder=4, # Below best validation loss series + ) + + # Initialize scatter series for best epoch validation loss + self.series["val_loss_best"] = self._init_series( + series_type=self.axes.scatter, + name="Best Validation Loss", + color=COLOR_BEST_VAL + (255,), + border_color=(255, 255, 255, 25), + zorder=5, # Above epoch validation loss series + ) + + # Set the x and y positions for the xy labels (as fraction of figure size) + self.ypos_xlabel = 0.1 + self.xpos_ylabel = 0.05 + + # Padding between the axes and the xy labels + self.xpos_padding = 0.2 + self.ypos_padding = 0.1 + + # Set up the major gridlines + self._setup_major_gridlines() + + # Set up the x-axis + self._setup_x_axis() + + # Set up the y-axis + self._set_up_y_axis() + + # Set up the legend + self.legend_width, legend_height = self._setup_legend() + + # Set up the title space + self.ypos_title = None + title_height = self._set_title_space() + self.ypos_title = 1 - title_height - self.ypos_padding + + # Determine the top height of the plot + top_height = max(title_height, legend_height) + + # Adjust the figure layout + self.xpos_left_plot = self.xpos_ylabel + self.xpos_padding + self.xpos_right_plot = 0.97 + self.ypos_bottom_plot = self.ypos_xlabel + self.ypos_padding + self.ypos_top_plot = 1 - top_height - self.ypos_padding + + # Adjust the top parameters as needed + self.fig.subplots_adjust( + left=self.xpos_left_plot, + right=self.xpos_right_plot, + top=self.ypos_top_plot, + bottom=self.ypos_bottom_plot, + ) + + @property + def log_scale(self): + """Returns True if the plot has a log scale for y-axis.""" + + return self._log_scale + + @log_scale.setter + def log_scale(self, val): + """Sets the scale of the y axis to log if True else linear.""" + + if isinstance(val, bool): + self._log_scale = val + + y_scale = "log" if self._log_scale else "linear" + self.axes.set_yscale(y_scale) + self.redraw_plot() + + def set_data_on_scatter(self, xs, ys, which): + """Set data on a scatter plot. + + Not to be used with line plots. + + Args: + xs: The x-coordinates of the data points. + ys: The y-coordinates of the data points. + which: The type of data point. Possible values are: + * "batch" + * "val_loss_best" + """ + + offsets = np.column_stack((xs, ys)) + self.series[which].set_offsets(offsets) + + def add_data_to_plot(self, x, y, which): + """Add data to a line plot. + + Not to be used with scatter plots. + + Args: + x: The x-coordinate of the data point. + y: The y-coordinate of the data point. + which: The type of data point. Possible values are: + * "epoch_loss" + * "val_loss" + """ + + x_data, y_data = self.series[which].get_data() + self.series[which].set_data(np.append(x_data, x), np.append(y_data, y)) + + def resize_axes(self, x, y): + """Resize axes to fit data. + + This is only called when plotting batches. + + Args: + x: The x-coordinates of the data points. + y: The y-coordinates of the data points. + """ + + # Set X scale to show all points + x_min, x_max = self._calculate_xlim(x) + self.axes.set_xlim(x_min, x_max) + + # Set Y scale, ensuring that y_min and y_max do not lead to sngular transform + y_min, y_max = self._calculate_ylim(y) + y_min, y_max = self.axes.yaxis.get_major_locator().nonsingular(y_min, y_max) + self.axes.set_ylim(y_min, y_max) + + # Add gridlines at midpoint between major ticks (major gridlines are automatic) + self._add_midpoint_gridlines() + + # Redraw the plot + self.redraw_plot() + + def redraw_plot(self): + """Redraw the plot.""" + + self.fig.canvas.draw_idle() + + def set_title(self, title, color=None): + """Set the title of the plot. + + Args: + title: The title text to display. + """ + + if color is None: + color = "black" + + self.axes.set_title( + title, fontweight="light", fontsize="small", color=color, x=0.55, y=1.03 + ) + + def update_runtime_title( + self, + epoch: int, + dt_min: int, + dt_sec: int, + last_epoch_val_loss: float = None, + penultimate_epoch_val_loss: float = None, + mean_epoch_time_min: int = None, + mean_epoch_time_sec: int = None, + eta_ten_epochs_min: int = None, + epochs_in_plateau: int = None, + plateau_patience: int = None, + epoch_in_plateau_flag: bool = False, + best_val_x: int = None, + best_val_y: float = None, + epoch_size: int = None, + ): + + # Add training epoch and runtime info + title = self._get_training_epoch_and_runtime_text(epoch, dt_min, dt_sec) + + if last_epoch_val_loss is not None: + + if penultimate_epoch_val_loss is not None: + # Add mean epoch time and ETA for next 10 epochs + eta_text = self._get_eta_text( + mean_epoch_time_min, mean_epoch_time_sec, eta_ten_epochs_min + ) + title = self._add_with_newline(title, eta_text) + + # Add epochs in plateau if flag is set + if epoch_in_plateau_flag: + plateau_text = self._get_epochs_in_plateau_text( + epochs_in_plateau, plateau_patience + ) + title = self._add_with_newline(title, plateau_text) + + # Add last epoch validation loss + last_val_text = self._get_last_validation_loss_text(last_epoch_val_loss) + title = self._add_with_newline(title, last_val_text) + + # Add best epoch validation loss if available + if best_val_x is not None: + best_epoch = (best_val_x // epoch_size) + 1 + best_val_text = self._get_best_validation_loss_text( + best_val_y, best_epoch + ) + title = self._add_with_newline(title, best_val_text) + + self.set_title(title) + + @staticmethod + def _get_training_epoch_and_runtime_text(epoch: int, dt_min: int, dt_sec: int): + """Get the training epoch and runtime text to display in the plot. + + Args: + epoch: The current epoch. + dt_min: The number of minutes since training started. + dt_sec: The number of seconds since training started. + """ + + runtime_text = ( + r"Training Epoch $\mathbf{" + str(epoch + 1) + r"}$ / " + r"Runtime: $\mathbf{" + f"{int(dt_min):02}:{int(dt_sec):02}" + r"}$" + ) + + return runtime_text + + @staticmethod + def _get_eta_text(mean_epoch_time_min, mean_epoch_time_sec, eta_ten_epochs_min): + """Get the mean time and ETA text to display in the plot. + + Args: + mean_epoch_time_min: The mean time per epoch in minutes. + mean_epoch_time_sec: The mean time per epoch in seconds. + eta_ten_epochs_min: The estimated time for the next ten epochs in minutes. + """ + + runtime_text = ( + r"Mean Time per Epoch: $\mathbf{" + + f"{int(mean_epoch_time_min):02}:{int(mean_epoch_time_sec):02}" + + r"}$ / " + r"ETA Next 10 Epochs: $\mathbf{" + f"{int(eta_ten_epochs_min)}" + r"}$ min" + ) + + return runtime_text + + @staticmethod + def _get_epochs_in_plateau_text(epochs_in_plateau, plateau_patience): + """Get the epochs in plateau text to display in the plot. + + Args: + epochs_in_plateau: The number of epochs in plateau. + plateau_patience: The number of epochs to wait before stopping training. + """ + + plateau_text = ( + r"Epochs in Plateau: $\mathbf{" + f"{epochs_in_plateau}" + r"}$ / " + r"$\mathbf{" + f"{plateau_patience}" + r"}$" + ) + + return plateau_text + + @staticmethod + def _get_last_validation_loss_text(last_epoch_val_loss): + """Get the last epoch validation loss text to display in the plot. + + Args: + last_epoch_val_loss: The validation loss from the last epoch. + """ + + last_val_loss_text = ( + "Last Epoch Validation Loss: " + r"$\mathbf{" + f"{last_epoch_val_loss:.3e}" + r"}$" + ) + + return last_val_loss_text + + @staticmethod + def _get_best_validation_loss_text(best_val_y, best_epoch): + """Get the best epoch validation loss text to display in the plot. + + Args: + best_val_x: The epoch number of the best validation loss. + best_val_y: The best validation loss. + """ + + best_val_loss_text = ( + r"Best Epoch Validation Loss: $\mathbf{" + + f"{best_val_y:.3e}" + + r"}$ (epoch $\mathbf{" + + str(best_epoch) + + r"}$)" + ) + + return best_val_loss_text + + @staticmethod + def _add_with_newline(old_text: str, new_text: str): + """Add a new line to the text. + + Args: + old_text: The existing text. + new_text: The text to add on a new line. + """ + + return old_text + "\n" + new_text + + @staticmethod + def _calculate_xlim(x: np.ndarray, dx: float = 0.5): + """Calculates x-axis limits. + + Args: + x: Array of x data to fit the limits to. + dx: The padding to add to the limits. + + Returns: + Tuple of the minimum and maximum x-axis limits. + """ + + x_min = min(x) - dx + x_min = x_min if x_min > 0 else 0 + x_max = max(x) + dx + + return x_min, x_max + + def _calculate_ylim(self, y: np.ndarray, dy: float = 0.02): + """Calculates y-axis limits. + + Args: + y: Array of y data to fit the limits to. + dy: The padding to add to the limits. + + Returns: + Tuple of the minimum and maximum y-axis limits. + """ + + if self.ignore_outliers: + dy = np.ptp(y) * 0.02 + # Set Y scale to exclude outliers + q1, q3 = np.quantile(y, (0.25, 0.75)) + iqr = q3 - q1 # Interquartile range + y_min = q1 - iqr * 1.5 + y_max = q3 + iqr * 1.5 + + # Keep within range of data + y_min = max(y_min, min(y) - dy) + y_max = min(y_max, max(y) + dy) + else: + # Set Y scale to show all points + dy = np.ptp(y) * 0.02 + y_min = min(y) - dy + y_max = max(y) + dy + + # For log scale, low cannot be 0 + if self.log_scale: + y_min = max(y_min, 1e-8) + + return y_min, y_max + + def _set_title_space(self): + """Set up the title space. + + Returns: + The height of the title space as a decimal fraction of the total figure height. + """ + + # Set a dummy title of the plot + n_lines = 5 # Number of lines in the title + title_str = "\n".join( + [r"Number: $\mathbf{" + str(n) + r"}$" for n in range(n_lines + 1)] + ) + self.set_title( + title_str, color="white" + ) # Set the title color to white so it's not visible + + # Draw the canvas to ensure the title is created + self.fig.canvas.draw() + + # Get the title Text object + title = self.axes.title + + # Get the bounding box of the title in display coordinates + bbox = title.get_window_extent() + + # Transform the bounding box to figure coordinates + bbox = bbox.transformed(self.fig.transFigure.inverted()) + + # Calculate the height of the title as a percentage of the total figure height + title_height = bbox.height + + return title_height + + def _setup_x_axis(self): + """Set up the x axis. + + This includes setting the label, limits, and bottom/right adjustment. + """ + + self.axes.set_xlim(0, 1) + self.axes.set_xlabel("Batches", fontweight="bold", fontsize="small") + + # Set the x-label in the center of the axes and some amount above the bottom of the figure + blended_transform = mtransforms.blended_transform_factory( + self.axes.transAxes, self.fig.transFigure + ) + self.axes.xaxis.set_label_coords( + 0.5, self.ypos_xlabel, transform=blended_transform + ) + + def _set_up_y_axis(self): + """Set up the y axis. + + This includes setting the label, limits, scaling, and left adjustment. + """ + + # Set the minimum value of the y-axis depending on scaling + if self.log_scale: + yscale = "log" + y_min = 0.001 + else: + yscale = "linear" + y_min = 0 + self.axes.set_ylim(bottom=y_min) + self.axes.set_yscale(yscale) + + # Set the y-label name, size, wight, and position + self.axes.set_ylabel("Loss", fontweight="bold", fontsize="small") + self.axes.yaxis.set_label_coords( + self.xpos_ylabel, 0.5, transform=self.fig.transFigure + ) + + def _setup_legend(self): + """Set up the legend. + + Returns: + Tuple of the width and height of the legend as a decimal fraction of the total figure width and height. + """ + + # Move the legend outside the plot on the upper left + legend = self.axes.legend( + loc="upper left", + fontsize="small", + bbox_to_anchor=(0, 1), + bbox_transform=self.fig.transFigure, + ) + + # Draw the canvas to ensure the legend is created + self.fig.canvas.draw() + + # Get the bounding box of the legend in display coordinates + bbox = legend.get_window_extent() + + # Transform the bounding box to figure coordinates + bbox = bbox.transformed(self.fig.transFigure.inverted()) + + # Calculate the width and height of the legend as a percentage of the total figure width and height + return bbox.width, bbox.height + + def _setup_major_gridlines(self): + + # Set the outline color of the plot to gray + for spine in self.axes.spines.values(): + spine.set_edgecolor("#d3d3d3") # Light gray color + + # Remove the top and right axis spines + self.axes.spines["top"].set_visible(False) + self.axes.spines["right"].set_visible(False) + + # Set the tick markers color to light gray, but not the tick labels + self.axes.tick_params( + axis="both", which="both", color="#d3d3d3", labelsize="small" + ) + + # Add gridlines at the tick labels + self.axes.grid(True, which="major", linewidth=0.5, color="#d3d3d3") + + def _add_midpoint_gridlines(self): + # Clear existing minor vertical lines + for line in self.axes.get_lines(): + if line.get_linestyle() == ":": + line.remove() + + # Add gridlines at midpoint between major ticks + major_ticks = self.axes.yaxis.get_majorticklocs() + if len(major_ticks) > 1: + prev_major_tick = major_ticks[0] + for major_tick in major_ticks[:-1]: + midpoint = (major_tick + prev_major_tick) / 2 + self.axes.axhline( + midpoint, linestyle=":", linewidth=0.5, color="#d3d3d3" + ) + prev_major_tick = major_tick + + def _init_series( + self, + series_type, + color, + name: Optional[str] = None, + line_width: Optional[float] = None, + border_color: Optional[Tuple[int, int, int]] = None, + zorder: Optional[int] = None, + ): + + # Set the color + color = [c / 255.0 for c in color] # Normalize color values to [0, 1] + + # Create the series + series = series_type( + [], + [], + color=color, + label=name, + marker="o", + zorder=zorder, + ) + + # ax.plot returns a list of PathCollections, so we need to get the first one + if not isinstance(series, PathCollection): + series = series[0] + + if line_width is not None: + series.set_linewidth(line_width) + + # Set the border color (edge color) + if border_color is not None: + border_color = [ + c / 255.0 for c in border_color + ] # Normalize color values to [0, 1] + series.set_edgecolor(border_color) + + return series + + class LossViewer(QtWidgets.QMainWindow): """Qt window for showing in-progress training metrics sent over ZMQ.""" @@ -22,6 +592,7 @@ class LossViewer(QtWidgets.QMainWindow): def __init__( self, + zmq_ports: Dict = None, zmq_context: Optional[zmq.Context] = None, show_controller=True, parent=None, @@ -33,41 +604,62 @@ def __init__( self.cancel_button = None self.canceled = False + # Set up ZMQ ports for communication. + zmq_ports = zmq_ports or dict() + zmq_ports["publish_port"] = zmq_ports.get("publish_port", 9001) + zmq_ports["controller_port"] = zmq_ports.get("controller_port", 9000) + self.zmq_ports = zmq_ports + self.batches_to_show = -1 # -1 to show all - self.ignore_outliers = False - self.log_scale = True + self._ignore_outliers = False + self._log_scale = True self.message_poll_time_ms = 20 # ms self.redraw_batch_time_ms = 500 # ms self.last_redraw_batch = None + self.canvas = None self.reset() - self.setup_zmq(zmq_context) + self._setup_zmq(zmq_context) def __del__(self): - self.unbind() + self._unbind() - def close(self): - """Disconnect from ZMQ ports and close the window.""" - self.unbind() - super().close() + @property + def is_timer_running(self) -> bool: + """Return True if the timer has started.""" + return self.t0 is not None and self.is_running - def unbind(self): - """Disconnect from all ZMQ sockets.""" - if self.sub is not None: - self.sub.unbind(self.sub.LAST_ENDPOINT) - self.sub.close() - self.sub = None + @property + def log_scale(self): + """Returns True if the plot has a log scale for y-axis.""" - if self.zmq_ctrl is not None: - url = self.zmq_ctrl.LAST_ENDPOINT - self.zmq_ctrl.unbind(url) - self.zmq_ctrl.close() - self.zmq_ctrl = None + return self._log_scale - # If we started out own zmq context, terminate it. - if not self.ctx_given and self.ctx is not None: - self.ctx.term() - self.ctx = None + @log_scale.setter + def log_scale(self, val): + """Sets the scale of the y axis to log if True else linear.""" + + if isinstance(val, bool): + self._log_scale = val + + # Set the log scale on the canvas + self.canvas.log_scale = self._log_scale + + @property + def ignore_outliers(self): + """Returns True if the plot ignores outliers.""" + + return self._ignore_outliers + + @ignore_outliers.setter + def ignore_outliers(self, val): + """Sets whether to ignore outliers in the plot.""" + + if isinstance(val, bool): + self._ignore_outliers = val + + # Set the ignore_outliers on the canvas + self.canvas.ignore_outliers = self._ignore_outliers def reset( self, @@ -80,112 +672,34 @@ def reset( what: String identifier indicating which job type the current run corresponds to. """ - self.chart = QtCharts.QChart() - - self.series = dict() + self.canvas = LossPlot( + width=5, + height=4, + dpi=100, + log_scale=self.log_scale, + ignore_outliers=self.ignore_outliers, + ) - COLOR_TRAIN = (18, 158, 220) - COLOR_VAL = (248, 167, 52) - COLOR_BEST_VAL = (151, 204, 89) + self.mp_series = dict() + self.mp_series["batch"] = self.canvas.series["batch"] + self.mp_series["epoch_loss"] = self.canvas.series["epoch_loss"] + self.mp_series["val_loss"] = self.canvas.series["val_loss"] + self.mp_series["val_loss_best"] = self.canvas.series["val_loss_best"] - self.series["batch"] = QtCharts.QScatterSeries() - self.series["batch"].setName("Batch Training Loss") - self.series["batch"].setColor(QtGui.QColor(*COLOR_TRAIN, 48)) - self.series["batch"].setMarkerSize(8.0) - self.series["batch"].setBorderColor(QtGui.QColor(255, 255, 255, 25)) - self.chart.addSeries(self.series["batch"]) - - self.series["epoch_loss"] = QtCharts.QLineSeries() - self.series["epoch_loss"].setName("Epoch Training Loss") - self.series["epoch_loss"].setColor(QtGui.QColor(*COLOR_TRAIN, 255)) - pen = self.series["epoch_loss"].pen() - pen.setWidth(4) - self.series["epoch_loss"].setPen(pen) - self.chart.addSeries(self.series["epoch_loss"]) - - self.series["epoch_loss_scatter"] = QtCharts.QScatterSeries() - self.series["epoch_loss_scatter"].setColor(QtGui.QColor(*COLOR_TRAIN, 255)) - self.series["epoch_loss_scatter"].setMarkerSize(12.0) - self.series["epoch_loss_scatter"].setBorderColor( - QtGui.QColor(255, 255, 255, 25) - ) - self.chart.addSeries(self.series["epoch_loss_scatter"]) - - self.series["val_loss"] = QtCharts.QLineSeries() - self.series["val_loss"].setName("Epoch Validation Loss") - self.series["val_loss"].setColor(QtGui.QColor(*COLOR_VAL, 255)) - pen = self.series["val_loss"].pen() - pen.setWidth(4) - self.series["val_loss"].setPen(pen) - self.chart.addSeries(self.series["val_loss"]) - - self.series["val_loss_scatter"] = QtCharts.QScatterSeries() - self.series["val_loss_scatter"].setColor(QtGui.QColor(*COLOR_VAL, 255)) - self.series["val_loss_scatter"].setMarkerSize(12.0) - self.series["val_loss_scatter"].setBorderColor(QtGui.QColor(255, 255, 255, 25)) - self.chart.addSeries(self.series["val_loss_scatter"]) - - self.series["val_loss_best"] = QtCharts.QScatterSeries() - self.series["val_loss_best"].setName("Best Validation Loss") - self.series["val_loss_best"].setColor(QtGui.QColor(*COLOR_BEST_VAL, 255)) - self.series["val_loss_best"].setMarkerSize(12.0) - self.series["val_loss_best"].setBorderColor(QtGui.QColor(32, 32, 32, 25)) - self.chart.addSeries(self.series["val_loss_best"]) - - axisX = QtCharts.QValueAxis() - axisX.setLabelFormat("%d") - axisX.setTitleText("Batches") - self.chart.addAxis(axisX, QtCore.Qt.AlignBottom) - - # Create the different Y axes that can be used. - self.axisY = dict() - - self.axisY["log"] = QtCharts.QLogValueAxis() - self.axisY["log"].setBase(10) - - self.axisY["linear"] = QtCharts.QValueAxis() - - # Apply settings that apply to all Y axes. - for axisY in self.axisY.values(): - axisY.setLabelFormat("%f") - axisY.setLabelsVisible(True) - axisY.setMinorTickCount(1) - axisY.setTitleText("Loss") - - # Use the default Y axis. - axisY = self.axisY["log"] if self.log_scale else self.axisY["linear"] - - # Add axes to chart and series. - self.chart.addAxis(axisY, QtCore.Qt.AlignLeft) - for series in self.chart.series(): - series.attachAxis(axisX) - series.attachAxis(axisY) - - # Setup legend. - self.chart.legend().setVisible(True) - self.chart.legend().setAlignment(QtCore.Qt.AlignTop) - self.chart.legend().setMarkerShape(QtCharts.QLegend.MarkerShapeCircle) - - # Hide scatters for epoch and val loss from legend. - for s in ("epoch_loss_scatter", "val_loss_scatter"): - self.chart.legend().markers(self.series[s])[0].setVisible(False) - - self.chartView = QtCharts.QChartView(self.chart) - self.chartView.setRenderHint(QtGui.QPainter.Antialiasing) layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.chartView) + layout.addWidget(self.canvas) if self.show_controller: control_layout = QtWidgets.QHBoxLayout() field = QtWidgets.QCheckBox("Log Scale") field.setChecked(self.log_scale) - field.stateChanged.connect(self.toggle_log_scale) + field.stateChanged.connect(self._toggle_log_scale) control_layout.addWidget(field) field = QtWidgets.QCheckBox("Ignore Outliers") field.setChecked(self.ignore_outliers) - field.stateChanged.connect(self.toggle_ignore_outliers) + field.stateChanged.connect(self._toggle_ignore_outliers) control_layout.addWidget(field) control_layout.addWidget(QtWidgets.QLabel("Batches to Show:")) @@ -203,7 +717,7 @@ def reset( # Set connection action for when user selects another option. field.currentIndexChanged.connect( - lambda x: self.set_batches_to_show(self.batch_options[x]) + lambda x: self._set_batches_to_show(self.batch_options[x]) ) # Store field as property and add to layout. @@ -213,10 +727,10 @@ def reset( control_layout.addStretch(1) self.stop_button = QtWidgets.QPushButton("Stop Early") - self.stop_button.clicked.connect(self.stop) + self.stop_button.clicked.connect(self._stop) control_layout.addWidget(self.stop_button) self.cancel_button = QtWidgets.QPushButton("Cancel Training") - self.cancel_button.clicked.connect(self.cancel) + self.cancel_button.clicked.connect(self._cancel) control_layout.addWidget(self.cancel_button) widget = QtWidgets.QWidget() @@ -248,48 +762,16 @@ def reset( self.last_batch_number = 0 self.is_running = False - def toggle_ignore_outliers(self): - """Toggles whether to ignore outliers in chart scaling.""" - self.ignore_outliers = not self.ignore_outliers - - def toggle_log_scale(self): - """Toggle whether to use log-scaled y-axis.""" - self.log_scale = not self.log_scale - self.update_y_axis() - - def set_batches_to_show(self, batches: str): - """Set the number of batches to show on the x-axis. + def set_message(self, text: str): + """Set the chart title text.""" + self.canvas.set_title(text) - Args: - batches: Number of batches as a string. If numeric, this will be converted - to an integer. If non-numeric string (e.g., "All"), then all batches - will be shown. - """ - if batches.isdigit(): - self.batches_to_show = int(batches) - else: - self.batches_to_show = -1 + def close(self): + """Disconnect from ZMQ ports and close the window.""" + self._unbind() + super().close() - def update_y_axis(self): - """Update the y-axis when scale changes.""" - to = "log" if self.log_scale else "linear" - - # Remove other axes. - for name, axisY in self.axisY.items(): - if name != to: - if axisY in self.chart.axes(): - self.chart.removeAxis(axisY) - for series in self.chart.series(): - if axisY in series.attachedAxes(): - series.detachAxis(axisY) - - # Add axis. - axisY = self.axisY[to] - self.chart.addAxis(axisY, QtCore.Qt.AlignLeft) - for series in self.chart.series(): - series.attachAxis(axisY) - - def setup_zmq(self, zmq_context: Optional[zmq.Context] = None): + def _setup_zmq(self, zmq_context: Optional[zmq.Context] = None): """Connect to ZMQ ports that listen to commands and updates. Args: @@ -305,112 +787,69 @@ def setup_zmq(self, zmq_context: Optional[zmq.Context] = None): # Progress monitoring, SUBSCRIBER self.sub = self.ctx.socket(zmq.SUB) self.sub.subscribe("") - self.sub.bind("tcp://127.0.0.1:9001") + + def find_free_port(port: int, zmq_context: zmq.Context): + """Find free port to bind to. + + Args: + port: The port to start searching from. + zmq_context: The ZMQ context to use. + + Returns: + The free port. + """ + attempts = 0 + max_attempts = 10 + while not is_port_free(port=port, zmq_context=zmq_context): + if attempts >= max_attempts: + raise RuntimeError( + f"Could not find free port to display training progress after " + f"{max_attempts} attempts. Please check your network settings " + "or use the CLI `sleap-train` command." + ) + port = select_zmq_port(zmq_context=self.ctx) + attempts += 1 + + return port + + # Find a free port and bind to it. + self.zmq_ports["publish_port"] = find_free_port( + port=self.zmq_ports["publish_port"], zmq_context=self.ctx + ) + publish_address = f"tcp://127.0.0.1:{self.zmq_ports['publish_port']}" + self.sub.bind(publish_address) # Controller, PUBLISHER self.zmq_ctrl = None if self.show_controller: self.zmq_ctrl = self.ctx.socket(zmq.PUB) - self.zmq_ctrl.bind("tcp://127.0.0.1:9000") + + # Find a free port and bind to it. + self.zmq_ports["controller_port"] = find_free_port( + port=self.zmq_ports["controller_port"], zmq_context=self.ctx + ) + controller_address = f"tcp://127.0.0.1:{self.zmq_ports['controller_port']}" + self.zmq_ctrl.bind(controller_address) # Set timer to poll for messages. self.timer = QtCore.QTimer() - self.timer.timeout.connect(self.check_messages) + self.timer.timeout.connect(self._check_messages) self.timer.start(self.message_poll_time_ms) - def cancel(self): - """Set the cancel flag.""" - self.canceled = True - if self.cancel_button is not None: - self.cancel_button.setText("Canceling...") - self.cancel_button.setEnabled(False) - - def stop(self): - """Send command to stop training.""" - if self.zmq_ctrl is not None: - # Send command to stop training. - logger.info("Sending command to stop training.") - self.zmq_ctrl.send_string(jsonpickle.encode(dict(command="stop"))) - - # Disable the button to prevent double messages. - if self.stop_button is not None: - self.stop_button.setText("Stopping...") - self.stop_button.setEnabled(False) - - def add_datapoint(self, x: int, y: float, which: str): - """Add a data point to graph. + def _set_batches_to_show(self, batches: str): + """Set the number of batches to show on the x-axis. Args: - x: The batch number (out of all epochs, not just current), or epoch. - y: The loss value. - which: Type of data point we're adding. Possible values are: - * "batch" (loss for the batch) - * "epoch_loss" (loss for the entire epoch) - * "val_loss" (validation loss for the epoch) + batches: Number of batches as a string. If numeric, this will be converted + to an integer. If non-numeric string (e.g., "All"), then all batches + will be shown. """ - if which == "batch": - self.X.append(x) - self.Y.append(y) - - # Redraw batch at intervals (faster than plotting every batch). - draw_batch = False - if self.last_redraw_batch is None: - draw_batch = True - else: - dt = perf_counter() - self.last_redraw_batch - draw_batch = (dt * 1000) >= self.redraw_batch_time_ms - - if draw_batch: - self.last_redraw_batch = perf_counter() - if self.batches_to_show < 0 or len(self.X) < self.batches_to_show: - xs, ys = self.X, self.Y - else: - xs, ys = ( - self.X[-self.batches_to_show :], - self.Y[-self.batches_to_show :], - ) - - points = [QtCore.QPointF(x, y) for x, y in zip(xs, ys) if y > 0] - self.series["batch"].replace(points) - - # Set X scale to show all points - dx = 0.5 - self.chart.axisX().setRange(min(xs) - dx, max(xs) + dx) - - if self.ignore_outliers: - dy = np.ptp(ys) * 0.02 - # Set Y scale to exclude outliers - q1, q3 = np.quantile(ys, (0.25, 0.75)) - iqr = q3 - q1 # interquartile range - low = q1 - iqr * 1.5 - high = q3 + iqr * 1.5 - - low = max(low, min(ys) - dy) # keep within range of data - high = min(high, max(ys) + dy) - else: - # Set Y scale to show all points - dy = np.ptp(ys) * 0.02 - low = min(ys) - dy - high = max(ys) + dy - - if self.log_scale: - low = max(low, 1e-8) # for log scale, low cannot be 0 - - self.chart.axisY().setRange(low, high) - + if batches.isdigit(): + self.batches_to_show = int(batches) else: - if which == "epoch_loss": - self.series["epoch_loss"].append(x, y) - self.series["epoch_loss_scatter"].append(x, y) - elif which == "val_loss": - self.series["val_loss"].append(x, y) - self.series["val_loss_scatter"].append(x, y) - if self.best_val_y is None or y < self.best_val_y: - self.best_val_x = x - self.best_val_y = y - self.series["val_loss_best"].replace([QtCore.QPointF(x, y)]) + self.batches_to_show = -1 - def set_start_time(self, t0: float): + def _set_start_time(self, t0: float): """Mark the start flag and time of the run. Args: @@ -419,52 +858,31 @@ def set_start_time(self, t0: float): self.t0 = t0 self.is_running = True - def set_end(self): - """Mark the end of the run.""" - self.is_running = False - - def update_runtime(self): + def _update_runtime(self): """Update the title text with the current running time.""" + if self.is_timer_running: dt = perf_counter() - self.t0 dt_min, dt_sec = divmod(dt, 60) - title = f"Training Epoch {self.epoch + 1} / " - title += f"Runtime: {int(dt_min):02}:{int(dt_sec):02}" - if self.last_epoch_val_loss is not None: - if self.penultimate_epoch_val_loss is not None: - title += ( - f"
Mean Time per Epoch: " - f"{int(self.mean_epoch_time_min):02}:{int(self.mean_epoch_time_sec):02} / " - f"ETA Next 10 Epochs: {int(self.eta_ten_epochs_min)} min" - ) - if self.epoch_in_plateau_flag: - title += ( - f"
Epochs in Plateau: " - f"{self.epochs_in_plateau} / " - f"{self.config.optimization.early_stopping.plateau_patience}" - ) - title += ( - f"
Last Epoch Validation Loss: " - f"{self.last_epoch_val_loss:.3e}" - ) - if self.best_val_x is not None: - best_epoch = (self.best_val_x // self.epoch_size) + 1 - title += ( - f"
Best Epoch Validation Loss: " - f"{self.best_val_y:.3e} (epoch {best_epoch})" - ) - self.set_message(title) - - @property - def is_timer_running(self) -> bool: - """Return True if the timer has started.""" - return self.t0 is not None and self.is_running - def set_message(self, text: str): - """Set the chart title text.""" - self.chart.setTitle(text) + self.canvas.update_runtime_title( + epoch=self.epoch, + dt_min=dt_min, + dt_sec=dt_sec, + last_epoch_val_loss=self.last_epoch_val_loss, + penultimate_epoch_val_loss=self.penultimate_epoch_val_loss, + mean_epoch_time_min=self.mean_epoch_time_min, + mean_epoch_time_sec=self.mean_epoch_time_sec, + eta_ten_epochs_min=self.eta_ten_epochs_min, + epochs_in_plateau=self.epochs_in_plateau, + plateau_patience=self.config.optimization.early_stopping.plateau_patience, + epoch_in_plateau_flag=self.epoch_in_plateau_flag, + best_val_x=self.best_val_x, + best_val_y=self.best_val_y, + epoch_size=self.epoch_size, + ) - def check_messages( + def _check_messages( self, timeout: int = 10, times_to_check: int = 10, do_update: bool = True ): """Poll for ZMQ messages and adds any received data to graph. @@ -496,7 +914,7 @@ def check_messages( msg = jsonpickle.decode(self.sub.recv_string()) if msg["event"] == "train_begin": - self.set_start_time(perf_counter()) + self._set_start_time(perf_counter()) self.current_job_output_type = msg["what"] # Make sure message matches current training job. @@ -504,15 +922,15 @@ def check_messages( if not self.is_timer_running: # We must have missed the train_begin message, so start timer now. - self.set_start_time(perf_counter()) + self._set_start_time(perf_counter()) if msg["event"] == "train_end": - self.set_end() + self._set_end() elif msg["event"] == "epoch_begin": self.epoch = msg["epoch"] elif msg["event"] == "epoch_end": self.epoch_size = max(self.epoch_size, self.last_batch_number + 1) - self.add_datapoint( + self._add_datapoint( (self.epoch + 1) * self.epoch_size, msg["logs"]["loss"], "epoch_loss", @@ -521,7 +939,7 @@ def check_messages( # update variables and add points to plot self.penultimate_epoch_val_loss = self.last_epoch_val_loss self.last_epoch_val_loss = msg["logs"]["val_loss"] - self.add_datapoint( + self._add_datapoint( (self.epoch + 1) * self.epoch_size, msg["logs"]["val_loss"], "val_loss", @@ -552,7 +970,7 @@ def check_messages( self.on_epoch.emit() elif msg["event"] == "batch_end": self.last_batch_number = msg["batch"] - self.add_datapoint( + self._add_datapoint( (self.epoch * self.epoch_size) + msg["batch"], msg["logs"]["loss"], "batch", @@ -560,9 +978,155 @@ def check_messages( # Check for messages again (up to times_to_check times). if times_to_check > 0: - self.check_messages( + self._check_messages( timeout=timeout, times_to_check=times_to_check - 1, do_update=False ) if do_update: - self.update_runtime() + self._update_runtime() + + def _add_datapoint(self, x: int, y: float, which: str): + """Add a data point to graph. + + Args: + x: The batch number (out of all epochs, not just current), or epoch. + y: The loss value. + which: Type of data point we're adding. Possible values are: + * "batch" (loss for the batch) + * "epoch_loss" (loss for the entire epoch) + * "val_loss" (validation loss for the epoch) + """ + if which == "batch": + self.X.append(x) + self.Y.append(y) + + # Redraw batch at intervals (faster than plotting every batch). + draw_batch = False + if self.last_redraw_batch is None: + draw_batch = True + else: + dt = perf_counter() - self.last_redraw_batch + draw_batch = (dt * 1000) >= self.redraw_batch_time_ms + + if draw_batch: + self.last_redraw_batch = perf_counter() + if self.batches_to_show < 0 or len(self.X) < self.batches_to_show: + xs, ys = self.X, self.Y + else: + xs, ys = ( + self.X[-self.batches_to_show :], + self.Y[-self.batches_to_show :], + ) + + # Set data, resize and redraw the plot + self._set_data_on_scatter(xs, ys, which) + self._resize_axes(xs, ys) + + else: + + if which == "val_loss": + if self.best_val_y is None or y < self.best_val_y: + self.best_val_x = x + self.best_val_y = y + self._set_data_on_scatter([x], [y], "val_loss_best") + + # Add data and redraw the plot + self._add_data_to_plot(x, y, which) + self._redraw_plot() + + def _set_data_on_scatter(self, xs, ys, which): + """Add data to a scatter plot. + + Not to be used with line plots. + + Args: + xs: The x-coordinates of the data points. + ys: The y-coordinates of the data points. + which: The type of data point. Possible values are: + * "batch" + * "val_loss_best" + """ + + self.canvas.set_data_on_scatter(xs, ys, which) + + def _add_data_to_plot(self, x, y, which): + """Add data to a line plot. + + Not to be used with scatter plots. + + Args: + x: The x-coordinate of the data point. + y: The y-coordinate of the data point. + which: The type of data point. Possible values are: + * "epoch_loss" + * "val_loss" + """ + + self.canvas.add_data_to_plot(x, y, which) + + def _redraw_plot(self): + """Redraw the plot.""" + + self.canvas.redraw_plot() + + def _resize_axes(self, x, y): + """Resize axes to fit data. + + This is only called when plotting batches. + + Args: + x: The x-coordinates of the data points. + y: The y-coordinates of the data points. + """ + self.canvas.resize_axes(x, y) + + def _toggle_ignore_outliers(self): + """Toggles whether to ignore outliers in chart scaling.""" + + self.ignore_outliers = not self.ignore_outliers + + def _toggle_log_scale(self): + """Toggle whether to use log-scaled y-axis.""" + + self.log_scale = not self.log_scale + + def _stop(self): + """Send command to stop training.""" + if self.zmq_ctrl is not None: + # Send command to stop training. + logger.info("Sending command to stop training.") + self.zmq_ctrl.send_string(jsonpickle.encode(dict(command="stop"))) + + # Disable the button to prevent double messages. + if self.stop_button is not None: + self.stop_button.setText("Stopping...") + self.stop_button.setEnabled(False) + + def _cancel(self): + """Set the cancel flag.""" + self.canceled = True + if self.cancel_button is not None: + self.cancel_button.setText("Canceling...") + self.cancel_button.setEnabled(False) + + def _unbind(self): + """Disconnect from all ZMQ sockets.""" + if self.sub is not None: + self.sub.unbind(self.sub.LAST_ENDPOINT) + self.sub.close() + self.sub = None + + if self.zmq_ctrl is not None: + url = self.zmq_ctrl.LAST_ENDPOINT + self.zmq_ctrl.unbind(url) + self.zmq_ctrl.close() + self.zmq_ctrl = None + + # If we started out own zmq context, terminate it. + if not self.ctx_given and self.ctx is not None: + self.ctx.term() + self.ctx = None + + def _set_end(self): + """Mark the end of the run.""" + self.is_running = False diff --git a/sleap/gui/widgets/mpl.py b/sleap/gui/widgets/mpl.py index a9b7fc838..890c1a67a 100644 --- a/sleap/gui/widgets/mpl.py +++ b/sleap/gui/widgets/mpl.py @@ -6,11 +6,10 @@ from qtpy import QtWidgets from matplotlib.figure import Figure -from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as Canvas +from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as Canvas import matplotlib -# Ensure using PyQt5 backend -matplotlib.use("QT5Agg") +matplotlib.use("QtAgg") class MplCanvas(Canvas): diff --git a/sleap/gui/widgets/slider.py b/sleap/gui/widgets/slider.py index bfe6bc9dd..084aeb7b0 100644 --- a/sleap/gui/widgets/slider.py +++ b/sleap/gui/widgets/slider.py @@ -248,8 +248,10 @@ def value(self) -> float: """Returns value of slider.""" return self._val_main - def setValue(self, val: float) -> float: + def setValue(self, val: Optional[float]): """Sets value of slider.""" + if val is None: + return self._val_main = val x = self._toPos(val) self.handle.setPos(x, 0) diff --git a/sleap/gui/widgets/training_monitor.py b/sleap/gui/widgets/training_monitor.py deleted file mode 100644 index ed405a747..000000000 --- a/sleap/gui/widgets/training_monitor.py +++ /dev/null @@ -1,566 +0,0 @@ -"""GUI for monitoring training progress interactively.""" - -import numpy as np -from time import perf_counter -from sleap.nn.config.training_job import TrainingJobConfig -import zmq -import jsonpickle -import logging -from typing import Optional -from qtpy import QtCore, QtWidgets, QtGui, QtCharts -import attr - -logger = logging.getLogger(__name__) - - -class LossViewer(QtWidgets.QMainWindow): - """Qt window for showing in-progress training metrics sent over ZMQ.""" - - on_epoch = QtCore.Signal() - - def __init__( - self, - zmq_context: Optional[zmq.Context] = None, - show_controller=True, - parent=None, - ): - super().__init__(parent) - - self.show_controller = show_controller - self.stop_button = None - self.cancel_button = None - self.canceled = False - - self.batches_to_show = -1 # -1 to show all - self.ignore_outliers = False - self.log_scale = True - self.message_poll_time_ms = 20 # ms - self.redraw_batch_time_ms = 500 # ms - self.last_redraw_batch = None - - self.reset() - self.setup_zmq(zmq_context) - - def __del__(self): - self.unbind() - - def close(self): - """Disconnect from ZMQ ports and close the window.""" - self.unbind() - super().close() - - def unbind(self): - """Disconnect from all ZMQ sockets.""" - if self.sub is not None: - self.sub.unbind(self.sub.LAST_ENDPOINT) - self.sub.close() - self.sub = None - - if self.zmq_ctrl is not None: - url = self.zmq_ctrl.LAST_ENDPOINT - self.zmq_ctrl.unbind(url) - self.zmq_ctrl.close() - self.zmq_ctrl = None - - # If we started out own zmq context, terminate it. - if not self.ctx_given and self.ctx is not None: - self.ctx.term() - self.ctx = None - - def reset( - self, - what: str = "", - config: TrainingJobConfig = attr.ib(factory=TrainingJobConfig), - ): - """Reset all chart series. - - Args: - what: String identifier indicating which job type the current run - corresponds to. - """ - self.chart = QtCharts.QChart() - - self.series = dict() - - COLOR_TRAIN = (18, 158, 220) - COLOR_VAL = (248, 167, 52) - COLOR_BEST_VAL = (151, 204, 89) - - self.series["batch"] = QtCharts.QScatterSeries() - self.series["batch"].setName("Batch Training Loss") - self.series["batch"].setColor(QtGui.QColor(*COLOR_TRAIN, 48)) - self.series["batch"].setMarkerSize(8.0) - self.series["batch"].setBorderColor(QtGui.QColor(255, 255, 255, 25)) - self.chart.addSeries(self.series["batch"]) - - self.series["epoch_loss"] = QtCharts.QLineSeries() - self.series["epoch_loss"].setName("Epoch Training Loss") - self.series["epoch_loss"].setColor(QtGui.QColor(*COLOR_TRAIN, 255)) - pen = self.series["epoch_loss"].pen() - pen.setWidth(4) - self.series["epoch_loss"].setPen(pen) - self.chart.addSeries(self.series["epoch_loss"]) - - self.series["epoch_loss_scatter"] = QtCharts.QScatterSeries() - self.series["epoch_loss_scatter"].setColor(QtGui.QColor(*COLOR_TRAIN, 255)) - self.series["epoch_loss_scatter"].setMarkerSize(12.0) - self.series["epoch_loss_scatter"].setBorderColor( - QtGui.QColor(255, 255, 255, 25) - ) - self.chart.addSeries(self.series["epoch_loss_scatter"]) - - self.series["val_loss"] = QtCharts.QLineSeries() - self.series["val_loss"].setName("Epoch Validation Loss") - self.series["val_loss"].setColor(QtGui.QColor(*COLOR_VAL, 255)) - pen = self.series["val_loss"].pen() - pen.setWidth(4) - self.series["val_loss"].setPen(pen) - self.chart.addSeries(self.series["val_loss"]) - - self.series["val_loss_scatter"] = QtCharts.QScatterSeries() - self.series["val_loss_scatter"].setColor(QtGui.QColor(*COLOR_VAL, 255)) - self.series["val_loss_scatter"].setMarkerSize(12.0) - self.series["val_loss_scatter"].setBorderColor(QtGui.QColor(255, 255, 255, 25)) - self.chart.addSeries(self.series["val_loss_scatter"]) - - self.series["val_loss_best"] = QtCharts.QScatterSeries() - self.series["val_loss_best"].setName("Best Validation Loss") - self.series["val_loss_best"].setColor(QtGui.QColor(*COLOR_BEST_VAL, 255)) - self.series["val_loss_best"].setMarkerSize(12.0) - self.series["val_loss_best"].setBorderColor(QtGui.QColor(32, 32, 32, 25)) - self.chart.addSeries(self.series["val_loss_best"]) - - axisX = QtCharts.QValueAxis() - axisX.setLabelFormat("%d") - axisX.setTitleText("Batches") - self.chart.addAxis(axisX, QtCore.Qt.AlignBottom) - - # Create the different Y axes that can be used. - self.axisY = dict() - - self.axisY["log"] = QtCharts.QLogValueAxis() - self.axisY["log"].setBase(10) - - self.axisY["linear"] = QtCharts.QValueAxis() - - # Apply settings that apply to all Y axes. - for axisY in self.axisY.values(): - axisY.setLabelFormat("%f") - axisY.setLabelsVisible(True) - axisY.setMinorTickCount(1) - axisY.setTitleText("Loss") - - # Use the default Y axis. - axisY = self.axisY["log"] if self.log_scale else self.axisY["linear"] - - # Add axes to chart and series. - self.chart.addAxis(axisY, QtCore.Qt.AlignLeft) - for series in self.chart.series(): - series.attachAxis(axisX) - series.attachAxis(axisY) - - # Setup legend. - self.chart.legend().setVisible(True) - self.chart.legend().setAlignment(QtCore.Qt.AlignTop) - self.chart.legend().setMarkerShape(QtCharts.QLegend.MarkerShapeCircle) - - # Hide scatters for epoch and val loss from legend. - for s in ("epoch_loss_scatter", "val_loss_scatter"): - self.chart.legend().markers(self.series[s])[0].setVisible(False) - - self.chartView = QtCharts.QChartView(self.chart) - self.chartView.setRenderHint(QtGui.QPainter.Antialiasing) - layout = QtWidgets.QVBoxLayout() - layout.addWidget(self.chartView) - - if self.show_controller: - control_layout = QtWidgets.QHBoxLayout() - - field = QtWidgets.QCheckBox("Log Scale") - field.setChecked(self.log_scale) - field.stateChanged.connect(self.toggle_log_scale) - control_layout.addWidget(field) - - field = QtWidgets.QCheckBox("Ignore Outliers") - field.setChecked(self.ignore_outliers) - field.stateChanged.connect(self.toggle_ignore_outliers) - control_layout.addWidget(field) - - control_layout.addWidget(QtWidgets.QLabel("Batches to Show:")) - - # Add field for how many batches to show in chart. - field = QtWidgets.QComboBox() - self.batch_options = "200,1000,5000,All".split(",") - for opt in self.batch_options: - field.addItem(opt) - cur_opt_str = ( - "All" if self.batches_to_show < 0 else str(self.batches_to_show) - ) - if cur_opt_str in self.batch_options: - field.setCurrentText(cur_opt_str) - - # Set connection action for when user selects another option. - field.currentIndexChanged.connect( - lambda x: self.set_batches_to_show(self.batch_options[x]) - ) - - # Store field as property and add to layout. - self.batches_to_show_field = field - control_layout.addWidget(self.batches_to_show_field) - - control_layout.addStretch(1) - - self.stop_button = QtWidgets.QPushButton("Stop Early") - self.stop_button.clicked.connect(self.stop) - control_layout.addWidget(self.stop_button) - self.cancel_button = QtWidgets.QPushButton("Cancel Training") - self.cancel_button.clicked.connect(self.cancel) - control_layout.addWidget(self.cancel_button) - - widget = QtWidgets.QWidget() - widget.setLayout(control_layout) - layout.addWidget(widget) - - wid = QtWidgets.QWidget() - wid.setLayout(layout) - self.setCentralWidget(wid) - - self.config = config - self.X = [] - self.Y = [] - self.best_val_x = None - self.best_val_y = None - - self.t0 = None - self.mean_epoch_time_min = None - self.mean_epoch_time_sec = None - self.eta_ten_epochs_min = None - - self.current_job_output_type = what - self.epoch = 0 - self.epoch_size = 1 - self.epochs_in_plateau = 0 - self.last_epoch_val_loss = None - self.penultimate_epoch_val_loss = None - self.epoch_in_plateau_flag = False - self.last_batch_number = 0 - self.is_running = False - - def toggle_ignore_outliers(self): - """Toggles whether to ignore outliers in chart scaling.""" - self.ignore_outliers = not self.ignore_outliers - - def toggle_log_scale(self): - """Toggle whether to use log-scaled y-axis.""" - self.log_scale = not self.log_scale - self.update_y_axis() - - def set_batches_to_show(self, batches: str): - """Set the number of batches to show on the x-axis. - - Args: - batches: Number of batches as a string. If numeric, this will be converted - to an integer. If non-numeric string (e.g., "All"), then all batches - will be shown. - """ - if batches.isdigit(): - self.batches_to_show = int(batches) - else: - self.batches_to_show = -1 - - def update_y_axis(self): - """Update the y-axis when scale changes.""" - to = "log" if self.log_scale else "linear" - - # Remove other axes. - for name, axisY in self.axisY.items(): - if name != to: - if axisY in self.chart.axes(): - self.chart.removeAxis(axisY) - for series in self.chart.series(): - if axisY in series.attachedAxes(): - series.detachAxis(axisY) - - # Add axis. - axisY = self.axisY[to] - self.chart.addAxis(axisY, QtCore.Qt.AlignLeft) - for series in self.chart.series(): - series.attachAxis(axisY) - - def setup_zmq(self, zmq_context: Optional[zmq.Context] = None): - """Connect to ZMQ ports that listen to commands and updates. - - Args: - zmq_context: The `zmq.Context` object to use for connections. A new one is - created if not specified and will be closed when the monitor exits. If - an existing one is provided, it will NOT be closed. - """ - # Keep track of whether we're using an existing context (which we won't close - # when done) or are creating our own (which we should close). - self.ctx_given = zmq_context is not None - self.ctx = zmq.Context() if zmq_context is None else zmq_context - - # Progress monitoring, SUBSCRIBER - self.sub = self.ctx.socket(zmq.SUB) - self.sub.subscribe("") - self.sub.bind("tcp://127.0.0.1:9001") - - # Controller, PUBLISHER - self.zmq_ctrl = None - if self.show_controller: - self.zmq_ctrl = self.ctx.socket(zmq.PUB) - self.zmq_ctrl.bind("tcp://127.0.0.1:9000") - - # Set timer to poll for messages. - self.timer = QtCore.QTimer() - self.timer.timeout.connect(self.check_messages) - self.timer.start(self.message_poll_time_ms) - - def cancel(self): - """Set the cancel flag.""" - self.canceled = True - if self.cancel_button is not None: - self.cancel_button.setText("Canceling...") - self.cancel_button.setEnabled(False) - - def stop(self): - """Send command to stop training.""" - if self.zmq_ctrl is not None: - # Send command to stop training. - logger.info("Sending command to stop training.") - self.zmq_ctrl.send_string(jsonpickle.encode(dict(command="stop"))) - - # Disable the button to prevent double messages. - if self.stop_button is not None: - self.stop_button.setText("Stopping...") - self.stop_button.setEnabled(False) - - def add_datapoint(self, x: int, y: float, which: str): - """Add a data point to graph. - - Args: - x: The batch number (out of all epochs, not just current), or epoch. - y: The loss value. - which: Type of data point we're adding. Possible values are: - * "batch" (loss for the batch) - * "epoch_loss" (loss for the entire epoch) - * "val_loss" (validation loss for the epoch) - """ - if which == "batch": - self.X.append(x) - self.Y.append(y) - - # Redraw batch at intervals (faster than plotting every batch). - draw_batch = False - if self.last_redraw_batch is None: - draw_batch = True - else: - dt = perf_counter() - self.last_redraw_batch - draw_batch = (dt * 1000) >= self.redraw_batch_time_ms - - if draw_batch: - self.last_redraw_batch = perf_counter() - if self.batches_to_show < 0 or len(self.X) < self.batches_to_show: - xs, ys = self.X, self.Y - else: - xs, ys = ( - self.X[-self.batches_to_show :], - self.Y[-self.batches_to_show :], - ) - - points = [QtCore.QPointF(x, y) for x, y in zip(xs, ys) if y > 0] - self.series["batch"].replace(points) - - # Set X scale to show all points - dx = 0.5 - self.chart.axisX().setRange(min(xs) - dx, max(xs) + dx) - - if self.ignore_outliers: - dy = np.ptp(ys) * 0.02 - # Set Y scale to exclude outliers - q1, q3 = np.quantile(ys, (0.25, 0.75)) - iqr = q3 - q1 # interquartile range - low = q1 - iqr * 1.5 - high = q3 + iqr * 1.5 - - low = max(low, min(ys) - dy) # keep within range of data - high = min(high, max(ys) + dy) - else: - # Set Y scale to show all points - dy = np.ptp(ys) * 0.02 - low = min(ys) - dy - high = max(ys) + dy - - if self.log_scale: - low = max(low, 1e-8) # for log scale, low cannot be 0 - - self.chart.axisY().setRange(low, high) - - else: - if which == "epoch_loss": - self.series["epoch_loss"].append(x, y) - self.series["epoch_loss_scatter"].append(x, y) - elif which == "val_loss": - self.series["val_loss"].append(x, y) - self.series["val_loss_scatter"].append(x, y) - if self.best_val_y is None or y < self.best_val_y: - self.best_val_x = x - self.best_val_y = y - self.series["val_loss_best"].replace([QtCore.QPointF(x, y)]) - - def set_start_time(self, t0: float): - """Mark the start flag and time of the run. - - Args: - t0: Start time in seconds. - """ - self.t0 = t0 - self.is_running = True - - def set_end(self): - """Mark the end of the run.""" - self.is_running = False - - def update_runtime(self): - """Update the title text with the current running time.""" - if self.is_timer_running: - dt = perf_counter() - self.t0 - dt_min, dt_sec = divmod(dt, 60) - title = f"Training Epoch {self.epoch + 1} / " - title += f"Runtime: {int(dt_min):02}:{int(dt_sec):02}" - if self.last_epoch_val_loss is not None: - if self.penultimate_epoch_val_loss is not None: - title += ( - f"
Mean Time per Epoch: " - f"{int(self.mean_epoch_time_min):02}:{int(self.mean_epoch_time_sec):02} / " - f"ETA Next 10 Epochs: {int(self.eta_ten_epochs_min)} min" - ) - if self.epoch_in_plateau_flag: - title += ( - f"
Epochs in Plateau: " - f"{self.epochs_in_plateau} / " - f"{self.config.optimization.early_stopping.plateau_patience}" - ) - title += ( - f"
Last Epoch Validation Loss: " - f"{self.last_epoch_val_loss:.3e}" - ) - if self.best_val_x is not None: - best_epoch = (self.best_val_x // self.epoch_size) + 1 - title += ( - f"
Best Epoch Validation Loss: " - f"{self.best_val_y:.3e} (epoch {best_epoch})" - ) - self.set_message(title) - - @property - def is_timer_running(self) -> bool: - """Return True if the timer has started.""" - return self.t0 is not None and self.is_running - - def set_message(self, text: str): - """Set the chart title text.""" - self.chart.setTitle(text) - - def check_messages( - self, timeout: int = 10, times_to_check: int = 10, do_update: bool = True - ): - """Poll for ZMQ messages and adds any received data to graph. - - The message is a dictionary encoded as JSON: - * event - options include - * train_begin - * train_end - * epoch_begin - * epoch_end - * batch_end - * what - this should match the type of model we're training and - ensures that we ignore old messages when we start monitoring - a new training session (when we're training multiple types - of models in a sequence, as for the top-down pipeline). - * logs - dictionary with data relevant for plotting, can include - * loss - * val_loss - - Args: - timeout: Message polling timeout in milliseconds. This is how often we will - check for new command messages. - times_to_check: How many times to check for new messages in the queue before - going back to polling with a timeout. Helps to clear backlogs of - messages if necessary. - do_update: If True (the default), update the GUI text. - """ - if self.sub and self.sub.poll(timeout, zmq.POLLIN): - msg = jsonpickle.decode(self.sub.recv_string()) - - if msg["event"] == "train_begin": - self.set_start_time(perf_counter()) - self.current_job_output_type = msg["what"] - - # Make sure message matches current training job. - if msg.get("what", "") == self.current_job_output_type: - - if not self.is_timer_running: - # We must have missed the train_begin message, so start timer now. - self.set_start_time(perf_counter()) - - if msg["event"] == "train_end": - self.set_end() - elif msg["event"] == "epoch_begin": - self.epoch = msg["epoch"] - elif msg["event"] == "epoch_end": - self.epoch_size = max(self.epoch_size, self.last_batch_number + 1) - self.add_datapoint( - (self.epoch + 1) * self.epoch_size, - msg["logs"]["loss"], - "epoch_loss", - ) - if "val_loss" in msg["logs"].keys(): - # update variables and add points to plot - self.penultimate_epoch_val_loss = self.last_epoch_val_loss - self.last_epoch_val_loss = msg["logs"]["val_loss"] - self.add_datapoint( - (self.epoch + 1) * self.epoch_size, - msg["logs"]["val_loss"], - "val_loss", - ) - # calculate timing and flags at new epoch - if self.penultimate_epoch_val_loss is not None: - mean_epoch_time = (perf_counter() - self.t0) / ( - self.epoch + 1 - ) - self.mean_epoch_time_min, self.mean_epoch_time_sec = divmod( - mean_epoch_time, 60 - ) - self.eta_ten_epochs_min = (mean_epoch_time * 10) // 60 - - val_loss_delta = ( - self.penultimate_epoch_val_loss - - self.last_epoch_val_loss - ) - self.epoch_in_plateau_flag = ( - val_loss_delta - < self.config.optimization.early_stopping.plateau_min_delta - ) or (self.best_val_y < self.last_epoch_val_loss) - self.epochs_in_plateau = ( - self.epochs_in_plateau + 1 - if self.epoch_in_plateau_flag - else 0 - ) - self.on_epoch.emit() - elif msg["event"] == "batch_end": - self.last_batch_number = msg["batch"] - self.add_datapoint( - (self.epoch * self.epoch_size) + msg["batch"], - msg["logs"]["loss"], - "batch", - ) - - # Check for messages again (up to times_to_check times). - if times_to_check > 0: - self.check_messages( - timeout=timeout, times_to_check=times_to_check - 1, do_update=False - ) - - if do_update: - self.update_runtime() diff --git a/sleap/gui/widgets/video.py b/sleap/gui/widgets/video.py index 12e6be7cc..08ee5bf36 100644 --- a/sleap/gui/widgets/video.py +++ b/sleap/gui/widgets/video.py @@ -14,7 +14,6 @@ """ from collections import deque - # FORCE_REQUESTS controls whether we emit a signal to process frame requests # if we haven't processed any for a certain amount of time. # Usually the processing gets triggered by a timer but if the user is (e.g.) @@ -25,57 +24,56 @@ FORCE_REQUESTS = True -from qtpy import QtWidgets, QtCore +import atexit +import math +import time +from typing import Callable, List, Optional, Union -from qtpy.QtWidgets import ( - QApplication, - QVBoxLayout, - QWidget, - QGraphicsView, - QGraphicsScene, - QShortcut, - QGraphicsItem, - QGraphicsObject, - QGraphicsEllipseItem, - QGraphicsTextItem, - QGraphicsRectItem, - QGraphicsPolygonItem, -) +import numpy as np +import qimage2ndarray +from qtpy import QtCore, QtWidgets +from qtpy.QtCore import QLineF, QMarginsF, QPointF, QRectF, Qt from qtpy.QtGui import ( - QImage, - QPixmap, - QPainter, - QPainterPath, - QTransform, - QPen, QBrush, QColor, + QCursor, QFont, - QPolygonF, + QImage, QKeyEvent, - QMouseEvent, QKeySequence, + QMouseEvent, + QPainter, + QPainterPath, + QPen, + QPixmap, + QPolygonF, + QTransform, +) +from qtpy.QtWidgets import ( + QApplication, + QGraphicsEllipseItem, + QGraphicsItem, + QGraphicsObject, + QGraphicsPolygonItem, + QGraphicsRectItem, + QGraphicsScene, + QGraphicsTextItem, + QGraphicsView, + QShortcut, + QVBoxLayout, + QWidget, + QPinchGesture, ) -from qtpy.QtCore import Qt, QRectF, QPointF, QMarginsF, QLineF - -import atexit -import math -import time -import numpy as np - -from typing import Callable, List, Optional, Union import sleap -from sleap.prefs import prefs -from sleap.skeleton import Node -from sleap.instance import Instance, Point -from sleap.io.video import Video -from sleap.gui.widgets.slider import VideoSlider -from sleap.gui.state import GuiState from sleap.gui.color import ColorManager from sleap.gui.shortcuts import Shortcuts - -import qimage2ndarray +from sleap.gui.state import GuiState +from sleap.gui.widgets.slider import VideoSlider +from sleap.instance import Instance, Point, PredictedInstance +from sleap.io.video import Video +from sleap.prefs import prefs +from sleap.skeleton import Node class LoadImageWorker(QtCore.QObject): @@ -193,6 +191,7 @@ class QtVideoPlayer(QWidget): Signals: * changedPlot: Emitted whenever the plot is redrawn + * updatedPlot: Emitted whenever a node is moved (updates trails overlays) Attributes: video: The :class:`Video` to display @@ -202,6 +201,7 @@ class QtVideoPlayer(QWidget): """ changedPlot = QtCore.Signal(QWidget, int, Instance) + updatedPlot = QtCore.Signal(int) def __init__( self, @@ -241,6 +241,8 @@ def __init__( self._register_shortcuts() + self.context_menu = None + self._menu_actions = dict() if self.context: self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.show_contextual_menu) @@ -359,41 +361,54 @@ def add_shortcut(key, step): def setSeekbarSelection(self, a: int, b: int): self.seekbar.setSelection(a, b) - def show_contextual_menu(self, where: QtCore.QPoint): - if not self.is_menu_enabled: - return + def create_contextual_menu(self, scene_pos: QtCore.QPointF) -> QtWidgets.QMenu: + """Create the context menu for the viewer. - scene_pos = self.view.mapToScene(where) - menu = QtWidgets.QMenu() + This is called when the user right-clicks in the viewer. This function also + stores the menu actions in the `_menu_actions` attribute so that they can be + accessed later and stores the context menu in the `context_menu` attribute. - menu.addAction("Add Instance:").setEnabled(False) + Args: + scene_pos: The position in the scene where the menu was requested. - menu.addAction("Default", lambda: self.context.newInstance(init_method="best")) + Returns: + The created context menu. + """ - menu.addAction( - "Average", - lambda: self.context.newInstance( - init_method="template", location=scene_pos - ), - ) + self.context_menu = QtWidgets.QMenu() + self.context_menu.addAction("Add Instance:").setEnabled(False) + + self._menu_actions = dict() + params_by_action_name = { + "Default": {"init_method": "best", "location": scene_pos}, + "Average": {"init_method": "template", "location": scene_pos}, + "Force Directed": {"init_method": "force_directed", "location": scene_pos}, + "Copy Prior Frame": {"init_method": "prior_frame"}, + "Random": {"init_method": "random", "location": scene_pos}, + } + for action_name, params in params_by_action_name.items(): + self._menu_actions[action_name] = self.context_menu.addAction( + action_name, lambda params=params: self.context.newInstance(**params) + ) - menu.addAction( - "Force Directed", - lambda: self.context.newInstance( - init_method="force_directed", location=scene_pos - ), - ) + return self.context_menu - menu.addAction( - "Copy Prior Frame", - lambda: self.context.newInstance(init_method="prior_frame"), - ) + def show_contextual_menu(self, where: QtCore.QPoint): + """Show the context menu at the given position in the viewer. - menu.addAction( - "Random", - lambda: self.context.newInstance(init_method="random", location=scene_pos), - ) + This is called when the user right-clicks in the viewer. This function calls + `create_contextual_menu` to create the menu and then shows the menu at the + given position. + + Args: + where: The position in the viewer where the menu was requested. + """ + + if not self.is_menu_enabled: + return + scene_pos = self.view.mapToScene(where) + menu = self.create_contextual_menu(scene_pos) menu.exec_(self.mapToGlobal(where)) def load_video(self, video: Video, plot=True): @@ -407,22 +422,33 @@ def load_video(self, video: Video, plot=True): self.video = video - # Is this necessary? - self.view.scene.setSceneRect(0, 0, video.width, video.height) + if self.video is None: + self.reset() + else: + # Is this necessary? + self.view.scene.setSceneRect(0, 0, video.width, video.height) - self.seekbar.setMinimum(0) - self.seekbar.setMaximum(self.video.last_frame_idx) - self.seekbar.setEnabled(True) - self.seekbar.resizeEvent() + self.seekbar.setMinimum(0) + self.seekbar.setMaximum(self.video.last_frame_idx) + self.seekbar.setEnabled(True) + self.seekbar.resizeEvent() if plot: self.plot() def reset(self): """Reset viewer by removing all video data.""" + # Reset view and video self.video = None - self.state["frame_idx"] = None self.view.clear() + self.view.setImage(QImage(sleap.util.get_package_file("gui/background.png"))) + + # Handle overlays and gui state in callback + frame_idx = None + selected_instance = None + self.changedPlot.emit(self, frame_idx, selected_instance) + + # Reset seekbar self.seekbar.setMaximum(0) self.seekbar.setEnabled(False) @@ -459,7 +485,9 @@ def addInstance(self, instance, **kwargs): instance = QtInstance(instance=instance, player=self, **kwargs) if type(instance) != QtInstance: return - if instance.instance.n_visible_points > 0: + if instance.instance.n_visible_points > 0 or not isinstance( + instance.instance, PredictedInstance + ): self.view.scene.addItem(instance) # connect signal so we can adjust QtNodeLabel positions after zoom @@ -487,6 +515,10 @@ def plot(self, *args): self._video_image_loader.video = self.video self._video_image_loader.request(idx) + def update_plot(self): + idx = self.state["frame_idx"] or 0 + self.updatedPlot.emit(idx) + def showInstances(self, show): """Show/hide all instances in viewer. @@ -790,7 +822,9 @@ def __init__(self, state=None, player=None, *args, **kwargs): self.setTransformationAnchor(anchor_mode) # Set icon as default background. - self.setImage(QImage(sleap.util.get_package_file("sleap/gui/background.png"))) + self.setImage(QImage(sleap.util.get_package_file("gui/background.png"))) + + self.grabGesture(Qt.GestureType.PinchGesture) def dragEnterEvent(self, event): if self.parentWidget(): @@ -1131,8 +1165,13 @@ def mouseDoubleClickEvent(self, event: QMouseEvent): QGraphicsView.mouseDoubleClickEvent(self, event) def wheelEvent(self, event): - """Custom event handler. Zoom in/out based on scroll wheel change.""" - # zoom on wheel when no mouse buttons are pressed + """Custom event handler to zoom in/out based on scroll wheel change. + + We cannot use the default QGraphicsView.wheelEvent behavior since that will + scroll the view. + """ + + # Zoom on wheel when no mouse buttons are pressed if event.buttons() == Qt.NoButton: angle = event.angleDelta().y() factor = 1.1 if angle > 0 else 0.9 @@ -1140,20 +1179,10 @@ def wheelEvent(self, event): self.zoomFactor = max(factor * self.zoomFactor, 1) self.updateViewer() - # Trigger wheelEvent for all child elements. This is a bit of a hack. - # We can't use QGraphicsView.wheelEvent(self, event) since that will scroll - # view. - # We want to trigger for all children, since wheelEvent should continue rotating - # an skeleton even if the skeleton node/node label is no longer under the - # cursor. - # Note that children expect a QGraphicsSceneWheelEvent event, which is why we're - # explicitly ignoring TypeErrors. Everything seems to work fine since we don't - # care about the mouse position; if we did, we'd need to map pos to scene. + # Trigger only for rotation-relevant children (otherwise GUI crashes) for child in self.items(): - try: + if isinstance(child, (QtNode, QtNodeLabel)): child.wheelEvent(event) - except TypeError: - pass def keyPressEvent(self, event): """Custom event hander, disables default QGraphicsView behavior.""" @@ -1163,6 +1192,23 @@ def keyReleaseEvent(self, event): """Custom event hander, disables default QGraphicsView behavior.""" event.ignore() # Kicks the event up to parent + def event(self, event): + if event.type() == QtCore.QEvent.Gesture: + return self.handleGestureEvent(event) + return super().event(event) + + def handleGestureEvent(self, event): + gesture = event.gesture(Qt.GestureType.PinchGesture) + if gesture: + self.handlePinchGesture(gesture) + return True + + def handlePinchGesture(self, gesture: QPinchGesture): + if gesture.state() == Qt.GestureState.GestureUpdated: + factor = gesture.scaleFactor() + self.zoomFactor = max(factor * self.zoomFactor, 1) + self.updateViewer() + class QtNodeLabel(QGraphicsTextItem): """ @@ -1212,6 +1258,9 @@ def __init__( self.adjustStyle() + def __repr__(self) -> str: + return f"QtNodeLabel(pos()={self.pos()}, node={self.node})" + def adjustPos(self, *args, **kwargs): """Update the position of the label based on the position of the node. @@ -1417,6 +1466,9 @@ def __init__( self.setPos(self.point.x, self.point.y) self.updatePoint(user_change=False) + def __repr__(self): + return f"QtNode(pos()={self.pos()},point=Point{self.point},node={self.node})" + def calls(self): """Method to call all callbacks.""" for callback in self.callbacks: @@ -1538,7 +1590,6 @@ def mousePressEvent(self, event): def mouseMoveEvent(self, event): """Custom event handler for mouse move.""" - # print(event) if self.dragParent: self.parentObject().mouseMoveEvent(event) else: @@ -1549,7 +1600,6 @@ def mouseMoveEvent(self, event): def mouseReleaseEvent(self, event): """Custom event handler for mouse release.""" - # print(event) self.unsetCursor() if self.dragParent: self.parentObject().mouseReleaseEvent(event) @@ -1560,12 +1610,14 @@ def mouseReleaseEvent(self, event): super(QtNode, self).mouseReleaseEvent(event) self.updatePoint(user_change=True) self.dragParent = False - self.player.plot() # Redraw trails after node is moved + self.player.update_plot() # Redraw trails after node is moved def wheelEvent(self, event): """Custom event handler for mouse scroll wheel.""" if self.dragParent: - angle = event.delta() / 20 + self.parentObject().rotation() + angle = ( + event.angleDelta().x() + event.angleDelta().y() + ) / 20 + self.parentObject().rotation() self.parentObject().setRotation(angle) event.accept() @@ -1576,6 +1628,10 @@ def mouseDoubleClickEvent(self, event: QMouseEvent): view = scene.views()[0] view.instanceDoubleClicked.emit(self.parentObject().instance, event) + def hoverEnterEvent(self, event): + """Custom event handler for mouse hover enter.""" + return super().hoverEnterEvent(event) + class QtEdge(QGraphicsPolygonItem): """ @@ -1632,6 +1688,9 @@ def __init__( self.setBrush(brush) self.full_opacity = 1 + def __repr__(self) -> str: + return f"QtEdge(src={self.src}, dst={self.dst})" + def line(self): return self._line @@ -1772,6 +1831,7 @@ def __init__( self.labels = {} self.labels_shown = True self._selected = False + self._is_hovering = False self._bounding_rect = QRectF() # Show predicted instances behind non-predicted ones @@ -1784,12 +1844,16 @@ def __init__( ) # Add box to go around instance for selection - self.box = QGraphicsRectItem(parent=self) + if self.predicted: + self.box = QGraphicsRectItem(parent=self) + else: + self.box = VisibleBoundingBox(rect=self._bounding_rect, parent=self) box_pen_width = color_manager.get_item_pen_width(self.instance) box_pen = QPen(QColor(*color), box_pen_width) box_pen.setStyle(Qt.DashLine) box_pen.setCosmetic(True) self.box.setPen(box_pen) + self.setAcceptHoverEvents(True) # Add label for highlighted instance self.highlight_label = QtTextWithBackground(parent=self) @@ -1873,6 +1937,9 @@ def __init__( # Update size of box so it includes all the nodes/edges self.updateBox() + def __repr__(self) -> str: + return f"QtInstance(pos()={self.pos()},instance={self.instance})" + def updatePoints(self, complete: bool = False, user_change: bool = False): """Update data and display for all points in skeleton. @@ -1948,7 +2015,12 @@ def updateBox(self, *args, **kwargs): select this instance. """ # Only show box if instance is selected - op = 0.7 if self._selected else 0 + op = 0 + if self._selected: + op = 0.8 + elif self._is_hovering: + op = 0.4 + self.box.setOpacity(op) # Update the position for the box rect = self.getPointsBoundingRect() @@ -2042,6 +2114,209 @@ def paint(self, painter, option, widget=None): """Method required by Qt.""" pass + def hoverEnterEvent(self, event): + self._is_hovering = True + self.updateBox() + return super().hoverEnterEvent(event) + + def hoverLeaveEvent(self, event): + self._is_hovering = False + self.updateBox() + return super().hoverLeaveEvent(event) + + +class VisibleBoundingBox(QtWidgets.QGraphicsRectItem): + """QGraphicsRectItem for user instance bounding boxes. + + This object defines a scalable bounding box that encases an instance and handles + the relevant scaling operations. It is instantiated when its respective QtInstance + object is instantiated. + + When instantiated, it creates 4 boxes, which are properties of the overall object, + on the corners of the overall bounding box. These corner boxes can be dragged to + scale the overall bounding box. + + Args: + rect: The :class:`QRectF` object which defines the non-scalable bounding box. + parent: The :class:`QtInstance` to encompass. + + """ + + def __init__( + self, + rect: QRectF, + parent: QtInstance, + opacity: float = 0.8, + scaling_padding: float = 10.0, + ): + super().__init__(rect, parent) + self.box_width = parent.markerRadius + color_manager = parent.player.color_manager + int_color = color_manager.get_item_color(parent.instance) + self.int_color = QColor(*int_color) + self.corner_opacity = opacity + self.scaling_padding = scaling_padding + + self.parent = parent + self.resizing = None + self.origin = rect.topLeft() + self.ref_width = rect.width() + self.ref_height = rect.height() + + box_pen = QPen(Qt.black) + box_pen.setCosmetic(True) + box_brush = QBrush(self.int_color) + + # Create the edge boxes + self.top_left_box = QtWidgets.QGraphicsRectItem(parent=self) + self.bottom_left_box = QtWidgets.QGraphicsRectItem(parent=self) + self.top_right_box = QtWidgets.QGraphicsRectItem(parent=self) + self.bottom_right_box = QtWidgets.QGraphicsRectItem(parent=self) + + corner_boxes = [ + self.top_left_box, + self.bottom_left_box, + self.top_right_box, + self.bottom_right_box, + ] + for corner_box in corner_boxes: + corner_box.setPen(box_pen) + corner_box.setBrush(box_brush) + corner_box.setOpacity(self.corner_opacity) + corner_box.setCursor(QCursor(Qt.DragMoveCursor)) + + def setRect(self, rect: QRectF): + """Update edge boxes along with instance box""" + super().setRect(rect) + x1, y1, x2, y2 = rect.getCoords() + w = self.box_width + self.top_left_box.setRect(QRectF(QPointF(x1, y1), QPointF(x1 + w, y1 + w))) + self.top_right_box.setRect(QRectF(QPointF(x2 - w, y1), QPointF(x2, y1 + w))) + self.bottom_left_box.setRect(QRectF(QPointF(x1, y2 - w), QPointF(x1 + w, y2))) + self.bottom_right_box.setRect(QRectF(QPointF(x2 - w, y2 - w), QPointF(x2, y2))) + + def mousePressEvent(self, event): + """Custom event handler for pressing on an adjustable corner box. + + This function recognizes that the user has begun resizing the instance and + stores relevant information about the bounding box before the transformation. + """ + if event.button() == Qt.LeftButton: + if self.top_left_box.contains(event.pos()): + self.resizing = "top_left" + self.origin = self.rect().bottomRight() + elif self.top_right_box.contains(event.pos()): + self.resizing = "top_right" + self.origin = self.rect().bottomLeft() + elif self.bottom_left_box.contains(event.pos()): + self.resizing = "bottom_left" + self.origin = self.rect().topRight() + elif self.bottom_right_box.contains(event.pos()): + self.resizing = "bottom_right" + self.origin = self.rect().topLeft() + else: + # Pass event down the stack to continue panning + event.setAccepted(False) + + self.ref_width = self.rect().width() + self.ref_height = self.rect().height() + + def mouseMoveEvent(self, event): + """Custom event handler for moving an adjustable corner box. + + This function resizes the bounding box as the user drags one of its corners. + """ + # Scale the bounding box and QtInstance if an edge box is selected + if event.buttons() & Qt.LeftButton: + x1, y1, x2, y2 = self.rect().getCoords() + new_x = event.pos().x() + new_y = event.pos().y() + + w = self.parent.player.video.width + h = self.parent.player.video.height + + if self.resizing == "top_left": + # Check to see if outside the range of the original bounding box + if new_x < 0: + new_x = 0 + if new_x >= x2 - self.scaling_padding - self.box_width: + new_x = x2 - self.scaling_padding - self.box_width + if new_y < 0: + new_y = 0 + if new_y >= y2 - self.scaling_padding - self.box_width: + new_y = y2 - self.scaling_padding - self.box_width + + # Update the bounding box + self.setRect(QRectF(QPointF(new_x, new_y), QPointF(x2, y2))) + + elif self.resizing == "top_right": + # Check to see if outside the range of the original bounding box + if new_x > w: + new_x = w + if new_x <= x1 + self.scaling_padding + self.box_width: + new_x = x1 + self.scaling_padding + self.box_width + if new_y < 0: + new_y = 0 + if new_y >= y2 - self.scaling_padding - self.box_width: + new_y = y2 - self.scaling_padding - self.box_width + + # Update the bounding box + self.setRect(QRectF(QPointF(x1, new_y), QPointF(new_x, y2))) + + elif self.resizing == "bottom_left": + # Check to see if outside the range of the original bounding box + if new_x < 0: + new_x = 0 + if new_x >= x2 - self.scaling_padding - self.box_width: + new_x = x2 - self.scaling_padding - self.box_width + if new_y > h: + new_y = h + if new_y <= y1 + self.scaling_padding + self.box_width: + new_y = y1 + self.scaling_padding + self.box_width + + # Update the bounding box + self.setRect(QRectF(QPointF(new_x, y1), QPointF(x2, new_y))) + + elif self.resizing == "bottom_right": + # Check to see if outside the range of the original bounding box + if new_x > w: + new_x = w + if new_x <= x1 + self.scaling_padding + self.box_width: + new_x = x1 + self.scaling_padding + self.box_width + if new_y > h: + new_y = h + if new_y <= y1 + self.scaling_padding + self.box_width: + new_y = y1 + self.scaling_padding + self.box_width + + # Update the bounding box + self.setRect(QRectF(QPointF(x1, y1), QPointF(new_x, new_y))) + + def mouseReleaseEvent(self, event): + """Custom event handler for releasing an adjustable corner box. + + This function recognizes the end of a scaling operation by transforming the + instance linked to the bounding box. This is done by updating the positions of + the nodes belonging to the instance and then calling the instance's updatePoints + function to update the entire instance. + """ + if event.button() == Qt.LeftButton: + # Scale the instance + scale_x = self.rect().width() / self.ref_width + scale_y = self.rect().height() / self.ref_height + + for node_key, node_value in self.parent.nodes.items(): + new_x = ( + scale_x * (node_value.point.x - self.origin.x()) + self.origin.x() + ) + new_y = ( + scale_y * (node_value.point.y - self.origin.y()) + self.origin.y() + ) + self.parent.nodes[node_key].setPos(new_x, new_y) + + # Update the instance + self.parent.updatePoints(complete=False, user_change=True) + self.resizing = None + class QtTextWithBackground(QGraphicsTextItem): """ @@ -2141,11 +2416,10 @@ def plot_instances(scene, frame_idx, labels, video=None, fixed=True): if __name__ == "__main__": import argparse - from sleap.io.dataset import Labels parser = argparse.ArgumentParser() - parser.add_argument("data_path", help="Path to labels json file") + parser.add_argument("data_path", help="Path to labels file") args = parser.parse_args() - labels = Labels.load_json(args.data_path) + labels = sleap.load_file(args.data_path) video_demo(labels=labels, standalone=True) diff --git a/sleap/gui/widgets/views.py b/sleap/gui/widgets/views.py new file mode 100644 index 000000000..ec3477ed2 --- /dev/null +++ b/sleap/gui/widgets/views.py @@ -0,0 +1,103 @@ +"""GUI code for the views (e.g. Videos, Skeleton, Labeling Suggestions, etc.).""" + +from typing import Tuple +from qtpy.QtWidgets import ( + QWidget, + QHBoxLayout, + QVBoxLayout, + QToolButton, + QFrame, + QSizePolicy, + QComboBox, +) +from qtpy.QtCore import Qt +from qtpy.QtGui import QCursor + + +class CollapsibleWidget(QWidget): + """An animated collapsible QWidget. + + Derived from: https://stackoverflow.com/a/37119983/13281260 + """ + + def __init__(self, title: str, parent: QWidget = None): + super().__init__(parent=parent) + + # Create the header widget which contains the toggle button. + self.header_widget, self.toggle_button = self.create_header_widget(title) + + # Content area for setting an external layout to. + self.content_area = QWidget() + + # Tie everything together in a main layout. + main_layout = self.create_main_layout() + self.setLayout(main_layout) + + def create_toggle_button(self, title="") -> QToolButton: + """Create our custom toggle button.""" + + toggle_button = QToolButton() + toggle_button.setStyleSheet("QToolButton { border: none; }") + toggle_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) + toggle_button.setArrowType(Qt.ArrowType.RightArrow) + toggle_button.setText(title) + toggle_button.setCheckable(True) + toggle_button.setChecked(False) + toggle_button.setCursor(QCursor(Qt.PointingHandCursor)) + + toggle_button.clicked.connect(self.toggle_button_callback) + + return toggle_button + + def create_header_widget(self, title="") -> Tuple[QWidget, QToolButton]: + """Create header widget which includes `QToolButton` and `QFrame`.""" + + # Create our custom toggle button. + toggle_button = self.create_toggle_button(title) + + # Create the header line. + header_line = QFrame() + header_line.setFrameShape(QFrame.HLine) + header_line.setFrameShadow(QFrame.Plain) + header_line.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) + header_line.setStyleSheet("color: #dcdcdc") + + # Created the layout for the header. + header_layout = QHBoxLayout() + header_layout.addWidget(toggle_button) + header_layout.addWidget(header_line) + header_layout.setContentsMargins(0, 0, 0, 0) + + # Create a widget to apply the header layout to. + header_widget = QWidget() + header_widget.setLayout(header_layout) + + return header_widget, toggle_button + + def create_main_layout(self) -> QVBoxLayout: + """Tie everything together in a main layout.""" + + main_layout = QVBoxLayout() + main_layout.addWidget(self.header_widget) + main_layout.addWidget(self.content_area) + main_layout.setContentsMargins(0, 0, 0, 0) + + return main_layout + + def toggle_button_callback(self, checked: bool): + self.toggle_button.setArrowType( + Qt.ArrowType.DownArrow if checked else Qt.ArrowType.RightArrow + ) + + # Hide children if we're collapsing + for child in self.content_area.findChildren(QWidget): + child.setVisible(checked) + + # Collapse combo box (otherwise, visiblity opens combo) + if checked: + combo = self.content_area.findChild(QComboBox) + combo.hidePopup() + + def set_content_layout(self, content_layout): + self.content_area.setLayout(content_layout) + self.toggle_button_callback(self.toggle_button.isChecked()) diff --git a/sleap/info/feature_suggestions.py b/sleap/info/feature_suggestions.py index 51f9038a5..a5f773fa7 100644 --- a/sleap/info/feature_suggestions.py +++ b/sleap/info/feature_suggestions.py @@ -644,7 +644,7 @@ class ParallelFeaturePipeline(object): def get(self, video_idx): """Apply pipeline to single video by idx. Can be called in process.""" video_dict = self.videos_as_dicts[video_idx] - video = cattr.structure(video_dict, Video) + video = Video.cattr().structure(video_dict, Video) group_offset = video_idx * self.pipeline.n_clusters # t0 = time() diff --git a/sleap/info/metrics.py b/sleap/info/metrics.py index 2ac61d339..5bec077e4 100644 --- a/sleap/info/metrics.py +++ b/sleap/info/metrics.py @@ -10,75 +10,6 @@ from sleap.io.dataset import Labels -def matched_instance_distances( - labels_gt: Labels, - labels_pr: Labels, - match_lists_function: Callable, - frame_range: Optional[range] = None, -) -> Tuple[List[int], np.ndarray, np.ndarray, np.ndarray]: - - """ - Distances between ground truth and predicted nodes over a set of frames. - - Args: - labels_gt: the `Labels` object with ground truth data - labels_pr: the `Labels` object with predicted data - match_lists_function: function for determining corresponding instances - Takes two lists of instances and returns "sorted" lists. - frame_range (optional): range of frames for which to compare data - If None, we compare every frame in labels_gt with corresponding - frame in labels_pr. - Returns: - Tuple: - * frame indices map: instance idx (for other matrices) -> frame idx - * distance matrix: (instances * nodes) - * ground truth points matrix: (instances * nodes * 2) - * predicted points matrix: (instances * nodes * 2) - """ - - frame_idxs = [] - points_gt = [] - points_pr = [] - for lf_gt in labels_gt.find(labels_gt.videos[0]): - frame_idx = lf_gt.frame_idx - - # Get instances from ground truth/predicted labels - instances_gt = lf_gt.instances - lfs_pr = labels_pr.find(labels_pr.videos[0], frame_idx=frame_idx) - if len(lfs_pr): - instances_pr = lfs_pr[0].instances - else: - instances_pr = [] - - # Sort ground truth and predicted instances. - # We'll then compare points between corresponding items in lists. - # We can use different "match" functions depending on what we want. - sorted_gt, sorted_pr = match_lists_function(instances_gt, instances_pr) - - # Convert lists of instances to (instances, nodes, 2) matrices. - # This allows match_lists_function to return data as either - # a list of Instances or a (instances, nodes, 2) matrix. - if type(sorted_gt[0]) != np.ndarray: - sorted_gt = list_points_array(sorted_gt) - if type(sorted_pr[0]) != np.ndarray: - sorted_pr = list_points_array(sorted_pr) - - points_gt.append(sorted_gt) - points_pr.append(sorted_pr) - frame_idxs.extend([frame_idx] * len(sorted_gt)) - - # Convert arrays to numpy matrixes - # instances * nodes * (x,y) - points_gt = np.concatenate(points_gt) - points_pr = np.concatenate(points_pr) - - # Calculate distances between corresponding nodes for all corresponding - # ground truth and predicted instances. - D = np.linalg.norm(points_gt - points_pr, axis=2) - - return frame_idxs, D, points_gt, points_pr - - def match_instance_lists( instances_a: List[Union[Instance, PredictedInstance]], instances_b: List[Union[Instance, PredictedInstance]], @@ -165,6 +96,75 @@ def match_instance_lists_nodewise( return instances_a, best_points_array +def matched_instance_distances( + labels_gt: Labels, + labels_pr: Labels, + match_lists_function: Callable = match_instance_lists_nodewise, + frame_range: Optional[range] = None, +) -> Tuple[List[int], np.ndarray, np.ndarray, np.ndarray]: + + """ + Distances between ground truth and predicted nodes over a set of frames. + + Args: + labels_gt: the `Labels` object with ground truth data + labels_pr: the `Labels` object with predicted data + match_lists_function: function for determining corresponding instances + Takes two lists of instances and returns "sorted" lists. + frame_range (optional): range of frames for which to compare data + If None, we compare every frame in labels_gt with corresponding + frame in labels_pr. + Returns: + Tuple: + * frame indices map: instance idx (for other matrices) -> frame idx + * distance matrix: (instances * nodes) + * ground truth points matrix: (instances * nodes * 2) + * predicted points matrix: (instances * nodes * 2) + """ + + frame_idxs = [] + points_gt = [] + points_pr = [] + for lf_gt in labels_gt.find(labels_gt.videos[0]): + frame_idx = lf_gt.frame_idx + + # Get instances from ground truth/predicted labels + instances_gt = lf_gt.instances + lfs_pr = labels_pr.find(labels_pr.videos[0], frame_idx=frame_idx) + if len(lfs_pr): + instances_pr = lfs_pr[0].instances + else: + instances_pr = [] + + # Sort ground truth and predicted instances. + # We'll then compare points between corresponding items in lists. + # We can use different "match" functions depending on what we want. + sorted_gt, sorted_pr = match_lists_function(instances_gt, instances_pr) + + # Convert lists of instances to (instances, nodes, 2) matrices. + # This allows match_lists_function to return data as either + # a list of Instances or a (instances, nodes, 2) matrix. + if type(sorted_gt[0]) != np.ndarray: + sorted_gt = list_points_array(sorted_gt) + if type(sorted_pr[0]) != np.ndarray: + sorted_pr = list_points_array(sorted_pr) + + points_gt.append(sorted_gt) + points_pr.append(sorted_pr) + frame_idxs.extend([frame_idx] * len(sorted_gt)) + + # Convert arrays to numpy matrixes + # instances * nodes * (x,y) + points_gt = np.concatenate(points_gt) + points_pr = np.concatenate(points_pr) + + # Calculate distances between corresponding nodes for all corresponding + # ground truth and predicted instances. + D = np.linalg.norm(points_gt - points_pr, axis=2) + + return frame_idxs, D, points_gt, points_pr + + def point_dist( inst_a: Union[Instance, PredictedInstance], inst_b: Union[Instance, PredictedInstance], @@ -238,46 +238,3 @@ def point_match_count(dist_array: np.ndarray, thresh: float = 5) -> int: def point_nonmatch_count(dist_array: np.ndarray, thresh: float = 5) -> int: """Given an array of distances, returns number which are not <= threshold.""" return dist_array.shape[0] - point_match_count(dist_array, thresh) - - -if __name__ == "__main__": - - labels_gt = Labels.load_json("tests/data/json_format_v1/centered_pair.json") - labels_pr = Labels.load_json( - "tests/data/json_format_v2/centered_pair_predictions.json" - ) - - # OPTION 1 - - # Match each ground truth instance node to the closest corresponding node - # from any predicted instance in the same frame. - - nodewise_matching_func = match_instance_lists_nodewise - - # OPTION 2 - - # Match each ground truth instance to a distinct predicted instance: - # We want to maximize the number of "matching" points between instances, - # where "match" means the points are within some threshold distance. - # Note that each sorted list will be as long as the shorted input list. - - instwise_matching_func = lambda gt_list, pr_list: match_instance_lists( - gt_list, pr_list, point_nonmatch_count - ) - - # PICK THE FUNCTION - - inst_matching_func = nodewise_matching_func - # inst_matching_func = instwise_matching_func - - # Calculate distances - frame_idxs, D, points_gt, points_pr = matched_instance_distances( - labels_gt, labels_pr, inst_matching_func - ) - - # Show mean difference for each node - node_names = labels_gt.skeletons[0].node_names - - for node_idx, node_name in enumerate(node_names): - mean_d = np.nanmean(D[..., node_idx]) - print(f"{node_name}\t\t{mean_d}") diff --git a/sleap/info/summary.py b/sleap/info/summary.py index c6a6af60e..0cad1617e 100644 --- a/sleap/info/summary.py +++ b/sleap/info/summary.py @@ -21,7 +21,7 @@ class StatisticSeries: are frame index and value are some numerical value for the frame. Args: - labels: The :class:`Labels` for which to calculate series. + labels: The `Labels` for which to calculate series. """ labels: Labels @@ -41,7 +41,7 @@ def get_point_score_series( """Get series with statistic of point scores in each frame. Args: - video: The :class:`Video` for which to calculate statistic. + video: The `Video` for which to calculate statistic. reduction: name of function applied to scores: * sum * min @@ -67,7 +67,7 @@ def get_instance_score_series(self, video, reduction="sum") -> Dict[int, float]: """Get series with statistic of instance scores in each frame. Args: - video: The :class:`Video` for which to calculate statistic. + video: The `Video` for which to calculate statistic. reduction: name of function applied to scores: * sum * min @@ -93,7 +93,7 @@ def get_point_displacement_series(self, video, reduction="sum") -> Dict[int, flo same track) from the closest earlier labeled frame. Args: - video: The :class:`Video` for which to calculate statistic. + video: The `Video` for which to calculate statistic. reduction: name of function applied to point scores: * sum * mean @@ -121,7 +121,7 @@ def get_primary_point_displacement_series( Get sum of displacement for single node of each instance per frame. Args: - video: The :class:`Video` for which to calculate statistic. + video: The `Video` for which to calculate statistic. reduction: name of function applied to point scores: * sum * mean @@ -226,7 +226,7 @@ def _calculate_frame_velocity( Calculate total point displacement between two given frames. Args: - lf: The :class:`LabeledFrame` for which we want velocity + lf: The `LabeledFrame` for which we want velocity last_lf: The frame from which to calculate displacement. reduce_function: Numpy function (e.g., np.sum, np.nanmean) is applied to *point* displacement, and then those @@ -246,3 +246,35 @@ def _calculate_frame_velocity( inst_dist = reduce_function(point_dist) val += inst_dist if not np.isnan(inst_dist) else 0 return val + + def get_tracking_score_series( + self, video: Video, reduction: str = "min" + ) -> Dict[int, float]: + """Get series with statistic of tracking scores in each frame. + + Args: + video: The `Video` for which to calculate statistic. + reduction: name of function applied to scores: + * mean + * min + + Returns: + The series dictionary (see class docs for details) + """ + reduce_fn = { + "min": np.nanmin, + "mean": np.nanmean, + }[reduction] + + series = dict() + + for lf in self.labels.find(video): + vals = [ + inst.tracking_score for inst in lf if hasattr(inst, "tracking_score") + ] + if vals: + val = reduce_fn(vals) + if not np.isnan(val): + series[lf.frame_idx] = val + + return series diff --git a/sleap/info/write_tracking_h5.py b/sleap/info/write_tracking_h5.py index 255c8c61d..2b714eeb5 100644 --- a/sleap/info/write_tracking_h5.py +++ b/sleap/info/write_tracking_h5.py @@ -1,4 +1,4 @@ -"""Generate an HDF5 file with track occupancy and point location data. +"""Generate an HDF5 or CSV file with track occupancy and point location data. Ignores tracks that are entirely empty. By default will also ignore empty frames from the beginning and end of video, although @@ -29,6 +29,7 @@ import json import h5py as h5 import numpy as np +import pandas as pd from typing import Any, Dict, List, Tuple, Union @@ -258,9 +259,11 @@ def write_occupancy_file( """ with h5.File(output_path, "w") as f: + print(f"\nExporting to SLEAP Analysis file...") for key, val in data_dict.items(): + print(f"\t{key}: ", end="") if isinstance(val, np.ndarray): - print(f"{key}: {val.shape}") + print(f"{val.shape}") if transpose: # Transpose since MATLAB expects column-major @@ -276,20 +279,85 @@ def write_occupancy_file( ) else: if isinstance(val, (str, int, type(None))): - print(f"{key}: {val}") + print(f"{val}") else: - print(f"{key}: {len(val)}") + print(f"{len(val)}") f.create_dataset(key, data=val) print(f"Saved as {output_path}") +def write_csv_file(output_path, data_dict): + + """Write CSV file with data from given dictionary. + + Args: + output_path: Path of HDF5 file. + data_dict: Dictionary with data to save. Keys are dataset names, + values are the data. + + Returns: + None + """ + + if data_dict["tracks"].shape[-1] == 0: + print(f"No tracks to export in {data_dict['video_path']}. Skipping the export") + return + + data_dict["node_names"] = [s.decode() for s in data_dict["node_names"]] + data_dict["track_names"] = [s.decode() for s in data_dict["track_names"]] + data_dict["track_occupancy"] = np.transpose(data_dict["track_occupancy"]).astype( + bool + ) + + # Find frames with at least one animal tracked. + valid_frame_idxs = np.argwhere(data_dict["track_occupancy"].any(axis=1)).flatten() + + tracks = [] + for frame_idx in valid_frame_idxs: + frame_tracks = data_dict["tracks"][frame_idx] + + for i in range(frame_tracks.shape[-1]): + pts = frame_tracks[..., i] + conf_scores = data_dict["point_scores"][frame_idx][..., i] + + if np.isnan(pts).all(): + # Skip if animal wasn't detected in the current frame. + continue + if data_dict["track_names"]: + track = data_dict["track_names"][i] + else: + track = None + + instance_score = data_dict["instance_scores"][frame_idx][i] + + detection = { + "track": track, + "frame_idx": frame_idx, + "instance.score": instance_score, + } + + # Coordinates for each body part. + for node_name, score, (x, y) in zip( + data_dict["node_names"], conf_scores, pts + ): + detection[f"{node_name}.x"] = x + detection[f"{node_name}.y"] = y + detection[f"{node_name}.score"] = score + + tracks.append(detection) + + tracks = pd.DataFrame(tracks) + tracks.to_csv(output_path, index=False) + + def main( labels: Labels, output_path: str, labels_path: str = None, all_frames: bool = True, video: Video = None, + csv: bool = False, ): """Writes HDF5 file with matrices of track occupancy and coordinates. @@ -304,6 +372,7 @@ def main( video: The :py:class:`Video` from which to get data. If no `video` is specified, then the first video in `source_object` videos list will be used. If there are no labeled frames in the `video`, then no output file will be written. + csv: Bool to save the analysis as a csv file if set to True Returns: None @@ -365,7 +434,10 @@ def main( provenance=json.dumps(labels.provenance), # dict cannot be written to hdf5. ) - write_occupancy_file(output_path, data_dict, transpose=True) + if csv: + write_csv_file(output_path, data_dict) + else: + write_occupancy_file(output_path, data_dict, transpose=True) if __name__ == "__main__": diff --git a/sleap/instance.py b/sleap/instance.py index b46c59ab2..382ececf2 100644 --- a/sleap/instance.py +++ b/sleap/instance.py @@ -364,7 +364,7 @@ class Instance: from_predicted: Optional["PredictedInstance"] = attr.ib(default=None) _points: PointArray = attr.ib(default=None) _nodes: List = attr.ib(default=None) - frame: Union["LabeledFrame", None] = attr.ib(default=None) + frame: Union["LabeledFrame", None] = attr.ib(default=None) # TODO(LM): Make private # The underlying Point array type that this instances point array should be. _point_array_type = PointArray @@ -799,11 +799,11 @@ def fill_missing( """ self._fix_array() y1, x1, y2, x2 = self.bounding_box - y1, x1 = max(y1, 0), max(x1, 0) + y1, x1 = np.nanmax([y1, 0]), np.nanmax([x1, 0]) if max_x is not None: - x2 = min(x2, max_x) + x2 = np.nanmin([x2, max_x]) if max_y is not None: - y2 = min(y2, max_y) + y2 = np.nanmin([y2, max_y]) w, h = y2 - y1, x2 - x1 for node in self.skeleton.nodes: @@ -1049,7 +1049,9 @@ def scores(self) -> np.ndarray: return self.points_and_scores_array[:, 2] @classmethod - def from_instance(cls, instance: Instance, score: float) -> "PredictedInstance": + def from_instance( + cls, instance: Instance, score: float, tracking_score: float = 0.0 + ) -> "PredictedInstance": """Create a `PredictedInstance` from an `Instance`. The fields are copied in a shallow manner with the exception of points. For each @@ -1059,6 +1061,7 @@ def from_instance(cls, instance: Instance, score: float) -> "PredictedInstance": Args: instance: The `Instance` object to shallow copy data from. score: The score for this instance. + tracking_score: The tracking score for this instance. Returns: A `PredictedInstance` for the given `Instance`. @@ -1070,6 +1073,7 @@ def from_instance(cls, instance: Instance, score: float) -> "PredictedInstance": ) kw_args["points"] = PredictedPointArray.from_array(instance._points) kw_args["score"] = score + kw_args["tracking_score"] = tracking_score return cls(**kw_args) @classmethod @@ -1080,6 +1084,7 @@ def from_arrays( instance_score: float, skeleton: Skeleton, track: Optional[Track] = None, + tracking_score: float = 0.0, ) -> "PredictedInstance": """Create a predicted instance from data arrays. @@ -1094,6 +1099,7 @@ def from_arrays( skeleton: A sleap.Skeleton instance with n_nodes nodes to associate with the predicted instance. track: Optional `sleap.Track` to associate with the instance. + tracking_score: Optional float representing the track matching score. Returns: A new `PredictedInstance`. @@ -1114,6 +1120,7 @@ def from_arrays( skeleton=skeleton, score=instance_score, track=track, + tracking_score=tracking_score, ) @classmethod @@ -1124,6 +1131,7 @@ def from_pointsarray( instance_score: float, skeleton: Skeleton, track: Optional[Track] = None, + tracking_score: float = 0.0, ) -> "PredictedInstance": """Create a predicted instance from data arrays. @@ -1138,12 +1146,18 @@ def from_pointsarray( skeleton: A sleap.Skeleton instance with n_nodes nodes to associate with the predicted instance. track: Optional `sleap.Track` to associate with the instance. + tracking_score: Optional float representing the track matching score. Returns: A new `PredictedInstance`. """ return cls.from_arrays( - points, point_confidences, instance_score, skeleton, track=track + points, + point_confidences, + instance_score, + skeleton, + track=track, + tracking_score=tracking_score, ) @classmethod @@ -1154,6 +1168,7 @@ def from_numpy( instance_score: float, skeleton: Skeleton, track: Optional[Track] = None, + tracking_score: float = 0.0, ) -> "PredictedInstance": """Create a predicted instance from data arrays. @@ -1168,12 +1183,18 @@ def from_numpy( skeleton: A sleap.Skeleton instance with n_nodes nodes to associate with the predicted instance. track: Optional `sleap.Track` to associate with the instance. + tracking_score: Optional float representing the track matching score. Returns: A new `PredictedInstance`. """ return cls.from_arrays( - points, point_confidences, instance_score, skeleton, track=track + points, + point_confidences, + instance_score, + skeleton, + track=track, + tracking_score=tracking_score, ) @@ -1214,6 +1235,9 @@ def unstructure_instance(x: Instance): converter.register_unstructure_hook(Instance, unstructure_instance) converter.register_unstructure_hook(PredictedInstance, unstructure_instance) + converter.register_unstructure_hook( + InstancesList, lambda x: [converter.unstructure(inst) for inst in x] + ) ## STRUCTURE HOOKS @@ -1229,29 +1253,37 @@ def structure_points(x, type): def structure_instances_list(x, type): inst_list = [] for inst_data in x: - if "score" in inst_data.keys(): - inst = converter.structure(inst_data, PredictedInstance) - else: - inst = converter.structure(inst_data, Instance) + inst = structure_instance(inst_data, type) inst_list.append(inst) return inst_list - converter.register_structure_hook( - Union[List[Instance], List[PredictedInstance]], structure_instances_list - ) + def structure_instance(inst_data, type): + """Structure hook for Instance and PredictedInstance objects.""" + from_predicted = None + + if "score" in inst_data.keys(): + inst = converter.structure(inst_data, PredictedInstance) + else: + if ( + "from_predicted" in inst_data + and inst_data["from_predicted"] is not None + ): + from_predicted = converter.structure( + inst_data["from_predicted"], PredictedInstance + ) + # Remove the from_predicted key. We'll add it back afterwards. + inst_data["from_predicted"] = None + + # Structure the instance data, then add the from_predicted attribute. + inst = converter.structure(inst_data, Instance) + inst.from_predicted = from_predicted + return inst - # Structure forward reference for PredictedInstance for the Instance.from_predicted - # attribute. converter.register_structure_hook( - ForwardRef("PredictedInstance"), - lambda x, _: converter.structure(x, PredictedInstance), + Union[List[Instance], List[PredictedInstance]], structure_instances_list ) - - # converter.register_structure_hook( - # PredictedInstance, - # lambda x, type: converter.structure(x, PredictedInstance), - # ) + converter.register_structure_hook(InstancesList, structure_instances_list) # We can register structure hooks for point arrays that do nothing # because Instance can have a dict of points passed to it in place of @@ -1272,6 +1304,127 @@ def structure_point_array(x, t): return converter +class InstancesList(list): + """A list of `Instance`s associated with a `LabeledFrame`. + + This class should only be used for the `LabeledFrame.instances` attribute. + """ + + def __init__(self, *args, labeled_frame: Optional["LabeledFrame"] = None): + super(InstancesList, self).__init__(*args) + + # Set the labeled frame for each instance + self.labeled_frame = labeled_frame + + @property + def labeled_frame(self) -> "LabeledFrame": + """Return the `LabeledFrame` associated with this list of instances.""" + + return self._labeled_frame + + @labeled_frame.setter + def labeled_frame(self, labeled_frame: "LabeledFrame"): + """Set the `LabeledFrame` associated with this list of instances. + + This updates the `frame` attribute on each instance. + + Args: + labeled_frame: The `LabeledFrame` to associate with this list of instances. + """ + + try: + # If the labeled frame is the same as the one we're setting, then skip + if self._labeled_frame == labeled_frame: + return + except AttributeError: + # Only happens on init and updates each instance.frame (even if None) + pass + + # Otherwise, update the frame for each instance + self._labeled_frame = labeled_frame + for instance in self: + instance.frame = labeled_frame + + def append(self, instance: Union[Instance, PredictedInstance]): + """Append an `Instance` or `PredictedInstance` to the list, setting the frame. + + Args: + item: The `Instance` or `PredictedInstance` to append to the list. + """ + + if not isinstance(instance, (Instance, PredictedInstance)): + raise ValueError( + f"InstancesList can only contain Instance or PredictedInstance objects," + f" but got {type(instance)}." + ) + instance.frame = self.labeled_frame + super().append(instance) + + def extend(self, instances: List[Union[PredictedInstance, Instance]]): + """Extend the list with a list of `Instance`s or `PredictedInstance`s. + + Args: + instances: A list of `Instance` or `PredictedInstance` objects to add to the + list. + + Returns: + None + """ + for instance in instances: + self.append(instance) + + def __delitem__(self, index): + """Remove instance (by index), and set instance.frame to None.""" + + instance: Instance = self.__getitem__(index) + super().__delitem__(index) + + # Modify the instance to remove reference to the frame + instance.frame = None + + def insert(self, index: int, instance: Union[Instance, PredictedInstance]) -> None: + super().insert(index, instance) + instance.frame = self.labeled_frame + + def __setitem__(self, index, instance: Union[Instance, PredictedInstance]): + """Set nth instance in frame to the given instance. + + Args: + index: The index of instance to replace with new instance. + value: The new instance to associate with frame. + + Returns: + None. + """ + super().__setitem__(index, instance) + instance.frame = self.labeled_frame + + def pop(self, index: int) -> Union[Instance, PredictedInstance]: + """Remove and return instance at index, setting instance.frame to None.""" + + instance = super().pop(index) + instance.frame = None + return instance + + def remove(self, instance: Union[Instance, PredictedInstance]) -> None: + """Remove instance from list, setting instance.frame to None.""" + super().remove(instance) + instance.frame = None + + def clear(self) -> None: + """Remove all instances from list, setting instance.frame to None.""" + for instance in self: + instance.frame = None + super().clear() + + def copy(self) -> list: + """Return a shallow copy of the list of instances as a list. + + Note: This will not return an `InstancesList` object, but a normal list. + """ + return list(self) + + @attr.s(auto_attribs=True, eq=False, repr=False, str=False) class LabeledFrame: """Holds labeled data for a single frame of a video. @@ -1284,9 +1437,7 @@ class LabeledFrame: video: Video = attr.ib() frame_idx: int = attr.ib(converter=int) - _instances: Union[List[Instance], List[PredictedInstance]] = attr.ib( - default=attr.Factory(list) - ) + _instances: InstancesList = attr.ib(default=attr.Factory(InstancesList)) def __attrs_post_init__(self): """Called by attrs. @@ -1296,8 +1447,7 @@ def __attrs_post_init__(self): """ # Make sure all instances have a reference to this frame - for instance in self.instances: - instance.frame = self + self.instances = self._instances def __len__(self) -> int: """Return number of instances associated with frame.""" @@ -1313,13 +1463,8 @@ def index(self, value: Instance) -> int: def __delitem__(self, index): """Remove instance (by index) from frame.""" - value = self.instances.__getitem__(index) - self.instances.__delitem__(index) - # Modify the instance to remove reference to this frame - value.frame = None - def __repr__(self) -> str: """Return a readable representation of the LabeledFrame.""" return ( @@ -1342,9 +1487,6 @@ def insert(self, index: int, value: Instance): """ self.instances.insert(index, value) - # Modify the instance to have a reference back to this frame - value.frame = self - def __setitem__(self, index, value: Instance): """Set nth instance in frame to the given instance. @@ -1357,9 +1499,6 @@ def __setitem__(self, index, value: Instance): """ self.instances.__setitem__(index, value) - # Modify the instance to have a reference back to this frame - value.frame = self - def find( self, track: Optional[Union[Track, int]] = -1, user: bool = False ) -> List[Instance]: @@ -1387,7 +1526,7 @@ def instances(self) -> List[Instance]: return self._instances @instances.setter - def instances(self, instances: List[Instance]): + def instances(self, instances: Union[InstancesList, List[Instance]]): """Set the list of instances associated with this frame. Updates the `frame` attribute on each instance to the @@ -1402,9 +1541,11 @@ def instances(self, instances: List[Instance]): None """ - # Make sure to set the frame for each instance to this LabeledFrame - for instance in instances: - instance.frame = self + # Make sure to set the LabeledFrame for each instance to this frame + if isinstance(instances, InstancesList): + instances.labeled_frame = self + else: + instances = InstancesList(instances, labeled_frame=self) self._instances = instances @@ -1679,22 +1820,20 @@ def complex_frame_merge( * list of conflicting instances from base * list of conflicting instances from new """ - merged_instances = [] - redundant_instances = [] - extra_base_instances = copy(base_frame.instances) - extra_new_instances = [] + merged_instances: List[Instance] = [] # Only used for informing user + redundant_instances: List[Instance] = [] + extra_base_instances: List[Instance] = list(base_frame.instances) + extra_new_instances: List[Instance] = [] for new_inst in new_frame: redundant = False for base_inst in base_frame.instances: if new_inst.matches(base_inst): - base_inst.frame = None extra_base_instances.remove(base_inst) redundant_instances.append(base_inst) redundant = True continue if not redundant: - new_inst.frame = None extra_new_instances.append(new_inst) conflict = False @@ -1726,7 +1865,7 @@ def complex_frame_merge( else: # No conflict, so include all instances in base base_frame.instances.extend(extra_new_instances) - merged_instances = copy(extra_new_instances) + merged_instances: List[Instance] = copy(extra_new_instances) extra_base_instances = [] extra_new_instances = [] diff --git a/sleap/io/asyncvideo.py b/sleap/io/asyncvideo.py deleted file mode 100644 index c48d21a8b..000000000 --- a/sleap/io/asyncvideo.py +++ /dev/null @@ -1,218 +0,0 @@ -""" -Support for loading video frames (by chunk) in background process. -""" - -from sleap import Video -from sleap.message import PairedSender, PairedReceiver - -import cattr -import logging -import time -import numpy as np -from math import ceil -from multiprocessing import Process -from typing import Iterable, Iterator, List, Optional, Tuple - - -logger = logging.getLogger(__name__) - - -class AsyncVideo: - """Supports fetching chunks from video in background process.""" - - def __init__(self, base_port: int = 9010): - self.base_port = base_port - - # Spawn the server as a background process - self.server = AsyncVideoServer(self.base_port) - self.server.start() - - # Create sender/receiver for sending requests and receiving data via ZMQ - sender = PairedSender.from_tcp_ports(self.base_port, self.base_port + 1) - result_receiver = PairedReceiver.from_tcp_ports( - send_port=self.base_port + 2, rec_port=self.base_port + 3 - ) - - sender.setup() - result_receiver.setup() - - self.sender = sender - self.receiver = result_receiver - - # Use "handshake" to ensure that initial messages aren't dropped - self.handshake_success = sender.send_handshake() - - def close(self): - """Close the async video server and communication ports.""" - if self.sender and self.server: - self.sender.send_dict(dict(stop=True)) - self.server.join() - - self.server = None - - if self.sender: - self.sender.close() - self.sender = None - - if self.receiver: - self.receiver.close() - self.receiver = None - - def __del__(self): - self.close() - - @classmethod - def from_video( - cls, - video: Video, - frame_idxs: Optional[Iterable[int]] = None, - frames_per_chunk: int = 64, - ) -> "AsyncVideo": - """Create object and start loading frames in background process.""" - obj = cls() - obj.load_by_chunk( - video=video, frame_idxs=frame_idxs, frames_per_chunk=frames_per_chunk - ) - return obj - - def load_by_chunk( - self, - video: Video, - frame_idxs: Optional[Iterable[int]] = None, - frames_per_chunk: int = 64, - ): - """ - Sends request for loading video in background process. - - Args: - video: The :py:class:`Video` to load - frame_idxs: Frame indices we want to load; if None, then full video - is loaded. - frames_per_chunk: How many frames to load per chunk. - - Returns: - None, data should be accessed via :py:method:`chunks`. - """ - # prime the video since this seems to make frames load faster (!?) - video.test_frame - - request_dict = dict( - video=cattr.unstructure(video), frames_per_chunk=frames_per_chunk - ) - # if no frames are specified, whole video will be loaded - if frame_idxs is not None: - request_dict["frame_idxs"] = list(frame_idxs) - - # send the request - self.sender.send_dict(request_dict) - - @property - def chunks(self) -> Iterator[Tuple[List[int], np.ndarray]]: - """ - Generator for fetching chunks of frames. - - When all chunks are loaded, closes the server and communication ports. - - Yields: - Tuple with (list of frame indices, ndarray of frames) - """ - done = False - while not done: - results = self.receiver.check_messages() - if results: - for result in results: - yield result["frame_idxs"], result["ndarray"] - - if result["chunk"] == result["last_chunk"]: - done = True - - # automatically close when all chunks have been received - self.close() - - -class AsyncVideoServer(Process): - """ - Class which loads video frames in background on request. - - All interactions with video server should go through :py:class:`AsyncVideo` - which runs in local thread. - """ - - def __init__(self, base_port: int): - super(AsyncVideoServer, self).__init__() - - self.video = None - self.base_port = base_port - - def run(self): - receiver = PairedReceiver.from_tcp_ports(self.base_port + 1, self.base_port) - receiver.setup() - - result_sender = PairedSender.from_tcp_ports( - send_port=self.base_port + 3, rec_port=self.base_port + 2 - ) - result_sender.setup() - - running = True - while running: - requests = receiver.check_messages() - if requests: - - for request in requests: - - if "stop" in request: - running = False - logger.debug("stopping async video server") - break - - if "video" in request: - self.video = cattr.structure(request["video"], Video) - logger.debug(f"loaded video: {self.video.filename}") - - if self.video is not None: - if "frames_per_chunk" in request: - - load_time = 0 - send_time = 0 - - per_chunk = request["frames_per_chunk"] - - frame_idxs = request.get( - "frame_idxs", list(range(self.video.frames)) - ) - - frame_count = len(frame_idxs) - chunks = ceil(frame_count / per_chunk) - - for chunk_idx in range(chunks): - start = per_chunk * chunk_idx - end = min(per_chunk * (chunk_idx + 1), frame_count) - chunk_frame_idxs = frame_idxs[start:end] - - # load the frames - t0 = time.time() - frames = self.video[chunk_frame_idxs] - t1 = time.time() - load_time += t1 - t0 - - metadata = dict( - chunk=chunk_idx, - last_chunk=chunks - 1, - frame_idxs=chunk_frame_idxs, - ) - - # send back results - t0 = time.time() - result_sender.send_array(metadata, frames) - t1 = time.time() - send_time += t1 - t0 - - logger.debug(f"returned chunk: {chunk_idx+1}/{chunks}") - - logger.debug(f"total load time: {load_time}") - logger.debug(f"total send time: {send_time}") - else: - logger.warning( - "unable to process message since no video loaded" - ) - logger.warning(request) diff --git a/sleap/io/convert.py b/sleap/io/convert.py index 6e20a05e4..7045ed71f 100644 --- a/sleap/io/convert.py +++ b/sleap/io/convert.py @@ -69,6 +69,8 @@ def create_parser(): default="slp", help="Output format. Default ('slp') is SLEAP dataset; " "'analysis' results in analysis.h5 file; " + "'analysis.nix' results in an analysis nix file;" + "'analysis.csv' results in an analysis csv file;" "'h5' or 'json' results in SLEAP dataset " "with specified file format.", ) @@ -79,14 +81,18 @@ def create_parser(): def default_analysis_filename( - labels: Labels, video: Video, output_path: str, output_prefix: PurePath + labels: Labels, + video: Video, + output_path: str, + output_prefix: PurePath, + format_suffix: str = "h5", ) -> str: video_idx = labels.videos.index(video) vn = PurePath(video.backend.filename) filename = str( PurePath( output_path, - f"{output_prefix}.{video_idx:03}_{vn.stem}.analysis.h5", + f"{output_prefix}.{video_idx:03}_{vn.stem}.analysis.{format_suffix}", ) ) return filename @@ -117,36 +123,72 @@ def main(args: list = None): video_search=video_callback, video=video_path, ) - - if args.format == "analysis": - from sleap.info.write_tracking_h5 import main as write_analysis - - output_paths = [path for path in args.outputs] - - # Generate filenames if user has not specified (enough) output filenames - labels_path = args.input_path - fn = re.sub("(\\.json(\\.zip)?|\\.h5|\\.slp)$", "", labels_path) - fn = PurePath(fn) - default_names = [ - default_analysis_filename( - labels=labels, - video=video, - output_path=str(fn.parent), - output_prefix=str(fn.stem), - ) - for video in labels.videos[len(args.outputs) :] - ] - - output_paths.extend(default_names) - - for video, output_path in zip(labels.videos, output_paths): - write_analysis( - labels, - output_path=output_path, - labels_path=labels_path, - all_frames=True, - video=video, - ) + if "analysis" in args.format: + vids = [] + if len(args.video) > 0: # if a video is specified + for v in labels.videos: # check if it is among the videos in the project + if args.video in v.backend.filename: + vids.append(v) + break + else: + vids = labels.videos # otherwise all videos are converted + + outnames = [path for path in args.outputs] + if len(outnames) < len(vids): + # if there are less outnames provided than videos to convert... + if "nix" in args.format: + out_suffix = "nix" + elif "csv" in args.format: + out_suffix = "csv" + else: + out_suffix = "h5" + fn = args.input_path + fn = re.sub("(\.json(\.zip)?|\.h5|\.slp)$", "", fn) + fn = PurePath(fn) + + for video in vids[len(outnames) :]: + dflt_name = default_analysis_filename( + labels=labels, + video=video, + output_path=str(fn.parent), + output_prefix=str(fn.stem), + format_suffix=out_suffix, + ) + outnames.append(dflt_name) + + if "nix" in args.format: + from sleap.io.format.nix import NixAdaptor + + for video, outname in zip(vids, outnames): + try: + NixAdaptor.write(outname, labels, args.input_path, video) + except ValueError as e: + print(e.args[0]) + + elif "csv" in args.format: + from sleap.info.write_tracking_h5 import main as write_analysis + + for video, output_path in zip(vids, outnames): + write_analysis( + labels, + output_path=output_path, + labels_path=args.input_path, + all_frames=True, + video=video, + csv=True, + ) + + else: + from sleap.info.write_tracking_h5 import main as write_analysis + + for video, output_path in zip(vids, outnames): + write_analysis( + labels, + output_path=output_path, + labels_path=args.input_path, + all_frames=True, + video=video, + ) elif len(args.outputs) > 0: print(f"Output SLEAP dataset: {args.outputs[0]}") diff --git a/sleap/io/dataset.py b/sleap/io/dataset.py index 0b249e227..1b894089f 100644 --- a/sleap/io/dataset.py +++ b/sleap/io/dataset.py @@ -40,6 +40,7 @@ import itertools import os from collections.abc import MutableSequence +from pathlib import Path from typing import ( Callable, List, @@ -52,6 +53,7 @@ Any, Set, Callable, + cast, ) import attr @@ -104,15 +106,17 @@ def update(self, new_frame: Optional[LabeledFrame] = None): """Build (or rebuilds) various caches.""" # Data structures for caching if new_frame is None: - self._lf_by_video = dict() + self._lf_by_video = {video: [] for video in self.labels.videos} self._frame_idx_map = dict() self._track_occupancy = dict() self._frame_count_cache = dict() + # Loop through labeled frames only once + for lf in self.labels: + self._lf_by_video[lf.video].append(lf) + + # Loop through videos a second time after _lf_by_video is created for video in self.labels.videos: - self._lf_by_video[video] = [ - lf for lf in self.labels if lf.video == video - ] self._frame_idx_map[video] = { lf.frame_idx: lf for lf in self._lf_by_video[video] } @@ -191,10 +195,7 @@ def _make_track_occupancy(self, video: Video) -> Dict[Video, RangeList]: def get_track_occupancy(self, video: Video, track: Track) -> RangeList: """Access track occupancy cache that adds video/track as needed.""" - if video not in self._track_occupancy: - self._track_occupancy[video] = dict() - - if track not in self._track_occupancy[video]: + if track not in self.get_video_track_occupancy(video=video): self._track_occupancy[video][track] = RangeList() return self._track_occupancy[video][track] @@ -248,21 +249,18 @@ def track_swap( def add_track(self, video: Video, track: Track): """Add a track to the labels.""" - self._track_occupancy[video][track] = RangeList() + self.get_track_occupancy(video=video, track=track) def add_instance(self, frame: LabeledFrame, instance: Instance): """Add an instance to the labels.""" - if frame.video not in self._track_occupancy: - self._track_occupancy[frame.video] = dict() # Add track in its not already present in labels - if instance.track not in self._track_occupancy[frame.video]: - self._track_occupancy[frame.video][instance.track] = RangeList() - - self._track_occupancy[frame.video][instance.track].insert( - (frame.frame_idx, frame.frame_idx + 1) + track_occupancy = self.get_track_occupancy( + video=frame.video, track=instance.track ) + track_occupancy.insert((frame.frame_idx, frame.frame_idx + 1)) + self.update_counts_for_frame(frame) def remove_instance(self, frame: LabeledFrame, instance: Instance): @@ -298,6 +296,10 @@ def get_filtered_frame_idxs( self, video: Optional[Video] = None, filter: Text = "" ) -> Set[Tuple[int, int]]: """Return list of (video_idx, frame_idx) tuples matching video/filter.""" + if video not in self.labels.videos: + # Set value of video to None if not present in the videos list. + video = None + if filter == "": filter_func = lambda lf: video is None or lf.video == video elif filter == "user": @@ -1242,6 +1244,22 @@ def remove_all_tracks(self): inst.track = None self.tracks = [] + def remove_unused_tracks(self): + """Remove tracks that are not used by any instances.""" + if len(self.tracks) == 0: + return + + # Check which tracks are used by instances + all_tracks = set(self.tracks) + used_tracks = set() + for inst in self.instances(): + used_tracks.add(inst.track) + + # Remove set difference from tracks in Labels + tracks_to_remove = all_tracks - used_tracks + for track in tracks_to_remove: + self.tracks.remove(track) + def track_set_instance( self, frame: LabeledFrame, instance: Instance, new_track: Track ): @@ -1316,8 +1334,12 @@ def add_instance(self, frame: LabeledFrame, instance: Instance): if instance.track in tracks_in_frame: instance.track = None + # Add instance and track to labels frame.instances.append(instance) + if (instance.track is not None) and (instance.track not in self.tracks): + self.add_track(video=frame.video, track=instance.track) + # Update cache self._cache.add_instance(frame, instance) def find_track_occupancy( @@ -2033,6 +2055,19 @@ def export(self, filename: str): SleapAnalysisAdaptor.write(filename, self) + def export_csv(self, filename: str): + """Export labels to CSV format. + + Args: + filename: Output path for the CSV format file. + + Notes: + This will write the contents of the labels out as a CSV file. + """ + from sleap.io.format.csv import CSVAdaptor + + CSVAdaptor.write(filename, self) + def export_nwb( self, filename: str, @@ -2202,7 +2237,12 @@ def from_deepposekit( ) def save_frame_data_imgstore( - self, output_dir: str = "./", format: str = "png", all_labels: bool = False + self, + output_dir: str = "./", + format: str = "png", + all_labeled: bool = False, + suggested: bool = False, + progress_callback: Optional[Callable[[int, int], None]] = None, ) -> List[ImgStoreVideo]: """Write images for labeled frames from all videos to imgstore datasets. @@ -2215,28 +2255,55 @@ def save_frame_data_imgstore( Use "png" for lossless, "jpg" for lossy. Other imgstore formats will probably work as well but have not been tested. - all_labels: Include any labeled frames, not just the frames + all_labeled: Include any labeled frames, not just the frames we'll use for training (i.e., those with `Instance` objects ). + suggested: Include suggested frames even if they do not have instances. + Useful for inference after training. Defaults to `False`. + progress_callback: If provided, this function will be called to report the + progress of the frame data saving. This function should be a callable + of the form: `fn(n, n_total)` where `n` is the number of frames saved so + far and `n_total` is the total number of frames that will be saved. This + is called after each video is processed. If the function has a return + value and it returns `False`, saving will be canceled and the output + deleted. Returns: A list of :class:`ImgStoreVideo` objects with the stored frames. """ + + # Lets gather all the suggestions by video + suggestion_frames_by_video = {video: [] for video in self.videos} + if suggested: + for suggestion in self.suggestions: + suggestion_frames_by_video[suggestion.video].append( + suggestion.frame_idx + ) + # For each label imgstore_vids = [] - for v_idx, v in enumerate(self.videos): - frame_nums = [ - lf.frame_idx - for lf in self.labeled_frames - if v == lf.video and (all_labels or lf.has_user_instances) - ] + total_vids = len(self.videos) + for v_idx, video in enumerate(self.videos): + lfs_v = self.find(video) + frame_nums = { + lf.frame_idx for lf in lfs_v if all_labeled or lf.has_user_instances + } + + if suggested: + frame_nums.update(suggestion_frames_by_video[video]) # Join with "/" instead of os.path.join() since we want # path to work on Windows and Posix systems - frames_filename = output_dir + f"/frame_data_vid{v_idx}" - vid = v.to_imgstore( - path=frames_filename, frame_numbers=frame_nums, format=format + frames_fn = Path(output_dir, f"frame_data_vid{v_idx}") + vid = video.to_imgstore( + path=frames_fn.as_posix(), frame_numbers=frame_nums, format=format ) + if progress_callback is not None: + # Notify update callback. + ret = progress_callback(v_idx, total_vids) + if ret == False: + vid.close() + return [] # Close the video for now vid.close() @@ -2279,23 +2346,30 @@ def save_frame_data_hdf5( Returns: A list of :class:`HDF5Video` objects with the stored frames. """ + + # Lets gather all the suggestions by video + suggestion_frames_by_video = {video: [] for video in self.videos} + if suggested: + for suggestion in self.suggestions: + suggestion_frames_by_video[suggestion.video].append( + suggestion.frame_idx + ) + # Build list of frames to save. vids = [] frame_idxs = [] for video in self.videos: lfs_v = self.find(video) - frame_nums = [ + frame_nums = { lf.frame_idx for lf in lfs_v if all_labeled or (user_labeled and lf.has_user_instances) - ] + } + if suggested: - frame_nums += [ - suggestion.frame_idx - for suggestion in self.suggestions - if suggestion.video == video - ] - frame_nums = sorted(list(set(frame_nums))) + frame_nums.update(suggestion_frames_by_video[video]) + + frame_nums = sorted(list(frame_nums)) vids.append(video) frame_idxs.append(frame_nums) @@ -2401,39 +2475,59 @@ def numpy( This method assumes that instances have tracks assigned and is intended to function primarily for single-video prediction results. """ + + def set_track( + inst: Union[Instance, PredictedInstance], + track: np.ndarray, + return_confidence: bool, + ): + if return_confidence: + if isinstance(inst, PredictedInstance): + track = inst.points_and_scores_array + else: + track[:, :-1] = inst.numpy() + else: + track = inst.numpy() + return track + # Get labeled frames for specified video. - if video is None: - video = 0 - if type(video) == int: - video = self.videos[video] - lfs = self.find(video=video) + try: + if video is None: + video = self.videos[0] + if type(video) == int: + video = self.videos[video] + video = cast(Video, video) # video should now be of type Video + except IndexError as e: + raise IndexError( + f"There are no videos in this project. No points matrix to return." + ) + + lfs: List[LabeledFrame] = self.find(video=video) # Figure out frame index range. - if all_frames: - first_frame, last_frame = 0, video.shape[0] - 1 - else: - first_frame, last_frame = None, None - for lf in lfs: - if first_frame is None: - first_frame = lf.frame_idx - if last_frame is None: - last_frame = lf.frame_idx - first_frame = min(first_frame, lf.frame_idx) - last_frame = max(last_frame, lf.frame_idx) + frame_idxs = [lf.frame_idx for lf in lfs] + frame_idxs.sort() + first_frame = 0 if all_frames else frame_idxs[0] + last_frame = len(video) - 1 if all_frames else frame_idxs[-1] # Figure out the number of tracks based on number of instances in each frame. # - # First, let's check the max number of predicted instances (regardless of + # First, let's check the max number of instances (regardless of # whether they're tracked. - n_preds = 0 - for lf in lfs: - n_preds = max(n_preds, lf.n_predicted_instances) + n_insts = max( + [ + lf.n_user_instances + if lf.n_user_instances > 0 # take user instances over predicted + else lf.n_predicted_instances + for lf in lfs + ] + ) - # Case 1: We don't care about order because there's only 1 instance per frame, - # or we're considering untracked instances. - untracked = untracked or n_preds == 1 + untracked = untracked or n_insts == 1 if untracked: - n_tracks = n_preds + # Case 1: We don't care about order because there's only 1 instance per + # frame, or we're considering untracked instances. + n_tracks = n_insts else: # Case 2: We're considering only tracked instances. n_tracks = len(self.tracks) @@ -2447,21 +2541,20 @@ def numpy( tracks = np.full((n_frames, n_tracks, n_nodes, 2), np.nan, dtype="float32") for lf in lfs: i = lf.frame_idx - first_frame + lf_insts: Union[List[Instance], List[PredictedInstance]] = ( + lf.user_instances if lf.n_user_instances > 0 else lf.predicted_instances + ) # Prefer user labeled instances over predicted if untracked: - for j, inst in enumerate(lf.predicted_instances): - tracks[i, j] = ( - inst.points_and_scores_array - if return_confidence - else inst.numpy() - ) + # Add instances in any order if untracked + for j, inst in enumerate(lf_insts): + tracks[i, j] = set_track(inst, tracks[i, j], return_confidence) else: - for inst in lf.tracked_instances: + # Add instances in track-specific order, ignoring instances w/o a track + for inst in lf_insts: + if inst.track is None: + continue j = self.tracks.index(inst.track) - tracks[i, j] = ( - inst.points_and_scores_array - if return_confidence - else inst.numpy() - ) + tracks[i, j] = set_track(inst, tracks[i, j], return_confidence) return tracks @@ -2495,12 +2588,21 @@ def merge_nodes(self, base_node: str, merge_node: str): inst._fix_array() @classmethod - def make_gui_video_callback(cls, search_paths: Optional[List] = None) -> Callable: - return cls.make_video_callback(search_paths=search_paths, use_gui=True) + def make_gui_video_callback( + cls, + search_paths: Optional[List] = None, + context: Optional[Dict[str, bool]] = None, + ) -> Callable: + return cls.make_video_callback( + search_paths=search_paths, use_gui=True, context=context + ) @classmethod def make_video_callback( - cls, search_paths: Optional[List] = None, use_gui: bool = False + cls, + search_paths: Optional[List] = None, + use_gui: bool = False, + context: Optional[Dict[str, bool]] = None, ) -> Callable: """Create a callback for finding missing videos. @@ -2513,14 +2615,32 @@ def make_video_callback( Args: search_paths: If specified, this is a list of paths where we'll automatically try to find the missing videos. + context: A dictionary containing a "changed_on_load" key with a boolean + value. Used externally to determine if any filenames were updated. Returns: The callback function. """ search_paths = search_paths or [] - - def video_callback(video_list, new_paths=search_paths): + context = context or {} + + def video_callback( + video_list: List[dict], + new_paths: List[str] = search_paths, + context: Optional[Dict[str, bool]] = context, + ): + """Callback to find videos which have been moved (or moved across systems). + + Args: + video_list: A list of serialized `Video` objects stored as nested + dictionaries. + new_paths: A list of paths where we'll autimatically try to find the + missing videos. + context: A dictionary containing a "changed_on_load" key with a boolean + value. Used externally to determine if any filenames were updated. + """ filenames = [item["backend"]["filename"] for item in video_list] + context = context or {"changed_on_load": False} missing = pathutils.list_file_missing(filenames) # Try changing the prefix using saved patterns @@ -2534,6 +2654,7 @@ def video_callback(video_list, new_paths=search_paths): if fixed_path != filename: filenames[i] = fixed_path missing[i] = False + context["changed_on_load"] = True if use_gui: # If there are still missing paths, prompt user @@ -2549,6 +2670,8 @@ def video_callback(video_list, new_paths=search_paths): if not okay: return True # True for stop + context["changed_on_load"] = True + if not use_gui and sum(missing): # If we got the same number of paths as there are videos if len(filenames) == len(new_paths): @@ -2567,6 +2690,10 @@ def video_callback(video_list, new_paths=search_paths): for i, filename in enumerate(filenames): if missing[i]: filenames[i] = new_paths[i] + missing[i] = False + + # Solely for testing since only gui will have a `CommandContext` + context["changed_on_load"] = True # Replace the video filenames with changes by user for i, item in enumerate(video_list): diff --git a/sleap/io/format/coco.py b/sleap/io/format/coco.py index 25122e4d0..44e7fb84a 100644 --- a/sleap/io/format/coco.py +++ b/sleap/io/format/coco.py @@ -180,6 +180,9 @@ def read( if flag == 0: # node not labeled for this instance + if (x, y) != (0, 0): + # If labeled but invisible, place the node at the coord + points[node] = Point(x, y, False) continue is_visible = flag == 2 diff --git a/sleap/io/format/csv.py b/sleap/io/format/csv.py new file mode 100644 index 000000000..4640ee117 --- /dev/null +++ b/sleap/io/format/csv.py @@ -0,0 +1,70 @@ +"""Adaptor for writing SLEAP analysis as csv.""" + +from sleap.io import format + +from sleap import Labels, Video +from typing import Optional, Callable, List, Text, Union + + +class CSVAdaptor(format.adaptor.Adaptor): + FORMAT_ID = 1.0 + + # 1.0 initial implementation + + @property + def handles(self): + return format.adaptor.SleapObjectType.labels + + @property + def default_ext(self): + return "csv" + + @property + def all_exts(self): + return ["csv", "xlsx"] + + @property + def name(self): + return "CSV" + + def can_read_file(self, file: format.filehandle.FileHandle): + return False + + def can_write_filename(self, filename: str): + return self.does_match_ext(filename) + + def does_read(self) -> bool: + return False + + def does_write(self) -> bool: + return True + + @classmethod + def write( + cls, + filename: str, + source_object: Labels, + source_path: str = None, + video: Video = None, + ): + """Writes csv file for :py:class:`Labels` `source_object`. + + Args: + filename: The filename for the output file. + source_object: The :py:class:`Labels` from which to get data from. + source_path: Path for the labels object + video: The :py:class:`Video` from which toget data from. If no `video` is + specified, then the first video in `source_object` videos list will be + used. If there are no :py:class:`Labeled Frame`s in the `video`, then no + analysis file will be written. + """ + from sleap.info.write_tracking_h5 import main as write_analysis + + write_analysis( + labels=source_object, + output_path=filename, + labels_path=source_path, + all_frames=True, + video=video, + csv=True, + ) diff --git a/sleap/io/format/deeplabcut.py b/sleap/io/format/deeplabcut.py index 6ef428a49..5892dba1a 100644 --- a/sleap/io/format/deeplabcut.py +++ b/sleap/io/format/deeplabcut.py @@ -19,10 +19,10 @@ import numpy as np import pandas as pd -from typing import List, Optional +from typing import List, Optional, Dict from sleap import Labels, Video, Skeleton -from sleap.instance import Instance, LabeledFrame, Point +from sleap.instance import Instance, LabeledFrame, Point, Track from sleap.util import find_files_by_suffix from .adaptor import Adaptor, SleapObjectType @@ -119,11 +119,12 @@ def read_frames( # Pull out animal and node names from the columns. start_col = 3 if is_new_format else 1 - animal_names = [] + tracks: Dict[str, Optional[Track]] = {} node_names = [] for animal_name, node_name, _ in data.columns[start_col:][::2]: - if animal_name not in animal_names: - animal_names.append(animal_name) + # Keep the starting frame index for each individual/track + if animal_name not in tracks.keys(): + tracks[animal_name] = None if node_name not in node_names: node_names.append(node_name) @@ -177,23 +178,33 @@ def read_frames( instances = [] if is_multianimal: - for animal_name in animal_names: + for animal_name in tracks.keys(): any_not_missing = False # Get points for each node. instance_points = dict() for node in node_names: - x, y = ( - data[(animal_name, node, "x")][i], - data[(animal_name, node, "y")][i], - ) + if (animal_name, node) in data.columns: + x, y = ( + data[(animal_name, node, "x")][i], + data[(animal_name, node, "y")][i], + ) + else: + x, y = np.nan, np.nan instance_points[node] = Point(x, y) if ~(np.isnan(x) and np.isnan(y)): any_not_missing = True if any_not_missing: + # Create track + if tracks[animal_name] is None: + tracks[animal_name] = Track(spawned_on=i, name=animal_name) # Create instance with points. instances.append( - Instance(skeleton=skeleton, points=instance_points) + Instance( + skeleton=skeleton, + points=instance_points, + track=tracks[animal_name], + ) ) else: # Get points for each node. @@ -268,7 +279,12 @@ def read( # Create skeleton which we'll use for each video skeleton = Skeleton() - skeleton.add_nodes(project_data["bodyparts"]) + if project_data.get("multianimalbodyparts", False): + skeleton.add_nodes(project_data["multianimalbodyparts"]) + if "uniquebodyparts" in project_data: + skeleton.add_nodes(project_data["uniquebodyparts"]) + else: + skeleton.add_nodes(project_data["bodyparts"]) # Get subdirectories of videos and labeled data root_dir = os.path.dirname(filename) @@ -295,13 +311,24 @@ def read( # If subdirectory is foo, we look for foo.mp4 in videos dir. shortname = os.path.split(data_subdir)[-1] - video_path = os.path.join(videos_dir, f"{shortname}.mp4") - - if os.path.exists(video_path): + video_path = None + if os.path.exists(videos_dir): + with os.scandir(videos_dir) as file_iterator: + for file in file_iterator: + if not file.is_file(): + continue + if os.path.splitext(file.name)[0] != shortname: + continue + video_path = os.path.join(videos_dir, file.name) + break + + if video_path is not None and os.path.exists(video_path): video = Video.from_filename(video_path) else: # When no video is found, the individual frame images # stored in the labeled data subdir will be used. + if video_path is None: + video_path = os.path.join(videos_dir, f"{shortname}.mp4") print( f"Unable to find {video_path} so using individual frame images." ) diff --git a/sleap/io/format/dispatch.py b/sleap/io/format/dispatch.py index e4803a87d..43f879627 100644 --- a/sleap/io/format/dispatch.py +++ b/sleap/io/format/dispatch.py @@ -5,6 +5,7 @@ """ import attr +from pathlib import Path from typing import List, Optional, Tuple, Union from sleap.io.format.adaptor import Adaptor, SleapObjectType @@ -77,7 +78,9 @@ def write(self, filename: str, source_object: object, *args, **kwargs): if adaptor.can_write_filename(filename): return adaptor.write(filename, source_object, *args, **kwargs) - raise TypeError("No file format adaptor could write this file.") + raise TypeError( + f"No file format adaptor could write this file: {Path(filename).name}." + ) def write_safely(self, *args, **kwargs) -> Optional[BaseException]: """Wrapper for writing file without throwing exception.""" diff --git a/sleap/io/format/hdf5.py b/sleap/io/format/hdf5.py index 353f88e3a..55a30d74f 100644 --- a/sleap/io/format/hdf5.py +++ b/sleap/io/format/hdf5.py @@ -81,7 +81,10 @@ def read_headers( # Extract the Labels JSON metadata and create Labels object with just this # metadata. - dicts = json_loads(f.require_group("metadata").attrs["json"].tobytes().decode()) + json = f.require_group("metadata").attrs["json"] + if not isinstance(json, str): + json = json.tobytes().decode() + dicts = json_loads(json) # These items are stored in separate lists because the metadata group got to be # too big. @@ -151,6 +154,45 @@ def read( points_dset[:]["x"] -= 0.5 points_dset[:]["y"] -= 0.5 + def cast_as_compound(arr, dtype): + out = np.empty(shape=(len(arr),), dtype=dtype) + if out.size == 0: + return out + for i, (name, _) in enumerate(dtype): + out[name] = arr[:, i] + return out + + # cast points, instances, and frames into complex dtype if not already + dtype_points = [("x", " List[str]: + return [self.default_ext] + + @property + def handles(self): + return SleapObjectType.misc + + @property + def name(self) -> str: + """Human-reading name of the file format""" + return ( + "NIX file flavoured for animal tracking data https://github.com/g-node/nix" + ) + + @classmethod + def can_read_file(cls, file: FileHandle) -> bool: + """Returns whether this adaptor can read this file.""" + return False + + def can_write_filename(self, filename: str) -> bool: + """Returns whether this adaptor can write format of this filename.""" + return filename.endswith(tuple(self.all_exts)) + + @classmethod + def does_read(cls) -> bool: + """Returns whether this adaptor supports reading.""" + return False + + @classmethod + def does_write(cls) -> bool: + """Returns whether this adaptor supports writing.""" + return True + + @classmethod + def read(cls, file: FileHandle) -> object: + """Reads the file and returns the appropriate deserialized object.""" + raise NotImplementedError("NixAdaptor does not support reading.") + + @classmethod + def __check_video(cls, labels: Labels, video: Optional[Video]): + if (video is None) and (len(labels.videos) == 0): + raise ValueError( + f"There are no videos in this project. " + "No analysis file will be be written." + ) + if video is not None: + if video not in labels.videos: + raise ValueError( + f"Specified video {video} is not part of this project. " + "Skipping the analysis file for this video." + ) + if len(labels.get(video)) == 0: + raise ValueError( + f"No labeled frames in {video.backend.filename}. " + "Skipping the analysis file for this video." + ) + + @classmethod + def write( + cls, + filename: str, + source_object: object, + source_path: Optional[str] = None, + video: Optional[Video] = None, + ): + """Writes the object to a file.""" + source_object = cast(Labels, source_object) + + cls.__check_video(source_object, video) + + def create_file(filename: str, project: Optional[str], video: Video): + print(f"Creating nix file...", end="\t") + nf = nix.File.open(filename, nix.FileMode.Overwrite) + try: + s = nf.create_section("TrackingAnalysis", "nix.tracking.metadata") + s["version"] = "0.1.0" + s["format"] = "nix.tracking" + s["definitions"] = "https://github.com/bendalab/nixtrack" + s["writer"] = str(cls)[8:-2] + if project is not None: + s["project"] = project + + name = Path(video.backend.filename).name + b = nf.create_block(name, "nix.tracking_results") + + # add video metadata, if exists + src = b.create_source(name, "nix.tracking.source.video") + sec = src.file.create_section( + name, "nix.tracking.source.video.metadata" + ) + sec["filename"] = video.backend.filename + sec["fps"] = getattr(video.backend, "fps", 0.0) + sec.props["fps"].unit = "Hz" + sec["frames"] = video.num_frames + sec["grayscale"] = getattr(video.backend, "grayscale", None) + sec["height"] = video.backend.height + sec["width"] = video.backend.width + src.metadata = sec + except Exception as e: + nf.close() + raise e + + print("done") + return nf + + def track_map(source: Labels) -> Dict[Track, int]: + track_map: Dict[Track, int] = {} + for track in source.tracks: + if track in track_map: + continue + track_map[track] = len(track_map) + return track_map + + def skeleton_map(source: Labels) -> Dict[Skeleton, int]: + skel_map: Dict[Skeleton, int] = {} + for skeleton in source.skeletons: + if skeleton in skel_map: + continue + skel_map[skeleton] = len(skel_map) + return skel_map + + def node_map(source: Labels) -> Dict[Node, int]: + n_map: Dict[Node, int] = {} + for node in source.nodes: + if node in n_map: + continue + n_map[node] = len(n_map) + return n_map + + def create_feature_array(name, type, block, frame_index_array, shape, dtype): + array = block.create_data_array(name, type, dtype=dtype, shape=shape) + rd = array.append_range_dimension() + rd.link_data_array(frame_index_array, [-1]) + return array + + def create_positions_array( + name, type, block, frame_index_array, node_names, shape, dtype + ): + array = block.create_data_array( + name, type, dtype=dtype, shape=shape, label="pixel" + ) + rd = array.append_range_dimension() + rd.link_data_array(frame_index_array, [-1]) + array.append_set_dimension(["x", "y"]) + array.append_set_dimension(node_names) + return array + + def chunked_write( + instances, + frameid_array, + positions_array, + track_array, + skeleton_array, + pointscore_array, + instancescore_array, + trackingscore_array, + centroid_array, + track_map, + node_map, + skeleton_map, + chunksize=10000, + ): + data_written = 0 + indices = np.zeros(chunksize, dtype=int) + track = np.zeros_like(indices) + skeleton = np.zeros_like(indices) + instscore = np.zeros_like(indices, dtype=float) + positions = np.zeros((chunksize, 2, len(node_map.keys())), dtype=float) + centroids = np.zeros((chunksize, 2), dtype=float) + trackscore = np.zeros_like(instscore) + pointscore = np.zeros((chunksize, len(node_map.keys())), dtype=float) + dflt_pointscore = [0.0 for n in range(len(node_map.keys()))] + + while data_written < len(instances): + print(".", end="") + start = data_written + end = ( + len(instances) + if start + chunksize >= len(instances) + else start + chunksize + ) + for i in range(start, end): + inst = instances[i] + index = i - start + indices[index] = inst.frame_idx + if inst.track is not None: + track[index] = track_map[inst.track] + else: + track[index] = -1 + + skeleton[index] = skeleton_map[inst.skeleton] + + all_nodes = set([n.name for n in inst.nodes]) + used_nodes = set([n.name for n in node_map.keys()]) + missing_nodes = all_nodes.difference(used_nodes) + for n, p in zip(inst.nodes, inst.points): + positions[index, :, node_map[n]] = np.array([p.x, p.y]) + for m in missing_nodes: + positions[index, :, node_map[m]] = np.array([np.nan, np.nan]) + + centroids[index, :] = inst.centroid + if hasattr(inst, "score"): + instscore[index] = inst.score + trackscore[index] = inst.tracking_score + pointscore[index, :] = inst.scores + else: + instscore[index] = 0.0 + trackscore[index] = 0.0 + pointscore[index, :] = dflt_pointscore + + frameid_array[start:end] = indices[: end - start] + track_array[start:end] = track[: end - start] + positions_array[start:end, :, :] = positions[: end - start, :, :] + centroid_array[start:end, :] = centroids[: end - start, :] + skeleton_array[start:end] = skeleton[: end - start] + pointscore_array[start:end] = pointscore[: end - start] + instancescore_array[start:end] = instscore[: end - start] + trackingscore_array[start:end] = trackscore[: end - start] + data_written += end - start + + def write_data(block, source: Labels, video: Video): + instances = [ + instance + for instance in source.instances(video=video) + if instance.frame_idx is not None + ] + instances = sorted(instances, key=lambda i: i.frame_idx) + nodes = node_map(source) + tracks = track_map(source) + skeletons = skeleton_map(source) + positions_shape = (len(instances), 2, len(nodes)) + + frameid_array = block.create_data_array( + "frame", + "nix.tracking.instance_frameidx", + label="frame index", + shape=(len(instances),), + dtype=nix.DataType.Int64, + ) + frameid_array.append_range_dimension_using_self() + + positions_array = create_positions_array( + "position", + "nix.tracking.instance_position", + block, + frameid_array, + [node.name for node in nodes.keys()], + positions_shape, + nix.DataType.Float, + ) + + track_array = create_feature_array( + "track", + "nix.tracking.instance_track", + block, + frameid_array, + shape=(len(instances),), + dtype=nix.DataType.Int64, + ) + + skeleton_array = create_feature_array( + "skeleton", + "nix.tracking.instance_skeleton", + block, + frameid_array, + (len(instances),), + nix.DataType.Int64, + ) + + point_score = create_feature_array( + "node score", + "nix.tracking.nodes_score", + block, + frameid_array, + (len(instances), len(nodes)), + nix.DataType.Float, + ) + point_score.append_set_dimension([node.name for node in nodes.keys()]) + + centroid_array = create_feature_array( + "centroid", + "nix.tracking.centroid_position", + block, + frameid_array, + (len(instances), 2), + nix.DataType.Float, + ) + + centroid_array.append_set_dimension(["x", "y"]) + instance_score = create_feature_array( + "instance score", + "nix.tracking.instance_score", + block, + frameid_array, + (len(instances),), + nix.DataType.Float, + ) + + tracking_score = create_feature_array( + "tracking score", + "nix.tracking.tack_score", + block, + frameid_array, + (len(instances),), + nix.DataType.Float, + ) + + # bind all together using a nix.MultiTag + mtag = block.create_multi_tag( + "tracking results", "nix.tracking.results", positions=frameid_array + ) + mtag.references.append(positions_array) + mtag.create_feature(track_array, nix.LinkType.Indexed) + mtag.create_feature(skeleton_array, nix.LinkType.Indexed) + mtag.create_feature(point_score, nix.LinkType.Indexed) + mtag.create_feature(instance_score, nix.LinkType.Indexed) + mtag.create_feature(tracking_score, nix.LinkType.Indexed) + mtag.create_feature(centroid_array, nix.LinkType.Indexed) + + sm = block.create_data_frame( + "skeleton map", + "nix.tracking.skeleton_map", + col_names=["name", "index"], + col_dtypes=[nix.DataType.String, nix.DataType.Int8], + ) + table_data = [] + for track in skeletons.keys(): + table_data.append((track.name, skeletons[track])) + sm.append_rows(table_data) + + nm = block.create_data_frame( + "node map", + "nix.tracking.node_map", + col_names=["name", "weight", "index", "skeleton"], + col_dtypes=[ + nix.DataType.String, + nix.DataType.Float, + nix.DataType.Int8, + nix.DataType.Int8, + ], + ) + table_data = [] + for node in nodes.keys(): + skel_index = -1 # if node is not assigned to a skeleton + for track in skeletons: + if node in track.nodes: + skel_index = skeletons[track] + break + table_data.append((node.name, node.weight, nodes[node], skel_index)) + nm.append_rows(table_data) + + tm = block.create_data_frame( + "track map", + "nix.tracking.track_map", + col_names=["name", "spawned_on", "index"], + col_dtypes=[nix.DataType.String, nix.DataType.Int64, nix.DataType.Int8], + ) + table_data = [("none", -1, -1)] # default for user-labeled instances + for track in tracks.keys(): + table_data.append((track.name, track.spawned_on, tracks[track])) + tm.append_rows(table_data) + + # Print shape info + data_dict = { + "instances": instances, + "frameid_array": frameid_array, + "positions_array": positions_array, + "track_array": track_array, + "skeleton_array": skeleton_array, + "point_score": point_score, + "instance_score": instance_score, + "tracking_score": tracking_score, + "centroid_array": centroid_array, + "tracks": tracks, + "nodes": nodes, + "skeletons": skeletons, + } + for key, val in data_dict.items(): + print(f"\t{key}:", end=" ") + if hasattr(val, "shape"): + print(f"{val.shape}") + else: + print(f"{len(val)}") + + # Print labels/video info + print( + f"\tlabels path: {source_path}\n" + f"\tvideo path: {video.backend.filename}\n" + f"\tvideo index = {source_object.videos.index(video)}" + ) + + print(f"Writing to NIX file...") + chunked_write( + instances, + frameid_array, + positions_array, + track_array, + skeleton_array, + point_score, + instance_score, + tracking_score, + centroid_array, + tracks, + nodes, + skeletons, + ) + print(f"done") + + print(f"\nExporting to NIX analysis file...") + if video is None: + video = source_object.videos[0] + print(f"No video specified, exporting the first one...") + + nix_file = None + try: + nix_file = create_file(filename, source_path, video) + write_data(nix_file.blocks[0], source_object, video) + print(f"Saved as {filename}") + except Exception as e: + print(f"\n\tWriting failed with following error:\n{e}!") + finally: + if nix_file is not None: + nix_file.close() diff --git a/sleap/io/format/sleap_analysis.py b/sleap/io/format/sleap_analysis.py index cc6eedb6f..b25ac39d7 100644 --- a/sleap/io/format/sleap_analysis.py +++ b/sleap/io/format/sleap_analysis.py @@ -78,7 +78,7 @@ def read( # shape: frames * nodes * 2 * tracks frame_count, node_count, _, track_count = tracks_matrix.shape - if "track_names" in f: + if "track_names" in f and len(f["track_names"]): track_names_list = f["track_names"][:].T tracks = [Track(0, track_name.decode()) for track_name in track_names_list] else: diff --git a/sleap/io/video.py b/sleap/io/video.py index 35e80c581..c8272cfbd 100644 --- a/sleap/io/video.py +++ b/sleap/io/video.py @@ -63,6 +63,8 @@ class HDF5Video: convert_range: Whether we should convert data to [0, 255]-range """ + EXTS = ("h5", "hdf5", "slp") + filename: str = attr.ib(default=None) dataset: str = attr.ib(default=None) input_format: str = attr.ib(default="channels_last") @@ -349,6 +351,8 @@ class MediaVideo: bgr: Whether color channels ordered as (blue, green, red). """ + EXTS = ("mp4", "avi", "mov", "mj2", "mkv") + filename: str = attr.ib() grayscale: bool = attr.ib() bgr: bool = attr.ib(default=True) @@ -514,6 +518,8 @@ class NumpyVideo: * numpy data shape: (frames, height, width, channels) """ + EXTS = ("npy", "npz") + filename: Union[str, np.ndarray] = attr.ib() def __attrs_post_init__(self): @@ -603,8 +609,7 @@ def is_missing(self) -> bool: @attr.s(auto_attribs=True, eq=False, order=False) class ImgStoreVideo: - """ - Video data stored as an ImgStore dataset. + """Video data stored as an ImgStore dataset. See: https://github.com/loopbio/imgstore This class is just a lightweight wrapper for reading such datasets as @@ -622,6 +627,8 @@ class ImgStoreVideo: indices on :class:`LabeledFrame` objects in the dataset. """ + EXTS = ("json", "yaml") + filename: str = attr.ib(default=None) index_by_original: bool = attr.ib(default=True) _store_ = None @@ -801,6 +808,9 @@ class SingleImageVideo: filenames: Files to load as video. """ + EXTS = ("jpg", "jpeg", "png", "tif", "tiff") + CACHING = False # Deprecated, but keeping functionality for now. + filename: Optional[str] = attr.ib(default=None) filenames: Optional[List[str]] = attr.ib(factory=list) height_: Optional[int] = attr.ib(default=None) @@ -816,7 +826,7 @@ def __attrs_post_init__(self): elif self.filename and not self.filenames: self.filenames = [self.filename] - self.__data = dict() + self.cache_ = dict() self.test_frame_ = None @grayscale.default @@ -846,20 +856,24 @@ def _get_filename(self, idx: int) -> str: raise FileNotFoundError(f"Unable to locate file {idx}: {self.filenames[idx]}") def _load_test_frame(self): - if self.test_frame_ is None: - self.test_frame_ = self._load_idx(0) + test_frame_ = self.test_frame_ + if test_frame_ is None: + test_frame_ = self._load_idx(0) if self._detect_grayscale is True: self.grayscale = bool( - np.alltrue(self.test_frame_[..., 0] == self.test_frame_[..., -1]) + np.alltrue(test_frame_[..., 0] == test_frame_[..., -1]) ) if self.height_ is None: - self.height_ = self.test_frame.shape[0] + self.height_ = test_frame_.shape[0] if self.width_ is None: - self.width_ = self.test_frame.shape[1] + self.width_ = test_frame_.shape[1] if self.channels_ is None: - self.channels_ = self.test_frame.shape[2] + self.channels_ = test_frame_.shape[2] + if self.CACHING: # Deprecated, but keeping functionality for now. + self.test_frame_ = test_frame_ + return test_frame_ def get_idx_from_filename(self, filename: str) -> int: try: @@ -872,8 +886,7 @@ def get_idx_from_filename(self, filename: str) -> int: @property def test_frame(self) -> np.ndarray: - self._load_test_frame() - return self.test_frame_ + return self._load_test_frame() def matches(self, other: "SingleImageVideo") -> bool: """ @@ -929,7 +942,7 @@ def height(self, val): @property def dtype(self): """See :class:`Video`.""" - return self.__data.dtype + return self.cache_.dtype def reset( self, @@ -946,7 +959,7 @@ def reset( f"Cannot specify both filename and filenames for SingleImageVideo." ) elif filename or filenames: - self.__data = dict() + self.cache_ = dict() self.test_frame_ = None self.height_ = height_ self.width_ = width_ @@ -967,10 +980,13 @@ def reset( def get_frame(self, idx: int, grayscale: bool = None) -> np.ndarray: """See :class:`Video`.""" - if idx not in self.__data: - self.__data[idx] = self._load_idx(idx) + if self.CACHING: # Deprecated, but keeping functionality for now. + if idx not in self.cache_: + self.cache_[idx] = self._load_idx(idx) - frame = self.__data[idx] # Manipulate a copy of self.__data[idx] + frame = self.cache_[idx] # Manipulate a copy of self.__data[idx] + else: + frame = self._load_idx(idx) if grayscale is None: grayscale = self.grayscale @@ -1102,8 +1118,9 @@ def get_frames(self, idxs: Union[int, Iterable[int]]) -> np.ndarray: def get_frames_safely(self, idxs: Iterable[int]) -> Tuple[List[int], np.ndarray]: """Return list of frame indices and frames which were successfully loaded. + Args: + idxs: An iterable object that contains the indices of frames. - idxs: An iterable object that contains the indices of frames. Returns: A tuple of (frame indices, frames), where * frame indices is a subset of the specified idxs, and @@ -1245,17 +1262,21 @@ def from_filename(cls, filename: str, *args, **kwargs) -> "Video": """ filename = Video.fixup_path(filename) - if filename.lower().endswith(("h5", "hdf5", "slp")): + if filename.lower().endswith(HDF5Video.EXTS): backend_class = HDF5Video - elif filename.endswith(("npy")): + elif filename.endswith(NumpyVideo.EXTS): backend_class = NumpyVideo - elif filename.lower().endswith(("mp4", "avi", "mov")): + elif filename.lower().endswith(MediaVideo.EXTS): backend_class = MediaVideo kwargs["dataset"] = "" # prevent serialization from breaking elif os.path.isdir(filename) or "metadata.yaml" in filename: backend_class = ImgStoreVideo + elif filename.lower().endswith(SingleImageVideo.EXTS): + backend_class = SingleImageVideo else: - raise ValueError("Could not detect backend for specified filename.") + raise ValueError( + f"Could not detect backend for specified filename: {filename}" + ) kwargs["filename"] = filename @@ -1422,19 +1443,31 @@ def to_hdf5( def encode(img): _, encoded = cv2.imencode("." + format, img) - return np.squeeze(encoded) + return np.squeeze(encoded).astype("int8") + + # pad with zeroes to guarantee int8 type in hdf5 file + frames = [] + for i in range(len(frame_numbers)): + frames.append(encode(frame_data[i])) + + max_frame_size = ( + max([len(x) if len(x) else 0 for x in frames]) if len(frames) else 0 + ) - dtype = h5.special_dtype(vlen=np.dtype("int8")) dset = f.create_dataset( - dataset + "/video", (len(frame_numbers),), dtype=dtype + dataset + "/video", + (len(frame_numbers), max_frame_size), + dtype="int8", + compression="gzip", ) dset.attrs["format"] = format dset.attrs["channels"] = self.channels dset.attrs["height"] = self.height dset.attrs["width"] = self.width - for i in range(len(frame_numbers)): - dset[i] = encode(frame_data[i]) + for i, frame in enumerate(frames): + dset[i, 0 : len(frame)] = frame + else: f.create_dataset( dataset + "/video", @@ -1512,22 +1545,17 @@ def cattr(): A cattr converter. """ - # When we are structuring video backends, try to fixup the video file paths - # in case they are coming from a different computer or the file has been moved. - def fixup_video(x, cl): - if "filename" in x: - x["filename"] = Video.fixup_path(x["filename"]) - if "file" in x: - x["file"] = Video.fixup_path(x["file"]) + # Use from_filename to fixup the video path and determine backend + def fixup_video(x: dict, cl: Video): + backend_dict = x.pop("backend") + filename = backend_dict.pop("filename", None) or backend_dict.pop( + "file", None + ) - return Video.make_specific_backend(cl, x) + return Video.from_filename(filename, **backend_dict) vid_cattr = cattr.Converter() - - # Check the type hint for backend and register the video path - # fixup hook for each type in the Union. - for t in attr.fields(Video).backend.type.__args__: - vid_cattr.register_structure_hook(t, fixup_video) + vid_cattr.register_structure_hook(Video, fixup_video) return vid_cattr @@ -1592,11 +1620,27 @@ def fixup_path( return path +def available_video_exts() -> Tuple[str]: + """Return tuple of supported video extensions. + + Returns: + Tuple of supported video extensions. + """ + return ( + MediaVideo.EXTS + + HDF5Video.EXTS + + NumpyVideo.EXTS + + SingleImageVideo.EXTS + + ImgStoreVideo.EXTS + ) + + def load_video( filename: str, grayscale: Optional[bool] = None, dataset=Optional[None], channels_first: bool = False, + **kwargs, ) -> Video: """Open a video from disk. @@ -1632,7 +1676,6 @@ def load_video( See also: sleap.io.video.Video """ - kwargs = {} if grayscale is not None: kwargs["grayscale"] = grayscale if dataset is not None: diff --git a/sleap/io/videowriter.py b/sleap/io/videowriter.py index 6e670a5bd..cd710c9d5 100644 --- a/sleap/io/videowriter.py +++ b/sleap/io/videowriter.py @@ -12,6 +12,7 @@ from abc import ABC, abstractmethod import cv2 import numpy as np +import imageio.v2 as iio class VideoWriter(ABC): @@ -32,22 +33,26 @@ def close(self): @staticmethod def safe_builder(filename, height, width, fps): """Builds VideoWriter based on available dependencies.""" - if VideoWriter.can_use_skvideo(): - return VideoWriterSkvideo(filename, height, width, fps) + if VideoWriter.can_use_ffmpeg(): + return VideoWriterImageio(filename, height, width, fps) else: return VideoWriterOpenCV(filename, height, width, fps) @staticmethod - def can_use_skvideo(): - # See if we can import skvideo + def can_use_ffmpeg(): + """Check if ffmpeg is available for writing videos.""" try: - import skvideo + import imageio_ffmpeg as ffmpeg except ImportError: return False - # See if skvideo can find FFMPEG - if skvideo.getFFmpegVersion() != "0.0.0": - return True + try: + # Try to get the version of the ffmpeg plugin + ffmpeg_version = ffmpeg.get_ffmpeg_version() + if ffmpeg_version: + return True + except Exception: + return False return False @@ -68,11 +73,11 @@ def close(self): self._writer.release() -class VideoWriterSkvideo(VideoWriter): - """Writes video using scikit-video as wrapper for ffmpeg. +class VideoWriterImageio(VideoWriter): + """Writes video using imageio as a wrapper for ffmpeg. Attributes: - filename: Path to mp4 file to save to. + filename: Path to video file to save to. height: Height of movie frames. width: Width of movie frames. fps: Playback framerate to save at. @@ -85,27 +90,38 @@ class VideoWriterSkvideo(VideoWriter): def __init__( self, filename, height, width, fps, crf: int = 21, preset: str = "superfast" ): - import skvideo.io - - fps = str(fps) - self._writer = skvideo.io.FFmpegWriter( + self.filename = filename + self.height = height + self.width = width + self.fps = fps + self.crf = crf + self.preset = preset + + import imageio_ffmpeg as ffmpeg + + # Imageio's ffmpeg writer parameters + # https://imageio.readthedocs.io/en/stable/examples.html#writing-videos-with-ffmpeg-and-vaapi + # Use `ffmpeg -h encoder=libx264`` to see all options for libx264 output_params + # output_params must be a list of strings + # iio.help(name='FFMPEG') to test + self.writer = iio.get_writer( filename, - inputdict={ - "-r": fps, - }, - outputdict={ - "-c:v": "libx264", - "-preset": preset, - "-framerate": fps, - "-crf": str(crf), - "-pix_fmt": "yuv420p", - }, + fps=fps, + codec="libx264", + format="FFMPEG", + pixelformat="yuv420p", + output_params=[ + "-preset", + preset, + "-crf", + str(crf), + ], ) def add_frame(self, img, bgr: bool = False): if bgr: img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) - self._writer.writeFrame(img) + self.writer.append_data(img) def close(self): - self._writer.close() + self.writer.close() diff --git a/sleap/io/visuals.py b/sleap/io/visuals.py index 7c46191c7..f2dde0be3 100644 --- a/sleap/io/visuals.py +++ b/sleap/io/visuals.py @@ -27,7 +27,13 @@ _sentinel = object() -def reader(out_q: Queue, video: Video, frames: List[int], scale: float = 1.0): +def reader( + out_q: Queue, + video: Video, + frames: List[int], + scale: float = 1.0, + background: str = "original", +): """Read frame images from video and send them into queue. Args: @@ -36,11 +42,13 @@ def reader(out_q: Queue, video: Video, frames: List[int], scale: float = 1.0): video: The `Video` object to read. frames: Full list frame indexes we want to read. scale: Output scale for frame images. + background: output video background. Either original, black, white, grey Returns: None. """ + background = background.lower() cv2.setNumThreads(usable_cpu_count()) total_count = len(frames) @@ -64,6 +72,16 @@ def reader(out_q: Queue, video: Video, frames: List[int], scale: float = 1.0): loaded_chunk_idxs, video_frame_images = video.get_frames_safely( frames_idx_chunk ) + if background != "original": + # fill the frame with the color + fill_values = {"black": 0, "grey": 127, "white": 255} + try: + fill = fill_values[background] + except KeyError: + raise ValueError( + f"Invalid background color: {background}. Options include: {', '.join(fill_values.keys())}" + ) + video_frame_images = video_frame_images * 0 + fill if not loaded_chunk_idxs: print(f"No frames could be loaded from chunk {chunk_i}") @@ -176,8 +194,12 @@ def __init__( video_idx: int, scale: float, show_edges: bool = True, + edge_is_wedge: bool = False, + marker_size: int = 4, crop_size_xy: Optional[Tuple[int, int]] = None, color_manager: Optional[ColorManager] = None, + palette: str = "standard", + distinctly_color: str = "instances", ): super(VideoMarkerThread, self).__init__() self.in_q = in_q @@ -186,10 +208,12 @@ def __init__( self.video_idx = video_idx self.scale = scale self.show_edges = show_edges + self.edge_is_wedge = edge_is_wedge if color_manager is None: - color_manager = ColorManager(labels=labels) + color_manager = ColorManager(labels=labels, palette=palette) color_manager.color_predicted = True + color_manager.distinctly_color = distinctly_color self.color_manager = color_manager @@ -201,8 +225,7 @@ def __init__( self.node_line_width = max(1, self.node_line_width // 2) self.edge_line_width = max(1, self.node_line_width // 2) - unscaled_marker_radius = 3 - self.marker_radius = max(1, int(unscaled_marker_radius // (1 / scale))) + self.marker_radius = max(1, int(marker_size // (1 / scale))) self.edge_line_width *= 2 self.marker_radius *= 2 @@ -448,15 +471,40 @@ def _plot_instance_cv( src_x, src_y = int(src_x), int(src_y) dst_x, dst_y = int(dst_x), int(dst_y) - # Draw line to mark edge between nodes - cv2.line( - img=img, - pt1=(src_x, src_y), - pt2=(dst_x, dst_y), - color=edge_color_bgr, - thickness=int(self.edge_line_width), - lineType=cv2.LINE_AA, - ) + if self.edge_is_wedge: + r = self.marker_radius / 2 + + # Get vector from source to destination + vec_x = dst_x - src_x + vec_y = dst_y - src_y + mag = (pow(vec_x, 2) + pow(vec_y, 2)) ** 0.5 + vec_x = int(r * vec_x / mag) + vec_y = int(r * vec_y / mag) + + # Define the wedge + src_1 = [src_x - vec_y, src_y + vec_x] + dst = [dst_x, dst_y] + src_2 = [src_x + vec_y, src_y - vec_x] + pts = np.array([src_1, dst, src_2]) + + # Draw the wedge + cv2.fillPoly( + img=img, + pts=[pts], + color=edge_color_bgr, + lineType=cv2.LINE_AA, + ) + + else: + # Draw line to mark edge between nodes + cv2.line( + img=img, + pt1=(src_x, src_y), + pt2=(dst_x, dst_y), + color=edge_color_bgr, + thickness=int(self.edge_line_width), + lineType=cv2.LINE_AA, + ) def save_labeled_video( @@ -467,8 +515,13 @@ def save_labeled_video( fps: int = 15, scale: float = 1.0, crop_size_xy: Optional[Tuple[int, int]] = None, + background: str = "original", show_edges: bool = True, + edge_is_wedge: bool = False, + marker_size: int = 4, color_manager: Optional[ColorManager] = None, + palette: str = "standard", + distinctly_color: str = "instances", gui_progress: bool = False, ): """Function to generate and save video with annotations. @@ -481,9 +534,16 @@ def save_labeled_video( fps: Frames per second for output video. scale: scale of image (so we can scale point locations to match) crop_size_xy: size of crop around instances, or None for full images + background: output video background. Either original, black, white, grey show_edges: whether to draw lines between nodes + edge_is_wedge: whether to draw edges as wedges (draw as line if False) + marker_size: Size of marker in pixels before scaling by `scale` color_manager: ColorManager object which determine what colors to use for what instance/node/edge + palette: SLEAP color palette to use. Options include: "alphabet", "five+", + "solarized", or "standard". Only used if `color_manager` is None. + distinctly_color: Specify how to color instances. Options include: "instances", + "edges", and "nodes". Only used if `color_manager` is None. gui_progress: Whether to show Qt GUI progress dialog. Returns: @@ -497,7 +557,7 @@ def save_labeled_video( q2 = Queue(maxsize=10) progress_queue = Queue() - thread_read = Thread(target=reader, args=(q1, video, frames, scale)) + thread_read = Thread(target=reader, args=(q1, video, frames, scale, background)) thread_mark = VideoMarkerThread( in_q=q1, out_q=q2, @@ -505,8 +565,12 @@ def save_labeled_video( video_idx=labels.videos.index(video), scale=scale, show_edges=show_edges, + edge_is_wedge=edge_is_wedge, + marker_size=marker_size, crop_size_xy=crop_size_xy, color_manager=color_manager, + palette=palette, + distinctly_color=distinctly_color, ) thread_write = Thread( target=writer, @@ -610,7 +674,55 @@ def main(args: list = None): "a range separated by hyphen (e.g. 1-3). (default is entire video)", ) parser.add_argument( - "--video-index", type=int, default=0, help="Index of video in labels dataset" + "--video-index", + type=int, + default=0, + help="Index of video in labels dataset (default: 0)", + ) + parser.add_argument( + "--show_edges", + type=int, + default=1, + help="Whether to draw lines between nodes (default: 1)", + ) + parser.add_argument( + "--edge_is_wedge", + type=int, + default=0, + help="Whether to draw edges as wedges (default: 0)", + ) + parser.add_argument( + "--marker_size", + type=int, + default=4, + help="Size of marker in pixels before scaling by `scale` (default: 4)", + ) + parser.add_argument( + "--palette", + type=str, + default="standard", + help=( + "SLEAP color palette to use Options include: 'alphabet', 'five+', " + "'solarized', or 'standard' (default: 'standard')" + ), + ) + parser.add_argument( + "--distinctly_color", + type=str, + default="instances", + help=( + "Specify how to color instances. Options include: 'instances', 'edges', " + "and 'nodes' (default: 'nodes')" + ), + ) + parser.add_argument( + "--background", + type=str, + default="original", + help=( + "Specify the type of background to be used to save the videos." + "Options for background: original, black, white and grey" + ), ) args = parser.parse_args(args=args) labels = Labels.load_file( @@ -642,6 +754,12 @@ def main(args: list = None): fps=args.fps, scale=args.scale, crop_size_xy=crop_size_xy, + show_edges=args.show_edges > 0, + edge_is_wedge=args.edge_is_wedge > 0, + marker_size=args.marker_size, + palette=args.palette, + distinctly_color=args.distinctly_color, + background=args.background, ) print(f"Video saved as: {filename}") diff --git a/sleap/nn/__init__.py b/sleap/nn/__init__.py index b3c4eacd3..648fd49ff 100644 --- a/sleap/nn/__init__.py +++ b/sleap/nn/__init__.py @@ -14,3 +14,6 @@ import sleap.nn.tracking import sleap.nn.viz import sleap.nn.identity +import os + +os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID" diff --git a/sleap/nn/config/model.py b/sleap/nn/config/model.py index ca4573266..76056782f 100644 --- a/sleap/nn/config/model.py +++ b/sleap/nn/config/model.py @@ -653,7 +653,9 @@ class ModelConfig: Attributes: backbone: Configurations related to the main network architecture. heads: Configurations related to the output heads. + base_checkpoint: Path to model folder for loading a checkpoint. Should contain the .h5 file """ backbone: BackboneConfig = attr.ib(factory=BackboneConfig) heads: HeadsConfig = attr.ib(factory=HeadsConfig) + base_checkpoint: Optional[Text] = None diff --git a/sleap/nn/config/outputs.py b/sleap/nn/config/outputs.py index ffb0d76e4..ccb6077b1 100644 --- a/sleap/nn/config/outputs.py +++ b/sleap/nn/config/outputs.py @@ -151,8 +151,8 @@ class OutputsConfig: save_visualizations: If True, will render and save visualizations of the model predictions as PNGs to "{run_folder}/viz/{split}.{epoch:04d}.png", where the split is one of "train", "validation", "test". - delete_viz_images: If True, delete the saved visualizations after training - completes. This is useful to reduce the model folder size if you do not need + keep_viz_images: If True, keep the saved visualization images after training + completes. This is useful unchecked to reduce the model folder size if you do not need to keep the visualization images. zip_outputs: If True, compress the run folder to a zip file. This will be named "{run_folder}.zip". @@ -170,7 +170,7 @@ class OutputsConfig: runs_folder: Text = "models" tags: List[Text] = attr.ib(factory=list) save_visualizations: bool = True - delete_viz_images: bool = True + keep_viz_images: bool = False zip_outputs: bool = False log_to_csv: bool = True checkpointing: CheckpointingConfig = attr.ib(factory=CheckpointingConfig) diff --git a/sleap/nn/data/augmentation.py b/sleap/nn/data/augmentation.py index 21dfb29e6..b754c0fe9 100644 --- a/sleap/nn/data/augmentation.py +++ b/sleap/nn/data/augmentation.py @@ -1,19 +1,11 @@ """Transformers for applying data augmentation.""" -# Monkey patch for: https://github.com/aleju/imgaug/issues/537 -# TODO: Fix when PyPI/conda packages are available for version fencing. -import numpy - -if hasattr(numpy.random, "_bit_generator"): - numpy.random.bit_generator = numpy.random._bit_generator - import sleap import numpy as np import tensorflow as tf import attr from typing import List, Text, Optional -import imgaug as ia -import imgaug.augmenters as iaa +import albumentations as A from sleap.nn.config import AugmentationConfig from sleap.nn.data.instance_cropping import crop_bboxes @@ -111,15 +103,15 @@ def flip_instances_ud( @attr.s(auto_attribs=True) -class ImgaugAugmenter: - """Data transformer based on the `imgaug` library. +class AlbumentationsAugmenter: + """Data transformer based on the `albumentations` library. This class can generate a `tf.data.Dataset` from an existing one that generates image and instance data. Element of the output dataset will have a set of augmentation transformations applied. Attributes: - augmenter: An instance of `imgaug.augmenters.Sequential` that will be applied to + augmenter: An instance of `albumentations.Compose` that will be applied to each element of the input dataset. image_key: Name of the example key where the image is stored. Defaults to "image". @@ -127,7 +119,7 @@ class ImgaugAugmenter: Defaults to "instances". """ - augmenter: iaa.Sequential + augmenter: A.Compose image_key: str = "image" instances_key: str = "instances" @@ -137,7 +129,7 @@ def from_config( config: AugmentationConfig, image_key: Text = "image", instances_key: Text = "instances", - ) -> "ImgaugAugmenter": + ) -> "AlbumentationsAugmenter": """Create an augmenter from a set of configuration parameters. Args: @@ -148,52 +140,64 @@ def from_config( Defaults to "instances". Returns: - An instance of `ImgaugAugmenter` with the specified augmentation + An instance of `AlbumentationsAugmenter` with the specified augmentation configuration. """ aug_stack = [] if config.rotate: aug_stack.append( - iaa.Affine( - rotate=(config.rotation_min_angle, config.rotation_max_angle) + A.Rotate( + limit=(config.rotation_min_angle, config.rotation_max_angle), p=1.0 ) ) if config.translate: aug_stack.append( - iaa.Affine( + A.Affine( translate_px={ "x": (config.translate_min, config.translate_max), "y": (config.translate_min, config.translate_max), - } + }, + p=1.0, ) ) if config.scale: - aug_stack.append(iaa.Affine(scale=(config.scale_min, config.scale_max))) - if config.uniform_noise: aug_stack.append( - iaa.AddElementwise( - value=(config.uniform_noise_min_val, config.uniform_noise_max_val) - ) + A.Affine(scale=(config.scale_min, config.scale_max), p=1.0) ) + if config.uniform_noise: + + def uniform_noise(image, **kwargs): + return image + np.random.uniform( + config.uniform_noise_min_val, config.uniform_noise_max_val + ) + + aug_stack.append(A.Lambda(image=uniform_noise)) if config.gaussian_noise: aug_stack.append( - iaa.AdditiveGaussianNoise( - loc=config.gaussian_noise_mean, scale=config.gaussian_noise_stddev + A.GaussNoise( + mean=config.gaussian_noise_mean, + var_limit=config.gaussian_noise_stddev, ) ) if config.contrast: aug_stack.append( - iaa.GammaContrast( - gamma=(config.contrast_min_gamma, config.contrast_max_gamma) + A.RandomGamma( + gamma_limit=(config.contrast_min_gamma, config.contrast_max_gamma), + p=1.0, ) ) if config.brightness: aug_stack.append( - iaa.Add(value=(config.brightness_min_val, config.brightness_max_val)) + A.RandomBrightness( + limit=(config.brightness_min_val, config.brightness_max_val), p=1.0 + ) ) return cls( - augmenter=iaa.Sequential(aug_stack), + augmenter=A.Compose( + aug_stack, + keypoint_params=A.KeypointParams(format="xy", remove_invisible=False), + ), image_key=image_key, instances_key=instances_key, ) @@ -226,22 +230,16 @@ def transform_dataset(self, input_ds: tf.data.Dataset) -> tf.data.Dataset: # Define augmentation function to map over each sample. def py_augment(image, instances): """Local processing function that will not be autographed.""" - # Ensure that the transformations applied to all data within this - # example are kept consistent. - aug_det = self.augmenter.to_deterministic() + # Convert to numpy arrays. + img = image.numpy() + kps = instances.numpy() + original_shape = kps.shape + kps = kps.reshape(-1, 2) - # Augment the image. - aug_img = aug_det.augment_image(image.numpy()) - - # This will get converted to a rank 3 tensor (n_instances, n_nodes, 2). - aug_instances = np.full_like(instances, np.nan) - - # Augment each set of points for each instance. - for i, instance in enumerate(instances): - kps = ia.KeypointsOnImage.from_xy_array( - instance.numpy(), tuple(image.shape) - ) - aug_instances[i] = aug_det.augment_keypoints(kps).to_xy_array() + # Augment. + augmented = self.augmenter(image=img, keypoints=kps) + aug_img = augmented["image"] + aug_instances = np.array(augmented["keypoints"]).reshape(original_shape) return aug_img, aug_instances @@ -258,7 +256,6 @@ def augment(frame_data): return frame_data # Apply the augmentation to each element. - # Note: We map sequentially since imgaug gets slower with tf.data parallelism. output_ds = input_ds.map(augment) return output_ds diff --git a/sleap/nn/data/pipelines.py b/sleap/nn/data/pipelines.py index b0892f8a1..2e334456a 100644 --- a/sleap/nn/data/pipelines.py +++ b/sleap/nn/data/pipelines.py @@ -18,7 +18,7 @@ from sleap.nn.data.providers import LabelsReader, VideoReader from sleap.nn.data.augmentation import ( AugmentationConfig, - ImgaugAugmenter, + AlbumentationsAugmenter, RandomCropper, RandomFlipper, ) @@ -68,7 +68,7 @@ PROVIDERS = (LabelsReader, VideoReader) TRANSFORMERS = ( - ImgaugAugmenter, + AlbumentationsAugmenter, RandomCropper, Normalizer, Resizer, @@ -406,7 +406,7 @@ def make_training_pipeline(self, data_provider: Provider) -> Pipeline: self.data_config.labels.skeletons[0], horizontal=self.optimization_config.augmentation_config.flip_horizontal, ) - pipeline += ImgaugAugmenter.from_config( + pipeline += AlbumentationsAugmenter.from_config( self.optimization_config.augmentation_config ) if self.optimization_config.augmentation_config.random_crop: @@ -550,7 +550,7 @@ def make_training_pipeline(self, data_provider: Provider) -> Pipeline: self.data_config.labels.skeletons[0], horizontal=self.optimization_config.augmentation_config.flip_horizontal, ) - pipeline += ImgaugAugmenter.from_config( + pipeline += AlbumentationsAugmenter.from_config( self.optimization_config.augmentation_config ) if self.optimization_config.augmentation_config.random_crop: @@ -713,7 +713,7 @@ def make_training_pipeline(self, data_provider: Provider) -> Pipeline: self.data_config.labels.skeletons[0], horizontal=self.optimization_config.augmentation_config.flip_horizontal, ) - pipeline += ImgaugAugmenter.from_config( + pipeline += AlbumentationsAugmenter.from_config( self.optimization_config.augmentation_config ) pipeline += Normalizer.from_config(self.data_config.preprocessing) @@ -863,7 +863,7 @@ def make_training_pipeline(self, data_provider: Provider) -> Pipeline: self.data_config.labels.skeletons[0], horizontal=aug_config.flip_horizontal, ) - pipeline += ImgaugAugmenter.from_config(aug_config) + pipeline += AlbumentationsAugmenter.from_config(aug_config) if aug_config.random_crop: pipeline += RandomCropper( crop_height=aug_config.random_crop_height, @@ -1028,7 +1028,7 @@ def make_training_pipeline(self, data_provider: Provider) -> Pipeline: horizontal=aug_config.flip_horizontal, ) - pipeline += ImgaugAugmenter.from_config(aug_config) + pipeline += AlbumentationsAugmenter.from_config(aug_config) if aug_config.random_crop: pipeline += RandomCropper( crop_height=aug_config.random_crop_height, @@ -1186,7 +1186,7 @@ def make_training_pipeline(self, data_provider: Provider) -> Pipeline: config=self.data_config.preprocessing, provider=data_provider, ) - pipeline += ImgaugAugmenter.from_config( + pipeline += AlbumentationsAugmenter.from_config( self.optimization_config.augmentation_config ) pipeline += Normalizer.from_config(self.data_config.preprocessing) diff --git a/sleap/nn/data/providers.py b/sleap/nn/data/providers.py index 16f439d10..9e93d0b18 100644 --- a/sleap/nn/data/providers.py +++ b/sleap/nn/data/providers.py @@ -394,9 +394,7 @@ def make_dataset(self) -> tf.data.Dataset: grid in order to properly map points to image coordinates. """ # Grab an image to test for the dtype. - test_image = tf.convert_to_tensor( - self.video.get_frame(self.video.last_frame_idx) - ) + test_image = tf.convert_to_tensor(self.video.get_frame(0)) image_dtype = test_image.dtype def py_fetch_frame(ind): diff --git a/sleap/nn/data/resizing.py b/sleap/nn/data/resizing.py index f5def38d5..a2fcbe5de 100644 --- a/sleap/nn/data/resizing.py +++ b/sleap/nn/data/resizing.py @@ -25,6 +25,7 @@ def find_padding_for_stride( A tuple of (pad_bottom, pad_right), integers with the number of pixels that the image would need to be padded by to meet the divisibility requirement. """ + # The outer-most modulo handles edge case when image_height % max_stride == 0 pad_bottom = (max_stride - (image_height % max_stride)) % max_stride pad_right = (max_stride - (image_width % max_stride)) % max_stride return pad_bottom, pad_right @@ -266,6 +267,8 @@ class SizeMatcher: full_image_key: String name of the key containing the full images. max_image_height: int The target height to which all smaller images will be resized/padded to. max_image_width: int The target width to which all smaller images will be resized/padded to. + center_pad: If True, pad on the left/top to center the non-zero pixels rather than aligning + them to the top-left. The offsets will be stored in the "offset_x" and "offset_y" keys. """ image_key: Text = "image" @@ -275,6 +278,7 @@ class SizeMatcher: full_image_key: Text = "full_image" max_image_height: int = None max_image_width: int = None + center_pad: bool = False @classmethod def from_config( @@ -330,6 +334,7 @@ def from_config( full_image_key=full_image_key, max_image_height=max_height, max_image_width=max_width, + center_pad=False, # TODO(jiaying): Add center padding to the configs. ) @property @@ -346,6 +351,7 @@ def output_keys(self) -> List[Text]: output_keys = self.input_keys if self.keep_full_image: output_keys.append(self.full_image_key) + output_keys.extend(["offset_x", "offset_y"]) return output_keys def transform_dataset(self, ds_input: tf.data.Dataset) -> tf.data.Dataset: @@ -378,6 +384,7 @@ def resize_and_pad(example): current_shape = tf.shape(image) channels = image.shape[-1] effective_scaling_ratio = 1.0 + offset_x, offset_y = 0, 0 # Only apply this transform if image shape differs from target if ( @@ -409,12 +416,19 @@ def resize_and_pad(example): image = tf.image.resize_with_pad( image, target_height=target_height, target_width=target_width ) - # Pad the image on bottom/right with zeroes to match specified - # dimensions + + # Switch between center padding and bottom/right padding. + if self.center_pad: + offset_x = (self.max_image_width - target_width) // 2 + offset_y = (self.max_image_height - target_height) // 2 + else: + offset_x, offset_y = 0, 0 + + # Pad the image with zeroes to match specified dimensions. image = tf.image.pad_to_bounding_box( image, - offset_height=0, - offset_width=0, + offset_height=offset_y, + offset_width=offset_x, target_height=self.max_image_height, target_width=self.max_image_width, ) @@ -429,12 +443,24 @@ def resize_and_pad(example): # Update the scale factor example[self.scale_key] = example[self.scale_key] * effective_scaling_ratio + # Scale the instance points accordingly if self.points_key and self.points_key in example: example[self.points_key] = ( example[self.points_key] * effective_scaling_ratio ) + # Update the offsets + example["offset_x"] = offset_x + example["offset_y"] = offset_y + + # Translate the instance points accordingly + if self.points_key and self.points_key in example: + offsets = tf.cast( + tf.reshape([offset_x, offset_y], [1, 1, 2]), tf.float32 + ) + example[self.points_key] = example[self.points_key] + offsets + return example ds_output = ds_input.map( diff --git a/sleap/nn/data/training.py b/sleap/nn/data/training.py index cb6177375..59f2023ec 100644 --- a/sleap/nn/data/training.py +++ b/sleap/nn/data/training.py @@ -3,20 +3,21 @@ import numpy as np import tensorflow as tf import sleap +from sleap import Labels from sleap.nn.data.providers import LabelsReader -from sleap.nn.data.utils import expand_to_rank, ensure_list +from sleap.nn.data.utils import ensure_list import attr -from typing import List, Text, Optional, Any, Union, Dict, Tuple, Sequence +from typing import List, Text, Dict, Tuple, Sequence from sklearn.model_selection import train_test_split def split_labels_train_val( - labels: sleap.Labels, validation_fraction: float -) -> Tuple[sleap.Labels, List[int], sleap.Labels, List[int]]: + labels: Labels, validation_fraction: float +) -> Tuple[Labels, List[int], Labels, List[int]]: """Make a train/validation split from a labels dataset. Args: - labels: A `sleap.Labels` dataset with labeled frames. + labels: A `Labels` dataset with labeled frames. validation_fraction: Fraction of frames to use for validation. Returns: @@ -48,12 +49,12 @@ def split_labels_train_val( idx_train, idx_val = train_test_split(list(range(len(labels))), test_size=n_val) # Create labels and keep original metadata. - labels_train = sleap.Labels(labels[idx_train]) + labels_train = labels.extract(idx_train, copy=False) labels_train.videos = labels.videos labels_train.tracks = labels.tracks labels_train.provenance = labels.provenance - labels_val = sleap.Labels(labels[idx_val]) + labels_val = labels.extract(idx_val, copy=False) labels_val.videos = labels.videos labels_val.tracks = labels.tracks labels_val.provenance = labels.provenance @@ -61,13 +62,11 @@ def split_labels_train_val( return labels_train, idx_train, labels_val, idx_val -def split_labels( - labels: sleap.Labels, split_fractions: Sequence[float] -) -> Tuple[sleap.Labels]: - """Split a `sleap.Labels` into multiple new ones with random subsets of the data. +def split_labels(labels: Labels, split_fractions: Sequence[float]) -> Tuple[Labels]: + """Split a `Labels` into multiple new ones with random subsets of the data. Args: - labels: An instance of `sleap.Labels`. + labels: An instance of `Labels`. split_fractions: One or more floats between 0 and 1 that specify the fraction of examples that should be in each dataset. These should add up to <= 1.0. Fractions of less than 1 element will be rounded up to ensure that is at @@ -75,7 +74,7 @@ def split_labels( that it should contain all elements left over from the other splits. Returns: - A tuple of new `sleap.Labels` instances of the same length as `split_fractions`. + A tuple of new `Labels` instances of the same length as `split_fractions`. Raises: ValueError: If more than one split fraction is specified as -1. @@ -110,7 +109,9 @@ def split_labels( ) # Create new instance. - split_labels.append(sleap.Labels([labels[int(ind)] for ind in sampled_indices])) + split_labels.append( + labels.extract([labels[int(ind)] for ind in sampled_indices]) + ) # Exclude the sampled indices from the available indices. labels_indices = np.setdiff1d(labels_indices, sampled_indices) @@ -126,7 +127,7 @@ def split_labels_reader( Args: labels_reader: An instance of `sleap.nn.data.providers.LabelsReader`. This is a provider that generates datasets that contain elements read from a - `sleap.Labels` instance. + `Labels` instance. split_fractions: One or more floats between 0 and 1 that specify the fraction of examples that should be in each dataset. These should add up to <= 1.0. Fractions of less than 1 element will be rounded up to ensure that is at @@ -137,7 +138,7 @@ def split_labels_reader( A tuple of `LabelsReader` instances of the same length as `split_fractions`. The indices will be stored in the `example_indices` in each `LabelsReader` instance. - The actual `sleap.Labels` instance will be the same for each instance, only the + The actual `Labels` instance will be the same for each instance, only the `example_indices` that are iterated over will change across splits. If the input `labels_reader` already has `example_indices`, a subset of these diff --git a/sleap/nn/evals.py b/sleap/nn/evals.py index 670c339c7..002f8a143 100644 --- a/sleap/nn/evals.py +++ b/sleap/nn/evals.py @@ -25,7 +25,7 @@ import numpy as np from typing import Any, Dict, List, Optional, Text, Tuple, Union import logging -import sleap + from sleap import Labels, LabeledFrame, Instance, PredictedInstance from sleap.nn.config import ( TrainingJobConfig, @@ -136,6 +136,7 @@ def compute_oks( points_pr: np.ndarray, scale: Optional[float] = None, stddev: float = 0.025, + use_cocoeval: bool = True, ) -> np.ndarray: """Compute the object keypoints similarity between sets of points. @@ -145,6 +146,12 @@ def compute_oks( is the number of Euclidean dimensions (typically 2 or 3). Keypoints that are missing/not visible should be represented as NaNs. points_pr: Predicted instance of shape (n_pr, n_nodes, n_ed). + use_cocoeval: Indicates whether the OKS score is calculated like cocoeval + method or not. True indicating the score is calculated using the + cocoeval method (widely used and the code can be found here at + https://github.com/cocodataset/cocoapi/blob/8c9bcc3cf640524c4c20a9c40e89cb6a2f2fa0e9/PythonAPI/pycocotools/cocoeval.py#L192C5-L233C20) + and False indicating the score is calculated using the method exactly + as given in the paper referenced in the Notes below. scale: Size scaling factor to use when weighing the scores, typically the area of the bounding box of the instance (in pixels). This should be of the length n_gt. If a scalar is provided, the same @@ -173,10 +180,10 @@ def compute_oks( Ronch & Perona. "Benchmarking and Error Diagnosis in Multi-Instance Pose Estimation." ICCV (2017). """ - if points_gt.ndim != 3 or points_pr.ndim != 3: - raise ValueError( - "Points must be rank-3 with shape (n_instances, n_nodes, n_ed)." - ) + if points_gt.ndim == 2: + points_gt = np.expand_dims(points_gt, axis=0) + if points_pr.ndim == 2: + points_pr = np.expand_dims(points_pr, axis=0) if scale is None: scale = compute_instance_area(points_gt) @@ -203,8 +210,14 @@ def compute_oks( assert distance.shape == (n_gt, n_pr, n_nodes) # Compute the normalization factor per keypoint. - spread_factor = (2 * stddev) ** 2 - scale_factor = 2 * (scale + np.spacing(1)) + if use_cocoeval: + # If use_cocoeval is True, then compute normalization factor according to cocoeval. + spread_factor = (2 * stddev) ** 2 + scale_factor = 2 * (scale + np.spacing(1)) + else: + # If use_cocoeval is False, then compute normalization factor according to the paper. + spread_factor = stddev ** 2 + scale_factor = 2 * ((scale + np.spacing(1)) ** 2) normalization_factor = np.reshape(spread_factor, (1, 1, n_nodes)) * np.reshape( scale_factor, (n_gt, 1, 1) ) @@ -471,7 +484,7 @@ def compute_generalized_voc_metrics( def compute_dists( positive_pairs: List[Tuple[Instance, PredictedInstance, Any]] -) -> np.ndarray: +) -> Dict[str, Union[np.ndarray, List[int], List[str]]]: """Compute Euclidean distances between matched pairs of instances. Args: @@ -479,20 +492,37 @@ def compute_dists( containing the matched pair of instances. Returns: - An array of pairwise distances of shape `(n_positive_pairs, n_nodes)`. + A dictionary with the following keys: + dists: An array of pairwise distances of shape `(n_positive_pairs, n_nodes)` + frame_idxs: A list of frame indices corresponding to the `dists` + video_paths: A list of video paths corresponding to the `dists` """ dists = [] + frame_idxs = [] + video_paths = [] for instance_gt, instance_pr, _ in positive_pairs: points_gt = instance_gt.points_array points_pr = instance_pr.points_array dists.append(np.linalg.norm(points_pr - points_gt, axis=-1)) + frame_idxs.append(instance_gt.frame.frame_idx) + video_paths.append(instance_gt.frame.video.backend.filename) + dists = np.array(dists) - return dists + # Bundle everything into a dictionary + dists_dict = { + "dists": dists, + "frame_idxs": frame_idxs, + "video_paths": video_paths, + } + + return dists_dict -def compute_dist_metrics(dists: np.ndarray) -> Dict[Text, np.ndarray]: +def compute_dist_metrics( + dists_dict: Dict[str, Union[np.ndarray, List[Instance]]] +) -> Dict[Text, np.ndarray]: """Compute the Euclidean distance error at different percentiles. Args: @@ -501,7 +531,10 @@ def compute_dist_metrics(dists: np.ndarray) -> Dict[Text, np.ndarray]: Returns: A dictionary of distance metrics. """ + dists = dists_dict["dists"] results = { + "dist.frame_idxs": dists_dict["frame_idxs"], + "dist.video_paths": dists_dict["video_paths"], "dist.dists": dists, "dist.avg": np.nanmean(dists), "dist.p50": np.nan, @@ -623,11 +656,11 @@ def evaluate( threshold=match_threshold, user_labels_only=user_labels_only, ) - dists = compute_dists(positive_pairs) + dists_dict = compute_dists(positive_pairs) metrics.update(compute_visibility_conf(positive_pairs)) - metrics.update(compute_dist_metrics(dists)) - metrics.update(compute_pck_metrics(dists)) + metrics.update(compute_dist_metrics(dists_dict)) + metrics.update(compute_pck_metrics(dists_dict["dists"])) pair_oks = np.array([oks for _, _, oks in positive_pairs]) pair_pck = metrics["pck.pcks"].mean(axis=-1).mean(axis=-1) @@ -649,7 +682,7 @@ def evaluate( def evaluate_model( cfg: TrainingJobConfig, - labels_reader: LabelsReader, + labels_gt: Union[LabelsReader, Labels], model: Model, save: bool = True, split_name: Text = "test", @@ -658,8 +691,8 @@ def evaluate_model( Args: cfg: The `TrainingJobConfig` associated with the model. - labels_reader: A `LabelsReader` pipeline generator that reads the ground truth - data to evaluate. + labels_gt: A `LabelsReader` pipeline generator that reads the ground truth + data to evaluate or a `Labels` object to be used as ground truth. model: The `sleap.nn.model.Model` instance to evaluate. save: If True, save the predictions and metrics to the model folder. split_name: String name to append to the saved filenames. @@ -708,11 +741,13 @@ def evaluate_model( raise ValueError("Unrecognized model type:", head_config) # Predict. - labels_pr = predictor.predict(labels_reader, make_labels=True) + labels_pr: Labels = predictor.predict(labels_gt, make_labels=True) # Compute metrics. try: - metrics = evaluate(labels_reader.labels, labels_pr) + if isinstance(labels_gt, LabelsReader): + labels_gt = labels_gt.labels + metrics = evaluate(labels_gt, labels_pr) except: logger.warning("Failed to compute metrics.") metrics = None @@ -763,6 +798,8 @@ def load_metrics(model_path: str, split: str = "val") -> Dict[str, Any]: - `"dist.p95"`: Distance for 95th percentile - `"dist.p99"`: Distance for 99th percentile - `"dist.dists"`: All distances + - `"dist.frame_idxs"`: Frame indices corresponding to `"dist.dists"` + - `"dist.video_paths"`: Video paths corresponding to `"dist.dists"` - `"pck.mPCK"`: Mean Percentage of Correct Keypoints (PCK) - `"oks.mOKS"`: Mean Object Keypoint Similarity (OKS) - `"oks_voc.mAP"`: VOC with OKS scores - mean Average Precision (mAP) diff --git a/sleap/nn/inference.py b/sleap/nn/inference.py index 2098dc63b..3f01a1c3c 100644 --- a/sleap/nn/inference.py +++ b/sleap/nn/inference.py @@ -33,20 +33,24 @@ import atexit import subprocess import rich.progress +import pandas as pd from rich.pretty import pprint from collections import deque import json from time import time from datetime import datetime from pathlib import Path - +import tensorflow_hub as hub from abc import ABC, abstractmethod from typing import Text, Optional, List, Dict, Union, Iterator, Tuple +from threading import Thread +from queue import Queue import tensorflow as tf import numpy as np import sleap + from sleap.nn.config import TrainingJobConfig, DataConfig from sleap.nn.data.resizing import SizeMatcher from sleap.nn.model import Model @@ -63,13 +67,65 @@ InstanceCentroidFinder, KerasModelPredictor, ) +from sleap.nn.utils import reset_input_layer from sleap.io.dataset import Labels -from sleap.util import frame_list +from sleap.util import frame_list, make_scoped_dictionary +from sleap.instance import PredictedInstance, LabeledFrame from tensorflow.python.framework.convert_to_constants import ( convert_variables_to_constants_v2, ) +MOVENET_MODELS = { + "lightning": { + "model_path": "https://tfhub.dev/google/movenet/singlepose/lightning/4", + "image_size": 192, + }, + "thunder": { + "model_path": "https://tfhub.dev/google/movenet/singlepose/thunder/4", + "image_size": 256, + }, +} + +MOVENET_SKELETON = sleap.Skeleton.from_names_and_edge_inds( + [ + "nose", + "left_eye", + "right_eye", + "left_ear", + "right_ear", + "left_shoulder", + "right_shoulder", + "left_elbow", + "right_elbow", + "left_wrist", + "right_wrist", + "left_hip", + "right_hip", + "left_knee", + "right_knee", + "left_ankle", + "right_ankle", + ], + [ + (10, 8), + (8, 6), + (6, 5), + (5, 7), + (7, 9), + (6, 12), + (5, 11), + (12, 14), + (14, 16), + (11, 13), + (13, 15), + (4, 2), + (2, 0), + (0, 1), + (1, 3), + ], +) + logger = logging.getLogger(__name__) @@ -124,11 +180,14 @@ def from_model_paths( integral_refinement: bool = True, integral_patch_size: int = 5, batch_size: int = 4, + resize_input_layer: bool = True, + max_instances: Optional[int] = None, ) -> "Predictor": """Create the appropriate `Predictor` subclass from a list of model paths. Args: - model_paths: A single or list of trained model paths. + model_paths: A single or list of trained model paths. Special cases of + non-SLEAP models include "movenet-thunder" and "movenet-lightning". peak_threshold: Minimum confidence map value to consider a peak as valid. integral_refinement: If `True`, peaks will be refined with integral regression. If `False`, `"local"`, peaks will be refined with quarter @@ -139,15 +198,33 @@ def from_model_paths( batch_size: The default batch size to use when loading data for inference. Higher values increase inference speed at the cost of higher memory usage. + resize_input_layer: If True, the the input layer of the `tf.Keras.model` is + resized to (None, None, None, num_color_channels). + max_instances: If not `None`, discard instances beyond this count when + predicting, regardless of whether filtering is done at the tracking + stage. This is useful for preventing extraneous instances from being + created when tracking is not being applied. Returns: A subclass of `Predictor`. - See also: `SingleInstancePredictor`, `TopDownPredictor`, `BottomUpPredictor` + See also: `SingleInstancePredictor`, `TopDownPredictor`, `BottomUpPredictor`, + `MoveNetPredictor`, `TopDownMultiClassPredictor`, + `BottomUpMultiClassPredictor`. """ # Read configs and find model types. if isinstance(model_paths, str): + # Special case for handling movenet models + if "movenet" in model_paths: + model_name = model_paths.split("-")[-1] # Expect movenet- + predictor = MoveNetPredictor.from_trained_models( + model_name=model_name, peak_threshold=peak_threshold + ) + predictor.model_paths = MOVENET_MODELS[model_name]["model_path"] + return predictor + model_paths = [model_paths] + model_configs = [sleap.load_config(model_path) for model_path in model_paths] model_paths = [cfg.filename for cfg in model_configs] model_types = [ @@ -161,6 +238,7 @@ def from_model_paths( integral_refinement=integral_refinement, integral_patch_size=integral_patch_size, batch_size=batch_size, + resize_input_layer=resize_input_layer, ) elif ( @@ -190,6 +268,7 @@ def from_model_paths( peak_threshold=peak_threshold, integral_refinement=integral_refinement, integral_patch_size=integral_patch_size, + resize_input_layer=resize_input_layer, ) else: predictor = TopDownPredictor.from_trained_models( @@ -199,6 +278,8 @@ def from_model_paths( peak_threshold=peak_threshold, integral_refinement=integral_refinement, integral_patch_size=integral_patch_size, + resize_input_layer=resize_input_layer, + max_instances=max_instances, ) elif "multi_instance" in model_types: @@ -208,6 +289,8 @@ def from_model_paths( integral_refinement=integral_refinement, integral_patch_size=integral_patch_size, batch_size=batch_size, + resize_input_layer=resize_input_layer, + max_instances=max_instances, ) elif "multi_class_bottomup" in model_types: @@ -217,6 +300,7 @@ def from_model_paths( integral_refinement=integral_refinement, integral_patch_size=integral_patch_size, batch_size=batch_size, + resize_input_layer=resize_input_layer, ) else: @@ -325,6 +409,9 @@ def process_batch(ex): ex["frame_ind"] = ex["frame_ind"].numpy().flatten() # Adjust for potential SizeMatcher scaling. + offset_x = ex.get("offset_x", 0) + offset_y = ex.get("offset_y", 0) + ex["instance_peaks"] -= np.reshape([offset_x, offset_y], [-1, 1, 1, 2]) ex["instance_peaks"] /= np.expand_dims( np.expand_dims(ex["scale"], axis=1), axis=1 ) @@ -450,8 +537,9 @@ def export_model( save_traces: bool = True, model_name: Optional[str] = None, tensors: Optional[Dict[str, str]] = None, + unrag_outputs: bool = True, + max_instances: Optional[int] = None, ): - """Export a trained SLEAP model as a frozen graph. Initializes model, creates a dummy tracing batch and passes it through the model. The frozen graph is saved along with training meta info. @@ -467,10 +555,22 @@ def export_model( model tensors: (Optional) Dictionary describing the predicted tensors (see sleap.nn.data.utils.describe_tensors as an example) - + unrag_outputs: If `True` (default), any ragged tensors will be + converted to normal tensors and padded with NaNs + max_instances: If set, determines the max number of instances that a + multi-instance model returns. This is enforced during centroid + cropping and therefore only compatible with TopDown models. """ self._initialize_inference_model() + predictor_name = type(self).__name__ + + if max_instances is not None: + if "TopDown" in predictor_name: + print(f"\n max instances set, limiting instances to {max_instances} \n") + self.inference_model.centroid_crop.max_instances = max_instances + else: + raise Exception(f"{predictor_name} does not support max instance limit") first_inference_layer = self.inference_model.layers[0] keras_model_shape = first_inference_layer.keras_model.input.shape @@ -485,7 +585,7 @@ def export_model( outputs = self.inference_model.predict(tracing_batch) self.inference_model.export_model( - save_path, signatures, save_traces, model_name, tensors + save_path, signatures, save_traces, model_name, tensors, unrag_outputs ) @@ -748,7 +848,7 @@ def call( tf.int64 ) # (batch_size, n_centroids, 1, 1, 2) dists = a - b # (batch_size, n_centroids, n_insts, n_nodes, 2) - dists = tf.sqrt(tf.reduce_sum(dists ** 2, axis=-1)) # reduce over xy + dists = tf.sqrt(tf.reduce_sum(tf.math.square(dists), axis=-1)) # reduce over xy dists = tf.reduce_min(dists, axis=-1) # reduce over nodes dists = dists.to_tensor( tf.cast(np.NaN, tf.float32) @@ -800,11 +900,13 @@ class InferenceLayer(tf.keras.layers.Layer): Attributes: keras_model: A `tf.keras.Model` that will be called on the input to this layer. input_scale: If not 1.0, input image will be resized by this factor. - pad_to_stride: If not 1, input image will be paded to ensure that it is + pad_to_stride: If not 1, input image will be padded to ensure that it is divisible by this value (after scaling). ensure_grayscale: If `True`, converts inputs to grayscale if not already. If `False`, converts inputs to RGB if not already. If `None` (default), infer from the shape of the input layer of the model. + ensure_float: If `True`, converts inputs to `float32` and scales the values to + be between 0 and 1. """ def __init__( @@ -813,6 +915,7 @@ def __init__( input_scale: float = 1.0, pad_to_stride: int = 1, ensure_grayscale: Optional[bool] = None, + ensure_float: bool = True, **kwargs, ): super().__init__(**kwargs) @@ -822,6 +925,7 @@ def __init__( if ensure_grayscale is None: ensure_grayscale = self.keras_model.inputs[0].shape[-1] == 1 self.ensure_grayscale = ensure_grayscale + self.ensure_float = ensure_float def preprocess(self, imgs: tf.Tensor) -> tf.Tensor: """Apply all preprocessing operations configured for this layer. @@ -840,7 +944,8 @@ def preprocess(self, imgs: tf.Tensor) -> tf.Tensor: else: imgs = sleap.nn.data.normalization.ensure_rgb(imgs) - imgs = sleap.nn.data.normalization.ensure_float(imgs) + if self.ensure_float: + imgs = sleap.nn.data.normalization.ensure_float(imgs) if self.input_scale != 1.0: imgs = sleap.nn.data.resizing.resize_image(imgs, self.input_scale) @@ -980,6 +1085,7 @@ def export_model( save_traces: bool = True, model_name: Optional[str] = None, tensors: Optional[Dict[str, str]] = None, + unrag_outputs: bool = True, ): """Save the frozen graph of a model. @@ -994,6 +1100,8 @@ def export_model( model tensors: (Optional) Dictionary describing the predicted tensors (see sleap.nn.data.utils.describe_tensors as an example) + unrag_outputs: If `True` (default), any ragged tensors will be + converted to normal tensors and padded with NaNs Notes: @@ -1004,7 +1112,6 @@ def export_model( os.makedirs(save_path, exist_ok=True) with tempfile.TemporaryDirectory() as tmp_dir: - self.save(tmp_dir, save_format="tf", save_traces=save_traces) imported = tf.saved_model.load(tmp_dir) @@ -1021,7 +1128,11 @@ def export_model( if tensors: info["predicted_tensors"] = tensors - full_model = tf.function(lambda x: model(x)) + full_model = tf.function( + lambda x: sleap.nn.data.utils.unrag_example(model(x), numpy=False) + if unrag_outputs + else model(x) + ) full_model = full_model.get_concrete_function( tf.TensorSpec(model.inputs[0].shape, model.inputs[0].dtype) @@ -1032,6 +1143,7 @@ def export_model( info["frozen_model_inputs"] = frozen_func.inputs info["frozen_model_outputs"] = frozen_func.outputs + info["unragged_outputs"] = unrag_outputs with (Path(save_path) / "info.json").open("w") as fp: json.dump( @@ -1338,6 +1450,7 @@ def _initialize_inference_model(self): peak_threshold=self.peak_threshold, refinement="integral" if self.integral_refinement else "local", integral_patch_size=self.integral_patch_size, + output_stride=self.confmap_config.model.heads.single_instance.output_stride, ) ) @@ -1358,6 +1471,7 @@ def from_trained_models( integral_refinement: bool = True, integral_patch_size: int = 5, batch_size: int = 4, + resize_input_layer: bool = True, ) -> "SingleInstancePredictor": """Create the predictor from a saved model. @@ -1376,6 +1490,8 @@ def from_trained_models( batch_size: The default batch size to use when loading data for inference. Higher values increase inference speed at the cost of higher memory usage. + resize_input_layer: If True, the the input layer of the `tf.Keras.model` is + resized to (None, None, None, num_color_channels). Returns: An instance of`SingleInstancePredictor` with the models loaded. @@ -1387,6 +1503,10 @@ def from_trained_models( confmap_model.keras_model = tf.keras.models.load_model( confmap_keras_model_path, compile=False ) + if resize_input_layer: + confmap_model.keras_model = reset_input_layer( + keras_model=confmap_model.keras_model, new_shape=None + ) obj = cls( confmap_config=confmap_config, confmap_model=confmap_model, @@ -1419,35 +1539,63 @@ def _make_labeled_frames_from_generator( arrays returned from the inference result generator. """ skeleton = self.confmap_config.data.labels.skeletons[0] - - # Loop over batches. predicted_frames = [] - for ex in generator: - - # Loop over frames. - for video_ind, frame_ind, points, confidences in zip( - ex["video_ind"], - ex["frame_ind"], - ex["instance_peaks"], - ex["instance_peak_vals"], - ): - # Loop over instances. - predicted_instances = [ - sleap.instance.PredictedInstance.from_arrays( - points=points[0], - point_confidences=confidences[0], - instance_score=np.nansum(confidences[0]), - skeleton=skeleton, - ) - ] - predicted_frames.append( - sleap.LabeledFrame( - video=data_provider.videos[video_ind], - frame_idx=frame_ind, - instances=predicted_instances, + def _object_builder(): + while True: + ex = prediction_queue.get() + if ex is None: + break + + # Loop over frames. + for video_ind, frame_ind, points, confidences in zip( + ex["video_ind"], + ex["frame_ind"], + ex["instance_peaks"], + ex["instance_peak_vals"], + ): + # Loop over instances. + if np.isnan(points[0]).all(): + predicted_instances = [] + else: + predicted_instances = [ + PredictedInstance.from_numpy( + points=points[0], + point_confidences=confidences[0], + instance_score=np.nansum(confidences[0]), + skeleton=skeleton, + ) + ] + + predicted_frames.append( + LabeledFrame( + video=data_provider.videos[video_ind], + frame_idx=frame_ind, + instances=predicted_instances, + ) ) - ) + + # Set up threaded object builder. + prediction_queue = Queue() + object_builder = Thread(target=_object_builder) + object_builder.start() + + # Loop over batches. + try: + for ex in generator: + prediction_queue.put(ex) + + except KeyError as e: + # Gracefully handle seeking errors by early termination. + if "Unable to load frame" in str(e): + pass # TODO: Print warning obeying verbosity? (This code path is also + # called for interactive prediction where we don't want any spam.) + else: + raise + + finally: + prediction_queue.put(None) + object_builder.join() return predicted_frames @@ -1458,9 +1606,18 @@ def export_model( save_traces: bool = True, model_name: Optional[str] = None, tensors: Optional[Dict[str, str]] = None, + unrag_outputs: bool = True, + max_instances: Optional[int] = None, ): - - super().export_model(save_path, signatures, save_traces, model_name, tensors) + super().export_model( + save_path, + signatures, + save_traces, + model_name, + tensors, + unrag_outputs, + max_instances, + ) self.confmap_config.save_json(os.path.join(save_path, "confmap_config.json")) @@ -1510,6 +1667,8 @@ class CentroidCrop(InferenceLayer): the predicted peaks. This is true by default since crops are used for finding instance peaks in a top down model. If using a centroid only inference model, this should be set to `False`. + max_instances: If set, determines the max number of instances that a + multi-instance model returns. """ def __init__( @@ -1526,6 +1685,7 @@ def __init__( confmaps_ind: Optional[int] = None, offsets_ind: Optional[int] = None, return_crops: bool = True, + max_instances: Optional[int] = None, **kwargs, ): super().__init__( @@ -1555,7 +1715,7 @@ def __init__( if output_stride is None: # Attempt to automatically infer the output stride. output_stride = get_model_output_stride( - self.keras_model, 0, self.confmaps_ind + self.keras_model, output_ind=self.confmaps_ind ) self.output_stride = output_stride self.peak_threshold = peak_threshold @@ -1563,6 +1723,7 @@ def __init__( self.integral_patch_size = integral_patch_size self.return_confmaps = return_confmaps self.return_crops = return_crops + self.max_instances = max_instances @tf.function def call(self, inputs): @@ -1656,8 +1817,78 @@ def call(self, inputs): # Store crop offsets. crop_offsets = centroid_points - (self.crop_size / 2) + samples = tf.shape(imgs)[0] + n_peaks = tf.shape(centroid_points)[0] + if n_peaks > 0: + if self.max_instances is not None: + centroid_points = tf.RaggedTensor.from_value_rowids( + centroid_points, crop_sample_inds, nrows=samples + ) + centroid_vals = tf.RaggedTensor.from_value_rowids( + centroid_vals, crop_sample_inds, nrows=samples + ) + + _centroid_vals = tf.TensorArray( + size=samples, + dtype=tf.float32, + infer_shape=False, + element_shape=[None], + ) + + _centroid_points = tf.TensorArray( + size=samples, + dtype=tf.float32, + infer_shape=False, + element_shape=[None, 2], + ) + + _row_ids = tf.TensorArray( + size=samples, + dtype=tf.int32, + infer_shape=False, + element_shape=[None], + ) + + for sample in range(samples): + n_centroids = tf.shape(centroid_vals[sample])[0] + if self.max_instances < n_centroids: + top_points = tf.math.top_k( + centroid_vals[sample], + k=self.max_instances, + ) + top_inds = top_points.indices + + _centroid_vals = _centroid_vals.write( + sample, tf.gather(centroid_vals[sample], top_inds) + ) + + _centroid_points = _centroid_points.write( + sample, tf.gather(centroid_points[sample], top_inds) + ) + + _row_ids = _row_ids.write( + sample, tf.fill([len(top_inds)], sample) + ) + else: + _centroid_vals = _centroid_vals.write( + sample, centroid_vals[sample] + ) + _centroid_points = _centroid_points.write( + sample, centroid_points[sample] + ) + _row_ids = _row_ids.write( + sample, tf.fill([n_centroids], sample) + ) + + centroid_vals = _centroid_vals.concat() + centroid_points = _centroid_points.concat() + crop_sample_inds = _row_ids.concat() + + n_peaks = tf.shape(crop_sample_inds)[0] + + crop_offsets = centroid_points - (self.crop_size / 2) # Crop instances around centroids. bboxes = sleap.nn.data.instance_cropping.make_centered_bboxes( @@ -1671,6 +1902,7 @@ def call(self, inputs): crops = tf.reshape( crops, [n_peaks, self.crop_size, self.crop_size, full_imgs.shape[3]] ) + else: # No peaks found, so just create a placeholder stack. crops = tf.zeros( @@ -1679,7 +1911,6 @@ def call(self, inputs): ) # Group crops by sample (samples, ?, ...). - samples = tf.shape(imgs)[0] centroids = tf.RaggedTensor.from_value_rowids( centroid_points, crop_sample_inds, nrows=samples ) @@ -1789,7 +2020,7 @@ def __init__( if output_stride is None: # Attempt to automatically infer the output stride. output_stride = get_model_output_stride( - self.keras_model, 0, self.confmaps_ind + self.keras_model, output_ind=self.confmaps_ind ) self.output_stride = output_stride @@ -2034,7 +2265,13 @@ def call( crop_output = self.centroid_crop(example) if isinstance(self.instance_peaks, FindInstancePeaksGroundTruth): - peaks_output = self.instance_peaks(example, crop_output) + if "instances" in example: + peaks_output = self.instance_peaks(example, crop_output) + else: + raise ValueError( + "Ground truth data was not detected... " + "Please load both models when predicting on non-ground-truth data." + ) else: peaks_output = self.instance_peaks(crop_output) return peaks_output @@ -2080,6 +2317,10 @@ class TopDownPredictor(Predictor): head. integral_patch_size: Size of patches to crop around each rough peak for integral refinement as an integer scalar. + max_instances: If not `None`, discard instances beyond this count when + predicting, regardless of whether filtering is done at the tracking stage. + This is useful for preventing extraneous instances from being created when + tracking is not being applied. """ centroid_config: Optional[TrainingJobConfig] = attr.ib(default=None) @@ -2093,6 +2334,7 @@ class TopDownPredictor(Predictor): peak_threshold: float = 0.2 integral_refinement: bool = True integral_patch_size: int = 5 + max_instances: Optional[int] = None def _initialize_inference_model(self): """Initialize the inference model from the trained models and configuration.""" @@ -2118,6 +2360,7 @@ def _initialize_inference_model(self): refinement="integral" if self.integral_refinement else "local", integral_patch_size=self.integral_patch_size, return_confmaps=False, + max_instances=self.max_instances, ) if use_gt_confmap: @@ -2155,6 +2398,8 @@ def from_trained_models( peak_threshold: float = 0.2, integral_refinement: bool = True, integral_patch_size: int = 5, + resize_input_layer: bool = True, + max_instances: Optional[int] = None, ) -> "TopDownPredictor": """Create predictor from saved models. @@ -2176,6 +2421,12 @@ def from_trained_models( offset regression head. integral_patch_size: Size of patches to crop around each rough peak for integral refinement as an integer scalar. + resize_input_layer: If True, the the input layer of the `tf.Keras.model` is + resized to (None, None, None, num_color_channels). + max_instances: If not `None`, discard instances beyond this count when + predicting, regardless of whether filtering is done at the tracking + stage. This is useful for preventing extraneous instances from being + created when tracking is not being applied. Returns: An instance of `TopDownPredictor` with the loaded models. @@ -2196,6 +2447,11 @@ def from_trained_models( centroid_model.keras_model = tf.keras.models.load_model( centroid_keras_model_path, compile=False ) + if resize_input_layer: + # Reset input layer dimensions to be more flexible + centroid_model.keras_model = reset_input_layer( + keras_model=centroid_model.keras_model, new_shape=None + ) else: centroid_config = None centroid_model = None @@ -2208,6 +2464,11 @@ def from_trained_models( confmap_model.keras_model = tf.keras.models.load_model( confmap_keras_model_path, compile=False ) + if resize_input_layer: + # Reset input layer dimensions to be more flexible + confmap_model.keras_model = reset_input_layer( + keras_model=confmap_model.keras_model, new_shape=None + ) else: confmap_config = None confmap_model = None @@ -2221,6 +2482,7 @@ def from_trained_models( peak_threshold=peak_threshold, integral_refinement=integral_refinement, integral_patch_size=integral_patch_size, + max_instances=max_instances, ) obj._initialize_inference_model() return obj @@ -2310,59 +2572,90 @@ def _make_labeled_frames_from_generator( else: skeleton = self.centroid_config.data.labels.skeletons[0] - # Loop over batches. predicted_frames = [] - for ex in generator: - if "n_valid" in ex: - ex["instance_peaks"] = [ - x[:n] for x, n in zip(ex["instance_peaks"], ex["n_valid"]) - ] - ex["instance_peak_vals"] = [ - x[:n] for x, n in zip(ex["instance_peak_vals"], ex["n_valid"]) - ] - ex["centroids"] = [ - x[:n] for x, n in zip(ex["centroids"], ex["n_valid"]) - ] - ex["centroid_vals"] = [ - x[:n] for x, n in zip(ex["centroid_vals"], ex["n_valid"]) - ] + def _object_builder(): + while True: + ex = prediction_queue.get() + if ex is None: + break - # Loop over frames. - for image, video_ind, frame_ind, points, confidences, scores in zip( - ex["image"], - ex["video_ind"], - ex["frame_ind"], - ex["instance_peaks"], - ex["instance_peak_vals"], - ex["centroid_vals"], - ): + if "n_valid" in ex: + ex["instance_peaks"] = [ + x[:n] for x, n in zip(ex["instance_peaks"], ex["n_valid"]) + ] + ex["instance_peak_vals"] = [ + x[:n] for x, n in zip(ex["instance_peak_vals"], ex["n_valid"]) + ] + ex["centroids"] = [ + x[:n] for x, n in zip(ex["centroids"], ex["n_valid"]) + ] + ex["centroid_vals"] = [ + x[:n] for x, n in zip(ex["centroid_vals"], ex["n_valid"]) + ] + + # Loop over frames. + for image, video_ind, frame_ind, points, confidences, scores in zip( + ex["image"], + ex["video_ind"], + ex["frame_ind"], + ex["instance_peaks"], + ex["instance_peak_vals"], + ex["centroid_vals"], + ): + # Loop over instances. + predicted_instances = [] + for pts, confs, score in zip(points, confidences, scores): + if np.isnan(pts).all(): + continue + + predicted_instances.append( + PredictedInstance.from_numpy( + points=pts, + point_confidences=confs, + instance_score=score, + skeleton=skeleton, + ) + ) - # Loop over instances. - predicted_instances = [] - for pts, confs, score in zip(points, confidences, scores): - predicted_instances.append( - sleap.instance.PredictedInstance.from_arrays( - points=pts, - point_confidences=confs, - instance_score=score, - skeleton=skeleton, + if self.tracker: + # Set tracks for predicted instances in this frame. + predicted_instances = self.tracker.track( + untracked_instances=predicted_instances, + img_hw=ex["image"].shape[-3:-1], + img=image, + t=frame_ind, ) - ) - if self.tracker: - # Set tracks for predicted instances in this frame. - predicted_instances = self.tracker.track( - untracked_instances=predicted_instances, img=image, t=frame_ind + predicted_frames.append( + LabeledFrame( + video=data_provider.videos[video_ind], + frame_idx=frame_ind, + instances=predicted_instances, + ) ) - predicted_frames.append( - sleap.LabeledFrame( - video=data_provider.videos[video_ind], - frame_idx=frame_ind, - instances=predicted_instances, - ) - ) + # Set up threaded object builder. + prediction_queue = Queue() + object_builder = Thread(target=_object_builder) + object_builder.start() + + # Loop over batches. + try: + for ex in generator: + prediction_queue.put(ex) + + except KeyError as e: + # Gracefully handle seeking errors by early termination. + if "Unable to load frame" in str(e): + pass # TODO: Print warning obeying verbosity? (This code path is also + # called for interactive prediction where we don't want any spam.) + else: + raise + + finally: + prediction_queue.put(None) + object_builder.join() if self.tracker: self.tracker.final_pass(predicted_frames) @@ -2376,9 +2669,18 @@ def export_model( save_traces: bool = True, model_name: Optional[str] = None, tensors: Optional[Dict[str, str]] = None, + unrag_outputs: bool = True, + max_instances: Optional[int] = None, ): - - super().export_model(save_path, signatures, save_traces, model_name, tensors) + super().export_model( + save_path, + signatures, + save_traces, + model_name, + tensors, + unrag_outputs, + max_instances, + ) if self.confmap_config is not None: self.confmap_config.save_json( @@ -2427,6 +2729,10 @@ class BottomUpInferenceLayer(InferenceLayer): the predicted instances. This will result in slower inference times since the data must be copied off of the GPU, but is useful for visualizing the raw output of the model. + return_paf_graph: If `True`, the part affinity field graph will be returned + together with the predicted instances. The graph is obtained by parsing the + part affinity fields with the `paf_scorer` instance and is an intermediate + representation used during instance grouping. confmaps_ind: Index of the output tensor of the model corresponding to confidence maps. If `None` (the default), this will be detected automatically by searching for the first tensor that contains @@ -2455,6 +2761,7 @@ def __init__( integral_patch_size: int = 5, return_confmaps: bool = False, return_pafs: bool = False, + return_paf_graph: bool = False, confmaps_ind: Optional[int] = None, pafs_ind: Optional[int] = None, offsets_ind: Optional[int] = None, @@ -2510,6 +2817,7 @@ def __init__( self.integral_patch_size = integral_patch_size self.return_confmaps = return_confmaps self.return_pafs = return_pafs + self.return_paf_graph = return_paf_graph def forward_pass(self, data): """Run preprocessing and model inference on a batch.""" @@ -2610,6 +2918,10 @@ def call(self, data): If `BottomUpInferenceLayer.return_pafs` is `True`, the predicted PAFs will be returned in the `"part_affinity_fields"` key. + + If `BottomUpInferenceLayer.return_paf_graph` is `True`, the predicted PAF + graph will be returned in the `"peaks"`, `"peak_vals"`, `"peak_channel_inds"`, + `"edge_inds"`, `"edge_peak_inds"` and `"line_scores"` keys. """ cms, pafs, offsets = self.forward_pass(data) peaks, peak_vals, peak_channel_inds = self.find_peaks(cms, offsets) @@ -2617,6 +2929,9 @@ def call(self, data): predicted_instances, predicted_peak_scores, predicted_instance_scores, + edge_inds, + edge_peak_inds, + line_scores, ) = self.paf_scorer.predict(pafs, peaks, peak_vals, peak_channel_inds) # Adjust for input scaling. @@ -2636,6 +2951,13 @@ def call(self, data): out["confmaps"] = cms if self.return_pafs: out["part_affinity_fields"] = pafs + if self.return_paf_graph: + out["peaks"] = peaks + out["peak_vals"] = peak_vals + out["peak_channel_inds"] = peak_channel_inds + out["edge_inds"] = edge_inds + out["edge_peak_inds"] = edge_peak_inds + out["line_scores"] = line_scores return out @@ -2731,6 +3053,10 @@ class BottomUpPredictor(Predictor): min_line_scores: Minimum line score (between -1 and 1) required to form a match between candidate point pairs. Useful for rejecting spurious detections when there are no better ones. + max_instances: If not `None`, discard instances beyond this count when + predicting, regardless of whether filtering is done at the tracking stage. + This is useful for preventing extraneous instances from being created when + tracking is not being applied. """ bottomup_config: TrainingJobConfig @@ -2746,6 +3072,7 @@ class BottomUpPredictor(Predictor): dist_penalty_weight: float = 1.0 paf_line_points: int = 10 min_line_scores: float = 0.25 + max_instances: Optional[int] = None def _initialize_inference_model(self): """Initialize the inference model from the trained model and configuration.""" @@ -2765,6 +3092,8 @@ def _initialize_inference_model(self): peak_threshold=self.peak_threshold, refinement="integral" if self.integral_refinement else "local", integral_patch_size=self.integral_patch_size, + cm_output_stride=self.bottomup_config.model.heads.multi_instance.confmaps.output_stride, + paf_output_stride=self.bottomup_config.model.heads.multi_instance.pafs.output_stride, ) ) @@ -2789,6 +3118,8 @@ def from_trained_models( dist_penalty_weight: float = 1.0, paf_line_points: int = 10, min_line_scores: float = 0.25, + resize_input_layer: bool = True, + max_instances: Optional[int] = None, ) -> "BottomUpPredictor": """Create predictor from a saved model. @@ -2817,6 +3148,12 @@ def from_trained_models( min_line_scores: Minimum line score (between -1 and 1) required to form a match between candidate point pairs. Useful for rejecting spurious detections when there are no better ones. + resize_input_layer: If True, the the input layer of the `tf.Keras.model` is + resized to (None, None, None, num_color_channels). + max_instances: If not `None`, discard instances beyond this count when + predicting, regardless of whether filtering is done at the tracking + stage. This is useful for preventing extraneous instances from being + created when tracking is not being applied. Returns: An instance of `BottomUpPredictor` with the loaded model. @@ -2828,6 +3165,10 @@ def from_trained_models( bottomup_model.keras_model = tf.keras.models.load_model( bottomup_keras_model_path, compile=False ) + if resize_input_layer: + bottomup_model.keras_model = reset_input_layer( + keras_model=bottomup_model.keras_model, new_shape=None + ) obj = cls( bottomup_config=bottomup_config, bottomup_model=bottomup_model, @@ -2839,6 +3180,7 @@ def from_trained_models( dist_penalty_weight=dist_penalty_weight, paf_line_points=paf_line_points, min_line_scores=min_line_scores, + max_instances=max_instances, ) obj._initialize_inference_model() return obj @@ -2866,58 +3208,97 @@ def _make_labeled_frames_from_generator( arrays returned from the inference result generator. """ skeleton = self.bottomup_config.data.labels.skeletons[0] - - # Loop over batches. predicted_frames = [] - for ex in generator: - if "n_valid" in ex: - # Crop possibly variable length results. - ex["instance_peaks"] = [ - x[:n] for x, n in zip(ex["instance_peaks"], ex["n_valid"]) - ] - ex["instance_peak_vals"] = [ - x[:n] for x, n in zip(ex["instance_peak_vals"], ex["n_valid"]) - ] - ex["instance_scores"] = [ - x[:n] for x, n in zip(ex["instance_scores"], ex["n_valid"]) - ] + def _object_builder(): + while True: + ex = prediction_queue.get() + if ex is None: + break - # Loop over frames. - for image, video_ind, frame_ind, points, confidences, scores in zip( - ex["image"], - ex["video_ind"], - ex["frame_ind"], - ex["instance_peaks"], - ex["instance_peak_vals"], - ex["instance_scores"], - ): + if "n_valid" in ex: + # Crop possibly variable length results. + ex["instance_peaks"] = [ + x[:n] for x, n in zip(ex["instance_peaks"], ex["n_valid"]) + ] + ex["instance_peak_vals"] = [ + x[:n] for x, n in zip(ex["instance_peak_vals"], ex["n_valid"]) + ] + ex["instance_scores"] = [ + x[:n] for x, n in zip(ex["instance_scores"], ex["n_valid"]) + ] + + # Loop over frames. + for image, video_ind, frame_ind, points, confidences, scores in zip( + ex["image"], + ex["video_ind"], + ex["frame_ind"], + ex["instance_peaks"], + ex["instance_peak_vals"], + ex["instance_scores"], + ): + # Loop over instances. + predicted_instances = [] + for pts, confs, score in zip(points, confidences, scores): + if np.isnan(pts).all(): + continue + + predicted_instances.append( + PredictedInstance.from_numpy( + points=pts, + point_confidences=confs, + instance_score=score, + skeleton=skeleton, + ) + ) - # Loop over instances. - predicted_instances = [] - for pts, confs, score in zip(points, confidences, scores): - predicted_instances.append( - sleap.instance.PredictedInstance.from_arrays( - points=pts, - point_confidences=confs, - instance_score=score, - skeleton=skeleton, + if self.max_instances is not None: + # Filter by score. + predicted_instances = sorted( + predicted_instances, key=lambda x: x.score, reverse=True + ) + predicted_instances = predicted_instances[ + : min(self.max_instances, len(predicted_instances)) + ] + + if self.tracker: + # Set tracks for predicted instances in this frame. + predicted_instances = self.tracker.track( + untracked_instances=predicted_instances, + img_hw=ex["image"].shape[-3:-1], + img=image, + t=frame_ind, ) - ) - if self.tracker: - # Set tracks for predicted instances in this frame. - predicted_instances = self.tracker.track( - untracked_instances=predicted_instances, img=image, t=frame_ind + predicted_frames.append( + LabeledFrame( + video=data_provider.videos[video_ind], + frame_idx=frame_ind, + instances=predicted_instances, + ) ) - predicted_frames.append( - sleap.LabeledFrame( - video=data_provider.videos[video_ind], - frame_idx=frame_ind, - instances=predicted_instances, - ) - ) + # Set up threaded object builder. + prediction_queue = Queue() + object_builder = Thread(target=_object_builder) + object_builder.start() + + # Loop over batches. + try: + for ex in generator: + prediction_queue.put(ex) + + except KeyError as e: + # Gracefully handle seeking errors by early termination. + if "Unable to load frame" in str(e): + pass # TODO: Print warning obeying verbosity? (This code path is also + # called for interactive prediction where we don't want any spam.) + else: + raise + + finally: + prediction_queue.put(None) + object_builder.join() if self.tracker: self.tracker.final_pass(predicted_frames) @@ -3265,6 +3646,8 @@ def _initialize_inference_model(self): peak_threshold=self.peak_threshold, refinement="integral" if self.integral_refinement else "local", integral_patch_size=self.integral_patch_size, + cm_output_stride=self.config.model.heads.multi_class_bottomup.confmaps.output_stride, + class_maps_output_stride=self.config.model.heads.multi_class_bottomup.class_maps.output_stride, ) ) @@ -3276,6 +3659,7 @@ def from_trained_models( peak_threshold: float = 0.2, integral_refinement: bool = True, integral_patch_size: int = 5, + resize_input_layer: bool = True, ) -> "BottomUpMultiClassPredictor": """Create predictor from a saved model. @@ -3294,6 +3678,8 @@ def from_trained_models( offset regression head. integral_patch_size: Size of patches to crop around each rough peak for integral refinement as an integer scalar. + resize_input_layer: If True, the the input layer of the `tf.Keras.model` is + resized to (None, None, None, num_color_channels). Returns: An instance of `BottomUpPredictor` with the loaded model. @@ -3303,6 +3689,10 @@ def from_trained_models( keras_model_path = get_keras_model_path(model_path) model = Model.from_config(config.model) model.keras_model = tf.keras.models.load_model(keras_model_path, compile=False) + if resize_input_layer: + model.keras_model = reset_input_layer( + keras_model=model.keras_model, new_shape=None + ) obj = cls( config=config, model=model, @@ -3357,47 +3747,73 @@ def _make_labeled_frames_from_generator( names = self.config.model.heads.multi_class_bottomup.class_maps.classes tracks = [sleap.Track(name=n, spawned_on=0) for n in names] - # Loop over batches. predicted_frames = [] - for ex in generator: - - # Loop over frames. - for image, video_ind, frame_ind, points, confidences, scores in zip( - ex["image"], - ex["video_ind"], - ex["frame_ind"], - ex["instance_peaks"], - ex["instance_peak_vals"], - ex["instance_scores"], - ): - # Loop over instances. - predicted_instances = [] - for i, (pts, confs, score) in enumerate( - zip(points, confidences, scores) + def _object_builder(): + while True: + ex = prediction_queue.get() + if ex is None: + return + + # Loop over frames. + for image, video_ind, frame_ind, points, confidences, scores in zip( + ex["image"], + ex["video_ind"], + ex["frame_ind"], + ex["instance_peaks"], + ex["instance_peak_vals"], + ex["instance_scores"], ): - if np.isnan(pts).all(): - continue - track = None - if tracks is not None and len(tracks) >= (i - 1): - track = tracks[i] - predicted_instances.append( - sleap.instance.PredictedInstance.from_arrays( - points=pts, - point_confidences=confs, - instance_score=np.nanmean(score), - skeleton=skeleton, - track=track, + # Loop over instances. + predicted_instances = [] + for i, (pts, confs, score) in enumerate( + zip(points, confidences, scores) + ): + if np.isnan(pts).all(): + continue + track = None + if tracks is not None and len(tracks) >= (i - 1): + track = tracks[i] + predicted_instances.append( + PredictedInstance.from_numpy( + points=pts, + point_confidences=confs, + instance_score=np.nanmean(confs), + skeleton=skeleton, + track=track, + tracking_score=np.nanmean(score), + ) ) - ) - predicted_frames.append( - sleap.LabeledFrame( - video=data_provider.videos[video_ind], - frame_idx=frame_ind, - instances=predicted_instances, + predicted_frames.append( + LabeledFrame( + video=data_provider.videos[video_ind], + frame_idx=frame_ind, + instances=predicted_instances, + ) ) - ) + + # Set up threaded object builder. + prediction_queue = Queue() + object_builder = Thread(target=_object_builder) + object_builder.start() + + # Loop over batches. + try: + for ex in generator: + prediction_queue.put(ex) + + except KeyError as e: + # Gracefully handle seeking errors by early termination. + if "Unable to load frame" in str(e): + pass # TODO: Print warning obeying verbosity? (This code path is also + # called for interactive prediction where we don't want any spam.) + else: + raise + + finally: + prediction_queue.put(None) + object_builder.join() return predicted_frames @@ -3506,7 +3922,7 @@ def __init__( if output_stride is None: # Attempt to automatically infer the output stride. output_stride = get_model_output_stride( - self.keras_model, 0, self.confmaps_ind + self.keras_model, output_ind=self.confmaps_ind ) self.output_stride = output_stride @@ -3735,11 +4151,13 @@ def export_model( save_traces: bool = True, model_name: Optional[str] = None, tensors: Optional[Dict[str, str]] = None, + unrag_outputs: bool = True, ): - self.instance_peaks.optimal_grouping = False - super().export_model(save_path, signatures, save_traces, model_name, tensors) + super().export_model( + save_path, signatures, save_traces, model_name, tensors, unrag_outputs + ) @attr.s(auto_attribs=True) @@ -3851,6 +4269,7 @@ def from_trained_models( peak_threshold: float = 0.2, integral_refinement: bool = True, integral_patch_size: int = 5, + resize_input_layer: bool = True, ) -> "TopDownMultiClassPredictor": """Create predictor from saved models. @@ -3872,9 +4291,11 @@ def from_trained_models( offset regression head. integral_patch_size: Size of patches to crop around each rough peak for integral refinement as an integer scalar. + resize_input_layer: If True, the the input layer of the `tf.Keras.model` is + resized to (None, None, None, num_color_channels). Returns: - An instance of `TopDownPredictor` with the loaded models. + An instance of `TopDownMultiClassPredictor` with the loaded models. One of the two models can be left as `None` to perform inference with ground truth data. This will only work with `LabelsReader` as the provider. @@ -3892,6 +4313,10 @@ def from_trained_models( centroid_model.keras_model = tf.keras.models.load_model( centroid_keras_model_path, compile=False ) + if resize_input_layer: + centroid_model.keras_model = reset_input_layer( + keras_model=centroid_model.keras_model, new_shape=None + ) else: centroid_config = None centroid_model = None @@ -3904,6 +4329,10 @@ def from_trained_models( confmap_model.keras_model = tf.keras.models.load_model( confmap_keras_model_path, compile=False ) + if resize_input_layer: + confmap_model.keras_model = reset_input_layer( + keras_model=confmap_model.keras_model, new_shape=None + ) else: confmap_config = None confmap_model = None @@ -4015,47 +4444,82 @@ def _make_labeled_frames_from_generator( ) tracks = [sleap.Track(name=n, spawned_on=0) for n in names] - # Loop over batches. predicted_frames = [] - for ex in generator: - - # Loop over frames. - for image, video_ind, frame_ind, points, confidences, scores in zip( - ex["image"], - ex["video_ind"], - ex["frame_ind"], - ex["instance_peaks"], - ex["instance_peak_vals"], - ex["instance_scores"], - ): - # Loop over instances. - predicted_instances = [] - for i, (pts, confs, score) in enumerate( - zip(points, confidences, scores) + def _object_builder(): + while True: + ex = prediction_queue.get() + if ex is None: + break + + # Loop over frames. + for ( + image, + video_ind, + frame_ind, + centroid_vals, + points, + confidences, + scores, + ) in zip( + ex["image"], + ex["video_ind"], + ex["frame_ind"], + ex["centroid_vals"], + ex["instance_peaks"], + ex["instance_peak_vals"], + ex["instance_scores"], ): - if np.isnan(pts).all(): - continue - track = None - if tracks is not None and len(tracks) >= (i - 1): - track = tracks[i] - predicted_instances.append( - sleap.instance.PredictedInstance.from_arrays( - points=pts, - point_confidences=confs, - instance_score=np.nanmean(score), - skeleton=skeleton, - track=track, + # Loop over instances. + predicted_instances = [] + for i, (pts, centroid_val, confs, score) in enumerate( + zip(points, centroid_vals, confidences, scores) + ): + if np.isnan(pts).all(): + continue + track = None + if tracks is not None and len(tracks) >= (i - 1): + track = tracks[i] + predicted_instances.append( + PredictedInstance.from_numpy( + points=pts, + point_confidences=confs, + instance_score=centroid_val, + skeleton=skeleton, + track=track, + tracking_score=score, + ) ) - ) - predicted_frames.append( - sleap.LabeledFrame( - video=data_provider.videos[video_ind], - frame_idx=frame_ind, - instances=predicted_instances, + predicted_frames.append( + LabeledFrame( + video=data_provider.videos[video_ind], + frame_idx=frame_ind, + instances=predicted_instances, + ) ) - ) + + # Set up threaded object builder. + prediction_queue = Queue() + object_builder = Thread(target=_object_builder) + object_builder.start() + + # Loop over batches. + try: + for ex in generator: + prediction_queue.put(ex) + + except KeyError as e: + # Gracefully handle seeking errors by early termination. + if "Unable to load frame" in str(e): + pass # TODO: Print warning obeying verbosity? (This code path is also + # called for interactive prediction where we don't want any spam.) + else: + raise + + finally: + prediction_queue.put(None) + object_builder.join() return predicted_frames @@ -4066,9 +4530,18 @@ def export_model( save_traces: bool = True, model_name: Optional[str] = None, tensors: Optional[Dict[str, str]] = None, + unrag_outputs: bool = True, + max_instances: Optional[int] = None, ): - - super().export_model(save_path, signatures, save_traces, model_name, tensors) + super().export_model( + save_path, + signatures, + save_traces, + model_name, + tensors, + unrag_outputs, + max_instances, + ) if self.confmap_config is not None: self.confmap_config.save_json( @@ -4080,6 +4553,263 @@ def export_model( ) +def make_model_movenet(model_name: str) -> tf.keras.Model: + """Load a MoveNet model by name. + + Args: + model_name: Name of the model ("lightning" or "thunder") + + Returns: + A tf.keras.Model ready for inference. + """ + model_path = MOVENET_MODELS[model_name]["model_path"] + image_size = MOVENET_MODELS[model_name]["image_size"] + + x_in = tf.keras.layers.Input([image_size, image_size, 3], name="image") + + x = tf.keras.layers.Lambda( + lambda x: tf.cast(x, dtype=tf.int32), name="cast_to_int32" + )(x_in) + layer = hub.KerasLayer( + model_path, + signature="serving_default", + output_key="output_0", + name="movenet_layer", + ) + x = layer(x) + + def split_outputs(x): + x_ = tf.reshape(x, [-1, 17, 3]) + keypoints = tf.gather(x_, [1, 0], axis=-1) + keypoints *= image_size + scores = tf.squeeze(tf.gather(x_, [2], axis=-1), axis=-1) + return keypoints, scores + + x = tf.keras.layers.Lambda(split_outputs, name="keypoints_and_scores")(x) + model = tf.keras.Model(x_in, x) + return model + + +class MoveNetInferenceLayer(InferenceLayer): + """Inference layer for applying single instance models. + + This layer encapsulates all of the inference operations requires for generating + predictions from a single instance confidence map model. This includes + preprocessing, model forward pass, peak finding and coordinate adjustment. + + Attributes: + keras_model: A `tf.keras.Model` that accepts rank-4 images as input and predicts + rank-4 confidence maps as output. This should be a model that is trained on + single instance confidence maps. + model_name: Variable indicating which model of MoveNet to use, either "lightning" + or "thunder." + input_scale: Float indicating if the images should be resized before being + passed to the model. + pad_to_stride: If not 1, input image will be paded to ensure that it is + divisible by this value (after scaling). This should be set to the max + stride of the model. + ensure_grayscale: Boolean indicating whether the type of input data is grayscale + or not. + ensure_float: Boolean indicating whether the type of data is float or not. + """ + + def __init__(self, model_name="lightning"): + self.keras_model = make_model_movenet(model_name) + self.model_name = model_name + self.image_size = MOVENET_MODELS[model_name]["image_size"] + super().__init__( + keras_model=self.keras_model, + input_scale=1.0, + pad_to_stride=1, + ensure_grayscale=False, + ensure_float=False, + ) + + def call(self, ex): + if type(ex) == dict: + img = ex["image"] + + else: + img = ex + + points, confidences = super().call(img) + points = tf.expand_dims(points, axis=1) # (batch, 1, nodes, 2) + confidences = tf.expand_dims(confidences, axis=1) # (batch, 1, nodes) + return {"instance_peaks": points, "confidences": confidences} + + +class MoveNetInferenceModel(InferenceModel): + """MoveNet prediction model. + + This model encapsulates the basic MoveNet approach. The images are passed to a model + which is trained to detect all body parts (17 joints in total). + + Attributes: + inference_layer: A MoveNet layer. This layer takes as input full images/videos and + outputs the detected peaks. + """ + + def __init__(self, inference_layer, **kwargs): + super().__init__(**kwargs) + self.inference_layer = inference_layer + + @property + def model_name(self): + return self.inference_layer.model_name + + @property + def image_size(self): + return self.inference_layer.image_size + + def call(self, x): + return self.inference_layer(x) + + +@attr.s(auto_attribs=True) +class MoveNetPredictor(Predictor): + """MoveNet predictor. + + This high-level class handles initialization, preprocessing and tracking using a + trained MoveNet model. + This should be initialized using the `from_trained_models()` constructor or the + high-level API (`sleap.load_model`). + + Attributes: + inference_model: A `sleap.nn.inference.MoveNetInferenceModel` that wraps + a trained `tf.keras.Model` to implement preprocessing and peak finding. + pipeline: A `sleap.nn.data.Pipeline` that loads the data and batches input data. + This will be updated dynamically if new data sources are used. + peak_threshold: Minimum confidence map value to consider a global peak as valid. + batch_size: The default batch size to use when loading data for inference. + Higher values increase inference speed at the cost of higher memory usage. + model_name: Variable indicating which model of MoveNet to use, either "lightning" + or "thunder." + """ + + inference_model: Optional[MoveNetInferenceModel] = attr.ib(default=None) + pipeline: Optional[Pipeline] = attr.ib(default=None, init=False) + peak_threshold: float = 0.2 + batch_size: int = 1 + model_name: str = "lightning" + + def _initialize_inference_model(self): + """Initialize the inference model from the trained model and configuration.""" + # Force batch size to be 1 since that's what the underlying model expects. + self.batch_size = 1 + self.inference_model = MoveNetInferenceModel( + MoveNetInferenceLayer( + model_name=self.model_name, + ) + ) + + @property + def data_config(self) -> DataConfig: + if self.inference_model is None: + self._initialize_inference_model() + + data_config = DataConfig() + data_config.preprocessing.resize_and_pad_to_target = True + data_config.preprocessing.target_height = self.inference_model.image_size + data_config.preprocessing.target_width = self.inference_model.image_size + return data_config + + @property + def is_grayscale(self) -> bool: + """Return whether the model expects grayscale inputs.""" + return False + + @classmethod + def from_trained_models( + cls, model_name: Text, peak_threshold: float = 0.2 + ) -> "MoveNetPredictor": + """Create the predictor from a saved model. + + Args: + model_name: Variable indicating which model of MoveNet to use, either "lightning" + or "thunder." + peak_threshold: Minimum confidence map value to consider a global peak as + valid. + + Returns: + An instance of`MoveNetPredictor` with the models loaded. + """ + + obj = cls( + model_name=model_name, + peak_threshold=peak_threshold, + batch_size=1, + ) + obj._initialize_inference_model() + return obj + + def _make_labeled_frames_from_generator( + self, generator: Iterator[Dict[str, np.ndarray]], data_provider: Provider + ) -> List[sleap.LabeledFrame]: + skeleton = MOVENET_SKELETON + predicted_frames = [] + + def _object_builder(): + while True: + ex = prediction_queue.get() + if ex is None: + break + + # Loop over frames. + for video_ind, frame_ind, points, confidences in zip( + ex["video_ind"], + ex["frame_ind"], + ex["instance_peaks"], + ex["confidences"], + ): + # Filter out points with low confidences + points[confidences < self.peak_threshold] = np.nan + + # Create predicted instances from MoveNet predictions + if np.isnan(points).all(): + predicted_instances = [] + else: + predicted_instances = [ + PredictedInstance.from_numpy( + points=points[0], # (nodes, 2) + point_confidences=confidences[0], # (nodes,) + instance_score=np.nansum(confidences[0]), # () + skeleton=skeleton, + ) + ] + + predicted_frames.append( + LabeledFrame( + video=data_provider.videos[video_ind], + frame_idx=frame_ind, + instances=predicted_instances, + ) + ) + + # Set up threaded object builder. + prediction_queue = Queue() + object_builder = Thread(target=_object_builder) + object_builder.start() + + # Loop over batches. + try: + for ex in generator: + prediction_queue.put(ex) + + except KeyError as e: + # Gracefully handle seeking errors by early termination. + if "Unable to load frame" in str(e): + pass # TODO: Print warning obeying verbosity? (This code path is also + # called for interactive prediction where we don't want any spam.) + else: + raise + + finally: + prediction_queue.put(None) + object_builder.join() + + return predicted_frames + + def load_model( model_path: Union[str, List[str]], batch_size: int = 4, @@ -4090,13 +4820,16 @@ def load_model( tracker_max_instances: Optional[int] = None, disable_gpu_preallocation: bool = True, progress_reporting: str = "rich", + resize_input_layer: bool = True, + max_instances: Optional[int] = None, ) -> Predictor: """Load a trained SLEAP model. Args: model_path: Path to model or list of path to models that were trained by SLEAP. These should be the directories that contain `training_job.json` and - `best_model.h5`. + `best_model.h5`. Special cases of non-SLEAP models include "movenet-thunder" + and "movenet-lightning". batch_size: Number of frames to predict at a time. Larger values result in faster inference speeds, but require more memory. peak_threshold: Minimum confidence map value to consider a peak as valid. @@ -4109,8 +4842,7 @@ def load_model( be performed. tracker_window: Number of frames of history to use when tracking. No effect when `tracker` is `None`. - tracker_max_instances: If not `None`, discard instances beyond this count when - tracking. No effect when `tracker` is `None`. + tracker_max_instances: If not `None`, create at most this many tracks. disable_gpu_preallocation: If `True` (the default), initialize the GPU and disable preallocation of memory. This is necessary to prevent freezing on some systems with low GPU memory and has negligible impact on performance. @@ -4122,6 +4854,12 @@ def load_model( for programmatic progress monitoring. If `"none"`, nothing is displayed during inference -- this is recommended when running on clusters or headless machines where the output is captured to a log file. + resize_input_layer: If True, the the input layer of the `tf.Keras.model` is + resized to (None, None, None, num_color_channels). + max_instances: If not `None`, discard instances beyond this count when + predicting, regardless of whether filtering is done at the tracking stage. + This is useful for preventing extraneous instances from being created when + tracking is not being applied. Returns: An instance of a `Predictor` based on which model type was detected. @@ -4140,42 +4878,71 @@ def load_model( See also: TopDownPredictor, BottomUpPredictor, SingleInstancePredictor """ - if isinstance(model_path, str): - model_paths = [model_path] - else: - model_paths = model_path - # Uncompress ZIP packaged models. - tmp_dirs = [] - for i, model_path in enumerate(model_paths): - if model_path.endswith(".zip"): - # Create temp dir on demand. - tmp_dir = tempfile.TemporaryDirectory() - tmp_dirs.append(tmp_dir) + def unpack_sleap_model(model_path): + """Returns uncompressed ZIP packaged model path. - # Remove the temp dir when program exits in case something goes wrong. - atexit.register(shutil.rmtree, tmp_dir.name, ignore_errors=True) + Also returns `TemporaryDirectory` where model was extracted to. + """ + if isinstance(model_path, str): + model_paths = [model_path] + else: + model_paths = model_path + + # Uncompress ZIP packaged models. + tmp_dirs = [] + for i, model_path in enumerate(model_paths): + mp = Path(model_path) + if model_path.endswith(".zip"): + # Create temp dir on demand. + tmp_dir = tempfile.TemporaryDirectory() + tmp_dirs.append(tmp_dir) + + # Remove the temp dir when program exits in case something goes wrong. + atexit.register(shutil.rmtree, tmp_dir.name, ignore_errors=True) + + # Extract and replace in the list. + shutil.unpack_archive(model_path, extract_dir=tmp_dir.name) + unzipped_mp = Path(tmp_dir.name, mp.name).with_suffix("") + if Path(unzipped_mp, "best_model.h5").exists(): + unzipped_model_path = str(unzipped_mp) + else: + unzipped_model_path = str(unzipped_mp.parent) + model_paths[i] = unzipped_model_path + + return model_paths, tmp_dirs - # Extract and replace in the list. - shutil.unpack_archive(model_path, extract_dir=tmp_dir.name) - model_paths[i] = tmp_dir.name + tmp_dirs = [] + if "movenet" in model_path: + model_paths = model_path + else: + model_paths, tmp_dirs = unpack_sleap_model(model_path) if disable_gpu_preallocation: sleap.disable_preallocation() - predictor = Predictor.from_model_paths( + predictor: Predictor = Predictor.from_model_paths( model_paths, peak_threshold=peak_threshold, integral_refinement=refinement == "integral", batch_size=batch_size, + resize_input_layer=resize_input_layer, + max_instances=max_instances, ) predictor.verbosity = progress_reporting if tracker is not None: + use_max_tracker = tracker_max_instances is not None + if use_max_tracker and not tracker.endswith("maxtracks"): + # Append maxtracks to the tracker name to use the right tracker variants. + tracker += "maxtracks" + predictor.tracker = Tracker.make_tracker_by_name( tracker=tracker, track_window=tracker_window, post_connect_single_breaks=True, - clean_instance_count=tracker_max_instances, + max_tracking=use_max_tracker, + max_tracks=tracker_max_instances, + # clean_instance_count=tracker_max_instances, ) # Remove temp dirs. @@ -4192,33 +4959,65 @@ def export_model( save_traces: bool = True, model_name: Optional[str] = None, tensors: Optional[Dict[str, str]] = None, + unrag_outputs: bool = True, + max_instances: Optional[int] = None, ): - """High level export of a trained SLEAP model as a frozen graph. Args: model_path: Path to model or list of path to models that were trained by SLEAP. These should be the directories that contain `training_job.json` and `best_model.h5`. - save_path: Path to output directory to store the frozen graph - signatures: String defining the input and output types for - computation. - save_traces: If `True` (default) the SavedModel will store the - function traces for each layer - model_name: (Optional) Name to give the model. If given, will be - added to the output json file containing meta information about the - model + save_path: Path to output directory to store the frozen graph. + signatures: String defining the input and output types for computation. + save_traces: If `True` (default) the SavedModel will store the function traces + for each layer. + model_name: (Optional) Name to give the model. If given, will be added to the + output json file containing meta information about the model. tensors: (Optional) Dictionary describing the predicted tensors (see - sleap.nn.data.utils.describe_tensors as an example) - + sleap.nn.data.utils.describe_tensors as an example). + unrag_outputs: If `True` (default), any ragged tensors will be + converted to normal tensors and padded with NaNs + max_instances: If set, determines the max number of instances that a + multi-instance model returns. This is enforced during centroid + cropping and therefore only compatible with TopDown models. """ + predictor = load_model(model_path, resize_input_layer=False) + + predictor.export_model( + save_path, + signatures, + save_traces, + model_name, + tensors, + unrag_outputs, + max_instances, + ) + + +def export_cli(args: Optional[list] = None): + """CLI for sleap-export.""" - predictor = load_model(model_path) - predictor.export_model(save_path, signatures, save_traces, model_name, tensors) + parser = _make_export_cli_parser() + args, _ = parser.parse_known_args(args=args) + print("Args:") + pprint(vars(args)) + print() + + export_model( + args.models, + args.export_path, + unrag_outputs=(not args.ragged), + max_instances=args.max_instances, + ) + + +def _make_export_cli_parser() -> argparse.ArgumentParser: + """Create argument parser for sleap-export CLI.""" -def export_cli(): parser = argparse.ArgumentParser() + parser.add_argument( "-m", "--model", @@ -4231,15 +5030,36 @@ def export_cli(): ) parser.add_argument( "-e", - "export_path", + "--export_path", type=str, nargs="?", default="exported_model", - help=("Path to data export model to."), + help=( + "Path to output directory where the frozen model will be exported to. " + "Defaults to a folder named 'exported_model'." + ), + ) + parser.add_argument( + "-r", + "--ragged", + action="store_true", + default=False, + help=( + "Keep tensors ragged if present. If ommited, convert ragged tensors" + " into regular tensors with NaN padding." + ), + ) + parser.add_argument( + "-n", + "--max_instances", + type=int, + help=( + "Limit maximum number of instances in multi-instance models. " + "Not available for ID models. Defaults to None." + ), ) - args, _ = parser.parse_known_args() - export_model(args["models"], args["export_path"]) + return parser def _make_cli_parser() -> argparse.ArgumentParser: @@ -4368,7 +5188,7 @@ def _make_cli_parser() -> argparse.ArgumentParser: device_group.add_argument( "--gpu", type=str, - default="0", + default="auto", help=( "Run training on the i-th GPU on the system. If 'auto', run on the GPU with" " the highest percentage of available memory." @@ -4411,6 +5231,15 @@ def _make_cli_parser() -> argparse.ArgumentParser: default=0.2, help="Minimum confidence map value to consider a peak as valid.", ) + parser.add_argument( + "-n", + "--max_instances", + type=int, + help=( + "Limit maximum number of instances in multi-instance models. " + "Not available for ID models. Defaults to None." + ), + ) # Deprecated legacy args. These will still be parsed for backward compatibility but # are hidden from the CLI help. @@ -4470,15 +5299,14 @@ def _make_provider_from_cli(args: argparse.Namespace) -> Tuple[Provider, str]: args: Parsed CLI namespace. Returns: - A tuple of `(provider, data_path)` with the data `Provider` and path to the data - that was specified in the args. + `(provider_list, data_path_list, output_path_list)` where `provider_list` contains the data providers, + `data_path_list` contains the paths to the specified data, and the `output_path_list` contains the list + of output paths if a CSV file with a column of output paths was provided; otherwise, `output_path_list` + defaults to None """ + # Figure out which input path to use. - labels_path = getattr(args, "labels", None) - if labels_path is not None: - data_path = labels_path - else: - data_path = args.data_path + data_path = args.data_path if data_path is None or data_path == "": raise ValueError( @@ -4486,33 +5314,117 @@ def _make_provider_from_cli(args: argparse.Namespace) -> Tuple[Provider, str]: "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), - ) + data_path_obj = Path(data_path) + + # Set output_path_list to None as a default to return later + output_path_list = None + + # Check that input value is valid + if not data_path_obj.exists(): + raise ValueError("Path to data_path does not exist") + + elif data_path_obj.is_file(): + # If the file is a CSV file, check for data_paths and output_paths + if data_path_obj.suffix.lower() == ".csv": + try: + data_path_column = None + # Read the CSV file + df = pd.read_csv(data_path) + + # collect data_paths from column + for col_index in range(df.shape[1]): + path_str = df.iloc[0, col_index] + if Path(path_str).exists(): + data_path_column = df.columns[col_index] + break + if data_path_column is None: + raise ValueError( + f"Column containing valid data_paths does not exist in the CSV file: {data_path}" + ) + raw_data_path_list = df[data_path_column].tolist() + + # optional output_path column to specify multiple output_paths + output_path_column_index = df.columns.get_loc(data_path_column) + 1 + if ( + output_path_column_index < df.shape[1] + and df.iloc[:, output_path_column_index].dtype == object + ): + # Ensure the next column exists + output_path_list = df.iloc[:, output_path_column_index].tolist() + else: + output_path_list = None + + except pd.errors.EmptyDataError as e: + raise ValueError(f"CSV file is empty: {data_path}. Error: {e}") from e + + # If the file is a text file, collect data_paths + elif data_path_obj.suffix.lower() == ".txt": + try: + with open(data_path_obj, "r") as file: + raw_data_path_list = [line.strip() for line in file.readlines()] + except Exception as e: + raise ValueError( + f"Error reading text file: {data_path}. Error: {e}" + ) from e else: - provider = LabelsReader(labels) + raw_data_path_list = [data_path_obj.as_posix()] - 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 - ) + raw_data_path_list = [Path(p) for p in raw_data_path_list] + + # Check for multiple video inputs + # Compile file(s) into a list for later iteration + elif data_path_obj.is_dir(): + raw_data_path_list = [ + file_path for file_path in data_path_obj.iterdir() if file_path.is_file() + ] + + # Provider list to accomodate multiple video inputs + provider_list = [] + data_path_list = [] + for file_path in raw_data_path_list: + # Create a provider for each file + if file_path.as_posix().endswith(".slp") and len(raw_data_path_list) > 1: + print(f"slp file skipped: {file_path.as_posix()}") + + elif file_path.as_posix().endswith(".slp"): + labels = sleap.load_file(file_path.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)) - return provider, data_path + data_path_list.append(file_path) + + 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=file_path.as_posix(), + example_indices=frame_list(args.frames), + **video_kwargs, + ) + ) + print(f"Video: {file_path.as_posix()}") + data_path_list.append(file_path) + # TODO: Clean this up. + except Exception: + print(f"Error reading file: {file_path.as_posix()}") + + return provider_list, data_path_list, output_path_list def _make_predictor_from_cli(args: argparse.Namespace) -> Predictor: @@ -4555,6 +5467,7 @@ def _make_predictor_from_cli(args: argparse.Namespace) -> Predictor: batch_size=batch_size, refinement="integral", progress_reporting=args.verbosity, + max_instances=args.max_instances, ) if type(predictor) == BottomUpPredictor: @@ -4580,14 +5493,14 @@ def _make_tracker_from_cli(args: argparse.Namespace) -> Optional[Tracker]: Returns: An instance of `Tracker` or `None` if tracking method was not specified. """ - policy_args = sleap.util.make_scoped_dictionary(vars(args), exclude_nones=True) + policy_args = make_scoped_dictionary(vars(args), exclude_nones=True) if "tracking" in policy_args: tracker = Tracker.make_tracker_by_name(**policy_args["tracking"]) return tracker return None -def main(args: list = None): +def main(args: Optional[list] = None): """Entrypoint for `sleap-track` CLI for running inference. Args: @@ -4601,13 +5514,11 @@ def main(args: list = None): parser = _make_cli_parser() # Parse inputs. - args, _ = parser.parse_known_args(args=args) + args, _ = parser.parse_known_args(args) print("Args:") pprint(vars(args)) print() - output_path = args.output - # Setup devices. if args.cpu or not sleap.nn.system.is_gpu_system(): sleap.nn.system.use_cpu_only() @@ -4618,7 +5529,19 @@ def main(args: list = None): sleap.nn.system.use_last_gpu() else: if args.gpu == "auto": - gpu_ind = np.argmax(sleap.nn.system.get_gpu_memory()) + free_gpu_memory = sleap.nn.system.get_gpu_memory() + if len(free_gpu_memory) > 0: + gpu_ind = np.argmax(free_gpu_memory) + mem = free_gpu_memory[gpu_ind] + logger.info( + f"Auto-selected GPU {gpu_ind} with {mem} MiB of free memory." + ) + else: + logger.info( + "Failed to query GPU memory from nvidia-smi. Defaulting to " + "first GPU." + ) + gpu_ind = 0 else: gpu_ind = int(args.gpu) sleap.nn.system.use_gpu(gpu_ind) @@ -4633,31 +5556,115 @@ def main(args: list = None): print() # Setup data loader. - provider, data_path = _make_provider_from_cli(args) + provider_list, data_path_list, output_path_list = _make_provider_from_cli(args) + + output_path = None + + # if output_path has not been extracted from a csv file yet + if output_path_list is None and args.output is not None: + output_path = args.output + output_path_obj = Path(output_path) + + # check if output_path is valid before running inference + if Path(output_path).is_file() and len(data_path_list) > 1: + raise ValueError( + "output_path argument must be a directory if multiple video inputs are given" + ) # Setup tracker. tracker = _make_tracker_from_cli(args) - # Either run inference (and tracking) or just run tracking - if args.models is not None: + if args.models is not None and "movenet" in args.models[0]: + args.models = args.models[0] - # Setup models. - predictor = _make_predictor_from_cli(args) - predictor.tracker = tracker + # 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! - labels_pr = predictor.predict(provider) + # Run inference on all files inputed + for i, (data_path, provider) in enumerate(zip(data_path_list, provider_list)): + # Setup models. + data_path_obj = Path(data_path) + predictor = _make_predictor_from_cli(args) + predictor.tracker = tracker + + # Run inference! + labels_pr = predictor.predict(provider) + + # if output path was not provided, create an output path + if output_path is None: + # if output path was not provided, create an output path + if output_path_list: + output_path = output_path_list[i] + + else: + output_path = data_path_obj.with_suffix(".predictions.slp") + + output_path_obj = Path(output_path) + + # if output_path was provided and multiple inputs were provided, create a directory to store outputs + elif len(data_path_list) > 1: + output_path_obj = Path(output_path) + output_path = ( + output_path_obj + / (data_path_obj.with_suffix(".predictions.slp")).name + ) + output_path_obj = Path(output_path) + # Create the containing directory if needed. + output_path_obj.parent.mkdir(exist_ok=True, parents=True) + + 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_obj.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:") + pprint(labels_pr.provenance) + print() + + labels_pr.provenance["args"] = vars(args) + + # Save results. + try: + labels_pr.save(output_path) + except Exception: + print("WARNING: Provided output path invalid.") + fallback_path = data_path_obj.with_suffix(".predictions.slp") + labels_pr.save(fallback_path) + print("Saved output:", output_path) - if output_path is None: - output_path = data_path + ".predictions.slp" + if args.open_in_gui: + subprocess.call(["sleap-label", output_path]) - labels_pr.provenance["model_paths"] = predictor.model_paths - labels_pr.provenance["predictor"] = type(predictor).__name__ + # Reset output_path for next iteration + output_path = args.output + # running tracking on existing prediction file elif getattr(args, "tracking.tracker") is not None: + provider = provider_list[0] + data_path = data_path_list[0] + # Load predictions + data_path = args.data_path print("Loading predictions...") - labels_pr = sleap.load_file(args.data_path) + labels_pr = sleap.load_file(data_path) frames = sorted(labels_pr.labeled_frames, key=lambda lf: lf.frame_idx) print("Starting tracker...") @@ -4669,6 +5676,40 @@ def main(args: list = None): 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]) + else: raise ValueError( "Neither tracker type nor path to trained models specified. " @@ -4676,40 +5717,3 @@ def main(args: list = None): "To retrack on predictions, must specify tracker. " "Use \"sleap-track --tracking.tracker ...' to specify tracker to use." ) - - 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]) - - -if __name__ == "__main__": - main() diff --git a/sleap/nn/paf_grouping.py b/sleap/nn/paf_grouping.py index 4a6a0a157..4091c026b 100644 --- a/sleap/nn/paf_grouping.py +++ b/sleap/nn/paf_grouping.py @@ -613,7 +613,6 @@ def match_candidates_sample( ) for k in range(n_edges): - is_edge_k = tf.squeeze(tf.where(edge_inds_sample == k), axis=1) edge_peak_inds_k = tf.gather(edge_peak_inds_sample, is_edge_k, axis=0) line_scores_k = tf.gather(line_scores_sample, is_edge_k, axis=0) @@ -836,10 +835,8 @@ def assign_connections_to_instances( # Loop through edge types. for edge_type, edge_connections in connections.items(): - # Loop through connections for the current edge. for connection in edge_connections: - # Notation: specific peaks are identified by (node_ind, peak_ind). src_id = PeakID(edge_type.src_node_ind, connection.src_peak_ind) dst_id = PeakID(edge_type.dst_node_ind, connection.dst_peak_ind) @@ -887,7 +884,6 @@ def assign_connections_to_instances( if min_instance_peaks > 0: if isinstance(min_instance_peaks, float): - if n_nodes is None: # Infer number of nodes if not specified. all_node_types = set() @@ -1240,7 +1236,6 @@ def _group_instances_sample( ) for sample in range(n_samples): - # Call sample-wise function in Eager mode. ( predicted_instances_sample, @@ -1700,4 +1695,11 @@ def predict( match_dst_peak_inds, match_line_scores, ) - return predicted_instances, predicted_peak_scores, predicted_instance_scores + return ( + predicted_instances, + predicted_peak_scores, + predicted_instance_scores, + edge_inds, + edge_peak_inds, + line_scores, + ) diff --git a/sleap/nn/peak_finding.py b/sleap/nn/peak_finding.py index 84dca00ae..e1fb43a6e 100644 --- a/sleap/nn/peak_finding.py +++ b/sleap/nn/peak_finding.py @@ -221,7 +221,7 @@ def find_global_peaks_rough( channels = tf.cast(tf.shape(cms)[-1], tf.int64) total_peaks = tf.cast(tf.shape(argmax_cols)[0], tf.int64) sample_subs = tf.range(total_peaks, dtype=tf.int64) // channels - channel_subs = tf.range(total_peaks, dtype=tf.int64) % channels + channel_subs = tf.math.mod(tf.range(total_peaks, dtype=tf.int64), channels) # Gather subscripts. peak_subs = tf.stack([sample_subs, argmax_rows, argmax_cols, channel_subs], axis=1) diff --git a/sleap/nn/system.py b/sleap/nn/system.py index 6acadff41..4cc3d1804 100644 --- a/sleap/nn/system.py +++ b/sleap/nn/system.py @@ -7,6 +7,8 @@ import tensorflow as tf from typing import List, Optional, Text import subprocess +import shutil +import os def get_all_gpus() -> List[tf.config.PhysicalDevice]: @@ -46,7 +48,17 @@ def get_current_gpu() -> tf.config.PhysicalDevice: def use_cpu_only(): """Hide GPUs from TensorFlow to ensure only the CPU is available.""" - tf.config.set_visible_devices([], "GPU") + try: + tf.config.set_visible_devices([], "GPU") + except RuntimeError as ex: + if ( + len(ex.args) > 0 + and ex.args[0] + == "Visible devices cannot be modified after being initialized" + ): + print( + "Failed to set visible GPU. Visible devices cannot be modified after being initialized." + ) def use_gpu(device_ind: int): @@ -56,7 +68,17 @@ def use_gpu(device_ind: int): device_ind: Index of the GPU within the list of system GPUs. """ gpus = get_all_gpus() - tf.config.set_visible_devices(gpus[device_ind], "GPU") + try: + tf.config.set_visible_devices(gpus[device_ind], "GPU") + except RuntimeError as ex: + if ( + len(ex.args) > 0 + and ex.args[0] + == "Visible devices cannot be modified after being initialized" + ): + print( + "Failed to set visible GPU. Visible devices cannot be modified after being initialized." + ) def use_first_gpu(): @@ -157,7 +179,7 @@ def summary(): for gpu in all_gpus: print(f" Device: {gpu.name}") print(f" Available: {gpu in gpus}") - print(f" Initalized: {is_initialized(gpu)}") + print(f" Initialized: {is_initialized(gpu)}") print( f" Memory growth: {tf.config.experimental.get_memory_growth(gpu)}" ) @@ -187,33 +209,41 @@ def best_logical_device_name() -> Text: def get_gpu_memory() -> List[int]: - """Return list of available GPU memory. + """Get the available memory on each GPU. Returns: - List of available GPU memory with indices corresponding to GPU indices. + A list of the available memory on each GPU in MiB. + """ + + if shutil.which("nvidia-smi") is None: + return [] + command = [ "nvidia-smi", - "--query-gpu=memory.free", + "--query-gpu=index,memory.free", "--format=csv", ] - memory_poll = subprocess.run(command, capture_output=True) + try: + memory_poll = subprocess.run(command, capture_output=True) + except (subprocess.SubprocessError, FileNotFoundError): + return [] - # Capture subprocess standard output subprocess_result = memory_poll.stdout + memory_string = subprocess_result.decode("ascii").split("\n")[1:-1] - # nvidia-smi returns an ascii encoded byte string separated by newlines (\n) - # Splitting gives a list where the final entry is an empty string. Slice it off - # and finally slice off the csv header in the 0th element. - memory_string = subprocess_result.decode("ascii").split("\n")[:-1][1:] + if "CUDA_VISIBLE_DEVICES" in os.environ.keys(): + cuda_visible_devices = os.environ["CUDA_VISIBLE_DEVICES"].split(",") + else: + cuda_visible_devices = None memory_list = [] for row in memory_string: - # Removing megabyte text returned by nvidia-smi - available_memory = row.split()[0] + gpu_index, available_memory = row.split(", ") + available_memory = available_memory.split(" MiB")[0] - # Append percent of GPU available to GPU ID, assume GPUs returned in index order - memory_list.append(int(available_memory)) + if cuda_visible_devices is None or gpu_index in cuda_visible_devices: + memory_list.append(int(available_memory)) return memory_list diff --git a/sleap/nn/tracker/components.py b/sleap/nn/tracker/components.py index e307df1ff..0b77f4ac9 100644 --- a/sleap/nn/tracker/components.py +++ b/sleap/nn/tracker/components.py @@ -12,9 +12,11 @@ """ + import operator from collections import defaultdict -from typing import List, Tuple, Optional, TypeVar, Callable +import logging +from typing import List, Tuple, Union, Optional, TypeVar, Callable import attr import numpy as np @@ -23,9 +25,26 @@ from sleap import PredictedInstance, Instance, Track from sleap.nn import utils +logger = logging.getLogger(__name__) + InstanceType = TypeVar("InstanceType", Instance, PredictedInstance) +def normalized_instance_similarity( + ref_instance: InstanceType, query_instance: InstanceType, img_hw: Tuple[int] +) -> float: + """Computes similarity between instances with normalized keypoints.""" + + normalize_factors = np.array((img_hw[1], img_hw[0])) + ref_visible = ~(np.isnan(ref_instance.points_array).any(axis=1)) + normalized_query_keypoints = query_instance.points_array / normalize_factors + normalized_ref_keypoints = ref_instance.points_array / normalize_factors + dists = np.sum((normalized_query_keypoints - normalized_ref_keypoints) ** 2, axis=1) + similarity = np.nansum(np.exp(-dists)) / np.sum(ref_visible) + + return similarity + + def instance_similarity( ref_instance: InstanceType, query_instance: InstanceType ) -> float: @@ -40,6 +59,95 @@ def instance_similarity( return similarity +def factory_object_keypoint_similarity( + keypoint_errors: Optional[Union[List, int, float]] = None, + score_weighting: bool = False, + normalization_keypoints: str = "all", +) -> Callable: + """Factory for similarity function based on object keypoints. + + Args: + keypoint_errors: The standard error of the distance between the predicted + keypoint and the true value, in pixels. + If None or empty list, defaults to 1. + If a scalar or singleton list, every keypoint has the same error. + If a list, defines the error for each keypoint, the length should be equal + to the number of keypoints in the skeleton. + score_weighting: If True, use `score` of `PredictedPoint` to weigh + `keypoint_errors`. If False, do not add a weight to `keypoint_errors`. + normalization_keypoints: Determine how to normalize similarity score. One of + ["all", "ref", "union"]. If "all", similarity score is normalized by number + of reference points. If "ref", similarity score is normalized by number of + visible reference points. If "union", similarity score is normalized by + number of points both visible in query and reference instance. + Default is "all". + + Returns: + Callable that returns object keypoint similarity between two `Instance`s. + + """ + keypoint_errors = 1 if keypoint_errors is None else keypoint_errors + with np.errstate(divide="ignore"): + kp_precision = 1 / (2 * np.array(keypoint_errors) ** 2) + + def object_keypoint_similarity( + ref_instance: InstanceType, query_instance: InstanceType + ) -> float: + nonlocal kp_precision + # Keypoints + ref_points = ref_instance.points_array + query_points = query_instance.points_array + # Keypoint scores + if score_weighting: + ref_scores = getattr(ref_instance, "scores", np.ones(len(ref_points))) + query_scores = getattr(query_instance, "scores", np.ones(len(query_points))) + else: + ref_scores = 1 + query_scores = 1 + # Number of keypoint for normalization + if normalization_keypoints in ("ref", "union"): + ref_visible = ~(np.isnan(ref_points).any(axis=1)) + if normalization_keypoints == "ref": + max_n_keypoints = np.sum(ref_visible) + elif normalization_keypoints == "union": + query_visible = ~(np.isnan(query_points).any(axis=1)) + max_n_keypoints = np.sum(np.logical_and(ref_visible, query_visible)) + else: # if normalization_keypoints == "all": + max_n_keypoints = len(ref_points) + if max_n_keypoints == 0: + return 0 + + # Make sure the sizes of kp_precision and n_points match + if kp_precision.size > 1 and 2 * kp_precision.size != ref_points.size: + # Correct kp_precision size to fit number of points + n_points = ref_points.size // 2 + mess = ( + "keypoint_errors array should have the same size as the number of " + f"keypoints in the instance: {kp_precision.size} != {n_points}" + ) + + if kp_precision.size > n_points: + kp_precision = kp_precision[:n_points] + mess += "\nTruncating keypoint_errors array." + + else: # elif kp_precision.size < n_points: + pad = n_points - kp_precision.size + kp_precision = np.pad(kp_precision, (0, pad), "edge") + mess += "\nPadding keypoint_errors array by repeating the last value." + logger.warning(mess) + + # Compute distances + dists = np.sum((query_points - ref_points) ** 2, axis=1) * kp_precision + + similarity = ( + np.nansum(ref_scores * query_scores * np.exp(-dists)) / max_n_keypoints + ) + + return similarity + + return object_keypoint_similarity + + def centroid_distance( ref_instance: InstanceType, query_instance: InstanceType, cache: dict = dict() ) -> float: @@ -410,8 +518,23 @@ def from_candidate_instances( candidate_instances: List[InstanceType], similarity_function: Callable, matching_function: Callable, + robust_best_instance: float = 1.0, ): + """Calculates (and stores) matches for a frame from candidate instance. + + Args: + untracked_instances: list of untracked instances in the frame. + candidate_instances: list of instances use as match. + similarity_function: a function that returns the similarity between + two instances (untracked and candidate). + matching_function: function used to find the best match from the + cost matrix. See the classmethod `from_cost_matrix`. + robust_best_instance (float): if the value is between 0 and 1 + (excluded), use a robust quantile similarity score for the + track. If the value is 1, use the max similarity (non-robust). + For selecting a robust score, 0.95 is a good value. + """ cost = np.ndarray((0,)) candidate_tracks = [] @@ -425,9 +548,8 @@ def from_candidate_instances( # Compute similarity matrix between untracked instances and best # candidate for each track. candidate_tracks = list(candidate_instances_by_track.keys()) - matching_similarities = np.full( - (len(untracked_instances), len(candidate_tracks)), np.nan - ) + dims = (len(untracked_instances), len(candidate_tracks)) + matching_similarities = np.full(dims, np.nan) for i, untracked_instance in enumerate(untracked_instances): @@ -443,11 +565,16 @@ def from_candidate_instances( for candidate_instance in track_instances ] - # Keep the best scoring instance for this track. - best_ind = np.argmax(track_matching_similarities) - - # Use the best similarity score for matching. - best_similarity = track_matching_similarities[best_ind] + if 0 < robust_best_instance < 1: + # Robust, use the similarity score in the q-quantile for matching. + best_similarity = np.quantile( + track_matching_similarities, + robust_best_instance, + ) + else: + # Non-robust, use the max similarity score for matching. + best_similarity = np.max(track_matching_similarities) + # Keep the best similarity score for this track. matching_similarities[i, j] = best_similarity # Perform matching between untracked instances and candidates. @@ -455,7 +582,10 @@ def from_candidate_instances( cost[np.isnan(cost)] = np.inf return cls.from_cost_matrix( - cost, untracked_instances, candidate_tracks, matching_function + cost, + untracked_instances, + candidate_tracks, + matching_function, ) @classmethod diff --git a/sleap/nn/tracking.py b/sleap/nn/tracking.py index af2e8ee2e..558aa9309 100644 --- a/sleap/nn/tracking.py +++ b/sleap/nn/tracking.py @@ -5,12 +5,15 @@ import attr import numpy as np import cv2 +import functools from typing import Callable, Deque, Dict, Iterable, List, Optional, Tuple from sleap import Track, LabeledFrame, Skeleton from sleap.nn.tracker.components import ( + factory_object_keypoint_similarity, instance_similarity, + normalized_instance_similarity, centroid_distance, instance_iou, hungarian_matching, @@ -88,6 +91,13 @@ class MatchedFrameInstances: img_t: Optional[np.ndarray] = None +@attr.s(auto_attribs=True, slots=True) +class MatchedFrameInstance: + t: int + instance_t: InstanceType + img_t: Optional[np.ndarray] = None + + @attr.s(auto_attribs=True, slots=True) class MatchedShiftedFrameInstances: ref_t: int @@ -98,13 +108,31 @@ class MatchedShiftedFrameInstances: @attr.s(auto_attribs=True) class FlowCandidateMaker: - """Class for producing optical flow shift matching candidates.""" + """Class for producing optical flow shift matching candidates. + + Attributes: + min_points: Minimum number of points that must be detected in the new frame in + order to generate a new shifted instance. + img_scale: Factor to scale the images by when computing optical flow. Decrease + this to increase performance at the cost of finer accuracy. Sometimes + decreasing the image scale can improve performance with fast movements. + of_window_size: Optical flow window size to consider at each pyramid scale + level. + of_max_levels: Number of pyramid scale levels to consider. This is different + from the scale parameter, which determines the initial image scaling. + save_shifted_instances: If True, save the shifted instances between elapsed + frames. + track_window: How many frames back to look for candidate instances to match + instances in the current frame against. + + """ min_points: int = 0 img_scale: float = 1.0 of_window_size: int = 21 of_max_levels: int = 3 save_shifted_instances: bool = False + track_window: int = 5 shifted_instances: Dict[ Tuple[int, int], List[ShiftedInstance] # keyed by (src_t, dst_t) @@ -114,6 +142,66 @@ class FlowCandidateMaker: def uses_image(self): return True + def get_shifted_instances_from_earlier_time( + self, ref_t: int, ref_img: np.ndarray, ref_instances: List[InstanceType], t: int + ) -> (np.ndarray, List[InstanceType]): + """Generate shifted instances and corresponding image from earlier time. + + Args: + ref_instances: Reference instances in the previous frame. + ref_img: Previous frame image as a numpy array. + ref_t: Previous frame time instance. + t: Current time instance. + """ + for ti in reversed(range(ref_t, t)): + if (ref_t, ti) in self.shifted_instances: + ref_shifted_instances = self.shifted_instances[(ref_t, ti)] + # Use shifted instance as a reference + if len(ref_shifted_instances.instances_t) > 0: + ref_img = ref_shifted_instances.img_t + ref_instances = ref_shifted_instances.instances_t + break + return [ref_img, ref_instances] + + def get_shifted_instances( + self, + ref_instances: List[InstanceType], + ref_img: np.ndarray, + ref_t: int, + img: np.ndarray, + t: int, + ) -> List[ShiftedInstance]: + """Returns a list of shifted instances and save shifted instances if needed. + + Args: + ref_instances: Reference instances in the previous frame. + ref_img: Previous frame image as a numpy array. + ref_t: Previous frame time instance. + img: Current frame image as a numpy array. + t: Current time instance. + """ + # Flow shift reference instances to current frame. + shifted_instances = self.flow_shift_instances( + ref_instances, + ref_img, + img, + min_shifted_points=self.min_points, + scale=self.img_scale, + window_size=self.of_window_size, + max_levels=self.of_max_levels, + ) + + # Save shifted instances. + if self.save_shifted_instances: + self.shifted_instances[(ref_t, t)] = MatchedShiftedFrameInstances( + ref_t, + t, + shifted_instances, + img, + ) + + return shifted_instances + def get_candidates( self, track_matching_queue: Deque[MatchedFrameInstances], @@ -121,6 +209,10 @@ def get_candidates( img: np.ndarray, ) -> List[ShiftedInstance]: candidate_instances = [] + + # Prune old shifted instances to save time and memory + self.prune_shifted_instances(t) + for matched_item in track_matching_queue: ref_t, ref_img, ref_instances = ( matched_item.t, @@ -128,41 +220,37 @@ def get_candidates( matched_item.instances_t, ) + # Check if shifted instance was computed at earlier time + if self.save_shifted_instances: + ref_img, ref_instances = self.get_shifted_instances_from_earlier_time( + ref_t, ref_img, ref_instances, t + ) + if len(ref_instances) > 0: - # Check if shifted instance was computed at earlier time - if self.save_shifted_instances: - for ti in reversed(range(ref_t, t)): - if (ref_t, ti) in self.shifted_instances: - ref_shifted_instances = self.shifted_instances[(ref_t, ti)] - # Use shifted instance as a reference - ref_img = ref_shifted_instances.img_t - ref_instances = ref_shifted_instances.instances_t - break - - # Flow shift reference instances to current frame. - shifted_instances = self.flow_shift_instances( - ref_instances, - ref_img, - img, - min_shifted_points=self.min_points, - scale=self.img_scale, - window_size=self.of_window_size, - max_levels=self.of_max_levels, + candidate_instances.extend( + self.get_shifted_instances(ref_instances, ref_img, ref_t, img, t) ) - # Add to candidate pool. - candidate_instances.extend(shifted_instances) + return candidate_instances - # Save shifted instances. - if self.save_shifted_instances: - self.shifted_instances[(ref_t, t)] = MatchedShiftedFrameInstances( - ref_t, - t, - shifted_instances, - img, - ) + def prune_shifted_instances(self, t: int): + """Prune the shifted instances older than `self.track_window`. - return candidate_instances + If `self.save_shifted_instances` is False, do nothing. + + Args + t: reference instances from a frame number more than `self.track_window` before + the current frame `t` will be pruned from the `self.shifted_instances` dict. + + """ + if not self.save_shifted_instances: + return + # Find ref_t older than track_window + shifted_instances_keys = list(self.shifted_instances.keys()) + for k in shifted_instances_keys: + if t - k[0] > self.track_window: + # Delete old items + del self.shifted_instances[k] @staticmethod def flow_shift_instances( @@ -269,6 +357,87 @@ def flow_shift_instances( return shifted_instances +@attr.s(auto_attribs=True) +class FlowMaxTracksCandidateMaker(FlowCandidateMaker): + """Class for producing optical flow shift matching candidates with maximum tracks. + + Attributes: + max_tracks: The maximum number of tracks to avoid redundant tracks. + + """ + + max_tracks: int = None + + @staticmethod + def get_ref_instances( + ref_t: int, + ref_img: np.ndarray, + track_matching_queue_dict: Dict[Track, Deque[MatchedFrameInstance]], + ) -> List[InstanceType]: + """Generates a list of instances based on the reference time and image. + + Args: + ref_t: Previous frame time instance. + ref_img: Previous frame image as a numpy array. + track_matching_queue_dict: A dictionary of mapping between the tracks + and the corresponding instances associated with the track. + """ + instances = [] + for track, matched_items in track_matching_queue_dict.items(): + instances += [ + item.instance_t + for item in matched_items + if item.t == ref_t and np.all(item.img_t == ref_img) + ] + return instances + + def get_candidates( + self, + track_matching_queue_dict: Dict[Track, Deque[MatchedFrameInstance]], + max_tracking: bool, + t: int, + img: np.ndarray, + *args, + **kwargs, + ) -> List[ShiftedInstance]: + candidate_instances = [] + + # Prune old shifted instances to save time and memory + self.prune_shifted_instances(t) + # Storing the tracks from the dictionary for counting purpose. + tracks = [] + + for track, matched_items in track_matching_queue_dict.items(): + if not max_tracking or len(tracks) < self.max_tracks: + tracks.append(track) + for matched_item in matched_items: + ref_t, ref_img = ( + matched_item.t, + matched_item.img_t, + ) + ref_instances = self.get_ref_instances( + ref_t, ref_img, track_matching_queue_dict + ) + + # Check if shifted instance was computed at earlier time + if self.save_shifted_instances: + ( + ref_img, + ref_instances, + ) = self.get_shifted_instances_from_earlier_time( + ref_t, ref_img, ref_instances, t + ) + + if len(ref_instances) > 0: + candidate_instances.extend( + self.get_shifted_instances( + ref_instances, ref_img, ref_t, img, t + ) + ) + + return candidate_instances + + @attr.s(auto_attribs=True) class SimpleCandidateMaker: """Class for producing list of matching candidates from prior frames.""" @@ -292,15 +461,44 @@ def get_candidates( return candidate_instances +@attr.s(auto_attribs=True) +class SimpleMaxTracksCandidateMaker(SimpleCandidateMaker): + """Class to generate instances with maximum number of tracks from prior frames.""" + + max_tracks: int = None + + def get_candidates( + self, + track_matching_queue_dict: Dict, + max_tracking: bool, + *args, + **kwargs, + ) -> List[InstanceType]: + # Create set of matchable candidate instances from each track. + candidate_instances = [] + tracks = [] + for track, matched_instances in track_matching_queue_dict.items(): + if not max_tracking or len(tracks) < self.max_tracks: + tracks.append(track) + for ref_instance in matched_instances: + if ref_instance.instance_t.n_visible_points >= self.min_points: + candidate_instances.append(ref_instance.instance_t) + return candidate_instances + + tracker_policies = dict( simple=SimpleCandidateMaker, flow=FlowCandidateMaker, + simplemaxtracks=SimpleMaxTracksCandidateMaker, + flowmaxtracks=FlowMaxTracksCandidateMaker, ) similarity_policies = dict( instance=instance_similarity, centroid=centroid_distance, iou=instance_iou, + normalized_instance=normalized_instance_similarity, + object_keypoint=factory_object_keypoint_similarity, ) match_policies = dict( @@ -311,6 +509,8 @@ def get_candidates( @attr.s(auto_attribs=True) class BaseTracker(abc.ABC): + """Abstract base class for tracker.""" + @property def is_valid(self): return False @@ -340,8 +540,7 @@ def get_name(self): @attr.s(auto_attribs=True) class Tracker(BaseTracker): - """ - Instance pose tracker. + """Instance pose tracker. Use by instantiated with the desired parameters and then calling the `track` method for each frame. @@ -360,22 +559,34 @@ class Tracker(BaseTracker): after the other tracking has run for all frames. min_new_track_points: We won't spawn a new track for an instance with fewer than this many points. + robust_best_instance (float): if the value is between 0 and 1 (excluded), + use a robust quantile similarity score for the track. If the value is 1, + use the max similarity (non-robust). For selecting a robust score, + 0.95 is a good value. + max_tracking: Max tracking is incorporated when this is set to true. """ + max_tracks: int = None track_window: int = 5 similarity_function: Optional[Callable] = instance_similarity matching_function: Callable = greedy_matching candidate_maker: object = attr.ib(factory=FlowCandidateMaker) + max_tracking: bool = False # To enable maximum tracking. - cleaner: Optional[Callable] = None # todo: deprecate + cleaner: Optional[Callable] = None # TODO: deprecate target_instance_count: int = 0 pre_cull_function: Optional[Callable] = None post_connect_single_breaks: bool = False + robust_best_instance: float = 1.0 min_new_track_points: int = 0 track_matching_queue: Deque[MatchedFrameInstances] = attr.ib() + # Hold track, instances with instances as a deque with length as track_window. + track_matching_queue_dict: Dict[Track, Deque[MatchedFrameInstance]] = attr.ib( + factory=dict + ) spawned_tracks: List[Track] = attr.ib(factory=list) save_tracked_instances: bool = False @@ -394,17 +605,33 @@ def _init_matching_queue(self): """Factory for instantiating default matching queue with specified size.""" return deque(maxlen=self.track_window) + @property + def has_max_tracking(self) -> bool: + return isinstance( + self.candidate_maker, + (SimpleMaxTracksCandidateMaker, FlowMaxTracksCandidateMaker), + ) + def reset_candidates(self): - self.track_matching_queue = deque(maxlen=self.track_window) + if self.has_max_tracking: + for track in self.track_matching_queue_dict: + self.track_matching_queue_dict[track] = deque(maxlen=self.track_window) + else: + self.track_matching_queue = deque(maxlen=self.track_window) @property def unique_tracks_in_queue(self) -> List[Track]: """Returns the unique tracks in the matching queue.""" unique_tracks = set() - for match_item in self.track_matching_queue: - for instance in match_item.instances_t: - unique_tracks.add(instance.track) + if self.has_max_tracking: + for track in self.track_matching_queue_dict.keys(): + unique_tracks.add(track) + + else: + for match_item in self.track_matching_queue: + for instance in match_item.instances_t: + unique_tracks.add(instance.track) return list(unique_tracks) @@ -415,6 +642,7 @@ def uses_image(self): def track( self, untracked_instances: List[InstanceType], + img_hw: Tuple[int], img: Optional[np.ndarray] = None, t: int = None, ) -> List[InstanceType]: @@ -422,25 +650,48 @@ def track( Args: untracked_instances: List of instances to assign to tracks. + img_hw: (height, width) of the image used to normalize the keypoints. img: Image data of the current frame for flow shifting. t: Current timestep. If not provided, increments from the internal queue. Returns: A list of the instances that were tracked. """ + if self.similarity_function == normalized_instance_similarity: + factory_normalized_instance = functools.partial( + normalized_instance_similarity, img_hw=img_hw + ) + self.similarity_function = factory_normalized_instance if self.candidate_maker is None: return untracked_instances # Infer timestep if not provided. if t is None: - if len(self.track_matching_queue) > 0: - - # Default to last timestep + 1 if available. - t = self.track_matching_queue[-1].t + 1 + if self.has_max_tracking: + if len(self.track_matching_queue_dict) > 0: + + # Default to last timestep + 1 if available. + # Here we find the track that has the most instances. + track_with_max_instances = max( + self.track_matching_queue_dict, + key=lambda track: len(self.track_matching_queue_dict[track]), + ) + t = ( + self.track_matching_queue_dict[track_with_max_instances][-1].t + + 1 + ) + else: + t = 0 else: - t = 0 + if len(self.track_matching_queue) > 0: + + # Default to last timestep + 1 if available. + t = self.track_matching_queue[-1].t + 1 + + else: + t = 0 # Initialize containers for tracked instances at the current timestep. tracked_instances = [] @@ -455,11 +706,19 @@ def track( self.pre_cull_function(untracked_instances) # Build a pool of matchable candidate instances. - candidate_instances = self.candidate_maker.get_candidates( - track_matching_queue=self.track_matching_queue, - t=t, - img=img, - ) + if self.has_max_tracking: + candidate_instances = self.candidate_maker.get_candidates( + track_matching_queue_dict=self.track_matching_queue_dict, + max_tracking=self.max_tracking, + t=t, + img=img, + ) + else: + candidate_instances = self.candidate_maker.get_candidates( + track_matching_queue=self.track_matching_queue, + t=t, + img=img, + ) # Determine matches for untracked instances in current frame. frame_matches = FrameMatches.from_candidate_instances( @@ -467,6 +726,7 @@ def track( candidate_instances=candidate_instances, similarity_function=self.similarity_function, matching_function=self.matching_function, + robust_best_instance=self.robust_best_instance, ) # Store the most recent match data (for outside inspection). @@ -482,10 +742,29 @@ def track( self.spawn_for_untracked_instances(frame_matches.unmatched_instances, t) ) - # Add the tracked instances to the matching buffer. - self.track_matching_queue.append( - MatchedFrameInstances(t, tracked_instances, img) - ) + # Add the tracked instances to the dictionary of matched instances. + if self.has_max_tracking: + for tracked_instance in tracked_instances: + if tracked_instance.track in self.track_matching_queue_dict: + self.track_matching_queue_dict[tracked_instance.track].append( + MatchedFrameInstance(t, tracked_instance, img) + ) + elif ( + not self.max_tracking + or len(self.track_matching_queue_dict) < self.max_tracks + ): + self.track_matching_queue_dict[tracked_instance.track] = deque( + maxlen=self.track_window + ) + self.track_matching_queue_dict[tracked_instance.track].append( + MatchedFrameInstance(t, tracked_instance, img) + ) + + else: + # Add the tracked instances to the matching buffer. + self.track_matching_queue.append( + MatchedFrameInstances(t, tracked_instances, img) + ) # Save tracked instances internally. if self.save_tracked_instances: @@ -517,6 +796,14 @@ def spawn_for_untracked_instances( if inst.n_visible_points < self.min_new_track_points: continue + # Skip if we've reached the maximum number of tracks. + if ( + self.has_max_tracking + and self.max_tracking + and len(self.track_matching_queue_dict) >= self.max_tracks + ): + break + # Spawn new track. new_track = Track(spawned_on=t, name=f"track_{len(self.spawned_tracks)}") self.spawned_tracks.append(new_track) @@ -549,10 +836,12 @@ def get_name(self): @classmethod def make_tracker_by_name( cls, + # Tracker options tracker: str = "flow", similarity: str = "instance", match: str = "greedy", track_window: int = 5, + robust: float = 1.0, min_new_track_points: int = 0, min_match_points: int = 0, # Optical flow options @@ -572,8 +861,20 @@ def make_tracker_by_name( # Kalman filter options kf_init_frame_count: int = 0, kf_node_indices: Optional[list] = None, + # Max tracking options + max_tracks: Optional[int] = None, + max_tracking: bool = False, + # Object keypoint similarity options + oks_errors: Optional[list] = None, + oks_score_weighting: bool = False, + oks_normalization: str = "all", **kwargs, ) -> BaseTracker: + # Parse max_tracking arguments, only True if max_tracks is not None and > 0 + max_tracking = max_tracking if max_tracks else False + if max_tracking and tracker in ("simple", "flow"): + # Force a candidate maker of 'maxtracks' type + tracker += "maxtracks" if tracker.lower() == "none": candidate_maker = None @@ -592,7 +893,14 @@ def make_tracker_by_name( raise ValueError(f"{match} is not a valid tracker matching function.") candidate_maker = tracker_policies[tracker](min_points=min_match_points) - similarity_function = similarity_policies[similarity] + if similarity == "object_keypoint": + similarity_function = factory_object_keypoint_similarity( + keypoint_errors=oks_errors, + score_weighting=oks_score_weighting, + normalization_keypoints=oks_normalization, + ) + else: + similarity_function = similarity_policies[similarity] matching_function = match_policies[match] if tracker == "flow": @@ -600,6 +908,10 @@ def make_tracker_by_name( candidate_maker.of_window_size = of_window_size candidate_maker.of_max_levels = of_max_levels candidate_maker.save_shifted_instances = save_shifted_instances + candidate_maker.track_window = track_window + + if tracker == "simplemaxtracks" or tracker == "flowmaxtracks": + candidate_maker.max_tracks = max_tracks cleaner = None if clean_instance_count: @@ -619,12 +931,15 @@ def pre_cull_function(inst_list): tracker_obj = cls( track_window=track_window, + robust_best_instance=robust, min_new_track_points=min_new_track_points, similarity_function=similarity_function, matching_function=matching_function, candidate_maker=candidate_maker, cleaner=cleaner, pre_cull_function=pre_cull_function, + max_tracking=max_tracking, + max_tracks=max_tracks, target_instance_count=target_instance_count, post_connect_single_breaks=post_connect_single_breaks, ) @@ -656,6 +971,19 @@ def get_by_name_factory_options(cls): ] options.append(option) + option = dict(name="max_tracking", default=False) + option["type"] = bool + option["help"] = ( + "If true then the tracker will cap the max number of tracks. " + "Falls back to false if `max_tracks` is not defined or 0." + ) + options.append(option) + + option = dict(name="max_tracks", default=None) + option["type"] = int + option["help"] = "Maximum number of tracks to be tracked by the tracker." + options.append(option) + option = dict(name="target_instance_count", default=0) option["type"] = int option["help"] = "Target number of instances to track per frame." @@ -707,6 +1035,14 @@ def get_by_name_factory_options(cls): option["options"] = list(match_policies.keys()) options.append(option) + option = dict(name="robust", default=1) + option["type"] = float + option["help"] = ( + "Robust quantile of similarity score for instance matching. " + "If equal to 1, keep the max similarity score (non-robust)." + ) + options.append(option) + option = dict(name="track_window", default=5) option["type"] = int option["help"] = "How many frames back to look for matches" @@ -740,11 +1076,12 @@ def get_by_name_factory_options(cls): option["help"] = "For optical-flow: Number of pyramid scale levels to consider" options.append(option) - option = dict(name="save_shifted_instances", default=False) - option["type"] = bool - option[ - "help" - ] = "For optical-flow: Save the shifted instances between elapsed frames" + option = dict(name="save_shifted_instances", default=0) + option["type"] = int + option["help"] = ( + "If non-zero and tracking.tracker is set to flow, save the shifted " + "instances between elapsed frames" + ) options.append(option) def int_list_func(s): @@ -762,6 +1099,42 @@ def int_list_func(s): ] = "For Kalman filter: Number of frames to track with other tracker. 0 means no Kalman filters will be used." options.append(option) + def float_list_func(s): + return [float(x.strip()) for x in s.split(",")] if s else None + + option = dict(name="oks_errors", default="1") + option["type"] = float_list_func + option["help"] = ( + "For Object Keypoint similarity: the standard error of the distance " + "between the predicted keypoint and the true value, in pixels.\n" + "If None or empty list, defaults to 1. If a scalar or singleton list, " + "every keypoint has the same error. If a list, defines the error for each " + "keypoint, the length should be equal to the number of keypoints in the " + "skeleton." + ) + options.append(option) + + option = dict(name="oks_score_weighting", default="0") + option["type"] = int + option["help"] = ( + "For Object Keypoint similarity: if 0 (default), only the distance between the reference " + "and query keypoint is used to compute the similarity. If 1, each distance is weighted " + "by the prediction scores of the reference and query keypoint." + ) + options.append(option) + + option = dict(name="oks_normalization", default="all") + option["type"] = str + option["options"] = ["all", "ref", "union"] + option["help"] = ( + "For Object Keypoint similarity: Determine how to normalize similarity score. " + "If 'all', similarity score is normalized by number of reference points. " + "If 'ref', similarity score is normalized by number of visible reference points. " + "If 'union', similarity score is normalized by number of points both visible " + "in query and reference instance." + ) + options.append(option) + return options @classmethod @@ -793,6 +1166,19 @@ class FlowTracker(Tracker): candidate_maker: object = attr.ib(factory=FlowCandidateMaker) +attr.s(auto_attribs=True) + + +class FlowMaxTracker(Tracker): + """Pre-configured tracker to use optical flow shifted candidates with max tracks.""" + + max_tracks: int = attr.ib(kw_only=True) + similarity_function: Callable = instance_similarity + matching_function: Callable = greedy_matching + candidate_maker: object = attr.ib(factory=FlowMaxTracksCandidateMaker) + max_tracking: bool = True + + @attr.s(auto_attribs=True) class SimpleTracker(Tracker): """A Tracker pre-configured to use simple, non-image-based candidates.""" @@ -802,6 +1188,17 @@ class SimpleTracker(Tracker): candidate_maker: object = attr.ib(factory=SimpleCandidateMaker) +@attr.s(auto_attribs=True) +class SimpleMaxTracker(Tracker): + """Pre-configured tracker to use simple, non-image-based candidates with max tracks.""" + + max_tracks: int = attr.ib(kw_only=True) + similarity_function: Callable = instance_iou + matching_function: Callable = hungarian_matching + candidate_maker: object = attr.ib(factory=SimpleMaxTracksCandidateMaker) + max_tracking: bool = True + + @attr.s(auto_attribs=True) class KalmanInitSet: init_frame_count: int @@ -1133,6 +1530,7 @@ def run_tracker(frames: List[LabeledFrame], tracker: BaseTracker) -> List[Labele track_args["img"] = lf.video[lf.frame_idx] else: track_args["img"] = None + track_args["img_hw"] = lf.image.shape[-3:-1] new_lf = LabeledFrame( frame_idx=lf.frame_idx, diff --git a/sleap/nn/training.py b/sleap/nn/training.py index a2d2b8d1d..c3692637c 100644 --- a/sleap/nn/training.py +++ b/sleap/nn/training.py @@ -1,84 +1,83 @@ """Training functionality and high level APIs.""" +import copy +import json +import logging import os +import platform import re +import shutil +from abc import ABC, abstractmethod from datetime import datetime from time import time -import logging -import shutil -import platform - -import tensorflow as tf -import numpy as np +from typing import Callable, List, Optional, Text, TypeVar, Union import attr -from typing import Optional, Callable, List, Union, Text, TypeVar -from abc import ABC, abstractmethod - import cattr -import json -import copy + +# Visualization +import matplotlib +import matplotlib.pyplot as plt +import numpy as np +import tensorflow as tf +from tensorflow.keras.callbacks import ( + CSVLogger, + EarlyStopping, + ModelCheckpoint, + ReduceLROnPlateau, + TensorBoard, +) import sleap -from sleap.util import get_package_file +from sleap import Labels +from sleap.nn.callbacks import ( + MatplotlibSaver, + ModelCheckpointOnEvent, + ProgressReporterZMQ, + TensorBoardMatplotlibWriter, + TrainingControllerZMQ, +) +# Outputs +# Optimization +# Data # Config from sleap.nn.config import ( - TrainingJobConfig, - SingleInstanceConfmapsHeadConfig, - CentroidsHeadConfig, CenteredInstanceConfmapsHeadConfig, - MultiInstanceConfig, + CentroidsHeadConfig, + CheckpointingConfig, + LabelsConfig, MultiClassBottomUpConfig, MultiClassTopDownConfig, + MultiInstanceConfig, + OptimizationConfig, + OutputsConfig, + SingleInstanceConfmapsHeadConfig, + TensorBoardConfig, + TrainingJobConfig, + ZMQConfig, ) - -# Model -from sleap.nn.model import Model - -# Data -from sleap.nn.config import LabelsConfig -from sleap.nn.data.pipelines import LabelsReader from sleap.nn.data.pipelines import ( + BottomUpMultiClassPipeline, + BottomUpPipeline, + CentroidConfmapsPipeline, + KeyMapper, + LabelsReader, Pipeline, SingleInstanceConfmapsPipeline, - CentroidConfmapsPipeline, TopdownConfmapsPipeline, - BottomUpPipeline, - BottomUpMultiClassPipeline, TopDownMultiClassPipeline, - KeyMapper, ) from sleap.nn.data.training import split_labels_train_val -# Optimization -from sleap.nn.config import OptimizationConfig -from sleap.nn.losses import OHKMLoss, PartLoss -from tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping - -# Outputs -from sleap.nn.config import ( - OutputsConfig, - ZMQConfig, - TensorBoardConfig, - CheckpointingConfig, -) -from sleap.nn.callbacks import ( - TrainingControllerZMQ, - ProgressReporterZMQ, - ModelCheckpointOnEvent, -) -from tensorflow.keras.callbacks import TensorBoard, ModelCheckpoint, CSVLogger - # Inference from sleap.nn.inference import FindInstancePeaks, SingleInstanceInferenceLayer +from sleap.nn.losses import OHKMLoss, PartLoss -# Visualization -import matplotlib -import matplotlib.pyplot as plt -from sleap.nn.callbacks import TensorBoardMatplotlibWriter, MatplotlibSaver -from sleap.nn.viz import plot_img, plot_confmaps, plot_peaks, plot_pafs - +# Model +from sleap.nn.model import Model +from sleap.nn.viz import plot_confmaps, plot_img, plot_pafs, plot_peaks +from sleap.util import get_package_file logger = logging.getLogger(__name__) @@ -89,11 +88,11 @@ class DataReaders: Attributes: training_labels_reader: LabelsReader pipeline provider for a training data from - a sleap.Labels instance. + a `Labels` instance. validation_labels_reader: LabelsReader pipeline provider for a validation data - from a sleap.Labels instance. + from a `Labels` instance. test_labels_reader: LabelsReader pipeline provider for a test set data from a - sleap.Labels instance. This is not necessary for training. + `Labels` instance. This is not necessary for training. """ training_labels_reader: LabelsReader @@ -104,9 +103,9 @@ class DataReaders: def from_config( cls, labels_config: LabelsConfig, - training: Union[Text, sleap.Labels], - validation: Union[Text, sleap.Labels, float], - test: Optional[Union[Text, sleap.Labels]] = None, + training: Union[Text, Labels], + validation: Union[Text, Labels, float], + test: Optional[Union[Text, Labels]] = None, video_search_paths: Optional[List[Text]] = None, update_config: bool = False, with_track_only: bool = False, @@ -128,7 +127,7 @@ def from_config( if labels_config.search_path_hints is not None: video_search_paths.extend(labels_config.search_path_hints) - # Update the config fields with arguments (if not a full sleap.Labels instance). + # Update the config fields with arguments (if not a full Labels instance). if update_config: if isinstance(training, Text): labels_config.training_labels = training @@ -154,18 +153,20 @@ def from_config( @classmethod def from_labels( cls, - training: Union[Text, sleap.Labels], - validation: Union[Text, sleap.Labels, float], - test: Optional[Union[Text, sleap.Labels]] = None, + training: Union[Text, Labels], + validation: Union[Text, Labels, float], + test: Optional[Union[Text, Labels]] = None, video_search_paths: Optional[List[Text]] = None, labels_config: Optional[LabelsConfig] = None, update_config: bool = False, with_track_only: bool = False, ) -> "DataReaders": - """Create data readers from sleap.Labels datasets as data providers.""" + """Create data readers from `Labels` datasets as data providers.""" if isinstance(training, str): logger.info(f"Loading training labels from: {training}") - training = sleap.load_file(training, search_paths=video_search_paths) + training: Labels = sleap.load_file( + training, search_paths=video_search_paths + ) if labels_config is not None and labels_config.split_by_inds: # First try to split by indices if specified in config. @@ -177,14 +178,13 @@ def from_labels( "Creating validation split from explicit indices " f"(n = {len(labels_config.validation_inds)})." ) - validation = training[labels_config.validation_inds] - + validation = training.extract(labels_config.validation_inds, copy=False) if labels_config.test_inds is not None and len(labels_config.test_inds) > 0: logger.info( "Creating test split from explicit indices " f"(n = {len(labels_config.test_inds)})." ) - test = training[labels_config.test_inds] + test = training.extract(labels_config.test_inds, copy=False) if ( labels_config.training_inds is not None @@ -194,14 +194,12 @@ def from_labels( "Creating training split from explicit indices " f"(n = {len(labels_config.training_inds)})." ) - training = training[labels_config.training_inds] + training = training.extract(labels_config.training_inds, copy=False) if isinstance(validation, str): # If validation is still a path, load it. logger.info(f"Loading validation labels from: {validation}") - validation = sleap.Labels.load_file( - validation, search_paths=video_search_paths - ) + validation = Labels.load_file(validation, search_paths=video_search_paths) elif isinstance(validation, float): logger.info( "Creating training and validation splits from " @@ -249,18 +247,18 @@ def from_labels( ) @property - def training_labels(self) -> sleap.Labels: - """Return the sleap.Labels underlying the training data reader.""" + def training_labels(self) -> Labels: + """Return the `Labels` underlying the training data reader.""" return self.training_labels_reader.labels @property - def validation_labels(self) -> sleap.Labels: - """Return the sleap.Labels underlying the validation data reader.""" + def validation_labels(self) -> Labels: + """Return the `Labels` underlying the validation data reader.""" return self.validation_labels_reader.labels @property - def test_labels(self) -> sleap.Labels: - """Return the sleap.Labels underlying the test data reader.""" + def test_labels(self) -> Labels: + """Return the `Labels` underlying the test data reader.""" if self.test_labels_reader is None: raise ValueError("No test labels provided to data reader.") return self.test_labels_reader.labels @@ -510,7 +508,7 @@ def setup_visualization( callbacks = [] try: - matplotlib.use("Qt5Agg") + matplotlib.use("QtAgg") except ImportError: print( "Unable to use Qt backend for matplotlib. " @@ -618,9 +616,9 @@ class Trainer(ABC): def from_config( cls, config: TrainingJobConfig, - training_labels: Optional[Union[Text, sleap.Labels]] = None, - validation_labels: Optional[Union[Text, sleap.Labels, float]] = None, - test_labels: Optional[Union[Text, sleap.Labels]] = None, + training_labels: Optional[Union[Text, Labels]] = None, + validation_labels: Optional[Union[Text, Labels, float]] = None, + test_labels: Optional[Union[Text, Labels]] = None, video_search_paths: Optional[List[Text]] = None, ) -> "Trainer": """Initialize the trainer from a training job configuration. @@ -745,6 +743,22 @@ def _setup_model(self): for i, output in enumerate(self.model.keras_model.outputs): logger.info(f" [{i}] = {output}") + # Resuming training if flagged + if self.config.model.base_checkpoint is not None: + # TODO (AL): Add flexibilty to resume from any checkpoint (e.g. + # latest_model, specific epoch, etc.) + + # Grab the 'best_model.h5' file from the previous training run + # and load it into the current model + previous_model_path = os.path.join( + self.config.model.base_checkpoint, "best_model.h5" + ) + + self.keras_model.load_weights(previous_model_path) + logger.info(f"Loaded previous model weights from {previous_model_path}") + else: + logger.info("Training from scratch") + @property def keras_model(self) -> tf.keras.Model: """Alias for `self.model.keras_model`.""" @@ -852,16 +866,16 @@ def _setup_outputs(self): self.config.save_json(os.path.join(self.run_path, "training_config.json")) # Save input (ground truth) labels. - sleap.Labels.save_file( + Labels.save_file( self.data_readers.training_labels_reader.labels, os.path.join(self.run_path, "labels_gt.train.slp"), ) - sleap.Labels.save_file( + Labels.save_file( self.data_readers.validation_labels_reader.labels, os.path.join(self.run_path, "labels_gt.val.slp"), ) if self.data_readers.test_labels_reader is not None: - sleap.Labels.save_file( + Labels.save_file( self.data_readers.test_labels_reader.labels, os.path.join(self.run_path, "labels_gt.test.slp"), ) @@ -932,7 +946,7 @@ def train(self): if self.config.outputs.save_outputs: if ( self.config.outputs.save_visualizations - and self.config.outputs.delete_viz_images + and not self.config.outputs.keep_viz_images ): self.cleanup() @@ -946,14 +960,14 @@ def evaluate(self): logger.info("Saving evaluation metrics to model folder...") sleap.nn.evals.evaluate_model( cfg=self.config, - labels_reader=self.data_readers.training_labels_reader, + labels_gt=self.data_readers.training_labels_reader, model=self.model, save=True, split_name="train", ) sleap.nn.evals.evaluate_model( cfg=self.config, - labels_reader=self.data_readers.validation_labels_reader, + labels_gt=self.data_readers.validation_labels_reader, model=self.model, save=True, split_name="val", @@ -961,7 +975,7 @@ def evaluate(self): if self.data_readers.test_labels_reader is not None: sleap.nn.evals.evaluate_model( cfg=self.config, - labels_reader=self.data_readers.test_labels_reader, + labels_gt=self.data_readers.test_labels_reader, model=self.model, save=True, split_name="test", @@ -983,7 +997,7 @@ def cleanup(self): def package(self): """Package model folder into a zip file for portability.""" - if self.config.outputs.delete_viz_images: + if not self.config.outputs.keep_viz_images: self.cleanup() logger.info(f"Packaging results to: {self.run_path}.zip") shutil.make_archive( @@ -1783,8 +1797,8 @@ def visualize_example(example): ) -def main(): - """Create CLI for training and run.""" +def create_trainer_using_cli(args: Optional[List] = None): + """Create CLI for training.""" import argparse parser = argparse.ArgumentParser() @@ -1825,6 +1839,15 @@ def main(): "specified in the training job config." ), ) + parser.add_argument( + "--base_checkpoint", + type=str, + default=None, + help=( + "Path to base checkpoint (directory containing best_model.h5) to resume " + "training from. Default is None." + ), + ) parser.add_argument( "--tensorboard", action="store_true", @@ -1841,6 +1864,14 @@ def main(): "already specified in the training job config." ), ) + parser.add_argument( + "--keep_viz", + action="store_true", + help=( + "Keep prediction visualization images in the run folder after training when " + "--save_viz is enabled." + ), + ) parser.add_argument( "--zmq", action="store_true", @@ -1849,6 +1880,18 @@ def main(): "job config." ), ) + parser.add_argument( + "--publish_port", + type=int, + default=9001, + help="Port to set up the publish address while using ZMQ, defaults to 9001.", + ) + parser.add_argument( + "--controller_port", + type=int, + default=9000, + help="Port to set up the controller address while using ZMQ, defaults to 9000.", + ) parser.add_argument( "--run_name", default="", @@ -1883,12 +1926,12 @@ def main(): ), ) - args, _ = parser.parse_known_args() + args, _ = parser.parse_known_args(args) # Find job configuration file. job_filename = args.training_job_path if not os.path.exists(job_filename): - profile_dir = get_package_file("sleap/training_profiles") + profile_dir = get_package_file("training_profiles") if os.path.exists(os.path.join(profile_dir, job_filename)): job_filename = os.path.join(profile_dir, job_filename) @@ -1903,6 +1946,10 @@ def main(): job_config.outputs.tensorboard.write_logs |= args.tensorboard job_config.outputs.zmq.publish_updates |= args.zmq job_config.outputs.zmq.subscribe_to_controller |= args.zmq + job_config.outputs.zmq.controller_address = "tcp://127.0.0.1:" + str( + args.controller_port + ) + job_config.outputs.zmq.publish_address = "tcp://127.0.0.1:" + str(args.publish_port) if args.run_name != "": job_config.outputs.run_name = args.run_name if args.prefix != "": @@ -1910,12 +1957,16 @@ def main(): if args.suffix != "": job_config.outputs.run_name_suffix = args.suffix job_config.outputs.save_visualizations |= args.save_viz + job_config.outputs.keep_viz_images = args.keep_viz if args.labels_path == "": args.labels_path = None args.video_paths = args.video_paths.split(",") if len(args.video_paths) == 0: args.video_paths = None + if args.base_checkpoint is not None: + job_config.model.base_checkpoint = args.base_checkpoint + logger.info("Versions:") sleap.versions() @@ -1944,7 +1995,19 @@ def main(): logger.info("Using the last GPU for acceleration.") else: if args.gpu == "auto": - gpu_ind = np.argmax(sleap.nn.system.get_gpu_memory()) + free_gpu_memory = sleap.nn.system.get_gpu_memory() + if len(free_gpu_memory) > 0: + gpu_ind = np.argmax(free_gpu_memory) + mem = free_gpu_memory[gpu_ind] + logger.info( + f"Auto-selected GPU {gpu_ind} with {mem} MiB of free memory." + ) + else: + logger.info( + "Failed to query GPU memory from nvidia-smi. Defaulting to " + "first GPU." + ) + gpu_ind = 0 else: gpu_ind = int(args.gpu) sleap.nn.system.use_gpu(gpu_ind) @@ -1966,6 +2029,13 @@ def main(): test_labels=args.test_labels, video_search_paths=args.video_paths, ) + + return trainer + + +def main(args: Optional[List] = None): + """Create CLI for training and run.""" + trainer = create_trainer_using_cli(args=args) trainer.train() diff --git a/sleap/nn/utils.py b/sleap/nn/utils.py index 2022412bf..3cb7c5130 100644 --- a/sleap/nn/utils.py +++ b/sleap/nn/utils.py @@ -3,7 +3,7 @@ import tensorflow as tf import numpy as np from collections import defaultdict -from typing import Dict, Tuple +from typing import Dict, Optional, Tuple from scipy.optimize import linear_sum_assignment @@ -126,3 +126,37 @@ def match_points(points1: tf.Tensor, points2: tf.Tensor) -> Tuple[tf.Tensor, tf. axis=-1, ) return tf_linear_sum_assignment(dists) + + +def reset_input_layer( + keras_model: tf.keras.Model, + new_shape: Optional[Tuple[Optional[int], Optional[int], Optional[int], int]] = None, +): + """Returns a copy of `keras_model` with input shape reset to `new_shape`. + + This method was modified from https://stackoverflow.com/a/58485055. + + Args: + keras_model: `tf.keras.Model` to return a copy of (with input shape reset). + new_shape: Shape of the returned model's input layer. + + Returns: + A copy of `keras_model` with input shape `new_shape`. + """ + + if new_shape is None: + new_shape = (None, None, None, keras_model.input_shape[-1]) + + model_config = keras_model.get_config() + model_config["layers"][0]["config"]["batch_input_shape"] = new_shape + new_model: tf.keras.Model = tf.keras.Model.from_config( + model_config, custom_objects={} + ) # Change custom objects if necessary + + # Iterate over all the layers that we want to get weights from + weights = [layer.get_weights() for layer in keras_model.layers] + for layer, weight in zip(new_model.layers, weights): + if len(weight) > 0: + layer.set_weights(weight) + + return new_model diff --git a/sleap/nn/viz.py b/sleap/nn/viz.py index 6fe5bf4ba..4fd6e8272 100644 --- a/sleap/nn/viz.py +++ b/sleap/nn/viz.py @@ -4,7 +4,11 @@ import matplotlib import matplotlib.pyplot as plt import seaborn as sns +import base64 from typing import Union, Tuple, Optional, Text +from sleap import Instance +from io import BytesIO +from PIL import Image def imgfig( @@ -194,7 +198,7 @@ def plot_instance( ms=10, bbox=None, scale=1.0, - **kwargs + **kwargs, ): """Plot a single instance with edge coloring.""" if cmap is None: @@ -296,3 +300,87 @@ def plot_bbox(bbox, **kwargs): bbox = bbox.bounding_box y1, x1, y2, x2 = bbox plt.plot([x1, x2, x2, x1, x1], [y1, y1, y2, y2, y1], "-", **kwargs) + + +def generate_skeleton_preview_image( + instance: Instance, square_bb: bool = True, thumbnail_size=(128, 128) +) -> bytes: + """Generate preview image for skeleton based on given instance. + + Args: + instance: A `sleap.Instance` object for which to generate the preview image from. + square_bb: A boolean flag for whether or not the preview image should be a square image + thumbnail_size: A tuple of (w,h) for what the size of the thumbnail image should be + + Returns: + A byte string encoding of the preview image. + """ + + def get_square_bounding_box(bb): + """Convert rectangular bounding box to square bounding box. + + Args: + bb: A tuple representing a bounding box in `sleap.Instance.bounding_box` + with the format [y1, x1, y2, x2] + + Returns: + A square bounding box in `PIL.Image.crop()` with the format [x1, y1, x2, y2] + """ + + y1, x1, y2, x2 = bb + + # Get side lengths + dist_x = x2 - x1 + dist_y = y2 - y1 + + mid_x = x1 + dist_x / 2 + mid_y = y1 + dist_y / 2 + + # Get max side length to use as square side length + max_dist = max(dist_x, dist_y) + + # Get new coordinates + new_x1 = mid_x - max_dist / 2 + new_x2 = mid_x + max_dist / 2 + new_y1 = mid_y - max_dist / 2 + new_y2 = mid_y + max_dist / 2 + + assert new_x2 - new_x1 == new_y2 - new_y1, ValueError( + f"{new_x2-new_x1} != {new_y2-new_y1}" + ) + return (new_x1, new_y1, new_x2, new_y2) + + if square_bb: + x1, y1, x2, y2 = get_square_bounding_box(instance.bounding_box) + else: + y1, x1, y2, x2 = instance.bounding_box + bb = [x1, y1, x2, y2] + bb = [coor - 20 if idx < 2 else coor + 20 for idx, coor in enumerate(bb)] + + frame = plot_img(instance.video.get_frame(instance.frame_idx)) + + # Custom formula for scaling line width and marker size based on bounding box size. + max_dim = max(abs(y1 - y2), abs(x1 - x2)) + ms = int(max_dim / 7) + lw = int(max_dim / 30) + skeleton = plot_instance( + instance, skeleton=instance.skeleton, lw=lw, ms=ms, color_by_node=False + ) + + fig = skeleton[0][0].figure + ax = fig.gca() + ax.get_yaxis().set_visible(False) + ax.get_xaxis().set_visible(False) + fig.set(facecolor="white", frameon=False) + + img_buf = BytesIO() + plt.savefig(img_buf, format="png", facecolor="white") + im = Image.open(img_buf) + im = im.crop(bb) + im.thumbnail(thumbnail_size) + + img_stream = BytesIO() + im.save(img_stream, format="png") + img_bytes = img_stream.getvalue() # image in binary format + img_b64 = base64.b64encode(img_bytes) + return img_b64 diff --git a/sleap/prefs.py b/sleap/prefs.py index 17137b23a..e043afc44 100644 --- a/sleap/prefs.py +++ b/sleap/prefs.py @@ -19,6 +19,7 @@ class Preferences(object): "palette": "standard", "bold lines": False, "trail length": 0, + "trail shade": "Normal", "trail width": 4.0, "trail node count": 1, "marker size": 4, @@ -26,6 +27,9 @@ class Preferences(object): "window state": b"", "node label size": 12, "show non-visible nodes": True, + "share usage data": True, + "node marker sizes": (1, 2, 3, 4, 6, 8, 12), + "node label sizes": (6, 9, 12, 18, 24, 36), } _filename = "preferences.yaml" @@ -41,10 +45,14 @@ def load_(self): """Load preferences from file (regardless of whether loaded already).""" try: self._prefs = util.get_config_yaml(self._filename) - if not hasattr(self._prefs, "get"): - self._prefs = self._defaults except FileNotFoundError: - self._prefs = self._defaults + pass + + self._prefs = self._prefs or {} + + for k, v in self._defaults.items(): + if k not in self._prefs: + self._prefs[k] = v def save(self): """Save preferences to file.""" diff --git a/sleap/skeleton.py b/sleap/skeleton.py index cd89bcd62..fbd1b909c 100644 --- a/sleap/skeleton.py +++ b/sleap/skeleton.py @@ -6,24 +6,24 @@ their connection to each other, and needed meta-data. """ -import attr -import cattr -import numpy as np -import jsonpickle -import json -import h5py +import base64 import copy - +import json import operator from enum import Enum +from io import BytesIO from itertools import count -from typing import Any, Dict, Iterable, List, Optional, Tuple, Union, Text +from typing import Any, Dict, Iterable, List, Optional, Text, Tuple, Union +import attr +import cattr +import h5py import networkx as nx +import numpy as np from networkx.readwrite import json_graph +from PIL import Image from scipy.io import loadmat - NodeRef = Union[str, "Node"] H5FileRef = Union[str, h5py.File] @@ -85,18 +85,521 @@ def matches(self, other: "Node") -> bool: return other.name == self.name and other.weight == self.weight -class Skeleton: +class SkeletonDecoder: + """Replace jsonpickle.decode with our own decoder. + + This function will decode the following from jsonpickle's encoded format: + + `Node` objects from + { + "py/object": "sleap.skeleton.Node", + "py/state": { "py/tuple": ["thorax1", 1.0] } + } + to `Node(name="thorax1", weight=1.0)` + + `EdgeType` objects from + { + "py/reduce": [ + { "py/type": "sleap.skeleton.EdgeType" }, + { "py/tuple": [1] } + ] + } + to `EdgeType(1)` + + `bytes` from + { + "py/b64": "aVZC..." + } + to `b"iVBO..."` + + and any repeated objects from + { + "py/id": 1 + } + to the object with the same reconstruction id (from top to bottom). + """ + + def __init__(self): + self.decoded_objects: List[Union[Node, EdgeType]] = [] + + def _decode_id(self, id: int) -> Union[Node, EdgeType]: + """Decode the object with the given `py/id` value of `id`. + + Args: + id: The `py/id` value to decode (1-indexed). + objects: The dictionary of objects that have already been decoded. + + Returns: + The object with the given `py/id` value. + """ + return self.decoded_objects[id - 1] + + @staticmethod + def _decode_state(state: dict) -> Node: + """Reconstruct the `Node` object from 'py/state' key in the serialized nx_graph. + + We support states in either dictionary or tuple format: + { + "py/state": { "py/tuple": ["thorax1", 1.0] } + } + or + { + "py/state": {"name": "thorax1", "weight": 1.0} + } + + Args: + state: The state to decode, i.e. state = dict["py/state"] + + Returns: + The `Node` object reconstructed from the state. + """ + + if "py/tuple" in state: + return Node(*state["py/tuple"]) + + return Node(**state) + + @staticmethod + def _decode_object_dict(object_dict) -> Node: + """Decode dict containing `py/object` key in the serialized nx_graph. + + Args: + object_dict: The dict to decode, i.e. + object_dict = {"py/object": ..., "py/state":...} + + Raises: + ValueError: If object_dict does not have 'py/object' and 'py/state' keys. + ValueError: If object_dict['py/object'] is not 'sleap.skeleton.Node'. + + Returns: + The decoded `Node` object. + """ + + if object_dict["py/object"] != "sleap.skeleton.Node": + raise ValueError("Only 'sleap.skeleton.Node' objects are supported.") + + node: Node = SkeletonDecoder._decode_state(state=object_dict["py/state"]) + return node + + def _decode_node(self, encoded_node: dict) -> Node: + """Decode an item believed to be an encoded `Node` object. + + Also updates the list of decoded objects. + + Args: + encoded_node: The encoded node to decode. + + Returns: + The decoded node and the updated list of decoded objects. + """ + + if isinstance(encoded_node, int): + # Using index mapping to replace the object (load from Labels) + return encoded_node + elif "py/object" in encoded_node: + decoded_node: Node = SkeletonDecoder._decode_object_dict(encoded_node) + self.decoded_objects.append(decoded_node) + elif "py/id" in encoded_node: + decoded_node: Node = self._decode_id(encoded_node["py/id"]) + + return decoded_node + + def _decode_nodes(self, encoded_nodes: List[dict]) -> List[Dict[str, Node]]: + """Decode the 'nodes' key in the serialized nx_graph. + + The encoded_nodes is a list of dictionary of two types: + - A dictionary with 'py/object' and 'py/state' keys. + - A dictionary with 'py/id' key. + + Args: + encoded_nodes: The list of encoded nodes to decode. + + Returns: + The decoded nodes. + """ + + decoded_nodes: List[Dict[str, Node]] = [] + for e_node_dict in encoded_nodes: + e_node = e_node_dict["id"] + d_node = self._decode_node(e_node) + decoded_nodes.append({"id": d_node}) + + return decoded_nodes + + def _decode_reduce_dict(self, reduce_dict: Dict[str, List[dict]]) -> EdgeType: + """Decode the 'reduce' key in the serialized nx_graph. + + The reduce_dict is a dictionary in the following format: + { + "py/reduce": [ + { "py/type": "sleap.skeleton.EdgeType" }, + { "py/tuple": [1] } + ] + } + + Args: + reduce_dict: The dictionary to decode i.e. reduce_dict = {"py/reduce": ...} + + Returns: + The decoded `EdgeType` object. + """ + + reduce_list = reduce_dict["py/reduce"] + has_py_type = has_py_tuple = False + for reduce_item in reduce_list: + if reduce_item is None: + # Sometimes the reduce list has None values, skip them + continue + if ( + "py/type" in reduce_item + and reduce_item["py/type"] == "sleap.skeleton.EdgeType" + ): + has_py_type = True + elif "py/tuple" in reduce_item: + edge_type: int = reduce_item["py/tuple"][0] + has_py_tuple = True + + if not has_py_type or not has_py_tuple: + raise ValueError( + "Only 'sleap.skeleton.EdgeType' objects are supported. " + "The 'py/reduce' list must have dictionaries with 'py/type' and " + "'py/tuple' keys." + f"\n\tHas py/type: {has_py_type}\n\tHas py/tuple: {has_py_tuple}" + ) + + edge = EdgeType(edge_type) + self.decoded_objects.append(edge) + + return edge + + def _decode_edge_type(self, encoded_edge_type: dict) -> EdgeType: + """Decode the 'type' key in the serialized nx_graph. + + Args: + encoded_edge_type: a dictionary with either 'py/id' or 'py/reduce' key. + + Returns: + The decoded `EdgeType` object. + """ + + if "py/reduce" in encoded_edge_type: + edge_type = self._decode_reduce_dict(encoded_edge_type) + else: + # Expect a "py/id" instead of "py/reduce" + edge_type = self._decode_id(encoded_edge_type["py/id"]) + return edge_type + + def _decode_links( + self, links: List[dict] + ) -> List[Dict[str, Union[int, Node, EdgeType]]]: + """Decode the 'links' key in the serialized nx_graph. + + The links are the edges in the graph and will have the following keys: + - source: The source node of the edge. + - target: The destination node of the edge. + - type: The type of the edge (e.g. BODY, SYMMETRY). + and more. + + Args: + encoded_links: The list of encoded links to decode. + """ + + for link in links: + for key, value in link.items(): + if key == "source": + link[key] = self._decode_node(value) + elif key == "target": + link[key] = self._decode_node(value) + elif key == "type": + link[key] = self._decode_edge_type(value) + + return links + + @staticmethod + def decode_preview_image( + img_b64: bytes, return_bytes: bool = False + ) -> Union[Image.Image, bytes]: + """Decode a skeleton preview image byte string representation to a `PIL.Image` + + Args: + img_b64: a byte string representation of a skeleton preview image + return_bytes: whether to return the decoded image as bytes + + Returns: + Either a PIL.Image of the skeleton preview image or the decoded image as bytes + (if `return_bytes` is True). + """ + bytes = base64.b64decode(img_b64) + if return_bytes: + return bytes + + buffer = BytesIO(bytes) + img = Image.open(buffer) + return img + + def _decode(self, json_str: str): + dicts = json.loads(json_str) + + # Enforce same format across template and non-template skeletons + if "nx_graph" not in dicts: + # Non-template skeletons use the dicts as the "nx_graph" + dicts = {"nx_graph": dicts} + + # Decode the graph + nx_graph = dicts["nx_graph"] + + self.decoded_objects = [] # Reset the decoded objects incase reusing decoder + for key, value in nx_graph.items(): + if key == "nodes": + nx_graph[key] = self._decode_nodes(value) + elif key == "links": + nx_graph[key] = self._decode_links(value) + + # Decode the preview image (if it exists) + preview_image = dicts.get("preview_image", None) + if preview_image is not None: + dicts["preview_image"] = SkeletonDecoder.decode_preview_image( + preview_image["py/b64"], return_bytes=True + ) + + return dicts + + @classmethod + def decode(cls, json_str: str) -> Dict: + """Decode the given json string into a dictionary. + + Returns: + A dict with `Node`s, `EdgeType`s, and `bytes` decoded/reconstructed. + """ + decoder = cls() + return decoder._decode(json_str) + + +class SkeletonEncoder: + """Replace jsonpickle.encode with our own encoder. + + The input is a dictionary containing python objects that need to be encoded as + JSON strings. The output is a JSON string that represents the input dictionary. + + `Node(name='neck', weight=1.0)` => + { + "py/object": "sleap.Skeleton.Node", + "py/state": {"py/tuple" ["neck", 1.0]} + } + + `` => + {"py/reduce": [ + {"py/type": "sleap.Skeleton.EdgeType"}, + {"py/tuple": [1] } + ] + }` + + Where `name` and `weight` are the attributes of the `Node` class; weight is always 1.0. + `EdgeType` is an enum with values `BODY = 1` and `SYMMETRY = 2`. + + See sleap.skeleton.Node and sleap.skeleton.EdgeType. + + If the object has been "seen" before, it will not be encoded as the full JSON string + but referenced by its `py/id`, which starts at 1 and indexes the objects in the + order they are seen so that the second time the first object is used, it will be + referenced as `{"py/id": 1}`. """ - The main object for representing animal skeletons. + + def __init__(self): + """Initializes a SkeletonEncoder instance.""" + # Maps object id to py/id + self._encoded_objects: Dict[int, int] = {} + + @classmethod + def encode(cls, data: Dict[str, Any]) -> str: + """Encodes the input dictionary as a JSON string. + + Args: + data: The data to encode. + + Returns: + json_str: The JSON string representation of the data. + """ + + # This is required for backwards compatibility with SLEAP <=1.3.4 + sorted_data = cls._recursively_sort_dict(data) + + encoder = cls() + encoded_data = encoder._encode(sorted_data) + json_str = json.dumps(encoded_data) + return json_str + + @staticmethod + def _recursively_sort_dict(dictionary: Dict[str, Any]) -> Dict[str, Any]: + """Recursively sorts the dictionary by keys.""" + sorted_dict = dict(sorted(dictionary.items())) + for key, value in sorted_dict.items(): + if isinstance(value, dict): + sorted_dict[key] = SkeletonEncoder._recursively_sort_dict(value) + elif isinstance(value, list): + for i, item in enumerate(value): + if isinstance(item, dict): + sorted_dict[key][i] = SkeletonEncoder._recursively_sort_dict( + item + ) + return sorted_dict + + def _encode(self, obj: Any) -> Any: + """Recursively encodes the input object. + + Args: + obj: The object to encode. Can be a dictionary, list, Node, EdgeType or + primitive data type. + + Returns: + The encoded object as a dictionary. + """ + if isinstance(obj, dict): + encoded_obj = {} + for key, value in obj.items(): + if key == "links": + encoded_obj[key] = self._encode_links(value) + else: + encoded_obj[key] = self._encode(value) + return encoded_obj + elif isinstance(obj, list): + return [self._encode(v) for v in obj] + elif isinstance(obj, EdgeType): + return self._encode_edge_type(obj) + elif isinstance(obj, Node): + return self._encode_node(obj) + else: + return obj # Primitive data types + + def _encode_links(self, links: List[Dict[str, Any]]) -> List[Dict[str, Any]]: + """Encodes the list of links (edges) in the skeleton graph. + + Args: + links: A list of dictionaries, each representing an edge in the graph. + + Returns: + A list of encoded edge dictionaries with keys ordered as specified. + """ + encoded_links = [] + for link in links: + # Use a regular dict (insertion order preserved in Python 3.7+) + encoded_link = {} + + for key, value in link.items(): + if key in ("source", "target"): + encoded_link[key] = self._encode_node(value) + elif key == "type": + encoded_link[key] = self._encode_edge_type(value) + else: + encoded_link[key] = self._encode(value) + encoded_links.append(encoded_link) + + return encoded_links + + def _encode_node(self, node: Union["Node", int]) -> Dict[str, Any]: + """Encodes a Node object. + + Args: + node: The Node object to encode or integer index. The latter requires that + the class has the `idx_to_node` attribute set. + + Returns: + The encoded `Node` object as a dictionary. + """ + if isinstance(node, int): + # We sometimes have the node object already replaced by its index (when + # `node_to_idx` is provided). In this case, the node is already encoded. + return node + + # Check if object has been encoded before + first_encoding = self._is_first_encoding(node) + py_id = self._get_or_assign_id(node, first_encoding) + if first_encoding: + # Full encoding + return { + "py/object": "sleap.skeleton.Node", + "py/state": {"py/tuple": [node.name, node.weight]}, + } + else: + # Reference by py/id + return {"py/id": py_id} + + def _encode_edge_type(self, edge_type: "EdgeType") -> Dict[str, Any]: + """Encodes an EdgeType object. + + Args: + edge_type: The EdgeType object to encode. Either `EdgeType.BODY` or + `EdgeType.SYMMETRY` enum with values 1 and 2 respectively. + + Returns: + The encoded EdgeType object as a dictionary. + """ + # Check if object has been encoded before + first_encoding = self._is_first_encoding(edge_type) + py_id = self._get_or_assign_id(edge_type, first_encoding) + if first_encoding: + # Full encoding + return { + "py/reduce": [ + {"py/type": "sleap.skeleton.EdgeType"}, + {"py/tuple": [edge_type.value]}, + ] + } + else: + # Reference by py/id + return {"py/id": py_id} + + def _get_or_assign_id(self, obj: Any, first_encoding: bool) -> int: + """Gets or assigns a py/id for the object. + + Args: + The object to get or assign a py/id for. + + Returns: + The py/id assigned to the object. + """ + # Object id is unique for each object in the current session + obj_id = id(obj) + # Assign a py/id to the object if it hasn't been assigned one yet + if first_encoding: + py_id = len(self._encoded_objects) + 1 # py/id starts at 1 + # Assign the py/id to the object and store it in _encoded_objects + self._encoded_objects[obj_id] = py_id + return self._encoded_objects[obj_id] + + def _is_first_encoding(self, obj: Any) -> bool: + """Checks if the object is being encoded for the first time. + + Args: + obj: The object to check. + + Returns: + True if this is the first encoding of the object, False otherwise. + """ + obj_id = id(obj) + first_time = obj_id not in self._encoded_objects + return first_time + + +class Skeleton: + """The main object for representing animal skeletons. The skeleton represents the constituent parts of the animal whose pose is being estimated. - An index variable used to give skeletons a default name that should - be unique across all skeletons. + Attributes: + _skeleton_idx: An index variable used to give skeletons a default name that + should be unique across all skeletons. + preview_image: A byte string containing an encoded preview image for the + skeleton. Used only for templates. + description: A text description of the skeleton. Used only for templates. + _is_template: Whether this skeleton is a template. Used only for templates. """ _skeleton_idx = count(0) + preview_image: Optional[bytes] = None + description: Optional[str] = None + _is_template: bool = False def __init__(self, name: str = None): """Initialize an empty skeleton object. @@ -121,6 +624,7 @@ def __repr__(self) -> str: """Return full description of the skeleton.""" return ( f"Skeleton(name='{self.name}', " + f"description='{self.description}', " f"nodes={self.node_names}, " f"edges={self.edge_names}, " f"symmetries={self.symmetry_names}" @@ -129,11 +633,13 @@ def __repr__(self) -> str: def __str__(self) -> str: """Return short readable description of the skeleton.""" + description = self.description nodes = ", ".join(self.node_names) edges = ", ".join([f"{s}->{d}" for (s, d) in self.edge_names]) symm = ", ".join([f"{s}<->{d}" for (s, d) in self.symmetry_names]) return ( "Skeleton(" + f"description={description}, " f"nodes=[{nodes}], " f"edges=[{edges}], " f"symmetries=[{symm}]" @@ -168,45 +674,68 @@ def dict_match(dict1, dict2): return True + @property + def is_template(self) -> bool: + """Return whether this skeleton is a template. + + If is_template is True, then the preview image and description are saved. + If is_template is False, then the preview image and description are not saved. + + Only provided template skeletons are considered templates. To save a new + template skeleton, change this to True before saving. + """ + return self._is_template + + @is_template.setter + def is_template(self, value: bool): + """Set whether this skeleton is a template.""" + + self._is_template = False + if value and ((self.preview_image is None) or (self.description is None)): + raise ValueError( + "For a skeleton to be a template, it must have both a preview image " + "and description. Checkout `generate_skeleton_preview_image` to " + "generate a preview image." + ) + + self._is_template = value + @property def is_arborescence(self) -> bool: """Return whether this skeleton graph forms an arborescence.""" - return nx.algorithms.tree.recognition.is_arborescence(self._graph) + return nx.algorithms.tree.recognition.is_arborescence(self.graph) @property def in_degree_over_one(self) -> List[Node]: - return [node for node, in_degree in self._graph.in_degree if in_degree > 1] + return [node for node, in_degree in self.graph.in_degree if in_degree > 1] @property def root_nodes(self) -> List[Node]: - return [node for node, in_degree in self._graph.in_degree if in_degree == 0] + return [node for node, in_degree in self.graph.in_degree if in_degree == 0] @property def cycles(self) -> List[List[Node]]: - return list(nx.algorithms.simple_cycles(self._graph)) + return list(nx.algorithms.simple_cycles(self.graph)) @property def graph(self): - """Return subgraph of BODY edges for skeleton.""" - edges = [ - (src, dst, key) - for src, dst, key, edge_type in self._graph.edges(keys=True, data="type") - if edge_type == EdgeType.BODY - ] - # TODO: properly induce subgraph for MultiDiGraph - # Currently, NetworkX will just return the nodes in the subgraph. - # See: https://stackoverflow.com/questions/16150557/networkxcreating-a-subgraph-induced-from-edges - return self._graph.edge_subgraph(edges) + """Return a view on the subgraph of body nodes and edges for skeleton.""" + + def edge_filter_fn(src, dst, edge_key): + edge_data = self._graph.get_edge_data(src, dst, edge_key) + return edge_data["type"] == EdgeType.BODY + + return nx.subgraph_view(self._graph, filter_edge=edge_filter_fn) @property def graph_symmetry(self): """Return subgraph of symmetric edges for skeleton.""" - edges = [ - (src, dst, key) - for src, dst, key, edge_type in self._graph.edges(keys=True, data="type") - if edge_type == EdgeType.SYMMETRY - ] - return self._graph.edge_subgraph(edges) + + def edge_filter_fn(src, dst, edge_key): + edge_data = self._graph.get_edge_data(src, dst, edge_key) + return edge_data["type"] == EdgeType.SYMMETRY + + return nx.subgraph_view(self._graph, filter_edge=edge_filter_fn) @staticmethod def find_unique_nodes(skeletons: List["Skeleton"]) -> List[Node]: @@ -800,8 +1329,7 @@ def __len__(self) -> int: return len(self.nodes) def relabel_node(self, old_name: str, new_name: str): - """ - Relabel a single node to a new name. + """Relabel a single node to a new name. Args: old_name: The old name of the node. @@ -813,8 +1341,7 @@ def relabel_node(self, old_name: str, new_name: str): self.relabel_nodes({old_name: new_name}) def relabel_nodes(self, mapping: Dict[str, str]): - """ - Relabel the nodes of the skeleton. + """Relabel the nodes of the skeleton. Args: mapping: A dictionary with the old labels as keys and new @@ -906,7 +1433,7 @@ def to_dict(obj: "Skeleton", node_to_idx: Optional[Dict[Node, int]] = None) -> D # This is a weird hack to serialize the whole _graph into a dict. # I use the underlying to_json and parse it. - return json.loads(obj.to_json(node_to_idx)) + return json.loads(obj.to_json(node_to_idx=node_to_idx)) @classmethod def from_dict(cls, d: Dict, node_to_idx: Dict[Node, int] = None) -> "Skeleton": @@ -953,8 +1480,7 @@ def from_names_and_edge_inds( return skeleton def to_json(self, node_to_idx: Optional[Dict[Node, int]] = None) -> str: - """ - Convert the :class:`Skeleton` to a JSON representation. + """Convert the :class:`Skeleton` to a JSON representation. Args: node_to_idx: optional dict which maps :class:`Node`sto index @@ -969,16 +1495,31 @@ def to_json(self, node_to_idx: Optional[Dict[Node, int]] = None) -> str: Returns: A string containing the JSON representation of the skeleton. """ - jsonpickle.set_encoder_options("simplejson", sort_keys=True, indent=4) + if node_to_idx is not None: - indexed_node_graph = nx.relabel_nodes( - G=self._graph, mapping=node_to_idx - ) # map nodes to int + # Map Nodes to int + indexed_node_graph = nx.relabel_nodes(G=self._graph, mapping=node_to_idx) else: + # Keep graph nodes as Node objects indexed_node_graph = self._graph # Encode to JSON - json_str = jsonpickle.encode(json_graph.node_link_data(indexed_node_graph)) + graph = json_graph.node_link_data(indexed_node_graph) + + # SLEAP v1.3.0 added `description` and `preview_image` to `Skeleton`, but saving + # these fields breaks data format compatibility. Currently, these are only + # added in our custom template skeletons. To ensure backwards data format + # compatibilty of user data, we only save these fields if they are not None. + if self.is_template: + data = { + "nx_graph": graph, + "description": self.description, + "preview_image": self.preview_image, + } + else: + data = graph + + json_str = SkeletonEncoder.encode(data) return json_str @@ -1012,8 +1553,7 @@ def save_json(self, filename: str, node_to_idx: Optional[Dict[Node, int]] = None def from_json( cls, json_str: str, idx_to_node: Dict[int, Node] = None ) -> "Skeleton": - """ - Instantiate :class:`Skeleton` from JSON string. + """Instantiate :class:`Skeleton` from JSON string. Args: json_str: The JSON encoded Skeleton. @@ -1027,7 +1567,9 @@ def from_json( Returns: An instance of the `Skeleton` object decoded from the JSON. """ - graph = json_graph.node_link_graph(jsonpickle.decode(json_str)) + dicts: dict = SkeletonDecoder.decode(json_str) + nx_graph = dicts.get("nx_graph", dicts) + graph = json_graph.node_link_graph(nx_graph) # Replace graph node indices with corresponding nodes from node_map if idx_to_node is not None: @@ -1035,6 +1577,8 @@ def from_json( skeleton = Skeleton() skeleton._graph = graph + skeleton.description = dicts.get("description", None) + skeleton.preview_image = dicts.get("preview_image", None) return skeleton @@ -1042,8 +1586,7 @@ def from_json( def load_json( cls, filename: str, idx_to_node: Dict[int, Node] = None ) -> "Skeleton": - """ - Load a skeleton from a JSON file. + """Load a skeleton from a JSON file. This method will load the Skeleton from JSON file saved with; :meth:`~Skeleton.save_json` diff --git a/sleap/skeletons/bees.json b/sleap/skeletons/bees.json new file mode 100644 index 000000000..819c6a894 --- /dev/null +++ b/sleap/skeletons/bees.json @@ -0,0 +1 @@ +{"description": "Template Skeleton for bees reference dataset.", "nx_graph": {"directed": true, "graph": {"name": "Skeleton-1", "num_edges_inserted": 20}, "links": [{"edge_insert_idx": 0, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["thorax1", 1.0]}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["head1", 1.0]}}, "type": {"py/reduce": [{"py/type": "sleap.skeleton.EdgeType"}, {"py/tuple": [1]}]}}, {"edge_insert_idx": 1, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["abdomen1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 6, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegL1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 8, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 10, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["midlegL1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 12, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["midlegR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 14, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegL1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 15, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 18, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["wingL1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 19, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["wingR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 2, "key": 0, "source": {"py/id": 2}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["antennaL1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 3, "key": 0, "source": {"py/id": 2}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["antennaR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 4, "key": 0, "source": {"py/id": 13}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["antennaL2", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 5, "key": 0, "source": {"py/id": 14}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["antennaR2", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 7, "key": 0, "source": {"py/id": 5}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegL2", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 9, "key": 0, "source": {"py/id": 6}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegR2", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 11, "key": 0, "source": {"py/id": 7}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["midlegL2", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 13, "key": 0, "source": {"py/id": 8}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["midlegR2", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 16, "key": 0, "source": {"py/id": 9}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegL2", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 17, "key": 0, "source": {"py/id": 10}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegR2", 1.0]}}, "type": {"py/id": 3}}], "multigraph": true, "nodes": [{"id": {"py/id": 1}}, {"id": {"py/id": 2}}, {"id": {"py/id": 4}}, {"id": {"py/id": 13}}, {"id": {"py/id": 15}}, {"id": {"py/id": 14}}, {"id": {"py/id": 16}}, {"id": {"py/id": 5}}, {"id": {"py/id": 17}}, {"id": {"py/id": 6}}, {"id": {"py/id": 18}}, {"id": {"py/id": 7}}, {"id": {"py/id": 19}}, {"id": {"py/id": 8}}, {"id": {"py/id": 20}}, {"id": {"py/id": 9}}, {"id": {"py/id": 21}}, {"id": {"py/id": 10}}, {"id": {"py/id": 22}}, {"id": {"py/id": 11}}, {"id": {"py/id": 12}}]}, "preview_image": {"py/b64": "aVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUlBQUFBQ0FDQVlBQUFERFBtSExBQUJZcFVsRVFWUjRuTFc5YWF4azZYbVk5NXkxVHEyMzZ1NjlUbTh6emRrNEhDN2lrTElsVXBRb1NxS2xTSFlNd1lhZEJIWmd3SWtUQkFFQyswZU01RmVRSHdrUU9MQ2RRTEFkTzdLMVdiYk1XS1FwV2hJcGl5T1RISEtHbkptZXRkZDd1L3Z1dFM5bitiNzhPUFdlKzlicDZ2RUMrd0FYOTk2cXMzemZ1Ky9IK1pWZitSWHJPQTYrNytPNkxvN2pJUC83dmsrbFVxRmFyV0t0QlNDS0lxSW93blZkSnBNSmNSeVRaUm16Mll3a1NjaXlqQ1JKU0pJRWF5MnRWb3RxdFVvY3g0eEdvK0p6WU9GNXJ1dmllUjdXV2x6WExaN2grejZPNDJDTUlVMVRqREVZWTVoTUpsaHJ5YkpzNGNkMVhjSXd4SEVjWnJNWmp1TWdoN1VXYTIzeFBLQjRaaGlHaEdGSXBWSWhDQUxTTkdVNm5SYlBTTk9VTkUyeDFoWnJjQnluK0Q1SmtnSm1ydXNXZTVSelpKK080K0I1WGdGYnovUElzcXhZcCt4VG5xVi81TG5HbUFKK251Y1Y4SkUxeWY3MDNuM2ZwMWFyRVVWUmNhOHN5L0Jsb1ZtV0xTQkZGaStiaWVNWWF5MlZTZ1hmOTR0RkpFbkNiRFlqeTdKaUVmSUFheTFKa2hTYjFJYzhRejlmZnphYnpRb0NjRjIzZUY0Y3h3VWhMTHVQN01GMVhZSWdLQWhEbnl1QUZzQTVqa09TSkJoanFGYXIrTDVQbG1YRnZnVVpjcDNzcmZ5L2ZDWUlMNi9SR0lQbmVRVUJBelNiellWN3lYbzEwdlhmUWxEQ0tQSXMvVndoYXYxZG1xWUxPQkNjK0dtYUxsQ1J2cEVzWGpqYjkzMmlLQ0lNUTRiRElkYmFBaGxsQ3BYN2pVYWpBcmxDSkhvVCtqa2FnSEplRUFURlp2VmE1Q2dEWG9Db3VVbUlRcDhuRWtDZUkvOVhLcFZpUGNZWWtpUlpJQnFORUwzbnh4R2psZ1J3eW1pZTV4RkZFVUVRTE1CTkNMRjhEN2xPZjE3K1RoT1J3RXMvWHhoRDQ4RFhuS2VScndsQ0tNcjNmWUlnS0c0bXlORWJsRU52ZURLWkZBU2c3eWRBMTlRc253R0ZTQlVpMVp6eHVFT0xUbU5NSVNabEw3SzJaY1FuYWtDcmpqSng2ZDhDY1BtdG42RUpYSE9zSEVFUVVLdlZGc1IxSE1jTDRsMUwxVEpzTlpObzJHdHBJN0FXcVJDR1lYR080TmVWaDJneHAyK2dOK0w3ZnZGWnRWcGQrRjREUlM5UTdpVjZUWDZXM2IrOENYbWV2bWNaRUdVa2lkcVpUcWNGUU10NzArZnE2MFZsQ0FMS25GNitYdmFzVmFVbXdHVjcwZ2dRd3BZZmZUL2dFWFdnY1NQZmFhbFVWdDJhR01vTUszdnd0Y2dRYWFDcHRtdzRpVTVPMC9RUnlhRTNXdVlHTVpTMHVOWFNwZ3hjRGVRc3k1aE9wNHpINHdWOXJrWHdNcU5MRzRiTE9FWHZUZXZOTXBJMVFwWkpTOW12bGhCaXZHcUVheUxXWWw5TEtNM3hqNU4wK2pseWY4L3pGczdSS2c4bzFxTWx1ekVtSjRBMFRRdkRSMjRrVktPSlFJQXZCb1hXTTJVT2VkeWlDOUV6SndMOWpES3c1Sm8wVFJtTlJvVStsN1ZvUUdseHFMbGU5aWE2VDR2aE1sY0pWK3FqTEFYS2hDUFBlNXpra0QzcFoyazRsd2x3bVVHNWJLMXlYaEFFaFpndkg1b1pOQk5vMWVScnhHamthTmRDMzJ3OEhoZWlSQmFsRFJTTkdJMzRNdVhyRFpkZEZyMEJBWTQ4ZnphYlBYS2VuS3ZGb2w2UDcvdkY4NVloWHo5TGM3eEdYSGxmWmYwdTV3bkI2ZnNBQ3lMZVdsdUkvYkxrTEt1V3N1ZWk5eWozZWR4ZTlPZGlDK25EMnJrUktQOElsOGlOOVFMa1p1SU82a1hwdjdWcUtLc1IyWUJHcWdCSEZxbnZKZjhuU2NKZ01EajFYVXZpdGF5bmhRdjEydVM1c3MvSHFSNU44R1UxbytHZzl5NTZ1Z3dEZVphR3Ezd21zWXF5ZWkxYjhlVzFsZFdqZUNsYXRXcTRhRHdzczZOOHZTa040R1djS1p4VTlnNUViR29ScVJjaVNKRy9reVFwQUtPNWROazFzdWtrU1VpekRCeHdIUi9IV2x3SGpGbEVkTmxDMXFwTFAzTVpsNVQzOERneFhEYndsdTIzTEJuMGQvcFoyaDNWM0YxR1lObVAxNGFuWEsvM3YyeVA1VmlMdFJaZmM5OHk5MEp2dHJ5QXNoZ3NIL3JoSW9Ma2Vkb1kwZWRwcVZDNGhwNUhFQVNzQm5XYWJnaXV3MUU2WnBqTmNGa09jSTFvYldnSkI1YWZLNGNtRmdIc01rbFdOdkRrL21YSlVqNi9iQWNKY2tXRmFkaVVQYVVQTXA3TExyYUdwZU00QmZPV3BaVmZGcUZhVDRnbzhuMS9xU0drRFN0dDFaYU5HYjJCWlJRcDU0ditsSTBZWTBpekZOODZmS0oyZ1cyM2p1L21HNXpZaERjbmU3dy9QUUs3YUhBSjhaVFZtVlpER3BBYVdBS1lNcUNYdVZ6YUEvZ2dUaGVnYTZLVWtIaVpFVFRoYU9TWFZaSStYeU8wZ0Z1YUxqeFB3czlhWlFDbm9XQzVVVGwwcW5XNjF1R2F1dlZDbDBXc0hpZWVoUHJMSWs4QUx2ZS9NcTJ5N29VWUxKbk43MVYxQWo1YU84ODRqYmszT3lra2dYNW0yV2pUQ0JHQWxxMWpUYnhhSkV1RVRodUwrcjRhUnZyUVhzRXlHMFY3UTh2ZytrRjcwbXE2Yk1SclExRWJnTUlZNGlXNVpVTlBHeGZhRGROLzYwT3JCNDAwRFJndFRzc0VJNGNFaUxTSWNseVhwZ25vSkFFWkZpMnNEUmJYY1hpcXVvSG51SThZZHN1ZXBhV1RUaXpwMEhGWnJCcGpGaUowWmFsV05zbzBYSVNJeXM5M0hLZElkaTBUMTFwU0xTTW9RYlMyRjJRTm1tamx0MGh3dlErQmxhODNyQ2xKYnFZL0V4MFNCTUVDVW5YMnFueVU3MWxXQjNJUE9WZTdpRW1XVXJNVlhBdm1VUzhSWXkwcmZwWElEWmlZWkVFR2lDalV4Q2pjSVFBUjZTWVNSemhIemhlOStUaHhMOFJkZHU4MFFaUzlBYm1uNjdyRWNWdzhSODdWbHJ3bXVESk10VDZYMzJFWUZ2L0wvWHpmSnd6RElwZ21zSkUxK1dXcTF4d2hDOUFMeTdLTU9JNkxuRUFVUmNVRE5RZnJleTVEdHQ2Y3RnMkU2S0lvd2hwRGFqTndIT0JSNGdMSXJDRTFHZGFZK1htTGExN212NHNVRTBCb2c3WXNPc013SkUzVHd2MHR3NnNzZ3N2aVhoQW14Q2U2dUd6elNKUlVjaC9MVkpnOFYvYWxEVCtkb1pWbnl1K3k1QlppRDRJZ2p3UElJdVFHd2hsbHNTb1VxeEVtR2EzWmJFYXYxMk0ybXhYU29HeXA2a09MUS9sZmI5QjFYUndMSjNaR1RFU0E4d2dKdUk3RGcxbVBjVG9yakVNQlhKazdOU0MxTGhkQU9JNVQxQmhvc1Y2cFZIQmRsK2wweW5RNkxlNnZKV0Q1T2ZyK1pja25pSnZOWmd2bnkvUENNTVR6UE9JNEx0THNPbU1yNTJrQzF2alEwa2JEVjF4djdTVlVLcFhjQ0N5TFpxRWN5VmlKeUJmcElOU2tOeW1FTUI2UDZmZjd4UWJMd0JkdTBOL0pZaVhWWEtsVWl1OG1Uc1p1T09WeVhNdjlmaFlOT3V1QTUvdll6RHlTT0ZsR2ZGcmRpSGlVdlUwbWt5TElwTG5ZOHp6cTlUcFJGREVlanhtUHgwc05USjMyMXA2SEVKbm5lUVZCYWRkUDIxRUNJeWxNbVV3bWhlaGVKbGxsTDNwZlFSQVVkUnRsRDBqMkk5S2pJQUQ1VWhaZnFWU28xV29MQVJyUlc1UEpoREFNaWFLb0FKaHNzdEZvNEhrZWc4R0E4WGk4dExKRkRubVcxQm1JWWFRWEhDY3g3MllqanVPQWkwNlRwaDlSOGZKUXRMR0dLOUVhZTR6WkhaOHM5VXFXQVVpcWNZVHpaUjFKa2pBZWo0dTk2aEN5Y0UrajBjRDNmY2JqTVhFY1ArSzZsYTEwMlpzd2tlaHZ5Q1hxZUR3dTFpUkVJdmR5WFpkR28wRVloa1ZoaWlaaUhSZVF3cHRxdFZvd3JjYWJGTzRJRElUSWZCRkxjbUlZaGpRYWpRVkRUeDdTNy9jTDc2QlNxVENkVHFsV3ExUXFsY0lBQWFoV3F3V0JkTHZkWXBOQzRUcnhKSnhWVGdwWmF3dVZZcTJsaCtXMTNrMzJkaC93NmEybitOeFRIeVhPVWp4Y25xbHNNdkl5SnJNcDQ5RjRvZXhNOWlVQWxiV1dMWERoYkczNFN0RkdGRVVMeHFBdWlSTzFvVGxVZnNwTUlzL0tzb3pCWVBBSVF1VDhTcVd5UUNoU09qYWRUZ3RiUVdDbERlZGFyVWE5WGw5STZBbWhTVEpOcTVISlpISWFDdlo5bjJhenVZQU03ZFpKSlk1Mm1iSXNZendlTTV2TkN2RXR3UWJSbjUxT0I5ZDFDeUtRK3daQlFMMWVMd2hIMndDNmlrZnE4eHhybVV5bjNIbTR5NzI3ZDNsbSt3azJtNnRrSm1QVnFYTFcxcmxic2F6NFFhR0NaSjJ1NnhhbFh0cU5FaWtrK2xhckpsbnJjRGhrTXBrVWlORVNUMkFsZG85ZXM0aGhyWE9GRXdlRHdVSk5oSndqTlF5YThIUmdUS3FWdEJxV1FnODVWOWRzQUl4R282SnVVOXNMWWtqNjFscHF0UnExV3EzUURRSTBjZThnTDVZUTkwbW9Wa3VIOFhqTVpES2hVcWtVQ3hYdUZiRXA1V0ZoR0JiVk1HS1JDcVhLOCtVKzJyanlQWTlhSmVMdTRRNi85dTEveVYvNTNIK2FQeCs0NXEveVlESmc1cHBDRGMxbU04SXdYSkJtR3JrYUtKN25MUVNsdElSSWtxUW9FbzJpaUdxMVdud3ZRSmVpV0JHdHVzeE9ZQ21HcEU1ckMySG9RNHBxeCtNeGpVYWprQWpXTHFaL3RkMGtoQ0ZybjB3bUM4VTM0Z21JYWhQOCtlMTJ1OUNGMnJvVmNXT01lYXlJWG1ad0NUZm8yRFBrYWtFV0xSdVFCWXVFa1ZJc1FZWVVrV2pWMHVsMDZIYTcvTjViMytYVFY1L25FNWVmSVU0VGFsN0lrLzRxMzUzZUovRDlndU5samJKNTRWaDVscWdEN1VycHZXbUxQazFUaHNNaFNaSlFyVllYOGhVaUljb1NVaVNhTG1iVlJxTndzY0JkZTJCSmt0RHRkZ3NHbFdmSitZSk1UY2dDZnduNjZGaUk5bUJrVDc2SUFubG9lYkhDbWVXUWFXRkZ6cWxKSXpXTzQ0VXlhUUdJOWxWMTdFRFVpK1pPdlhoNWhoREEwZEVSM1g2ZmYvRE5ML1AwbVV0RVFZaXhoaWNxSGU3TnVoeGtZMEkvSUF6RGdwdEV6TVp4WEloYUxjNkZFN1VrMElqU0hwTFlDMXB5eXZYYTNSUENsaGlDMXI5YURTM3ppalN5eHVQY3JoSDdSUmhPdTUveUxCM0JGU0xVOXBEQVY0NGlFR1N0TGZ4T09UUUJpRmlXWWhEdHZwVDlVd0dFMU9hSi9wTG9uSEMycGxJNXl0RkhTVjZJR0kraWlHYXpTYlZTNGNidUxmN1o5LzZBUC91cEx6QkxZMXpINVpsb2s2OFAzc2Y2UHE3akxuQ1RKamJoTmtHc2NKTGV2eVpVelRteVY1RUdJcVpsNzhJQTVRcGZIYUxWdG9HMmY3U3hMRVFpUDNFY0U0WWg5WHA5Z2JIRWZpbkRNU2Nxa0MwNURuamU0ak44dVltSTJzZUplT0ZvVVJkQzlicDRRUnRRMnQrWERlc0ZDN0ZwU2k2WGNNczkwalF0bmlzQXFGYXIrSU1Cdi82dHIvSFMxZWU0dkhHR0pNdllxRFM1TWwzbFZqYkFjNzFpN2RMa1VSYnhvaG9FTVJMczBqRFFRTlVFN3poT1lVQktlWGVXWllYKzFVeWtJNUx5WElHZEpxNXlnS3k4bGppT0M2OUV4MlhLRVU5akxGbG1pQ0pEdTUzaGVaWitIM285RjJ2QmRlY3FRSXdsNFRTTnhESWhsSXNTUkgzSVVZNTZpYjdTM1RaaUYrak5sNUVpWEtuMXNMZzZVUlN4c3JKUzJBSkh2UlArenUvL0Z2L3puL3hMT1FDdDVabkdHVTZtQ1VPYkZOUmVmbzc4TCtzWEJoQXJ2R3lZQ1N6MFhnWEJJdTAwdDVZVFkvcGEvYmVjcXlXeDNGOUxIRG0wY1ZsV2xmcFphV280Zno3bHlTZFRvc2ppT0pDbXNMZm44TlpibGl3TGNGMlZEQ3BIdHNvaVNNU3h0Z1hLY1cxZDdLRUJWZGFST3ZLbHc4YkxnamdpUWJTNHJ0ZnJySzJ0Y1hoNHlHZzA0dmZmL0E2LysvUkgrZnlIUDhVc2lZbGNuNmNyRzN3bmZvRGxWT1JwaE9uc3BmN1JLdWh4eHpLZHFvbDIyYjNsdW5Kb1dzZEc1QnlORS8yM3VMUGFvMWttQWRMVXNMbVo4dXl6R2E0TGdsckhnZlBuTFk0VDg1M3ZKUFQ3ZzFNQ1dFYWxtaWkwY1NaVUtHRk40V1E0cmVYWDU4dW05SGxDTkdWZzZtZnF6OFF3RXorNzFXclI2WFE0UGo1bU9CcnhmMy90Ti9ub3BRL1JyamZKakdIYmEzTEc3WE0zNnkwQSs0TkVzeHhsZmI4TThmSy9Sb2JzVnh2UW1sTWZCMk85TjEyUVV6NWY0S0hYSXBJNWg2WG8rNHhMbHpJODcxVC95NUdtc0wxdG1jMzJlUEJnbU1jQnRGRlFYcHc4VkJ0bFdoTElvalVuNkdzMFVMVmtlVnl6aHY0dEtrYk9GUXRZUXFSbno1NHRJbzN2UGJqTHI3ejhWZjZyei85cE1tTndnT3ZCT252eGtPSGM2TlNpVW90Uk9lUlp5OXd0dlFjZGc5ZHJGODdYMmJ6SFBVdlVodXlueU03TmpWSDVmTmt6UkYyNXJrZVdHZExVRlBwK1k4Tnc1b3hsYmMxNUJQbHllQjVjdU5BaWpsZE9JNEhMcW5uTGg5WXpZdlRJNTlyd0s0ZVFNNFVBYlRCcW5hYzVTSDhud1JWOWpqeS8xV3F4dXJySzhmRXhZYVhDZC9kdmN2UG9QcGM2MjZRbVk4V0xlTUpwY21lOHUyQUhpRkdxa1NLY3FOUEJXb3FWOWE0UXZ4YjdlczlhQ21qWUNlRm9tSXRVbFZTd0pvQ3ljWmluNGtNY3h5Vk5Fenh2eHRtek1WdGJsdFZWU3hTQnRRNW1VYWd0SE5aQ0dOYW8xWnhUQWxpMldDMlNCSEI2TVpKQTBaR3pNaGN2RTFuNk9mSmJJMEtmSjBhWlBGZi9ybFFxYkc1dUZ1N2ROSW41QjkvOE1uLzFDMzh1bHg3V2NyMit4WGZUZDNnWXp3ZzhmK0daWmFPd2JQZG82ZllvRUU5RDJ0cHRLK3ZrRDdLdFJCMkoycHhPcDRWTEt0SlBpTUhhSExGeG5OSm94S3l0R1RZMlVqcWRqRW9sTi9LTU9SWDVyaXZYTEs3YmNXQTZ0ZHkvUHlQTHZOUEdFTm5RNHhaY0RpQm90MG1xZlRWeXRQaVN2M1hzUUFCUTF2dGw2U09jS21wSFJMRGo1Qm0wVHFkRHI5Zmo1czJiekdZei92RCtmZjdGdVNmNXVZLzlLTE1rcHVJSHZMUnhqYi8vZzkrbFZxL2pMY2tGbE5XVzdFMUVkRG0rWGhiTDJualU5OVZGR0ZxaWFLa28zcEhzVHplbjVzWmhCYzl6aVNLSDdlMkFTNWNNVzF2anVXWHZZTzJwa2VlNjRIa09TV0k1T2pKVUtnNnRWaTROckQwbGlqZmVTT2wyVTRMQTVqYUFka1hLb3YrVUFrLzFzc1NqeTdxeHZGazVYNTlYUGpTUjZiWG9ybFpCZkpxbWhHRzRRR1FDd05Gb2xNY1dUTWIvOC9VdjhZbkx6N0M1c2txYVpYeG84eUxYbTl1OHN2OCthKzNWUjNMK0lzM0VSUzAvVS9haHJmMHlzV2hKcDBQTldxSm9PRXFPSCtENCtCaGpETFZhRFhBQUI4L3pxVlk5enB6eHVIcTF5c1dMVlpwTnQrQjBhNTA1VWgwOEw3ZjhUMDRNOSsrbjdPeGtIQjlEcmVidzdMTStaODU0K0w1RHYyOTUrKzJFTzNjeVhIZWVDOURGbUhxQittOVp2QUJKUXJ3aXF1UmMwV1ZhbW9qdkx1Zm84OHZQS0J1aStocWRqaTM3NEpJc2tUYjBPK01IL0wydi96UCsybi95WDVBWnNGaCsrdWxQOHNydHQrZzZQVlphclFVN1JBaGRFNFZlcDdhUHlqcGZvb3h5cllodTdkZHJnMCtlMWV2MWFMVmE3TzN0MGUxMnFWU3FEQVpqbXMySUo1NW84dHh6TGE1ZGE3SzJGdUY1RG5rRERQTm5Pbk1MMzNCME5HTjNOMlozMTlMdHVpU0pnK1Brb3I3WE0vekJIOFJFa1lQdjU5K2xxY1h6bkxsNm1QY0dMdU5nYmNFS0Z5K3ppalhDTllJZVp3UG8rK3JQTmRDVy9XakRVaEFrQk5Ob05GaGRYV1U0SE9aR2t1dnhwZTk4bmM4Kzh3ays5ZFR6ek5LRTdaVTFmdXBEUDhUZi9hUGZ4bkV1VUowbnVDUzBMWHZSU0NvVHlUTFh0aHhIMFI2QUlGK2luZ0tudk5ONVFyOC81UER3aUNqeXVYeDVoUmRmUE1Peno2Nnh0VlVuQ0Z5eXpHS01KVTB0cnVzUUJBNVpaamsrbm5EbnpwaTdkeE42UFI5akFqelB4L1BBODhRYk9jWHBkT3BnVERvbkhBODR0ZXQ4cmF1MWxTc2JGcVFMNXkrejhPVzhNdmNJaDBoOFhDTlFQMGRMR0hsdStVY2JnSHA5QUsxV2k2dFhyNUttS2J1N3U4U3pHYVBaalAveks3L0M4MDljbytLSHhGbktqei83US96K2pWZTR1L2VBSjg1ZmZFUzNMNU5BMnVndEU2S3VQTmFFa3dNL0Q4Zkc4WXpwZERwWEN6R3pXY3pKU1JmWE5adzVVK2ZuZi80cFB2clJzMXk0c0VLbDRwTmxoaXl6SkltWkk5M0RXc1BKeVpUMzN1dHgrM2JNMFpIRjk1czBtK3ZVNnc1SkVpK284VEl6Z2NWYVE1Ymw2NU82RFd2dEtRR0lyNjI1WHBBdkNDNWJ3eG9weTVKRDhyZU8rUXZBeStwRlg3UE1adEFpV0JPZ2ZMYTJ0c2JUVHo5TnZWN245dTNiek9LWWI3LzdPci82ci80RmYvSEhmNEZwTWlQMEEvNnpQL1l6L0M5Zi9nZE14aFB3WEFKcmNKMUZOYWJ2djh3MTFkL3JDR1V1cGkyZWx4dGJvOUYwWHB3eTVlam9CTmMxbkR1M3dxYy9mWldQZkdTYksxZFdxVllESkc0ZngxbUJkTENjbkV4NTU1MURidHpvOGVCQmlyVVJxNnVyTkp0MXF0Vm93ZTNXdVgvdHhaUkQyb0lQK2R3WFNwWWdqeFpyMmtDVFVLOU9IMnVBQ0JISWRkcVEwdnBSdnRQNnNXd2NDc0ZwOTBvV3ZNenRsSFBXMTlkWldWbWgyV3p5emp2dmNHOTNoMS82Mm0veW84OStqQ3RiNTBpeWxPdG5ML0cvL2VuL2hsbVM4UGJSRHQrOC94WXprK0tWOGhJYXlacElOVEZJTlZPZWFUU3NyMWY0OElkcmREcTV6Yk96TSthM2Z1dVF5YVRQWno1emxrOTg0anhYcjY1UnI0ZHpwRnZpV0NSb2J1RDErelBlZWVlUWIzM3JIbSsrZWNoazRySzl2YzNhMmlxTlJwMTZ2YjZBQTFsWGVWWlRPWEZWSm1wSmtUdS85RXUvWksyMURBWUR1dDN1QWdDMENoRC9WQkF2UnFEOExaNkJqdnRMaFcrNVdVSXladVB4ZUdHVWl6NTBTTGtzUGZUR05BSEk4NlV5K2M2ZE83ejJnKy96eDU5OGdmLzF6LzkzU0hlQjU3bzRPSGlPeXp2N08vekRHMThudGlrbU94WG5aZmU0N01OTFhEN3ZHOGpZM283NC9PZGIxR3FueHBybnVReUhlUUJzWlNXYVN3eTVUKzZ5T1k3RGFKUnc5MjZmMTE4LzV2MzNCK3p2ajhreWkrKzdCSUZQdTkybVhxOHZGTExxSWg1anpNSTBzM0tsazhCcG1WMVZWQVZIVVM1ZXBGSlZJbmZMUklmV2ZUcWpWellZUmM5b3JoWC8zL2Q5R3MwR2Z1QVg1V1JwbXVJNnArN1hzbHI0c2o5ZGxoQ2k0OWJYMTJrMEdqU2FUZnhSVnFTVXNaWk1ERFl5bnR3OHo2ZTZIK0pyOTE3RG5UTitPVFd1Q1UxL2xvdmRETTl6K2VRbjY5UnFGdDA1WjR3aGlud2Noem1uNXhhODY3cE1KaWwzN295NWNlT0V0OS91MGUybWdFY1FWRmhiaXdvRTZqcEc3VTJJMFNvNDBsSEpjbUN0akhpOVByK2NhWk5hdk5sc1ZoQkMyVVhVQnArbVFsM2lMV0ZOWGRLbGtabGxLYUZUcDFNL1I5Q01tQ1VUSHB6YzRXUzB2NUJLTFZ2WlpaR21wWklXMTBLc1o4K2Y0MU9yMTZpR0ZSTHphSEE4c3huWDE4L3p1M2RleGRoSFU5Nnkzckp0SlBzZWpTWjBPaTdyNjJkSjAwZkQ1em5SUUJDNHhISEd6czZRR3plNnZQdnVnS09qQkdOeThTK3VyQ1kya2E1bHRTeFN0SnlIa2ZPa0Zhd2M1eWdUZ0xVVy8vajRlTUcvRjVFaDRtMDZuVEtaVEJaMGluYVpSUFQ2OHpvOHFZelI5UVhTM0dDTXdmUHpYdi8xNmpuV292TTV4d1Axb0VXbnRzWDlrL2U1ZGZCbTRjYVUvV2tCaWc3R0NJR0krSnRNSm94R28xeVNXSU8vN2tLcGUxZ2ZnZTlqTFF2RUtvYzhYd2UrWkYxeEhMTzdlNS9SS01Yem5zSThHdWNDY3E3L3hqZDJlT1dWUS9iM1o2UXArTDZINjRyK3pyTjAydENWRGlFdDhhU3FTVmN3aDJGWTRFckRTWWZ3ZFcrR0hJVXFIdzZIaFZzUUJFRlJSU3NMa2RKdDBkWGExUk5rU09PRDQrVGpXVFdIekdhem9oTFdtTHpSSXlCaXRYTU9Cd2N6Yi9lV3BaM3RYR0ZxUmh6MGQwbmk5QkZqUnlkSXlwdWFUcWVNUnFPRlpvczBUZG5ySHNPNXh5REhjVG5xZDVuT1pnaHphR05QL3RkU0QvTGkxK1BqWTQ2T0RuajY2WTloYllqalRMRjJrZEJjRjZaVHc2LzkydmZaMlRtbTNXN2hlWG1ybWRiVnN0NUdvMEc5WGllTzQ2SUdVTmNwNmhDejQrVDlESUxEVnF0Vk1HQjUzV1VWS2swa1Bwd0dQYlFQS2JsK1kweGh6RWtQZ053c0NJS2lZbGpyZGdsK1NLbVVGR2ZLb3RyVlRUekhLNUN2RHdlSDFkbzJ3K1NFd0U4Wmo4Y0ZSZXRXSjcwWkthR1dXanl0bWtMZjU0Mmp1L3p3NEJuV1d5djVtSm41SVpiL2I3M3lEVWF6RWExRzh4R3JYL1NxWHY5b05LTGY3eFBITVQvek16L05UL3pFVHpJZTM2Sld1NGNFV2ZKeklZcEN2dnJWRzl5NGNSdlhkVWlTUEFTczV5a0x4NGRoeUdnMEttWXpTeldWL2hINENpTUlRVWpIVnExV285VnFGVXdzQnFQZVV4QUVoYlF1Q2tLRXF1U0dTWklVbkMxR21aUSt6MmF6d2dzUWdoRWlFR3RVRDByU090cHhJUFNpNWV4SUxnbGNQQ2FUTWI2WDl5YUtWQ25iSHJyK1RzU2p0dGhGVmZYaUViLyt4aC93aTgvOEtDdXRPdGJKQ1cwOG52QTN2dlNQK08wMy9wQ3IxNjVoYXZWSERDc2RISko5VFNZVGdpRGdNNS81REMrOTlCTEdXRWFqaTNoZVJyVjZnTzlMOHN2eXU3OTdrNy81TjMrZk5JM25LbVF4WEN3WlB5bjRsR1FRbk5vOVVnMHRYVDlDQUNKMVphM0dHSWJESWRQcE5EZUE1LzBST2g0Z29YbXByU2lTUVJwUnhwaENiT3RHUXdHODdsQ1JCZWpPSVUyaDJoWndIQWVMWlpxTytDQ2Q3RGtCaHc5UEdNMEd0RmZhUmFHRTVuNmhlbDFTTGdEVEViNDBUUWs4bjF1alBkNStkWWRuMXk3aTFCMm1zNWkvL3Z0L20zLzUrc3VzZDFZWmowYlVhN1ZpQW1vNU9DWWNLeG04ejN6bU03end3Z3ZGc3owdjVOMTNHN3p5eWplcDFmSXA2amR1N1BGSGYvVCszQXRhTENnUm90SkZKRUxBdW1kUm1DckxNa2FqMFVKWnVQUUJhbHRCSktKMFIwa0JyVlJWNjBGZm51ZWR1b0Z5YUlyWG14ZGJRTTdSaTlmNmNsa3hneXpZZFYyd2NEemFZN054QWQ4THNTVTFZSzJoRWJYNGtRLy9OTC83blgvT2E5OS9sVnExenZyNk9sdGJXd3Rpcnh6NUVnTFY4NHg5M3llc2hBUitRUDI0eXVUQkRJdGw2TTVvbmwzakkrNkhHWS95aHRESlpGSklHcTF2ZFg0L0RFTis3TWQrak9lZWUyNmhQZXZnWUo5dmYvczc3TzVPMmRtNXo2MWJ0NWhPSnpoT3ZpZGpUdDJ5c2dGYmhycytSNnZUV3ExV3FHYkhjUmdNQm5RNkhScU54aU9SVzljOWJSS1pUQ1owT3AyaUcwdkhDbnlkMENuNzFrS3RJbHFxMWVwQ1prL2JBeHJSc29sbEZyVGp1RXlTQWJlUGJuQnA3V2tDdjNKcUFUSVgzZGF3MHVqd1U1LytVN2pHNDl0di9DRW5KOGRrSm1OdGRYV09qTVdBaDZ4YmpDSGQ0T3A1SHI3alVlMVZzQzY1OUlsY25ycDRuZFd6Ryt3OWZFaTMyMTBvNXdJVzFGbVdaVVJSeEJlKzhBV2VldXFwaFdLT25aMGRYbi85ZFR6UFpXTmpEY2V4dUs3bHpwMDdqRWFqQWw0YStEcmRyWDMwc3RHbUdVMEhvUVRPV1piUEdwQytUbUUrZVo0a24wYWpFWTFHbzhDTmZQZkloQkN0dDJXeHVvTkdQb05UdDBuN3EyVTNTdCt6UUxPQi9mNE9nMG1YdGZvMlVWaGpta3d3TnVQQzZqVThOeUF6R1pXZ3dwLzQ3Qyt5dFhhV2VKWnc5dXg1WE5kaDUvQVdCLzFkbVB2WTF1YkRxMWRXVmxoYld5dGFxZ3QzQ1NBMitHWk9oRURxWmxRYk5iWXFQcFg1RkpEUmFMUVFUOUR0YWRWcWxTOSs4WXRjdlhwMW9WRGtqVGZlNER2ZitVN3hNZ2FKRUxiYmJZNk9qZ3I3UkdDczArbTZMRTI3bUpxWlJCWHBsSE5aU2x0ckYrNTVLazFQMVlMT2V1cUVYVEVwdEN5cXRTV2RKRW5SQmlYVUs4RFJsS2l2MTRjdS9kYkVNSWtIM0psMjUvL25lZXpCcE11VDJ5OVFEZW9ZbTkvelV4LzU3RnlVNWdpL3VIV05OMjUranh2M3ZrTVFCTFRiYlRZM040dm9uenhUdURsSkU3SkJqSnZtMkhlc3d5aVpjSGh5Uk9nSFJWV1Ria1lWcVNYYzliTS8rN05jdkhpeFFJVG5lYno4OHN0ODdXdGZLN3drUVZhYXBnd0dBMXpYcGRsc0Z2ZlIxd3BzTlpkclZhcEZ1aGh1b3Y2RThlU2UxdWFoZkNFQUdiQ2hZemFpdnN0SFlRUXVJR2ZPcks3cllwM1RqaFRwRWRRTDExVzB5N2k5L0YwNWt1Zmdvajg2R2UzemczdmY1S250ajdCU1c4ZGFRNW9sQzllNHJzTnpWejdLOFdDUExKaHcrZkpsT3AxT0VReVJSdFBoY0pqbkJZWUR6TkVNeDF6S0NjQjFPSm4wZWZ1ZHQvQ2QwK25uMGtvdE1aSGhjTWphMmhvLzkzTS94L2IyOWtKSSs4dGYvakpmL3ZLWEMra25SQ0IrZTdWYVpYdDdtOEZnd0dBd0FCYnJKelN5eTFLem5EV1ZQVUV1UVdwell6VkpFa2FqRVpQSnBDQUdNVkxseU1QUjBVSm50MlpjZitGQk9GZ0RtV3Z3UXhkY0Y1TmFjT3pDellVQXhNb1dxdGI5Ymd0SWRoNU41anp1Y0IyWFNUemlqWjF2OGV6NVQ3SlNXMXRpS09ZYyt0U0Y1OWlQYnhKRjBZSkhNSnZOaXVUVy92NCtEdy8yMkRZcmVOdHU4WXo3eHcrNWNlY3RJcjlTM0ZPTDJUaU91WGp4SWovLzh6OWZGSjRLTWYvVGYvcFArZXBYdjFvWVplSXA2VFp1SFNFVkVheG5JY2d6dFFvdXovSHhQSzh3YUxWck81dk5pa0ZkZXFST0VzL0kwZ3J4YkVaWUNZdG5hTyt1bkVYMUYyTHNGbHJYYXJRL1hDWG8rTmpZTXJvVjAzdHRRcFpRSkdpMDM2OEJJeFJldG02MVh2bzNIVUtJR1NtcGlYT2lYSEtlc2ZrTHFicURvUENiaFNPR3d5SEQ0WkNIRHgveThPRkRKdkdValdZRDMvRXg1QUR2VG5NM3lYZDgzRGtYYXl2NzdObXovTXpQL0F3ckt5dkZIck1zNHpkKzR6ZjQrdGUvWG5DN25oNGl5SnpOWnNYa2tDSUpKZXVlNjJBeElpdVZDcTFXYTBHY3kyL2Y5d3Z2UytZTDZIY21TTDltR0FaVW9vaXpGNTlrYy9zOEpwbHh2SCtQTko1U2RyZkw5dDdwSzJPTXcvckhHMng5dG8zak9XQXNPRkRaRG9qTytEejhjcDk0RmhlQVdGYjdwNm10WE1LbExkM0hMV2poYzJSMi8zS0o0VGdRRHgzY3JFS2N6c2dTdzNnOExtWVRuWnljY0hKeWtxL0ZjNm02SVo3allxekJHb3RUOWRuZTNzYkVlVEJKOXVCNUh0ZXZYK2R6bi9zY1VSUVZSRCtiemZqVlgvMVZYbjc1NVFLaGdqUlJBV0luQ1ZFSXA0b2JwNnVucGJoVmhrc0lrVWtVVU53K0tUc1htMHZtR3duRFpXbEtlM1dMTC96aVgrYlNVeS9pVnlwTW5KaUQ3ajM2SjN0MDc5MW1jdWY5UityRGhZanlPRUJtaVRaQ05uNTRKVGUyZEZZcnM5UXZWV2g5dUVyeWc0dzBXQ3dnTGNlWlJScm9LSlU4VVB1L3k0aEJFNFUxaHYzK0RwdXQ4emh1eWJ1WSs5Wkg3NmFNUitzRVYvZEpnbkdSVmg0TUJneUh3d0tnbys2WWlnMXlXOE9Dd1pCNmk1bE1DYW84Kyt5ei9NaVAvRWdCZUtrditPVmYvbVZlZWVXVnd0Q1QvTHdFYVpJa0thSnd0VnFOWnJOWkdKV0R3YUJBbms3Y3lIVWl3VlpYVnpsMzdoeUR3WUNUazVPaTdYdzZuUzVFQ2FVRUxQQTkydTAyUC9lZi93OWNldW9GNG5SR0w1cVNWcURadmtqcnlpWE9mK3dsUmc5M09makc3MkRIZ3dMbUFzKzhQVHl6MUorbzROZGNUTElrcFpsQjg4a0t2VnNwSnBrWEt2TG9NRU5CdEk0MGxmMVpRYkFPV0dpOUtaR3Z5V1RDM3Y0Qlp1cnl3cE9meFBmOHdoYXdCdTYvMTZOM09NT3hGZUszempCZG45S25SNy9iWnpBWUZ1OG83UFY2N0I4ZkVOUmVQSTFSWUJtbEU1STQxN25yNit2VTYzV2VmLzU1UHZXcFR4WHF6Zk04aHNNaHYvN3J2ODVycjcxV2VCVnlIOTFKTEdwUnd0TzZIYjNWYWhYcVJaSmpPbFl2NnFUZGJzLzNQcVphamVhUnlZaFdNdy9wZW43QWFEUWh5U0NNR3JUWHR6bC85VG5PWDMyV09KNHlyaHVTQ2pnV1RGNEFDRUJ0K3l4ckwvMElSMS8veW9LTFh4Q0F0Ull2K29CdVdHTUpWMzFXditpUjNMVk1iaG5TSTR0SkRGbWFGV3BHR3l1NjdreXJCdm0vSERHVXo4YmpNYjFlajVPVEU4YmpNZSsrOHc0Mzc3M0xDMDk5Z2thandYUTI0ZkJCRDN0L0d3Y1hYQXVwVDdSM0RkOUxlSER3TnQxdWwrbjBkRlJLbGhrYWZsNXpMeG5JN3FTZnI0bDh6UysrK0NLZi9PUW5pL1Y1bmtlLzMrZTNmL3UzMmQzZExkN3ZwMmNCaUNFbXZRbVNETk9XdnFpRmZyOWZETlFVRlpBa0NWbWFZckdzZGpib3JMVG85ZnM0dUZTclRacXJaMml2YnRMZU9FdHJkWlBxeWlwQnZVbFFxK05YcXhCNlpLNmxiMktNYXpGZWp2enlZWktFMnBsekRGYzNpWS8yd0RtMXllWjFWekE5U0ZpU25GTlVBRjdUd1gvZW9YSTlKTmszY0NOZ2ZBUFNRWWIxTEY3Vlc2QXVheXlPNDg1RjlxTXJFd0lSemhxUHh4d2RIYkcvdjgvSnlVbVJqemc4T3VUOW5UZloyTmdrREFQQ01HQ3RjNVZtL3luY0xNQTZCbkRZeko1akVoaStPZnJIek15VXdNdUhTV3lkMjJaN1phTllRMnBTOW5xSHhEYW1Fb1I4OHBPZjVLV1hYbG9JcWh3ZEhmRTd2L003UEh6NHNKajk0emhPTWVoS0o1MTAxQTFPeCtGSTUxS2FKUFM2Si9SN0kzemZwOVdva3htb1Z1dXNycCtoMVZsbis5d2xOczlmb3RMc0VOU2JSQ3R0d25vZEp3cXdub3R4d1RnRzQxaG1HS2FrV0ZKQjMrTk1wZUp3UEIrLzNpQTlQc0JSU1M3ZmRWM2MwR1YwSjJaOGYwYjlmR1ZSRFRqa1JpRmdNNHROY3dLcW5IUFpQTmVnL1lrcS9YZkg5RzZNeVU1eXFlQzRMb0huNE5mbTE4NHN5UXdjZjNGUklrN2pPS2JYNjNGNGVNaisvajZEd1dDaGlDUk5VNDZDWTZJb3o0cUJ5eVI2aVBFbk5FNnVFMll0REJtR2pFdXRqMUMvMW1HODlpNk5qWURoWUpSYnlOTXRNcE9YWmNVMnBUOGVNSE9tL093WC93UXZ2ZlRTS1VCOG45M2RYYjd5bGE4d0dBd0t1eVlJZ21Jd1pObDk4N3c4eCtIT2JaUEplSlFIYnlvUmcvNkFKTE0wT21jNDAxbG4rOEpsT2x2bnFLK3VVKytzVVdtMThHc1JoRDdHc1JnM2IyUXhHS2JXUG9ya1JkU2Mvc3dObk94eGhKQ2wyT2tZei9keDUxNVptcWFuRXNETURMdGZQdUxjVDYxUk8xdGhYaWxOTXN6by9tQkV1QkpRdjFUQnE3cGdMUE1nSFdITFkrT0hXcXg5cE1ua1ljenc3Umo2aHJXUFZQQzNmWXdMN3RBeWVTdGw4SzVsSHBndDlQMW9OR0ozZHpkMzErYURGOFc2MXIzOElpSEV3czZTQ2hQM21INzFaVmI2MStsNGx6RTJJN01KNjlVTE9Pa1ozUEFodHZFK251TlRUYUw1bkZuQWQzanV4US96eEljdTg0bVBmMklocm4vcjFpMis5S1V2RlNQYXlsMitEcENsQ2VuY2ZuQUJHNFpVYXcwcXRTYU5sVlZXTnJacGI1NmxzMzJXMnVvNmxkWUtZYU9PVjYzZytGNk9hQ2V2MVUvblA1WTRGOThsS1Z4R3NnUDVNOGxkNFFTWUdNTXdNM2lPdzFiZ1BVSUVnZXR3Y3p5bE41MnhuUVAvdEM4QTVqcmFjNWdlSk56NjFUMGFseUtpOVpCMG1qRzhOV0YybU9LSEFlM3pUV3FYUTJwWGZZSlZEOGR6Y3FtUVdIQ2hkcjVDN1h3Rk1ndmVhZE9pV1hXby9YQ0lGeVVjdjVhQm15TzEzKzl6Ky9adDd0Mjd4M2c4TG5Tbnp1dnJJcFhaYkZha1JJMHhlSTVINWt6NWZ2L0xiSnJuZUtyejZWekhPeG5NWE14N1oyaHVXT0xhTGxIczRHYnpMc2s2ZlBhUC94aXJtK3NMR2IzMzNudVByM3psSzh4bU02cFJoRWxUYkphUnhqT1MyWXd3Q1BIYUVaMnRDelE2NjZ4dW42Tjk1aHlkTStlb3I2NFJyYXpnVnlQY01NQzZEZ2FEbGFZTWE4bHNDbWJ4ZlFzTFNIWWdyMWMrUFZKclNheGxiQ3pEek5ETk1rNnlqT1BVY0pKbWRMT01rVEVNamFIbXVQeVp0UmJYbzBvaExGemdZWnp5YTRNWkg2dFVPVGNkZ1NydlgzaHBGQzVrTTBQM3pSR09Nd1ljSEJmOGlvL3ZlU1FuR2QzRENZTWZPRlRPK05TZkRJa3UrSGpWUEloa05lbnB1a29MbVFQaGN6NlYyNFpKMXpBWTVtWGJPenM3UmRXUDcvc0xVeTNsRUNJUVExRzdsTk5KbnVsNk8vMEdaNitzMFI1OWlIUUdqbXV4MXNGL2NJNXMzZWU5Wjl0VVcyM1MxQkEwSnF5c1pwZzBMWUIvZkhEQXpmZmVJL0FEVE9SUXFUZXByM1NvZGRhb3ROY0lteXZVMXphSVZscUVqU1plSmNUeFBXeVI3alZ6amdac0RDVThheVE3Q3NsMmp1VFlXSWJHTURDR2JwcHhuR2FjWkRtU2Uxbkd5RmdteHBCeUtzZ2NsRHZ0K25TdDRlOGQ5dmhvUGVKNkpjUnpITzdNRXI0MW5uQ2NHV3BKakxFR3g1Nlc5Zm5hTFhEeTFZRUhydmZvQ3c1d3dBMGNUR0taM0VtWjNzMm9kSHlpU3o3Vkt6N0JXbjdPVW9QRUFwRkQ3WXhEYnovajhQaUVnNE9ENGlYVVlndm9raTVZYk1Zc0cxMlM2ODVuNkVXMHIxak9yYVRjLzVaRDB2ZHdNS1JuUXFwZi9DUjdHNmRWU0RhejFFZDlMa3g3T0s3SElERThJR0xqazU5bDVWTStYcTFPVUsvaFJ6VWNQdytKUzZyYXpnTkpLU2trcGJlbm9FUzFjeHFETTBCaUxET2JjMm92TlhRencxR2FjM00zeStobGhyRzFURzNPTzlaeHNQTTdpR1h2ZWg2ZXRmaFpobWN5U0JLODJSUi9Oc0dmVEVoYUt3eld0L2lEd1pnL0hJeUxaK1A1YkE1N3JIV1BTSHdYWDVEdisvbVVNQjJmRnQ5Y0NrVzFteWFBZHozSk4wUGFONHgva0JHL0M5RjVqK1lQZTFoL09SRWt4dUdITDZha2t4bS9jampoMWY2QWFaSVJlcms0aXRPWWRONVg1M3NPdm5lYVNOSzZXTGpmR0lQSk1xcFJoU2N1WG1TMXVjTEdoUUF2SFBId1d5NlRRWVh3cDg1UTNheGlrMFhsT3FtMXVCblZ3WEhJSEJkbnl5TndJQkJxdFhsZEFwbFprR2FpZzkwNWtvVzJEWmFac1V5dGlHckRTV1k0eWd6SG1hRnZESDFqbWRqOFBPbE5jS3pGczRZZ1MzR1RoR3FTNEV5R2VPTXhrVW1wSmpGTmExajFYY0xwaFBUa21QN0RCeVRkRSt4b1FFaSs1cXBqY2M1ZTRMdWYvd1Y2NjFzNFdTNG5ITWVsTmgzenFiZS9oemViWUx4NnZtWmJwUEVYWDFlaVU1QUZ4eWpPRTB1NHFBOXdjLzF2TXBkczErSjBEWGJUWFZRQmN5QjV4bkkrUzlpNDZQRGg3UXY4cTJjaS90RTNidktITi9hb2hpNmZmMkdMTTJ0MXByT1VsOTgrNEszZEhxSG5ZRTFHUEowdzZKMVFEWDA4MjhiRmdEVVkxMmYxL0ZVMlB2UVIzcGsyZWUyZGhBZER1RmVaY3UxY2k1ZTI2cGprVWYvV0JjeDhqcUFEWUxLNVdDMko2dmtIeG9KeEhLWVd4dFl5eUd3dW9yT01velRqT01rWVpDbkROR09XWldSSmpJMWozRGpHblUxeFJ3UEM2WmlWSkthV0psU1RtR0E2cHA2bGhFbE1rTVEwWEllNjYzQzh2OGZ1blR2NGpzT1ZKeTZ5dHJiT2REYWwyKzF5Y0hqSXJEOGd5VkljMThPclZyR3VpeHRGVk83djhLSGYrTHNjZlB5UDBidDRGZXY3YkhTUGVQYk8yNnoyajVtNkhyTjUybGhlQmVDdnJLd1VoUk1TbmRKbHgzQTZTRkphdUhUMWlxUk9YZGNsVGwybWJ4bXFHeTZaeTZsRjY0QjE0WmxCek1Zc0F3dVZ3T1Z6TDU3bGM4OXY4ZTEzRDZtSEhzOWNXVVU2SzN1OUNmLzdiNzdHMy9tOVd3U1ZDck9vamR2WVlyOTVrWEgxSW0rbkhRWk95R2c5d1BnMWZuL0hKOGtNcVluQmdTenphVjdMOWFCNWpKUHNvSnBOWFpjTVNDek1JTmZIU2NwSm5OQk5VN3B4VEhjOFpqZ2E1Y01vUmlQc2FJQTNSMkk5UzJsT3gzVEdJNXhCSDNjNndabE9ZRHJCVDFQUzJSU2JaVVNCejhiNk91MTJtNU51bHpoSjhQMkFlclBCbVRObnFWU3JWQjNJNHBpRGd3TU8rZ05PeHBOaWFubVNKS1RHNExnZXJ1Y3htNmZwQjhOaEhtMmNUcm4yemEreGV2TU5vbW9WTDAzSnJDRjJYRnhNWVV3blNaSkxlWW1YNjBwZVBUUlpWOXpLWitJYjY4OEFnc0RTZTkvRGl4ekM1MTFzTmMva09SbHcyMkRlNnpQWU1EU2JsZHhGU1BJbzRpYyt0RG0zaGd6U1c3WFNpUGlmL3N5TDNOMzZFYjR5dUVxbFdpWHhJM3FPbTlPVnpaTlZqZ09PeVlXdzYwQTRGMXhUNjJLUzlMSHhFUWVJamVWaDk0aHBtckYvY3N4b01tSFE2N0gvNEQ1bU9xSHV1UVR4RkhjNklUczVocE1qZ2w2UDFtaUlreVI0RGxTQ2tKVm1FOWQxU0xNTXgzWEYwU1hOTXF3RFlWU2x2YkZSdEluM1p6R3pibzk2dllHZEo0dmNPT0gydlh0RmFybGVyek1jRGprNk9sb1lreXNHc1Vob3lSZ0tnOVpxdFR4UzZMbTQxbUk4RDJ2eTNJcUlmZWtjR28xR3VRMmd3N0k1YkU4SEVPcktta0o4dXFmRGxTVU9YbFQvK3BhajE2RjZ6eU02RStDR1B1NEFKb2VXcng2Ry9NclgzK0ZqWitDblA3ck51YzFtcm1QVEpTSEl6T0Q0SG4vaEl6Ny84dFhWdkpUYkdoeWJGWlgzZGs0Qnh1U2VKelluQ0Mvd3VUQTc1aGUrOUkvSlB2clhvTmw2WkdDZTR3ZjAzbjZkL2g5OWcxYTl6dXpOTjJnR0FaZFhPN3ozenJ0a1NjTGE2aXJXY1VpemxNRndpRGNZRUtRSldSQmdQQy8zcDhPUWNaYVJ4Zm45ZFFVMTVDUHVtUnVzdlY2dlVLL2RicGRXcTRYbmVaeWNuQ0JsYlRJSFdBbzl4TmlWUS9jdFJsRkVyVllyVXNYVmFwVkdvekV2L25ReFN3cHhkTVdYNTNuNGttdVdEM1FRWnFGV1FBRG5uSGJuTEtzRVN0T1VsSlRreUdQV2h5QUV6OCtEMU5hbTNOa2Y4bnZmdXNzdi9ZczMrY0pIei9GZmZ2NDY1OWZydVpJdEh3WXUxbU1pM3pLMVBvN2o1M1dBeHVDYUZNOU1DVXpNVmpQa2ZLZkdSczFscmU2eWxveDQvcGYvSVdmZmVvMjMvdjRXTzMvNXZ5WDBmWmh6S0o1UGYvOGhvOWUrVGRPa01CNXg5ZUpGVnRmV2FEV2JYSC82R1hxOVhoR2ZzTE1aZnBJUzFRMUJGQlZSU2wyakorbGNPSzI0a2F5ZmxJaEpqY0JzTml1S1IyU09zVVE4UjZNUjBxTXB2cnAwWk9uTXF4anZ4OGZIOUhvOW1zMG1xNnVyckt5c0xMem1wMHdBdXRmUWNSejhhclZhVks3SzhVRWxTcG9BdEdlZ3c2T3U2Mkt4cERiQnBnWi9IbkE4UGo2bTMrdmkycFM5NHlsLzQwdHZzTjRJK0N0LzhnV1lMWmxxNkRna1NVcDJjQnM3T01GT1RxaVpNZWZhRVozSXdZdEhtT21BODJjMitkRVAvekNkOVRYY3laVFcvL1gzaU41L2s3aFc1K28vK1RXcUJ3ZTg5eGYvRWw2blF6TG9NN241TnIyN3QyRTJ4YzdmTnVhNExpc3JLenozM0hPc3JhM3g0TUVEVGs1T0NvNnJWcXRrV2NiSnlVbUJFR2s5azRub29oYjFTelBFclpWS0pkRzl1c3hPS282cjFTckc1Qyt2a29rcW9vSUZrWkpPVHBLRWs1TVRKcE1KalVhanlEaHF6MDFYQWhWdWZva29mQ2xEa3Mzb21JQXVEaTFUbFJDRXRnbjBieUVJb1dKZHp5OHVaQlE0ZlAwSDkvbExQLzBjb2VjOFVyUkE2UE43TDcvR3lXLytFaFhYNExrT1diVktjTzBhbllzWENXc1JZeWRrWjJlWEg3ejlMaDhMS216L3Y3OU0rT29QeU1Jd3Y1L3ZFM1hxZFBidjRKMDhZUGp1bXd6KzFkZW9ybTR5UFhjRjY0ZGdjd0M5Ly83N1RLZFRQdnpoRDNQanhnME9EZzZLUWxoSlVldmlUVjFoSzIxeWdud2hCc2tXQ2tKMTI3d1FrbVFYSlNZaUtuV1pCRTZTcENBUXovTllYVjJsMCtrVUJiRlNkUEs0Mmd1UjlFVlZzQ0JkUEFBcFhOQXBXMW00Ym1tU2hZbTQwd2pYYWVFeTVlbUYrWjdEdjM3M2tHOTk1elgrMktkZkpNK0VtRHlyRXJpOC9kNGUvOGMvK3o0ZUJsd1A2N3BNVTBOM01HSWpUcW5XQTJvMWwwa2NjL1B0dC9tUlAvclgxRjkvL1JUNVdjYkpGNy9JeVUvL0ZQSGhBWUV4dEo5OG1zR2Q5NW5ldjBzMVRaaWV2WXlwTldDKzl0M2RYUTRQRDdsejU4NUMyMW5aVGhKcjJuRWNHbzBHVVJRVm5oRlF2SFhOZFYyR3cyRmh1RWw4UmVBbXNOR3dGbGRiSTFMcSs4ZmpjYUhyRzQwRzdYYWIxZFZWYXJWYW9YSUVOK1VDM21VNDhTWDNMZHlyRFR1UkNzc1FXYTRFS2tjVWhTQkVWT3FGRkVXUnVHeldNcTZkZkJOdUhNTDJjNWpLQ2c5SEtWLy93UVAreHY5M2c0TkJRaGdFR0h0YWZESVlERGc2T3NxQjNHaFFEU3Q4NXZYWDJUNCtJWnNQZ1hDTllmOXpQOGJkbHo1SmRUekdkNzE4SHA4RkxsNkR3MzI4eVlqYTNYZVlubm1DdExVR05pZUNPSTVaWDEvbjZPaW9pRUJLZVpjMnlJUXhkS21YSHAvbk9FNVJwZ1lVM3BZdUNoWHUxM1dWY3IydUh4UTdvZDF1RjMyQ3pXYVRWcXRWdkw2bVVMOEtWeDlVZFFYa1hzQ3lMd29Sb1JwQXk3WHJ5MjU2Mml1M09ENU8yc2gxYTFPY1dYN3NmTXgyeThDRE4rSG9IWDdydlJyLy9kZERVanc2S3kzV09pdU14NmN2UUxMV01oZ09PVDQrcHIyNlNsU3I4WVc3OTNpeDJ5T2RxeWszTTR5LzhKUEVmL0lYeUhaMk9KaGIzMUtpdmI2NVJlUEpweG04K1JwT21sRGRlWi9aNW94NC9RelkweGMzYm05dmMzaDR5T0hoWVJHbUZyRXVkZllDK0N6TGlpU1ZxQXZ0U3BkN0FQVGJSQVJXdW1OWTF5Z0tjOWJyZFZaWFY0dm1sMmF6dWZBK3dzY2hXNjdYamJ6eW1SOUYwVUw4WFVxUnkvcGRibFErZFBHbmZLK05RZEg3WVJpeXNyTEN4c1pHL3Y3Qk5LUG1Hbjd4eW54OG5PdGhNOHMvZWozaGVHQlpiOWVKWjlPRmVuaGpETk0wSloxT21jVXg2V3pHUzYrL3pvdDM3NUhPQ2RsTFU5NjlmcDNlRDMrYWxlbVVlcTNHWk43V3ZyR3h3ZXJxS3BVb29ySzVUbnE0eC9SZ0R4eUh5c083dU5ZdzJUaVhwMXZuKzVhUzhPUGo0OEt5MTYxWjJqN1NYYjA2aE4zdjk0dTNqWmE3cS9Rc1pJR1Y0RUJlZkNYRTFXNjNpMEZZK2tWZWVsakhRdXBhNlg4dGtlWHdQQTkvZjMrZnRiVzFvdHRIaUVCVG9hYlNzam9vRTRjMk5vQ0NLN0lzeTZ0enRyWTRQanhoRnNkY3VKTGlQT0d4YjJIVFRYbjd3T1dQSHZwRVBndXZYUUZJMHBRa3kvakpLNWY1Y3gvN0dKZlBuc0ZQVWhvL2VKM3UvUWRnREw2MWZIZGpnMStQS29ULy9KOXovdXhacmx5NXdzcktTaUVtb3lpZnY5TWJEQmwydG5BT0h1WnhCZGNsT0xqUG5lNkE1b1ZMTk9ZV09jQzVjK2VJb29nMzNuaUR5V1N5SUs0MTV3VkJVSENsSUVQbUNJZ0lGeGpwOG5tTk5HbkpseXBqS1FiVkJLRG5OWllOeFdWU1FCaFJNN1JJWW45blo0ZHV0OHU1YytlS0tsYnROb2dob3YzZFpZY3VCWk5EMndsaUJHMXZuR0gwa1QzRzIzc2NiTlg0ODI2ZFRtcjRVOU1oUjkrYU1KaENOVHdGakN4K2xpVDgxNS80T0gvOWl6K0RHNGFueFFibnoxRzdlSUdIdi8wVjNqdDdscGVmZTViV2RFbzhtZkRnd1FNT0R3OXB0OXM4K2VTVHJLNnVGZ2JkNGVFaHg4YkI5V3RzbWlrbXJ6QmtiWFRDOTE3cmNmWEpKOWxZWHkvRTV2cjZPaSsrK0NMZi9lNTNPVG82S2lwOG04MW1NYWFsWHE4WDdsaVdaZm5iemJyZEJZdGVBa0h5bzZ1bnRacVVSbHd4R2lWVXI5dStOQUhwejhwRUlHcEo5M1VVM3AweGhtNjN5MncyWTJWbHBTaEYxdjEvbXZQbFptV2ZVaU84bk1zWEVaV2xobW5sbUhjLy9CNzl3T0tZdkk3Z3lIUDVXeXNyTkorcjBucHRTSnhrdUw0U3M3N1BTMmZQOEZkLzh2TjVPVk95MkNyV2V1WnA3a3dtL090V205VldrM1Y3MnEvUTcvYzVPRGpnd1lNSFJkRnB0VnBsYzNPVGVxUEJYZU5SaVROYW9ZOEIxaXMrMjVNSjMzdjFOYTQvZVkwbm5uaWlrR0ROWnBPWFhucUpWMTk5bGZ2Mzk0RVF6NnNVUDNvNlNxL1hZMmRuaDRPRGc0WHFZWEVEeGZVV1dNdjdEMlFPb0JpVHduaWFFZUYwcW1yWk9OZk1xSU56dXA1Q1hOSW9pdkk0Z0xXVzBUeko0WGtlbHk1ZDRzS0ZDNFZSSWpjUTduZmQwd0hKdXM5c29hNkFSWmN2eXpJY1kzbTMvUVpIM2hRL080MHJlSUNiV3BKbkE2Nzg4Qm5HNzNsWTF4UTYxL28rZitwREh5S3ExWXBjUVluRTZYem9RMFNUNmNKd0JhRFFvN2R1M1dKdmI2OGc0cjI5UGNLVEV5YXBZZGVwMENMdkhNMHNQTjJ1TWE0NGZQZlZWOW5mMytmRkYxOHNPQ2NNSzN6MG81L2c2clZ2Y3ZIQ0hpdnRRMGFqSm5mdm5HTTBxaGYrdll5c0VTU0xUU1FHWnIxZUw1cElaQzZUOUJWcXBwSy9IY2RaYVAvV1VjZnlJWEVYYld0SThLbnNmaGJEb3NYL1Q1S0VuWjJkNGtYRW92ODFNblhYUzFuM2xHMEJiWHlrSkR5b25KQlgwaTBlRHBBNGhzYXpIYTVXTGhMYnVBaVV4TWF3c2RwNU5GQWtoN1hVZlo5cUdCTE1HeUgxdnFSWjg5S2xTMFd6aUVUbFBNOGpxbFl4ZTNkd2p2YkJkZkd4WEFrc045S1ViMy83Mnh3ZEhmR2pQL3FqUkZHVkxETmN2Zm9xbHk3ZnduV3orWkw2UFBQTVB0Lys5alBjdm5rV1MxeDRDeEtjMFowLzdYYTdhR0dYMEt3T0xwV0pRUDdYcnFZUWdEYnlCTjRTZmhacHJLV0ZNRWhCQU9XWWY2MVd3eGpEclZ1M09IUG1ETTFtY3dIeDJ0ZVVIeDFCZkFTeGhXVXFKVEtQN3o4QWkrTTZCRUZZRktVWVl3aU1vVGViUFo0QUhJZnVaRUxtZXJScU5XcnprU2dTUERIR3NMcTZ1dUJhNllGWHJ1ZmhOR3Frd3o0Mm5wSGhzT0U3WEl4OEhnQTNiOTNDY1J3Ky92RlBjZTNhQ1JlZmVBMWpITEpNOXVJUUJDa2YvL2hiM0xzVGMvdU9ZVEtaTVJyTjV0SXozNysxa0tZWnMxbE1HTWFQTUpibWJIajBuY0xTZ3JiTTRDdmJBMEp3NWNCUStmd2lEcURIcmJodVBzYnN6cDA3cksydHNiYTJWbENkcGlyZEthd25XSlIxVXVFN201Q05XWnZEc0w4VWo1NXg2UFRxV09lMFI5NTFYUnhyK1lPSGUvekUxaVliN1pYRnhKR1RoNUMvY1hEQVFWakozN3BkcVJSTkd2VjZ2VlRDN1MyVW9UbE9YcDgzZFR3bXJYVWFoenVBUTJZTW56aXp4azV2U0Q5T09ENDU0Wlh2Zm9jWFB6ckc4eUJOeTRhV1F4REUvTXlmZUllVEU1ZHUxK0g0Q0E0UDRlVEVZekR3NlBVZ2poM0c0eEZ4YlBEOUNaVktpTzk3aEdGQXRScmgrOTU4aHVEaWk2bTA1WDVhRVdXeE5nL1dZUTA0R1ZtV0xraHRIZGJYUkZYWUk1cnFqREhGRzdMbDRzUERRMmF6R1Z0Yld3c1RLTFc3S0dKTWY2ZkZqT3U2K0s3UDJJNDVETWFsdXRkNVNaV1g4Y1IrbTJwM0RUeHc3Q2t4VGNkajNybC9uNzl0TXY3SHozNEdOY0FBazZaODVjNWRYdTcxQ2NLUSs5WnlkSFNFNjdwRmY1N0U2VDNQbzlmckZRMmt1dXYzcE51bFAwMjU0SVkwc3huTjFYVStkUGtLbi9qczU1Z2xLYmYzRHZpamQyL2hlUThvendJczltRWRHZzFMczVseTZaTFlSR0J0U3BMa2Mvdkg0eW45dmtlLzc5SHRlcHljK0F3SEFkTnBsVGl1a1dVTjByUkdFSVFZNDVEUCtIZHhYVzkrTCtaMW1pSEdUS2xXSCtJNGZhYlRLdDF1RzJNY2ZOL0JkUmNuaU1LalUxV3R0ZmhTWnEzVHd0SzdKbFpvdDV0UDhkamEybHBvZFJicElhSlZDRUJVZ2k0eGM2ekRHODAzT0lnTzhleGNKemtHTE5ReWp6TjdtMnpmdW9TMTgzekEvSmhNSmtYV0t4T09uLzkrWmZjK3YvM2dJVGZUbE1EUFU4WDY5WEF5TUhJMm14VUpHNG5TU2JldVZDTFBaalBpTk9VdUlaL2FXdVBwRjE3QUMvS2NnZ09jM1ZqaitvVUxUUHhEakwySE5GWHB3M0hBY2V4YzFEc0xHc3Qxb1Y2M05CcVdyYTBNTFNUVEZKTEVZVGJ6bUV3Q3BwT0l5YlRHWkZ4bk1xa3ltZFRJc2laQmtHQ3RqN1VCdGZvQlo4LytIclhhZlZ6WFlJekg4ZkVhYjkzNEdLUFJLbms5NE9KTE84dWVnekVHdjlsc0xrUUJwZXhhb25jeUJYdzRIR0tNWVd0cmE4RVhGU0xSdVFRZERuWWNoNHBYNFo1M2o3ZGJiK1BhZWVBSXk4ZU9QOFphdkVvVXU1aGV3TkFkazdqeEhKaW40K3JpT0NaTFV6Nnl1VmtRZ0xXV2Y3Szd5ODBrcFZXdDRwYUNLM0tPR0lLU3c5ZTVkUUdNbk9zQ1RsVGx3dlduOGZ3Z2I3Q2NINWt4ck5UcUJNbUxXTE16UjdUU3dhNGxtYmtjSEZhbzFUS2lLQ01NRFo1bkVkVXI1eHYxemg4NWdnRENNS1BaVE1sTDhvOXhISXN4RHNhNHBLbFBra1NrYVpVa2FkRm9QQ1NLZWhqalkweU8ySTJOUFNxVmwvbjJ0ejVMbXRZV2tGMkdpekJvTVNaTzZnTDFTVExPVktobk1CZ1F4ekdycTZ1MDIrMEZGWkJ2N05GSkhpWXp4RTdNOTlyZkkzVlRQT3VST1JsWGgxZTUxbjB5TDd6MFhleUtwZGFzRjkyek1xTTRqbVBTTENQeVBKN2VXTStoNXpqMHBsT09rcFI2R0JMTnhYelo2SkdOU25DbFZxc3RTSUJ5dDI5bUxWdk5CaXYxMmlON3lZazJ3eDAreWM3dFp6aDcrUWF1bXdFT2ptT0prd3JmZWVVNk45N3NVS21rVktzWmxjcU1LQnBUcjA5b05HZlU2MU1halpSYU5hVVNaZmgrUGsxc2JzYk1DY0xCR09jUk5STUVDVUVRNHpnOTRBSFdlaGl6S0lXeXpLZlZPdUhjK2J2Y3V2a01ybnVhZE5KNDBvZC9kSFMwNEk0SUlrVWlTSWV0V0tBNkxibTl2VTIxV2wzUTlicHVFTUMxTHQrdmY1L0RTaTc2aldOb3hBMmVQbmlhT0lteHJpVndUc2U1U1VtVEVGc1lobFNpaVBQTkJoZmI3WGt0b01PRDJReFRyZEpTVXoyV0JhTEtzZTk2dlU2ajBTaW1lRWpTQnNCbWhpRElKNFlZKzZqSFliSDRuc3Y5M1UreDN6M0RtZTE3aEpVeGcwR0R1M2ZQYzNMYzVzd1pkNzdFdkZTdDI0MjVmMy9NWkRMRzJvd2dNRlFxR1ZFMW85bElhRFlUbXMwWnplYU1XbTFLSllxSm9oamZON2h1aWxPMCt6cHpxZUUrMWdiSjkrdlFiaCtSdjRCaU1TQW5ockUyRHYyYk4yK3l2cjdPeHNaR0VaU1FxaFNoR0FrSWlVOGRCQUZIUjBkTXA5TmlQcDB4cHBoVGEwemVFdVVhbHp2dUhkNnN2MW1JZnNjNlBIZjBITlc0U21JVHlDRGxORVNwQ3hxc3RmbUlsRnFOSCtxMHFjNVR2UUFQTTBOalpZVkl6U0RRU1EvdDJ1cS9wWXBaUXEyMVdxM1kzM1E2WXppTmlkTUV6L01YaUVldW42VUptYldNdXBmb2RTK1JaU2xKa21KTVNoaWVOcElLODlScUllMTJyWkJvczFtTXRUQ2RlTXdtRHZ2NzBvN3U0bm1HS0lKbXkyZDkzYWRlaXdrckE4S3dSeGdPQ2NNUnZqOGlDR1lMeUMyVGFlQkg4MExSOFVKK1o1a2Q0RStuVTI3ZXZFbVdaVnk3ZHEwWWk2SURDZVV4SlhKeEhNY2NIeDhYa2E4c3kvajR4ejlPcDlNaG5zVU0weUhmYW4rTHpNMXdyVXZtWkZ3WlhPSHk1REpaa09HYjAxU3oyQkFTYXBhM2lRd0dBekxINGNxRjg3a2xOZGZMdTJsS21IZTJGRWdYa1M3cjFNVVVzT2hYQzBCRVBRaUNSK014ZDQ5N1BMVzFRVkxLbmpuQXU0Y245S2NKWVdIN1pGaWI1UExCbnFhRnRZdXNwNENMZXRNNWxkTUVUWlZhclU1VXFURVorMHpHK3NYY0dkYk9TTk1aMjlzM2VQTDZLNWpzMGRsTDFzSjAraVJyYTJ0TUpnR2owV2hCemVrVWRCUkYrT2ZPbmVQaHc0ZnM3T3d3blU2NWNPRkNRY0dWU21YaGZYZGFuRWdVVFhSdkdJYU14Mk4yZDNZSnZSRGY4WG10OGRxQzZHOG1UVjdvdllEcm5mcWlPbW9sQnB0d2k4UWtYT0JLbzE1dy95d3pIQnBMNFB2NTBNZDA4Vld0eXhJbGNuOEJ1QlJlaUNjZzU3WGJiWDV3Y01Kc011SHBDK2NJZko4a1BTMHZ6OTJ4ZU9HZTVTaWNHSnV5UiswTmlaVFZWZGZpcGtwVlVYNmR3WEhzUE9hUWtyK1F5aVhMS3V6c2ZJalZ0WWVzcjkvREdBOXJjenZFY1RMNi9hZm85Njlqekt6SUpzcjRPeUZ5VFpDKzY3cGN2SGlSWHEvSHdjRUIvWDZmczJmUHNyYTJWc3pOU2RQVHNlMkNGT2FBbHdXSFlVZ1VSQXhHQTc1Nzc3c0VGd0xlYXJ5MUlQby9OdmdZemF4SjZxUkZZNk1nU1UrKzBoT3p2REJrdlZialFxTlI2UCtUTEtGbkREYkxpRldPUXJ3QXlYcHB4T2lzWkpabGhUdXJLM0JjTjMrMzZzbHd4Ti82K2plNDBHN3gzTlZML1BqSFBwSzNxUUhYTnRvY0pJYXB5b0VJWU12NzBTbDBZTUcxbG9JU3lmTEoyc3RXKzJtczM4NmxUSUl4UG0rLzlSa21UN3pLK3ZvZGZIOUdta1ljSFY3bThQRFRWQ29Ccm52NmF0NVdxOFYwT2kwS1VtVm1jSlpsK0FjSEIzUTZIVFkyTnFqVmFod2VIbkw3OW0zNi9UN1BQLzk4VVdrcXRYSEMrUnBwbnVmaDRURnFqN2gzN1I2RDFpQVgrL05tNTh6SnVENjl6dFg0S2pOM2hqV25PbHN5WDRKOFNWZ1lZM0I5bjVibjhlTVh6dE9VT2ovSFlTZE5tUnFEbzlTUjVqUk5uQXNpM0ZsOGU1a0VnbVRzaXdDKzMrc3hIbzk1cmR2bDlidTduRjFmNTZOUFhpRkpVK3ErejlsNnhLM0I1SkVCZHVYQWk1WnFBaitKdWNnNWtpaVNTR3E1cGxMdXE2dUQ4bnRXdWZuK3A5bmRlUkhQai9QNWdIRU4xODJJNDE2UkJKTjdDZUsxcSs1NUhuNmowWmpQMU1rTnVyTm56M0owZEVTdjErTzk5OTdqaFJkZUtFU242RFhkb2gyR0lZNTFtRFZudlB2OHU4UzFHTmU0S3RoakNlS0FzemZQRWpkaXZNRERwbzgybzJvWHpuVmQvREJrTXd6NUM1Y3VjcjNWV3NnRGRGeVBpalZNY3lndklFQ01NSjBqMTkvcDMvSXM0VFFoOU9QajQ3eThPd2l3T1B6T0s2L3kvT1dMT09SREdTNjJhanljSnN5VW5WR1dOSm9ZNUhPZG01QXk4RElCNlVNVHR4Q05xQmhyRFk0RGNSeEJYTVZ4bUx1bEZDMTgraVVUY244ZDdzK3lEUGY4K2ZQRkdOVER3ME9tMHlrYkd4dGN1SENCNCtOalhubmxGVjU5OVZVT0RnNFdYZy9qdW03Um5oMVBZL1l1N3VYSXo5eUZ6bURIT2hqZnNEUGE0ZGF0Vy9SNnZhVklMeER2KzFTaWlHb1U4V2VldU1qMWxaWEZKSkMxWEkwcS9GaXpXYmhxd2hYYTJpMERVd0NnRVY4V3UwRVFNSmxNNlBmN2hhNE1BNThiZDNmNHdjMDd1ZmdHNm9IUG1mcGlhbmJaTTVldFFZak5jWnhDR2dnOGw2MVhmcGVMUjA0UGcrT1lCYTlBMWlJbDVETGhWZTlaM0hzM1NSTFcxdGE0ZlBreXRWcU5YcTlIdDlzbENBTE9uejlQa2lROGVQQ0FXN2R1TFF3dmxJSUZZd3pqZE15Z1BjQjVqSDlxZk1Od2RjaDBQR1ZuNTVRUVpGTWFPWjduNFFjQmwxdE5ubXMyVGl0L1NzZUxqVG9ybnZjSUVZaDAwb2ZPdUQwT0tZSkVtZlduZ1pWbEdWLzl6cXNrYVpvSGJiQmNxRmNJM2R3dUtHZnp5cy9TenhSQ2xkeCsrWHNOQ3gyM0YrOUlHM09QMjRzYzJpWFcway9nWkszRjdmVjZIQjhmNC9zK0Z5OWVaR05qZzlGb3hQMzc5NW5OWm14dWJoWjU5RnUzYmhYQkdkR2w5ZHI4UlJLUGMwdExoekY1QThUdTdpNTM3OTR0UnNQb3BKVGplYXptbmF1UDJ4a056NlBoZVFzamRjclZ0bkxvc20wQlhybHVRUU90ckkvRElPRDl2VDNlMlgyQVAwL0tOQUtmN1ZvRlV3bzhMZk8xOWIwMG9UK09NTFVxMGNqWEw5OWFkcDBtRnUxZTZ6VUlEZ3JYVzBhVjd1L3ZNeDZQMmRqWTRNcVZLd1JCd043ZUhnY0hCNFJoeUxsejUvQThqemZlZUlNYk4yNnd2NzlQbXFhME8yMDZqUTdOWHJOSTQ1WVB4empVam1wWVR1UHZqdVBRN1haNS8vMzN1WC8vUHROcC9qS2xTcVZDR0FSTTdmSXFaRGxteHVTR0lJOEM3bkYxQ1krekEvVDFaWVBNZFYxY0o2OVIrTUhPUTFKeEpiRmNhRlNKZk1uU0xVYmRsbVZGNVo2NnNHTVpjWllQTVZnbEdGZTJiOHI3bEd1RVVKYXBqaUovNDNuNStIRnI4elNxU0lQTGx5OXo3dHc1a2lUaDRjT0hwR2s2ZjNGeGs4Rmd3TTdPRHJkdjMrYm16WnNNaGdNMjcyd1Nqa09NcDNqU3ljVi8rMzZibGU0S0dZKyt6MWF5amZmdTNlUGc0Q0NQUUxvdUI4RHViSGFhL1Z2Y0plOU5aM1NOSWZEY1IvUytwdmF5T0YwbXJ2VjU4cjVCY1EyRElLRFphckd4dnM1SmtyRS9IT2N6Qnl3MFE1L3RXc1M4M0dVcG9lbFlRVGtCcFYxcWpUVDl2LzVjSTcwczVmVDUrcHE4ak8zMFBVTnlyUkNTdjdlM3g5cmFHdlY2bmRGb1ZNVGdhN1ZhOGZuQndRR0hoNGRFVVVTejJlVDgrZk4wdTExNnZSNjNiOS9tWWZTUXRmWWE1OHc1amo1OHhHaGxoSEVON3RSbDVkNEtaMitleGZkOXB1a1VERXM1dzNHY1lzWnZvOUdnc2JMQ2w3RDgyWTExV3ZOVXJ5Qi9MNDc1YW45UUJJbVdKVzdLdFcrbnRMUDRURGtrREMwMTk5cFhyMVFxcksrdjArNTB1RGVhc2Rtb0ZkYzkwYXB6dHpzZ3RYbmFXRXVoeDNHcFJsWlpEWHdRVXZWYXRZZndRZWRxQTFOblBvWDQvSjJkblNMNEkwR2ZPSTZMU3VGMnU4M2x5NWZwOVhvOGZQaVFCdzhlc0xLeVFydmRabVZsQmJFaFRrNU8yQjV1YzIxNGpXd2xZK2JNY0FZTzdzQmw1c3hJL2ROM0FjdW10VityWGFaK3Y4OXdPT1FnRE9sT3BueHVlNHVMWVlqQjh0NTB4amQ3UFFiRzRpbHUwMUcrWmZxOWpQZ3lBWWhFT0gvK1BGZXZYdVhXclZ1Rjd3eDVvS3RXclhLU1pIUm5DWjFLZ0xHV2xVckEyV2FOMjczaGZHN1FZc21jSnM0eW9zc1M0WEhpZjlsbldzUS9UbjJJSkN2YlBQcGFYNlpXU0haUDNpNGxzL2RuczFuUmdWcXIxZGpmMytmbzZJalJhRVNuMDJGMWRaVXdERGs4UEdUMzRTNG52Uk0yTnpaWlcxMGpxa1k0Z1VObXNtS0NoYnpnUUxLTDF0cEMvNWNYbWNVeGJ6NTR3TzNCZ0kxT0ozOHhoREZrbVNsOGNwMDRraGkzNWtCQlFCbklXa2RyUURZYURWNTg4VVhnVkxMczdlM2xJMTViTFZ6UDUrNXdRcnR5V2hoenBkMWtkekRHUUVFRVlrdG93aTRUZ2F5amJJL0ljM1ZTUys5Skc4d2ZKR1gwYzJWUWRUa3FXc3dKRk5FL0hvOVpYVjB0T2w3ak9HWnZiNC9oY01qcTZpb1hMbHlnM1c3ejhPRkREZzRPaUtLSVZxdkZ1WFBuYUxmYkhCd2NjT3ZPTGZZUDk5blkyS0RUNlJUcFdubVdXT29TbVpMUGRYQkk2L1hKY01qTy9JVk9ydXZTNlhTS05IUlplbWl1RW5mdzMxVVZOSnROR28wRzMvLys5NHU0dnZSTkJFSEFRd2N1TmlJNmxSQmpMZTBvNUV5anlzNXdzc0I5c284eXB5NHI1UzRqdVp4bmtMVnBvdElWeE12dUpjK1NWLzNJYy9VekZnWkZ4bkhNdzRjUEdRNkhiR3hzMEc2M2l5SUtrUWFOUm9PVmxSVXVYNzdNMGRFUkJ3Y0g3Ty92RjZuZ1M1Y3VjWEp5d3RIUkVYZnUzT0g0K0pqMTlmV2lpMVgzSFk1R295S1dVQmFOWld2WEtBQk1KcE1pcnk4dFg3SUhuYWpTeHBibWVLMC85YXRZaFNBa2lpWklrSXFvL2YzOS9PMmRRY0NkL3BqT3h1bUxtSzYwRzl3ZmpoZUlXSDVyUFYzT1RPcVF0ZjVaUmlRYXFSTEtsUnkvbGl3TFJTN3pjNHNLYUhmeEZmTisrUUZabGhYalRIcTlYakY0UU93RGVTT2xqQ1NwMStzY0hoNFc0OTFiclZZeHF1VHc4SkJlcjhmZHUzZHBOQnBzYlcwVjNLdmZUU3pKRzBGRzJXcldmd3ZCOUhxOVlteXNORnBJYWxmcUd3VzRHdWxsVWJ6TVcwalRsR2F6aVV4UEVhQWVIeDhYT1pPOXNVOTNGdE9lMndLcjFZaXRXc1Q5MFJUdk1kSkdFSy8xc0NDcG5La3NjNnBlcjY3c0VVTFJSS0NSckhHcll3VEZmT1JIeUl6VFhyS2pveU1ta3dudGRwdDJ1MTJFZ2FVT1FQcmh6cHc1UTZ2VjR1RGdnTUZnd0dnMG90bHNzcjYrVHFmVHlVZkQ5UHZzN3U0eUdvMEs2Yksrdm83cjVtM2JXdHd0QzR2cTFxWnlSbElrbFBUVWlkcVI4elhpdGIyZ2sxbENqTkx4MU9sMDJON2U1dWpvcUVDaXZJK28wK21RWkliYi9SRWYyZWdnVWJCcnF5c2NUT0tGNkdUWkVGMEllSldzL3JMWWY1dzBLTytuYkN0b2dpOUxoN0xSN1Mrek12V0NaRnJWWURBb1dwT0xFUEM4dVVJU0d4Y3VYQ2htL2g4Zkh4ZmRzaHNiRzdSYUxZNlBqems4UEdROHpzZVlGam5wZVJKRys2ZkxMUGhsUU5YZlM1MmZUUHFXVm03eFBzckdsM0RDc3FGS251Y1YvUkFpU1dUWVU1cW11QTQ4SEU3cHRXSlc1cmJBYXJYQ1pyM0svZUg0ZEpLWlhVeElsYmw1bWE5ZlJwS0krakt4aUdTQzB4ZDZhWFdvbTBtMTVKR2N4NElOOERoTEVpalVRaHpIREFhRElqNGdob1VVSEVnN1diMWVMK2IvSHg4ZkUwVVJLeXNybkQ5L3ZqajM2dFdyaFRyb2Ryc2NIeDh2OUJrS3h3dmdIdWNpbGZXN0FFUDYrYTIxaGIwZ2hSZzZHbGdtSWlFSzEzV0w5d0pwWTFJS1NxMHhKRGpjN285NFlXNExPTUNWbFRwN284a2pkZzBzMmlKQ25GcXlDWkxMVlZKYUJjcDlOQXcwY1lrbnBBbFoxaUdTVHJ5dzRuMEJINFI4ZlhQWi9HZzBXbEFMR3VpVlNxV0lFelNielFLNU9wQlVyOWZaMjlzcmJJSE56VTJpS09LdHQ5NHFLRmV2cVVoY2xNU242SHBOQ0xwSVJRQWtObzIwY1JlOThhb0RGMDdUcUNJNlpSeUxTQ3hSalVtU1lLekZkUjBlREtkY1hrbG9oYmt0c0ZhcnNGRU4yZW1QOGQxRkxwZjFhSUxRRTFRMEVTenpCSmI1K2VXL05hemsvaUt4aFRDa0FtazhIaSszQWY1TmZxWFU2L1Y2UGRydE5oc2JHNFd1U2RNVXFUUnV0VnFGdmo4K1BpNjhCbm5ibHJScWR6b2Rack1aNzcvL2Z1Rk5OSnZOQWpuYTNkT3QwbUtrUFE3QWNvaWhLZmw0VVF1VlNxVndkOFZkMDAwdGpVYURzMmZQOHZEaHd3V0RUVXJvUGM4ak1aWTd2UkhQYjdTQmZONy9sWGFUN2pSbWxtVWthVHJQSlFRRm9zTXdMTlloc0phMHNNUkxaQ0taaHJ1VzFNdWt0aVljMmFNdWtCRnBFQVJCNFlJNzFXclZhb0Q5bTZSQitRaUNnSldWRlZaWFY0dFhsT3FTcUNpS0N2RXJSWjdDa1hKdHJWWmpOQnJSNy9lTE9Yc3lxMEFYYldvWFM4YmJsZE8yUWlqbGNpeFlMRnVYKzhnYTE5YldpcG84cVJ3T2dvRDc5Ky96OHNzdkY1Tyt3akRreXBVclhMMTZ0U0Q2d1BQNDlOazFHb0ZmREp4T3JXVXdTM2kzTytBb3pxak81d0NJNU5IMmdFYW83RU15ZitXaFVtWFBRUFloa2t0ZVpxbGZaU3ZuQzVFSlFTUkpnbE92MSsweVAveHh4dUhqQ0VTUUp1Tll0QTh1Q1NkNXJidmpPQndkSFhILy92MUNOTGRhTFlJZ0tJeE9tV2d0RzVJeWJ0MnBKQUdPc3BFbmZyeHd2UUJQSDVvSXBPSkdwSUxVT3pRYURWelg1WHZmK3g3Mzd0MHIraU9lZlBKSnJsKy9YanpMQU0rc3RuaXkweVNUK3dwaXJPV3Q0WXlqT01PWk13eWN2cHBlcDQvbDBBUXRLVzVSVDlwUTFKenV1bTVSV0txbmxBa09CQS9GSzNkRXVsU3JWVnRHN0FjUmdJN2NsWTB2QWFDTVNoRUxYMFNyRU1uVzFsWlJJcjI3dTh2T3pnNXhIQmZkTzNyU2hxWnM2YXNYdTBNQW85ZWpwM2ZwNlNabHhNdWhHMkswd1NaU3BORm9jSEp5d3M3T1RxRlBMMTI2eEpOUFBsbFVRbU1NbnpxN1Rqc0tIMmtvY1lGUlp2akJZSWJqNWM4U08wSUlXQkkybXFzRnFkb21rSEZ4V3RJSmN3alI2ajFxNDFJSVFLU2I0TktKb3VqZnNwU0RBa2lQT3pRbGkrV3ZKWUlnUkJPQ3ZLVkxadDVLbWJTTVJOV2JrS0xLWnJOWmhHVjFnWVJ3Zy9hTFJjekRZb200bksvckI4djdMSjh2M3BCa0RiZTJ0cWhFRWMzQTV6TVh0K0VEdE9mM2UxT0dKdS8vMGdpUzMxb0NhME5PSjh5QVI4YlRpa0dySjZOb3dwZjdhUzlBOXVjNHpuOVlBaWo3MmdDMVdvMlZsUlZhclZhaFk3WGxLeTlXOUR5dmVQM3E4ZkV4azhta1VCMVNoallhallyeVpsRVBRUkE4TWxkSEVLZGRLUjJUbDdYcWdZekxERW10VWdRUjhocllvdVBHRDlodU5mZ0xQLzdISHc4WDROWHVtRjZTajd0ZFpzQnA5MVRHOHNpZVpPMXluWllZc0ZnRFdFNk5sNE5BK2hyWGRaZDdBZisrUjFtdml1c29pQlhyWG56Z05FM3BkcnVGTjFDcjFZb3c4bUF3S01LOTQvR1lsWldWQlV2Wm1MeDlyZHZ0Rm1xZzNXNFhuS0NOUUtta2tmOUZYSlpGZjlrOU04WVVmWkFpUmZMM0UxV0tuQWJXMHB0TTZJK25kQnBWTWxPV0pEQk5EYjNKRk92NVdIczZPMW5uNmJYTkpPc1gxU2tFV0g3OXZDWmdzUkUwNHVVUW1KU0hVLzQ3UzRCL1d3OUJCenJLT2xWR3ErbFh0V3RFaEdGWXhQWFROR1U0SEJiMUFmSzlTQVJqVFBGbTd1RndXTGgxRWhMV3lTZXhKelQzNmJlZHlCcUYrNUlrS1FwVUJHRnl2UmlNVWlYdCtRRS84dHgxZnVMNXAzUDFJMXptT0xpT3d6ZmV1Y21yOXg0UytGNHhOMGdhY2l2S085QWhhUzNLWmIwaUVXUzlvdk8xblNENzBJUWxkcEVZbm5vUC8xRUlBQ2lzZFQwclFCZC9DcUpsV3BaUXZMU2lDUUpGYmN4bXN5TFBJSU1mSktna2hwVjRCbUt0aStmUjZYUndYYmNZMTZZNVFiaE5nQ25wVTBsa0dXTUtEaEtYVm94VWJZUjJPaDMrK0xQWCthR3JsMmhFdWRzNm1zMzQzcDFkWHJtOTgwaGtVeU5jZExrWXdPS0NsZ05mY3VoWlFTSWhsaG5sOHJlV3VMS09vaVA4MzlVR1dIWXNJd3poYkMyV3lyWHR3Z0VTcXRWdDNuS2RHSVNTOWhXcDBPMTJHUTZIQmJISTlkS3JJUGFDQkhSRVBjajl5MjNTV2tYSVN4eDZ2Vjd4dmJYNU93TldWbFlXQUF3VTBxVmFxN0hXYkhCbXRZUGpPQnlQeHZTbitTU1N4N0dPN0ZYZ3BVZnhDV0ZxK0ZZcUZkYlcxbWcybXdBTGtrSzhGTGxlOXFkbk5PdUs1ZitvQlBDNDc4U29FUzRRRGhRT2VCd2hpTGdWNDA5eUVDY25KNHhHbzJLaWlZUjZoVmdta3duajhiZ0lIQWxRNi9YNlFyR0t2QlJhKzg3U01pWnIwWTBrc2pkQmtPUWU2dlVHeGhvODM2YzI5N25MSENrSWtFUHJmLzFibjZ0MXQzNHRqVFlNSmNJcTQyL2t2Z0szVHFkVEdOTUN2MzhyQWlqSENNcmZsZDBZZlc0NXRhdkRrem9wbzFXREdJU3lVYTBYWmJQaS80cElsMVR0Y0Rnc1lnNGlPZlFjSUhuN0Z1UWVTcnZkcGw2dkYxYTM2RXZ4dThVVEVkKzUxK3NWWTJaMDFaS2twY1UyMFlNZk5lY3RTKzdJVElaeUhjUXlvdEh3ZzhWYUFpRWVuUzZIVTZZVFloZkphSzM5RDBzQSt2L0hIYm9PWG42V1JmT0U0NFVZOUJSTnNYamxIUGtCR0kvSGRMdmRZa2d6VUxpUzlYcTl1SDQ0SEJhVHdnUXhRUkRRYnJjTG9oUEVkRG9kbXMwbW51Y1Z5UzJ4SS9UYVpmK3lOcjIzOG9CR0RTUHg3VDhJOXZxM0VKM0FXa2R5eTdaTkdYY3k2NkZRTy8rK0trQnZSQk9CY0ZCNVJyNitya3dFWlFJUWhBajM2SEN3N3E0Vi9TZnQzc0x4RW5TU1BqK1pOeURHajhRa3RFMGhZbEhxSExJc0t3elU5ZlYxMXRiV0NtTzFtRnFtNGdHNk1FUGlFWHEvMnZYVUJwdjhMb3Q5T2NxRk1uS3VTTXl5U3RJNDBaL3BPSWxJTU1keGNDcVZ5dEpRY1BtR1pjVHI4MlVSWXAyV2t4ajZLQ2R3eWdTZ2dWWit2dmpDWXYzcjFtcDVwbVFKUlNwSVBsOEtWU1J1NERoT1VaQWkvZktpU3VSSGpFREpDMnh1YnRKc05oZldJM3NYb2hPWFVWU0lxQVBSMFhyUEduWmxBaEN1MXNhcGZxbVVpUFF5ZlBULytyZUdzWTZFRmdUd3VPTnhCbDc1Y3dueENpQjFLck5NQUZwM3lrSjBWVTZaQUhSb0YwNjlCeWxKRTMwclhDaXVwRWdQSVJpWmhkenY5emsrUGk1Nkg0UXpwTWhVQURzWURBcHZRR3dMUVZZVVJVVUdWSDYwTFNQZWhIRHJNaVlDQ2x1blBKWkhZS3JQTFhzS292YkUrdGRxWVptcTFxRmxrWnFQRU1BSFNZSVBPay9FdjBTdkhuZXRsZ0RsUXNieVlzc1NvQnl5MVFhaEZLNktCNkNES2NKTjlYcDk0ZVVSb2lJT0R3L3BkcnNGWUNYWXRMS3lzaUJtUlRJSVlZZ3RJaXBLMUpBWWpXV2kwRkpSOW5MMTZsVTJOemZaMzkvbi92MzdCZkxFY0JPQzB4azlnWWt1L3lySERNb0JObGcwd0lzZzAzOUlBdEF4NjJXSGlDSVIwMnRyYTBWQ3A5L3ZMN2hoWmEraS9Idlpzd1VSWXZRSkFpQzNTV2F6V2NFdFV2VXJxV1hSNitYWDVNcGE1WDU2bXNsa01pbEsyYVRCUm13QVlHRVNXYVBSZUNSTUhVVlJNWk9wMSt0eGNuSUNVSlRmYjI1dUZvR3A0K1BqNGkxbDVjemhNbHRBQW5INmV5MUJaQnJMQWdFc0UrdVBJd0Q5ZVZsVWZkQWhpRzIxV2p6MzNITlVxMVVPRHcrNWUvZnVRaitmTnBMS3J1V3lOV28xSVJVdjhtbzFjU2YxZmZVUVRMSENCVEFpdGdWSU91SW40ZXpUVjdUbTk1UXFIcGxJS2g2R0VKTjRHWks4OG4yL0dCM2ZicmNYWGdrcnRreWowU2oyS1BjWGcxSUlWZFlrTm9obVFPRjRIWGNCRnV5Sy94ODZkUXBRRU80VlFBQUFBQUJKUlU1RXJrSmdnZz09"}} \ No newline at end of file diff --git a/sleap/skeletons/flies13.json b/sleap/skeletons/flies13.json new file mode 100644 index 000000000..7a2c02422 --- /dev/null +++ b/sleap/skeletons/flies13.json @@ -0,0 +1 @@ +{"description": "Template Skeleton for flies13 reference dataset.", "nx_graph": {"directed": true, "graph": {"name": "Skeleton-0", "num_edges_inserted": 46}, "links": [{"edge_insert_idx": 44, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["head1", 1.0]}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["eyeL1", 1.0]}}, "type": {"py/reduce": [{"py/type": "sleap.skeleton.EdgeType"}, {"py/tuple": [1]}]}}, {"edge_insert_idx": 45, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["eyeR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 34, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["thorax1", 1.0]}}, "target": {"py/id": 1}, "type": {"py/id": 3}}, {"edge_insert_idx": 35, "key": 0, "source": {"py/id": 5}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["abdomen1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 36, "key": 0, "source": {"py/id": 5}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["wingL1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 37, "key": 0, "source": {"py/id": 5}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["wingR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 38, "key": 0, "source": {"py/id": 5}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegL1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 39, "key": 0, "source": {"py/id": 5}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 40, "key": 0, "source": {"py/id": 5}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["midlegL1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 41, "key": 0, "source": {"py/id": 5}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["midlegR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 42, "key": 0, "source": {"py/id": 5}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegL1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 43, "key": 0, "source": {"py/id": 5}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegR1", 1.0]}}, "type": {"py/id": 3}}, {"key": 0, "source": {"py/id": 7}, "target": {"py/id": 8}, "type": {"py/reduce": [{"py/type": "sleap.skeleton.EdgeType"}, {"py/tuple": [2]}]}}, {"key": 0, "source": {"py/id": 8}, "target": {"py/id": 7}, "type": {"py/id": 15}}, {"key": 0, "source": {"py/id": 9}, "target": {"py/id": 10}, "type": {"py/id": 15}}, {"key": 0, "source": {"py/id": 10}, "target": {"py/id": 9}, "type": {"py/id": 15}}, {"key": 0, "source": {"py/id": 11}, "target": {"py/id": 12}, "type": {"py/id": 15}}, {"key": 0, "source": {"py/id": 12}, "target": {"py/id": 11}, "type": {"py/id": 15}}, {"key": 0, "source": {"py/id": 13}, "target": {"py/id": 14}, "type": {"py/id": 15}}, {"key": 0, "source": {"py/id": 14}, "target": {"py/id": 13}, "type": {"py/id": 15}}, {"key": 0, "source": {"py/id": 2}, "target": {"py/id": 4}, "type": {"py/id": 15}}, {"key": 0, "source": {"py/id": 4}, "target": {"py/id": 2}, "type": {"py/id": 15}}], "multigraph": true, "nodes": [{"id": {"py/id": 1}}, {"id": {"py/id": 5}}, {"id": {"py/id": 6}}, {"id": {"py/id": 7}}, {"id": {"py/id": 8}}, {"id": {"py/id": 9}}, {"id": {"py/id": 10}}, {"id": {"py/id": 11}}, {"id": {"py/id": 12}}, {"id": {"py/id": 13}}, {"id": {"py/id": 14}}, {"id": {"py/id": 2}}, {"id": {"py/id": 4}}]}, "preview_image": {"py/b64": "aVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUlBQUFBQi9DQVlBQUFBbitzb0hBQUJGSzBsRVFWUjRuSjI5ZVl4bDJYblk5enQzZVd2dFZkMVZ2WGRQVDg4K25JV2o0VElqTGlJbGthSmt5WllkU1hGZ3hJaWlCSTZqUUVnY0NBNkVPQWdTNUE4SGdRRTdpWklBam0wNGppTkxva1FySW0yU0lzVmwyQ0tIdzFsNlpycDd1cWYzcmw1cXI3ZmZlMC8rZVBYZCt0NVg1MVVQYzRCQ3ZYZmZ2ZWQ4NTl1Lzczem5YTmRvTkR5QWN3N25IQURlKzVFL2dDaUtjTTZWM3o5SWt6N2xHZWxQeG5IT0VVVVIzbnVLb2lpdjZaYm5PZDc3Y256cFQ4TXF6Mmw0YlI5UkZKVmoyZWZqT0NhS0lvcWlLSCtUL29xaTJBT1RuYU9HUTY3RmNWek9UNjRWUlVHV1plVmNOZXloUHVTWktJcUk0NWhxdFVxMVdpVkpFdkk4cDlmck1SZ015UE84aEZQRExQK1RKQm5Cb1c1SkNPbjZtZ1pPT3JUM2E0VHVoeHg3bnlhYW5yeEcrampraHdndi9WdkV4bkZjUGlPRURzR294N1Q5YVRocy8vb1orVDNMTXRJMEJTZ1p6d3FFSGxkZkd3d0dwR2s2QXE5empzRmdnUGVlV3ExR3BWSWhUVk82M1M2OVhvOSt2eitDUjVsakZFWGtlVDdDVEVWUkVNY3gzdnNoQTBpTG9vZ2tTY3JPOWtPOGNMYVczSkJrYWdUb0NWdUU2dDh0UWFRUFN5QTdscDcwT0FiU0NNL3p2RVNFdEJEVFN0OEN0KzVUUzU2ZGt6Q0JadWc0amt1dGx1ZDVlVTBJTXhnTVNKSmtEK3hGVVpTRTdIYTdKU1BVYWpYaU9DYU9Zd2FEQVZtV2xSclB3cWMxWEo3bjVIbE9vaEdWSkVrSmNML2ZaNzhXa2dKTmFIMmZFRVFEWTVHdXBjUWlWU1JZeHRJU3JQdlFrajZPa1RRRGluU0l1ZzVKb3g1UGtCb3lJeUYxTG45V0ExaFRKSnBpTUJpVXNGZzhBeVhERkVWUkVqTk5VNUlrS2IvcjN6VERhcHhwaGt3MElLSmlzaXdMSW1LY0Q2QW5xdS9WaEFSSzI2WHZzY0JwUkZ1RXl1UzBiUTJwY3d1WFZlLzZHYkdQbG1EV0o3Rk1xMVZyaVBHbGlYMldzVFJPeEMrQklmRzFiNkR2c2N3cDJpRExNcElrS2ZzVi84SXl2MlpPN1IrVUprQkxWci9mMzVmUUd0bmFlZE5jYnRXbjNLK0pMeE1YRlN6MlNUOW43YlZXdytNUW5tVloyYSsxMFpaNTVGNjVYeGpNM2o5T0lnVW1VZUh5dXlhYTRFVG1Jc0lsL2N1OGhhSEcrUnNob25ydkdRd0dRVDlHMDJnL0p6UFJBNDF6dUd4bklRS0V1TTJxZE8zUWFHN1gyaU9rZFhULyt0blFaTFgyME05WnM2TGhBVXBwdG4xYUdPUlA3SzdZYmEwSkxOTnErNnZoRXFKM09wMVNRS3htME9QcWlFQ3VoeUlYUzBlQnh6TDBDQU5ZaDhPMlVNY2F1UlpobWlIMkE4NXlxTlVnKzlsbTNiZWVoNGJId3FRZFJFRm95SVpMLzVvQTFxWUx3YlJqQlpST0hPejFHL1FZMHRkZ01OaWo2c2NKaWlXaTlCSEhjYWxkN0p4a3JrVlJrQ1RKaUNDT1JBSGoxS3BHb0oyRVpoYnI4RmlFV2E0T3FTYUx0RkRURTlBRTBNUU9NVnBvZkN0QndJalRhZUcwNmwzM1o4M091SERXTXJnNGdkcWNhcE00emd3S3JNS01HbTkyUEIzdGFHMlVhRzU3VUFzUlRJZ3IzSmNreVZqSnR3alRnSWJVYklpd1ZwMWFxZFlKSFEyM2hVTXpwbGJUMW9UbzUwSU1GTkpnV3BYciswUDlhWk9oQ1dRRlN6T2M3U3VrZ1VQbVdJZWJNbmJ5SU5zZlFvUjgxOXdvOXRDcXNIRjlod0RVTGFURzdPOTZzc0NlY000aU50VEdaZVVlaEFzWjN6cTJJWTFpbWR0R09jNjUwaUVOYVRkN3I5Vysxc3pZcUNSa2ZrYzBRQWhCRmhHaDc1YUkyam14d0Q2b2pTTkFhQno5alA1TkV3TjJFMEwydXUxZmE4Qnh1TEJxMnpLNWx2eHhKc2hLc0VoaWlGRXNBMnVtc3hwWU02T0dUZVBNOWkxdHhBZXdMU1NoNC95QWtQMjF4TE45aFpBZU1oZjd3V1dsUWE1SlZ0T3FVOXNzc2ZaaldBdXZOV002bEpQdnRtK3R6cTBUR1ZMdEllbTFNRmpHQzlFaU5EZm5ITkU0RXlBY1pHMnU3ZFFPYkRuVjJpL2RSMGhTeGtsUGFMeVFyNkFkTWZGSFFneWxKVVdhamVmdC9hRW0rQW1GZVpvUVdrdEpJa2UraDNBa05sdmcwdmkwTU1uNE5pbG1tU0ZFNjBRNitLQ3EyazRlOWk1MjZHc2hKeWxrMzBQSTh0NVQ3SHlPallkck9Wc0lvSk04blU1bnhDYUhtandyU0xadFhKUWp6NHJOdG1iRWV2QlpsbzJFanhvZW5ZK3dnbVpYUWEzemFRVkFQL2NnVGVtOS8rQStnRVorNkw2UTVJUzhWZzJnZG56MHBJcWlJQ3NLdXYwQlUvVWF6VXFGKzYwV1JWRlEzWkZxQzZORnVDRGF3bUxoMTU2NFZkbjZ1bVV3aTNpTEgrLzlTSHd2c0lWd29wMDUrYTV4RW5KbVF3UU81UnoyTTkyd3ozS3dibGJTclZOaTdkYzRFNkdScWozMlBjMDVKcXBWZnVQakgrT3B3NGVweERHM05qYjRmOCs5elhjdVg2WlJxWXlWNnBEUEVWb3ZzTTVyS01FeTdobHRGc2RwTkgydkpxeUZNOFRNOXJQV2NLRStiZjVCbnRQK3lEaDhKZnM1Vy91MWNiWmVybWwxRjBMS09Fbkw4cHlKYXBYZi9PUW4rTTFQL2lTVFU5T1E1MUFVdkhqOE9QL05sNy9NSzVmZnA2STBRUWo1NHlSOTNGekdtUUM3RW1udHRiVzFXcjJMNXNqem5DUkp5TElzNk1OWWZGcG4wakpqNkx0ZGN0ZDR0YmdZV1F3THpqcUFJQ0dtVmswV0lKbUUvRWx5U0FPbC9RVzVybFdkOTU3anM3UDg1azk5aXNsS0ZXUloyamsrOWRpalhMeC9uMWZldndKcVhCdU9oVlJqeUhjSU5hc21yVm1RcHBsZnJ3cUdQUDl4RHBqR256eHJZUStGc0hZKzJreG8yUFI4dEoranRVbjBRWkNpSjJvQmx3SHRBb2Iyaksxalo0RXZuL0dlTkk1NTlPQkJKcXMxMEJMclBYR1NjSFJtaHFXcHFkSTV0TTZRMWtJVzBSK2t5VHlTSkNtakFpR3EvaS81ZHkwYzFsYUx3T2drbVhYQzVMUDJFMEpyR1pZV0dsNGQ3WVRNdERZeituT1NKQjlNQStnSE5CQWhOYWJUakhMTkFtNDV1NnpaY3c2Y296WG9ReFJCSUg3UGZVRjNNTmlEa0pEdHRzMytGcEpLbTh6eTNsT3BWSWlpaUY2dnQwZlZhdzllTTRCbUh0aFY2L3FhSm9hRkxVUTAvZHM0RXhSeWpFUFhTOGR6TExaTXM0Qll0YTJSWm9zVWRZYktNb2FlUUJMSEZONXo0YzVkYnF5c2dKbjRkcWZObXpkdnNySzFSZXhHUTcrUXBPb1dzcWVoWmxPNUlzSFdhZFhJbGQ4dHdtWGxUZnF5L29TMisxS2laY1BKRU03R09kd0N2NzVITTV1VWkybmEvZjltQUdtaE1FTysyL0JHMUpXZWpFVkU1QnpYMTliNU8zLzRSVzZ1clVHbE1tU0VPT2I4OGgzKzRJMDNTT0trUkk1ZTNwU3hORFBzeDNDaFAxSEJnaXlnckxTeEJOYkVsUmJIOFo0cUk4MU1RaVJyVXVTNnRlZUN5eENzSDRSZUl3SzJneXNOL3dkMkFxMmFDbm5kSVdkSE9GK3IvWEZjWG1vTVgvRGx0OS9sNnRvNm56cnpNUC9sWno3RHpFU1RZN096L01UeEU3eDI0eFpWNDI5b2MyUlY4NDhiNldnQzZES3IvU0lOU3hncEVySHoxeVpCSjVDa1dEU2taZTBpVjJoT2x0RzFZMndYenJTSitrQmhvQTA3UkZKQ2dJUlVyeTV1MEFBSklqUkNSWG9MNFBWYnQ3aTZ2czVVbzhGdmYvNXpISnllNXE4OTl4eC9kdkU5YnF5dms2cjQzWTZ2aVJGeU9pMUJOY0kxN0hxdTlqNHJtU0ZWcloxblBiWU9DU1ZMcU1lMHVIMFFucTBXRWJpdHYySDcvMEFtd0NKVGR6Sk9OUW5BT3ZUUVJRbGFSY3AzYlFNajU2Z21DZHY5UGw5Kzl6eXZYNzBHVWNSUG5uNklYL3Z3OC9UenZXclMvbWx2UFlTNC9Sam5RUXd6VGcxYnYwVDZ5TEpzWkZNSTdJWnpvYkJOK3RwdkljczJLUlFWK0VUTGFKdXZ4L2pBREZBNkRBRmtXbW5Rem9jNFIxYUZQY2lXYVljbzhwNXp0Mi96VDc3L2ZmQ2VhcTNHenovMUpCOS82QlI5RXlOYjVyUHc2dmxZQnJSejBuRDlPRVFRb21tSjF2a1FnY3N5cDRiWitqVDc0VXlyZVFrSDllcWcxYmI2K1ozSTY4ZGJCTExjYWdjS09UOXBtbEt0VmtzZ1E5S3ErN1FwNWs2M3kzZmV2OExYTDE0RTUzanU1RW4rNnJQUGtDWkpHU25zcDRuc3RkQzlJVHpvKy9WL2dYbWNiNkRWZTRnSmhibjNVK3VocE5KK1RSaFBuRkNydmF4NUs4ZjVjUmdnei9OeTc0QUZXaE5kYzZLa1F1VnpsbVVqbXNFaVJ6dE9nb2hhcGNLbCsvZjVsejk2blg2L1R4SkYvTnlUVC9Bemp6L0d3R1FCYlVMcVFjMXFqWEVTcHVjWTBtUnlyOVRwYTJlc0tJYVZ3M1pNd1lzMnFTR0h6WTRkOGczRWhJcXBDZEhJTnUvOWJqM0FPQ2w0RVBLczlNdkU1RGU3bTJXL3BxVmYrcExuOGl6ajdMWHJmT244QlhDTzAwdEwvT0pUVHpJMzBZUXhrcnlmZ3p0TytpM3pXSnlNMHhTV0VXUjh3WTg0WlRKR3FIVE00a0wzTlk1R0ZuYng3dVZlcmFXMHVTNzlwQitYNlB1MTRBRFJhTUdtVk1DR21pVys5RmtVQlJRRlYrL2U1WS9mT3NmZHJTMmM5L3o4azAveWhjZWZvRys4M1JBVGpOTUtJZWN1Rk45Yi84WktvWFdPTlN6NlQ2ZklkVHA1UDBLSHBIOGNJK3FrbEJiT1VQOVJGTzExQWg5a0Z6VlFvdDVEQ0pUUFJWSFE2L1gyTFRyUmxTLzdxVi95bkc5ZHZNanZ2L2tXT01mczlEUi82ZWtuT1hOZ2dUeGc1MElhd1BZZkdrdm1ZSW1xbVZrN3R5R3B0TXdzNXFGU3FaQWtDWWNXRC9QTTQ4K3pNSGV3dE5zNlV6aE9HRFJlUS9PemtnNlVwamUwUHJOblgwQW9KTEVxTFlUQWtFUm9nSzJVNkw1REsyaDJmUGxiYjdYNCtxVkxmT2JNR1I1Wm1PTUxUenpCTjkrN3hQLzYzVmVJbmNNWHhaNXhRNHlocitsUVZUZHRoN1hhdHFwN1hDU2hDUkJGdzlYUlJxUEpmLzRidjhQSFgvZ2tlWmFSSkNsbmYvZ3QvdjcvOXQvUzZiWkxXMjU5STF1d292dTI2bDdmYTJHQllaS3FVcWtBTzJzQjR5UitQeHRxMjRPMGhUWUhsaGkyWnNEK2pVd2l6M25sMG1YKzZPMjNLUXBQVktud2w1OSttbWVQSENFeldzYjZONkZWUzduZjVpazBySUpVdWE0bDM4NHRwRlYyUFhyNHJWLy91M3o4aFU5U3I5YVphRTVTcTliNHlQTS95Vy85K3Q4dE40aUtadFZ6Q0VWWlZzcERmb1g0WXpaOEYyYytrazVFRGNrZ09wYTFkWFhqYk5RSHNXWGpWSmY4YnB2bFlPY2M3WGFiTDcvekRxOWN1d2JlODlLamovQnpUejdPWktOQlpPSnEyL1Q0R3JFNjZ0Qy9hV0k3dDdmME83UzZaL0VsYlhaNm51ZWVlcEZHclRGeXZWNnQ4OXpUSDJGNmFnN3dJNkd5SFJNWVNTaHAvTmh4UTVsQTUxeTVwUnhVUFlDRUpCWjU0OVN6YldNbFZ2VWovKzFLbW5Cb0tPbWg0U21SRHZ6bzZqVys5UFk3ZEh0ZDhKNWZlZlpaUHY3UUtaeXl6YUdtSldHL2hJdEZtc0NoNTZYaHN0ZjBmL2w5NmVEaFBmZ0Y4SGlLUE9QUXdTV2MyNnRKUWxLdmZiRDloQ29VZlduR2o2eFUya2xwVHRNZDJQOTJQNTIyVGZ0SnRpQi92eGIwdUxPTXI3eDducTlldm9MM250T0hEL09MSDNxYVE3TXpKR202cDVSYSt0Qk1yaXVjUnFwa0ZETll4aEFHRHZrbk5yTTNOQTJPdk1ocE5pZDQvcWtYbVd4T0JwaHpPUDd0TzdmS3ZqVVRqeE1PVFVnOXBzV1pNSUZPQlpmenQ0aitjZXkrSUVBUGFQc0lPVnc2VGF6djI0K1RiZDhPZVAvZVBmN2tuWGU1dDdVRjJZQmZlZVpaZnVHRm4yRGh3QUdxMWVvSWZQSlpaOHIyTTFmNytUVHl1ODdXYVVkTTVoa25NWEdjc0RpL3lILzRhNy9Kci8vYTM2WmVhK0J3eE5IdUlWSWIyMnQ4L2J0ZlpydTlGWVRManFzamhwRHExNzZKYmpxeWtXZjNuQTlna2FBSmFJbXRuN01Fc3ZmcDMwTVRDOW5NY2VPSjA1VUMvL2I4ZVg3eW9aUDg2clBQVUluZzExNzRNT3RweXJkKytFUDh2WHZsS1ZwYVl1MTZmS2hwN1dYTmtkWW1tZ24wMHE1SThJa2pEL0VmLzN1L3hiTlB2b0J6RWIxK2x4dTNyK0tMZ2dKUFVYaGVmZU1WL3ZmLzZ4K08rQnRXR0t4SmdOR0NWUjJTaHdSSm5GekxITUh0NFRZR0RoSEhldGlXaUxvdmJZTnNpT085QjArWjA3Y0kxeUdONWx4Qjl2MzFkYjc0MXR1OGVQUW9EOC9QOC9Ua0JKOTcra2xXdTEzZWZ2dHRWdTdmTDA4OUNSVjFoSmhlaDN4eUxjUUk4dDBTd3VPcFZXczg4K1FML0VmLzduL0cwVU1ud01ObWE0TlhYdnNtLy9UM2Y1ZTF0WFhtWnhhNGMrODIyNjB0NGpnaGlwSmd0alFrR0NINjZDZ21SQk9adjA1RUpWcWlkTWNmeEZNUE1ZYStSL3NRZGlMZWUvSkJUcFJFcE5XVVFYZEFuaGRFeWZnTkpyYUpEZnZLbTIveXNhT0grVnN2dlVRMWl2akk5RFMzbm4yV3JDaDQ1NjIzV0Z0YksvUGsxcWV4V1QzeGtIdTkza2hPUGVTVWl2U0wxKzZjQXdjelUzTjg5cVhQOGUvOHdyL1B6T1FNaGZmY1cxM21qNzc2Ly9DbGYvT3Y2SGE3T0FjM2JsK2pLQXJTdFBLQjF5K0VSaFp1NjIrRi9EZnJSRHJuaGp1RFFrUU1jWkJ0V3YzWkNNS3EwRDJBRnA2alR4emk0SmtEVE00MjJiaTN4ZktGdTl5NnNFeGFUWW5jK0VNaU5QRmtqTi83MFJ0ODlQaHhQbmJxRkl0WnhoT1RFOXgrOUZINjNTN3ZYYnpJNnVycVdKc3FmMG1TVUsvWFI2cUFRb2pXWTl0MS8yTUhUL0JMUC9NcmZPYWxuNk9hVnNuem5LdTNMdkV2dnZTUE9mdkRiMU1VUlJtQ3hYRXhzaW5GTXIwT3cvVjFEY3NIOGRrMFU5Z3k4OFJ5OVFkdElTOFU5cDRKcUlFb2tlL2g1UFBIK01YZi9sbE9QSE9Fcko4VHB4SHZmZThLZi9qZi95bTN6OTh0alpQVkdpRlRGRHZIRDY5ZTVmZGZmNTBuRHk0eTFXendTSy9IYXc0ZWZld3g4cDBWc3UzdDdXQllsS1lwemprbUp5ZXBWQ3EwV3ExeVp6R01obzUyN21Mdks1VUtEeDAvdzEvNTJiL09zMCs4UU9SaXV2ME83MTUrZzkvNzAzL0dwU3NYU05NS2NieWJscFhESUhXR2NkeUNtVFd2bXZoVyt1V2FqUkNpYVBka00ya1BQQ0ptblBScmdIVklGZXJMWnJIU1Nzb3YvSjJmNXZDakJ4bjBNaHlPdko5ejRwbWovTUovOGRQODdxLy84ejNwVEF1YmxlWnFIUE43cjczT3AwOC96T2VmZXBLbGVwMkg4b3lOYW9Xang0NXg3KzdkOG1oVmE4OGxNcWhVS3RUcmRmSThwOTF1ajVSMnl6TkM5SExaTjNKTU5pZDU1dkVYK01LbmY1bGpoMDdoY0t5dTMrT0g3NXpseTkvNkltdHJLelNiRS9pNkwvUHlVblNhWlZsNXdDTXc5bnpHRU9OcjB6M3VmbTMvN2ZPZ3RvYUZFTHpmTlVHS3RwTWFTZkpkcHlpOUgyYTVaZzlQczNCOGZ1ajQrV0VpQkNCT0loWk96dEdjYTdCOWY1dTRGazdvV0pzV1JSRnBITE84dWNrLy84R3JQSGZrTUlmbjUvbkpBd2U0Zkh1WnUwbkM5TXdNNnhzYmUzTHFPaHJvZERyMGVqMjg5elFhalpGNU9PZW83T3hKbEFNMW84Z3hON3ZBaTArL3pDZGUrR2xtcCtZcGZNSE51OWY1Mm5mL05YL3g1bmZvRC9xQUk5K3BnNUIrS3BWS0tUU0R3YUJrZ2lSSnlzakZydXRyTFdCVnVYVU1kZUpOVEl3K0ZrL3UzN2NxZUQva0MwQzJDVUdFUVFUaCt0NXFyUUxpL1p0bks3VUtILzc1cC9uUm41eGo0KzRXYVhVb1pUcGpweWVnQ1RsUnFmQ243N3pENTU5NG5GK2RtbUttMmVRVGM3UGM2dmFvTnhyVXF0V1IwamF0NG5XR01rM1Q4aXhlbmFtVWd5N3pJZ2NQU3djTzhmTHpuK0hwUjE2a2x0Ykk4b3lMMTk3bFQvN3M5M25uMHV2NEhhR1RvM2Qxdlo3R3AxUk1aVmxHdFZxbDMrL1Q2L1hvZHJzang4cGFwdFhSa080dmxMME4rUkY3R0dCY3lHZWJWUy9TbWZjZW0yb1ZMeGwydWZiK3RWVTJWN2FwVFZZQU4xUUVPNkZnYzZiQlozN2pKUTQ5c3NpN2YvNGVsMSs5eHNieUprazFKb3IzSHFlaW5iSTRpbWoxZXZ5VFYxL2xZeWRQOHZEaVFaNlpudWFIVzl2Y2FEWnBURXdRcWFWWHFkU3BWcXRNVGs0eU9UazVJamtpN1ZxaSt2MCtXWjV4K01CeFhuN3VwemgxNUZHU0tLVTc2UERhdWJOODVkdC96STNscStUWmJzZ3A0WmxtT3RnOS85Y3VxY3VTY2FWU29kdnQwdS8zUnp6NmNWbldFUEZEUk5kYXdVMU1UUGdQRXRxRmJKQUFvT05ydmVJbUVqUVlET2ozKzdzNUFBL1BmTzRKUHZlZmZvcWxNNHRrZzR3a2plbTNCeVMxQk9mQXVZajEyeHU4KzYzM09QK3RTMXc4ZTRYV1NvdHFvd29SUkM1OC9Ic1V4eFRPOFR1Zi9ReC84NFVQVTY5V3VkWnE4VCtlZTRlM3IxNmx0M01vb3p5VHBpbXpzN01zTEN6UWJEWVpEQVowT2gyNjNTN2RicmNrbEtqdWFyWEd5VU5uZU83Umo3STRkNWc0aWxuWnVNLzNYdjhtZi9iS2wxbmJXS0ZTcWU0eGZYcEpXQXRNbnVlbGhnaHBwSDYvWDJxRVhxKzNoNWhDR3kyQWFacU9WQWpMSEd6QktvQ2JuSnowT3U2M0NCV2l5bi90K0ZtN281MGtVWnUxV20yRWkwV04rc0x6OUdjZTU5alRoMmxPTjJodnRCbHM1aHc5YzRTVEx4NWg4bGdURnptY2g3VmJHMXo0N21VdWZQc3lsNzkvamUyVk5vM0pPa21hbE02VWVPSnhIRU1VY2ZMQUFmNm5uL2xwbmx3OENNN3hlemR2OHNVTDc5RWJEQ2gyRmxDU0pLSFJhREE5UGMzczdDeEZVYkN4c2NINitqcnRkcHRXcTdXN0VoYzVGZzhjNGlNZmVwa25UajNIZEhNVzcrRFczV3Q4NCt5WGVmV3Q3N0cxdlJWY2c5REUxb1NROEZremljYXBKbFMvMzJkamMydDQ2SVJ6UkFHenFEZWphdjlMQzZxOXh6V2JUVzhUQ0ZieTVVOTNiQmxHQUxZaGs0NWx0VDhReHpGWkx5T3Rwa3dmbUthejBjSG5jR0RwQUk5LzdBd25YempLa1E4ZlpPSklIZWNpS0lhTWNPbjdWM24vbGV2Y2UyZU5ySjJUdTZ3OFluMWlZbUxJQ05VcTljbEovc1l6ei9CWERpOVJqU0xXc294L2RPVWF0MXF0TXNsVEZBVVRFeFBNemMweE5UVkZyOWRqZVhtWnV6c1JRN3ZkSHRyZXlMRTR2OFNuWHZ3OFQ1eCtobnExU1o1bm5MOXlqcSs5OGllOGQvWGRrUU8yUXc2YWpwYTBPcGVvUk15UkRjdWRjMlI1UWFjM29KNFUrR3pBN2RVVzRLa2tvMHU5OXJQdVI4YTBtMXJkeE1TRWwyMUora1k3Z2RCS2wyVUd6U3doSjFCckNtMnZvaWdtTHdvbW1nMW1KaWJvOURPbTVxWjU2dU9QY3ZUWkpSYWVuR0x5U0JNWFJaQjdOcGEzdUg5aG5jMkxIVmJmM1dEMTdqbzVHZE96MHh3K2RKaG1zOG5rMUJSejA5TjhJWUtqTytPZGJYWDR5c1lHYTV1YmREc2RzaXhqY1hHUnVibTVNdjVmWGw1bWVYbDVKenpyTXhoa0hEOTBpcDk4L3FjNWVlUU1hVktoMit0dzd2SnJmT2UxcjNOeitkcHdYcmc5ekc2bFh5UmUvNjQxUXFmVDJTT0F2VUhHNG5TZHYvN0owNXhlbWdCZmNQM2VGdi9pRysveTNYTzNxRmZqb1QrdHZIK2JNOUI5MnVJYjEydzJ2YzNYMjdCT000SGxVRTFZbmRVU2JhRUIwQ0ZZV1pLMDgvMHZ2ZnhSSGoxK25EUVpPbkxuTGwvampTczNPSGJ5R0VjZVA4akNvelBNZjJpS3ljTk53T0c4WTdDUjA3N1JvL04rUnU5R3hvRzVneHcvZFh6WGZ1WTU4NjB0UHJiZG91SUwrc0FmOUFkY2FiWEx0M0pNVGs2V05yUGRick8ydHNiYTJscHBiMDhzbmVIWk14L2g0UHhoSExEZDN1VGMrei9rL0xVMzJXcHQ0QXZLc0UzOEh0RWVFdUtKbzJjZFB2MjVLSVludFEreWpEejNETEtNVHJmUC9HU0YzLzdsRC9IWFB2NFFsVVk2OUpiemduL3o2aFgrM2ovOUxtZmZ1VVdhN2kxbUNkRlJtd1Jod0QybmhGbkhRdHNrN1gzcWp1MmYvVTA3TjhJY2tnV0xvNGhmL3ZUTGZPN0ZEek0zTlVWZUZEZ0hEeDFhZ3NqeG84dlhJUE93bFpEZGNmUWU5a3cvVmllZWM4U1RqcW5INjB5ZGNMQWVjNGdUSEttY0lQS09kcTlEdTkxaXhSZGNiM2M0bFJkVWdJK21NYmZUaEdxdFJxTmVMOS9CSS92emhxYWtpZmR3YVBvVXh3ODh6RVI5YXVnZmROYTVjT04xbGpldlVXL1dxTllxWmU1QWpvR1JIYmlTME5GbVU1dmFQQy9vWnpuZVE1WVg1SVhIRXpIUmFMQTBYV1Z4dXNMQnlaUVBuWmptbHo1Mmtrb1N3eUFYbGN4UHZYQ0tzKzh1OHhmdjNoN3hGeXpOdEZDSDFnWVMvWUNXZGgzNmpBc0w3ZjIyajVBVzBjeVZKQW1MOC9OOC9pTS93VVM5eGtCNXJVY09MUERKRHozRnF4Y3VjZmYrWFpKS1NrcktwSjhtYTFYZ2tDYzY0ZkdOQVZFOXd0VUw3dWZYNldhYkhCd2NZY3JONFhOUHU5dmx3c1FFaHpZMmFPQTU3aHlQMU92Y2lJZDUvM3E5WHRyRE5FMXBOQnVRTHpCZlBjcFViWjRrcnBBWE9adWRGUzR0djgxSzZ3N1Y2akJIME9sMFJsWUN0WXFYeElzSEJubEJmNURUNncvbzl2cmtlY0ZVTGVMRWZJM0RjM1VPejlVNU1qdjhQemRScFZtSmFWWmptcldFeVZveWxQQkNtd1pQRXNVY25aOWdmcnJPeW1hSE9CNHR4QW5SVFdkV3BTV2FlTmFXVzQ3UzNLVHRuUjFvM0xOYUs4UnhUTDFlNS9TeEk5UjJpamRHZ0hXTytabHBIanY5RUhmWE54Z00rcVRWbExucGVSWnFDelR5QnNsNlJIdXd3V3BqbVY3U0k0OWE5TklPVy9FYWsra3NrL2s4elg2ZFpIS0dqY1o5YW5lV2lZcUNsNUtZcjA1T2tkVHJKUUhGMlV0OGxhbG9pVnJjSkhJUmVaRnhiK3NHTjFiZlk3TzFQcXc2amlMeWZLZ3hLcFVLZ3l3YkptMEtUMTU0dHRvOXV2MkNMUE5NMWlLT0hHeXcwSXc0T0pGd2FLYkM0ZGthTTgwS2pXcE12UkxUcUNZMEtqR1ZTZ3l4SzVmR2NReVRaUVBqbDNrZ2poamtCWjErWHA2aEdOTENXdURzNlNkUkZJMitNMGhMcS9VSk5ERkQ5UUtXQWZRZ3VyODRIcjcrYkdwcWlxTkhqL0xVaDU0bGpnSWF4bnNxMVNxSGpoMG5iYXp3eUNPUDhNZ2pqN0M0dUxqenNxUTZhWnhRNUlzYzdoNW5KYjNEN2VRcS9haExOeXJvUnowMlpsZHBOQ1paNkJ6aFpueUFtZFZWNnIwdU03N2cwVHpuU3BMZzJKR015RkZsa2liekpLNUtoQ1BMKzl4WXY4U2Q5V3NNaXFHMzN1bDBoK1VMVVV5V2UzbzU5RE9vcFRIek5jOUMwekgvMERTTGt6RkwweW1UdFlScTRxZ2tqbG9TVWF0RVE0bU8yTW1HK2lHaFpaOWpMK2ZXNmpZM1Y3dGNYK2t5eU9HelQ4MHpQMVhkelp3NngvcDZpN2V1M0dlcjNhZGVIYWFsUTZZZzFIVHk3TWQ2WDREK2J3a2RXam5UNGFHc3JrVlJ4T1RrSkFzTEN6ejExRk44OWdzL0R4ZmVJTS9NdVQ4dW9qSTV5Y0xpSXZWR2d5ZWVlSUlUSjA1UXI5ZExXd3ZEaEZBY1R6UGo1emlVSFdNNXVzR3QrQXA5MThVbkJWdnhnSFoxazN2WkRKWE5CazlkN3hQNWdrZmJMZTVOVDlOTlV3YTlIaE1zVUhWVFJBeVpvcHQzdUxaMmdaV3RPd3lLZ3NMSDlITklJODk4cldCcEd1YnFqdmxxd2t4dGdtYkZrVVNlTkJvU3U1STRrbVJIbWwySk1NZ3pLUHI0UEdXTFNWclJETmZ1YnZPTmIzK2JtNnQ5MXJvRi9heWduM202ZzV6K0lPZjFxNnY4MXM4OXpJSFpPaFN3M2VuemovN29SL3lMYjU2bm1pWllPb2VJcnpPSW10WWZlRGxZcTVOUXhVd29MYWsvNjFXMFdxM0d5Wk1uK2ZTblA4MnBnM05jZW1jbk83YWpYZ0hTK1FVcUUzUE1yN2VabTVsaGNYR1JxYWtwNmp0cVd5WWtublhzRWlhWm9aNDNXY3lPc0J4ZjUxWnlsWUViVU1RRldYeWY3NTlKV0Z5dnNyZ0pGVC9neUswN3ZFL0s1UHdacXVrVWpoaVBvNVZ0czdKOW5rcCttMGVuZXN4VlBUUFZqT2xrUUNXT1NKd2pqUjFKQkltc0lUZ1lybXo1bmY4RkZKNWVOK1AyWnM3dGpZeGJteG1USno5Q3V2UWtnMlNXd3NVVUpHd2ZhTE41ZUlLemYvRi9FcVdWNGJ4MkZvSjhVZkQxTjN1OGZXT0xJL01ONXFNVzcxMjd6VGZPcjdIZXpxbkV1eHA3bk8zZno3UW40OWFmYmJPeCt6aGJZeGxBbmhFdFVLdlZhRGFiUFAzMDB6ejM3TFBjT3Z1dEVwalowNDlRWHpoSTVpS2lhcDFzWllWbXMwbXRWbU4rZnA2SmlZbHk3VjZTS09KUGlQT1Z1SlFKWmppWk5WZ3NqbkVydXNweWZKVWl6dWxYQ3M0K2x2TXozNi96WnZRMDJmUUVUZWVJa3lyRE5ZbUM2ZWdhVDlkZUpXNzJjQlRFemhNN2lKMGZTcG9ERUlMdnpyZGZwR3d5eGFhYnBoWFAwNG9YYUNVTGRDZnFaTE9RRlo2czhHeWtkVnhTeFJPVlQwZVRzeno4NGMveVovL21EMmh2YlpiaDRaRFJZN2I2Y0t5N3l0K1l2Y2l4ZW9mdWZNNjlSejEvL3l4ODhieWptamhnYjRRV01zM1N4RlRzV1EwVVl1azk3dnBoa1RwOVhiU0JYdlN3RERQTW8xZkxsTzJCQXdmbzNMeEdlMzExQ0VpanljR25ubUdRKzUwa1RNYms1Q1FuVHB3WVNka21TVUszMjZYVDZRVDNNWGlmRXpsSExhbFFMUklXa2cveEVHYzQzN3ZBZXZVNnl3c1paeXRQRUUzTUU2VXhPMjRSUmVHSnVoczhmdkRiUkQ1SFVYdm5jd1E0aXF4UDBXdVRkOXY0ZnB1ODJ5WHJkOGdLRDhRMFhVcmRKY3hHQ1FVSmhVdHdMc2E3Q0Z5RXgrSGR6cWd1eGp1SEoyYlE2OUY0NUM2Ym14c1F1ZUY5M3BHNW1Pa2s0K1dEMnh4cjlJbUhZUERRak9PL2ZnbjZPZnpyOTZBV1UrSmluTzNYNndDbENaQWZKWkZoanlyYlJleW9DYkFwUnV0RTZ0U3dNSU13d2R6Y0hNMXFoWHZueiswOEczSDQ2ZWNnVGlIdmwzNUVvOUZnY1hFUjUxeXBDZUo0K0hLa1NwcFN4QkdGSkZOaXgxYTM0TVphbjZ1clBXNXM5cm01bFhGcksrZjJWa1kzbTZJK084ZXZIcjhPVXpQRWNZUmVqNDZpQ0o5V3VYWWZUaDZJb2QrRnpqcDAxcUM5dHZOL25hamZJWEtlMkd0MVA2eG9lTUFhNmc2cjJjdFNKZVY1NUZDQlgxTE1ySjVNSS9Ya3pzY25EenMrZXJqZ0s1YzlxRWhPUjF1YWZwYjQzdnZkZHdicEVFRXZZMnBiYXhsQkozcENaa0RmWDYvWE9YYnNHTWVPSGVQb3NXTXNSVG5GWUpnc2FTNHNNSDM4VkxuNElndEd6amxxMWVxd1lNUjdza0dmUEhPc3QzcGNXTjdreW1xWGErczlycTMxdUxyV1phV2RrUmVld3JQN1Z6aGNaWm5LL0xkcFRmK0l5dTJmaFVWZ3o4a3huangzM0wrUmMvTDlmd3lEUHZpaGFrVVRlNFNjdTUvMkovNXVLOW5BMjR1TzNiV2ZVRlFVNkN1SCtUck0xV0cxNDNjaXlQRWJjVUs1bnBGM0JrbEdESFpmcEJoYTJOQ2ZyVDlnNzNWdXVPVGFiRFk1ZmZvMHp6MzNBck94ZzYzTjRUMVJ4T0tIbnQ5VFVwWVhucnZiQTk1ZjdYQjFwY2R5YTVVYld4bFgxN3FzdFROZ1NHaS9VMUhrL2FqRTRCMXgvVHIxdVQ4bm1Ud1BVWStjZ2pmamQza215dGtOc2hYU1k3aGVuK0hxM0g5RnY5dWkyMjRSQVpVMG9jZ3pldDBPM1hhTGZxOUQ3QnlPZ216UXA5L3IwdTkzeVFkOW5COHlqSE9lQ0Uvc2hrREdFYmlob1BMWU15K3pjT2dZRkJseDVGbTVmWldMcjM4TG53MXdlSnpQS2JJTVgrVGdDeDZlN1BKekoxbzdES2xhQWhzOVdPK0EyOUZCSVRyczV3dVVHa0N2VmN0RDRvell1bnpkaWJVNW9haGl1RFpkOE96Y05BOFBOb2lLM1RXRitxRmozUFlUWEhwM2hVdjN0N2w4dDhXVnRTNDNOL3EwQmdWT0NzWVVnVVhkaWgvbWRzWk5ZMWhzeE16TVhXT3o5alhXM0hrS0JrUEU0RWlJeVk1TzByK3pSVHBYTFV2UUFZb3NvN2Zlb1QxekZGOUEzMC9RenR0bGhwQVVXbm1MZGI5T256NXBraEpGRVoyOHcxYTJSYXZUb3R2dERwZWFKUWZpUnM4SUZQWDg3Vzllb05hNFRYTjZqbzJWZTJ4dnJ0THZUUVBEaloreTlwOWxHZTEreG1OVG5sTVRYUjZiSzBaMHcvdjNQSzh1T3pxWnB4WVBYNjRodFFSNnlYNC94ekRSTndremlGMlhXRnV2WG1uSExoUmUyQmJITWYwczR6LzQyWi9pNGNNSGlaUFJQTUg1TjgveDI5OVF0a285cThObkY3bVM2STAwNHVoTWhSTXpOWTdQVmpnNmszSmtLdUZtL3cyK2RQc1BlWGZyUExuUGgwa2VZbUlYODdHRmovRkxSMzZKNDVNUHNmM0gvd05iei80S3llSUJ2SGZnSXRidjlMaDdkNW1wWjZya2c3dzBpOTd2MWoxYVpwZklScGVTRlRzK2lzeTlOS2ZDQkVWQmtlZHNiYXl5dm5xdkxCQ1ZncG5CWUZDdUxlUjVqczl5M2w1TCtIcy9tT0YzWHRqaXhNU0F3c085dHVlLys2N25EODhYMUpOUjZiZEp2RkI0V0lhQlFzaFFtWkY5MEVxMzJPdFFaWTdjNy9FY1hqekNzUU96UTFWcXRNalNWSjNESzV2Y2R0UEVEaUkzVEFOSERxWnFNVWVuRWc0M0kwN00xM25rMERTbjVodE1WeHpPNzd4VkpPL3kvWlVmOEEvZS8zM2UyM29QNzRaTHM3R0xxYmthSDV2L0dMOTQ1QmM1TVhHQ3ZNanA5ZnJVcmx5aDhlZi9DZjBqajNEOXMzK1pHM2RQa1hjOHJqSk5iMjJOcUxscittenRnMlpzbmRhVzZpY3BOTEhGSFZwSWltSjRhb3E4MGthSUw0eW1YeVNkcGtNaC9PRkt6Ri85eWl3SDRoWlp0OFhGbFlMV0FKSm82RVNQSTd4Tnc5czI4dlp3TGVIQytlTWVEa1VLSWpXYVVmSzhZT25BQWVJbzNxTitZSmo4K2ZCVWo4SFJCWTdOVkRreW1YQjBLdVhRUk1SazZ1anRsR2hWZC9JSGFhVkNiOUJqcGJQRzJmdG4rYU9iZjhUbDdjdkViamh1NmxJbTQwbGVYbmlaTHh6NkFrdTFKUWI1Z0szdExUemdOemVwcmR3SDUwaFdydUdmbktPYURXamZTdkI1Uk90eWsrcWpkK2wydTJVWnVTU3d0SE1zV3RDcVdydlJRNFNyMysrUFNIdTczUjRwRDVlbUN6YTAwTVZBdTkzanJhMHV2VjVHRkxsaFNNZ3Vyc2ZsWWVUL1dDZFE1L2QxS3RmV2p3a0I1ZDZSQXgyajBmUHpTd2tCM3I5eG5mNllWOUxIa2VPdlBsTG54Yzg5Tmx3dDYzYko4cHk4R0s2SjV4NEs3OGh6VDJmUTVmNWdoVy9kK1JaZnZQcEZycmV2azBRSmFaU1N1cFQ1Nmp3dno3L001eFkveDN4bG50Nmd4L3JtZWttc3pIdUt0ODlSTFlhMnRIdjBLQzZPbVhzc28zMDNodHlSYjFUbzNhK1ExVGIzRkcySVE2dkwwTFRXMUZVL1FGbnFQUmdNMk5yYUtvVkthZ0ExVHZkcnNyemM3WFlwaWh6bjlrcDRLQ20zM3hpbDQ2OVZrdzBKSDdRY3JGVy81VUJkRVhQdi9oM09YYjNCekVTVGVyVlNYdS8zKzZ6ZXVjM1ZiM3lOV3IzS3lROS9sR3duZkl1aWlNaEZKSEZDei9lNHZYMmI3OS8rUGwrOSsxVnVkVzlSaVNwVTR5cTFxTVppYlpGUExIeUN6eDc0TERPVkdRWitRT1l6OG1MM1ZTMkR3WUNCOTFRdlhZYWRZMlk3UjQ3UUh3end5WURHRVUvN2FoMmZSK1MzWm9oUHIrUFZnV1k2c2FXZExGMndLYXBiaUN5L2lhUUxYclNxRnEwQnU5S3YzOHRRRkFYZGJwZDJ1MTBXbHdoUmJmclhTcmxkaU5OdFpDM0FPamJqdU1vK2JDZGd1YTZNNVNzVmZ2ZExYeVp5RVUrZVBFcXRXcVU1MGFUZjZYSHR3bm1LUE9mYi8rVC9vTE8xeGVtUGY0SW9Tb2FPMG1DTDI1M2JmTzNPMS9qbXZXK3ltcTJTUkFuMXVFNDlybk9zZG94UEgvZzBMODI5UkROcTBpLzZiSFkyaVZ4VUVpZlA4N0pvSTNPT3hjdnY0M1lRc2pZL3g5YlcxcEJBMHg2ZkhzTmxGWHluUXJZOFNYLzZOa1cyNnptTDZwWkRId2VEQWExV2k2MnRyWExibWZlK1pBaTlYVnZqVHZJY2xrajZrRW5SRnAxT2g2MnRyWks1aEY3NmNBdHI1eldEaGh4Mi9YbmtyV0hTc1YwMzFxR2lsbmc5QVptRWRYWktSaWt5L3BjLy9oSVBuWHlZejN6eVU3ejArSE1jUFRqUDhwMWJyRnk2U0pGbHZQb0gvNUpldTgzaGozK0VhNzJiZlAzR1YvbjYyamZaeXJhb3VJUjZVcWZwbWh5dkhlZFRjNS9pSjJaK2dtYmFwSmYxMkNxMlNoaHo4dEtqN3ZmN2REb2RXcTBXdlN6anlJMGJ3emVST0xoYXFkQmZXYUZXcTVIbkJZT1ptMVR2bllRaUlyODd5ZkxHbXd4OEIrOHB0WWd3bFRDNE9ITlN6NmZ0dmthMHpwamFmUUJ5ZXFyR3RURFg5dloyV1ZGdEhVcXRPWFFMbGZlRmhObDdUNkxqMDFCc3I5V0tKYjYrMXo0dnpERVNNYmlFMVpXN0xOKy96Y1VMNy9MR0cxMU9QUHRSbW8xcGx0OStuVjZ2eHh0Zi9pUE8zdmcyMzZ0ZXdIWDd6RTlFMUthbWNiVXFCL01EZkdMbUV6dy8vVHkxcEVhMzNXVTczemFMSjI1RVNnU21RWjdEOGpKSmQzaW1VSzlSNTM1UkVHMXZsK25sVG1VTGw4eFJ6V2RJZllObzlRQVhWNzhHeGU3Yk52VDg5VFdadC9ZYk5FSDBOaSs5YzByblcrUTUwU0RkYnJlc050YWwzOUtITGd2WHp1ZzQ0cGZDcU9pVnlONTIzZlRKRjZIa2o3MHV2Mms3cEgvWFRsU3IxZUxWSDd6S3plczM4WVhuSno3NklpOTkvaVV1REM0UnZkc2h6U09hcjYvdzArNEFSZVR4ZU5aTzFLZys5Z1R6N2NOTU04V2FYOE5GcnR3Y29uZmI2dTFjY3IzZGJ0UHBkcG02ZmgzeVlYNWdmZUVBdU9HSzRzcktDcFZLQlJjN05xcnZzZEI2amppcXNGQTVUVEk0eTkzTnErUVp3RjUvUnpTTlRwc0h3MkVsQ0hKTjFsNkVDY1JVaVphUit5UkUxTDZCeFhPSXlQSmZhMlo5MzA1MGs0d1FTS3NxelNsYXVxMFRZN25LMmh2dHJPUlp6dHE5TmZxRFBwV2xDajhhdk1acmwzL0VwUk1YZVhGN21pZXVUT09UNFFzandCSGhXTG9WRVJYYkxFL2NaV1h0UGlkT25DaGg2bmE3M0x0M2oyNjN5OFRFQkZOVFV6U2JUZXIxT3M0NSt2MCtXMXRiYkxUYkxGeS9RU1RiMCtibTZQWjZ0SFppOGZuNWVhTElzVldzay9qcnpQdUhhS2JUUEhIZ1pkWTd5eFJ4UVZIczNjSXROdDF1bnRINDBtR2t2SGhLK2hGVkw4eXFWMkcxeHJDbmYxZ1RveGQ2TlBPSXFaQjdKVXdWM3lEUjlrTThVTG5aZW84aERyZWhvODByZU85M3NuZ09NcUFKNlltVTRtUkI1N0VPN3h4K0I5L3h4SEhDMVpOOW5yeGFKbitIL1FIOVFZZnUzVnUwQzVpWW1tRmpZNE5XcTBXcjFXSjFkWldyVjYreXRiVkZyVlpqZG5hV3BhVWxscGFXaU9PNDNKWFV5bk9lWFY0bThoNEgzR28wMldxMVdGbFpJVWtTcXRVcXRWcVZ3bVhjSHJ6SlpIcUlTbHpuWVAwaERrOCt3dnVycitOOFVoS2szT0VVY0xRMEhzUVpsU2hBaDRaeXJkZnJsYmtGcTFsMXBaWDFIVFJkckQrZ2FXQkw5RFhNaWFpdmtmMWl4cGFMU2RBY1o4Tkg1OXlRV240bjh5NEk4UkJsRWNsVVFub2tKVDRWa3p5YjRBOE5mMHQ4UXBxbE5OWWFuTjQ0Z2t1Nnd6ZUZtZ2s2QitrTzB0OS8vMzIydHJhNGYvOCtHeHNidE52dFVoTmN1WEtGZXIzTzdPd3N6V1p6eU8xeFRLMWFZMkpqQStjOWhYUGNTQ0pXVmxaWVdWa0JoaDcrd1lNSHFkVnJ0UDBhVjdaZTQ5R1psNmdua3h5dVBjVnI5NzlOVHI2eit1dXAxV3A3RnN1MDh5dmFSOVMzZm5tMGpwREVWR21tMFUxTHRLYUovaHh5TnFYcERUMTZWNUtNbGVqTm5Ib1N3blgyQWUwSGpEZ2NPK0ZTM0lpaGdLSlRFTHVZZENHbGVySks1VXlGOU1tVTZHQlVNa2E4SFJQZGpVaXVKMVJ1VjlpZ1Q2K2FrVVp1ZFBYVGU5YmJIUzVlZnA5aUp6VGEzdDVtYzNOeldCdFFxWlR4Y3JaVG9idXhzVkdlVEo0RForSmtwNlFEMWhzTk9uSE02dG9hTjIvZUpNOXpWbGRYYWJmYkhEOStuQ1IxM041NG00T3RoNW1iWE9USXpNT2NYdmd3Mzd2MHB5U2tGRVhCOXZiMkhyeU1hRDIzNnpoS2FHY3pxOXFKMHdKb0N6djFXY2FTcDlIK2czWWdyWWJXL1dwR0VLWktMUEd0QTZPdmE1czBZdnN6VDdxVVVuMjBTandYUXc3NS9aeVltTnJwR3VsVEtXNW10NDlrSXlHL250Ty8yQ2Uva0pPdjVkek9iM085WGlGYm5PZlp4VGttYWhXS25WcjRtMXR0Zm5CbmxSdGJiWnlTSUVGb3U5MHVFU0Flc2FSZm5YUDRKT0Z3bEpGVWh1WG5keWFud0RtNk80eWsxWGRSRkN3dUxwSTBQSmUzdnM5TTQrZVlxTTN3NU9HUGMrN2E5OWpxcmc5UE5GR3Exa1pDMW5HMm9adG9CeG5QU3I1MUlFVVFkWkpPdm9lMm8ybDYybVNSM3JJSHFpaDBITWZKLzFBY0NWQU1DdEpES1pPZm42VHhmQU9YRE5kbmZYZEhMZFYyYlhxOEVqTzROS0IvcFUvL1FwLzIvVGJkckVzVUQ0RWE1QVBPOXZwc2Qzc2NuS2dUUjQ1V1ArUHEramJYTjdkSmxCblNTTk5WVEZvRlNrNWpNQmh3dWxZblphZ0JidFhyYkd4dXNyNitYaUlzeXpMVzE5ZnA5WHBFVWNUaTBpSSszbVMxZDVPRituR096SjNtaFljK3k5Zk8vZDhrVVdXUCtnMkZZTnJXd3U1Uk5FVlJsQ2VFNkRlSjZIUzg5djR0b3dsTmRLU21IVDlMVHkwWTFuOUw3QmwzNHVCb0x0VUE2ampYZXc4NU5KNXZVSCt1UGlSOHRzTWd5UTYyQzRqdVJnd3VEc2d1WlhUT2Q4amFHWm5QaU9LSU9CbGRQT2tQQnZ6ZzVoMnFjVXdsaVdrUGhsNXhHdGpBS2dqUUNSVE5vR1U0NkQxbm9valVPWnozWEsxVnViZXlRcXZWMnFOTjhqem4vdjM3VEV4T01EVVJzK1l2TVowdjBhaE84Y1RSajNMKzlnKzR0WGFaSks0Q282ZCtXT2ZaYWszcFg3NXJJbXZjVjZ0VnZQZkI5TEh0VDlxNDFWeHJhalNqZUs5S3d2VE5nOEZnSk5GZ1ZVanB6T1NlZUNJbVdVaUkwbWlYK0ZBdTdQZmY3TlA5WHBmZXhSNzlkaDhmRGFNQzc0Y3hmaWgzRUx2aGx1aXNHRmJYUkFwR0hWWUs4ZlpUbjRYM0xDUUppMUZFRFBTaWlPVTRZbVYxdFl5NWJTaDcvLzU5b2lqaTZORWpOQTVNc3BuZFpLNDR4ZEwwQ1Y1NDZMTjg1YTEvaG1NVXBwRHpKdkJaTGFCL3Q2dUpVamNweDhOb3gxRVRQdVI3MlBIdEM3cjBid0pQRXVKYThWaTE5Nmx0aHg3UTc4VEdvVEkybHpwYVAyalJlcU0xTkFQUjNseTBqR2tCa3hJZ3E3SnN1bGxQTHBURElJNDVVNmtNM3pUcVBmZWJEVGE3WFZvN2UvKzExaEJUSUdxNVdxMVNyVlp4dFF0TXVpVXFjWjFIRDcvQTljMTNlZWZHV1lwczl4bWRRcGZ4clo5Z3BkUkt0WXpwdlI4eERkYTNDREdjWlFMUjRxRnNvZTV6cEI1QUQ2aUJ0azVpYVdjajhDMVBkamVqNkJaRCt5OHdPTWpYY3ZwMyswTkpqL2J1SXhnWDBsaWkyM3VrYWVuUnorblkyVHZIdzNITThEUWl1RHM5dzNhN1RYZW5yTndpUmZyZDN0N20xcTFiZ01jdlJjeE1YV2JKUDhsTWZZbm5UMzZLdGQ1Tmx1L2NvdGNiUFgzVUl0Z0tqTldxMm96SkFkZFM5cTducVQ5YjlXODFnWjJQUkEzbFN5S1VkaDg1TEZxYUpuakk2ZEQzUjNGRTYyd0xOK09ZZkdtU0tJMGdobXcxWS9OZmI5Sy9zK3RIV050a3Iydm0wbW96cE41Qy96VnM0akc3T09aTW5GQWQvc0NOYXBYMWUzZkwweitzRnk5ejdmVjZyS3lzREplUnN3SHBvUW1tWmc5VGoyWTRPdk00ejV4OG1VNy9UN2wvZDIxUFNHeWJIY01LbkZRVU5ScU5jbUZKOGdSVzFXc2FXWTJubXpDZXppTHErY25ua2RWQWpjeFFUdHR5TDRDUFBQMzdmVGIrZElQZU96MHFpeFdLWGtGdnVjZmd5Z0FHbERaL1AzdGxXNGpUN2U4V1BrR01UQnlHS3ZVa2tIcFA1RDBYZk1IYTVtWjVIcUNHd2NKV0ZNTXpnd2FEUHR1YmJaS1RNN3g0OU9lcE1zSHBBODl6cC9VKzdkYVBhTGM2ZXdwcXJTUmFiYVh6K3JJTVhLMVcyZHJhQ3BiZ3k3UGpjS0x4cTRWSS9CQmRxU1dMWDJCMkJ0bVlWRHRISWVJUFJ3YVhPUEsxblBaNm0zNjlUNUVWRklPQ0tJNzIrQWJqbktXUVZ0RHFNMlNpckhyVmVmZ29pa2dxRlk1Vktrem5PYTd3YkZlclhObmNMUE1Hb2RoZHd5R2ZXNjAyN2U1VktzVzNPVHp4Q0VlbXp6Q1hIdVhNd2VlNXMzcUQ1ZjZkRVhPNUoxSXljN2RaVlRsTXExNnZCd21yOFI2eS9Sb25jazJQSVdwZjQxVmFKSFpRMjBQTHZaWkFGbG5PT2VJMEprb2lpbjR4RFAyU1hlS1BzL2wyY3VQdTBVa09PMmxydy9VeExGbFJjRFF2cU96NHFEY3JLYmZ1M1J0SnFJU1FiY2R3enVGenVITG5YVjY3OGcwS2NtSmY0Y2prWTV3KytpVE55VVo1WnJER2xRNVJyV2J4M284czlZcnpKMHhrMWJiRm8vMDhqbTd5WjVldFN3WUlJZEVDR2tLOG5xQUFIRVhEZmZaUnZPc3JXRS9YQW1vUkh2S1FoYWg3bkZEVG40NnB2ZmYwODV6aldVYVZZYVh4MjcwZXJVNjNySzZ4NmxRenRPNWI3czJ5QWVkdnZjcUY1UjhTeHltVExIRnE5bWtXRmhhb1ZOSWdFMWttMEg2VU1JM3NtVnhkWFIwNU0xRHVIeWNnbGhuR1hkdVB4cEVscW8zNXJYZHBPVnl2aEZsVmJmdTJTQTdaZm4yUG5venRWOE5tNFplK00rODVDZFFZYnUxOHE5T2xNK2hUcUlVWXV3SVhraVFRcHlyaTdzWjFmblRsbTdUN0cwUXVZYW4rQ0tjT1BrR2pXUTh1cUlXY1ExMVZMT2NHZHpvZE5uYk9NcmI3TS9kek1FTU9ZT2llY1MyeXRsMHZTNFljSTJsYUxZOVRVeG9BKzEwVDBTSThsUFd5enFobHlKRko3V2lrV2hSeEJFaThCK2Q0cDl1aHU2TjI5YmlhSUphcGJmUGVjK0hXRHpsMzR5eHBuRkpubmxQenozRGswSEdhRTQzZGd5c1VnOXF5T1NGdXM5bGthbW9LNzMxSi9KQ0dzNzZFeHFIY281bi9RUXd4Z2l0TmVCaDlvN1ZNUkh1c0Zoa0NqTlVnY3QyV2FXbTFhb0VmcHhGQ0U3ZkxudFpVWlVYQnlUUmxJaHErWnU0Mm5tM25SaElrMW9uVS9ZVDhucUlvaUZ6TVptZVZ0Mis4d3IydEcwVE9zVmc1dy9HNXgyazA2enVuaU85V0tlaytoU25TTkdWaVlvTEZ4VVdxMVdxNUtiWWtpbG1aRFJGMVJJMHJCaHVIdzNIWG81QUVoUjYycGtHSEZSWUlQV2t0WGJxZi9WUnZ5SXpJNXhEbmErUkt2eGx3T2ttcEQwdFJ1SkJuNUdQZ3RPTmJNMkMxVHh4RlhMajFHdWR1bkNXS0lpcCtnak1IbjJOcC9qZ3VHbFhidW1oRTNrZ3lQVDA5UEIraDArSG16WnUwV3EwUExBQVdIZzI3YlhZdUlUcEhjcU05Uzk1eWZxamprTXJSQkpaajE2dlY2by9seklTMGdvUlgrMVhoU012em5BSTRGVVhVM1ZBRFhCams5SXJkbzFmczJDRVZhcldWUmxzM2EvUDJ6ZTl4Yy9VOVhCd3hHNTNpeVBURFRNOU9qVGpGb2xrbHptODBHdFJxTmU3Y3VjUHk4akxkYnJlRVJ4ZHM3TmRDNWtCSE5lTjhoeEN1ZG5la0sra0pJWFkvMjJMdjFTdGZJU1lKQVdJSllMbGFjdlRDQU5xOFNKOWE2OFNWQ2llQitzNjlGd2FEY21YeFFaSW1STmZSaDRVemlWTGV1L01HNTI2Y0pTK0dZZUhwaGVkWmFCNGlUWGZMNnNUVGw0TFZQTTlaWGw0ZXFVT1FKZXNQMHNiUkllU0hXYnlHV2hUcVZNSWVhN04xeDJKRGJZeHVseTdsNkhXNzZCSUNkcHg2ZnRDMVBScklPYVlpeDZJYlpyb3k0UEtnejhEdlhkM1V6VHEybXJrc25weHorS0xncmV2ZjRlcjl0NGdpeDJMMURDY1duaHhXR0x2ZGhTSjV3NGhVS2ttZXZ5aDIzeHNrZnBiNEo2RUtMWUVsRktHRXpGWElqRmxHaWJ6ZlBjSGExcDZGdU1lV2tPMUhESTFVSGRib2ZpeVRXUlVzLzhmRnNiby9lYTV3anVNdUt1My9sYUtnN1JsNTFvNWhWYTkyZkczOXY5eWZ4Q2szVmk3eXpvMi9vRHRvNFhBOGR2Q2pIRHZ3TUxWNnJkUlNVdENwQzBIMXZrcGRvcVZoRTc5Qktvckh4dklQY0FMM2paaXM2cmZPbmdaS08zSTJkQW8xYmF0MUcvZmRxdjc5YkpnTlFmVnZ1ZmVjZEJFTklNSnhNYy9vK2NBNmhocEhpS0RMc2tPbTBHcURKSzd3K3JYdmNPbnVtempuT0ZBN3ljTkx6OUdvVDQ3Z1N2YjloK1psY2F6bktNeG5ROE9RNlJ0bkJpeWU5ZmNSSDZCY1FWT0FDQWVISENUZGFlaDdhS0lQWW9aeHpZNHZqR2ZWZnh6SDVONXozTUdFRzFZVFg4eHllc1d3SE56bUdHeDBJczBpTkRUKzhMbUkxZFp0emwzL0h1dnQrM2dLbmpqNEVyUDFwYklVVGdocEl3T3QyYXl3Nk90MjFlK0RSQXdQd211cFpaeHpJeWR2Q3FEV3JsdlZieVhQRXQ1NjZhWEU3THl2NTBHNWVQMU02TGZRdmVXWVVjU0pVZ1BBeFVHZlFRUStrTGlTRmxvQ3Q4aXk0OHRmRWxWNDQrcTN1SHozTFR5ZTZlcEJQblRzWlNacVU4VHhybURKbkVNaHRFUmlWZ1BhUHczVGZpWXgxRUo5UkhJeGxQZVh6L0k2VlUzOEVGQWFvQkJYaDV3dk81NVZaOXAyV1liUVJKYzVaRVhCQWVlWWo0Wm45R3g3ejQwc0cyNDdEeVIrTkRMczlpNzlXMmlPNVhVUG5mNDJyMS85SnZlM2JwSDduQThkK1FTSDV4NGlpcEt5cHFCa0dIV0NpSFg0WkU3N0ZYMThFT0tHZmd2UkxJbWlxSHg1ZzU2MFB1bGlwQTd3QTlnV1N4eTVKbHl1Kzl0UG5Xa21zdmVHQ2thaUtLSmZGSnhJVXlaY2hQTnd5WHY2YnVpeDYzNDFZa0syVXdnajMrM3VKOXVTT09YdG0yZDU3UEFMekRVUFVra2FmT3pNenpNM3NjVHl5aldXMTYrejFWNGRlVDdQOHpJMGxJakJDa3dJTnF0Wng4RmtmOWQ3SnFXUFJMWTRpNTBSb3BkTHFqczMyMDBJZGswNzFMU25Md1BLU3B6MS9LVnBpYkRFdHhNS2VlYTlMT040cmM2RWMwUjRyZ0J0aWVYZGJ0WlFPMVVpaVNHR3NIWmZ0MUdrTzdKQnh0bjN2c0t4K1VjNFBIdWFNd2VmNTlUQ2gwampDcmZYM3VkZnZmSVB1TDV5b1N6UUNEbkpVYlMzY25mY21GWTcybnRsbmxacjZtY2lZT1R3QWZFRk5OSkRsYmNmeE83b2ljZ2J2YXdOMGdEcWJKL05MNFFRb0ZXYUlESUhqc2NSa3p1VHUxVGt0UE44ZUNaQW9GbXRwaGwyUCtteUpncWdrbGE1Y3ZjYzk3ZHVBMURzSEZ1YkZ3TU9UaC9sbHovNnQ1bHN6b0ViM1NKdWNSYXk3WmJRbHZHdGtBaE9MTTUxTFlUMzZzV1IraUdSRHIxQklhUUNMZWRaYjFxa0ZDaTFqTGJEdHVMSFBtL0h0RGJmYm1BWkVpSGxlSkxRWUpnUGVMZlhwMTBVeE43dnZPZ2hEOXBZWFQ1bEY3L0dhVGo3bS9jRkU3Vlpxc25leWg2QXBibUhtRzB1MHVsdmxjOXExUzlhUVp0ZW1YZW9URXpqUmZCaGZhaVFzeWlhQnhoOVpZd1FYS3R1UVk0ZXpBNXNmNVArTkZLRlVQcStrTDNURHBKb0NQMjdsUVF0U1QzdmVTcEpPQnpGZ0tQcllDWnlWSk4wNTNXdm83WHlOczloSFRMTmRBTC9mb3hRZUU4MUdhYWZQRlpyT1BKc1FLTTZVYzViYjlYV1JKV3hyQWJTaDNCSkcxSG55azhUWVpPK1F6NFRCTjRlN3B3ck4xVktSNWJBMHFIdUxPU1FhVFVrdGkzTE10STBMWTk2MTc2SFJ1YURtdlZtYytjNEJQek5XbzJINHBnQkhncjRXNVVxZWRybno3b1ovUjFOWmgwODZVY3poOVl3b1FNamd6QVJzZDYrUjZ1M3VYT1BBMkVFQjFreFlLMTFwK3hUejhVNjRGcHdOSUVGajFxSU5JT0t6eWFDSkRUUnBrRDZ5dk44dHlwWVM1MnNtZXZLV2F2MnJTY2FVdjhDbFBUcHZTK1pTLzdEN2lwWWlKbnNUbGladEI2MzhKNGlpdmpsYXBXUEp5a1JJT3gwTUlyNHpZa0p6dlc2M0RLT2w5WWl1azRnNU54S0hLOHpjMXA3bHFyYTUvem95amVabTF6aStQeWpPL0RHYkhmWCtjSDcvNVpXZngxZEs2bWRVaTNOV3ZQWi9JdGVaUlRZcEErdDFmUVpoSnJoNVhOUkZMdW5oR25uVDJ5UzdraXJRaXVoSWNkRVg3UDE5eHI1c21Uc25CdlpwcVVucjA4UEYzams5eUhTUFpOeHpISG5hRGpINkk1R09CVEhuS3BXdWR2cmtUc0hBYWEyQkxGU0xocEJ4dFJIditsK0tuR1ZjemRlQVFkUEhQa0l6ZG8waGMrNXRYYUo3MS8rTWxuZUx3KzExSXduanZnNEJyUWFWcXQ4WVJadHVyVWZZVFdCcmpkTTVFRnAwcUhzRDdRQWhEaEpFMXdUWGhNZjltN2RrdDJ5Y1J5WGUveERxM0U2YWFJM1RKYS9BMFdTVWhRZTc5eHdDN2tpWGc2a3JoUzdQWDZIU0luc25KRS9VY1dWU3FVa2xod1VxWStCczR5U0psWE9YWCtGZDI2Y1phSTJTM2ZRb3B0MVNLTktPZmVLcTVUemwzT041Q1FSdmVSdEdVRUVWSjlMSk1JaGJ4MlhwZWVpS01wNkF4dTFDTE1rK2tmaERsRnhRbUJST1pwekh1UmxDcEUwOGV6RWhEdjcvWDdRQzViUEFteG8rZG01WVh4L3A5L2o5bUJBdHJPOVNsbGZ0cjNuZXBZeEtJcnlaSEdCVTVoY0RuWFVjeE1rUzZ0V3F5V3hoQkEyZ3lvdFRZWnZFRjl2M2FmSWh3V2xBN2Y3YnVBOHo0ZjdEcDJqVnF1VjBZQ1lHUnZEQ3o2RitIckpYajRYUlZFeXF6Q0hQbHNncE5raTZkaUdHbnFqbzY1MzE1TU5lZlUyeEJJaWpsc0FHUXdHSTh1aytyZ2EzYTllbE5vRGkvZmtXY2FYMmkyKzArc04zOExHc0JwNEcvam4vUjdMQVhXdmwyRGxtdFUrd2dqNlJHL1JCaG9lL2R3SS9ON2gvV2kxanpqRGdoUFpocTlyQWdRZUc0MW9BUkdhV1Z6S3JtZUorYlZnV3FZYU9SOUFENlJEQ3UyazZCUnh5Q0cwenFKK1ZxN0w4em9sYVROKzBwZSticzJQY0hZY3gxU2ppRGY2ZmY3bmpRMWVyOWM1VXEyU1J4SFhJc2RYaTRKQkhKTUVORWdvVk5MRWxQdTEycFY1YU45RTM2dFZzeEJJejFrblk2UVNLSW9pYXJWYStkM0cvVGFxc2d3cy9ZczJsUVUraVFiMCtjUmFHNHd3Z0paZUc1cU1jL1RHT1lTYWs3VlhxNXRJazJnSVMyeU5URDJlbGpndEtUWG5PRGZvODI2ZWNURFBvRnFscUZaeGNUdzhyMTlKZ2ZhcXRUclY4N01JMW82ZmpTUTBMclNXMHlwYStwRjdoRUdFU09JVDJQNnNScFQrTlNFMXpuVjlaeHpITkJxTkVjYlRjeXlyZ3VWL3BWSXBhOVZsY0EyUVZaSDZlMGg5V21iUnhOWGpoclJLaUlHMERRMjFkRGdwVnZ0OU9vTUJhVkdVUlE5V085ay8vVW82VFN4TlBMMXBZNzhGSWoxWCthN3g2SndycFYwSUttY0lhdWFTWnMydDFiaDZYR0hXa0FETDUxTHIyUWxvTHJGQVdNQkNhbCthWGo3V1FNai9jWDZGOWhsQ0U5ZnI2aUZ6NWYydzhNTVZCYWgrckhhek1BSGxlb1ZJcC9VNzlQMmlYa01hVWVOT1orQXNEZ1RlVU5XUC9sM3dZYldQeGIwTjNhVmZNYlZXYUwwM1I4U0lJN0cxdFRVeWFXMnpOSEFXZ1NFTzFkR0RIbHdqUXU0VHUybjcwbU1LOCtqdmVueWJYcmJKRVMzTkdsWmRicTZqbnhCaHJla0pOYzBFNGl0SXY5cVBrbkZsYWRqaVYvZG5jUlB5bXpTKzlzTzd0RVNjR0wyUW9ITUFHcWxXNHEzNjE4MG1KL1IxK1pNa2lFYTYzcUVreUpQSjZEQlVJeUpFZUdzYnJhUksweHJDWmkzRlBtdHBsUHUxVXhVaWVrZ3k5ek5wdGk4TnE1NmY3ay93b1FWVTk2TWxYZWNzUmpTMWRzUTBNVUxIamxrVkVnTFVhZ0g3dlBZQlFpYkZacTYwUFI1UjgyNDBLdERxV0JoYTVoSUsxM1FNcldIemZyZEUyeUxWTW53b2E2Y0xYdVNheFBpVzZCWlBlcTNCNW1HME5nNlpGa3Q4QzVNOGE1ZjdFMjN2Tk9MRVNkR3FVanN3bWtoV0FyVWthVTJnMWFnd21DMUN0V0dqWk9kQ2s3ZWFRT3lvT0hONnVkZ1N5cG9RYTdPRm9ld0NrSlp5bTl6UzZsMzZyRlFxNWQ0QW5adVhaMnk1WGVpVnZYcitRTG1YUVB0ckdzYVFvQWx1TmZ6QTdsdkROT2RaRlJaU2E5cDNzSit0cWhKMUhnTEFTb0pOeDFwTkVWSmpJWW13QkxKWlNJdGtyU2xFZ21YRjBqS0F3S2dkVmMyY1duTm9KZ2pCYkpueFFYUFgyczlxRk8zOVMrd3ZRaVlNSUtHbmJHSk5oTnUxcEZqMXBvRzJRT2ltNzdlY0tXbE82ek5ZbFMvTW9zZTNIS3dsWC81YmM2RjlBTTJRK3FDSjBKeUVZV1VqaDYxUEVLMW9OM0pZRDE1d29KTXlPdnVuTmFJMncvcklPYTJkOVR4RHVKWnJPcHNvZU5kSDBXdGNGMFV4TkFINm9sNHZ0MHhnYmFDZGVLaFo0bHJDaHlZbGNJeWJzRFpMMXRQVjZWS2dUTmxxeHRaRTBuTVRKdFdTWkU4VDBmWmZ3NlhoRWFKSVlxZGVIeDRlSVlkWjJ3MG93TzY1eG43MCtIM3RwR3VZZFdMSDRsVXorTGh3dWt3ODZadEN0ZnJXNDdTT29BWktFMEl2S1Z1cDEvZU9zOC95WC9ldkpWRVFKYXR6TnF5U2UzUVJxbVpXbXczVVdrOS9sMGpBYWh0cmR3V2VrTWVmcGluMWVuMWtzVW4vYm1IV01GcjZXTlV2dU5iWGJIcGYreDBXem5JNVdOc3hQYmdsdEZiN0ZtRDdYUk5mK3drYVFmc3hoMllDM1k5R3V0VUFvWDZ0bHJKaldzblE0NHBES1ZwQjc5TUw1UktzcnlObVo5TWNUYWZOcmpTZERBcVpLVEVWUXVSUTRzaHFOazFmYlZwRkEwUVdRZU1rVWt1akFCQktXVm9BOU84MlBCcjNuTTRWaE15QVNMNk9YRUxtU0pzcExiRjZBY2VxVHV2YjZEeUJlTis2c0ZRemdGYS8ydVRKYTJHMDFwRWlHTTE0bHZsa3Jub3VWbE9KS2RHYlNFUENGRExsWlVuWU9GV3VKeWRJc0wrSHBGNDNQUkZ4YUt5azZEN0ZEdXRuTFl3YVFUSVpyWHJsczE1cEUrUks0WWtnemlhOHBGbkhXQk5JcEZwckpVa1l5Unhsekg2L1g1NXJJTERKT1BvdHBOSi9pT0M2NmNVY2EzSTBUcXhtc1JwY3ZvK2NGS3FsUkhZTGFRSllsYWQvMHkya3R1VzZMYnV1VkNvbE4wcWlZaHhEYWpoc2VsZmJQdjFpUmxzK0ptTkVVVFJTZ2liaG0yVjI3UVBwRUZYR2tkOEVOenIzNEp3cjdiNDl2Rm1hVGd0clZTMWo2MzR0OFd4YVc4TVdNaUdhRHVJTC9IOFlQSWFuMkM0Q3ZnQUFBQUJKUlU1RXJrSmdnZz09"}} \ No newline at end of file diff --git a/sleap/skeletons/fly32.json b/sleap/skeletons/fly32.json new file mode 100644 index 000000000..c75361ce5 --- /dev/null +++ b/sleap/skeletons/fly32.json @@ -0,0 +1 @@ +{"description": "Template Skeleton for fly32 reference dataset.", "nx_graph": {"directed": true, "graph": {"name": "M:/talmo/data/leap_datasets/BermanFlies/2018-05-03_cluster-sampled.k=10,n=150.labels.mat", "num_edges_inserted": 25}, "links": [{"edge_insert_idx": 0, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["head1", 1.0]}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["eyeL1", 1.0]}}, "type": {"py/reduce": [{"py/type": "sleap.skeleton.EdgeType"}, {"py/tuple": [1]}]}}, {"edge_insert_idx": 1, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["eyeR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 2, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["neck1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 3, "key": 0, "source": {"py/id": 5}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["thorax1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 23, "key": 0, "source": {"py/id": 5}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["wingL1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 24, "key": 0, "source": {"py/id": 5}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["wingR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 4, "key": 0, "source": {"py/id": 6}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["abdomen1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 5, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegR1", 1.0]}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegR2", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 6, "key": 0, "source": {"py/id": 11}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegR3", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 7, "key": 0, "source": {"py/id": 12}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegR4", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 8, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["midlegR1", 1.0]}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["midlegR2", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 9, "key": 0, "source": {"py/id": 15}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["midlegR3", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 10, "key": 0, "source": {"py/id": 16}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["midlegR4", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 11, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegR1", 1.0]}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegR2", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 12, "key": 0, "source": {"py/id": 19}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegR3", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 13, "key": 0, "source": {"py/id": 20}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegR4", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 14, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegL1", 1.0]}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegL2", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 15, "key": 0, "source": {"py/id": 23}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegL3", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 16, "key": 0, "source": {"py/id": 24}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegL4", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 17, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["midlegL1", 1.0]}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["midlegL2", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 18, "key": 0, "source": {"py/id": 27}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["midlegL3", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 19, "key": 0, "source": {"py/id": 28}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["midlegL4", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 20, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegL1", 1.0]}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegL2", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 21, "key": 0, "source": {"py/id": 31}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegL3", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 22, "key": 0, "source": {"py/id": 32}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegL4", 1.0]}}, "type": {"py/id": 3}}], "multigraph": true, "nodes": [{"id": {"py/id": 1}}, {"id": {"py/id": 2}}, {"id": {"py/id": 4}}, {"id": {"py/id": 5}}, {"id": {"py/id": 6}}, {"id": {"py/id": 9}}, {"id": {"py/id": 10}}, {"id": {"py/id": 11}}, {"id": {"py/id": 12}}, {"id": {"py/id": 13}}, {"id": {"py/id": 14}}, {"id": {"py/id": 15}}, {"id": {"py/id": 16}}, {"id": {"py/id": 17}}, {"id": {"py/id": 18}}, {"id": {"py/id": 19}}, {"id": {"py/id": 20}}, {"id": {"py/id": 21}}, {"id": {"py/id": 22}}, {"id": {"py/id": 23}}, {"id": {"py/id": 24}}, {"id": {"py/id": 25}}, {"id": {"py/id": 26}}, {"id": {"py/id": 27}}, {"id": {"py/id": 28}}, {"id": {"py/id": 29}}, {"id": {"py/id": 30}}, {"id": {"py/id": 31}}, {"id": {"py/id": 32}}, {"id": {"py/id": 33}}, {"id": {"py/id": 7}}, {"id": {"py/id": 8}}]}, "preview_image": {"py/b64": "aVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUlBQUFBQ0FDQVlBQUFERFBtSExBQUFvZFVsRVFWUjRuTzJkZVpSa1YzM2ZQL2ZldDlYV1ZiMVB6MHhyUnJOSkd1MGd0QTBJU1FpREZRZ1lBemFiRFNUMnlYWklpSlBEeVhGT25KUDRISi9FU2J3R0wyQ0lrNEFqTUFuWUxMS0VRUkpJTWxyUVNKcFZzMmkybnVtZTZiWDJ0OXg3ODhlcnFxN3U2WUhwMFVnejBQM3Q4ODZyZWxYMTNuM3Y5NzIvKzl2dWJVR0szd0grQmF0WWNaQ1h1Z0dydUxSWUpjQUt4eW9CVmpoV0NiRENzVXFBRlk1VkFxeHdyQkpnaFdPVkFDc2Nxd1JZNFZnbHdBckhLZ0ZXT0ZZSnNNS3hTb0FWamxVQ3JIQ3NFbUNGWTVVQUt4eXJCRmpoV0NYQUNzY3FBVlk0Vmdtd3dyRktnQldPVlFLc2NLd1NZSVZqbFFBckhLc0VXT0ZZSmNBS3h5b0JWamhXQ2JEQzRWenFCdndrWS9qS1RXeTc1VGFTS0dMMzl4K2xQRFY1cVp1MGJLd1M0QUlnbGVKbmYrV2ZjTmY3UDhqZytsRjBvamwxK0NEZi9OTS81Ty8rNnY5ZDZ1WXRDNnREd0FYZ2xyZS9nL2Q4OGxPc3VYSXpRaWdjejJQRHRkZnprZC80TGRadHUvcFNOMjlaV0NYQU11RjRIbmY4L2ZmZ3VDNDZqckhXWUkxQnh6RzVVb2s3My8zemw3cUp5OElxQVpZSjEvTlp1MlViMXRxelBoTlNzWDdiTlplZ1ZSZU95NG9BYS9LQ1g3ek81WVBYdTZ6dnVheWExa0VVTmpteTYzbUVFQXMvRUFLck5ZZDMvdkRTTk93Q2NjbU1RQ0hFZ2w3MHl6ZTZmUEoyajJzR0ZWTEFTNU9hUDN3NjRvK2ZqVm1pczEweTZEam15YTk5aFp2dWV4dWU1M2Z1d1hGY3BrNmU0QWRmLytxbGJlQXljY2tJMEMzODI5WXJQdjMzQXJLQkFKTWUyejZpK0oyM0J4eWF0angwT0xsRXJVelI2ZTNXSXYyQTNzMWJtU3VYR1JvYXhtcU4xcG9Ydi9jd0QzM3VqeGsvY3ZpU3RuVzVlTlgxckJCaXlVMUtDYTBIKzBzM3VHUjlBUnF3clUyRDd3bytjcU9MK0ZFWGVBMWdyZTBROXY1UGZvb1AvZHYveU1EQUlFYnI5QXVPeTY3bm5tYjM0NCtsOS9VVGhFdmEyclpnYjFxanp2bWRhNGNVU3FXZm56WHVkcCtyUmF4WEE1NHJ5YTFmeDVhZmZRZHZmdjhIY0pPWTduSEpjeFIzdnZjRERGeDlMY2FZVjZVTnJ4WXVneUZBOFBUSmhEczNMRUVDQy8wNWw5dTJEL0RFM2xQWUpFUXBoVzczdkNXdzJMWjRwU2hzMmN6SWh6K00ybkVQMjN1SEtCVjY1bnQrQ3laSldML3hTalpjZXoyVCszWmZ0R3UvRm5qVkNXQ3Q3ZlRPYmxVS3BEMWJPZnpsQVkrUDNXVHBDU3pZVmk4VzZlc3JpcG8vZTF2Q2IvYU84cjBURWt4Q3BWS20ybWlpRTQzVk1ZTDU4N2F2MTM3OVN1RDFsbGo3bTc5TmRjTTExQm9oNnhPQk5hWXpkTFVoQUswTlNYSnBiWlVMd1d1aUFkcUM5endQcFJUR0dBWUhCOG5uOHppdWkrZ2Y1UGVQVlhqL3VuRTJacW9JWUR6dW9jK3BrN01OcnNyUDhhZHZidkRBbWExODg4eGF3amltTnhwSHh5Rmp6WUFqRTJXa2pVbVNoSHE5VHFWU29kbHNBbEFZR0dGa2RCTTYwUnc3dEp1NFh2bVJiZTBteitaZmZDL1YwVzNFalNZZWNLZ1pNaEZuR1BWZGRCZTNsT3R4Wk85dURqMzdnMWZwQ2I1NnVDZ0VXRHoydG51aGxCS2xGSTdqNFBzK3ZiMjlGSXRGZ2lDZ3I2K1BJQWhRU3BISlpOaG5KWDh3dlpWdHdReEN3TkdrbjFGM2xwOHY3R1NkTjBOR1JYeDBlQzgzbG1vUTlIQ2RQNE1qTkFkRGoyK01YOG5UMVNHU3FFR3RXbVY2YW9ycDJUbEdyNzJUTi83c0I5aDJ6ZlhFY2NJTHp6N0JONzc0aHh4NjRVbWtsQ1JKY3BaV2FyY2ZRTjUwSzdHWnQxWG10T0hSU3AyZmN3cGtsRUpJQ1VJeTIyendyVS8vSHRVVHh5L0c0M3hOMGI2M2k3cFVySlFTMy9jSmdvRCsvbjVHUmtiSVpyUGtjam55K1R5dTZ3SmdqRUczM0NnQWJTQnVEUUZLV0VBdzZOYjU4T0FlYml1TUlheWRiM0hiMXBJVzdmYnp2L1E3MkJlUG9NTTYxaG95QXh1NWRzZlBrYzk0NkRnR0lWQ3V4OWo0T0gveE83L0czT25qaEZHTTFwcG1zMG10VmlPT1V5Mml0Y1pvemZiLzh0dE12UDZ0MkRqdTNKc0cxcm9PZC9pQ2tWcU5nM3QyODhobi9qc25kajU3c1I3ZmE0b0wwZ0RkaHRaaW8wdEtTYUZRb0wrL24vNytma1pIUitucjZ5TkpFb3d4Q0NFNnI3dDduN1VXZ2NYclVpWlNTcVowamorWnZJWGpkb1IzRkY0a1kwTkF6QlBCZ2dyUGNQZklITG1yL2psV3VxbjJjWHlVRXNSUjFQcWV4WVJOaHZyN2VlTzdQODdrOHc4U3hRbFJGREU3TzB1NVhLYlJhSFNzZUFVRU81OWw3blZ2cG83b1hFNEE0OWJ5MGhNUGMraXJYMlBQdnYyTWo0OWZ5R05jRXV2V09XeTgwcU5XdGV6ZTNTU09YOTBvMkNzbVFEZWtsQlNMUlVaR1JsaS9majI5dmIzNHZrK2owU0JxQzZMMXZmYXdJYVhzYk4zdmhSQW9wWkJDa0JqRDM5UzJjMXZ2TEZja0IrQ3N5SUJrc1BJQzJTQWdkZ3NJYThBWWpEM2JKUk5ZMW85dXhwOWNSek9NQ01PUVlyRklGRVhVYXJXT0lTY0FXMnNTN0gyYVExZS9qcXB4MEZZUVNNUE5lb3krZ3k4eUpoUkJOb3NYQklSaCtJcU1UaW5oZ3g4c2NjKzllZGF2ZDZuWExIdjJOUG56UDUvaHBaZkNDejd2ajhNcnRnSG1RNkVPUTBORGpJNk9zbWJOR2pLWkRNWVlxdFZxcCtjdjN0cS83L1lVMnB2ak9QTkVBQXlHTTJvdFZ5UUhsMm9GRlhlSWFubUtSTmJBR3FSZklBajhOS2pVQldOaHJobVR6K2RCMURBbXZiYm5lV1F5bVk3dDRyZ3VycVBnNVplNVRTUWN2ZUpLWkE3ZTBudWEyL3hwL21aTGdkTUhmWWFIaDFOTk5UVkZzOWtranROaFpibGtlTWM3QzN6czQzMDRqa0JyUzdFa2VPT2JjcXdaY2ZqRUowNVNxNzQ2OFlWbEUyQng3MWRLSWFXa3I2K1ByVnUzMHQvZmorZDVSRkUwMzV1V0NOSXNma0RHR0J6SG1ZOFNudlZkeTkvVlI3blp6eUdUS2d2SEFKOW5teHZZL2ZSREtKdWtOc0RhRzdqeXVqdnhoRjB3WElWeHdrT0g1OWpFSU5ma0pFcEtqSVY2dlU0Y3h4M1NGUW9GY3JrY1VrcUNSSERWMkduV3JZL1p1R1lPcE9EVzIwYzRlaHdtSitmbzYrdGpabWFHNmVscDV1Ym1xRlFxaEdGSTNHVTd0SEh6elRkejQ0MDMwbXcyZWZUUngzSGRPdmZjVytLdXUyS2tGQXRVdnJXVzBWR1hONzBweDRQZit0SGV5NFZpMlFUb0ZwempPQlNMUlVxbEVpTWpJd3dQRDZPMTdveWwzV3E5bzlLWEVLN1dHcVhTaUYvYlFHeGZSeWxGRUFSSXFUZ1d1enpzdjRrM3VzK1NTNllCUTZpSzdGSTNzak5hanpCTmhBQXBJQnpmdzZsOGlmNlJ6UVNlaDhYU2JEUjU4S1Z4OWs4MU9TejdxSmRjN3VpZHhSV1dwTGQzZ1NieWZSL1hkVHVrZEJ5SDZRcjBWcHNVQ2lFREF4NTMzcm1KL2Z1YmpJNVdPWDM2TktkT25hSmNMbE9wVkRoOStuVEh5RzAwR21TeldUNzYwWS95bHJlOEpiV0pOTHpuUFZkZytXdEdSZ1RHUUpJczlrYkE5eVhidG5vOCtLM2xTdXI4OE1xR0FPbFM2dTNuaXRIMURBejBMeGpYdTlWNTJ4VnM5KzYyRm1tL2RsMlhUQ2FENDh3M3AzM2M4N3hPL0VBSXdUTzhnYkhnUnJhckl6Z2tISFcyY0N3cWtyT2E3SUl4MzZKUFBzTjRkWUo4L3pva0VEVm1DY3NHa0dncmVHeW1TTTM2M0wrMnlWQWdNY3puS2RyZVFKc01RUkJncmFCUzBSUUtZNEJsMnpZSEliWlFyWVlVaXlWeXVSelZhcFZtczhuUTBCQzFXZzBoQk0xbWszdnV1WWYzdmU5OWFLMkpZNDAySnhrYWZnaHJRNklvOVhpV1FoZ2FYajV5dGlhNVdMZ2dBdlRrZkg3K1RWZnorcXZXYzdxaE9GVDIwZExENmdUUDgxSTNxbVZOZHh0NWJRM1FWckd1NjNZZWVMdm5kOXNBcnV2aXV1NkMzMGtwYWNnOE8vMTFLT1hnU2t0L3ppRGx3bEJ5aDRERXFQQm82cHJtZkQ1MHRVZGZYdkxneXhvRVBEdnJVOGZqbDY2V3JDczRHRUJKU2JsU3BWeXBkdTdCZFYxODMwZUlERkUwaStmVkNJS0lMVnZLTkpzK2ZYM3JLWlZLMU9zMW1zMG0wOVBUVkNxVkRxbHZ2LzMyanZjRERrbjhQWkpramxUd1p3dGZDb3NVaG1OakNZODlXcjBRTVowWHpwc0E3VjU3eC9aMS9ObXYzYy9XZGIwNHZvT09OTWRuWWo3OTZDUkhwaEpVbHdHWHorYzdCbEVtayttUVFDbEZOcHZ0RUtDdE9icjMzZHFqVFlEMlhrcUo3MG9jWi81OGp1TVFCQUdlNXkwWVB0ckRpaENDUkdzOFIvR1AxanFNOXRYNHdndFZxckZoejR6Z2ozWUwvc0VOUGtONVJUT0JYTUZuODBBL1VhS0JlUzJsbEl1MUc3SDJSVUNRelU2VHpRcUtSWmVob1FGT25oemt4SW5qTkp0Tk1wa00xdHBPRUt3Ny8ySHRHR2xVNFd3UlNLRnBKQm1PMTY3Z001L1p4OXpjcTVkZ1dwWUc2TW42L09kZnVadHJOZzlCWWlBeEtDWFlPT1R6aTdlVStMMUhaMEI2T0NvVmpPY0hMUUU0cVRDa2FxbnlWTWh0TGRGVzk5MEdZTGZkMEJaOFd4dTBJNHVlNTNXMGhKU3lRNER1Yzh6MzNQbGhSMG5KaDI3cFlXMnB6Qjg4ZVpySnV1Wm9XZk43ejlZcCtKTFpwdUdLb3VLTm94bmV0cm1BZ05RcmNGMmtkRWlUcU9rMXJHMFBlekY5ZlJOTVQ2OWhjbklLWTNTSDBFbVNNRGMzUnhBRXJTZHBFWElyNkIrUXVpbnpHa0FKdzNoOUcxODVjRGZQVDE3TGJQSDdJUDdyZ3V6anhjUjVFOEJheTkwM1hzRk5tNGZUa0YyN1FSWXdsdXZXWmZqMXQ3dU1Wd3d6RGN0c1V6QVhLV3JHd1FnSGkwUklCNHNnakRYYUdKUVVLQ2x4SE5YeDFycnJCYnJEeVZMS2pzRGJ3ME0rbjZkUUtIUzBTL3Y0NGtCVm0wVHpScDdFV3NQOTF3WDA1MzErNy9GeERrMkZ6RFFOMHcyREVQRENoR2IzbVJnckhYN2hobDRNc25WdVM1S2NXdklaQ1dGdzNWTm9iWkJ5WHFoeEhETTJOc2JBd0VBcnRXMXgzUjBZOHpER25NVGFsRXlPMUNnUjhPQ1JlM2pzeEczNFRremhpbXVZVWc0bWlTOTZwaE9XcVFFR2lsbnlHZThzM3hvTG5pUFlOdXl4YmRqT2YyNVR2N3NhSmN5RmduS1VVQTRGYzZHa0VrRlRTMklyYUdwRFUxdWFXbUtGZzFKcEQxTkNvaHdIS1JXZTU5TGYzMCt4V01UMy9jNFE0amhPWjhqcERpZ3RScmRoQ3ZQeGgzdXVIcUlTQy83RHcwY0pFNHRxL1Z3S1FhUXRqeDZ0ODlhckIxaFhDa0FvaElqUk9qeG5oM1Njc3pPQ1Vrckd4OGZKWkRKczJMQUJ4M0V3SmsrNS9BczR6c01Fd1hFY0dYT212bzd2SEwrRFIwL2NTS0NhSUFUOWJvVFlzSUVqUjE3dXhGTXVKZ21XUllDZGg4WVpteXl6YmswSkZya3NXTHRZbTRGTUZXVlBCbm95N1ZJZlFHaXdFQ2ZRVENJYWlVZzNMV21haUdxaXFHdVhodlpvQ2tVc1hkd2dTeWFiSTVQTmtjM21DSUlBeDNWUnFxVXBoRURLZEw4VUZzY1gyZ1J3bEdBMk1rU0o2UXI0dGg2T2hLTXpFV2VhZ3F0eldTSnRFY0pENnpVMG0zTUlzYmlHUVdCdFAxQTc2L3B0ZDFjSTBRb2FOYWhXaXZTV1BrUlZ6L0Mxd3hHSDU5WndwTnlIcnhJUTRHRFk1azR6czNVejVmSWNrNU9UbDFZRFBIZHdncTgrY1pCLytwNWJRSW0wZXd2QVdCNTUyZkREY2NuYUhrVnZSbEQwTFgwQkZIeUxyOEJWRmxlQ3AwQktDeEpjRjF6WFVsaHdUeEVZZ2JFQ1kwR1R1bWVoOWRHTVE5U0xrQ1VzZlVBUktUTUk0WUwwRUk0UHlnT3BXa09VVGNQQzdkZGR2YWRqS0xxS3ZseUE2eWppWktHeFpTMFVBa1YvSVl2bkI1Qm9RQklFMjRpaVl4aFQ3eUtCQWZvWUdub2RwVktabVptcER1R01NUVJCd0pZdFd5aVZTcDJBazFJSzE4dFE4TmV4TnFmWk94M2hxd1JqQVFRRkoyRjl6cU13T3NxcGlkUE16TXdzcURtNEdOcGcyVjdBcHo3N0NPV0c1dWZlZEJVYmhncWNMbHQybllISFR5aVFEbE5SUzgyMkZJSVVscHdMQmMrUzk2RG9Dd28rRkh6SXVaYWNhOG03bHF4cnlUb1dwQVZoVXpjSWNGcStmWVlJZEFVcUo2QVRGSk1ZTjRQMUNsZzNoM1h6R0xjQVhyNzFQcGUrOXZKWU40dVFMblNLUnl4WWl4Vnc3OVhEL1BrUFRyTDdWQVZIcG9rbWF5RXhsdHMzOXJGOWJRK0phUk5INDdwcnllZmZUTE81anlRNURVaVVHc0Z4dHBMTkRuRHZ2ZmV3YTllTGpJMk5kV29mTm0zYXhPRGdJRnByZW50N3llVnloR0VhNDFjUzNyVlZjc2RhbCtjbjREc25ORWNxbHVuWTVXVFF4MEEyUTdGWXBMZTNsMmF6MllrdGRPZFhMaFRublE3dVpsdVF5WEh2blRkeDg3VlhJWU1DTmVPVDhiMk80YlBBclJPaU16cEFhb0FoSktxbERUS3VJSEFFZ2FjSUhPanhvQmhBeVRmMHVJWmVEM0tPQmhLc1RWbzl1clhSMVdPN2U0S1FvRkp0WUpVSGpvK1ZIbmdGVEZDQ29BUitDUk1Vd2UvQmNUeSt1MytLZi9mTkE1eXV4alFUOEYySExZTU8vK0dkVjdKbElJc25NZ2drMmlTdDU2RFF1b0hXNVpZbmtHc1pjMm1ib2loaVptWUdZd3paYkJiUDg2alg2NTBZU1hzOGo2S284eDVyVUNibU8wZWJmR2EzSVRIUTUycmVsZG5ENlJOSE9IandFSlZLQldNTVI0NGM0Y3laTTY5QTlDa3VLQkFVeHlIN2pwekdLUXl6NmNvU2dTOFhXTDF0V0d0UlVxYloyeTdydmozK2FpT3B4WUo2SWxHSlJFaUY1enI0a1UvZ2VtUnpHVUxWUkxtd3BUVE1OYVZocEs0Z296SXlLcVBpR2tJM0VUcEM2Q1lrVFVUU1NNbVJOTkwzN1FxelZzQkZ0a2paYWhRSWhmVUt2Q1hYeTYzMzVmakJLYzJ1YWNtR05ZUDA5T3ppcTgvL0xqTnh4QzBqYitTT3plL2lpdUtXbHZ0cWNXUVc1V1RCR294cEY1ZEl0TmE0cnN2QXdBQkFKNnJvK3o1eG5HQ05RRnF3clhab25mNDJTUklpWTdsbDJPVTd4NXJzbXhOTUp3Nkg1VHF1SFUzd1BKK1ptUm5tNXVZWUd4dTdNSWt2d3JJSTBPN1pSbXRtWjZhWW01bWl1V2FJd1BjV2pFVnRmeHRZWUxrdUpvRm9HVzVLU1pSS1NTU3hTQXNWVytiUjVCRmVubjZaaXFrd09uMEZieGw5S3grNStpTTQwc01JaWNiZzJBalhSZ2pkZ0xqZTJxb1FsdE90T1FkUkdjSUtXTjF1WUdzUFdJMW96a0JqbWdLVys3SndYODZDMGN6T2FiWUVvOHk2RVpPVHV5R3E0US9maXZaNjB1SEdMMkRjQXNiTkk2VFQwa3dXZ2NEYUpEMjlOUWlwa0lDU0xxWTV5d3ZqMytaQU5NMFZUb0ZyZW01RGVjTm9FM2VlbWFzRTk0MUs5cGNOeGdyMk5ncHNLZlhTMjZkSnRHSGZ2bjFNVFUyOUlzRzNjVUVhd0ZwTHBWTGg1TW1UbEVxbFRyeStqYlk3MW83L3c3dy8zcmFFdTdPRDNkL3hYQS9IVlh4ZFBjeUIrQURTcGhwa1gza3ZCL2NjNEV4em5CMXJkdERRRFF3R0xTeEdHQkpyaUV4TWdrWW5NWEhTSUVtYXhFbWRXRGRKYklPc2llZ3hocEt4OUZub0U0cCtGSUZVQkNMZGZLc1FTQkErSlJkS3dBWVhDSVpBeHpEMmZWenBnSFN3SXJWN3JIU3dYZ0hqRmRGdUVlUDFFS3M4V21XeFNLeVFnTXZ4bWQzOHQ1ZCtud1AxNDFSc1RFNDRqSjU1bUkrdi9TaHJpN2VnZFFOSWJldHIrZ1RYbG1EbkZJekZPU1pDbCsycVJ0TVRUSlhyeEJlcEFQV0NDQ0JscXVacXRSclZhcFZ5dVV5aFVPalU3N2N0M01XUnZiWm1hR2NLRjFmdkNpRndwTU5SZVpRVG5FQ2hGaVNZTEpZdkgvb3lYenIwcGZOb3BlamFpYk9Qa3lvQVR3ajZaY0NRQ2hoV0FZUFNaMWhsNkZjZWZjcW5UM2owS3A4KzZWRlFYdnJJckFHakVXalFVWHJHc0l6aUJLN1ZoRllUVzBOc0RYV3BxRXVmcXN6d3A1TlA4blR0WlpSMEVNS2pobVZYTk1FWFR2MXYvcFU3alBIWG9SVm9DVm5QY3RzYU9GTFJmTmg3bVBlS3A5aW9qbk5pWUlqOERZTGZPdTVUcjljdlJId0xzQ3dDZEJkN1dtTnhwVXZXeTVKRUNYRWNwMk4rcStxM3ZUOVg4Y2ZpODBLcnRrQklKcGdnSkVRdW1yY2lFRWdoTWJaMVhzUlpleW5ra3NjWFhLL2xvdGpXMzZ6VlRDVlZkaVZsdExWb3ExRUk4dEtoSUJ4eTBtM3RIVGFxUEZkNVBWUk5UTTFxYWphbXFoT3FOcUhlRW55RTZSQWdRcE5ZUThQRXpGbU5JK2RuT2drRVNqZ2NUbWFZM1BmYjNGNjNOTHcrbWs2UnVsUGtYdHZMM2NVOTNOMTRDSm9SV01sbU1jRy9mWDBQZWRid3liODgwaktHTHh3WE5nUm9pM1FsY2tRU0RvWm9wZEhSL0dTSjdyUnU1emN0NFhmWENYVFBGeEFJSktud1NwUndjVWxJRmdqUFdNT2E3QnJ1V25zWE9TODNYL0lsNWovdi9pNGl0VUhhZ2s1TWdqYWEyTVRwcG1PYXVwbHVTYm8xa2dibGNKYUdDV2xhVGNOcWpHNm1FVzhzajNNR3R5NUp6OXE2TDFMYjMzYUhRRzFyM3pvdUVIalNRUzRpbzBSUUVUQlhPMGJQeEhGNmxKTjZNVUp5alpDQWJzMlZjT2FWVjdQTWgyL280Y3Y3Ti9IRUMwdFZTSjAvbHBVTGFPLzlVWi8rdC9XVHVUN0RlSGFjY3JuTThNUXdnMmNHd1lDd0FtSFRyS0N3clY0cFd6MVNpdmJUNnZSUUxUUk4wU1FrWkk0NUFnTHk1SmxsOXF4MlpGUUdSemcwa2daTjNTUk1RcHFtU2FqRDlGalNKVkE5TDFSdHp6MmJDRnBlZ3VpOFduRFA3WVJ0Sy8xRHZLanVnTlpuQW9HdmZESk9oa0FHQkU1QVJtWElxQ3hPMHVSQTlTQnpKbGtRcmRSWWhxMWdpd2hBT3EwcjJkUmd0UnFFNHF4MHNaVU1lSFZ1Nm9jbmZxemtmalNXclFGVVZySDJWOWVTMlpUQmFvdXhodkpnbVZxeFJtUWlpclVpeGpNSVQyQjlpM0VNeGpVWXg2QmRqVkdHUkNVa01pR1dNVnBxakRCWTBlcW5JdDFDd3JOVXR4U1NseXN2czI5MlgxZHYrL0ZvbjBlSlZrWlNwRU9ORXUzWEN0ZHhRVnVFMWlqcDRnVVpQT0ZnalVZaEdjNE9NWmhiUzg3SlVmRHo1UDBjV1pVaklFTkdaY2c1T1h6aG8xQ3BKbXNSWHdtRnNCS1ZhTDU0NE5OOGFlSWhFdWtoaFVpMWlJbTVJWGN0M3BVZjVZWEdMS0oyR2xVL2pkczRRNkY2bE1IWloxRTJZaUVKTEFaRlRaOTdUdVg1WXRrRTZIbEREOEZvZ0UzbWt6N1NTcXhyT1hiOXNYUCs3c2NKclBPNW5WZVowRmF4cmIvV01DS0Z4Rk1ldnZUeFZicDV5c05YUG9FSzVvOUpqMEFGZUNyZFo1MHNHU2VUN2xXR2pOUGFWSmJrekJUNjlCU2kwaVNmS1RGOHhWYUdObCtOOGhhNnVFSUpaay9WbVoxbzRQcVN3UTE1bENlSUk0M1dDVWEzZ2p3dFpaK1loRGlKTVE1ODZNcVBFd2lYWjZhZjVMaXVNaXdEYmlqZXpqdUgzMDh6R0NIeUJvbXpHNG1pa0ViaVl2MSs3dGo1Q1FZbnZ3ZHkzc3RDU2ZiTStEeDhZSGE1NGpzTHl5WkE3cW9jd2hFcEFiclJUZ1NKUmNkb3FYbzcvNEZBTE1nWU90YkJzeDRlSHA1STk0RklCWmIzOHhTRElqa3ZSMysrbjJKUUpPdG1DZHdBMzJrUndFazNWN3A0eXNPVDZlWklCMDk2dU5KRkNkVWhtVFo2Zms2Q0ZNd2NPOHpZL3Yzb09PMXBwakhMeWFtbmFNek1NUHo2V3hIV29wVEVHdGoxeURoSGQ4NVFtUXB4UE1uZ2hoemI3eG1pTk9LVEpCcHJvR2xybkxUSHFOc2FSZHZMSUd0eGhBTmVpZmR1K0JYdUtPNWdQSzR5Nk9WWWs5bEVpRWVTaEpnNEFoMWpyRVFISTJpL2ozMWJQMEd1Zm94c2ZCclFJRnhtUlMrLy9uQ1ZrNmNtbGl1K3M3QnNBa1NURWRZczNadmRwb3RYOXBDeFJDWVNGU3VVVGpmWHVqamF3YlV1SGg2T2FRbGRlSGpLSXhOa0NQd0EzL1B4UFI5SE9XU0NERDFPRHoycWgwS21RQ0ZUb0tmUVF5YklwRVVlc251dGdiUU5iVzJCQmFNTlVSTFJNSTBGN2V6MGFDRXdVY2laZy91SXd3WkN0VlZxcW4vbXhvN2lyeG5CNyszSDh4d08vdDBNeno5NEVtdFNUYURqaE9NdnpsR2ViSEQ3aDBad1BjVnBUckpQN3FRcEdoZzBEb3E4TFhGTmNqTnVsS0VaaGtpOWxyWFdrblZ6Tkl4RjY3U2MzT2lFeERnMC9MVllsVWVSTUphNWxzZVREN0ZWNzJLZEhtTlBwY0R2Zm1zdkw3NTBjcm1pV3hMTEpzRHNFN1AwdjZVZnA4ZFpTQVFCZllmNkdIeHBFSTN1cUc0cFU4dGVPV2tsRDJLK2xOeHhISVFqMEZMVENCdG9UeE82SWI2WFZ1VFdxMm1wZGhpRk5NTW1ZUnpTQ0J2a0Mza3ltWlFFM1dWaUMxUjFWOFZSSi9UY1ZhdW9sRUlvUlhOdWxzYnNaRHJQcnh0Q1lKT1l1Wk1ueVBrQmxXazQrc0lNMW9KMFJPYzdRa0IxS21ac2I1bkI2eHoycStlcGl5cXk5V2V3ek1wSkR0bzlySzl0cFZLdVVDNlhzZGJTVHorWklFQWJUUkxIR09GUWRkZWlWVDZOdFlSVnpyejBHTS90MnMwM0p5YVptUTJabWp6T3pOUWtaeGRsWEJpV3J3SEdJOFlmR0dmd1hZTjQvUjVDQ1pKcVF1WjRodEt4RXRLWG5iaTJ0UmFON2hSNUd0R2FEbVlzd2dxc3NCaFNuMTRaUmFJVFpDZ0ozYkJUMlJOR0lZMUdnM3E5M2hGa0dJVmtNaG15MmV5Q0lwRHVDcUlvaW5CZEYyTk1aODVma2lUekZVS09nd0Npa3ljd2NYSldiS0oxUWlKdHNMVUt6V2xENVV5WWVqRUx2Z05HUTJVOFFWeC9ob2FxTHhHL2tKU2RhU2JyRXpTbUk4STRKQWdDa2lTaHBoV2g2TU00QWlNOXRNd2lwVUJIRGNiM2ZaK2orNS9uNElHWE9IcjBHSTFHWThtNUJxOEVGeFFIbUhsc2hzcUxGWXEzRkpFWlNYd3dKaitYSjdNaHcvQ2E0VTZsVG52K0h5ek1EM1QzeUtVS05kckhsVktFWWRpSkZTaWxTSktFVENaREZFWFU2L1VGMVVEZEpkMWhHT0o1SHJWYWpWcXRodGE2VlQya1VNckZkeHk4OGhSaTVzelN3c2RpSFE5UktLWXVxd0luRU1RTmU1WlhKaFZZTDJTNk5vVXRuVjFZSWhERVRzU2ttQ0NhRlhpdWc4aGtDTDAxeE00Z2l4ZHFNWEdEVTNzZVkvK0xUN0o3OTE0T0hEaElvOUhvUEo5MkxPVmlyRVp5d2ZNQ2twbUVxWWZuRXhMTm9FbWlFeEtkZEdZRGQ1ZGhMZFhZN3JUbzR2QnhkNjgyeGhDR0lYTnpjOFJ4M0pscDNMMTBUSGZJdVY2dlU2L1hjVjJYT0k0N0JSaSs3K042UHI0UytHRU5FZGJuZzBnaVRVUzFSYWVSTkhNOU9JbkdiZFFwajBOVXM2M3NZc3RYVDgxYm5LeG1WaHdqUGx4QjNDREJ0UXMxZE91a3pmVnpvRnpFeVNMR0x4SmxodE1aejRCVkNxSFRlc1M1aVJQczMvVTBSNDhlWTJ4c2pFcWwwcm0zTnRvRVdCeE9YeTR1MmdJUnpXYVRpWWtKeXVVeTA5UFRyRisvbm53KzMwa1d0V2ZKZEhMZkxiVFozRDArdDdHNEVEUkowcEJ6cFZKWlFKaHVMQjc3MjJYaHJ1c1NSaEdCZ041R0E4L0VyY0NVWWhLSGs0MlFQSWFDRklUYWtPUjd5THBaVkwxR2VBcE9QeFdnSTRsVUFpc1RwSFV3R0dwbW1vbzl5T2xuamhBMll6YkpZZGJlT29neHJhRk9pbzZ0SkR5TDNSRFRXRE5ENWtWRjcvLzdXL0o3bmlQdTYyTnV4enRwWHZ0bWpKc2htMWp1TTVvYnI3K2U1bFZYOGJrbm4rUnpQM3lPcVdZVEtjNWVhZVdWNEZWWkg4QjFYWEs1SExsY2JzRmswYllRMjRKckM2cDdxbmkzS20rWGYzZVhnN2ZEek5aYWdpQm96ZGl4YVZDbGxXZFFTcVZaUlVjaFZMb2FtWktTQWM5bG1BVFBwajB0c1RBV3cxaXR5ZFQwTkZKSUVwMjJyNysvbjhIQmZqeVJwYnk3UURqcG9xU2liRTl4UFB3aGpzMVNEeXNjbjlsSGJKck16WmFwMStwa2VnSzIzNytGclhkdXBEalN3K3l4Q2xONzUranB6ek55MndDcTE2T3c4eVJYLzlaM3lKNG8weTVZMEM2Y3VmODlSUGU4bjl0ZS9nRkZtWUE3Ny9zLzl0eHp2UFB6ZjA0NURDOXFpZmhGMHdEZEZVUHRPdmpaMlZtbXBxYm82K3VqcjYrUC92NTArbGhmWHgrNVhHNUJuVUI3M0crbmtOc2thUjlmVEJKSWN3NmU3MkcwNFVwL2tPMDk2MUJTY2J3K3pmNzZTWHJqREpzcS9VZ3RtY3ZNNFpkcU9OSWdsYUlheHJ3d01jMkp1UXFOZXAxR280RzFsbWF6aWU5N1lBU2U4bkduaXNSblVnSTJiWmtYcDc3TjBjbTlZR2pkM3d4UmE1cDVGS1V1OHM2bm4yZHd0SitCTmYySVJDRkR4ZkRJTVAxUDlYTERPemR4OWRmM2tUdGF4dmp6ajE5cXk5QTN2a29wYkZEY3ZnMmtDMTBhOGE2YmIrWVRMeDNnejNidHBsS3JVNjFXY0tUazNxdXU0bjIzdkI1akxRODg4d3lQdm5RQXZRemI0S0pwZ01YNS9jWEZsMEVRNFBzK0FNVmlrZUhoWVJ6SHdWcExxVlRxalB1bFVva2tTVG91WGx0OWR5ZVkycG9qeUFRb29YalhwdHU1ZWVSS2hETmZoRktiYVZMYlgwZUdxUnRxaEtHUnFUQXpNc2FSeWlUZjNmMFNMNCtmSm00Wm1WRVVZYTNGODMxZWY4ME9idDErRjMybEFab1Z6ZXlwaVBIamt6eDIrQUgyalQvRjNFdzZBVFNLb3M3TXAzT3BaTi8xS1JRTFpMTlpZbTI1Y2FqSWY4cjRlR2VxMkc2UHdscWs0N0x4L2UvQlg3dDJnZkE3OTIwdGV5YW5lUHI0Q2Y3MnhSZTQvNXFyZWY4dHQrQjRIbGhMSEVYOGp5ZWY1Sk5mL2dxMThQeldGTGlvaTBTMWUzTjNmcitOTUF3N2l5ZzBHZzJtcDZlQmRKeHZUK3lRVXRMYjIwc2N4eDMxM3A0MlBqdzhUQ2FUb1Z3dWQ3U0JGL2pzdU9KNmJsNjdHU1BiZFlLQWdHeC9nQjJ5Tkk2SDJOWnlNN2xHaWJIakUzemgyY2M0ZU93RXpVWmpvU2NpNE9kLzVpTzg1eTBmQkdtd0dESTVsLzZSUEtkcSszbjRMLzR2VWtyQ01EeHJSYkNsUFFrSTQ1QjRPclZib2lSaE1LNGhObS9zbUpFTFR3S2lOVWR5S1VqSDRicVJOVnczc29hUDNmWUcwSnJXdEdJQVhLWDRoenQyOE0xZHUvbnF6dWZQUzJhdjJpcGhpM3RFMnh0SVo4ZkduZm9CSVFUbGNybnpuY25KU2VJNHh2ZjlqcnRucldWb2FBamY5ekhHVUN3VzA5OHF5UnZ2K2hEU0ZaZ2xrbjMrc0VmelZKU0dyVVVhSlJ5S2h6bTAveWdIeHc2akU5MnhwSldqdUg3YjY3anJscmNpSFVoMFZ3K1VsbTFYYjJMRG1tM3NQYnp6bk1JKzEvMGJZenIzY2FSZTQ1a2s1RzVIMGRUeksxQUpLMmdveXlNSDkvRXpRME5ubjFBSWpwK1pKT3Q3OU9menFlMndoSllRanNQSDdyamp0U2ZBWXBYZmZyMlVtOUpkSHdobmF3b2hCSTFHbytQN0NpRTRlZkpreC9YcDdlMmxwNmVIVEM2TDczdG4rZDF0Q0NWWS9GR2dQS1luSjRuQ3FITnVheTF4RkRQWXU0YkJnYlErcnh2YWFFYUcxM0x6dGJldzkvRE84M29lUzkyM0VJSnlOZVJ6eDA1eC9ZWlJlaXN4U2N2MVUzbWZCNXBsdnZUTmgvbXJ0UnZZdkhGalY3R0g0TWtYWHVDRFgvd0xSbnBMM0xaaEk1OTYyOCt3cHJlMEpBbDZzOW56YWlPOHhpdUZMalUwTE1aU3BBQTZOZlFBazVPVGxFb2xSa2ZXNFFmZWt1T3ZFQkRQeEZnOUg3anhISmZ2anoxRk9hcDFydEV0S04xYVYwaTJiQk5yVEZyVVNXcUVYb3c2UENFRTN6ODl3OGNUelM5dlhjL3JaTUMwaEFjbUp2bkcwUW5xVWN6Yi8raVArUmM3N3VUZE45NUlsTVI4L3UrZTRyUFBQTU9wYXBVajA5TThlZWd3cFd5VzMzajMzMStTQUYvZjllSjV0K2MxWHlyMmZOVG5Vci9wbnQwcmxhU24wTU0vdnUrOWJGMDdpckVXMTNIUUxkdkFWUTRpZ3Rwa2lEQ3BGdkFjbDRxdThDZFBmSWxhczdIa0hNTG45ejNMN3IzUHNYbmRNRkhVSk5NemlKY3BJQVdNalkzeGcrY2V1eWozSzRBWHArYjQxN01WWENFd3RJYWNsbVk4T0QzTlAvdnJyL012djVrdUN4SzFsdEhySnVzWG5ucUs5NzMrSnJhUFhqRlBBaW5aK2ZMTC9NWFR6NXgzKzE2VHBXSXY1am0wMWd3UHIrSFgzdjFMM0xmOURVZ2hxVFJxL0hEdmJxNGIzVUl1aytYYnp6L0pseC81Smx2ekcvaTU2OTVLUnZrOFB2WTBmL0xFQTN6M3dBL09UdnkwTUpCVlRPOS9pT2IrSmtrY2t1OGZaWGpMN1pUVzNzRC8rc3BuT1RaKytJSUl2QlNFU0FORVVXZktESjJZZ0JBQ3k5bUM3OGFCMDZmNXdHYy96ei9Zc1lOMzNIQWR4bHErOXZ3TGZPN3h4emsrUFhQKzdXanRMMm9nNk5WRUlWL2d2L3pUZjhQSDdubFhxdWFUaFAvNHhUL2kwMS83SWoxK0ZxVVUwNVU1eW8wcXlsRU01L3RSUWpMVG1LTjZqcDV2akdHa3Y0OVB2dTFlSE4zbytOSFdhSEtGZmg1ODZSUi8vY1FqRjAzNEZ3dnRpVGVEK1R6R1dzNVVxOHZ1Y0Q5Ui96Yk9jMTErL1lQL2lJL2QreTZFVFlYL20xLzRJLzdULy9rTUNKaXJsanZmVGNQTGhwT3pweGNjT3hkKzVxYlg0Uk1UVzlMcGE0QlFrckJSNXFxQlBBOTVQbUVVWGxZa0VFS2dqV0c4dlBDK2w1TWsrb2tnZ0pJSzVTZys5WXUveWlmZTlXRUVhWVh1Ny96bDUvbnRMMzBXWS9TQ2VRYlE4alNnbzFiYng4NkY5Y1hjMGdrcmExbFg2c0ZUaXZESG5PTnl3SEl6aEpjMUFRYUx2Yng3eDF2NWhidnZaNlIvZ0N2WGpPSW9CMnZodjM3NTgveTcvL2tIblVET3VYQytBcXRFQ1FQZTJScENDRUV0U2pDWHVlQXZGSmN0QVVyNUhqN3phNy9KMzd2MTdqUVhZQTNHV3FRVWZQcHJYK1RmLzgvZjd5d3lmVEd5WTkvWnRZZGZmZE10NkxCRzJ6UVNRT0JuK2R2ZGgybEUwU3RPdlY2T3VHei93YzM5dDcyWm43MzF6V2hyaUhXU0dtWXRRUitkR0NOcXJRQitzY2JrWFVkZTVwSDloM0JiTlFhTzR5RGNETThlUDhOM2R1M0NtQjhkOC85SnhXVkxnUGUrNlcwNGkrcjhXc3M2OE42NzNrN2crUjFDWEN6TWxPZGFVOHZnNEdTWkx6eTlpODk5OXhHYTU1bFkrVW5FWlRzRWFLT1hMSHNVaUdXbE81ZUQ0WjQ4Rmt1a05YL3ovSXNjbUpqL2IrQ0xEY3lmRmx5Mkd1RC9mUGNiSklzTVBOR3F3djN5WTkraUdWM2NYcm1ocjhTbXdYNjBzUmdMZzRYY1dZdGVyQTRCcnlFZWZ2WUp2dks5djBFQXJuSnhIUWNsSmQvKzRaTjgrYkVITCtxMU5nLzI4Y3M3WHM5QVBvczJCdDlSdlB1bTdkeDN6UlpnWVgzRFR4c3UyeUdnWEsveWozLzNOL2lySi82V0Q5ejdUanpINWY5Ky95RysrdjF2TTFrKy8xRG5qNFBuS0haczNVaGZQa2ZTOWUvZ0hLVzRjL05HWGpneHp2amNxN05VKytXQXk1WUFBT1Y2alFjZStSWVBQUElxclpVT0RPUnpiQjdzUHl1QVlxMmxrUEc1Wm1Ub3A1b0FsKzBRY1BuZ3AxUDF0N0hpQ1RCWnJYSG96TlJaZVFJaEJKVkd5SjZUcDgveHk1OE9yQ2dDdE9zS3VyY28wVHgrOENoVDFWcTZZcGxJNS9WclkzamkwQkVteXEvZVd2MlhBMzdpMHNHdkJPZUtHbHByR1M3bWVjUEdVVFlQOWpGZGEvRE1rZVBzbjVqRW5HTW05RThMTG1zajhHTGpSN2x5RTNOVnZ2NzgzcVdyZFgrS3NhS0dnSE9oVXh2WXFzUnBIMXNKV0ZFYTRGeFlTalA4dEFaK0ZtTlZBNnh3ckJKZ2hXT1ZBQ3NjcXdSWTRWZ2x3QXJIS2dGV09GWUpzTUt4U29BVmpsVUNySENzRW1DRlk1VUFLeHlyQkZqaFdDWEFDc2NxQVZZNFZnbXd3ckZLZ0JXT1ZRS3NjS3dTWUlWamxRQXJIS3NFV09GWUpjQUt4eW9CVmpoV0NiRENzVXFBRlk1VkFxeHcvSDg3bDJsdG05eFJId0FBQUFCSlJVNUVya0pnZ2c9PQ=="}} \ No newline at end of file diff --git a/sleap/skeletons/gerbils.json b/sleap/skeletons/gerbils.json new file mode 100644 index 000000000..66264a3a6 --- /dev/null +++ b/sleap/skeletons/gerbils.json @@ -0,0 +1 @@ +{"description": "Template Skeleton for gerbils reference dataset.", "nx_graph": {"directed": true, "graph": {"name": "Skeleton-0", "num_edges_inserted": 13}, "links": [{"key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["eyeL1", 1.0]}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["eyeR1", 1.0]}}, "type": {"py/reduce": [{"py/type": "sleap.skeleton.EdgeType"}, {"py/tuple": [2]}]}}, {"key": 0, "source": {"py/id": 2}, "target": {"py/id": 1}, "type": {"py/id": 3}}, {"key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["earL1", 1.0]}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["earR1", 1.0]}}, "type": {"py/id": 3}}, {"key": 0, "source": {"py/id": 5}, "target": {"py/id": 4}, "type": {"py/id": 3}}, {"edge_insert_idx": 2, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["spinestart1", 1.0]}}, "target": {"py/id": 1}, "type": {"py/reduce": [{"py/type": "sleap.skeleton.EdgeType"}, {"py/tuple": [1]}]}}, {"edge_insert_idx": 3, "key": 0, "source": {"py/id": 6}, "target": {"py/id": 4}, "type": {"py/id": 7}}, {"edge_insert_idx": 4, "key": 0, "source": {"py/id": 6}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["nose1", 1.0]}}, "type": {"py/id": 7}}, {"edge_insert_idx": 5, "key": 0, "source": {"py/id": 6}, "target": {"py/id": 2}, "type": {"py/id": 7}}, {"edge_insert_idx": 6, "key": 0, "source": {"py/id": 6}, "target": {"py/id": 5}, "type": {"py/id": 7}}, {"edge_insert_idx": 1, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["spine1", 1.0]}}, "target": {"py/id": 6}, "type": {"py/id": 7}}, {"edge_insert_idx": 0, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["spine2", 1.0]}}, "target": {"py/id": 9}, "type": {"py/id": 7}}, {"edge_insert_idx": 7, "key": 0, "source": {"py/id": 10}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["spineend1", 1.0]}}, "type": {"py/id": 7}}, {"edge_insert_idx": 8, "key": 0, "source": {"py/id": 11}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["tailstart1", 1.0]}}, "type": {"py/id": 7}}, {"edge_insert_idx": 9, "key": 0, "source": {"py/id": 12}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["tail1", 1.0]}}, "type": {"py/id": 7}}, {"edge_insert_idx": 10, "key": 0, "source": {"py/id": 13}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["tail2", 1.0]}}, "type": {"py/id": 7}}, {"edge_insert_idx": 11, "key": 0, "source": {"py/id": 14}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["tail3", 1.0]}}, "type": {"py/id": 7}}, {"edge_insert_idx": 12, "key": 0, "source": {"py/id": 15}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["tailend1", 1.0]}}, "type": {"py/id": 7}}], "multigraph": true, "nodes": [{"id": {"py/id": 8}}, {"id": {"py/id": 1}}, {"id": {"py/id": 2}}, {"id": {"py/id": 4}}, {"id": {"py/id": 5}}, {"id": {"py/id": 6}}, {"id": {"py/id": 9}}, {"id": {"py/id": 10}}, {"id": {"py/id": 11}}, {"id": {"py/id": 12}}, {"id": {"py/id": 13}}, {"id": {"py/id": 14}}, {"id": {"py/id": 15}}, {"id": {"py/id": 16}}]}, "preview_image": {"py/b64": "aVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUlBQUFBQi9DQVlBQUFBbitzb0hBQUJtRVVsRVFWUjRuTDM5WjdCdFczYmZoLzFtV0dHSEUyNTRPZmZyaU81R0E1M1JBR0VBalc1UUZrRENJZ0hSRkVIQXBxTlVkQ0JJeTdMNFFXVlgwUkN0c2tTVzZMSXRDVXlBYVZJeUlRSUNBWklBd1c2RWJuUUdPcjBPTCtmM2Jqcm43TERXbXNrZnhweHJyMzN1ZVE4Tm1PVlZ0ZXVlZTg3ZWE4ODE1NWhqanZFZi96R0crdG4vNEgrWE5wc042L1dhMlh6T3dkRWhzOFVjWlExYWE3ejNSQjlRTVpGU0lzWklpQkhuQms1T1QzbjUycXU4OE9JTHhKUzRmUGt5RHozd0lORkhVa3pVZGMxeXVjUmFpN1dXcEJOS0thcXFZajZmMHpRelNJcVVJSVRBZXIybUh3WmNjSkNnYmh1TXRRQm9yWG5xcWFjNE96dmo4UENRZzRNRDV2TTVWVlVCa0pMY082YUU3M28yNnpXcnN4WGI3WllZSTIzYjBqUU54c2h6MVhWTlhkY0F4QlJ3cmlmR1FFcUpFQUo5MytPOVJ5azEvajk2ajBxS3VxcFlMcGZVZGMzSjZveXo5WXB0UDdEcGUwNVhaNnhXS3didmlDUVNrQlFZWTZncWk5WkdmcTRyNXJNWlY2NWM1YTQ3N3FacVcyemQwTTVtSEJ3Y01Kdk4wRm96ZEFQRE1EQ2Z6Mm5iRnFVVVdtdTAxdklzUnFPQk1BeWNyZFpvbFppMUxWVlYwWFVEMFFXOEMvUjl4NlVINzJXMm5HT040dVRGRitsWEsyUjI4d1NqUUNrRmdDcXZsR1NDRVFIUVdxT0FhQ3h0MjNKNGVNaU5XemRaclZaY3UzYU5nOFdTdytVaGJkT2l0YVpwR3VxNnhoaERJcUswd21pTlNnbVZJTVVFQ1lnSllrS2pxTFJGYVVWVE45UzFMTEJTbWl1WExsTmJpMUo2ZkwrUzRjbkVLSTBtb2V1YWJ0dWhrR2VKTWRKMUhURkVxcnFpcWlycXVzWmFtNS9YQUltaDM0SlNwSlRHVndoQk5rR01LQlRHV09xbW9aM1BhZXFHQUNTdHFCcEhOZlRZdWtLUk9Eazl3OFU0anMyYUNxMk1qQ2twcks2WXRRdVdpd01XeXlYdGZJNnRhdXEyNWZqNFdCWWJPSEczU01ZU2ZjQVBUdVpSUjVMU2tCSXFXWHlNaE9BWmhvSEtha0lJVkZXRktzOFNJekZHaUFtRHB0S0dlVHNqYkR1czBvcXFyZ2d4eWk1TkNlODlOaVhRbWhRaUtVYUM4d0JVVllXcEt0Q0ttRnJxYnN0eXNXQ3oyVEFNQXpkdjNxU3RXdzRQRGxrdUZyUnRpMVlLcFJXZ1pVTHlnc2ZnNVhkSmhNMG9SWkFaUXl0TmJTMTFWWk9TQ01tbG95T3NNUXhETHdLYklpa0VsRmFvcEVncW9GQm9yV1MzV1MzZnF5Q21pUE1ETWUvTE90VHlPYVZJU1ZIWEZVb2wrcUV2ZTBMK2pzSmtRVkVKcXFxbW5TMll6UlpvbzJsVHBQY2VwUTExMDlCVU5RWkZRblByOUpRQW1LcVNuV29NV3NtWWJGWFR0blBtaXlYenhVSUVxcDB4WHk1WXpCZFUxcUJSdU5tTTREd3BCS0tYZjVWUzFIVk44dUJqa2cwWkU0cUVRbzNybVBjeXNRaEFpRmlnVXBwWk82T3Z0MWhsREhYYjBzN254QmhKS2VINmdXUXR4aGk4OTJ3M0cxQnk0N3F1cWFvS1cxV2tyQjZyckU3N3ZtZTFYcEZTb3JLV1dUdVRCMVpLZGpscG5Od1lJc0U1dERZb3BWRWtqRkVvSDFFeG9aSkdKWVZSV3JRUENhTVZiVk9OVWg2Q3g2VjR1MXBVaXFhdHFCcUxIaFNhckIyeVlNem1MWFZiRWZCWlN5U1VCbHRYdU9CQks1VFJLQVZHYTZ4U01vRm9tcXFsYm1mVTdZd1VJOFltak9ud1BtSVVMR1pMVk5TRXFJaEtzK282VEdWUldtT05xUCtVRXFhcXNVMUQzYzZwMnhuYUdHYnpscXRYTHBOUzJhMkt0cTV4eHRCMUhUZHYzYUt5MWFqR1k1QWRicTBWUWRXS2c0TWxoNGVITWovdUZHSWdCRWZ3anY3c0RKWnowQW9DMUhVclIwQlJGVnJMeE1hc3VrSUlyRllycmwrL3pudys1K3JWcTd2ZGtTZW5iVnRtYlV2YnRteldHemJyRFdkblo2d09EakhhY0hoNGlOWjZQS1BMZmN1L0tzbU9KU1dzTnFRZzZscWJDbTNsakN1ZmkxbXFqZEU0MTNOMmRvWlNqQXR2akdFMm00bUFXazNUMXRqZVlpczVVcXl4bUh4UEZ4MmhDK085eXhWSVJBVkpLYXd4NC9FWVFpQWxSZFhVTkcwRE91ODNMY0tubEJwZjg4VWNyOEdyQktzVlE0cFlZMmlhaHFxcWFKcUd5NWN1Y1hSOExIWk9WV0dzcG1scVl2UnlUd002d1hxellyVTZvKzg2Vm1kbk5FMERTbzVPVTlseEhxMjFIQjBkamJhSk1RYUQ0dVhOeTNUZGxtSG8yWnlkY3RZMmJQUEc5dDVqeStJcnBiS2hVczVja1hxbEZONTcrcjRmRGFnUUFvbEVUSUdtYlduYkdjdkRBN3F1NCtUV0xkYlpBRE5LWTYzWUNzWm8rcjRmSnltRUlHcThBbDNwZklhcjBmRFVVZEYxUFFtdzFtSzB5ZVBVSUFjRk1ZcHhCb3hqTC9lSitYTjEwMEFXN3ZHNVVoUkR0ZGczK2ZuTEMwQVpoVUVFUzJVaFNGbFlVNTcwWWlPVSs0N1BVRlVzelJKZFZ5eVBqK204bk4xMVhUT2Z6Nm5ybXRsc1JwczNqcldXV1RaNFF3cFlMTnZ0bHUzWm10T1RFemJiRGQxbWl4c0dPZmVWSmlXd1RZVXhKcThUek9lWHhqVkN5WFBGRUloUkJIMFlCcTVmdXpacVM2MDF0cTdyOFdHcXFob0ZJTVk0dnNrNXh6QU1lTytwNjFyT2xCUUpYcXpyNVhLSmp3SFhEd3hkUDA0cUNVNVBUems3TzhOYVE5OTM2S3cxNXZQNXVOamp1WlVYcmFwcnRLNVFXdTBNTUsxUllqeU1DNmUxSnNhSWMwNHNadWRHbzgxVWxwakV1RkNvM1dJREtTK2FENEhndmZ3dEgzRlZQaisxMHVnc3dGcHJjSTRZd2Z2QUpteHd6cEZJZUI4SU1SSlRRaXRRMm1DckNxT2dXY3c1VkFxUENOaGlzUmd0L0hHY1djc0F1SDRBSWs0NXJyL3lLdGRmdmNiNmRFMGNQQ0Y0dEJJaDFtYWdtYzkzeDJsS3hBUjFYZWM1U2ZqQnNWcXRDQ0dpbFNacFdaUHR0Z01TeGxnV2k3a2NBVVdLWW96anppeHFyV2tham82T2NNN1JkNTJvSU1RclVJQldpc1Z5SWJzcUJQcHRSMjFybXFhbW5iVnN0MXY2dnBmUDkxdTg5MVJWeFIxMzNNSHg4VEZWVlJOU3dpWVJPRk5aMmxsTFZCcVZkMjFNQ1dJMjlwUVljY3BvbE5HRUZQRXh5RmszZEd5Mkd6YmRscXFwU2RrdFBIOGxHQzNqT0xIVVV6N2JpazFoc3NHcnRTWXFDSU80eE03TGhsQkdnOUgwUkJ3Uml4aXViZE9ncmNGcGhWZVE4bncyVGNOOFB1Znc4SkJoR0lneDBqU05hSmNZT0RzNUlRWkhqRkcwNkdyRlpqMmdDQ2c4eGxRMGRZTW40bE9nMGpPVU1kazJhN0JXTm5QWDlmUmRSOWNOSk1UZ1ZDSElneXZ4YnB6enBLU3d6c3Y1a1pRbUZGY3NSYlF4R0tXSUpPcDJoaklXTnd3a0pYNTdqRXBjRVJJYVExTzNIQzZQaUZmRUJUazhPS1N1NjFGN0ZHczdoRWdJUFRkdm51QmNZTGxjc2x3dWlTU3NNU2lqMFZXRml1SS9qNHVXa2xqOStlZWkwa01JYkxkYjF1djFPS2xvUmRVMExKZExxb21HSzVjQ2xOYmkwUmdqYWwrOE01bWpMQUJNVktWU0NxczBMa1VJaWFRU3lXaWF0dVhnMGpIT2Vkd3dvSHpFS0xING8xWmljQmt6THZ4OFBpZUVNS3JxR0NOOTF6RjBXL3pRWXlzWlQxM1ZIQ3lXekdjV0gxWU0vUlpqREUwN282cGFxcXJCYUlzMW9yVzBNWnljbmFHMUlvYkFkdWh4TWFDTXlnWjd0cjJTSXBGR1k5Y096cEd5T2kzbmV3QjBqSVRSK0JFVjFyUXRLWUgzWG9RZ2lWT2x0Y1lheTNLeFpEbWJVOWxLQnBVWHFmalVCYmdwYW4wWUJrNVBUMlhYbXhuUkozU1NpUyt1VzB5SkZNWDR5NllnNUFkdzNySFpicmx4NHlicjAxVStmaFRKUWpLS3M5V0tvK01qckxFQ3lSUVp5T2U4R2ZyczFkUm9xeUZxTkFhalpVSjlQaisxMHNRUVNDay9TM2EzVEYweFd5NVlIQ3pGZmU0SCtyTTEyb3Z2alRJWWJkQlZ4ZEhSRVVkSFIrTlo3SndUdGU4YzNYWkxDaDVyTEcxZGp5Nm5XV3FVWHVDQ29SOUVFODJheTdUdEhHTXFyTEhaaTVLZDNYVURLY21ZbmZONVhTMm1NUmdyZG9YWUxNWFdVVmp2eGI4dloxMngyTXNaVlhiRDFJS2Z2cUlTYkVCMkRLaWtxWXdkNzFjK1Z5UytMSDc1TGg4Q20rMFdVMWNZYlFoRU5JWVVGVDVHZlBCNWh5cTBSclJBaW15Mlc4N1dhMWFyTmJmNlU2Ni91V2Z6a0N6eTdPdVI1Vk9HYnR1UkZLT2FIUTI4ck9hTFMrWmpwRlppalN0alJ2d2dob2h6UWJRQ3lGazYwVWpXV2t4dHNiT1d4V0tPMjNSc3RhRS9XVEc0QVcwdHRxNnA1clBSNW5IT2pVZHUzL2Vqb2QyMk0yWk56YXlwc2NhdzJtNVlyVGRvM1pMMGhxZ3JqTGEwN1JGdDIxSm5RUkYwVmx6aU9IaEM5Q09pS1I2V3htaU4xcEd1Ni9NR0VzRUFKVVpnakZGY2d1em5lKy9IQlo1YXo4RG9Qb1FRMkd3MjJLYmVUWVlSaVFjeElvdmxXOXl6Y3Q2Vys0UVE2UHFld1RzMm00MDhsTkhZbEVoUnNlbTdjY0txN0NwQnBPdTJiRFliVG03ZTRqU3NlUDRISE91SEFDdGozYjVSMFgwdGNjZHZPRlN2UjRHcktwdWxYdzZDQXBqWWxLaWFPZ3ZGVG10TnpwOVJhMHdOaWJxcG1jMUV0Uy9tYzV5cFViMW5lL01VSHdJcUJCcHJXQzRXV0d2M2JJNHB3bWlzcFdrYWNhZWJTdjdtL0xnUnRkYVlKQUo4Y0xoa1BsdGtTMTh4OUQxOW56ZWpFd0hRR3VxNm9USjJCUEwyUEp3cy9LSzVzM3RWWEwwUlU4K0Q5ZDdMR3pNYVZnYmU5ejM5MEpPMEd0OVhXVXN5bHBDUnZKalJ4U0pFNTNkaFhkY29yZkhyZ0hOT2hMQ3FDRlhBTzlubGczZmplMjFsZ01oMnUrR0ZGMTdnNVBvdFhucnJtdlViSWlvbzhEc1Z2M2tyM0h6Q2NmUk5xTEtCNlNjR24xSWFHeU8xcUNkQW9iVkZLME5DRVZGaTcyUlZtYkxRRkl3OHBpaW9ZTnZTVkJWdUdIWXY3MlJPbmFQditvbjdKbTdpNE53WWF3Qm9xb3FtYmFuYmxtSG9XRy9XREc3STZ0cWh0YUtwR3F5dG1MY05zNmFWSTFGcFZFeXN6ODdvdHgxOTEyR3RIc0VnclJUQmViYnJ6ZDdhRnVOK3VWeGkxVVFsaW5Yb3hvR2w3TjVZWTBqYWdJS1FGNy9zVE8vY3FNWkNDRGdHak5ZWUxXcXVCSDZtN3M1VUF1c1VVUnRGOE9MQ09lOUlXMGhKTWJpQjFXYURkNDZxcnFrcVEwcWlBVmFyRllOejNIaXdvMERNMDkySlZXemZxbW0vNVBCRWpMSFlrTVo0aDBKUnB4cWxJN1pDVG5XbEVSbEpKSjJ5dWxkNTl5ZkIvUkhzUHlYRmRydGxjN1lTdUZzcmZEN2JRelpFVTB3RTV3amVNM1RkNkdtVXhTOExFbUtrSHdaU2lneERoL2NoRzl1SmxBSTZpYUZ0bEVXVHNCcTBObmdmY0gzUDBIZDAydzM5NEppWkZyU1dJTnBrTTI4Mkc1d1RJN21xYXhhTEJmUDVIS3NTWXJYYVhWUk5KOFlIVVVvUkVsZ2p2cmpSaHVWOFFVeUpFQVUxREV3QUZYYUN0RjZ2eDZOaG52M1cwY0xPa3h0Q1FDazV4N3BPZ2pFaHlvTDVGT2s2OGJsOWNBeURHcy9PbEJJK2hGSHRuNzlrd3lhY0N3UUROcW5zdU82T00wSHlETVo2MXVzdHhsU0VtSTh6YTh1NzgrYklzcFc5aGFoaHRWNmhyY0VXKzZZZk9EMDc0OWJaS2RwYTZxWkZ4VVFZSEp1ejlXalVoaFRGM2N6ejRFTmd2Vm16VmhuTHJ5dytpbSt2bEllZ1pGeGE0WVlOOXZBQVl3eEQzL1A4Yzg5eWVuWUNKSFJia1ZUYXVjWkI0aDlER0RnN08yR3oyZERPWnVqYXNEaGNVTTlxUVFLVlV1ako0b1FNeXNUc1ZoWERVTFJsM3RuV1VHczUvK1BrZU5ReEVVTmt2VnFQVWJpenM3UFIzYXFxU3JCd2s2M1hqTU1yblVoRVFlMk14aGdGU1dPdEJnd3hlbExTeEJoRyt5SEdRUE5FcEw5TGpaRy84ZklKOVkyQUk2QkNJZ0l4bTNOYWk1RDZGRWxLNGFPNFRldHV5M0s1WkpGRHIyUk5nUUpyREZZYk1hR1VRTVp1dTJVWUJ2ck5GcVUxUTlleFhxM3B1azdnMmFybWNyeUNpeEh2SEQ1NEFaOUl6QllMRG8rT21MWHQrQ3dwSDFXSDlZSDQ3bHFUdkJ5UENqQTYwSFVEcm5lcyt6VzNidDFpZlhiSzZ2U1VldFpnTktpRnBtckVvTVVrdEZZTVhjY3dkTVRvUVE0M0lsSGlIMXBKZUxhNGM2TVFCUG5pWXJSTWpaZHlKcGRZZmNqK09Wa1poOEd6VnV2Ui9ldjdmc1FDcGtLZ010SldWeldESHpCRzU5MHZScDlWaWdNT1dLMVcyV0lPb3hIcXZTZkV5UEwzSXQxREduZnZSQVRLS21tSmtwRmQyWlFST1VJTzBTcUY4MDRpaGNHUGNmLzFlczE4TWNjYU80NjVybXZtVFpzUlFwWGo3UjJielliMTZabG9TeFFxcFhFdStyNW50VnFqcXdxZlVVb1h2SGhPZFUzS0tLWUFjRzZNd3h3Zkg3TThXbUsxNXNhMTYzVGJEbUpFS1Mxdzd2WHJ1SXowV2FNRmlCTVZMT3VYNHlKS2k1YUduWmRYak56QkRheE9UN0hGRWs3NUJnVTVLNlNKcWZ0WERNTnlNMXRWNGg1TkJNQ2c2UDNPMmkvb29uT09wbWxHMTdKY280ZWdNcExvWEE0ZFExVlpiTFhjdThmVUJVMHFZZGVhUy8vRXMvcDJSZi9HakJ4ZU1sQ0QrMkNGZmlGaW5nbDdac0w1QUZES1dJT2JRTW5ETU95aWkza3VYRHRndGFqOHVtbllkaDJiMVpxaDd3a2hNS3VGKzFCQVoyTXJqTmFqRmM1a0xydStaN3ZkN2dKZE1ZMXpYSUNpV1NheG5KNmNrR0xLc0xmbnpKMFJRMklZQm1iek9UYlVkSDJQcXZMRzBVWUVNYStsdFpiRmZENGluY1YyTyswSDdHS3hHSEgrR0lLUUMxSWNTUk9yMVlyTlpqTXVWbUgzZ0JyRHh5SHQ4UG1ZRjMwcU9GM1hqY2ZJQ0NYbjl5dTlDK1Mwc3htbXJnUWtTV0lMRkxpMElJcGxyR01ReG1yMEdjdys3cWwvSTBnMDhjTXR3L2ZVY0tSdzMxK2gvMUZFRDdjdi90UWpLY0phV0UvRlFDdGEwUTBEdmgvR09haTZhZ1IwU25ETXhZQUt2a2dWV0V2TTF2cDhMa2RLSXJIcE85bGs4cVdDQ0U3R05Bd0RmZDlUNVFoaThkTEt6M1hkNEZXa2JoVktlL0FSbEFWdG1GVTFqVEZZSllLWGpLR2R0YlN6R2Q1NW9rcm95aENRNDhFMlRUT3F1VUc0V1ptVll6Q1ZwYzhSdGlMNTFsaHFZekZaM1FrekorL0k3QzZINE1jRkwyNWtlYWppVG81eEJ6VG9YVXpmSkUzUUdwSWVCYUNnWm1WMzdrRzdLYUdNcUgreHNoWDE3dzZFK3czaEVVTjh5T0EvV0tFLzVzZEZucnFqNVpnNi8vK3BwdEpheGhLaXdMem1uRnNjVTh5ZmphTmdwcFF3TVFBUnBSTEdDQjhoaElqVkJwL25TQnROVXpmWVZHT3o1aGtHeDlBUGhLb2hoQ2pjaUtqUWFJd1MvMTliUTZVa0hKMVN6SjVid3ZVOUo3ZE91SDd0T292NW5PQWQzWFlqUjArT29aRHRPRzJzQklPS256KzlDazVlVnhXenRzVnFLeW81YXdDbE5Va3JRdkxFSUlaZnNSTlNtQVJZSnFxbzdPTGlFb1lZQ05Iam9xTjNZaWY0NENVbWtjVDM5bG1EVElOVmdtbW4zZEhGSkJ4ck5XeWgvWmVPOWIrdFlhRnc3Ni9nV1UvNGVvK3VkMnI5dkNCTS8xL2N0Tkg0MVlaQmFRd2FhNFhUcDYwUmlEaEs3RVNIaWJlUUV0VkVNT1NsOFY3Y3doZ2xPRE52WnpSTlE4d0NQbVFnN3V4c2hZcXc3WVRhVmxVVkpPRmdKRUFiRVhiblBmMGdicVZXaW02em9kLzArT0RvTjF0U0RQVDlsdFBOQ21zTUIwZEhzaFlaYzdIbG5Cc0huY1BCWllLYXFvWTJqY1NITW5sSk1TNUNUTHZGa1J1eHB6Nm5PRU5ad09LTHUrZ1lYRS92K3pIRWloSVBJS1NJeXdzeFhmd1l4ZWFJY1lKeWFTRkhwcFRBZ240Qm1rOEV1ZzliVkF2dSsycjhzNmZvczBUVjd2aUE1NCtFNlRoSG04TUhqdTg1NWsxLy9LMWNlZk5WaHRYQUM1OTRqcHVQM1lBUWhWT2tJQnFEVmp2K1pJbGVsUEhIR0hOOEllS2RSNlZFV3pmQ243UVd0Q3pvWnJ2RlplOHBBYmF5NkRTZHozeDhta1MvSGRodU8xUVNRSW1ZSUFWMGhINnpSWnQ4ejdWNFphYXVPR2lQOFZsbzdmVEJwOWNVdHF6cTZyWUppcFBkWjdRaG1SMXJHSFlFazRPRGcwbWNlZ2NZalNwY0pUYWJEVnUzaFFUYUdERUNzMjBoeDhCazRTY2tqbEZsay9hRVdDbng4ZXZQQjl3OUVOOXU0VDVMK1A0Vy93dG54RDd0M2ErYzZ3V3BteDRENjlXYTQwY3U4VDMvNFE5dzVaRXJLQ01BenozdnU0OXYvSlBIZU9JWHY1YTlLRVR3OG5NbWR2R1VBcHh0MW10VzZ6VzJiamc0T0JpMWpFVDVXb3cxOUlYYllBd3FSTFpkaHcrNzU1WTFpQ1FGaXNUWjJZWis0NWkxTTZwcVNXVkVVQVJzQ2hJeUQ0R3pzek91WGJ2RzJXYk4vZXBoN3I3N2JoYUx4ZTRJS0xoMEdkUU9yR0Z2d3NzT2owa0dvYldtcW11VTM2bk9HT0lvQU5aWXFscU9rN0tEaDJFWWJ4V2k1K1RraE1ITGd5c2o5eU5wb2lvN01kTDNneUJrT1hnVE0wcVpNdUZEWlpzalpYSkVBdWdqL05xR2RPOENkZG1pdjdQRmZiT24vMnlIcnlNK1JKd1hnN2RCZ2RJaklwaFFoSkJJV3ZIdFAvWnVycjd4S21FSWhZeUVxUXdQZmVSUlh2NjlGem41eGcyaDBTdVQ3eUdRay9PQjFXWWpabEtNck5jcnR0dU9xaHBZTHBjanBsSTJYUEtKRkFKR0tVRVhFd3pPMFRrL2F0dmdIVXBYNk1yZ2ZHQXhYMkMxcGFsbU5IV05VUXB0ZG1DYmoyTExIQndjOE1vcnIzQjZjc0t0R3pjNFhDeW9qTUVPd3pENjZxTjdsWGZ5YUppTmkrZDNPMDlwdEJHSVZEU0FKa1o1cFNpZ3FiSENnalYyRi90T0tUSmt1RG5HU05kM25KNmRFUk5DMm15YVFqVWhLb2x0QzRjZ2d0TGo0aXF0YzRSdUY4TTMxZ29NRzRFVXdTamlpNEg0S3l2TWp4OUJyVEVmUGNDOTZIRXZCcUlLaEFRK1JFSktOQW5xT2tjZFVSaGJNNTliSHYxamJ5UzZuV3NMUW1xZFg1NXg2VzFYZVA1eno5TXNHbUJIUmRNWk5CcWN4MWl4ZlRaZGovTUJaWXk0YmZrOEg0WkI0dk9JbllRQ2c1QlN2ZmVzMWlzVXNGZ3NDRVRCN3dFZlBMYXlwS3oraGNpYTJVMlZaYTRYYkxZYnJMVWNIeDl6NWNwVnR0MFcxdzk0NStnMkcreloyZG5JcTN1dDgxRFV0aHZQeFpRU3RyWllWUXVoVTBXMFZ2a0ZuZ1E2VVRjWjhORUk5cVFDUG5yNm9hUHJPdFo5eDlCbnlEbmo2eWFCQzBtTXBsRkxRRXhLWXVCVlRYRGlveXNndVVHczJ6eFdRZThrbHBCVXd0U1c0ZmM2MGlOcjdJZVc2RHN0NXFOTGhwODdnU0M4eG1qQWJ6c0c1Nm1xWVF5M1ZrM0QvTkljWXcyN0EyOTNLYTFBYXhHaW1Fak9FeEswcmFKcExCR0IwVU1DWGRYWU9oQ1ZwcG5OV1I0ZVVUVXRJY0ZxdTRFWTZidnRHR01wWHRRcnI3ekM2bXhGWlMzdHZCWENxcFlnVmUrY0VHVTFLS3VFUmFwMkRHbGJpVkZjejJ0aWlBeURaNzFlazRDMmJsak01dGlDUkUzOTNtSnNGRXhmeUp6WnowOWUwQ3NxVEdWazUySkFKYlFCRlJKS1M4S0cwY1VxVHZsNGNReXVvK3UzYkxzTktTbG04NW5nOFhXbW9ZZUE4NTRZMDJnUVJwSkU1WXhpdGx4Z2ZBNWhCdzg2dTRkSkdFTXFpaUNhQkVGck1hQTZ4ZkNySzdpL3dqN1lZTi9SNHI5N1lQallHbVBOR01zWWdzZTRnZDQ3WnJNWnkva0NOd1JlL3YxWHVQZDk5NURDaEZWa0ZOdWJXMTc2MHN0RURUNEtyQnljazdGcUxkeUNHSWtnUXBYeERLMDF6VXpvWENFbFZFcTR2bU1ZZXJZNTlqRUNVdjFBTzY4NU9EZ0FJNHV0cmJDM2h1eGlLdzBoQlRSZ2pDQzAxbFlZYTJoU2d3K2U3WGJMWXJFWVVWNnRGUE4yaHAwYVZzVWRMTGg5QVY1RU1CVFd5dDhsT0xQakN4U3JmcW81cHRwaloxREtkM1hkbHE3cm1DME9hSm9hV3pkVWJZTUMrbUhBaHpoeTE5SW9uR1Nxc3l5cUQ0RXVBeW9Kc0NrUmt5S29YUWpYV2dnaFVqVVZ3NG1qLzZVVHpGKzRpbTQxOWZjdGNVLzJ1Q2NHZEwyemQ0TGU0UStDa3NMVHYvMHNkMzM3blpqS2pPRmdGRHoyeng3amhTKzhNUElLeXJGWmRuR1pqNUxtZFY2N2xtTlJJMGRjM3c4anZGeldwWkJveStJNU4yQUcwUzZGWXhCaUpBMERKcWUrMVUwelV0Q24wVk9UZ1NWSUk4eHRoVU12R0VCSitvQWRWYnJnN2lXVVNUYjhDamRQVXFZMFNlMFF0Q2w0VSs1VnNQOWlmUmVrMFJncmJPUnNFQmx0aEVLKzdRaXBMSVFZa3lqeE1Jb0xxQkdMUEE5TDZPQktqV3JRbUoyRmIydEwvN1dCL2wrZDBYNzBDSDFrbVAzd0lXZi81VFZpRjhTWVlBZGR4eGpGZTBsR2FHRkdHRS85clo2ekY4NTQvRjgrenRPLytiUXM5TGs0VkxtOGw1MVhucjhzdURHR2s1TVQ1amtaaCtqcHQ5dVJRRHRsYVJXZ3JtamwwOU5UemxacnFxWVZleW5iYjlFSGlKSGExdERPSm1TZVJOZDFlK3lqTXVBUWdpQ0JCUjFybW1aUG1vc3dDSlZZak1BUVhmYTdaV2U3WVVEWlhheS9MSDR4TG90bW1icC9CZEljUWFXWXdFVTBZSUZXVzZncWVqZmdrUGhDYlN0MEpSWjIzL2RFRjBnNWFUVUhGU1dVV2d4RnBUQkdZVzJtdXpjVkxnVGN4OWJZUnhyc1cxcXFSMXZhRHgrdy9TVUpwMDVCSVhIYk50Uk56WlczWE1hMkZ0OTd2dm5mZkpOWFAvVXFRUVdPRDQ5Wm1kVVkwSmxxdjJud3pEbVhrMWpVT0s4NmsxTEY5VXlvR0lqQmp3SlNqTyt5a3d1YXVscWRrVEJvdTZYT2Y4dDZoZFBUVTdhYmp1MjI0OUtsUzNSZGgvZU92dS9HOFJVYVhOLzNnc3lXWDViWGxNaFpwRWh5QjRZc0FNSXpWMmlpRDJLUTlPSWJtWHdjUkI4SXp1T3k1aGdKb2pGUlo3QWl4b2hSa3IxUzNFcVZzWEpqTGUxTWd6WFlHRWJ5b3phU3lkdWxsRW1hV2NDSzRROENoQUE2N1hoL1ZWVlJ1UXBqSFduajZINzVsTVc5TmVwQTAzN1BBZjdKSHZmN1c2ajJqekhuSEZGSDdublhQYVNZMkw2NnBYKzVaM0cwUUZ2eHRXMWxPVDA5M1hOdHB3QllFWUlTWENyWE1BeXMxMnRaWUtOSTBSTzlKNmFTOUNMejBYVWR3dWVYd05GNnZlR0ZsMTRpcE1pOTk5M0hBdzg4UUYwMVJCZDQ5dm9yQkJjNE9UMWh0Vmx4NXgxMzdOQlNMZkN4dUpNUUl3eUR4NWEwb21KMVRnR1dIU05ZR0NpRkVGSUFrNUNqVXlFYkk5R1kwWUNKTVJMOExqQlNnSmEyYWFtck9pTnN4V05HRWthVFpLOHFuYkNWSEEyQzZnajVJeWJQa09uWGN0d3dvbzRxZjAvWkRlVXkxbUx5TXhxdGNRYkNVd1BkUHo5aDlpZVBVVFBOL0ljdmNmYThJOTNhSFFWbHR4NDllTWpodlFja0VqZWZ2TW5xeFJXTDVXSU1FVStEVlZQaG1mNWNORW9SeUxLd2hTRmRtUnhYU1NHVE9ndHhVN1JBMTNYajUyL2V2TW4xNjlmUWxlVUI4NkNralRjdGZwQ1VNbGxMSmJzKzh3c3FJd2JoZHJzZGNSNlFjTFV0Tnk3Vy8xU1ZUejBENzExT000bzUxYnVnaFdFdlBXcUtJSmI3VE5uRlUzNGdSdHoxc25NTHBJdFdLSXlBUEZxVFlxSUxIWDJJREYwdmxuWktJakJhSUdPZElFd0RSRGxYVmlzMUhqVkYvYUdoKzhRSzgwaE4vWjRGNXI2SzJSOC9aUE1QYndxb2xNYzZkSTZIUC9pd2VBbys4UFNubm1HOVhsTm5LSGxFOFpxRzdYWTd6c0VVTWkvZk9ZV0R5N3h1dDVMdVZWbU5VVExpeEE2SEtmZWJVdW5YcXhWOVA3QnNtakcxckcxYWdnNHNGZ3RVekRtUWs3ekc4dnhUZm9kSzJRWW9aM1l4Zm5aKy96NzBXbUxrSWU2UXd1SUpuTmNhNVhmVDRJcW9OUEIrZHpiR1VEYnQ3dXhVU1FnTmVXdUxsNUZrTENXaTZMemc2RG9icGlybTlLZ1FTREVRazg0c0pVMUM3d21meE9VVGFVaHNmdWtXNXY0YWMyZEY4OTRGNFduSDhEdHIwUEw4cytPV0I3L3pBWlJXZEtjZGozL2ljY3hnOE1FSmlUTVhtSmlTTFVjRU5BdmMxR0NXWjk2cCtMN3ZjVnJUazZpTXhockJWRWFVUEtlbmwyZVBNUkJpNFBMbFMwTHR5dVNPcG1sd3lYRjBlQ1R6cC9SSVF5OUNXcnlKTWZrM3I0OHRibHl4OXN2Wk0wYjJ4bU5oaC9NWHlSNnJoeWlGVVVwY3RoQWxNaGhTWnRtcUVaeVp1all4K3B5ZXBIY3FPd2RTVUZwQW43b2lKTWN3T0xwaG9PdGNCbzVTTnZveXVoZ2hlRG1PaEtNWVFFa1dNT2FDd0ZRUTRDcTk0dWwrNVlUNW43MkNxalR0Unc0SlR6cmlTd0VmQWcrLzUxNHUzWGNNQ3A3NTNITmNmK0VtYmQwd0RQMlkzRG1kb3hHQUthNjAxaVN0YVpUQ0FGNGJ0aWFNODF0Y2JLTVNMa2x1SVdySHF5VFBhYm0wem1SUEphRFoyZW1hYTY5ZXh5aERERkd5b0tPU3hKeHNZQmFCQkhZaDdKeVBXUXZyS21mcnhnQlJLTXNUUUhBY2pJeEhveFdDNzFjVkNzRUtZZ2dFbDNjWlNDZzNLWXd5WXlDb2FKVVN0MVlZWW5KanRrNUk0Z3ZISk9SVHJZV3ZiNnRLRWtSeUpDM0VOR3FORW5GTEtFSktBbzQ0eitBZENVM1R6ckc2a294ZG83RjFoZDVvRVpDVTBFYmhQN2RsZUdoTjgzMUw5RlhMN0U4Y3NmcTd0MUNieUFQZitRRExLMHRpVEh6OXR4N245TllLTjNjNFY0OSt1ODVnazUwWTB1VW9NOEIzM2pyaC9iZE91ZVFjTjZxS1R4OGY4WVhEcFhBdk1xbVdLQ0ZsTmFhZ0ZQdGhQd1l6ZW1wMWpmZUI2OWR1U0xKS1FyaUZQakpyV3FxcUZvM28zRWkvSzhSVm90Ui9DRUU4S0t1c0lRVUlQdUhjZ1BJN2lZR2MwWk1ZVllsUmx0clcxRlZOVzdmTVo2MUU4N1piVWtZRmRRb2pMNitxNnBGYmtGSWExYmpXZ1pSTVhrQXluQ3FnaGtaMmhRWjhTcG1qcndrcGpkYSs3SkQ4TTRtSVJBOEhON0RlZHZJWlk1aFZCbVd0Wk9sWVdTanYzR2c4a2pUOXYxaGpINjB4RDlUWXR6YVlEODNnTTU0SFAvUUdrdFdjUEhXZEY3LzZFaW1EUkYwLzRFSmsxcmJNWmpOUjIxSGlDU0VsYkYwVGpPRUhicDd3UTlkdmlwWlFpbnU2bmoveDBpdTBNZkNiUjBzQmNGS21oR2UxTExqQ2JSVFh2SU1WYVhEWUJJTVByRGNkcDZkbkRJUG4zbnZ2bFp6TVhKS243enFDODZQS24rV1NQYVJFditubytvNzE2UmxXVzROUjBLOEdZWm11MStPSFNoVHBhSG5BZk5aS3RDbWZKY0lYaEJCM2hSbTZycVBiRHZTRFIydFJpZlA1ZkZLTGh3bTJzQlc4UDBmZTBFb0tIdVFRc05HS3BIV08rS204K0dxSHlJK0xMd3pkRXI3ZDlCMDMxaDB1UXFqbTZDWmlLaEhrdG0zcHNzVmUwTXVrRlBFa3N2M0ZGWXVmT2lZZUtPNzUzaVB1dnhsNFo1L2cyVnQ4OGNzdjh0TGoxOUJHR0QweFJsd0lBanJWTlJxSWZtQ2VYZDZtcW5sWWE5NTN0Z2JVeUpwT1NxRlQ0bjAzVC9ocVcvTnlYV0Z6SkRhUUllMEpnSFkrTnVNTG15bVRhc29SdEY2djZmdGV3cnQxTFRDMHRYU2JEU2xJOGExVHBibnp6anV6QVorNGNlTUdDc1FHZ0oyUlY1Q3JNWGZQKzF5WlEyTzBWTTJZb29jNVpYMVVmNVd0R1laQTZJUXFYVkxEeXJtbmxNSmFreTFkQ1JxaDFaajdUaFQzY3R0MTBQY2prWEpxRll2bVZ5TXFTNzUzN3p3bUR2ejRXd2JlZG9laVY2Zjg5blhOYzBNbDUxMnRzSFdMcVJ5REYvNUJBcEtHNGJHQjhQRTFIM3JQRmY2ZGp5ZmU4bXFDdi9UTGJOOXdpZTdoQTM3dHFPSGF0UzFXdzJHQ3ExcHpWMHJjMHcvY1VWVWNPcyt4Tmh4N3gySHZ1UlFUTTNtY3ZTc3F4UjNPc3h3R25zczVCZVc4TGpiU2xLSldvcDZ3NzVxSEVNYXFZWVhKZk5kZGQ0M3JsbEppdmRuZ2g0SEcxRnkrZkVsY3hFeHBjODdSYnp2QkFiYmI3ZWpIRnZlbXBBN05aak5xVytXOXB2YVl3dWN2cGNTQ3I1b0tQZlJDWDVxNE5EdE9uNkJoMWd5RWZJYkhITXp4V2NVT2d4dkxxNWxjV3MxYWs5MlpzTk1FTWpNNEg3bG43dm5wNys3NTBQMEtYU3NJRy83TXB1ZS8rRWJrTTdjdVV4bkZRYW80TTVhdTBUbUROMlZORm5uaytveS8rTjhHN241dXkyQVZOSWJtNlZ0OHo4c3JyaHdkY3QxWjdsS2FRNjJwbEtJQmFoUjFpRmlkS1hYNXVDU0JldzJJdUZlS3JmZjAzUlpUMWFPZE5JMjJsaU9YbEhKeGpOdHZWaXF1TkUyekIwUU53OENOR3plNG1YZTVXaXdsTXhrMUpxZW83TVhaWVJqWWJEWnNOaHVVa2lvV3M5bU1vNk1qWnJPWmNNMHlBVlNyWFpadmtjanpSb28xMmVDeUJtM015QUdjU20vQnVQdkJNNFRBa1BueVNpbTZZV0RyQjZLUzJFVGJ0a0xFVkJybkZONDd2SGVrdUF0QVNZV3N3RSsrdmVON0hnR0NBZ2VndURLUC9QVGJYK0dKMVNsYUsxUU1xQlRRS2FDVnBGa1pCZFpHcnI4VWNKLzJETGFvRmtoV0UxemtiYmNpdG03MkZtRDY3QU53UXVJV2NLWTFKMXJ4aHBDNFB5WDh1SDJnU29tdk5oVXZhTW5ySzR0WTZoWVdJUmczbE43bkxrNi8xM3RQMTNVak83bFkvRjNYY1hKeWt2TWJGalFIa2diV242NFpOaElYSUFOMTl2bm5ueDh6ZDBydG1vSS9GeENDbEVnK0VKTXdrQW1KVk1BZHBZUVFoNmlxcWlwQWhCMlBrRks0WVdvbEcyTlEyZDlQTVRBRXo2MWJ0eGlDUnh0RDNjd3dqYmlDSm9yTEo1ODlud2NvTnNKUmsvandBeDM0OHpvWEtwMTR5L0U2dzQycW5Cdmo4UUpJcmFMSE5yelltUkVTSGk4RklTWnVoa2dQbk1iSXl5bnhTa3E4SEFPdkFDY0tZdE1RcXdwdkxZTXh2RGtsZm1MYmMzZU1OQ25obE9LNXl2S3JSd2QwdGNYbWlPTVV0Q251ZFJHQTg5SFY4bnNSZkFIWlZxc1ZOMi9lNU5sbm4yVzlYclBkYnJsMjdScmRkb3RkemdnYWJyeDZqZGoxbk4wNjRlejBqTlYyeTdidlJRT1VtOVoxemRIUjBSNGhRV0JXb1V0Si9sNVg1cDBZQTBPMzJRc2lwWXpDeldhek1acFhvTXcyVjdBY001Q014ZytlOVhiTDZYckZ6Wk5id3N5Wno1Z2RIVkhOV3FGWXBWSUxUemdGSVFnZ1VvSlNXaHRKdzY3aWJ1dnVMV0RpZXRmd1N0K1FrbUx3Z2Q0RmV1ZHhQdUdUWWtod1lPYmNPVFBnM0o1dzZKUzRjYlhtcnp6OU1pOEh4YmJJajlhNS9KeW1xUzBIVFUzYnRGUkdLTnRQa1BoYnRlWGRnK055ak53d21pOHQ1NXpXTlUyK2Y5a1V4WWlkb3FoVDlQQWlEVkIrdDkxdWVmWFZWMUZLOGZ6enorK2dZeFJxMmRLc1RxbldEdDA3YnJ4NmpSc25OOWxzTjFTMXhSWkF3em5IY3Jsa1BwK1BFbGgyN2ZTTFM5NmI5NTYrNnprOXVjSGg0ZUhJY1lQczVSdURSRHFGUUZLSUVOT0lsQXkrNDJSMXhzbnFGQmNrdU9SVHhMYjFXSXFOVE5ISzRZSlIwRklTT3BvMW1xQm1QSGFyNVcxWHVuM0xTMEhuRlQvN3hMMThjWE1uaHNSNjAzSHI1SVJiSjZlc05qMHVRaGNzNzNsYnhYOXdhRGgrZVNCYTBSUXFKQktPMHgvOFFab3Z2TWpxZC83VldHZEFJOGVIVVlxbXNzenFtbG5Xbm9YL3NDTHg2NDJWUkU4U05WQ0ZRSm9jcGRQZGZCNUczK05pbnJ0S2VMbThYbm5sRlVxaVQ0eVIrV3pPNldxRkkwcFJ6eUZ5OCtRV20zN0RmRDduK1BBSUt3a0xoa3VYanBuUEY2TmtGVmR3R0FhQzgvaGg0T3owakZ1M2JvMnMwKzEyaXg4Nm5ubm1HUTRQRDNuMDBVZVp6V2JacUpQeXBTWGR2QlNnQ0RteDQrenNqR3UzVHJoMjZ4YlhUMC9aOUZLK1JGdEQwb3FoSDdER0VraW9tS3R6cEIzMWF5U2hlRG1CMXNIdzN6eDFoYjkwK0NLTGFsSmdTQ2MrOXVJQnYvSHlJZk5sZzFHS1hpdDZlZ2JWMHdXZmt5WVVUNzI4eHYzVSs5bit6clBVajU4d0Q0blZ2WE91ZjljSDJQN1F2OGRQZm8vaDU5eS96NWMrL1RGc1ZlOHRSb3FpK2ZaeUxKSUlnUTJlbENJQ3BFb21kRm44QXBGUGtkZnpPLzIxcm1rSWVvU1dKMlNVVTM5QzM1MkJWdHpxRmZPZ1VaWEJMR2M4OU5CREhCMGNZbU9BbzhORERnNFBnUWs4YVF6YmJzdXRtN2Vrd0VEWHNWcXZjM2d5c3QwS21FRDJpMC9YRzNSVjg4Z2pEOU0wTTFKSXhDSGlla2NNa3FidHc0YkJDOXAzY25iR3lYck42WHJGWnJNV0tRMDVTWkxFeWEwVEtsdWhqU1doV0cvV2VEY1F2QmRxMlZCUU9DbUFwRlBpRTY4cytHdWZ1NHMvOWZBTjNuTFVjMzBMLytUeGluLzYwakZwcHFnVTFKVWxlY084clhGOWpXczY2Q1BiSWZDblB2QUdQdlNCTjNMNnpnZjQ1WC80ZWY3eHIzMk5vWFY4KzVWMzhzSFovVnhxSFgvMkwvNmYrTm0vL3BmNTVoZC9sM28yeTBlaEFGRE9PYnh6b3dCb1ZRdzVnL2M3eGxDS2loaDNwMHhLWXpCN1hQanBtZjk2R3VEOCs2WmVGeW5oVXlCcDZQckUyYTAxaDVlT3VIcmxtS09qSTVxcXhpNFBEam0rZEVVUXN1Q3BtMnhwTzAvZmQxeTc5aXJYcmwzSE96ZHkySWFjN1RzTUE4R0xwdEREUUh6K2VWUlY4L0Q5RDFFYjhUbXR0cWcwNUdSR1IrYzlRL0NjckZlY0RoMWQ4TmkycHJMQ1BKWnFYejJyczFNdUhSNVNIN1lZTk5FNXZFdVNZdTEzRWJNUUpJUmJqb1JQdkRMbkV5OVZiRmVuOUlQSG1aYkRBOFB4WE54TW81QTZnVEdJaTZTRTRmdmdIUWY4NmU5OUkxb3JHcVg0K2NkZjVwTnVvSHErNTdIL3gzOEtxZVdEUC9palhMMzdmbjdxTC84TWYrYy8rZmQ1NHN1ZkZVMmdGTUZIdHR2dEdQeVJ4WkhGVFZIR0hYTGNwRzFiaWZvaG1rMmJ6SERXQm10TFpkSTRmdjc4VlR5S1ZGekUvUHpGTGlwR2Jvb3hjemdTcXo3UWJkZWsybEN2Vm1OWkd0dk9CVDBTNG9haG9tTGJyUmlHbm02ejRkVnJyM0w5NWkyYzkyWElFcTFMU1dqYlJvdWFWdENseU5ZRitzRlJ6Mm9xVTZOclRkY05Jamhlaks2VHJTeisxblhZeFl6YWFPcW1vdXQ3ZlBKMG15M0dHcGFMR2ZPMmdRU0dHWDZRRlBFeHBJcksveThUazVDYTVKclo4cElBTWFSY25UemkzVUFYQWtPM1plZzZvaHVraGs2Q0gzalgvYnp0a2F1QTRsZCs5eW0rK3ZoMVpsWXlmVGJyVy96WC8rWC9tZGw4d1hkODZLUGNjYzlEL1BuLzlWL2piLzlmZnBxbnZ2WkZLV3laWUxXUzh2VEZmUzBzSHAvVHh3VHJTQndkSFVuVmxDaHNwVklFMDlvS1kyd200aFJNZ0QyN29Ed24yUUNXWXRoaUg3bFNlTEljQ3lubGN2RUQvYllucW9BZXR0aVRXNXl0empoY0xySHRmSVl5T1dzbkNaZS9hUnFpSDNCaHdQa2VyUkpKZzlLV2xKUkFyMGhTUmxUaWRxdjhjOVNDZGtXUTJ2cDFpelpidExMMHc0cDFjSFF4UW1XeHFlSEtsY3NjTGhja0pFNndtTTNZbkswNHZuVE00V0pCazdPU0RGRG5VdStWcllpK2tFWWxrRFJlU21vSkZ3Nml6aFhCQ1o1K3U2SEx4cGIzam40UXl0VGh2T0xQZi9SdG9CWHIweTMvOWNjZnAvY1JVMHNLbkRLR3M5TWIvUHgvL2grUkVuekhoejdLM1E4K3lwLy95Mytkdi9NZi96VFBQdjRWVkxibXkxazhKY3lPS1hONTE1NmRuUkZqWkxGWTVNOUlxcnRpNXdxSy82OXdicmdOYnlrcUlDb3lMVC96TU1oMCtwU3JuQ3RGWXkwV1JSOGgxVFYxSXhsSXI3NzZLZ2Z6QlhhMVdnbTZoOVNOTU9pY24yNVpMQlljSGh4d3R0cklyamRXUXIyVHNaeEhxTXFaRktQc3hwUWtxSk5pWkwzWjBCTkpsYWF1R3k0ZFgrSjRzV1RlMVBMdHpZeTVNbXpyR2N1alE5cTJ3UnBodm1JamRRbDAyQjRYeGJBa1pXRXNFNVFaUGRQdzcraGlqVXdpbVNpVmhNLy9JKzk3aUxjOGVBbUEzLzNxeTN6eUt5L1MxSmFnMHBnUFlHekZ5YTFYK1FkLzZ6K2libWE4L1gzZnk3MFB2WW1mK09tZjRXLy96Ri9paFNlK1N0UE94dm1RRlBjMExzN1VkWnU2M3JBekJDWE5ZRkxITnlPd2hYanpCNWdFZTNDN3pvWmdaU3ZxcW1ZK200RlN6R2N6RG1ielhRbWZKNTk4a3NFNUxsKytMRVlMU2RTOWQxeTZmSW43N3J1ZnMvV1d6bnQ4amtLcDdJZW5JQTg0WmIxNDUramR3S3h1aVNIU2J6WnNodzZmSk1hdUtvRnptL21jeThlWE9HaGE1dFppY3dqMW9KN1JMM3VVTVdPOVFlOERTUWVhcHFacEdqWjJJOURiNjF4VGtzcjVud3NhT1Y4c1dDeG4vUGozdlFWZFc0SUwvTzEvOW1WY2tPeWJLVlVCd0JqTHJlc3Y4L04vODYveUUvK2J2OFpidi9ORFBQRG8yL21wdi9LZjhGLzl0ZjhWTHozempUMVgxMVExSkRVU01OSzVzYTF5d21ZcE1xV0w0NkoxanFKS0ZyWXhOcnUveFZpOEhldVlic1NRajR5b2pWUk56ZmRxNm9iRHhaSlowMlQ2V0lYOTJqZS93Y25xakhlODR4MDBWWVd2TFQ0NmxKSmM4cnZ1dlp0cTF2SzFiejdCNlhvanVmdGVFVXRKdGhoUjJtU0xNN0hhYk5nTVBYWFRFd2R4QTRjVWNTU3dCbVdGb2pYUDNNREdWRFRHU3BXUm1LaTFJU2hEQ0ZGWXY4WktsNUNVQ0xuT3NBUTFkbkh6MTlvYUZ3bEJtV0E1SXpYZi9mWTcrYzQzM3dVS1B2bmxsL2pDRXplcEswdmtkdU1Md0ZZMTExOStqcC8vei80cVAvVlgvanB2Zk9mN2VQRE43K1FuL3ZKZjV6ZC8vWmU0ZXVVS1dodSsvdld2OE9UblAwYjBBMlN5MTI0OFFJckVRV29rem9kaFpCY1YrTGVxc3NDM2t1Z2gwZThvaHA0dXp5ZThDM0pZVEtrZEpoQkRRSm1FTnhxdElscEJrOFBYZFNtSWJUUjIyM1hjdkhYQzE3NytkWTZPRGprK1hMSmN0RFMxTkNFQWhHa2p5VjE3a3oxMVYwVDlCRTQzSzU1LzZTVk96MVpqdnlDbnM1MVFpVVFhcmJIYVNDVUxJMFdoVll6RVhLYkY1UnA1MisyV3FxcFlMSmZVVlRYV0doclB5UW4xYkZxWVlUcW04NmpaZEtlMHRlRkhQL1F3VldOeFc4Yy8vdTBuMlE0UmF6UkRybkZRR0UwZ1NMSktZSnFXNjY4OHg4Lzl6Yi9LVC83MGY4eERiM29uYjNqYmQvTEFXNzZEV1E3Um5weWQ4bHUvOW92OHlzLytER0hvOHZlVzNTc0xGNk1FeU03OEJ0MXR4KzhyWmVXVkFtM0FXc243RStxNlVPTkxKZlNRNGlTU3VoTUtwU0FvaFVFUms5eW9ybXBtN1V4WVRkNVJ0eTA2a3ZCUmF2TTRMMnlhM2cxanJidCs2Rmx2MXZSRHoyYmIwZlU5L1RDTXhZZW1WMHlSOVhiTHFsdlRSNDlYQ2E4U1FVSFNTanFUMUExV0daUVA0SUlFRjJMTVpWa2QyKzJXYnJQbDFaZGY0ZnExYTd6NnlpdTg4Tnh6dlBqQ0M5eTZjWE1NVjVjR1VPV2FZdWJuTmNCRmx3dVJkejV5aWZlODZTcWt4SmVmdnNsdmZlVVYycVllamJDTEluRGxPNnFtNGVYbm51RHYvMmYvQjE1OC9tbFJxU294ZEJ1R2JzT2lxZm5vai93WjN2RjlQd3BKdEtRMnU1ZFN1K3JrS2NjYVFreTRFT2tHUjlmM2RMMWpzKzBaQm9kV2toeWpsUm1GS01ZY1VzOXNyZWtZUzZ4RG9DamtLS2dsUjlCb3c2d1JtTjJpMU5oUlEzeFlsYWxYY3Q2czFtdmg0dzBEMjI0N0VnQ21rNTBtT3l2RUlGV3lyU2JvaEpZYXpDaWptYmN0UkVuM1VrTWc5bzZrRFQ1RVl2UVpXWFFNZmMrMVYxOFZyWlBTV0pUSlpHYVAwWHFzaEZWeThRdFRlYzhnbkV6SUZIbUxVVWlZUC9MQkI5R1ZnWmo0NVUrL1FFZ1ZiYVBvaDRTTGtySzFNd052djZxNjRma25IK1BrNXF2Yys4QWpwT1RIdndtTURoLzRZeC9sOC8vczV6RzZxR2xWQnJVWDV4OWZNTlpuVEJHU2FsQm90Q29zWXdHU3lHeWlGTVViTUtnTEJWWThOU25scDlqeEFwT0NydSt4MDhKUHh0cWN4QkM0NVhwaThHT29XSWdoY2RjRGlOdURFb1hzVWVYN2xYS3hoRWlWRkxXcGFLeFV4Slo4T1VOU2taakNPQUVscXdqRXJ5Mlp5OVYyeTJ5eFlEYWZDejM5M0VLclBLSFRrM3RLckpnV3ErN2R3UHZmZkpYM3ZQa09BTDc1d2htZitQb3REZzhYVXZFclJyVDNNc212c2ZqbDB0clFOczJGZjFQQWN0N2VScmsvYjVQc0NVRDJITHozOUVpdWY1V3hnU25UV215ZmllYlRFcFdkZWdKN1kxR0t6WFpMNkIyMzBrME9qZzZGSmplYnpjWXpSM3J4U0gzYnd2ZnYreUhYdEVsaTdHbTlOeW1qS2tPcWV6VHRmS1JNanl5WGpKTlh4bkF3eTEyeEtuRXBYZlNFa0lCSWJhMFVMVEE1c3BnTkdxMmxNSkx6SHJaYlNZcE11OFNUTXJtN2MzWi9Vb3NHS0huN2ljUVB2dnQrRm9zR1F1UlhQL3NTMjBFYVhXbWtjT1FRSEs1enUxMTZRWkN4Zk9kVHp6M1B3Mi85anR2K2xrZzg5ZlRUdHgxTlpYeDdjM2crMUJzaUxqcTBobm5UeWx4TUpXdnkzdGM3Nm9yZFFwSkUyWUJnME52TmhxcHAwRlZsbWMzYWtTc0dpZFZxbmM4ZVQwelNBaTNsekQzeDdnMXg4cSs4TEtacW1jOFBXQ3dPcUNzNVMyT0kyWGpyMFFvcGZWWlZWTG5SUWEwMWxUSFV4bExyWERLKzFDcmV6WkJNU2hRbTdqQTRxUkpDTG9tVFdjSzNFeWprdGZPdHBZTEhtKysvelBlLzYxNUlpU2VlUCtXVGoxMm5iV3JxcXFLcUsrcGMzNCtVU2d4eU9wcTlTeHZEYi82VG4rV1ZWMTZXNnA1NXNhM1d2SFN5NFRjLzh4bHNwbldWbDFiQ281aUtoSm84WjNuMlNNeEZvQnk5ODFMSUloTm54dytwOHU2THhwbkdEVWhNWXduQWlCQndjMGw3eldJeFp6R2YwYzRhYkczQldEbVhRWGE5YVVoVUtOMkFxa2xVUUVXaUltSUp5YUNybHNYQlpZNk9yN0pjSEdKdExhckxlN2JiRGR2dFdsaEZnRW9SVGFLMlJoWmZHMXBiVTJrTlB1ejZEb0cwV3pFbU41R1FuUHRJTGhyQkxoVmNLWTNTQnFYa3BYVnBwcURSMnFLVUlVU0ZENHAvODMzM1U3Y1dZdUxqWDNxRkc2dUJXV3RwR3lsSXJUV29qSXhPWDJXM25YY3BYMzNxcS96ZC8rdi9uazkvOXBQMFRsalB2L3ZzZGY3dXA1N2cxUWUrQis3K05sUVFMbjdwUlRTK1VMSkxpMUJNVmJxU2NQalplczNaZWszdlhLNGhuQVE1eks5RUpLVkFxVVpXZWl1TjQ0NHhKNTVLbGRLQU5OeXcxbUtQamcrNWZPVjRyT2R2ak9iU1pUZzVPUm5SSjF0WDJLYkZZakl2ZitMVGF0bUdUVHZuMHBXcnpHZE56bGdSL243WDl3eVNoWXBWZ25tbjZQRmVhdWVwckZ0S2xxQ2FUbkkyVUl2Qmw3UVdGcStDWE53NEh5K1RuVFRaUlNVcVo0d0ZyYm43dU9YYkhqemdBMis1QWdsZXZySGxYM3poSmVyY3BrVWJoUTZRa0R6RTE3djJoRUFwbnZuaUovajViM3lCdGhFM3NIdjdqekM4OGZzeEIxZUlIL3h6bUkvLzM5RW5MNUMwelVHb1hRQXJGbHRqWXJPVVM1cHlST2k3VVNpTWxaeURrZUZFTmh6VFBuOUFZZ2lTck90N1I2Y0hTU3d4d2s4SU1XTHZ1dXV1a2N6aEoyZHFqRktYZnhnY3RxcUVhQkJXWS9oM2Q3WXFiR05wWjNMMmw3WnFrbEFpaVpORFZXSGl6b0NKS1VId3hEaGg5ckt6MW5lV01qa3pPRGVReXVFN2xWRkRJakk1aWR2TzBCM3J5R0MxNWdmZWRTYy84djU3dU8vT3VTUWhBSi85NWcxT041NHFHM0ZpVisxWU9OL3FsWkFrMU9nR05rTXZOTmN2L0FKbWNSa2VlRGZwK0Q3OGUvOXRtay84VitoaGc5TDcrWUpLNWVUUWlTMHdGYlNDYzJ5N0RwUTB2NndxZzdFU0x4anZNOVlsVEhzQ05sTFpDeTlEbTNITzlNSHlJTGRMazRJTnMxYU13c1Y4em1LK29La2xDZkhnWUNGdHhxd1VISzRxSzVRaWE1alBaOVMxM1lVdWs2Z2tVbVErbTNIcDBqR0x4WHcwNXNiVHFreENmcFZRcWR5dkZqN0FCZjc0YUFtZkk2ZW1TWkJpNUIwcXczdmZkSm4vMlE4OXduMTN6TUduZk1CR1B2aVdLeng4OTNLdnMxaEpYUG5EQ01EME81V1cwdnZLYmFrKzlmT29hMDhBaVhqdjIzSGYrYWRSVlR0V1ppOWovNFB1V2E1U2NFS0Fzc2o1NCtpaSs0Mnd0SkgraDZYU2FqbHFkSW9SUDBqbXI5V0dwcTZaTlMzejJaemxRa3FueitxR2VWTng2WGpCWXRFeW0xWGp5NWhFU280UWVxUmxoMEFQbWtTbE5QT3E0bkEybzYyc1JCVlZ5cWhpbHM2Yzh1V0RWT3l5dVpsQjZZQzliMEdmTS9KUzJ2djdSUk9pRlB6eGQ5OGx4OUtreGc4SkxoKzNmT1E3N3M3a0RMbEhLZFVhb3hwZHkyOWw0Y3UvTytFMDZQVU43S2QvSHJXNkpndjR5SGN4dlBVakk2UDVJdUJxU3ZFcTE3UnFpUVMyZGhYYkxrSTR6M01KcTV4cVh6S0UzVEJJaTVyWlRPb0VGdlV3bFpacFhmLzVJcUJYRmQyMTZ5d1dMU25XMHBjUFdLL0ZuUkJrVHVyeU5NcFFhZUVYR0dOd0E4QWNra0VaU0RybkNTU2hlMEVCUVFLWXhHd3hvNnByekRCa0EwbUtVU290ZExGeTdSZ3h3aklTaURTaTBtUkJVTng3dWIxNDViVGkzc3N6RWxCWnk3YVVaMG1NNTNTZTBXOUpDRzViVUZOaHJqMkordXcvWXZqZ1QwSTl4NzNsSTZqMWRhckhmNXVFdWsxb3B5N2hlY3BYSWVxV1JUNC9ENmo5eUtPby85d2pJT2MvSEJ3c3VmZnVlM2p3d1llb3F6cTNqSkZ2RzhPclk2cDRMR25FaW9QNUhIL2swRVRxcXFiT0VhVjRkRVRTVXVDeHJpeTFNalJhVVNuSkVZZ3hvYXpCdERVcWlIVTcrdFFwa3h1U09LdkdpcHRXY2dKc1piR1pQMWNFQUZPc2YvS2huWEJweUsxZ0lZVTRucGt4UnJSSlBIZDl3OVhqQzRRZ0psNjRJZEJ5S2Q4Kzdpb2xxZXF2alFQZUxnQzNIVmNSTWZxZS9neDJmZ24vN2g4SFcrUGU5YU80cyt2RXB6OVBISkZWY25jdnZTY0EwMklSNVhmVG5iKzdMajRLcG0xL1p6UER3Y0dTcTFldmNPblNKWkowSVNuYy9rVDAwdEVpRmVsTGVYR1NPSDdIaXprbUJlcE1BeGRta0tZYnBNZHZYVmRZWmFpVkVEZ1VTVnJKNVVYWFZtZTNMVThhWlBKbzJHWCtWQmFUQkNuYzVQdU9EeXk5V2NtZzF6anhhZEtScTR5OS9DMG16My8zeWVmNTlvZVBwVVJLRHZKZ05hZW5QZi9pQ3kralZjcGN3M044ZkMwVnVsTXFSOWJ0aTE0VzV6emFCNUNVMkJ0SkcvVFgveFY2Y1lYNHRvL2dtMFBlOU4wL3p2L29ROS9CdHgvVVhQT0pmL1RseC9pMTMvOE15ZStYa2lrRTJHSU1UcjRkMkRYdzBGcUwyM2RPQzhDdVNQZlIwUkdIaDRlanB3Skl2NEJFMnJVcG03QlRZOVlHT2tIeUVkTjdMbGR6S2lPbFc3UXlndUo1bWZSV0s2cXF0SUlSbjdTYzd5VVFkcHU2eTRaYlNVeXhkUVhHY1AvOTl4T1U0dWF0bXlPbEtrMVF4OGxOUnBnM1hHQzRHYVA1MURldTg3ZCs2V3Y4eVEvZXo0UDNIVUpJUFBiRURmN2hiejdMVXkrdlVDVUpOVTlnMHpTRW1PamRNSmFDejlXeGIxdjgwWmg2amV3ZCtSbUlIdjM1WDJCb2p2akEyOTdGMzd3L2NsLzloaEg4K1lFM1BNVGZ1UE1xZitPZi85UFJtajh2Q0x2ZkpieDNxR0ZmS0pwS2NJL3BNVEw5L0pocGxmbVhNUVRzNFZMeTMwOXUzUkttVHlvN1J4Z3pPcE1Mb3cvU3NqekRwUlFBSTRGSjBwNnNDMnNHWXdFcEdtbHJPMDZTTmxwVTZ2VE0wMUlYV0N2eEtwcW1rYWJQd01IQmdydnV1Q0lsMVBvZTV3WmNLSFMwYzlSL3JZakdFTDBYTkNGbHdkQTY1eWZDcjN6MlJUNzN6ZXZjZGR6Z1ErVFpWemVjOVltbXNybnNmWFpUbzZLcUt4WktvM3JSYm1wU1YyZTY2T2Rkem4yNVZLRFpGWmRVbWpoMEhIN3h2K1hmZmUrOTNHY0hpWkZQbnVFbnZ1UGIrZmpqVC9DNXIzMlJLamZ4S3B0bWVxNjduUFpON2tPUTBSTlVTdElGTlFOZ0lRUlV5a2VabHRLN0JUanpRMll3TjVYNHdMZGlrdDdBU0toVlV4NVNJRW1yTmRyWW5jK2UyUUlhQVVLTTBuZ2ZXSzlPaVNwUzFSVkx2Y2paUUVKMjhJTVhkbXd1SmsyTTBqWTJ0MXFScWhxU0haeThaMVpWWERvOFlPZ2J1cjZqY3hGZlhNZGNVVHhtNFNSS2pyNlBVa1FDeUx6RVVybGM4L3lOTFUrOXNoTEp0NFpaMjRnd0ZaOVk2MXo0S2FGVVFBMkNTTWFVSnM4OVdXUlo2WEhIN1FsQndlREw4aVJKWWJzY3QzemYwdDBlWElpSksvT0dEOTU1bVU5L0pkSFl2QkdSVWpoRnQ2VlVCQUxwQUJKMlRiYUpBZkJTYkJ2aEJraEpuaURFMktaQm13b1ZGYWtmR0xvdHRySldmRVB2NlhOamhsblRTbU5vUmNhc2xZUnRsUjlEbFFwNVFLMmtWU3cxNEJ3YVJkMDBMQThQYUdjN1Z3Nmcxd05oRzBtbHJwQ1UrcWFxREl0WkswZFFrdlF1My9lNHpZYlE5VlJLWWRxV3VrcTRLTVNVa2xIc2hrSFlSdEZBcWxBdWtaQjhlNVN3Z3NYSWhLcTJhS09JVVdlc1BlWGFBbksvWFJlUUNLWDhURks1QmwzYUUvemlKYWlzQ2M4TFIwcHBETUtVZjZXVXIwRGErM0hMM2FVellscWh4MklZKys1bzBRVGdYRURyaE1sbGNId1NvN2VBYm9sSUdCekJSMGxYYTF0MEp0UVNlNGF6dFRTTm1xWWtsOWZVc0RFb1VvajB1ajlYRkZFNDdWcHI2bFFUYXVrR2JodXB6RGxOYTA1SXA2eElJbW9JUGtnOWV5VzFha3JCYVNLa0dCbTZEVVlqQ1J6T3lmR2pWYTdZYVVsS2tNdmczSWlsR3kxTnJBR2NrdU5pOFB1UXJxam1YR2dhQ1lxY1R6aWRSaUxQWit5azZYM09YUmVCT3VjemdHNTJBLy9xaFd0OCtJRTdZTUlXUml1dWJUbysrK29KODBxQ1lvcU1tMlM0ZTdjKysyZ2ZNUEl5YjhzbFZCcVVRZGNOcXE3eFNmSTY5REN3WGEreFV5dXpHRE5GQUlweFpaVkdHWExwOXJ4N1ZabjBIU3RuWjhTUjgvcDI1MVpNd2tHckcxRlBYWktzSWhTNDRORkJmUDF5My9sOFBuWWFjODZ4SFJ6ZDRCaEN5QXVlY3RNbDJXazJJMTFhYTNRd1VuK25WTVE2dDJoanlMVjRPZGxDM1pGYnA1TTlMVXh4TzhIMEQ3cW05b0l4aG0yLzVmLzU4WS94NWovNXd6eHdNQmUxSFVYci9iOS83eXM4OXZRVE5GVTFNcS9GK2RHaTlVYjNNREd1NzBRSXpzUExVbUhOWTAydUxaVEx6YTI2am1IYk1mZ2V1OWxzNkhKYjB5bm9NSjJveWRQYy9vU0pzYzJic1FJZ29jbGNHZ2xGSmdBbHhadzFtc3BhYUJxa1paUWkrSUJMRWE5VWJoY2Z4NVpwcFNCbDJ6bE9WbWY0OVJydlBjWUl4NkNwS293U0l5NVZpSFhzUGRGREg4SzR5T2RqN2lYZWtSOXMxQUlxZjUvTHhTOUwvZUUwRVpTTHlCd1hhWVR6Um1LTWtkb3FQdmZOeC9nTC8yRExuLzNBQi9taEIrN2duc01EQUU1dVhTTkVqMVZaUDQxZnN4djNSVURRMUFhWkNzRzBZSFZsTFZacmtzOXRaRGRib2tIYXg1K3Y5bjJicEo5enZzclpSMGJlckxMNVN5U2VrRkxJTGVqS25Pa01yVXFiV2FNdDFpcGNrTXhhRlNNcTcrQml0R203YXorZlVxS3lEU0ZHQnVmWmROS2tzYW9xNnFyQmVUZG1JTnNjTVhRcG9aUWJEY1dMRm1jM2laSy9WeVl4eEVBSXUwYVhCZDVPcVNTZEtxWW8zVVZvbmhSa1l1ODlSUWlzVGp6ejBqUDhILzgvVC9Mcmp6N0szLzR6UDRZMWhqLzl6bS9qWDN6dGE5eFlyV1J1aVNQbmovSWRhV2Rkam5aSWNZWFZmbXlrYUd2aGhJb1hoZytrTGxkekJXenkwbXN2T3FrRVVoa3JGVGxRMldnWmRjM1lOemNrV1FDU3NFNURDRHZjUGlSQ2tOeUNiVTRsTDI1WlVta3MrYUtUcGpZTldnblNhTFNSUmRBVGdjc3djQVMwRGpTMWNBeE1QcDZxV29nYlZhancxdUVycVpqaFlwQWpZU0pBcjZldTVUMWxWKzAwSUZHTTQrTHVxc2t0cG1wMmV1Wk92MCt4cjNYR3paTmYxbGI4L2tzdjhiRW5udVREYjNzcmI3cnJUajc2bGpmeGM1LzZMRVpsa0l4ZDdLUkVRMlh4azhEaVJsQllaYkp4cVNWY0x1RjFoWThKaThiN3hMRHBXZmVCdVUrWnBLcWtSbEMzbGRUc0pnTUZwV3BGcWVaeG5uWTlvbTR4WWRTdUJHc3hHSWRoVi9mZWxZYVVPWmxrdVR4Z3NWemtvaEpheUJja3FaaXRwalVBQ3NwRjVpQkU2cnFSS3BuYkZqY0poaGlFZ1VPcHJEMVVoTTJHSmdqTHVSaTVyM2ROZDNUcGZpTHQzSVFaVFVqc2VQZzdTSFphZ3ZhaXdFeVpzL01DQjR6TnB2N1I3MytSNzNya1llWnR5Ny8xem5md3kxLzZNdGRXSzluRnhCSDIzbW1rbE1jbzJkR2xSdUZZdW1maUtkaW1RUnREM3c4a0g2bTFwYlVKUFd0Skdxa1ZYSFp3S1E5VEZyOFVrUVpHTzJGYVRwNEVoQjMwT0JZNW1MekNNREQwUFp2dGxpSEhvdHU2UnRlTkJJdTBxTmpiczJERnVJc3hqalFxWXhUejJaeDJOc2Q3bCt2ckQwUWx4d3BLK2diWnRzRXJ4ZHIxTktFWksyNi8zalUxbnBRQ2F6UDlXbXUwVmZSZER5bGtLdlpPYUthN2Z3b0lLYVgyNFBraUlPYzFRV1VNWDNqaEJYNzdpU2Y1eUxlOWpiZmVmVGNmZnRNYitiblBmZzZsQ2pIbWZMbmJnbTNzT3BkUGowdEYrUjQ1cUVPS09EZGdqZUY0ZHNpODkyenFTTkpSYklBaXhhVmhSQ0ZRVHV2VWx3R1U5empuaEdOZTIxRlF0QmFqcnE3cjhmTmQxN0hOalNaMVp2ZzY1NlFvMVh4T1ZSb2RzYSttWTh3UnZxSys4ekdodEVGWlE4cGw1NFB6OUdIQTZBcGpLcFFDa3lMSHgwYzRsUWo1WHV0c1BGNEVrNTRYQktWS1BTS0RNaHB0aGI1RjZnaEJ3ckZUSVNpTC8zb0dZYmwzdVVadG94UmI1L21Idi9mN2ZPOGJIcUZwR3Y3Y2U5L0RMMzdweTV4MDI1RUZWTlprcXFFdWFvQzUvMTFTUVVWc00rbFBPR3RiR3VWNWViaUoxeEY3NitZdDZxYm0wcVZMTkRuNWN0ZHAydXlkZGRPK3YxVlZFWHpBcUoyV2dNeFB6d09xcW9yNWZEN1d4dTl5VFlIdGRqdE9YRnZiVWFMSkViRUNSWThGb0ZPQ0NNb29LbE9oa3BTRTFkbDFNekhYNTlVRlNmVFlaRm5NNXRLTU9pTjVtODFHY3VhbklkUEp3b3plRDR6NFJtVXlpYVZPcEtqb0J3Y1poQ3BqS3diWDlOb1p5cmN2L3ZTS01XS1Y0alBQUE12dlBQa1UzLysydC9Mb25YZnczLysydC9KM1B2VnBaazB0UVNtenF6NithOUIxMGVMdmYyZlYxQnhmdXNUbHkxZXdsV1hWYmRuMkF5dmZNeVNQOWNHam5OcmI5ZFBNbUtrQVROMEtyVFZPT1F4MjM5Zk9GYTRWQXN4VUttZXFLa1ZjcjNIZXNkMTJNc0dEWVhBOUVLa3FLeDAwamM0UEc3SWQ0Qm1jeXpXRVJRVW5CQUgwVWVvSzE4ME1vM2M5RDRpTU1QWEJiQWE1dXJoS2lhN3JJYm1SQlRTdHpURnFtNXh3SVVVYXBUaW1xbXNrUVVQUkpRamVsNU5XRExLSlp6QWVrZXExQ0NXNVBPNDR0NG8rQnY3ZVp6L0hCOS93Q0xPbTRYLzRubmZ6cTE5OWpPdmJEYlV4STVQWWxDT0FuRTI4ano0emRXbHRaVGc0T09McUhYZHljSEJFU0lsYlEwZnFPam9WNkpOSFg3bmpLcGN1WGRxcmIzOCtyRGxLZERsM0prYmlGT2tDSk5pZ05JSVNHblJWU1NxVWtiekFkakZuY2JCa3Zsd3lYeTVJV3RGNXo5WjVQSUN4bUZ3YVJsdXg1SjEzMHZkbTZGbXRWNnhXSy9waHdIbXBwMmRzUmQwMk5MTldQb080a3pvbUtoVHpxcVkxbGpZbnBWVEdTbU9LWWxpbkhldFhFaXN6ZnBFRWg2KzBvYllWYlYweGF4cmF1c0pxaFZIN255MExQL3JpS1kzMWc2ZXZsQ0hxOGdyNWV6NzMvUE44L0J2ZkFLVjR4MzMzOFFOdmVaTUFhTm5RTlpsRkxDOVF1WGl1eXZaU0VYdGhSRnNXeTBQdXVQTXVybHk1aWxhRzdUQ3dKWEttb1U4UkQ5aWpveVBwZjN0dThhZldmaEdBY2dZVk84QWFpK3ZGR2krRkN1dTZGdWFPRWhPa1ZNWlFSbk53Y0pEai81RjJKaGt6eWlwc1o0Z3BZU3JwTWlxSkg2S1JmSkNXOWk0RXJETFpjNUFBU0tVMUdJMnVhbkdGdEZRRVYwT1BVU29EUk5EWUdsZlhzbXNUNkJUcFVzSUZkcDIvMllkWGkvdGFMUDFSQTFiU1ViUnB4TFB3NTZEbWNmZkxwQW15bVRHVFJDYmNabGFrOUR2SWdTWUZaMFBQMy8vczUvaGpqejdLZkRiamYvNWQ3K2RYSC9zeUs5ZUJhb1F3TTM2UElJTEM5aEZ4bUo0eXhoam1zeG1IUjBmWXVxYmJyUEVxa0JRTWVEeFJPbzlKN25rUTFhMzJ6NCtwRDFzbXBhUlhUZDg3dFliUCs3M251VzExMDBqbjdjTGExU0N0emJyZDRLMGxrMzMzVldwRzRzcGlWSFdOc29hbzlPZ3FqZCtmczVETGhCZE9YSlZrMzVrWUJNOFl5OC92bnB1VXE1TEhuVkUzMWs0MGFxeDBXcDR0Rkk4b1gyTlRCaVVoWVQxQkdhZEc0bFRnWW93WTRMY2VmNXpmZXZ5YmZQVHQ3eVNaUi9rZnZPY3ZjdEp2MlhUZjVQZGUrQnd1UmN6azg3SW0rZVNmd1BKVlZiRThXRkxWTlc0WXBCMjlpWHZkM1ZCZ1M5blE2VUNtdEtUcFlLZjFBNVVTQ0RlR1hUQmlkQjBud1pXaUhaeDNJNnBZM2lmMzhoUXFkb2hocnlsMWpHbDA3UmdHNFMxbUFFTnBsWk5GRFQ2eEk1bG1ZMnlzcHEwMXNlOHcxc3BreElBT1p0UXVGd2JsQ2hJN3VWOUthV1RXRmxaMFROTFN6VGtITVk1TTNmTCtSSUxBQ0lDZDMyQVhXZTY5Yy93WG4vZ01kdjZEUEhaOXlYMVgzOENEV2tIOFl6eHcrZHY1MWNmK1gvUytaL3JSL1RWTGsrb3VoMEFhQzBlV2pPOVVRQ1hBcnRjcmpOS1RCZGtaZmROL3g0ZktDNXBTa3JNeU1LcitrbVNhd3E2T1FBaVNlcjdkYm9TWE5wK053cVMxa1NhTklUSUVUeDFMN2xwR0hFbG9hNmhuRGQwZ2FkSXE1S29YVFRNaVlDcEkvS0RzV0dzdG1vUXlSa3JONThKU2RWWGhnaGVvTjFxczk3aXdTMHNwZFVabGg4VHhXTml6NEJVb25UQldVeVdEVWxMb0dlOEF2eThFNVNPVDFUb3ZCT1VhT1l3cWNlZWxkL1BZaldNaW5oU0h6R0pUM0h2NS9iejNnY2Y1K09PL2daMmt4b01FNmpBcUUydHFLZlE5bjBNaXA1cDNZQTI2MHRLWnpDVEptZWk2Z2JhdWJsdnM2V0JINUNxN2hjVkhGOUJuMHB5eFpBVmJOWmFTQzE3SUNFM1RqTERwam52bkNSRkNVcmpCczE1dGFlc1pxUVZHVTBlak1CaGpzWFozM0JTTUlvWXdlZ21KaE5LSnloZ1MwajVXVzRzTG5zRjdURjFodlVQN3ZCdXpxeWV0MnBLd245SXU1VXBGaURGSTY1Y2dXa2JyM0JCYmFUQldqQzhiZ1JxTnd1RWttYmJBbWFvd3AxU3VTS2F6YmFCSEUxNGNEMDlNbmtEZ3ZxdnZKZk5kcHZxQm1CU1hsKy9BcTMrZU5VQlJYekpIS2tsM3RNUERRNXFtWWJWYTRYek9wd3llNkRRbWFJelZxS1JCZzdVWkFDb2RLczhYWFNpWGxDMlJFcWpPdVpIcUZId1kvZEdxa3Zaa1Zwa1JudXc2S2QwcVhhNGx0bDNLeG9yYWtoM2pmR0J3YSthTE9Rcy9SK1dJWXRsMUVsTXF1elZ4dGpyRFZoVm9sWThHY1Rmck9wZFV5Zlp4RlNQT08vRWFnaGZvMUR1ME5laVFLV1BzN0EwUk1KbDhrN3VqVHdNclJxZnNwbVpITTJsSUZtVVN0akxVVlNXbDRieFVJUFZSYUZubkExSnE3Rmhjd3VYU2NTU1JDR2wvZDArdlFHNm9kZjdLd05EQndaS2pvMlBtOHhucjdVYVNmSjJNSlJtTjhZYXFzV2hqc1NwaW02YmQ2MjA3VmZjWFhlZGp6NGtkajZEUXQ2MnhrTTg4VzNaZ0xobnJnaWZGSFpseGREMk5acjFaMDIwN3VzVkFWWnZ4d1ZTMitqVTVTU0pHWWk1YWtYSVRDMXZ2RUV6YjFJU1lpQWtxRFBOWkt5M1luZlQzcVh5RmRZUDBJYkNXbE1QR3U4aGRLZEs0UzVPYld2Y3g1WDRIeFNwWFd2Z0hVVGdOTnJPc3VxRW45ZjMrWnkrSVRKWjVMSWJuTUR3TlBIalJHaFA5YzB6Qm52R0tDVjFwbHNzRGpvNE9zZFp5dGw2Skp2Wmk4S2FrcFFGMUVQYzFxaUM5Z3k4cVlEQnRCM2Mremx4K1ArNzZyRFhHNDBIRmtZeFIvT3J5NEpXdHh2R3I3QVl0bG5Oc1hmSE1NOC9RRHdOOTE2Tk1uUzMwNmNMazhHQ1owQXc2YVMwY2d6b0hQdVFaNUVnWW5NTkhPU0tLU3I3b21qN2pic0YyUWxxZWUwckRCbkpoUm8zRzVCS3d1OGJUS3FPSTAzNTk1eW5iNDV5clhiRHZxZXZQY2Q5VndmSkxhenlqTE92K1dUNzU5TC9FS0xzLzlpVEk1Y0hCQVpjdVNhS3YxSGJvcGVGbWxJb3ZNVVVpUVRxTkc0dU9HbXNydS9kQXhVQXJUWXpQSTRIN0wwc3l1Vmdoak81aHlIR0N3alh3ZVFBRkhqWldiSW1oNzNFeFNLTWxiVGhZSGdnL1B3YWM4OElZeXVNUjNxTFlFNUtUb0VmTllJMmxhVnJxV2pwakN4b29wZVczbXkzZDBPZEdVUUdOQkplRXF6ZUpzY3V2Uk1PRU9KWnFuUnJEVXdFWmp3UmpwWmFoU3Fpa0NUNFNsQnlMU1luMktzV3RYaS9wVkNIaDhrVjl6Q04zZmxBczlSUlpEeWNZclRqZFBNWnZQZjZydkxLNklRYmdSSmdqd282NmRPbVlnK1ZTNGpkdXlFU2NYQ2NvUmtMS3pBWVZNU0Zpa3NhYVRCOHVBeXdXZnBuMEtRUThEVWlNUjRWbW5JeWRmU0FMNkhOT2ZFeHg5TkZqakpoa2lQazlneDlHQU9kd3VaQ0NTQ1JDTHJTWW90VGdEVjZPanJadHBWNlF5V0JUWGlTREl1YTBMclJZeGQyMkkrUU9JeEp5bGo5WGxkMzFQTnJ0d2Z4OVlZeEhwK3dYbk4rd1U3d2psdnE4T2tjUmE0c09VbWZKa2xES0NwZFJsWWpxK0cxTXZ4b2todkcyKzc2TE80OGVSR0Y0N01YZjRaZSs4SCtUREtrc1VIWGQ3RmpLU3VvTkNPaXo0T3JWTzVqUEY3Z1lPZHRzV0hmYjNJbE55dnRJYW9NU0ZuWEdYNnhTVXNTNTFMa2RjdUpnYVIxVG1qeGM5UEFBbU4zQ1RwTVlmU2hjK29KUXkrV2RsRjBwU1lvK0ROUk5CY25RVkJackNwNHZpeWxIaUN6Z2NqRm5rYnVRRlFGSXNPc1k2bDNHMklWaWxvSWplQWN4NU9wZjRIeEFLVTJJbm0yM0luamhCb2FZWVZXVk1MbXNYY3puNXV2RitSV0tFTHhVNzlLWjM2QjBybnVVTjZwUk5IVkY5STRZdktRRDdFbVZKcWJJdkQ3azIrNzlFSldwY2I3amk4OThMSHNUbW9SNEh5a2l2cndTMVYrMUxRZUxBKzY2NHk0V2l3TldtdzJEYzV5c3o5Z01IYVNkWms1STRTbU5qRThwSzZUUWxLUk9iNmxyNjcwZnU0ZU1MYzR6S2FUd0Fnb2ZRTEZyaUR5RmpVdHk2WFN5aXFZbzlLMFVkd1dTcTZxaW00QTRwZVVNU0tHSDdYcERXemQ3SWREeVhUNzMzaG1GTDBhaWpxVGtpZDR4YTJ1VTFuUzl4Z1pQNVFJbTErRTlKYUVHSmIwQVkwNDdLZUJUQ0ptQXVkOGFmbi96cGxGUWxTcFZPaElwZHdHWG8wT1NacXRhR2pxNnVMT1BkcGhCNVA0cmIrWGhPOThKd0pPdmZwRVhibjR6bDRYYkdkMHh4aHdReWpXU2xhSnFhcXE2b3U4N2J0NDhwWGVPbTVzVnZaT3NiN0ozVnhoTkkrOGhoRjEyY1BIVHA3dTlUSEE1Qm9wd3JOZnJYU3FYMmhtUjV6dGVUQU5GWVdJVUZtRXgxb0RlVmZBcWt5RUNzQXMrS1NXWkxPZDNZdmxNNlV2a2MzZVNxQ0FaU0ZxWU13WGNNVGxqeGhxcCtKazBXVk50Q0ZGcTYrT3pVR2U3cGhSWHVJM3NNVmtVK1hrZkRwZmZxMUgzVFFOcENqUE9pUUJxa0tMaU94LytNRlpYT04veDFlYy9RZWMzR0Z2dmVWNkY3R0dNcG0xbTh2c1kyYXczOUgzSFp0UGpvdFQvZ2VJNjd4WjlPbStRK3daT0F6eGx4OVYxUFZxdnBVMjZNSEI2TnB1TklINHhVYzJiTVZoaWM1bTV3aklxRXpFMUtpK0NSTXYzN1BIWnVUMFpVMUtkNUpkVlZZMGFhN1BaN0JsYUlTV3dJZ1NGdCtCSytGWlpLYkZpTGFheTBwNHVBYmtxWUJjeWV5amxSZE1Ha3RnRjA0VTRMd0RuQzhxSnRwQ282QlJpRjlzallUSmlHVUpnU0k2SHJyNHQ3LzdFS3lmUDhyVVhQbzFteDhjb0NiU0ZnYTIwWnI1WTVPTTJzTjZzczFCSkgySmZhZ1p4K3pXTlFkZ1MyTmdmdU5xVDBISk5EY1NpdnR1MjJTT1BsTVUvYnhnV294SVlqY3FVRGEwWTB0N2ZpZzhPYVd5TkpveGZJd3dmdCtQNUZYZW5aTUQ2M05kQWVhVFRwdzlvbzhVQ1RxQU1LRk5SNVJiMXk4V0M0QU1sK1ZQRmhCczh6a2xIUTJIM1pqY3dxOU5kckdLU1NFdmFFNGlwQUV5RlJmaURPMDBoMUhQTk94Lzg3OUhXU3dDKytOekhjS0ZISVhtTjV4bkl4bGFTbm04c1NvbDEzN3RTUGJzazg0REtUVGpQaThHZUFKeVA2WmVJWDNtSW92YW5MbER4M3hVN0lHZGFNWHc2Q2VWdkYxMkZ0MGJlY1NDR2pSamZXYzBpUHZDaVhZd3BaVEUzbVE0KzBBOTlqa25JNzRrQ2pJcTdBenFqYkRFcHZBL29EUFBGSUFoaGRKN0tXaGJ6R2RacXJGYWNwUlhPRCtpVU1rSUloYmVZa2lvQjNOdXVLUmRBRmt5TXlxbktMWXUrTTZZalZ5KzlnVWZ2ZkRjS3hiV3paM255bGM4SkV5bEJ5dFhFVklhVVU1SUUwS2FkN2JBRnlNNXRUdlZYakQyV1NtRHIvT0lYb2JKRlpZOCtlMWJUeFNZb083ZW81aERDV0FUU1ZwWDBCS3BLNlJLL1YxK25TRzJWTTFKS1E4U0xCR0hQczhqSDV4N1RTQ2tKN2dRSmFicmVqWDJPQytTOGU3OFFTSldWd3NvcGF4am52SUF6dVJOSDc3TEdTRUVpbTA0WXpHUXVmb3BKTXF2UzdsVmc2WXV1L1dTVDEzaTJ5VUxrTi9Eb0hlL2hZSGFWbENMZmZQblRESEZGWGNteG05UU9kOUdGLzJBTWFKTmpHQmxCWW9jSnBNbUdNbm5PNHFTMjh4N0h3MmNCNlB0K1hMeGk4QlVHOEhUQVpVSExTcTIzYTRGV2M1R0dLVUZpYWtDV2VQeDUwc2x1SGlaWkw2UXhzamZ1cUZFSVpGSFB6czcyK2h4UDFYRWk1eEQ2a2xzbmJWWUg3M0kwVHd2SkpCOVhNUVo4MFFnK1lKU1V1L1haYmloN1hxdGRldlYwU1dWelRKcENwUjE2dWZ2NzdvcVQ1NXhWaDd6NTd1OGlwY2pwOWhwUHZQcTVrZkFpUjh1T1gybHorTnRVTnR1WFpzK2QzRGRBODN4cFNidzV2NGFqRVRpaVNRVzJ6Y2JLZWFQc1BNR2o2enB1M3JoSjlEdXloZGE3enVJRmFKbCthVjNWSkhZcTBIdS9wNkdtbklSeXZvK3VVa3cwVlVXS2tWdTNidEgzL2RnMmRUck9sREx0Q29HazBRSW9kc05BUC9UQ1VGSms2dHIrcmhtL2t4M1VIWk5rTkVsWnV2enZSQUNtRTE0K3M0UFZkMTdBK1N2R2dBc0Q3N3ozSXl5Yks0RGlxV3UvenlzblQyTk5OVTVLMlVCTjA5RFVOYnFxU0ZhS2V1c0x0TkZ0bmdvQ0UrKzVuSlB4MnBJOXFyVEpaV0Z6ZmZra1JoSlptcTNkOWNPUnllL3B0MFB1VEJWMlZUcnlNVEpmekRGS3VBRWpwR3lrakVtWnBHTEJKalZKUGt1N0drWEYrSXNwb1JNTTFySTZPK01zZzFhYnpVWUVvR2lLdkFzam1YZVhFa2xKaWxvM0REU1ZlRGNhMkhRZGZVWTZ5MUtWR0d5SWt0MlVFalIxQTlGbmZoOXNYYWJJbCtIbWlaWXM0L0gwbXZ4dC93aUlNZUw4UU5zc3VIcnBmdDc2d0FjdzFyTHR6dmp5Y3g4VDZEYjc5MXBwYk5OSUJkZXFrdUxPeGhLTjVDdHFjenR4WjNvVjQ1U29pSHBuMUU4M2l3MEpvdFpnSzJ3amZRTWpVbEZOeDUyVnFyUkZJYXJTWjZ2WldBUEpaTlp2RHFzbWNDR3c2cmEwamJRM2o4V1MwZ3BkbEdvQkpaSlVDNHRST0hoYUtYU005RU5QMzNYMFhTZEZvcU1rYkc0MjRvcDIvZTV2bnBRTk5ISXBtVjN1dndSQUZHOSs4QUgrMkh2ZnpUMTMzVTJNa1NlZmVZYmYrUFJuZVByRmwwVUlGR01Ya2hBaVVXa2V2SG9uYjczN0x0cXdCUlFiVmZPbGwxN20yV3V2UXE1alVLWmQ1YUxGYW04Qk1sSlpqalNrYU9NNzMveEJmdmpEZjQ0M3ZPR05KQktyYTQ1UGZlb3IzTmk4aUtrcUtsdGF4UmlxZGlHTG4yTWZLUWVZZEQ3SzlPVDhINyszYkNkeElVWUJtUjRSUlFoc1VGSmVoYnJDYWkzTTNOd29PcVFrWDJLazdxNTBxZEFvWmJCV2N0dUtuenRlV3VOVFRwNVFReTY2dkJ1aWpvSzNoeUJaYno0R2ZBckVqRmVyWEl4aEdEcUd6Wlp1SzJwK3RWNng3cnNjMkJGRFRlb1BlVUtHWHlHemxBQ1hBajRtQnU5NDJ5T1A4S01mL1FpenRwVlM4TWJ3bGplOWljdVhMdkgzZnVFWHVYWjJsZ21zYVp5M3U0Nk9lZGRkbDhHdFJ0ckZUSG5lYy9kVlFraGNPejNaY2YyWTRnQnFmRmlwWm1ia3JBWjhETng3NXlQOGhULzdWemc2UHNveENqaTZxK0g5My9zdVB2WEVXM2oybGNkcDJsWjRDM1ZGTXRJdFJPSU5PY0RFYmtOeGJ1Y1hBR3EwaWNnZTdsaFpxMFJWNWYwMndWaVBOeHJ4NzFNVnBFcEZCb1NzbFFJT0tUZ0plbGlEU25ia3lKVkJPT2NZZ3JCOFVsVDBNWGNZdjAwQUppNFRRYXBpNDRrKzRQb0IxdzFzK3pYOWFrTy83Vmh2Tjh5ck9ROHRIa0hQSzdaeHpkZGUvVHFyYmtOU0NvK29PcCtQSDJVMHkvbVNTMGRMRm9zWlAvaWg3eHBEcE9YeTNuUGw4bVYrK0x2ZXh6Y2UrK3ArT0J4WU5pMzRmdStNVFFtVTcvZzNQdmo5M1BXT2o2QlNISDE5cGFWc3F5Ny9WM3JNa1pnS2hkRW1sK1hkZVVReFJpNGRYK0hmK0w0ZjQrLzk4dCtnclZzeGR2UENKNjJFektFem0yaGlPRS9IZlZHa1VTbjJqTzd6NzdNeFJla2Ftand1SlZ6YXVYMlZTZ3dCcVFsdURIMUtCSzFKMWtpVUR6VVpoRWpXMXZVNDVMd3NRVzVkWENoeTVoQktsaXdHYVJYcmhRN2xNaGRnMkhaMDNaWmgwN0hlckhqazBrUDhxYmY4R0E4dEg4R3FpajV0K2Z3cm4rZnYvLzQvNFBtYkw3R1lMN2pqeWlYdXZIS0ZPeTVmNHNyeE1RZUxCWWZMSllmTEpWVkczQzZhblN0WHJuQjkxbzQ4Z25LRmVER0tGbU1nYkc1eXoxMFBFY0s1MW1XdjVSOU8vbGppOHhmY21UdnV1b0tkTnloYnljNkZURnN6WTBlWGdnZnNIbUUvUmxHZWN4U01mQzZmZDBkSEwyQUlIb3RoMi9kc3VpMmJic3N3T0RBS0d5cnFVRk1aSTZYaVlpNzdrTTFQblFWYkt6R1loaFRvVXFTTFhvUWdqM1JQQUlxUEg0TGtxZ2N2YldHSG5tM1g0WWNlMXp1MjNaWnV2ZWFvT2VEZmV2T1A4WWJsbXhoQ1R5Q2cwTHovNmdlNS9QMkh2SGo4RE1kSEI5SmlicElzT1o3TnFwQkNMMTZUMDgyRzU4ODJtZGl4bTdPcml3VTJoZHZXVkNsTkh4TmYrc2JuaWNHVG5kWnpGclpRMzFLeFFaTFlCeUVFSHIzM0xSd2ZIWk11a0phdTkxRFhZT3JSOVVRSi9XeWZxYVgydXFaTk1mNGlBT09aSDVHdHFuWjB2Nm0zWmJzZ0xMUFRic3ZKMlJuYm9XYzc5Q1AvM1ZwTFpTeHpXMUViOFkrVEVpUE9wMXpnUVVuSHNNNDd0c0d4alk0dUJ2eEVBRWJIS0dSTFBRUlVCT004b2V2WXJOZDAzVmFLUG5tSFQ0NCs5SHpYbmQvTnc0ZVBNUGgrc200Smx4d1AyamN3dXdxKzZTRXcxalhjOWowdjM3ekpDOWR2OE55MTZ4ek5XbjdvZmU4ZGkxS0Q1Q0I2UC9DUFAvMTVQdnZONTZXQ3RncWpBSHpnNFVkNDMrVVdIendUdTU3SzFuenk2U2Y1L0NmK1EzRmhVM1lOVXhwNytJN2g4ZXh1cWt5Vkl5VSsvQjAvd3AvN0V6K1ppejlNRWtzamZQNXJYeUNwQ3JRMGpFUWxkTktrdEcrOVg1UVRXQVN3b0k1RkFIU0d2S2VmbjJJVjlpdlBQeVVEellQMjBSTzE3R2dURXpaRXFwdzRncEVnQ2lpQlpXUE0yYmVCM3ZXc2g0N2VCL29ZR1ZJaWpnS1FjdjNlUkJ6ODJFS2U0TkF1a056QXR0K3c3YmZNMUl3NzUzZnc1dU5IZWRmVmQvTEdvNGVKL3VMdGEzekZDeTlmNS9uK0pWNTQ5UVpQdi9JS0w1L2M0dWEyWitzRHZROXNlcytpYldqYUdSOTg4Nk1zWmtKTHY3VmE4K3RmL0NwZnZyWm1kdm5LWHRkT3BSUlB1TURkekxpdkNtZ3ZTU3ZSem5oTzF6ekhkUzdkZFhYMEFRUzRpbE5NSnFQWjBta2xLdkVDWWd4ODV1bmY1ZDVQUDhBSDMvRWhEcGFDL1ordFZuenlTNS9nTTQ5L0VxVnlMMlpBNTdxS1JMV242a3N0NVBNSTQzU1JSeTFRdWpHa3RLY0Z4dmpDLytUZit4K25vSGJKUzFOZ28zUzJycFRob0oyeGFHZk0yMWE2akNGUTZkQUxzV08xWGt0UUp1UjZQeVM4a25OVXh5VEZKSDNBYlR1Y0d4aWNrRFdVY3pSUjgyQnpOMjg4ZUlSSER4L2gwYU5IT01pQkVSQ3lSa2o3NTZaRzBlbU9mL2QzZm9ZdnZmb1VsUlV3cW0wYnFsb2FVaFdQUldtTjFacDMzSDBYOTF5NVRFcUpwMTk1bFc5Y3Z5V2N3bnlVN1NaWjNFSnJMUGN2bGpTRFZCTWRtaVV2ZGh0aWNxaUozWi9TRHJuY2lXZkdJVkNFbEt1d0ZIQXRLTjU0OTF1NTk2NTdRY0VMTDcvSU4xLzhtaFJzc0phZDZUZ3BoSlh4ZlpRRXVRVEgydGNBNTBFcGxjR3Vnby9zZ1YxNUxOYkgzVTdkaXp2bkQ2YVlRQ2M2NzFDRElobEZSWTZQSnhoaVlEUDBiSjNEWmNNcGtqQm9McWtsbGFybzQ1WWJ3d25kMExOZHIvQ2RZNkZuM052Y3o3dXV2b20zSDcyWnkvVXh5M3FCVVpLUjY2TG5abmZDczJmUGMybCt5TU1IRHdxakdJbUoxOXJ5MzEzN0xDK2JnVHZ1dlYvbzZOWmlqRWE2NGUwTVZLc3JRUEdOMVpwdm5Ld0FPUUtXQjR1OFhYZnVuMHdjRkxYL1hMOUI2VXFzKzl5MVF5TXFXcFhQSklrWm5EZXlWQW5IQnNSdVFzdjdkT1FyTDMyWjMzdjI5eUNWSFA1RzFIMVVJLzFkS1pVTnVDeFNGNE9LdThWbVh5aWcyT0g3R21ONlRGaGxEVlA3OTd3RUdXTnlKNjNFWm5EMEllNUtvbVEzWjNBOVF3b1pmWU9GbXZHOXpidDRaL01HRHRTY0crR1UzN241ZTN6aXhoZDQxRHpLVys1NW1EY2ZQc0tEeTN2R0JTL1g5ZTFOdm5MejYzengydGY0M0t0ZjVpczN2c21qVngvZ2YvSHQvdzd2dmZ4T2FtbzJiUGlYcTgveHo3dmY1Njc3NzVGYXYwd3NZQ1FCVktlWVZYdVpHREZtODNSS01XZWdGSUtNR2N3WktlS1FtenptSmxaSlUvclZ4TnlkRXpYWmZSUERMdVk2U2lrbERGWUNUc2lSbVl5aHNaYXFTWkphRitMZUhKeGYyS2xCVytJT2Y1UnI2Z21NQ09qLzlILzd2engza01oUk1PNmdFb3BrcCtyMmJraVNTRnJlL1RZby9zM20vWHlnZVJzK1YvYlZXV0hlNkU4NHJKWXNxdGw0ajg3M25BeW5mTzNXay96T2k1L2xxemNmNTVYdGRjN0Noc3BXdE0wTWJUU0hCOGZjZi93Z2Jic2sxSnFYM1UxQ2pCaGpwV1Y5R1R5QWl1Z1l4ZlpBenVMQ1hKNUdETXRsbEFqeVZFMmVEK2hBRm9DeFN0ais1RjZFczh2R25mQWxVOEtuT0tsUW1sVjJTRGtaZHRJNENqQTVFbGxTVjhZNFF5azl5c1VROFBTS2FWZEIvVHdsUGFXRWhYT3grbkllbHJTbFNkQ0VsUHNIajNjUUZlanorZGNIeDV2MFBieTllcGd3bG5VbUYzWlYzTkZld21xRGk1Nm56bDdrS3pjZjUwczN2czduWC8weUwyOWVIYk43bXFibHVMbURwbW1vNmxvYUsxdkxDNXlpL0JhamFxeVNjeDNFV0NvTHZIdUl6QXBJaUQwdy9pWDdJMHFOajZYUStZd3R0WTkyc0s2YVBMK2doV0w3Wk8wOFdZZ01GS205VVl5WVBrcmNhSk0wUm9HT1FRem9yT0xUNk4rbjNXY25FNzBiUmpyM0JSZjhQRm1mNmJYdlNzcGxweW5GRjM5V1hMN2RaTEIza3dTZ05DRkVPdWRvYmMyUldkQ2w0ZHo5RWdyTlAzMzJ0L24xRno3Tk02dVhlTEc3VGtpT3hsVE1qa3FKbW9hNnFUR2xlcmlSc25MS1ZwQlVadmJrTk01c0dLVko5eXk1ekdpZkM0Q3hROHVtQzdTWHhZd0kvU2dFNXladDkzOXh6Nlk3YXVkV1hUQTNNb1Y1TXlSTXhreUt4T1JUcENnV01STHpzNDJBajVLeHlYRFRYcDFwcFM5YStkM25LSTI1WGtOVDJBdC9PN25PUDB6NU4wNVVYbW5pQ0lwTkdsakhEcXNNMHpOUm96anpHMzdoNWQvaTY1dG5hT3FhZy9xUXFxN0dsak0yTTVCSDFvd1Y0a091aGl5N0ZqVXViM25LQzg5UGVlcmJmMzFPclo5LzFtTDNuSGVweGwyVFphM3dINmJIeHZRN0JHL2ZxV3FkaTQ2Vk1xODZKU2xjclpUMDloMmJRRXRnaTBSKzdnSTN2NzZxZjYxbzROVG52KzFaQUtzNEY4eDVqV3YzbnFJT3g0QW9LamMyYm16THMvNDZUN2lYZUVmekVFUGFXZTJWc256bTlPdXNLc2RkbCs2a3NwVmsrRnJKejlQR1pNMjcyMzNDRDlRanNpZjBxTnVYKytMaFgveE1JdzF0Ny9OeDhuUHhIdVFwbGRxaGU3dGRYZ0FaaTlhbGhzQXVQMSsraC95WkhEVlVTYXpSN002V3lpUmFGYXQvVjJTaUhFTXhSclI1ZmFGOXZldTFQck1YRHY1V2JpUVRQSzMrTVlFYUUxVDVYNjBVam9GZjdqNkRVWnFIN0ozTVZjTXFiZm5DOWdsK2RmMVo1b2RMckJKQXlSb3JHU3JzYTVReThSTHVMQThoVlVERzJ2aVRLOGJkeE8rUCtWdWRsTnNGUW5iZDY3MnZmR2ZCNk5Oa0hEdStIeG1JeVpaR3pzaEpPOEhLcDZyT1VWUHhyalI3VnVZZmZ1MWY4OW5LNzRxbFlhZHE2alZ2a2MrbWlUK1NCV0RjQy9KcmJUQ200WHBZOFEvNmovUGdjQWRMMVhLU05qdyt2SWliSnc1WmpQY3RybVNTTDdndFEzbTYyMGg2ekFRNnI3RXlFbnZoZFJzd1FucE5kYm5idmJ1ZE8zbkgrTHhLRmFHRG5TQ2tNU3RJb0hISktpcWRQY3A3ZFdGeFphTlJxcUNBVGpzQklFYklXazhxZ3BYNU9HOWgzdTcvMzY3Tnl4RTVHYWVTNHRvbzlhMXBnUElGcjNlV2xNdG9TZU1lWXVCTC9obEFOSU94aG9iNnRzK01HWGpuRnYvMkFhUlJFNTEvMk5jNzA3L1YzNThQdHBTZmJ3TllYdWV6MC90TFRxUUhkYnZyQlRzQzZUaXZjcVBiczZ3RVM2VVFiaUNMYVRrdVVuSFRjNWxkNHUxRFZGbkRLaldLUVhtVC9WYk8vNHNlOUxVbVVWeElBWGRtdHRuNzNFWFlkY3c3TDZhTGQrYitjNXkzeUc5ZnFQUFhiZWpjNjN6SDlLeTlDRnFWTWJ6TytOUitpbmt4OXFjQ05iMm1peDF6RGF5Q1hoYTBUc05lNEVmclhVR0w2WmgzNDk0bG9xVGlsNzdHV3FXVXNOT2QvWWNSaHRlN0ZHcU1YNy9XTlU1dXp0dFBGOFpyenc5YTdqNjloL3orWDkvWWQ5LzFXaXIxOW95bGk2NnAwYnd6SlBmSE9vSk5Xa2d6cUIxZnY3elhUQlorekNkZ1h3QXVHdnMwNUl1NjJJalVXbVBMMmZhdmV3Sy9sVXV3N2ovTUIyN1hBcTgxN3Vray9GR2U3Zi9YK1RqdmJVelYrdm43YTZYQjdMOS9pa2FXeGI5SUFDN0tRNWorZlA1N3o3L1BwcjMrYS9DSFc1RS8ydlVIVGU1cnErbUwrUGl2Zjc4L3FuYTQ2TGdUamZXdEcrVVgyU3JUWStoMkEzVVhyaTBDTUVMRGFwY3NPNXB6ZTU3VDdmYzdqL3RQRTNQTFpkbkRBWXB6d0FWUCtZZnhSVjU3d3N2WmVKc2VWY1ZTbmFxM2kyNDcrWndxOTdsZ1ZiN0ZOZitEN0pxTHJteUw3ajlDM3BtN2Nhanh2YmNmSXVVZStTWVhZQlBqMk5LNU1iN0crRjlQRTA0MXlXaDQ1anZadlM5T3UzK1Uyci9oU0c3OEF5NTVzR2tKNXR2L1h2emYwVWdaMS82Y3AzRnU5NTZuVVkyMS9DNXc3UklYSHkvVDNYZ1J3REpWdmVWOTVmZjdVRGk3WjloN0h4UERxNHloaEtxbUVjUDhyOXI3M3dRK3p2ZUxhUmVQbWJDQ3k2aW5SOXdmNUIxTi94NXlJTWYrVVZYazYxMnZaYzZkUDQ4VFpOOStoMWVmNTdSTlAzdjd2ZjYxRHZ1UGRMM1dtVHVORDV5bnpsOTB4QldyL1h5VjFsUVFSQ1hzNExKWjFPVDdMc3BKdkdpTSszWlJKb1JNSzJEdE50NU9IZi8vODNxOUlNejBkeGNWVzdwTmlQZjE4Yi8yYTdweFhtdW5uZi9kTk0zN3RZUmcrcmZ6Q3pmTllpcWZMdXQzbnZyOWVtTlRhaGRQK2Y4QyswcGo1M1ZKa3hBQUFBQUFTVVZPUks1Q1lJST0="}} \ No newline at end of file diff --git a/sleap/skeletons/mice_hc.json b/sleap/skeletons/mice_hc.json new file mode 100644 index 000000000..1931f8166 --- /dev/null +++ b/sleap/skeletons/mice_hc.json @@ -0,0 +1 @@ +{"description": "Template Skeleton for mice_hc reference dataset.", "nx_graph": {"directed": true, "graph": {"name": "Skeleton-0", "num_edges_inserted": 4}, "links": [{"edge_insert_idx": 0, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["nose1", 1.0]}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["earL1", 1.0]}}, "type": {"py/reduce": [{"py/type": "sleap.skeleton.EdgeType"}, {"py/tuple": [1]}]}}, {"edge_insert_idx": 1, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["earR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 2, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["tailstart1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 3, "key": 0, "source": {"py/id": 5}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["tailend1", 1.0]}}, "type": {"py/id": 3}}], "multigraph": true, "nodes": [{"id": {"py/id": 1}}, {"id": {"py/id": 2}}, {"id": {"py/id": 4}}, {"id": {"py/id": 5}}, {"id": {"py/id": 6}}]}, "preview_image": {"py/b64": "aVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUlBQUFBQ0FDQVlBQUFERFBtSExBQUJWQkVsRVFWUjRuSzI5MlpObDJYWGU5NTNoem1QZW5DdXJzcXE3cXJvYjZHNFFJeHNETVZBUUJaaWthU0pDMUlQTUNObldDeDBodjFsL2dNTVJmdkNEM3h4K3NoME8yeUZyc0J3S21ZTW9DQVJBREVSallzOFR1bXZPeXN5YmVlZjVUSDY0K2R1NTdrVTF5QWVmaUlyTXlyeDV6ajU3citGYjMxcDdiZStQL3VpUHN0bHNwaXpMdEwyOXJYdytyemlPMWUvMzFlbDBGRVdSc2l4VEVBVHlQRTl4SEt0VUtxbFlMRXFTa2lSUkZFWHlmVisxV2sybFVrbWU1K25SbzBmS3Nrd2JHeHRLMDFUeitWeFJGRW1TS3BXS2dpRFFZckdRNy92eVBFOVJGR2s0SEtyUmFDaWZ6MnN3R01qM2ZSVUtCVTJuVTRWaHFNM05UWVZocUNBSWxDU0pGb3VGeHVPeGdpQnc0NDZpU0hFY3kvTThiVzV1YWpRYUtVa1NWU29WeFhHc05FMGxTYVBSU0hFY1M1TEc0N0dpS05MQndZRzJ0N2RWTEJZVkJJSDYvYjZPam80VXg3RjJkblowZUhpb1hDN24zdWZvNkVpZFRrZEJFS2hRS0toWUxDcE5VNTJkblNsSkVqZG5sVXBGa2hUSHNYWjNkOTM5SldteFdDaUtJalVhRFUyblU1MmRuYWxVS21rd0dDaE5VOVhyZFlWaDZON1g4endGUWFDN2QrOHFuOC9yeXBVcnl1VnlpdU5ZY1J3clNSTDN6RXFsb2pBTTNYdFBKaE1kSFIzcDVPUkVZUmpxOFBCUW9lZDU4bjFmdlY1UFFSQm9jM05Ua3BUTDVSU0dvZEkwVmFQUlVCekhldmp3b2ZyOXZuWjJkdVQ3dm51d0pGV3JWUlVLQmFWcHFpaUtGQVNCeXVXeXdqQlVsbVh5UE0rOThIZzhWcUZRVUJBRUNvTEEzU3NJQXRWcU5SV0xSUlVLQlkxR0l5MFdDNlZwNnA3bGVaNDh6MU9TSkJxUHgwcVNSTnZiMjVLa05FMDFtODJjOElSaDZKNDdIbzlYSnJCYXJTb01RL20rci9QemN6MTQ4RUR2dmZlZWU3OWFyYWJoY0tnb2lsUW9GSlJsMmNva3oyWXpCVUdnUnFQaG5vVkM1UE41OTI3SHg4Y2FEQVpLa2tUNysvdnVmUkdJT0k3ZFBFZFJwRnF0SnQvM1ZhbFUxTzEyTlJnTTNGanorYnlpS05Kb05GSVVSYXBXcTFvc0Zsb3NGazZnUGM5VHVWeFdyVllUMTN3K1Z4QUVLcFZLcXRmckdvL0h5ckpNV1pZcDVFUFQ2ZFJKU3JWYWRVSXduOC9kWW0xdGJia0ZDTU5RdVZ4T1daWXBUVlA1dnU4MFBJb2lUYWRUbGN0bCtiNnZMTXVjcHNkeDdEU0dSVS9UVkdtYUtwL1BLNS9QS3d4RFZTb1ZGWXRGblo2ZU9tMlE1TzdIUFF1RmdncUZnck1pV1phcFVxbW8wK25vNU9URVRVS2FwczZTNVBONStiNHYzL2VkY0cxc2JNanpQSlZLSlVWUnBINi9yOGxrb2lBSWxNdmxuQUFpQ0lQQlFKSlVLcFdVWlpsN1JoQUV6a3A1bnFjc3kxUW9GRlF1bDlWb05KeVFTTkpzTnROaXNWQ2xVbEVVUlpyUDU4cmxjdko5WDBtU2FENmZPd0VwRm90S2trU2owVWlUeVVUTlpsTzd1N3VTNU1hNVdDeWNwVVdKNGpqV2REcFZQcDlYcVZSU3BWTFJ4c2FHczdnaGsrbDVucWJUcVk2T2psU3RWdFZzTmpXYnpUU1pUTlRwZEZTdFZsV3RWbGNXbndIbTgzbTEyMjAxR2czMzRGS3A1QmFOQ1pMa0pMRlVLam1oUVBvOXo5TjhQbmNUTkpsTU5CZ01kUC8rZlVuUzV1YW1OamMzdFZnc05Kdk50TGUzNXhZTzRVQkFQTS9UWkRKeFkvVjlYNDFHd3dsUHI5ZlRZckZRcVZSU0xwZlR6czZPd2pCY0VhWTBUWjFHVjZ2VkZjR3IxK3RPYVZocy92SE9TWktvV0N4cVkyTkQ5WHJkaldPeFdLamI3V3F4V0RoTGkxVmhzUmhmc1ZqVVlyRlFITWNhRG9jYWpVWnV2S1ZTeVZsVkJIVXdHT2o4L055NUt0NEJLMUF1bHpVYWplVDcvbEs0am8rUFZTNlh0Ykd4b2Nsa29vY1BIeXJMc2hVL3pJdHpnL2w4cnRsczVueC9McGRUdlY1WFBwOTM1aExOd0dRaW5Vd1labERTaWhBZzhRaGtyOWR6Zmd4VHlkL3dPZndlejFrc0ZrNGcwalNWNTNuSzVYSXFsVXJPN0U0bUUrSCsydTIyOHZtOG1zMm1NK1ZXYUhPNW5OTm1McXdja3d6Mm1VNm5LeFlQeldVT2VYYS8zMWNjeHlxWHl5cVh5MHFTUk4xdVY5UHBWTHU3dTZwVUtwcE9wd3FDUUsxV3l5MWlzVmgwV2x3dWx4WEhzWEs1bkNhVGlTcVZpdkw1dkU1T1RyUzl2UzNQODFaY3hIUTZWYXZWVXFsVVVwSWtLcFZLQ3J2ZHJxclZxdXIxdXZOcm1BZE1sOVVxRnB3WHhnVVVpMFhuVXhFTXREQkpFc1Z4N0h3YWJpYVh5N25KQklqeU0vNW1jM05UVjY1Y2NZc0t1T0psMFlEWmJLWWtTVFNaVERTWlRKeGZuazZueXVWeXpvOWF2NHRHem1ZejUvNzYvYjdETTd6TG8wZVBGRVdSTmpZMmxNL25sU1NKVGs5UG5Rc1lEb2NyWUxCV3E2bFFLTGlGSDQvSEs4SUNGdUgvYUhldjE1TWt0eGFUeVVUMWVsMlZTc1c1aDBLaG9GYXI1VUI0THBkelkySWRybHk1NHRZTGF4eEZrUjQrZkxnaWxNVmlVU0VTbGN2bEhNb2VqOGNLdzFDMVdzMU5HaVlFRTRkV29TMEl3M3crZHhaaU1CZzRZQk9Hb2NybHNxSW8wdm41dWNJd1hFR3dhRFAzNXg0SVo1cW1Hby9INm5RNjZ2ZjdrdVN3Q2M4ZERBWk9veWFUaWVienVjN096clJZTFBUMDAwOXJjM1BUV1E3Y2hTUzFXaTBIWERjMk50UnNOaDJvNHJtZzlhMnRMYzFtTTdYYmJXMXZiOHYzZmVYemVhVnBxa0toNExBTEpoWmdXcS9YVlNnVTFPdjFOQjZQNVhtZVdxMldpM3BtczVtYXphYWF6YVp5dVp5R3c2RlRQakFKZ2pPWlRIUitmcTU2dmU2RXRkVnFhVGdjYXJGWWFHdHJTMkVZcXRmck9WdzBuVTYxczdPalZxdmxYRndZaGdwcnRacW0wNmxHbzVIemdkYnNzVGhvSk5JMEhBNmQ0TEJ3VEJUK3I5ZnJLVWtTYlc1dXFsZ3N1c1h0ZHJzNk96dFRQcDkzSVJMbU9rMVRaVm5tTkI3ZzVmditMeTIyRlVUR2gyRDArMzJkbnA0NkM5UnV0MVVvRkZTdFZoM3dSSGg1ZHFWUzBmNyt2cXJWcXZMNXZPYnp1UU9KazhsRXcrRlExV3BWazhsa0JYUDR2cTlxdGFwU3FlU3NFcUdsSkIwY0hPanExYXR1b2Z2OXZyTmlBT2xtcyttaWsrbDBLdC8zdGJlM3A4VmlvZVBqWTgxbU01VktKUlVLQlQxNjlFanZ2UE9PYnQ2OHFhZWVla3JGWXRHTmVUd2V1M2taalVicWRydE9PSGQzZDEya3hudUV6V1p6R1E2RTRVcWNMc2xORWo3YkluN0F4WFE2ZGRaaFBwODd3QlFFZ2VJNFZxL1hjOGcrQ0FJVmkwVnRiMit2bUVlQURoT09yMGR5SmFsY0xqdFREdEp1dDl1cTFXcmEzOTkzaTQ4ZzV2TjViVzF0cVZLcE9FdkI3MjFZNm5tZTR4QmFyWlpiUVBEQTJkbVpwdE9wV3lDcnZjVmkwZUdDS0lxY0pRQ0orNzZ2N2UxdHA1R1NIQyt5V0N4Y1ZKTEw1Vnk0RzBXUjAzUmNHQnhOclZaendIVTBHcWxjTHJ1NUFPdUFRNGhpV0w4Z0NEUWNEdDA3RTNXRWdEYUVnRkNHQldEUjBVWUdsR1daQTRsUkZEblNhSDkvMzAxNHRWcDFnb0lsQVFnUkFscTNBZHExcG8vblpGbW1xMWV2dXZoMloyZkhnU2ZBYWJmYjFiMTc5OXpFdDFvdGh5dldvd0tzRFJaanNWaTQ4TkFDeDBxbDRpellZckhRMGRHUkZvdUZBMjBiR3h0T3EwRDMwK2xVMVdwVjVYSlpoVUxCQ1JqS0JTaERnUkJJd3NUaGNPZ0VaVGFiT1NzRGVDd1dpN3A1ODZhenpPQ1l5V1RpSWdJNENzZ3hua2xZNnJDUVhXaWtBMmxFUy9nZTRxWFJhRGdRazgvblZTd1duZWJrY2ptTngyTkhSdGdvQXRjUXg3R0xGaGhZcFZKeFlRMFNDbURKNS9PNmYvKytack9aYnQyNjVSYXcyV3lxMSt1cDMrODc5dXpldlh2YTNkM1Y1dWJtQ2lIRXM1a3djQTI4d0dLeDBNbkp5UklaWDN4K05CcTU4QXBYQWRBY2o4ZUs0MWdiR3h0dTNKMU9SOGZIeHpvN085T1ZLMWQwOWVwVjl6d3U1aElpYTdGWUtBeEQ3ZS92Ty9jS2c5ZnI5VFFZREp6Q3pHWXpkKyt0clMzZHYzL2ZFV0hUNmRTQjJYSzU3QWd2ckhPeFdGUVVSYzRxQUx6RDJXeTJFdUlBdnVJNFhvbGRrUmdzQmVnVGtpU2Z6enVOQkRBQnJMZy9vUXhNR1RoaE5CbzVNQVMxREw5QXRORnF0Und1Z0VPQTBjSjl6R1l6SFJ3Y09JM0cvQ0dZZ0NrbzJ5aUtWQ3FWbkYvdWRyc3FGb3NPS0EwR0EvZitXRUxDWDZJUXJNWm9OTko4UG5lRUQ1ekliRFp6K0dvMm03azVoaWdEc0hML0pFa1VocUdMQ2p6UDA4YkdoaVRwN3QyN21rNm5ldXFwcDlUcGRQVEJCeDg0NWhiaGdnanpmZC9OTlVJM0hBNGRKcGhPcDB1dzMrLzNuWm1Lb2tpRHdjQkpkejZmZHlZRGExQXFsZHhrb3hFMkRzZjB6Mll6QndMeHc1Z3g3c1dna3lSUnY5OVhvOUZ3OTVQa0loRGY5NTNQNVlVUXVsYXJwVUtob1BQemN6VWFEVjI3ZHMxSk56NGF2d2tKVTZsVW5LWHI5L3R1OFRZMk5sUXNGbGVBTFNZYUlNZzc4Zy9RMVc2M05aL1BuU1hMc2t6dGRsdEJFR2cwR3FsWUxMcFluWVhCMGd5SFE4VnhySU9EQTAyblU2Y0VVTGUxV2sxMzc5NVZ1OTNXL3Y2K2lzV2k3dCsvcjNLNXJPM3RiYWZwa2h3Zkk4a0pnWFYzRmd2MWVqMkY4TWNrS1BMNXZBTmVNRldBRlFEWWZENTM3b0FrQ0pJYWhxRWpIL0JkbUx0aXNlaklHRUt4YTlldU9YS0VRWVpoNk1KQ0VDejNBcnhFVWVSOE5IeTlqWEV0S0JvT2gwN2ppU2I0T3B2TkhBbDBjSENnUnFQaHJGYTVYSFlDWU1lR05RTUFTMHZVVDBpSUc4VFNqY2RqdGR0dEY2SmxXYWJOelUwRlFlQm9YQ3lFdGJCRU4xbVdxVmdzNnZyMTY0NGpRR0FKc1h1OW5yTXFBSFhlRVVDSnhaclA1NXBNSmt0dUJNREZaQUYyZUhFbUZoSW95ekpINGxqM2thYXBoc09oa3pvbUZtMGFEQWFhVHFmT056RklCQWlKWmZIdzg3aVNYcS9uc3BDWVVqUTVpaUpuaFlpRmZkOTN6OE5NVytIbHZYQjlsdlBIbE9LVDBSb20wYUo0TW0vUTVEd0QvZ0tzWVhFUC8yQVROelkyVktsVUhGNWdQV3lPb2Rsc3FsQW9PTmZBV296SFk0ZTFDUHVJbUd6eXl2cDlTS245L1gyRlNBUkFnd1VtWnVhRnVRR0pobks1N016WmZENTN3Z0txWnJBSWxiMXNOc3R5RDZCK202aUIwQmtNQmlxVlNxclZhdTR6czluTXVRbDh0VTBIOC9LTlJzTng3cFBKeExtSFdxM21jQWtFRmJrQk5BK054MVVoVURCNGk4VkN0VnBOOVhyZFJRZTlYcytCWUd2cUVUQk1zRTMzTW5iQ1RDd3lycFg1UFQ0K1ZwWmwydDNkZGV4bmxtV096T3AydTVyTlppcVh5dzdRSXRCUTFqQzVoVUpCNFhRNjFXUXlVUnpIYWphYkRzeUJKREUzYUtza1I3V1d5MlZIQVdkWjV1SlNpM294N1VnLzVnMk5HQTZITGdGaVRUUCs5L2o0MkpuV1lySG9mQ21Uei9qSlE2Q04wK24wa3UwS1hkTFRqUUczWmFsVVRHT3RWbk5LWVlVS3dlSWRzRlpZRTF4S3Q5dFZ1OTFXbG1XNmN1V0s0d2F1WExtaVdxM213Q1NNSnVFd1FsWW9GQnoxR3dTQnB0UHBjckV1c3FTTW1RdUIyZC9mVnk2WGM5R0xGWjUxMTRwQWhwUEp4Smw3ekNwU1F6eVArZWNmazQ3NXM1U3dmUkhpVDl3QWVDSkpFaGZyTnhxTmxXaGgvVDZZT3JLSStYemVJWGs3Sm9TVTUxaGhRMEI1ZGhpR0xpZVJwcW5qRnRJMFZhL1gwMlF5Y2FDUmR3R3BFMEV3dGxxdDVvUkJXcWJWTWNPRWw2ZW5weHFQeHpvOFBIVHVCSUcyU1M1K0JvNGlocWN1Z3VmZysxRkVGcnBRS0tqUmFEanR4cW9pdUZ5c1lSQUVDa3Vsa2l2YzZQVjZqckNBOUpIa2tDUm1GUjhNcUVDQytiMHRUbUJpcDlPcGszNzcwbWk4clR5eUUxS3IxUnk1QWwrT1dXWHhBVlkyL2NtOWJHRUxKcHgwc09jdHE0YkFDSUJSd2xJb1pjc1oyTnc5NDBPQVNVcVJWeUZVeENLUjZtWXVlUzd6eEQzQUFwQlRDSklrbHhBQ0dQTlpvcDJ6c3pPbnNCQkZQTStDOHJPek03VmFyU1VHQUd3eFdQenFhRFJ5bkVBdWwzTnVBY0REeEJDclEvMk94K01WWUFSb3NqNmVGNWJrQm9uUGhpT1lUcWRPRXhBa1hBOUVVUzZYYytFZUdqTVlETnp6TmpZMlhGZ0szODhrRWpPakxRaHpyOWZUK2ZtNTR4TlFCQ0lZdm9jQkJOTjBPaDNOWmpNZEhoNXFZMk5qaGVVa3pFYnpjR0VRUVJCaXVDdG9lYXd5S1Z3YmRXSFNzZDVKa3FqVDZXZ3dHR2h2Yjg5UjJ4WURjRzhBZTBqeUpvNWpOUm9OVmF0Vk41R0VUYkJkMWxkWkFnYW1DZnpBNEVERUpEZElUektKU0tpTk1BQ1pXQTE4TXFhTmNxbVRreE1YQ2hLbG9PMW5aMmVPeDBpU1JPZm41ODRVTnB0Tmh5TnNBUWJheUlTeFVMd1hlSUNmSVdDa24wZWprWWJEb2VyMStrb09BcURXYXJVMG5VNTEvLzU5UjNwWkMyZ3BheFlKVElJN3NmUEl2RUhvb0JDKzcydDdaMGZiMnp1cU4rcUtMbGhkRkZtU0UrcDhQcSt3MCtrNDZVY3FoOE9oQTNYNFBhVE9adXlJWGZGL05rVU1YVXJvUVY0QWtES2Z6MTE2VnBJRFVreG90OXQxeElsTnBtQ1NZZmFtMDZrVEdNdld4WEhzY0FKK0daS0UrMmRaNXBnOTJEWXdBaUZjbG1VckRLV2RLNndXMW5OcmE4dTVKOGFicHFsakJ5ZVRpUjQ5ZXFUUmFPUmMzTzd1cmhOY0ZnaUFlSHA2NnRhQWQ2S3FpWHNqMkZtV0tVdFR5ZlBWMnR6UjN1NzJNcFU5bVdzUlh4SnJ1SFNJc0hCalk4UDVQbndPSUF5UVFqNTduUklHK2FLNURJZ0ZwZWdBcGhIelRyZ0NBQ01CaFY4bk1VUU5BUlB0Kzc2TEdzaWJ6Mll6UFg3OFdHRVlycVJVS2NKQUtLYlRxZlAzbU43ZDNkMFZLOFg3a3BIRXNxeS9zd1c2dytIUVpTbUpSTGduQ2dXR29aaG1PcDFxT0J5cVZDcHBmMy9mMWZyQis2UDlwSmpSZUN3VVFJN3FxdVhQTWtWSnB2MVdWYi8vOFpwZXVKSXBqV1BkNmViMG80YzFkZWM1NVhQTEtPdng0OGV1VUNSRVl5RTVySStIcHB4T3AwNTdHSnlkRUV3NS9wMDRFMXJYUmhsOHhVcll5bDJ3QVBHcXpVVXc0VmJEY0RuZ0JNQmxxOVZTcTlWU3Y5OTMrWUphcmJZU2VWaVNDMFlPbCtaNW5xdE81bjFoNlN5bkFZY0JKd0t3STN3R0VDNFdDejErL0hpRnVZUGFSb0Z3YmJaUWhUWGdId0tKTDJmc1FSQm90bGhvbytqcG4veTlBOTNjelV0Wklzblh6UjFmbjdubTZaKzlHZXBvRkNnWEx2TXFWNjllWFFvNnlCTCsybVlHWjdPWm8zeVBqNDlYQ2tENERINFp6U0dNc1dZTkxjSnZBaWp4cnhBZ0VES2dhNTVuQmNOYUtOLzNuWVd4SldHQVBWQTE5N014TUJrOG01MDdPVGxScFZKeHFXWUFITllObEkvZ2dJKzREN2lIKzJNUnQ3ZTMxV3cyVnl5b0pPZWlDTG14Z0dBeTNJKzFnRVJrVUxtWEdNTFQ3enhmMGMyOWdoUmZLcGtrTmNxWmZ1dEdvdi96clZCWnRzd1hvQVFoc1N6K2RES1p1SXBmR0NiUDgxd1l4Q1JpZWdxRmdqUDdjUDdrc3UwaTRhdElja0JtMkNJS1FxQm1zK2xDVTZ3RENCMUJBSURaU2w2YlNDR2VSL2hJeXNBMzhOVVdZVlNyVmUzdDdTbWZ6NjhBU2FJTVcvU0IxYk5qeE1JaFpKaHJvZ2ZjbXNVeGxzc2dYd0J1SUNJajkyRERYQVM5VnF2SkR3SzFxam05ZUtVZ3BhdUx2NVJPNldvOTFYWTUwOG5ZVitCZHptY1lodUZLUVFaU3lzdkNVUlAyV0xJR3dnV3pLY21GY2tpeU5mczJMa1Y2eVNvMkdnMTFPcDBWczhZOXNTYVc5N2V1aEh2RGpWcy9uYy9uMWUxMkhVdkh3alFhalJYQ1pYTnowOFhPdlY1UDNXNVhtNXViYnZGZzJ3QmxnQ2liQ2FYa2kvbXljVGNGbjlDelJBMnRWbXNsOFdXQkpxRE5Kc0Y0TnpiUkJFR2dKTTFVQ1VNVlFrOTZ3dnBMVXVCSlhqTFhZQmhybzFGemN4dnlBcGg3WHBUQ1VPaElHNWNTdnlPUmFCckpHbGc1UGtPSlV4ekhLL2NsUzFldjE1MDVwS0xGNXNZeGt6YkxTRWhwNnhVc2xZcHBETU5RT3pzN0x0Ym5mbWdBV2dwWmhMVlkzL0RCb2pKZi9DM0tRMUxIK20xcGliajcvYjZHdzZHMnQ3Y2RiNEVsSU5KSmtrUzFXazNWYWxXajBVaVNuSElndUpaWjNkemNOQUI2b2RuQ1UyZWFxVm5SRTRWZ3ZKQ08rd3ZOWjNOcFhRQ3NUd1BFa1ljbTNDTHpCeC9BWWdHeTBIZ1crdno4M0NGZE5BdDJrVEJ3UHAvcjVzMmJMb1VMZVFJdlB4d09uVFd3V1VLYm5VVFFxRFN5dERSV3BGNnZ1d1VGcDdDd3VLajFVSmJzbXRYTVdxM21NQUJDaVB1Q3YzaFN5SWl3V3NHQWkzajQ4S0cydHJZYzUxK3YxOVZzTnQxY2VaNm5zN016aHlWUUZrazZPenR6Y3hEbWkvcmUzYmtPTndLRnhpWEpreFJJTHo5TTFCNUc4ajJ0RUh3aDRRL2hFeHBodVh4cGlkaW4wNmtPRGc2Y1JxTEJoSkpvNzJ3MjAvMzc5NTJnMk5TczFXaUFIb3NMaVNUSklmTFQwMU8zbU9BVnNualdDbUc5S3BYS1NzcVR1anlleWFMeGRkMVY0VjVxdFpvVE5LanZORTFYZGtBQnluZzNteEhGWXNHWEVPcGE0SXF5OVB0OUJ5QXBYckZ1c0Znc2FqcWRxdFBwdUxySU9JN2RMcUI2dmE2ZDNWMzk1UDVVWDc4ZGFLZWVXMW9CVDVwRm1YNzQza0xmZk45VFBoY3FpU01IdWllVGljSjZ2ZTQwbUVIWVlvZkpaS0xkM1YxWGtZckpINC9IeXVWeWp1SHE5WHJPSkRPWjdJUWxiT0VybkFMZ2t0UXd2MmV4TUlYMWVsMmowY2loZVFBZEdUT3lleFNjQUdhcDZBV1RFSllPQmdPWE9WeVBNaEFDU3psVHdnMkRGa1dSV3EyV1cyVEdpQkxZTW5VMGpiK2JUcWVPTUNKN09wbE1mb25mZCtUT0JRbEVEUUNFWEtQUmNPVmtZUmdxU2FXbk5ueTFxa3ZjRUtmU0g3ODUwODhlTGZSNGtDZ0lmT1V2MWdiY2s4dmxsaHREa0ZSTUlOSnFZMVdrRHJOUHJNeExBVm9JY2FpRnR6dGtZUGQ0a2NWaW9jRmdzRkk4S2wwV0xpQmdwVkxKVlJzUk51S0RiWTRlZ0FXQlFtMmROZTJFZSt5NHNhaWRmQUVBMkNiQkVBNnlsOXdUUzRHZnhxcVFQVVNnSlRtaFEvdkpTUkRhRWtJeUpuWVlzV2o1ZkY3MWVuM0Z0ZkZPZ2UvclM3ZHFDZ05Qa3FlN25VaC84dlpNYVNiNWtpYmpzVVltODhselFzd1NzUzdXQUFSc09YMGtIU1NjWmN2S1djZ1FCdGJ0ZHQwaWc2S1p0T1BqWTFkc1FySUg0ZUg1QUxIOS9YMkhrQ0Z4dU9yMXVyTWVGcHV3TUdnUlpkc3NNaTdHTGhBTDNPbDBYSWlIcndWY1FqSGo2d0daclZaTHVWek9GV0pZbmdUdzIyZzB0TE96NC9DQTFYTDRDQkpPUkRtNHJtcTE2dHdlOUx3bDcwcWxrcWF6dWNyK1hNOXQrODcwLy9oaHBEVHpsQXVrT0U0Y3lNZUtPc2FUbENuYXdJdmlFdENDWHEvbjJEU2JDS0xzYXo2Zk8wMjJLVTViQVNQSmhVTmdEMkorTzJsSmtyanFHUnZTSVdBa1J1d1dNZnRNSm5LeFdEZ05reTYzWlFkQjRFQVp4U1ZCc095TkFPS3YxK3Z1WGxZNDRTK3dldmg0Zm1ZcmhxRjhFV0JiSVkzL0owTnFVOFNNRVFhVnpidVlicnUzMFBkOTlmb0RmZVFnVmFWVWxsSnBORTMxNW1tbWZCaElTbDFOQWU5aVM5M0R3V0RnZkp5bGYyMVJJeHBUcjlkWFhzQ3lmWVJzeEt1WU0wd2dNV3kxV25WYnNQaDdKaEpOaStOWVoyZG5Db0pBeldiVE1XVUlBZHpEY0RqVTF0YVdJNWJzaFlEaUVrRHJZSWxXcXlYZjkxMTlJQnFIc0orZG5Ubno2dnYrU2xnWWh1RktpaGozZzFXQjBrV3grdjIrN3QyN3A1MmRIVFdiVFdlQzAzUzVHWFZyYTJzbEF3cHV3VExpRWxGS1dNTk9wNk5PdDZ2SmFLUlBmbnAzcWZwK3BqZmJxYzdHcWJJa2NpRTFZQkZYNDhMaXlXVGl3aGNienNIRkk2bjcrL3NydVdXYkNMSlZ2a2duUHg4T2gyNGZYeEFFT2pnNGNMWHkxb2RpZ2tuRFp0bXlySG84SG10emM5UHRmS25WYWc0UFVLcHRLVmlFZFRnY3V1M1VrRnhZTTFqR09JNWRXeHR5OUw3dmEzZDNWOFBoME1YdjVBV2dkL3Y5L2tvbHNpU1hUZ1ljd3pXd2dYTTZuYnJFRGhZUllzdHVyV01NbHZ6S3NzeFpBemJsTEltdlZKMXVYN2Rhdm03dEZxVTBVNVpKUDNrUU9XdEttYnZGYU53L1RkTmxWVEFFamszM2drcnRBZ09VOEdOY3BWTEpWYU5JY2x1Y0ZvdUZlcjJlVGs1T1hNS0V6NTZjbkRqT0hyQXpIby9kQkJJTFU0VUQ5ZWtHSG9hdUVtZzRIRHFhZWpRYXVXMXFZQmhBTHBwTUlRdENTWHFXVFNId0JyUlRZYTlFczlsY0FiMTJRWWtJUU84Mm9VT2R4WHFkSHFFZW1VcllVVDRETHVOZTlybkxaMmJLSkgzcDJZYkN2QytsbVk3NnFlNzBzaVh6WjhpeS9mMTlWd3ZCV0pNa1dVWUJQSXhRaHdIaW56Q2RGQjlzYkd3NEpvOXR6KzEyVzZlbnA2NS9FQk5CRGp1S0lyZERGODBETHdCSU1FMndYNlNEbVZCS294RUFUS25kdmNQRVdvUnNldy9ZRUFzU2pOekIxYXRYSGU0QUNCWUtCUmVwYkcxdHVibEFHQzBsalZWQ3V4M1NYbk56akFtc2dmc2g0c0psc2dZSUFYd0hybm0raUxSZHpldWxwMnZMSElBbi9meFJyUEU4ays5ZFdwbGlzYWlyVjY4NmQyTHA5QkN6amVUQkFsTGRTb1RBNEpsZ01udjR3dUZ3Nk13MDVoVHdnNm1iVENZcklBaytuYzJmbUVOOEhidVU4ZHNJQndLQjJlZGV1QlJDUlVrck9RNmJpMEFMbUJCQ1A3UVVLN2RZTExTNXVlbmNqdWQ1MnR2YmN5VlZDTGxsN0hBek1IWldTQURaZGllMGRRazIwNHJtUTdBUmxWQnpPUnBQOU5MMWlyWWJlU25MTkoybit0bkRoUUkvVUpaZTRpRUxwSW1hWUdKRFFCTDhOQkw0NE1FRG5aMmRPWE51MDdoTUxwTGI3WGJkeE1CMVErZXlVSkxjYmwzOEdQN0lGcVFnaENTZk1LczI0Y1Mxbml1dzlYRjJFdEYyRm9kSm9lUU5YMzV5Y3VMOE5ySDhjRGgwdVFRS1dxRElyWDhlRG9jNlB6OTNHMWZtODdsakRNa3FycWQ2QVdKc21zRjZBb1RaTW9ZZ1dQY3dHbzNrSzlYbm42NHY2VjdQMDd2dFdKMUZxRnF0ckVHLzd4YWRORGJOb1pJa2NZcm5ta1J4b1YxdzRUQnZBRCtYUkxqd3VWQ2hvRk8wQzNQVDcvZFh0bnV6NE53VDgwaVpkcWxVY2h3RXdvTW00b0lnZ2RiM0VRQjgySy9Id3FacDZzeTRyVHJHVmFDRjNXNVhSMGRITHJ5bEkwbWFwcnA2OWVwS2tzcGFJUWduM0F1THhXWlR4bUVUVHphN2lzbUhKR09CK3YyK2ttVFpZTU1XMUtacHF0azgwcFdhcCtkMjh5NEYvTVo1WHJtOGxCbmN3TjRJbm8zQXNrczRiTGZiamtpeENEVU1sNDBaaVlmeGxiWkpKTUlEL1VwZklSYVlRcEo2dmE3TnpVMWxXZVlRTk0rYnpXWU8vZHRpVkxzanlTWmV1RGNUeCtmdEJnODdVWXdkbmtPNlRMWGFLaWplZzRtSGltWVRDOUVTVzg5c2x6TjJHYUVrK1BlSER4K3FYQzdyeG8wYlNwTEVoWWRVWDYrN013U00rYmNXMERhMmpPTllvOGxNWDcvZFVLSG9TMG1temtSNnYrc3A5S1VzUzEyVXh2elpQWlA5ZnQvbFRjTHo4M05WS3BVVkhody9EZXZFSUJndzV0anpQRWQrMklWQTA0a1lJSXRnMTRoM3lTdFFjNGcxWWVJdG8wZVJKMEtLOEdIS2JFazdRb3d3VUxPSEFHRkZXRUFtM29JNkFDazFFZmpNL29WcHhhUXpiOHlWNTNrNlB6L1h3NGNQMWUxMlYxaEl3aklXTk1zeUY0TGJBaFZyOHFNbzB1bnBxZnU1Ny91UzV5bnZKL3JjemFwai90NW9TOE9GcDlEUEZFV1grd0VsclpTeGNROHdSVml2MTdXM3QrZXFURmdFZkRtTUduRTdHeU1RQUVJOUtsOHg4VWdxVGFnQWp5d2lpUklTTkV3b09BVHRuYzFtR2c2SEx2eEJ3SkJtdnJmVlFWZ2Z5MFlTUHRxSWdGSXkzb3ZQMUdvMU5adE5UYWRUblorZk80b1g4OC85RVFwY0R1T0dXR3MwR3RyYjIxdlpNa2R4Q056STN0NmVFekF3a08vN0s1dGNzYm91dVpSNitzU05ocTV0TG1QL09KRmVQZkhrZVpsVEtvQXBpdzJRRG9KbEl5eFhlQXN3STlPSHFiRzlkUWxick1SYlJyQlFLTGlhT3dnTHJBYkltUUZKY3Fsa0prN1NTdU1JU1k0T2hzSGpIcmJjR2cybTZnZExZMDBwbitGNzdpbkp1UzVBRWd0RldweE1IOHdjOS9ROHo0WEY1RUw0UEZwTkhzTjJUN0drRVM2QW1CNE1BRTBMaTJrN2x1QzJwck9GdnZ4TVNYN2dTVm1taHdOUHZiU3NSczEzRzNXSU11STQxcDA3ZHhUSHNhNWZ2KzRza3R1VU1ocU4zRU13M1d4RUNNUFE5UTYwdnRKZTFNdkJaQ0VvZHJNRjJUdUFIM1h2OC9sY3JWWnJwUkNFejVGQ1pmRnBPOGZXZElBU3o2SlJoR1c3bUFBV0QrdkRvcWRwNnNnUlc4YkZ0bkFzblJVR1d4OUlNbXc4SHJ0T283N3ZyMVJWcjNNQzRDMFVBa0lLQVJtUHgybzBHcTdFSFdCTnYrRWdDSFc0WGRHTFYzSXU5bisxN1N0S1BaWHlsNVZPek1ONFBOYlIwWkcydHJaY2FUcHVOUXpEeTJ3Z29ZblZjT2pUVXFua3drR2JVYk1BalRKb1VxcGdCMXdCb1IzM3hXUVM2MFBid3JuYkhnV0VxbWdVUXNWa1dST0xtUWNEb08wSTMzZzhkZzJhb0lsWnBEaU9uV1pTRTRFd1VyOW5lUkdzMGQyN2R4MkZUQkdweFV1NEk4c1NzcWp2di8rK3RyYTJkUDM2ZFZlS1JtN0Nwc2hkUXNvTDlPSitxRXB4bWZidERCZjY1bDgvVnE2MnJlTFdwcnJkcnFzeXd0K3p2dVE5QU1VWFJhcVhXNmVaUEY2Y1B3YU5Jc1dXQm1ieW1FZ3FnbWluWXB0QjRUTzczYTdDTU5UR3hvWURLN2JXRGpCSmcwak1MT2FTYWhiU3BiYUpCVnFMaXdDWUFVb0JnQWdJWU5TK0U5clArNTJmbjYrQVQ2eEtvVkRRNXVhbVRrNU8xTzEydGJlM3Q3SnIyUW9laTRqd29PM01NMGtrbEFkQWFydU0rbjZnTU1qMDhkMkxnUWFlL3VMVkkvMzR0ZnZhM3h1bzJ6blg0OGVQMVc2M0ZVV1JheVpkcjlkMWVIaTRVbVVNM2d0aHg2UWxXTnJZMkZoSmE2S3hoRi80UWRLU2xJS0R0UEY1cEdKdDdFeFdhejZmdXdVbDI0WjVSbGp3cFFBMkZwaXhrZ3ZnNzFnZ3RNaldPa0xmVW5sa0NhTWdDTlJ1dDExUGhFNm40M3I3SEI0ZWlteXA3ZUlGU1FSZGkrV3k0N1RLd1lKWHExWFhWdmJodzRlcVZDbzZPRGh3Z291V1NzcytoWGJ1ZmQvWFBJcDByUjdvV3JNZ1pWSWFwZnJaNDFUYkY3VUdEeDgrMVBuNXVYcTludHVqNlB1WHRSMjJGdEpsQTVrRVMxTGdKeW01b3A0ZG9FZGhCS2FVd3RBZ0NGdzl1OTFVUVJFaXlTRHJkbGdNb2cxTDE2NExVQnhmTmxlTzQ5aTlCT2FZdWtXN1JRdmhnZ0N4MklRY1FxL1hjMkRUa2xTbnA2ZnlmZDl0RmNlZFNFdjJqZzZlbUZhRW5uZXpHVWllaVlXRFB5Q2RUQWN2QkFHWEtjbTFlYys4UUY5NmVxRWdXQ3JCeWRCVGZ1ZTJucW5NMUw5b0M4dFljQ1VJS1VKb2dXeVdaY3RHa2FCTEpobUFkWEp5NGtxVkFSVmdCTXU0TVdFc0lDOUpPUmJZQWhOdlNRbGJSa1pJeUhZdmF5cXBtTFZicGUwOXgrT3h6czdPSEhJR3RJSlR5dVd5KzU2RndOdys4OHd6T2owOTFXS3hjQzNlMkJIRjJPRWk2Tk9MV2NaMDEybzFqY2RqOVhvOTV3WVFObW9Wd0NiazVVdWxra3N4STZqMEpEZytQdGIyOXJacjd6NlBJajE5c0tQbnRqSVgrNy9UeXlzb2xMVmRxcXA4SVN3c051Q1VxSWM1NW4zQUppSDhPQ1lhTFVDQ2FkZE9UMkZ1TUJ3TzNkWmxBSXRsMzJ3MHdFQVFFR0ozdElXc0h6dVRtUmpNTjMzeTJhMXovZnIxRlNLSUZ5VGxTaWlKZGVFZTVCbXNPeGtNQm1vMEd0cmMzSFQ5ZHdxRmdudlhYcS9uWEJicFpsd0pZTEZVS3JrK2hrZEhSeTRxb0NXTXBXV2h1MkU3QVpqeitkeGhJaXdiVnJqVDZVaEJUbCs4V1ZHOUtDbVQ1Z3ZwOVZNcFdzemtoVXZMdTd1NzY3Z1JXRlhDWXF3Zjd0c0pBSnJXN1hiVjcvZlZiRGFkcVVlQ09UckYwc1VzTUNHWlJicjRMdHdDUHRQdTlMVnNHc0FTMXdNdWtLVFQwMU5Iby9LVkY3VGtDWjFPRU5CdXQrdVNWOFBoMERXMzV2ZTJKcEFXOFZtMmJFc0xaWXNtdGR0dHRkdHR0NHNISk0yNzRGdEoza2h5a2M1NkFZM3YrNDVvbTgxbU9qOC9YMm54YXB0TmxVb2xuWjJkcWR2dHlmYzlQVlBmbHZ4bDJkYzdaNGxlKytCRW85RlF1WXZvcU5sc09vTHE2YWVmZHBFRFFvRjdRRW56K2Z3eUhZeHA0STlCM3hiUVFHUHlVaXdlL3M3V0I5b3cwdnAxUGsrOHpYTzVKd2tLcUdJYmNpWEpjczhnK1FRazJHWWY4YTFrOFN4WVJlTkIrSnpJQVlNNUhBNTFmSHpzdG8zaEx1cjF1azVPVHZUNDhXTlhWblY0ZUNqZlgxYi9uSjZlYWpxZDZ2RHdVSXZGUXRldVhYT2JQcXliQWhPUjg4ZEtFV0szMjIwZEhSMjU0aFBldjFhcmFUU1phVE0vMDdNN2w0bWYxOXFCQnFPeGhyMmVjcm1jQTMrNEpKVFBjamUyYU5ZSkFDRVMzYkVCZ2ZsODN0WGpqY1lUaGJsVmJlWEFJaGFieU1FZXJRSzR3d3d4R0lnS2FnbVlJSHI3cmpPT0xDRFBzQ0VlTkNmaHF1LzdqbVlGc01KV0lnVGo4ZGhSdGdoNUdJWnVqOE5nTUZnSks2bmx3MldjbnA1cVkyUGpRanU3N3ZTT1pyUHBpbVVRUWphVm5KNmU2dWpvU0pWS3hlMFVQajgvVjdQWmRNZS8zTGx6UitmbjU0NVVhN2ZidW4zN3R2YjM5L1cxcHpPVlNxR1VadXJPQWowWUJ5b1Zjdkl2T3FkWTBnbkVEK25HZ2tOVWdXMnk3S0lzSFA4V0JJRWJkRDYvQkJoQm11aHFLWkQ4bkVaSklHV3hmR1VyaTJ5MUZtU05CdGt0VW53V1JNN0JFWlNEMlhJejdnT2F0WUpqcFpqRUNzZ2Z2QUtPd2ZKUVk0Zlc4WG1pSDkvM1hjVVAwUWJsVkJCUXVJM2o0Mk9YQWFRREtwdE5iUmw3b1ZEUTQ4ZVA5Zmp4WXoxOCtOQzFlQ2NmOFBqeFk4MW1NMTI3ZHMxeENxU1ZOemMzbHdJZEJLcjQwbWVmTGtyWmt2bDc2OHpUdzlPQk9oZjhCUEUrdkFHaHMyVkVVVEtVMk0wbldvcDVJUHp5d29JKzB4em9hNDFmNkdwaHFpajE5T1pzUy8vUHlhSHU5bUpGMDdFaXMzc0ZWQTNZWUVCUXVvQTlQazlyVmMvelhQcVY1N040YURndndUMnNkdmI3ZmZkemdCYmFnRDhtVThkbmdpQndKaHBmelR3Z3ZIWVRCcGFLMEd4N2UxdFhyMTUxNDdJc0p6Nlh5T1RkZDkvVmd3Y1BGTWZMOHdnT0RnNmNGYkFWVCsxMjI5VWRvTUcrNzZzL0hHdmZQOWR1dlNKbFVwSjUrdGFiNTNydDFiYzE2SGRkQk1ZWlFZOGVQWEkxamN3TDQwRzRZRllYaThVeUNyQUFiV2tyQ3ZyS2RrLy91UEdYOHJPWnRKeEhmYm40VU05ZU85Ri9zL2cxdlR1SWxVU1hGY0NBSEtwVm1IeVNHOHZRY0tIQXYreGJhL01QOWd3Z2gxQ053TmlFRGw5eEIzd092QUhRdy9wWW40dUxnUVcwMURUYnV5Q2J5QkJTQStoU3FCZmpMNVZLdW5MbHlncVl4VHFsYWFxSER4L3E2T2pJMVJLd281ZS9MNWZMcnVpRXNudWlLdVpTeXZUU2plSXk4U1BwRjhlUnZ2L2FIWFhPejVRa3k3RDg3YmZmMXVucHFRNFBEN1c5dmUzQXF6Mk5CVXZQM0tFc0liMTZTQUNsOGxUUEpmcEc0M1g1NlV6U2N1S1c2aW50K2NmNnhwVmQvUSs5YldYeFFsRTBYMW9tejFjUStBckRRSXVGM01iUlpkbDFVWUh2cTFyZjBPN1ZweFVFZ1FhZFkwM0hBNUZiUWxLcDAwT1RMSG1CcHVMTFNhUmdEU3c0QllEWjdCK1R5bWVwYmVUM2hHYTRIS3Fac0ZoTUltd24yN1FoaGJBd2dON0hqeDhybjg5cmYzL2ZhU2twZGdRMHk1YW5xN0xEeUhIK1dhWW9UclZYQy9XSnc4b1MvUG0rL3NWMzM5VUhkeDhvaXhkTzBDa3UzZC9mbDZTVjVoaTRKZWJDRnRPT3grTmxqeURicWFKVXJ1cG1QZEdXMTlWeVY5bmFsV1Q2OU5aYzMvaFAvNGw2ZzVINjU0L1ZPenZXb0h1cXlhZ3ZwYkZtazVGeTRVVnUvQUpiUFArWnIrb1RYL3dkVmV0YmtpZE5oajM5NHBYdjZNN3JQMVNhcHU2QUl5WUdxU1hSUkdrVElKTUZZL0VSSExzVkhIeUJlYmN4TXIramJCeUxBMmtERWNZT0pOcTFYcmx5UlllSGg1TGtNblJadGl4TlB6czdjeWVQNGlwMmRuYWMvd1dkMjRWRHVJbGtZRXl6TE5NOGl2VHNickpNL0hpK1RzL0grcE9YUDFDOG1NdlRwYlhKNS9PdWxaOHRoNFB3d1FyWWZBM2NTTGk1dWVsMm94UUtCWVc1VU1WY3VyN3M1dkpVam50NmRyZWk3bk5mbEovTXBXU2hORTIwbUU4MUdmVTFHdzgwR1hZMTdMYlZPenRTdWQ3U1ovN08zNWNmaE1yU3BYbXROYmYxaWEvOGZTbE45ZDRyMzNWa0NINFYzMFo0U1B0V1hBU0lsc1VDTjJDdTJlL0FmV3gzRFM2K0o1UkY4TUFoN1haYmp4OC9kaGdKNFlQaXBuUWQ5NFg3SWQ5dks0d0lSN0VLdGpLSWJWdEVNYTZOMjN5bWozNnNJcWtnK1o1KzhGNVhaOE5ZbmlkNThsWVdmendldTIzbWpVWmp4ZnBaWHNVbXZtYXoyVElYZ0xuTHNrejFaa3YzeDNtTjZtVlZOZGV5NU5TdWY2RGk3RVNmL2FzLzFKMXIvMUIzRHYraEpxVXJDbnhQaFZKRnhYSlZubmZ0NHU4dW80UXNUWlFtc1puOFJINFE2cWtYdjZDM2YvNjlsUncyQ3dKaFJPeE92U0crMjlZWVNKY25uYTN6M1JaSG9EVjhqcisxZXhMNWVhRlFjTFJ0UHI4OHFCbnd4UFBzdGpUMkEwSU8yWWttQy9yZ3dRT2xhYXBXcTZWS3BhTHo4M09IM0RIWHRWcE5HNXZiK3RSVFRkM1lYSlo4WjNHbVYwODlWYW9WRGZ0ZDZTTFMyTnJhY3ZXV2xQZFJ3bTdkS0w0ZlljQ3FoZmdoQUZpcGtOTjVsTk0zUjdmMSs5V1hwVFExUXBCSVNpVXZWSEYyb28rODg5L3Irc04vcFY4Yy9xRSsyUDk5elFzN3l2bVpnaUNUNTEzeTBtajkrcFdscVVyVnBrcTFEZVg3blpXRnQ2WnJ2YXFWSEwwRmg5YmZXV1pSMGkvdHhBRkQyR0lSQkdrd0dEaXlwbFFxNmVtbm4zWUFHUzJYNUk1KzNkalljT0VycnVyazVNUTExNEozT0Q4L1Y3L2ZkNzBBNmFlQVJiR0NlWDUrcnN6ejlmbXY3aXNJbDFOK012WjBIbGNVQnA1TGcyOXZiN3ZHVm5BZXM5bE1EeDQ4Y0x1S0xYYUNGNEJlbnMvbnl6Q1FlQnNRSmkvV3Z6eTZvc1h1Wi9SMzZ4K282VStWeU5lN3VxRTNvajM5bHZleU5yeU9GQlJVbnQ3WHg5NytiM1h3L3YrbTcrc3plalg0aE5MYUZUWHFEWldyRFpXcUc2bzB0cDRvQU11QnBRckQ0SUlmajkwa0VzdmF2UXBvRThrZEpCemZ6bWNKN3dCOFZCcFpwdEx1RVdEeUVUN3VoVFpaNFVOZ2ZOOVhwOU5aMmNOUUtwVWN5Yk8rc0RTN3B0b1o4MDkwWW9WN3ZvaFV5MlY2Zmpkd2laKzN6a01WcXh2YTJkNVc2ZkRRRVhmZ0J5d1FjOWZwZERRYWpWWjZKZURlenM3TzNHWWNSd1hiVFptZVVxVkpxbjkyZjBkL2x0dlFyVmFnZHVGQWYxcjRPK3FuUlQzbi9hNytLUGczK2tid1BlVzlSUEx5Mm93ZjZmZjBVTDgyL3JiK3crTm45ZlA0cHFLZ29tSXUwQXUvOFEzdEhINVVTWExaYUVxUy9DQlF2LzFJOFh5a1NxWHErSEI4RzFJTFFJVk9sZVJDSlduMWNFbk1QbGlBQ2NGa1kwMHNMY3JmOFQzZ3lUWlRzRXdtbU1uMi9BZFV0bG90U1pjdWhTemt4c2FHZG5aMkhMZzhQajVlMFU1cEdZWSs5ZFJUYXA5MzljbkRzaHBsWDBwVHpXTlByNTFreXRMWThRaTg0enBIQWt1THByUGZBbnFmS21yWHNvZjZ1TUZnNERwWkxrMXJyRUtXcWpPVFhqNUtGZWJiS3U4OTFxUjBxSGV6cS9xdm8vOVNMeTl1NngrRzM5TEg4dmVVODFKSmdhNlhCdm92aWovV3ZmaWV2alYvVWE4dXJ1bk9XejlXYmV0QXhYSkRXVVl6SmwvenlVQjNYdnV1Y21FZzM2UnUwV0lFQUZOTi9wd0p0L1F3VW80cklGMXJoY1MyY09Oc0lKN0hJbHNTeVc2WVpXeTB3K0dRcUhhNzdZZ3V0c0dSajhEYUJFSGdkaUVUbjFQMlZhdlZOQmdNTkovUGRmdjJiVjIvY1VNSFY2ZjZuVThGa2pMSjkvVGFvNWwrL09ZanBja2xRMG1kQVNWN1pCWUhnOEZLTzMrYmt3RlVvekJCRUN5emdhQmZKZzhRbENTSlF2K2k2YUVYNlhiL1p4cUhUYzNDbWpKUCttTjlRYU5aVWM5SGQvWGx3dXQ2SWJ5bklJc2wrYm9lbnVnL0Q5dDZ2M2hGM3g2K3FIZC9rR3JyMXErcnNiRXRUOUtvZTZ3SGIvMUlvODZSQ29YTDJOaUNJVFRPNWdYNDN1YmlXU0NidUhKV3h1QUtKb3kvczUwNnFmQWhneGpIc1RxZGppdjJSUFBaMk5KcXRiU3pzK09FY3phYmFiRllyQncrZ2NaaHdUcWRqaXYzaHJTaHJ6RjRRcDZ2Wi9acWV2N0F1eWo2OVBUUHYvTzJYbm50UkpWaTN1MGlCalIzT2gyM1lUUk5VeGNKc0gwTnk4aGNlR3VLRnFMeGhGWk1sUFdQa3BSbW5yTEJpYTVFMzlQZHExOVRKbW5zbGZSNmVGT0ZlSzY3MDMzZERvLzFsZHhmNjdud2dZT05ONE9IZXJwMHBMZkhiK3E3UC91NTNzamRWcXBBNlh5b0pJa1ZCSmNsYVRZSHdQTnQyR2F2SjZGN0xBTk1Jbi9MdmdNMEZST083eVFCUk1ZVFRSME1CcTRKQlhzSVdGQjJJbGs2MjI0RjQzMm9obUwvUUxGWTFNSEJnVHY0Z21qamNoK0RweGQzcFRCY092OEhweE45LzYxanhZdTV4a25rU3ZZUERnNVdlaDdaeU9YR2pSdXVxUmZwZVJScXZZUTloQWEyOFRJM3M2blVNQXkxaUZPRlI2OXF0M3FnbzQyUEs4aGlQZkQzdE9WMzlFejZVTzhrQjNvLzJkTnp3UU45SmYrS2JnVkhTODJVOUpId25wNEpIK25ONUlhK2wzeFNkNE1yeWhUSVQyZnU1WkZVSnM4bW02eUdXd0d3LytjekxLeXQ2SUhoczNYeG9IZDJMWU5CYkgyZXRRcFlSYlNQTWNQOFdjc0RUOENXT2VZeWpwZCszQ2JIY0J1eitVTFZVbDR2N0N4RFB3V2V2dm5xc2M0R00rVkQzN0dmUkVtZFRzZlZFMkRsN0JhMTlYcE1YQUo0eHZmOTVjR1JMdnQzRVNiWkRKSnR2ZUw1dnJ3ZzBOYnhqelNyN3F1VDI1R1hwWG9qdUsxTkRiV1ZEUlZubmw3TnJ1dmQ5S3Blek4zWGwzS3Y2cnEzRklSQXFWNE1mcUdQQlBmMVducEwzMGxmMUIyMWxIcVpmUCtTb0xCeE9zSzRydWsyeGtkZ0VBUSt4d1R3ZXdvOUpMbkZYYmMyY1J5N1hyNVVOQ0VRMG1WVGFEZ0hLM3lFWVVtU3VDN3IwTFQxZXQwSkdRVTB1RnZLNTNxRHNWN1k4YlJkeVV2eU5KdkcrbjkvZkU5cGtpanhMcE51NUNnSWh4RTg4akFjc1dmck9YZ21jMEhFRk5LZWhJVzJtVFZib01sVktKWVZKSFBkT1B1UlJydC9WNUZYME1MTDYrZitzL3I4L0NjcStJbENaY3E4VUs5bXorbTkrSlplOU4vVGIvZy8xNzUzSXNsVHFGaWY4Ti9RUnd2djY2ZkJiWDFuL2xIZG05WGxCWjRDTDE3UkRBc0kxNjhQY3cvOGJ0MUNVQytJY0lGL0xBdm8rNWV0V2VsY1FrOUN0SXZTTmVhTmlpZmNERlZNOUJhR0diUVhPNjhwK3hxUFJwcE9KL3JFL3M2U2dmYzgvZno5TTcxK3J5UGZ2NndzaXFMbDBUU2NTVVIrWW50NzIxWDkyTTZuVmpsc1RzUnR4Y084MmRwNkM3cXNGQkdlZWZJVWpJNTBMZnlwUHRqK2d2d3MxWm5mMGl2Wm9WNmN2SzVTc2FSY0xwRG5KWW95WHo5Sm45ZGJ1cVdQZTIvcmMvN1B0YTB6U2I0S1hxVFA1MTdUcjRYdjY2L0NXL3JPNUZrOWp1dnkwMWllMHBYbnJpL29yN293MWZ3dDk3RVpQVXk1TGU4bVlyQWNCRkVHSVJielE5RW9uMXNzRnE2dklpVmV0bVF1am1ObmdzL1B6MWZvYTBuS1BGODN0aXY2K0dGVldnWlUramN2Mzlka0hxbVVEeVh2c21TKzNXNnJWcXU1VXIzcjE2KzdMbUtkVG1jRmlLNFRRUWlBaTVnb1hyQXh0MDFTY0FHQUx0dXhlTnJzdnFWQllVZnQrak1Lc2tTUFNqZVZ5VlBKUzdXVkxuVE5INmpnWndyOVZKRlgxRi9wazNvdGVWYWY5TjdRWjcyLzFzWkZ3cW5pemZYVjBtdjZUUDREZlc5NlM5K2QzRlk3cVNwUXFzQzd6UDdaOGZCU1Q3cXdIUGgvYStiNWFrMWttcVp1TWdGU05MSUVKMWhxRjBIQUFsQkdocUR5UGZsM0dEaU9jejg1T1ZteERtbWFhcjZJOWJrWFdxcFZsMXUrem50enZYbVNxRm12YVRHZnJZeWYzY0tVcCszdDdhbFVLcW5iN2Jwai8yelNhMzNPVmdwbnJhVFlPTkZLT3krTkNjSi9LRTEwMFA2UkpvVk5UZkl0eVpNZWxKOVJKdWxkWmRwTSsvcUMzdE9tdjVDOFRLR1hhcDZWOU4zMDEvWHo1Qmw5S250Rm44MjlvWVkza2pKZmRYK3EzNjYrb3M4V1A5QjNwcy9vQjdQYkdxaXFJRXZrL3kyMDMzTDdBRmRpWG43UFo2QjYrU3lJM2RZc1dzQm53Mk5MOFdiWjVTa2l0cUtKSEFFaDVkblptZHJ0dGlTNW5EOExNcDh2Rk05Ryt2ek5hMHZ3NTB1dlBsNm90TEdubThXNjd0eTU0NTdGZ1ZQRllsRzNidDFhYVhEQnMzQnYxb3BiQWJBL0N6RXJGdXdCaHBnY3dDQjdBUWdsZk45WGJ0NVhxL3VtSm51L3NlUXRkSWtYMnQ2R2ZwemQxRmZUdDVYM2x5QXl5RElwaXpWVVdYOFcvN3ArdExpdHo0ZXY2YlA1OTFRTnhsSVdxQldNOUkzcVQvV0YwdnY2enV3amVubDJVOTBrcDV5ZnVqU28xWGE3Nk91ZzBaSTdsa1BBTWxEZ1FWVXRsVWk4TTYzeXJIdUFjS0h3QmVESFdKSmsyZnFkSEQrVnhtZ20yOCt6YkZsMmZ0N3Q2OFVyUmQzY0swdHBwaVNWZm42VXFWZ3Fhem9lT1JkeWNIQ2cyN2R2dXg0TExEN1BKZTNjNy9jZE1iWWV6cTlmSWNqVXZpUzBLMmxRd2tQTGJ2SENpUUtOaXhkTkN0ZHZya1FuYXFpZFZYUlZZM25lNVpZc3BZbkNMRllucmVwZlQzNWRQNWcvb3k4WDN0UkxoZmRWOUdkUzVtc242T3NQS2ovVUZ3cnY2RnZUaitpbmk2YzF6UW9LbFN3RndmaDJMc2FMNmJXVk9qYTZzZTRCUkUxb2huYVFIeUdVWXZIaFROaU5aSGYwU3NzSWc4VkJrVWpPZ0RjZ3FMcmRyazVQei9SYlgvKzB3a0lvSmFudW5zNzAydjJCSnBObDNhUWszYnAxU3pkdTNIQUhXOWhrbVExMzRTTjJkblpjZDVkMUlXQStzaXhidWdBNld0TVZoQ0lMVE5oaXNYQWR3eml0SzAxVEpYR3MyQTgxejlmMVlVZFZwUEkxU0F2SzB1Rkt1TVdBdlN4ZENrclMwUDgxK2J5K1AzOVd2MWw4UTUvTTMxSEJYMGlacnl0aFYzOVkrNEcrbkx5cmI4MWUxQ3ZSRGMyenZBSWxVclphTzhBQ01qRk1rclRhOHRWV0hxOUhIZXZBQ1dzQWtRSlp4TEh3ME1iTUM1ckltRERSdkw4dFlWdEVzYmFxb2I3eS9PNnl4YmNuZmYvOWtkNzU0SjRHM1ROWEI3RzF0ZVV5akd6Qnd5SkRYVlBUUVNoTExlUjZOR1RuUDdTVk1iYUsxeFkzZU42eThwU05HVWoyZkQ1VEZzVUtvdkVUTFlBa2VWbXFYREpXN0NmeXZkVWUvL1lLbENxUWRKUnU2ZjhZZjBsL09YdFdYeTI5b1YvTDNWUG9MZW5sYThHWi9sSGwyL29nM3ROZlJCL1Q2NHRyV3FTaFFpK1ZielI4dlI3QUNnR3Vqcnk0L2YzZjVDK3RNTEFmb1Znc3VwWTJkai9rMmRtWjYydElxcGlXNzdhd1pEcGY2SGMrdHErOTdhcVVaQnBOWXYzNVh6L1NXZnRFaTluVVZlL2N1WFBIWlNlcFdwWXVEK2ZtdWJsY1RudDdldzZIMkdJUSsxNnNRMGc2azFDbTArazQ4d1phVE5QVWhVNU1BZzJaa3NWY3JlRUhHalJ1eXJzb0FuSGE3NFZxUkdlcXpFNjA4RXZLWFFnQXdHd2R4WHVlcDBDSlBOL1QvWFJQLzh0b1I3ZkR4L3BxNlEyOWtIc2dUOHZhaEtmREl6MFZIdXVkM0lIK1l2RnJlaWU2b2pqekZIckx0dW5lRTF3RGkyeDVqaWRGRm94akhUZXMvMTVhS2drbGFLUFJ5QlZacEducStpUndHZ2lSQmhpcVdDd3FDSFB5MGxqL3lVdlhKWGxTS0wzOGZrYy9mZk91WnRPSndpRFFsU3RYWEdVeTZkMGdDTnh4TTFodlNDdTdYclpZaG9XM2k1OWwyYkpUcU9YZ29UUWhGTkFZQzRMd25iN3ZLL1Y4dFlZZmFOSjVWZTJORjVSNW9ST0NVdFRYcmNGUEpVMFY1UytMTmV4QTFnZkk1T2I4VEVtYTZkMzRpdTZNcitpaitTUDladjVWUFJNK1dpNkNwT2ZDQjNvbWZLdzNva1A5eGVKRnZSL3ZLYzR5QllwWHFuL1g3Mjh6Z0gvVE9HenhpUldPZGRyYUhra0RBd2hYZ0NDUmVTVXY0QWM1ZmZMV2psNTZkbGRLbHViL3A0OFNIVnc3MUdJNmRwYVhuYzY0R0lDbExYT3psVXgydTU1ZE93Z3Y2L3BDU1N1aEhRY1JzZjJLSnBBVUZyQ0I5REpkS3lsTGRlMzBoMnFNSDZoWHZxWTBMS2c4NzJwbmVrOVZiNmFvVUhLUnhycDIvaXB5Snd5Q1pkVGdlWG96dWFIM3BnZDZQdmRBWDg2OW9xZUR4OHZKVjZvWGN4L29vN2tIZWlXNm9XL05udGVkYUZ1WmxwVkp2Q2hJR3NGZ01YK1ZOV0x5d0VRV1orQXkrVnNvV2k0U1Rtd3lCUXhDSTI5dmJ5dkpQUDNPcHcrVUwrV2tKTlZSZDZHM1RoYmEzZDZTNzIydEZJdFE1RW1MT25iK01KZHNhTVVOc0xGWGtndEppVmdJRlgzZlh4SkJESklpU29vbTdBWlBBQVlkd3dpaExnZFZWR3Z5UVBYaFBZVmhUb0V2WmZJVUJhRzhDNzZhaWh4TGF2eE43SjZ6Q0Y2aVRJRmVUVzdwbmVSUUw0UjM5T1h3RlYwTGx2UnlvRVNmekwybkY4SjcrdW5pYVgxNy9vSWVwWnZ5TWw5ZUdxM2dndldJeDRadzlwbnJUQ2hDd0lLdVd4SGY5MWZxQ0tsdVF0RFkvYk81dWFseXBhcGFLZERmKzdVclMrMzNwWmZ2akRXWUppcmtKSG0rNjRobTU0c3Q2dndmaTJEbmtzNXFsSjFkdlhwMXBVb0tDeFlFd2JJZ0JGNmJmZTUweVlLbElsdG1nUk1aSnFwNUM0V0NzbHhPV1Jvcjh6eGwvdElYWlJkYVI1cldhbzFGN1grYnkvY2tMNHNVZTRGK25uMVViMFZQNmVQSmUvcFMrSXAyL1hOSm52SmVyTThWM3RMSDgzZjE0OFZ0L1lYM0VUMmFWNVY1bVhLNTFXTlhzUWFXT3JhQ2grbTJic01XcXF6L0RSYzFlK1FRQUk2TlJzUFZBTVNwOUluRHVnNjJTbEtXYVRIUDlNTVBKdkxOTTZQbzhyaDVnQjd1SlpmTE9ieEJtem1FaFdvbGhNNXVsckhhSHdUQjBnSlFVVUluREVBZ0h5TFp3UTVncXkza3ZxVkxVR1hOUEd5YTNiMXJ6YkNrRDlXODljVnc0RXlaQ2tHcVRDWDlWZnd4dlJvL3JjL2szdFVYd3RlMDZYVWsrU3A1QzMycDhKbyttWDlmUDVqZTFyZEdOM1VhVitYN2lid3NYWjYwcmRXMDg0Y3RxQjJISGUvNlpYa0hxMlZjN0MxTTAweWVwTTgrVmJyWWV1SHI1KytkNlNmdlBMckk5SVVyM1U5SUF3UDhPRGFXenFZY2drVVVSQVdRcEpVamN5VTVBWEFKdjFLcDVKb2RFTjRCT0FDR1NMQWxVU2pWQm4xYXpWcG41R3oxTFFVS0NCYWZSU2pXRjkvZWMzVkNQU2xMbGZkU3pWVFVkNUpQNnRYc09YM0dmME12QmErcDZmVWwrYXA2TS8yOXlpdjY5ZUw3K3U3a0dYMXZla3ZuY1ZuU1FsNldyb0JiaFBqL2p5dkxsdDFEN2FFYmtHbnlBbDNiTE9wakI2VmxvWFVnL2VzZmZLQjdEeCtwMWFpNXMzMXp1WnpyMTRnSloyNm9OK1F3Q3VhR2J1bHNtQVdYc0E3TU5mTVpPa0xHdSt5d05adk5WQ3dXVmEvWEhUNkE3N1o1ZDh4TkZFV09Vc1ZOMkczY0xMd3RvZ0JiY0M4RTRGZkY1cnprQ29IamVRbzlTVW8wekVyNlp2cVNmcG84bzEvM1g5ZEw0WnVxZVNNcEM5VDBKL3E5MnMvMHVkSXY5TzNKcy9xcjJVMTFvcnlDTEJZeVpkSCszOFkxL1UyZllUT0ovVXdjeDVyTzUvclVZVk9WeWpMeDg3ZzkwdmZlYW11ejFWVHRJdGN2WFlKenNwS3oyY3gxUlVQcHFITmdYcVhMNGxlaU8wbU9veUFqeXZoRENnaUpUZEZJQUtEZGJjdU5vVTRoaXRnaEE1ZGdld25aWERUYWIzOXUrWE9idWZvd2k4RGdueFREZTJtaVVLbTZhVlYva254T0wwZlA2amZDMS9XWjNEc3FlVk1wODdVZER2VUg5Ui9yaStWZjZKdWpaL1dqNlhVTms3eDhYL0w5OUpjc2dLV1BuMlNkVnA1dmt5d201R1hjeS9kTVZTdjYrdXJ6V3hkVlA3NisrOWFaT3BORTE2N1czZGwrekJtbGEvWWNKOUwzOXY0c09JVW9nSFJLMmdrQjExMTBpR2JhZ2tGSnJyS1VoYURzeUpaV0UydmljeWlPdE9ET21sWWJWZUFDZUM0WWdYRFVobHZyN0p6ZDRHakpIcmRZV2FwUTBsblcwTCtlZjBFL2pKN1RGM092NmxPNTkxWHc1bExtYXkvczZRK2JmNlV2bDkvVG40K2UwNDlHVnpSVEtNOVBIS2U1amswc2YvQmhTUlltMk80bHNJVW04eWpXWjY5VzlmVHVzdFZMa2lUNnkzY0hXc3dYNnB5ZnV6TUdXQ0FvZU9teTZUTXVlcDJveXJMbERpKzdaYzNPUFFKZ2NVbG9nZDZUR0RRT1dFclQ5SmNxWTZ6SnRpMWsxZ2tXQnNyL0VZRDFmelpldGx5OW5Wd0xydFp6L1BidnBDVzk3SHVaanJOTi9mUFpWL1M5MmJQNnpjTHIrbmorcm5KZUpHVytydVU3K3NjYlA5Q1h5MXY2MC81dC9YUzhwM2thTEJOTzNpK3phSllYc005OUVxRmszMXRhbXZRNGl2U2JIOWxRc096cnJnK09adnBGZTZZZ2tLdnpJelBKKytQTE56YzMzVHNpYUlTRnpBZFdGcHFhNTlxaWx4V3JhOE1ndW1LejREWSt0blg0dHZPR2ZXRWVna2JiUmJFUFJZT0lFT3p4c3RaRWNaOTE2MlJmWkgyQjFvVmdLUWlKZkMvVHZXaEwvMnYwSmQwS245TlhTNi9yeGR3RCtSZDVobHZGTS8xWGhYTzlNZHZSbi9adjY5WEpqcUkwVU9nbFVyWmFaQ2xkRWtUcmxzQmFDN0FRZlFzbXM3azJpcDVldXRrUVIzcCs3eGNEelJOUGhRdlRMc2tWcExLQWhOazhFNHR0ZDBMWmRqdVNIQlVNTFUyT3gxNXBtaTdEUUd2U3JFWmFLaGpmRDV2RW9oRlM1UFA1bGI2N0Z2WGJQWFVzbHAwNGkyNnQ4RGk2T1YxdDVXcUZ6Z3JodXNsZXZ3SWxTck5VNzhXNyttQzBvMmZESTMyMStMbytrajl5ZVliblN5ZjZTTEd0VnlkNytwUGVMYjA1M1ZJaVg2RlMrZjR2azBYcjQ3SC9Sd0RvV1RTYXpQWGJYN21sclkyeWxLWWFEQmY2NDVmdmF0Z2ZPZmRJSTJrYlFkRk9wMWFydWVOcmJCOUU1cDdZSHdFZzVmeWs0aENISGRaZkFCTnJlLzJ3V0F6TWJzVWkzV2gvemdReEdMdVk5bUtoOFUwMjlrV3diTVJndVgzTHdxMVR1ZXN2dVU0NmhVcVVwZEtiMFlIZWpmYjAwZkNCL2s3cERUMmJQMW1PVlprK1hqblNpNlVUL1dTOHJ6L3QzOVo3ODliRmU1aFV0cmVhY1Z3WEFpeW43L3VhVEtjSy9WUy8rK2tEeVZ1Q3YyKy9kcVFmdmY2K0F1OHlPMGtCS1M2WFkyNW9NNE1BTUMvZ2pTekwzSFl2cW9adEtmcVRCTUR6TG1vQzBUQmJxNDdtb2NuY25FWUU5aUxUUmJpWVpabWpqVzNmblNkcEt2OFFBbHdOejVZdXQ0R3RML2I2d3R2SnQ5OC9LZjNzZVZLUXhjcms2V2V6cTNwbHNxMlBGeDdxYTlXMzlWUitlZjVoNEtWNnFmWkFuNmdjNjBmanEvcXovaTE5TUdzbzg2UXd2T3hNc241WjNvS2F3ZUY0cWhldk5mWHAyOXRTbkVuSzlIOS83eGVhVEtZcTVsY2JkcU04dU1zd0RMV3pzNk1nV1BZZGV2ejRzZHVzQWdhQVpDSzlUeVJIdFJKcmFsMytSUUN3bXFHRGZnUk0ySWttQnJWcFJpWUJLcElpaENBSUhDZU5LN0hsM2NTamRoRkoxdGc0MVE3K3d4WjczZVJibnVERDRub0xUb01zVVp4S1A1cmUwR3VMcS9wTThaNStxL0syRHZJZExlbmxSRitzM2RHbnkwZjYzdWlhL3J6M3RPN05xcEluZVY3OG9WYUFjWmRLSmVWR1UvM2VTMDhwWDg1TFNhYjM3bmYwL2JjZUsvQXZxVjhVVGJwc2dzR0pvNXVibXk3TVBqNCsxbmc4MXRXclY5MHByTGhhckNoUmxWMUhhN0ZRc05BdW9qWFptRjA0YUZxbXNjMEtyUWFNSUR3QXdmV1c4ZmJFVGp1bzlZc0Z0dzBudVRjZ2FIMDM4UHJpVzBHelFyQXVBUEFWa3VSN25nSXZWWlFGK3N2cGJmMXNlazB2bFQ3UVY2dnZhaS9YbCtTcDVFZjZyY1l2OUxuS1EzMjdmMDEvMXIyaGgzRkJtU2Q1V2swNzJ3Z21sOHZycVlOdC9VZWZ1aVlseXgwLy8vYmx1MnIzcHlybUFpRTdXWmE1azBoUW9pZWxzMG5YYzNZaDY4UWFnYjJ3d05LbGNqRVBEa2h5WTd1ZDJaN3J3OE95N1BLRVRzdndvZm1nWktUUm5rZHM0MzRXYzMxeDFoZUZRVnFMd1dmczV5MlhzTDZvOW5NSTY3b3dyUC9mVTZhY0YydVNodnJ6MGJONmVYcW8zNmpjMFc5VzN0TldPSlF5WDlWZ29kL2RmRSsvVVgra2Y5Kzlwajg3UDlEeExLOGdTMWFLVmgwMlNxV3Z2TENydzkycWxHYWF6aUw5OFUvdXkvZCsyVEl4ZHJ2ZHpPWmdzQ2lXdEhNbDN1SGw4VHlVOGR0ZTBBZ0xjK1Y1bmtMODQ0ZHg0QkFLOUJKdXRWb3J1WEdrRFFtRDBXT2ZQRkpLT1BTa05PcjZ4VDFaR0R0SlZvcjV5dGlmNU92dFBXd3VnM3V1NDVQbDkwc2dtUGRTamRLQy9uand2SDQ0T3RTWHlyL1FWMm9mcUJsT3BNeFhNemZUSCt5K3F5ODNIK3BQMmxmMXpjNmV6dWQ1cFprVkxrOWhJSDMxK2MyTGRLYjAwemZQOWFBYnExbXZLNDRqdDBnV3BKRjlaYnNaU1RvYmp1TEgyUjFrZVJ5S1QxZ2I1cHhuVVZTNmNuQ2tSZXJVb3NFNmxjdGxWL2VPbEZuelR5amkrNzdiQzgvMktQdndzN016YlcxdHFWS3B1QzFZOXVYWHFXT2J0K2ZuNjNFK212Mmt4YmNMYXdYZ3c3YWI4VGZPTW1TcFFxWHF4RVg5aTg1SDlaM0JOZjNkK2dmNmN1MmVxdUZNU24zdDVLZjZ6dzdlMVc5dFB0Sy9QYjJxUHovZVZDY09wRFRXSWs3MTFIWlpuM3Fxc1RUL3ZxZC85K3FwU3BXYVdvVkFhWHA1S2docFhnc0NzV2lVa3RuaVQ0cHNLQVhqODZQUmFLVm1nUGVGMTdGV01yU3NFdkU4ZjRBdm9oT1ZUZlNnV1pnVXVselRzQUM4Z0pEQVRaTnhwTmhoUFcvQVZ3dmtMSFdKa1BCN3l4RThLUjVmeHdMMjczNVY2R2kvejdKc1dkenFwVHFOeXZyZnoxL1VYd3l1NjJ1TjkvV0YyZ09WdzRXVStqb29UdlJIaCsvb2ExdFYvYXVIZS9vUGo2czYzQ3JxSDMxeFY1VnlLR1hTMGRsWVA3NHpWTFZTVWk2OE5OM3M4Mk5UQ3Z2OFlGNUxwWkxyUDh5WlB5QitMQUtjQSszcnJQVWtwV3pYTGN1eVpSaUlmN2IwWnBabGJ2dVUzWWxxK1hvRWh3SGdZMmg3Wm12MCtUL25CM0FHc1kxUDdZS3Vad1laRTgreUllU1RGdjVKaTdnZUhhd0x3SHJVWS8rT3Z3MDhLVkNteDFGZC8zUDc0L3IzM1d2NjdlYjcrbHpqV0FVL2xsSmZUNVZIK3FlMzN0TS8rT1NudGYzc3gxU3VGSnoyNXdMcG9KblhuVjZtUWhnb05SYVEwOG9aUjdWYVhkbWxSZDZmaUFDQ0RWZkJ1UXJXdXZHOXhRMVlpaVJKNVAzZTcvMWVCbmdhajhldUlzaEtEeHBHVEc4UFhZQnRzdElseWZrZUxJbzFaVkVVYVdOalk2VWVZRjBURVFETFRGcUN5Z3FBRllSMXJtSGRHdGo4d2ZwbjFqSEJldGhxQzE2NDF6eGV1cmJieFhOOVkrZUJQdGM4VStBdHBNWjE2Y1gvV1BKekY1M1dMcTdRMTN2M3p2UlAvK1U5elZOZnljWG1rSEs1N09hRTV3UE1MVDlDU00zQ2d4V3M1bk1SR2V6djd5dVh5eTBiUTE2NDdHNjN1MndUeDRzenliUk94YWRZbmdBTFFOMGduYTlaVkJZR1NjUEhZejJJTWtDMzFpV3NnOUIxRGVRaWhGemZ5cmF1dWV0QzhLc0V3QUpLWEpEZElHdXRnUDFjbG1YeXMwUmVGdXZOVVVOdkRhdjZhUGxjLzJEdmdUNTkrem41ZmtGS0wwUHI1UXVrdW4yMXFVOWVQZFZmM3AwcHVIQ1J0bURXcmdtTXFEMXJDUzBHSjdINHRwa0g5OXJlM3RhTkd6ZjA3cnZ2cm5STWM4MmsxeWNJMUNrdFU4S2NYa1ZUYVE1WmdQSGp3WUFNZkQ0Rm9BdzB5ektYV1VSb01QY2ZsdDVkOTlYcmZ0eHRValcvZTVJRnNMOWJ6eUN1TDc0a04yYjdPZXMrckp0TTAxVEtNdVdVS3M1Uy9hVGIwSjFKVmYvVDUzYTBvMThHcFpJazM5ZXp1M2w5LzM2c2ZMZzAvZXVkeTZRbEY0STF0aUFZbGcvU3J0ZnJPWUJ1RjU5VFNWNTc3VFdIRyt3NWhyVmFiWGxlQU1lSkF6b3NrT09oL002U0RUUTNzbWFmTGh4SUdsd0MxU2dra1RZMk5sYUlEaXdCZmg4VGJOMkVaU0J4S1ZndXUwaFdBTllGWVIwRVlzM1doWVZyZmVIWG93ZDN2eXhUbGk1TDFLYVIxQjRuMnZHbEo4cEFscWs5enBUTGhjcm5Bc2Z0V3h6Q1pVTTdCTk1LZ0EwaFVZajFTQzVKRWxkRFdDcVZYSEZKRkVYTGlpQUVnQnNTY3RpRGtaaHNlM2dqdTJvOXozUGRxYmxzanpwK1BoZ01mcW12bnRWQVczMWpKMzU5WXF3Si9EQ3ovNlNmV1ROdUYzVTlrbGkzT0ZZZzE1KzNMamllSjQyalROOTV1NnZuYjIxcmJiT1VGUGpxZG9mNnljT0ZjbXQxR09zWEp0NmFlOWZjNmFJQ0MweGtJd0xjQitUUlpESnhQcjlXcTdrbUZ2UDVYQ0g5NVRESitOZUtxVTBMZ2tDTlJzTzVCeG9kczAvZGxtbEpXb2xQNllaSmswU2FKdGd6QlN5NVk3TisxaFJib1VCWWJMbnpPczM3SkRid1NSWUNiYklzbVVYOWR2R2ZCQndaRzErekxGUE9sLzc0dFlGZU9IaXNMMzE4VC9JdXdsaGZtb3htK2gvLy9UMDk2aTZXUjc1NFQ4NXpNRjZxcmRoa3dyelRCaGJ3RFY5ajZ5N3RQR0xoSmJrV2VVbVNMUGNHYm05dkt3eERkMVQ2T21YS1RaQkFtNmUzaTBpWkdDd1VsU3hrcW14M1Qvd1FaSkZOYi9JQ1FYRFpzUXZ3dDY0eEZyaDkyR0t2LzN4ZDQrd0NyMWNpOGZPL1RjbjRKVGhNTlltay8rNVA3dXRINzNmMXhXZWIyaWg2ZXYzaFNQL21aOGQ2NzF3cUZmTWFSWE9uS091UmtMVTBjUnk3RGliVWJzS2pBTFJ0V1o4TnZ5MVRtMldacXpGMGVPUHJYLzk2QmpqcjkvdE9DSXJGb3ZiMjlsU3IxWnhib0dJSTdXTVFoSUxXTDhNSUZnb0ZuWnljT0NHWnpXYXVWbDFhYnFHaXRidTBDczQ4ejNQWWc4bmcyZnplVnNDeXNFOWFyQ2VoZmlzQTY0dHBoY2ptMDU5MDhSbkwzQzBYSU5Wa3RwQ1hMS1FzMW1DeVVMNVExTzcycHVzdElPbVgwdXZXM1ZqOHhUeVJYS01KTmViZVJsUlpsamxzWWFseUFEclBDVWs1MHI2VVJhV25MUnBqQVNBYXg4VFpqdU13VkVndUJ5Qmd5Z0NHdnI4c05PVzhvUFdGUkZyWjNrU3pCdkxiNjF6RWsxRC8rcUxheFYwWGp2VnJKZFJibzU2ZkpBajI4eXpnWXJGUXZKaHBzWWprK1o2cWxZbzJOcG9PVzBtcnhiZU1uUjdFN1BQTHNteWxweERqSVdSbjhYRmY2NjFpQWJ1MmNnaThFRnJOWW9FSjhRai84STFNUElORjJ0aU1tTXZsWEQ3YStpK2trVlpwV1phNWRDWVVKWGtFZmg5RmtUczFuTTBPcEpJUlVGdmNzTzRXN0dVamhYWHc5eVNmL3FURlhhOW00cklKTVRUUEpuSElaK1R6ZVcxdXR0d3BxNUtjSHlhU3lySWwrWVBMeElMYXNNNEtEc1dnMWlKaW1TK2JlV1VycEJGendmUENlcjIrN0U5LzhYQnJIcDZFdk8zRjVFMm5VM2Q4T3FWSTloLzR3RllOa3pMbVoreGt0ZFpDa3V1TmF4ZGlOQm81aTJOOUhaK3hvWkMwR3RkYklmamJYSllSWFJjc20yaEJFS3d3a0tWakxEYXNaWjZpS0hLSFYvTzN2dStyMVdxNWJpMHNPTytHZ0tGOHRrQ1dlbzBuRVV2cjRhdm5lUXFiemFhVFJNNzRYVS80V0k3Y1RnZy9BeVFDMk5CZzZmTGdabnNjSzF1a3lEWXlZU1JFYkFJSnhzcnp2Sld6Z0R6UGN4MnkxeGNBeXRocS9mb0VyTk8rSCtiZlAweG9zQ0k4MzJvL2MwRHpEY2FKcTJWalo3L2ZYMmtxd1lLeTA0ZlFtbENiUnRDbFVzbFZEcTNUNHRZTkFhUUJpaGJZTWo4aER6ZytQbmJvMGFMSVh3VjhrSER5QjdSQnNST0ZKTnFHRTFnTU5HTGRSVmh6Wmw5T2ttdU1RQU1rcE5taTNEaGVIaVJ0TmNneWxVd083L2VrUWhIN25rOTZkeGFNQmJlTkY2d3dXa3pBd2RPVlNtWGxoTkx0N2UwVndhY052U1IzRWlra0Q1d05ycFVJZ2xKK3R2VlRSR0x6Rit0anp1VnlDbnU5bnN0RjIwSU4ycDdpTjlBV3JJT2xmUUVxYURVRnBFZ3VyQlg5OGRkZERReVZOV1dXRU9KenRGVzFzVHFhaFJZalNHbWF1bWRLV3RFQ3hvOGcyQkxySjRIRUp3bUFEYkdZVk9ZSDEwUUxGNndWYUI5c3dQT2hnaEZHRHNPc1ZDb3JWaEdNUlpVVzRiaTFPSHdPdkxUdUNxd0FaMW1tRUhJQTBnZi96STJRTkM3WVFoNEtTWUZwRG9KZ1JmTzRKNkVrdVczTU9WcEF5M1NFaFFXbEdRVkFCcERKOHpINVlBWjJPNmZwc2xKNU1CaXNWTkpZSVVZanJCa0ZZVE5CTmlyaFdxZGx1U2R6UU5ReW1VeWNlZC9aMlZHcjFWckJBOUMwL0QxdU5FMHZ6M0VrMDJvN20vSU1nUHQ2aFJXZkF3K2dNSlpyWWU1Qys1SmNmSkNRMEw2MGRNazZZVW9vQ2QvZjMzY29FKzNBUEZHcURJWEp4R0ZwMWxrNmUrWVBMMDlGREFLQzVtRlZhTzF1N3crdW9lbEZITWR1MGlDeENGdXQ2YlpFRlVxeFhtSExXTkZFeThCaHdkWUZpdm1CQU1NYUVOTHhHZGhXMW9LNXd4SmFWODF6Vm9wY2pVQmhCYmlQZFh2aE9ycTF2NlRZazBsZzRhMjFZQUNXckxFa0J1N0VhcEtkTUVtdUFTV0xGNGFoTzArM1VxbG9hMnZMQ1I0K2p3cmtpOXAyWjliZG1Yc1hZV0t6MlhTTUdhYllUdVo2aFRMZll6NVpMRnJqTUg1YmtHSG53V0tNVXFta1NxWGl6TFZsVGozUDA4N09qbnN2dTNzSHpiWmZDWDBSQU81aE4rb2l1SGJNQ0FPQ2gzSWcwS0hOcTFzTHNBNWlXSEF1SmkrZnoydDdlOXRsQnZIL2xvQmdRaEFPQm04SFlnWEtwbms1YW0xN2U5dU54MjdHd0FKTnAxUFhRZzN0dFZ3Qjk2RllsVENLQ1hRK01ReWQyVVZnMXMwL2lvRzJXYTJTTHM4K0pzekZnbG5hSERUUCsrRFNiRG9YWmNBZFoxbm1yQzNDaWZ1enVaTWdDRndrc1g3SWxpMnRkd1VoOXVMaFBKUUZXdytWZUFsZUNwT0tJSkJPdHFFZjk0ZmpwNFFKbHNzaWRyNlBva2hIUjBkT0tDaDRwSmlrWEM2dmRQcEdhNWpBMld6bWprbVQ1RTRUWS9FM056ZWQ5V0Fod1RsV1cyeUlaN2V3cy9FVFVFc3VoTEFXMzJ1SkhoU0QrV0F1RVNqaWZINW45MkhhZ2hnN1B1dENMYkJsWFN3K3NCYkx1UUJlM2k2eVpabnNUYmdSUDU5TUpzNVVXYXJZdGlxRjNJRnRIQXdHYXJmYlRwcWhtcGxrWGdUaElaWEoyVDBJRkJxRUpneUhRN1ZhTFhkMEsxWUEvTURDWXkyd1pKenRBMFZ0b3dTMG5zVmtYRGJleHVKWS8yeXRHdS9EQXRxZjJ5eW5YVkJibVUxVVlZK2xzWXBwYXpTNUQ1YUFmb1hyQ1ROSlN3RmdjT3UveEhjd1NFdDNXZzIxNUF2L1Q5UFVuYUxCQkRKNHo3dmNabzcvNi9WNnptd0JXaXFWaWtxbGtscXRsdXZCYjNQWmt0d0VzWENEd2NDMXJFRVRPRUdMSmhmbGNubmw0RVhlRHg4UDFyQTdvTEF3dUV3c2hrM0NnRW5zMFRUcmMyckRXdTVMOXBSRnRBUVl0ZjFFVVN6MmszaWFkWExMaHJ6ckFzQzE0Z0lzY0VQU2JkVU9KcytHRS9nNjNBVytsWVdsenFCYXJUcXpQWmxNM0dUYnlpTTBFRitGMzBLYkVTeHlGWXdSd1FJTThlTHNUbW8ybTg1VWo4ZmpsVDJPYUlzdFpTZVVwS2V2ZFhQV3ZTQ3NJRzRFeHlvTmJkNXdSM1pQUHhZVXQySFBSVVJwRUhJcXFoQUFubWZ4bWdXaGpKbUZaKzI0dDdNQUZ1RFpYMWplMy9vd0MrTElaZHNPMVpQSnhGV2RVTVFRQklFejMxbVd1VU9xbUd5THlBbGI4SHNJbGMwVThyZDI0bTNuVE0vejNIMVpMQ0lGaEk2RjUzY2dkdDZYbmJWb0cyTW5wTFhGTXBabG8zWVM4TWlrNDYrcjFhcXpHQlprMjFEVWJyZmozbWl5RmI1MWZQWWsxdFlXa2lJRXpGMFFCTXNlUVVnUGwvVkpWZ0NRSlBzemZOOTRQTlo0UEY3UkF0d0IrUWIrenJZLzQ3SUF5emFsNlBmN3J2ek1tbDhiWFZTclZSZjJBS2lzVlpQa3VteXQ3NjFIRXdHVXNIZSs3N3VOTVFnSlNSYkxydG41UVBqUThpekxYSjRGUHNQM2ZXZktyWXV4bFZDNFc0NjVzOGt4Nit0NXRuMWZxN1IyUFJuYnVzVUliVkdocFdMWGI0YnBzeHM3K1R1U080dkZRdlY2M2NXdHhML3JyZExRVU12TjgxTHJwQVdoajZWU0NZRklvNUpaQS9oRTBmSmtMYlNhUkpmMTRkeC9YZGo1SENFYTRCZDJ6NXBaSnBlSXdSYk0ybmNGeVZ0THgvOVpkQXNjY1JlV2tMTEpMUXN3QWJWMnJTekhnanZFK3EwWDBEb21rQWxCS3ZrL04rRkZyTmFBYU5kZk9Fa1NkYnRkeDJTTlJxTW5hbkN0VmxzQktFUUQrRy9RUHViVHBvR3RsYkFsVDFnQytBSExBTm9KNDNzaURQejFrL2h6TE1BNmV1ZXlaaGJOWCtjNGlGNm9pTEpoSUhQTUJlVk5zUTYvdDN3SzY4SDhXZVcxN3NEMmV3Q3MyMDRzb1VXVS9JRTFIOWJVTVFodVpETkxmTTZpVnNDUFJicnJMMndIR3dTQkt6MkRGMEFiQ2FIUVpwQXlMc2ppQmJ0OWplZGE4c1lpNGlSSjFPdjFYRVJpdVEyckNPdUZyM2JPMWsyd1JlUE1IVVVlL0IveXh6S0VGTlVRdmNBMTJJT3cxME05N21ldEFoZDRCTzIzNjhnOVFpYUVQV1dZRUFvSExiZk5BeXhZaFBYQzkyTUIwQWo2RDF0QWhLYXNhNUcwckpLQnVxVVpFbHlBTmRsMklhd0paekxSV3Z2aWRzTHNWMDRIWFEvVkxKL09QUkVDRmdWc3crZHRQb0dGQit4U0gyRDVCN1NhalozMWV0MUZQZlppanEwbDRwbk1nN1VBbGk2MzFzT2VEeGtFZ2Y0Ly9GTzRXd1htM0NzQUFBQUFTVVZPUks1Q1lJST0="}} \ No newline at end of file diff --git a/sleap/skeletons/mice_of.json b/sleap/skeletons/mice_of.json new file mode 100644 index 000000000..93f6f0438 --- /dev/null +++ b/sleap/skeletons/mice_of.json @@ -0,0 +1 @@ +{"description": "Template Skeleton for mice_of reference dataset.", "nx_graph": {"directed": true, "graph": {"name": "Skeleton-1", "num_edges_inserted": 20}, "links": [{"edge_insert_idx": 3, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["neck1", 1.0]}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegL1", 1.0]}}, "type": {"py/reduce": [{"py/type": "sleap.skeleton.EdgeType"}, {"py/tuple": [1]}]}}, {"edge_insert_idx": 4, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["forelegR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 16, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["nose1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 17, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["earR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 18, "key": 0, "source": {"py/id": 1}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["earL1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 6, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["tailstart1", 1.0]}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegR1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 7, "key": 0, "source": {"py/id": 8}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["hindlegL1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 8, "key": 0, "source": {"py/id": 8}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["tail1", 1.0]}}, "type": {"py/id": 3}}, {"edge_insert_idx": 19, "key": 0, "source": {"py/id": 8}, "target": {"py/id": 1}, "type": {"py/id": 3}}, {"edge_insert_idx": 9, "key": 0, "source": {"py/id": 11}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"py/tuple": ["tailend1", 1.0]}}, "type": {"py/id": 3}}], "multigraph": true, "nodes": [{"id": {"py/id": 5}}, {"id": {"py/id": 1}}, {"id": {"py/id": 7}}, {"id": {"py/id": 6}}, {"id": {"py/id": 2}}, {"id": {"py/id": 4}}, {"id": {"py/id": 8}}, {"id": {"py/id": 10}}, {"id": {"py/id": 9}}, {"id": {"py/id": 11}}, {"id": {"py/id": 12}}]}, "preview_image": {"py/b64": "aVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUlBQUFBQ0FDQVlBQUFERFBtSExBQUFlRGtsRVFWUjRuTzJkZWJSY1ZaM3ZQM3Z2YzA1VjNicGpKakNFQkF3QmpHRXlCTVFHR1pTcEFYMkswTUpTY1dobld2dTViRjJyMTNwdjJVOVgvOUZ0ZDYvV2ZyVHRoQUtpSUdyMGlReU5vQ0FrQkdRS1F5QWhaQ0R6WFBmZXFqckQzdnY5Y2VyVVBWVzM3cGhiOTlZTjk1dDFWdDJjT25XbS9kdS8rZmZid25WZHl5VENXbHZ6S1lRWTl2ajY3NVBmRGZYL0dZd09RZ2lzdGNqSnVsZzlwSlJJT1NtWG44RXdjQ2JqSXVsWldrOE1JM0dBZW94MC9BeEhHQjJTOXpRekJkL2dxQktBRUdMTXM3RlpzSUMyRmozVk4vSUdRSlVBakRFWVk2YnlYZ0FJclVVQWN4MkhiaWtKclVVenc5YWJoYW9PMEFxelA3S1dDOXJ5WE52WnlWc3pHZnFNNFUvRklyY2NPc1MyS01RZDVoNW5aUC80SUNiYkRCd0tvYlc4dDZPRGI4eWRSNXVVUk5ZaWhNQUZuaXFYdVhIbkRuWkZFV29JczNDR0FNYUhHaDFncW1DQUhpbjVkSGNQT1NueEsvSS9zcGFTdGJ3dG0rVzZXYk54czFrOHowTXBOV05DVGhCcWRBQ1lHa0xRMW5KYUxzY2l6eU5zTUpORGF6bS92WjFqWjg4bWw4K1R5V1JRU3RYY2F5c3BzZE1KZzNTQVpyUFNaS0NFRURWS3B5ZmtrRGFwQlRLT1EzZTJpMGhLZktVb2w4dFlhMnZPWWEwZHRZZHhCakdja1Z5dHpVQjZvS1NVdU1DTFVjaXVLR0srNnhMVjNZTzBsZ09aREIyemVpQ1RvYmRRd0hFY0hNZkI5MzJDSUNDS29wbEJId2RrTWhqcFFXazIwbHdBUUFHN3RPYU92ajZrdFRpQXFHd0FrUkNjVWlweGVibE1XMGNIbVZ3TzEzWEpaREswdDdmVDJkbEplM3Q3VlQrWUlZVFJZMUpjd2ZXb2R3MExJWENFNEpiZUFuZ2U3Mjl2NXloajBFS1FxUnlyck9XcVBmc0kyOXY1aGVmaWVCN0dHS1NVR0dQd1BJOHdET252N3llS0lzSXdIQ1FPYk1XeW1NRUFoT000azI0L3BRZWhKaWdrQkpsOG5oUG16dVhObVN3eTM4WloybkQ1L3YwRHZ3WHV5bWI1bVRVVWkwVWtvTFd1NmdKUkZPSDdQc1ZpRWQvM3E0TStveHMweHBSemdCcHVBQkNHN0M0V0tYc2VlV0JmVHpkYVNhN2NzemMrSHJpbVhFWjRMcmQ0SG1FUXhMK3RETExqeEkrVUVFUkNIUFVLNHd4aUhCWUJXR3VSVW81SmQwaG1ZUDFuY2o2dE5YNnBSRWtwSEtBc0pmZDNkaEpaeTN2MzdrTVMrdzJ1Q1VKUWtwdWxKQWhEWkVXVUpMcU02N3JBZ0lzN2lpS2lLRUxybVFoREdvZEZBT05ocDhsdmhuTGthSzN4ZmIrcXpHbXR5WWNodjh2bDhMdTd1T2JnSVJTZ2dXdTBBYVA1bm80SUxBZ3N4aHFzalluQmRWMjAxdFZCTjhiTUVFQWR4cXdEVElRTVRjLytoSXZVbnp1Zno5UFcxbGJWOXJPNUhDcWI1YklvNHE4T0ZYQ3NBYTBKNWk5bTdmSjNVNXAvUEdGL2dZZFczOGVxdFk5U0RuMlVWRlVDMEZwWGxjTVpJaGpBbEJCQUdsTEtLaUdrUHozUEk1L1A0N3B1ZGZNOGozeFBEeGNVUzF4M1lEL205QXZvKzhEbmNEbzZrZFlBQW1IZ0Q0L2N6YmQrOGszOEtLZzZuTkppWUlZSUJqRGxEdlZrZ0JJbExmbE1CaXFSMjhtK2NtOHYvNjBrZHk1WVRQOVZuMEMwNTlHaFR4aUZoRkZBYUVNdVBQOUt6ajNqQWlJZDF2Z2JwSlE0am9QcnVpaWxwdmJCV3dSVFRnRDFGa0d5YWEwSEVZQXhCcjljcG5Ed0FQN0paK0hNbWdOUk5PaDhSbGd1UHVjeW5KVDVsMEFJZ2VNNGVKNkg1M2x2K0tEU21KWEF3L1VXTm5JOUQyVVdKc2VudVlQV210NytYcFIwVVZJUU5lRGsxbWp5cytjalp5L0M3TnNFd3FtS21nU0psUkJGVWRXVlBOa2UwVmJBbFBnQjBoaHU4Sk45VmUxZENDSmp1R1RKRXE1KzgzejhNR3g0VG1FTWU0eUh1dlFycUJmdnc2eDdFT3NYd1hFR21aMUtLVHpQcTFFU0U2N3pSdkFjVGprQkpLaFA3TERXWW9HaTd5T2ppSXd4Wkl6aDQyZXQ0S3NYbkU5Ynh2SkVzVURZM2dXbWxnMVlBYkxOSTl2ZVRiamlPdFNpNWVpbmY0WGQvanpXQURLVy96WHhDS1dxRm9mdisvaStYK1VLUnpJbTNSWGNhRVkxNGdKR0NPWjJkWEgyOGNmUjNkYkc2NGNPOGRFVksvaklXU3ZpQTQybVgzWHlkT2JOME5hQmtoS3cySXBNZDZUZ3ppMEgrT25tL2JpdUI2R1AzdkFJNXJuZlludjNnRXBDVG9OUlZUakxaY3JsOG9RK2Y2dGhTbUlCSXlHS05KY3VleXZmK0IvdjRiUTN2UW5YY2VncmwyblA1Y0JhcUJEUnJhdFhjZXVHYlh6eWsvK0g3dTQ1V0JQUkJpaGpFUklpQS8vMnlpNVc3ZTNIVXhLa2l5M3N4RHo3Rzh5cnE3QlJnSlcxMWtBNmJoQkZFZjM5L1RXQnBTTU5MVWNBV210T1hiQ0FCNzc0QmViMGROZHErWlhCTC9nKy8vemdnOXp4MG5vKzlJV3ZjOHFLODdFVlAwQ3VXS0xyVUI4QWpoRHNMb2Q4NDRYdHZPNWJIRXlWL2R1dHo2S2ZXWW5kOHlwV1NHeUtHNlJGZysvN2xFb2xmTitmckZjd3FXaEpHK2lHYzg1bXpxd2VDTU40MEpNTk1OYnk5ZnZ1NTkvLytERG5YbkkxeTk5eE1XaURNQlpoREtWc2h2NjJMTUphSW1zNXVzM2pFL005Y29lMllJU016Mk1NWXVFWk9KZDhHYm44YWtTbUhXazFTa3FVVWlpbHFxWmlKcE9wcHFBZGlXZ3BBckRXNHJrdTV5MCtBWWFJM0VrcDZROEM4dTJkbkhiMlJaZ29BbW9qaXYzdGJmaVpEQUlJdE9IMFk0N2gydHdCekpOM1Fya1F5MzhkZ2RlR092MTlPSmQrQmVmNHMzQWRCMGNPT0tlMDFsWEZNREVianpTMEZBRkFySUR0TC9ZUCszMi9IK0E0THUyZFBSWFdYM2VNbEJ6TWUvaEdJNFFnTXBZcjNua2w1K2REZVBCZlVWdi9IQjhvQk9nUU1Yc1I0dnpQWXMvNUdIUWNCVHJFVmh4UDFsbzh6eU5YeVVJNjB0QlNCQ0NFSUl3aWZ2SDBNL0hnMUZzTWpzUG1mZnRadldVTFFiR1BMYSsraUZLREI4V1JrcjJGL2R6Ky8zNUlFQVFJUURrZUg3bm04eXpwYmtldC9pSE80emNqRG0wSDVZS05mUXdzZmdkYy9HWGswa3RRYmdaaElxZ0VxL0w1UExsYzdvanpDN1FVQVFCSXBiamppU2RaK2VTVDRMcmdPS0FVZUM2RllwR3YzWHN2KzRwRmRCand5SDEzVVM3MzR6aGVQREJDeEJsR2pzc3JUei9LL1EvK2t0ODhjQ2RLS2JTT21OVTlsdzlmL1huYWNubkVsaWR3SC80UG5IWDNReFNBZEVDSGtPdUdGZGNqTHZvaXpvSmxTR0hCR3FRUTVMTWVEZ2FyTlJ3aFRxSXB0d0lhdVg0anJlbk01ZmpRMldkeDllbW5NN2VqblRXdmJlYkhqei9PcXMyYnllZHlsUVFRT08rU3E3bnl1czh4ZTk1OHBGS1UrZ3RzWEx1YUIxYitnRDI3ZHhFR21yKzU0YXVjZmZxNUJHR0E1M3JjKy9DdnVlV1gvNFVVZ0RIbzJjY1RMZjFMN0ZGdkFlSUJSemtRbEpFYi80Ulk5d0EyOHJGSG5Vd1JqK0xyTCtOdmV3a1QrU0NtdDNMWWNnU1F3RmlMTlFiUGRYR1ZvdC8zb1pMcGswVDFzdGtzQWt2WHJMbWN1R3dGK1h3N3ZRZDJZTU1pNVhLWllyRkUyUy9UMGRiRlZ6LzlkZDQwN3hpMDFnZ0VQL2o1dDNsdzFiMTRyb3ZWRVZaNW1PUE9JVHJwM2RqOGJEQVY4MU00aU1KMnNBYmJjVFJDT2Rpb2pML2xlZmJmL3g5RUIzWWc1UFFsZ3BZbGdBUW1TZWFrTnBFa01kRTh6NnVjeUtDVW9xdXJtNTZlSHFSUytMNlBNWWErWWgrbm52ZzJidnp3VjNIZERFSUkrdm9MZlBQN1gyUEQ1blY0Ymdhd0tDeTJZeDdCa29zSkZwd0IwbzBKUWFqNEJvd0JZbCtFY0RLVU5xeGgzeS8rQWF2RHdmcktORUhMNlFEMWtFSlU4LzBTV0d0cmN2eGMxNlV0MzA0bW15T01JdnFMUllJZ3dGcExHSVk0MHVHNWw1L2lOdy8rSENVbHhtaTZPcnE1NGYyZnBUUGZVNGtHYWdKdDBRZDM0ajMxVTNKcmZvUTZ1Q1VlV0tzcjhRYWIzQUEyOHNrdVBJWHN3bVVJMjdnNktiMnZWZEh5QkRBVTZoTTlremcvUUJBRWxNdmxLaEZJS1hHVXczMFByMlQxTXcvanVSNWhGTExrdUpQNTRGVWZBMncxTEZ3T1FvcmxNdUZyVHlELzhDM0V3VzFWNzJFTnJFVTRIdG41SnlIRjJNUGNyWUpwU3dCSmJrQVN4azFxQUJ6SHdSaERxVlNpVkNwVkkzckdHRXJsTXJldC9ENmJ0bTNFY1Z5Q01PRDhzOTdOdTgrOWlqQUtxdWMyeGhCWkNBcjdNSHMyZ21qd21rU2NkMkNMQjFDT1U2MVlsbExpdWk3WmJMYnFOMmpWd1lkcFRBQVFEMVFZaHRVdENJS3FLOWZ6dkNveFZHc0hFZXpldDVNZi9lSS9LUmI3NHBSMkxIOTF4UTBzTy9GMC9NQ3ZFbFVZUmtTUkpucHRUZXcxckNjQzZVTHZIcHc5cjVESnRWV1ZVNlVVUFQwOUxGeTRrSG56NXVGVWNoQmF0WHA1V2hOQWtqYWVGSWo2dmsrNVhFWktXVlVTazB5Z1pQTmNqeGRlZVlhZjMzTXJRc1JsWmZtMmRqNSt6WTNNbVRXUEtFcEYvcFFETzlhaDE5NGRleHlWRy9zTEhBOUtoK0RwdThqYU1wMWRYZFVzNW82T0R1Yk5tOGV4Q3hjeC85aEY1RHU3UVRxSVJseWtCWERZVnNEaFpzMk1sVDAyS3ZNU0ZRZVFVcXFtVUZSS1dWTVpsRnpQR0FOQzhPbnIvcFlMMzM1cDFUL3c4SnJmOCs4My8yTlZiQWdoWW9VUFVQUGZpcnZrSEd5Mkc3dHZFMnhlQXdkaS9TQmRrR0tNWWRic09WeXcvQ1RPUEM2UDhmdjR3N09idWZ1eGw5bXoveEJLTlo4UXhqSW1MVzhHMWlOTkFQWDdrMktRenM3T2F0TG5VT1h2eGhpNk8zdjR1MC85QTRzWG5rZ1loVGpLNGRaZmZaYzdmbnNMamtxbmo4VW1vcGZOWW96RjZBZ1FnNVJEV3puL0Y2ODZoYzljK1ZieUdRVlNnSUZIMW03alkvLzBXMTdkdnIrU3ZOSThqSVVBV3BNdmpST0oyZGZiMjB1aFVLQ3ZyMi9JWkUrbEZJZDZEM0R6WFRkeHFQY2dTaXFNTVh6Z0x6L01pbFBQUWV1b2VrNFFXT21nRFZnRVFqbnhsaEl0UWdpQ1VIUHBHUXY0MHZ0T0llOHAwQlpDQTlwdzN2S0YvT3VuTDhBWll5bmRlREFXam56RUVFQjZrQk45b0wrL24yS3hXQ01HMHFYaWp1T3lmdE5MM0hIM2o3Q1ZmN2xzanIvKzRCZVlmOVNDS2hHa1JRaFFsZWZwYXhwajhSekorOTl4UE1KUllPb0cyWSs0Nkl4Rm5MYjRLRXo5ZDFPSUNTZUErb1lUSTIzak9mOW92ay9rY2JsY3JwcURqYko5UGRmam9kWDM4Y0NmZm9mcnVFUlJ4TEZ2V3NUSHI3MFJ6OHMyR0h4UmsySmVyV013R2svQmtxTTdCdzkrZkNEdCtTeExqdW1CRnVwN2VNUndnRFNTSXBJa3FTT3hFaElQWXJyUXhCaUROWlk3N3I2WkZ6ZXN4WFU5Z2pEZzdXZWN4d2N1dng1ak5LUWNQZlhFbTdCL0tTVitaSGx0VnlHVysvVVFnbEl4WU11ZUF0QllqNWtLSEpFRUFBUDlBWUFhSWtqdlMyb0VwWlQwRmZ2NDBWMDNzZi9nWHBSU1JEcmlmWmRkejl2ZjlrN0N1dnFENU54SjZwaVVFaVVsb2Jhc2ZIeHp6QUhxaWNCMWVPekY3VHkxZmpkeUVpeUIwYUxtVGxyUlVURmVwQnRDSkpaREVBVFZMUkVGaWFzNDQyWFl0TzFWYnYvTkQ2cS84OXdNZi8zQkw3RG9tT014UnRldy9yUW9TSnhQR2MvaGQzOStuZS84OW5uOFNBOWtuVXZCMnZXNytmdGJWaEZHcGlhd05kV29JWUNKWUV2MW12RklXek5STDcrVGZlbVdNZ21zdFFnRUQ2MjZqN3NmL0NXdTQ2SjF4UHg1eC9ESjY3NUl4c3NTNmRvNnhBVFZQa2RLZ1pEODA4b1hlT2paSGVBb1VJTFg5NWI0L1BlZVlOM1dnemhPNjh4K2FBRVIwRXdpU0FhN1h2dXYvMHpjeU1ZWWhCRGNkYyt0UEx2dXozZ1ZmZURNVTgvaG1pcytUQlJHMWNGT1loSDErb0RqS0x4TWhuS0tWdnA5UTZHa2thTDEraGhPT1FFMEc0MW1lNEpFVElSaFdEM0dkVnlDS09EbU8vOHZ1L2J1UUNtSEtBcDV6OFhYOGhkblhrQVFsS3R0Y1licU8rUW9oZXNvRW0zZllsRlNvQnR3cEtsR1N4REFaSENCWktCcWJYZFRZeHBDVEREV1dEWnNmb1h2Lyt6YmxTaWh3RkVPSC8zQTUxaDR6R0w4d0srcFdrNy9Qckh3WlBxWmJFVVBNUU5WenExQ0NFM3pBd3kxZjZMOEFXTkJFakpPRDN4OWpLRCtYaDNsOEtjbkh1U1g5OXlPb3h5MDFzeWRkUlNmdVBadmFNdmxCN1dvclo2UHl0OWFrN1M3REtLSVFxR0F0VE1jWUVxUW1IeUpuRSszakVtMGVhaFZHdVA5aXR0L2ZUT3Jubm9ZejhzUVJnR25ubndHSDd6aW94Zzd1TG0yTVFZZHhTWm40a1ZFUUxuc3MzLy9mb0lnbkJUbGR5d1lNd0dNOUFCcEpTbTlUZldEcHp1TzFIT0NldTllK2puSzVSTC9lZXUvc0hYN0poekhJWXhDTHJ2Z3ZaeC8xc1g0Z1YralRNYm5IT0Eyc1JrWXkzNnROY2FhbGhwOEdBY0J0Skw4R2lzU2hTK3R2U2ZpWVNoRjBYRWNYdCt4bVp0dStSZks1VEpDU0tTUWZPVDluMkx4d2hNSndvRkdsWkNJZ3loT0xhOGdlVit5eFFZZnBrQUhtRW9rQTU0NGd0THU0a1orZ1FTZWwrSHhaeDdoOWwvL01NNHhNSnFlcmpsODZ2cS9wYnV6QjUxcVVHRUJtNDRGaUlFeXg3SE8vc25nRm04SUhTQ05SUGJIY2xyWFdBTnBVWlVrbUNUNmdWSU9kLzN1Tmg1NS9JR3FQckQwaEZQNTBIcy9HUmVUVmhROGEweFZQMGhnSzZuazFyWmVmdUFiamdCZ0lLMDhhZnhRRFFwVkNDQko3a3luazBraENhT1E3L3prMzlpNGVUMk80eEpHQVJmOXhXVmNmTzRWUk9sNGdhV205NGd4c1pkeFBQY0pnOXZyVHlUZWtBUUFBMFNRSHZ4MEo3SWswVFJ0NHp2S1llZWU3ZHgwNnpmcEwvWWhoUVFFMTEzMWNaYWVlQnBoRkJOQnpEM2tRQmtCU1VQTXc3L3ZlbVgxc004M1lXZWFobWpreVV1TGhIUXdLWG5wR1MvTDA4K3Y0U2NydngvWGpGaERaM3NYbjdqMlJ1Yk9tbGVwV25JSDVmNUpwWENjZ1RUeDBZaUNoQnVsTGFsc05qdWgzR0RDQ2FEVnpKeVIwR2l4ckhTRUw3MGwrb0RqdVB6bXYzL09RNnZ2eDYwVW1aeXc2R1ErY3ZWbnlMZTNrMi9QNDdrdUNRc1FRdUo1TGw3R082eE9JMG5jWWlJVjZxWllBZE1GYWZrUDFMUytUMkw5OVZ0eW5EYWFILy9pTzJ6WXRBNjNvZytjdS94Q3JyancvWldzWkRmSkVnVWh5R1p6MVU0am81MGt5ZjJsZlNzSkFiUXNCNWh1cUU4WlQ1Q1VtdFUzcTNaZEY4ZHh5TGdaOXUzZncvZCs5aTBLZlllUUlpNHl1ZXFpYTFoNndpbG9NeEFPdERZbXFHeWwzOUI0NVhpYTlUZU5BMHkxeDI2eVVSOGJTSkJPTTA5U3pKTy80MllVc1gvZ3BRMXJLMG1sOGJseTJUYmUrNjdyNld5ZkhSZVZZcXNpUll3ekk3aVpjWk1ST2NDUlRoREo0Q2RtWVNPUFlQSU9rbTZpaVNpQTJGUDQ0R1AzOE5EcWU2dEpKUE5tTHlBejV5SktvVXZKT29RVkl0RGF0RnpQd1RlOENJQ0JhR0Y2ZFJFWW5GYVdhT1ZKdTNsakRJTFl3WFBuM1Q5bTNjWVhjQjBYYk1SQnM0ZzFwY3RaM1hzSi90eExlY2RaYjhPYXVBeTltaWZRQW9Rd1F3QVZwTlBHMDF4Z3dFOEFFUkt0TWhpVlFia1paS1V5U0NsRmIzK0JXMzcxWGZZZTJGUGQ3ektMakozRDdJN2xmUHdEWCtHeWQxMkkxaUd0OU5vSDNjbFV4dTJuQ29uenAxd3UxOFFJNGp6QnVNQkhZRGw3WHNDWFR1dmpzNmVVT2JISFlvUkVveWhyZ1JFZXUzZXRaOTNHMVNpVmlBZ0RHSXdKVVRiTGV5NitnYU9QbnQwd2xEeFZhSmx1NGEyQUpIMDg3UUxHY1puWHJ2amE4b084ZTBFSlI4V1Q0Tk1uU2I3N2ZKYkhkbVU1WTI2UlpiTUNGczEyMkgvU2NZUU5GakdJZE1SUnM0OWwyYkxUMmJyMXZwYnBQRHBEQUNrSUlhcnUzMXd1Unk2WHc4a292bnhhTDVjZDN3OWFnb2xuYlZmRzhuZG5sckNtaEpBV2hNSEtOaDV5Mm9ZOHZ4UUtwYnpKZXB4Um9YV0VVUXNnaVE4RVFVQi9meitGdmlKSHF3THZtbCtNQno4dEFTMWdLa0VmS3dDRnNFWG1sWi9HeXNIelNrbkpvYjU5Yk56NEFrTzFxWjhLREVrQTllYmZhTTNCeWN6N2J5YWlLS0szdDU4NXFrQlBacGdWUndYMCtiQmhyMlhsOHhFcjcva2xSWDgzcnBOQklCRUlsSEJ3WEpjL1BQNXJYbjc1dFVucEVUQmF6SWlBWVdIWWNpQ2s0RXM2YzJKd1RhZUVGL1lvUG5WM3dQTTdBd29CQ1BzVWwrNzZLdGRkLzNrV3psNkNhMTMyNnQwOHMrcjMzSHpiRDRqWFNtKytNajFhZC9FTUFRd0RSOExhWFlaSHRocXVXS29nU0gwWmMzMSs4cExpc2MwR0tTeU9BSVRpM2djZTVqbTFnVE51T0JQUFp0aFoyazcvdzRjSUFvR1VFNU1ZVXQ4b28zNndSK3N5bmlHQUVhQ041ZS8vQ0F0N0pLY2NaYW5PWGdPM1AyUDVyeWVLQ0JHazh2MHNEZzdsUTJWZURWNEJhVkhDb2FPbmcxeTJ3TUhDd2FiZGF6TG9UcVZyV1gzUlN5UE1FTUF3c05haUpEeTN6ZWZTMnpUdk8wbHg0U0lvK0paZnJZdTQvMVZOb0VISndUTk45Mm1VVVFncFFJRm9FM1IzZGJQdjRENUtwZEpoNjBmMTEwdUtYRHM2T2dpQ2dHdzJPNmdpdWhGbUNHQVVVTkt5b3hCeTArTWhOejArc0YvS2VQRHJZYkdFdldHOHdyVURTQkJaUVZ1dWpiYTJ0cVlzUkdWdDNFYzVsOHZWNURxT2hCa0NHQ1ZVUmVhUENnSjByOGJxT0JmUVNvdk4ybXFUNjhORkkvbWVkRVE3ZVBBZ3J1dldOTThjRGpNRTBBUUlCQ1kwNkpKR3RhbTQrMUFtN21McXFMaWh4R2htNTFpUnBMc256cXdrbVdRNE5KMEFKdG9YTUMzaUVRS0lZajJBT2ZFdWt6VUlLWkRxOEpNNmg2cTdFRUxVWkRpTjVqcXQ0NUU0d21DMVJmZFh1b1RZbUFDUWpDczl2Sm1ZSVlBbXdVWXBBZ0JNeG1CRjYzR3ZHUUpvQmtSY0htYjZLZ21kVm1BeXBwVkNBRUFsN1h5cWIrSkloYVdXQTlpTXJWb1JreFVqR1UwOFpzWUthQ0owbjY0V2lscHBNWjZaMUI2Um8xR1laemhBa3lBUXNSV1E1SVlvWWdKb0lWaHJ4MDhBMHozY094bUllaU9zSHVBQTJ0VVkzVnBFTU80T0lmWFJxRGNhUnBNckdmVkZzUWl3WU5VQUFiVFM1RGtzRVpEVXlzMmdNYUpDUkJUR0ZVTENFUVFpSUNnRkxkVXBiTnhLWUN2Yy9GUmlwQmxzTUhpdXg2bnpUMmJKZ3VQSmVCN2J6QzRlM2JLR1BZL3VtZkF5Ny9GaXpDdUcxTi8wWkJQQ2RDQThZeXo1MlRrKzl1M3JPUDI4cFJodHdWcWtKem00cjhBUC91ZFBlZkdCbDFzaU03amxlUGlSVUpkZ3JlSGNENS9OMjk2MWpEQ00wRWFqclNIMEkzcm1kUEcrcjF4T3BpTlQyMHRvaXRCeUJERGRra3JyOVNCckxObjJER2Rjdmd3ZERLNFBDUDJJWTA0OG1zVm5IemVvbDlCVW9DRUJEUFhpUjZ2NVQ0ZUJPMXdNUjZES1ViUjM1eHZPY0dzdHJ1ZlMxcFZyOWkyT0NnMEpZRFNEUEJ4TG5raFdQVks3K1lua0dHTTVYN3JaWkgxeVpybmZaOU56VzFIdTROY3JsYVIzZngvYlh0eFJNNkdTRGlTVExlYkdKQUlhTlZJNDBqQWVRcW81WG9BT05ZL2V2b2IrM3RyY1B5a2xidGJoaVh1ZVplZTYzVFVMVG1ReW1TbFJDbHRPQjVoS1RKVFNLUkJzZW5JcmhWMTlDQlVUZ0hRbHhWS0pCMjU3aEpYL2VFL045WktheEtSMzhXUmlKaGpVQkZnc3g1MitrSjc1M1ZoamtVcnk1TXBuK2QxM2ZzL3JMMnhIVXJ2MERGRFRsMkF5NFVCdFE4S1JLa3BHb3REcExoN3E3My9NUFhrc2dPRFVkNzJGYkp0SEZFYVVlMzBldmZsSnRqMi9BeVhqVlBINmR6NFZFRUxncFAzNjA4WDBtZ3FNbGhDTU1lUzdjaXg5NTRub1NDT1ZaUHNMdTlpelpSL0tVWVBPTWRVVHBrb0E5WW1FUTNXa21rNE9tWWxBMGpNNGtkWERQYnNRQWdzc1huNGM4NDZiZ3pFV0pRU3ZQUG9hcFdLODFNeFV5UG5oSUJOSFJuckFoNm9NcnYrK2xSNmttUmoxODFhV2hsbDI0Y2w0V1JjaG9QOUFpVmNmMzRURnRDU1hkV0RvUlI0UzFCY2cxTzlMWTZSWVFhT0hIN2UyM1VCK1R2VExUZXJyWU9TS1cyTXM3ZDE1bHI1elNRMzczN2YxUUxXYmVIS2V3OFZFMUJZSUlXcXRnRFFSalBURDVFVU10ZTVPbzJPaDhjT1BWZEdhN0JrMDJ2c3lSdlBtNVF1WnMzQTJ4bGlrRUt4L2JCTjloYjRSeGNkWWtIUXJtd2h4M0hRenNGSE93R2k1eDdTQ2plMy9oUDJIUVVUeFlJbU5UMnhHMjZHWHJodjM1U1pJRjJzNkFUU2pCS29WWWF5bHZTZlBXODViUWhScGxDUFp0blluQjdZZGloZU1tRUJNcE10NHpBVFFTRDhZcmxGQnMyWDBhREdSRFpZYndSak40aFhITWVmWVdWZ1REM2t6Mkg5OHJZbGJmbTdjaTBaTnR4aDlVN1Z2Q3dMSktSWDJEN0gydjJIMWEvaWhQK0h0WWNlaW80MkVHVmZ3Qk1CYVMvdXNOazVPc2YrdHorMWc5K2E5UkRxYXRFbVNYdW9tV2ZSaXhOOU13bjBkOGRCR2M4S0s0NW16b01MK2plV2xQNjZudDlBM3FUcFEvVHBINDJvU2xYZ0ZoMHNLZ2RyNHdYQm90azR3RmhOeUxETngxT2UxOFlvZ3l5NDhHVGZqRUFVUmZmdjZXZmZvZW94cHZITDVlSkcwZ1VuL1A0MWt4bzhsY2FmaGVnRktxV0VKb0JVeVdsdEMvN0J4QzloOFY0NmxDZnQzRlJ1ZjNNcnV6WHN4REU0V09WeTRyanRpT3Y1WTNrdEREcEIyOHJ4UnpMaXhJbm5KSjU2OW1QTS9kQTZ6anVtSmV3SVl6ZHJmdjBTNVdFWTRFenRKaEJBMUN1VklYSGdvYnBzK2ZoQUJwRTgrNVRPc1JXR3RSVWpCZTc1MENaZDg1Z0ljTDJiOVFnaWl5RkRZMzR1MkdtVW5Qc05uUEdKc3VIMXlxQnk0aE5YWGJ4UE4rdXNmcUpHSjJRb21aL3I2V210T3VmQXRYUGI1aTVCS0VnVlI5UmczNjNEWmpSZVNiYzgwalhzbTkzSTRwbTN5MjFFdkdkTk1PN3JSNEtZRFZLMkE2dlBiT0lIenpQZWNobkxrb0dKUEV4bU9YVHFmRTg1Njg3RHJFVTgxa3VjNWJEL0FTQnJ1U0ZiQVVOOU41c3RLejZhUm5zTllnMVN5NnZGcmRDNG42ekJyZm5mVDduZXNsdGh3NXpsc1A4QklpdUowOUJvMlFwWHRJdENSWnVzTDI1RU51a1FLSWZEN2ZMYS9zclBsR2tMVlEwcloyQXhNSTFsVnEzNGJTWFlQdFkzMStJbmVHaUU5bytxZmY5QjNJdjU3emNxbktSWktPSzZxT2RiTGVieXk2bFUyUGJPbG12dlhMT0lmcTFpdTEvR3N0YkVTMkV5TVpTREdjcjZoL3Q4TTFJc0hwUlRybjlqSVQvL1hTZzdzUEloeUpFN0d3VmpEY3crOHlFLy85MHFpUUUrNXIyUWtXR3NSdVZ6TzFsTisrb1dPRkhrYTZlVzNHdHNmemFDa2syVFRxSGtXRzFzRHN4ZjBzUFQ4aytpYTI4RnJ6MnhoL2VxTitPV2dKU3AvNjVGK25xUVNTV1N6V1F0RG14WXpCSkJTQUJ2b09pWXlHQWIyU3lIakR1RXRpRVlFNENRUFZlOWRhdlRqcWRMU0p4SWozWGY2T2RPZmpYSWhoUkJJUnlLWi9KcSs4U0M1eDNUQVNDYSsvN0cyZXhuTy9YZ2thUDMxYVBRczAvWDVFcWNlZ0pOT0MyOGt0eHBWdjZiL3JtZUxFNW4xTzlrWVB1UFhWTDJqVUdzeDFQODlXVWc0MDFpdVdTL2l4OVVsTE8wU0hxMU1iV3BHemdSaExMcE8rbmxhL2JuU1NNOStnUDhQSTRkcXRleWZPbmtBQUFBQVNVVk9SSzVDWUlJPQ=="}} \ No newline at end of file diff --git a/sleap/training_profiles/baseline.centroid.json b/sleap/training_profiles/baseline.centroid.json index 933989ecf..3a54db25c 100755 --- a/sleap/training_profiles/baseline.centroid.json +++ b/sleap/training_profiles/baseline.centroid.json @@ -116,6 +116,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": true, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/sleap/training_profiles/baseline_large_rf.bottomup.json b/sleap/training_profiles/baseline_large_rf.bottomup.json index ea45c9b25..18fb3104f 100644 --- a/sleap/training_profiles/baseline_large_rf.bottomup.json +++ b/sleap/training_profiles/baseline_large_rf.bottomup.json @@ -125,6 +125,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": true, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/sleap/training_profiles/baseline_large_rf.single.json b/sleap/training_profiles/baseline_large_rf.single.json index 75e97b1a6..3feeccd69 100644 --- a/sleap/training_profiles/baseline_large_rf.single.json +++ b/sleap/training_profiles/baseline_large_rf.single.json @@ -116,6 +116,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": true, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/sleap/training_profiles/baseline_large_rf.topdown.json b/sleap/training_profiles/baseline_large_rf.topdown.json index 9b17f6832..38e96594b 100644 --- a/sleap/training_profiles/baseline_large_rf.topdown.json +++ b/sleap/training_profiles/baseline_large_rf.topdown.json @@ -117,6 +117,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": true, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/sleap/training_profiles/baseline_medium_rf.bottomup.json b/sleap/training_profiles/baseline_medium_rf.bottomup.json index 1cc35330a..61b08515c 100644 --- a/sleap/training_profiles/baseline_medium_rf.bottomup.json +++ b/sleap/training_profiles/baseline_medium_rf.bottomup.json @@ -125,6 +125,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": true, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/sleap/training_profiles/baseline_medium_rf.single.json b/sleap/training_profiles/baseline_medium_rf.single.json index 579f6c8c3..0951bc761 100644 --- a/sleap/training_profiles/baseline_medium_rf.single.json +++ b/sleap/training_profiles/baseline_medium_rf.single.json @@ -116,6 +116,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": true, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/sleap/training_profiles/baseline_medium_rf.topdown.json b/sleap/training_profiles/baseline_medium_rf.topdown.json index 9e3a0bde5..9eccb76c1 100755 --- a/sleap/training_profiles/baseline_medium_rf.topdown.json +++ b/sleap/training_profiles/baseline_medium_rf.topdown.json @@ -117,6 +117,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": true, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/sleap/training_profiles/pretrained.bottomup.json b/sleap/training_profiles/pretrained.bottomup.json index 3e4f3935f..57b7398b5 100644 --- a/sleap/training_profiles/pretrained.bottomup.json +++ b/sleap/training_profiles/pretrained.bottomup.json @@ -122,6 +122,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": true, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/sleap/training_profiles/pretrained.centroid.json b/sleap/training_profiles/pretrained.centroid.json index a5df5e48a..74c43d3e2 100644 --- a/sleap/training_profiles/pretrained.centroid.json +++ b/sleap/training_profiles/pretrained.centroid.json @@ -113,6 +113,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": true, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/sleap/training_profiles/pretrained.single.json b/sleap/training_profiles/pretrained.single.json index 7ca907007..615f0de4d 100644 --- a/sleap/training_profiles/pretrained.single.json +++ b/sleap/training_profiles/pretrained.single.json @@ -113,6 +113,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": true, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/sleap/training_profiles/pretrained.topdown.json b/sleap/training_profiles/pretrained.topdown.json index aeeaebbd8..be0d97de8 100644 --- a/sleap/training_profiles/pretrained.topdown.json +++ b/sleap/training_profiles/pretrained.topdown.json @@ -114,6 +114,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": true, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/sleap/util.py b/sleap/util.py index 1335bcac4..bc3389b7d 100644 --- a/sleap/util.py +++ b/sleap/util.py @@ -1,35 +1,35 @@ -""" -A miscellaneous set of utility functions. Try not to put things in here -unless they really have no other place. +"""A miscellaneous set of utility functions. + +Try not to put things in here unless they really have no other place. """ +import json import os import re import shutil - from collections import defaultdict -from pkg_resources import Requirement, resource_filename - from pathlib import Path +from typing import Any, Dict, Hashable, Iterable, List, Optional from urllib.parse import unquote, urlparse from urllib.request import url2pathname +import attr import h5py as h5 import numpy as np -import attr import psutil -import json import rapidjson import yaml -from typing import Any, Dict, Hashable, Iterable, List, Optional +try: + from importlib.resources import files # New in 3.9+ +except ImportError: + from importlib_resources import files # TODO(LM): Upgrade to importlib.resources. import sleap.version as sleap_version def json_loads(json_str: str) -> Dict: - """ - A simple wrapper around the JSON decoder we are using. + """A simple wrapper around the JSON decoder we are using. Args: json_str: JSON string to decode. @@ -44,8 +44,7 @@ def json_loads(json_str: str) -> Dict: def json_dumps(d: Dict, filename: str = None): - """ - A simple wrapper around the JSON encoder we are using. + """A simple wrapper around the JSON encoder we are using. Args: d: The dict to write. @@ -65,8 +64,7 @@ def json_dumps(d: Dict, filename: str = None): def attr_to_dtype(cls: Any): - """ - Converts classes with basic types to numpy composite dtypes. + """Converts classes with basic types to numpy composite dtypes. Arguments: cls: class to convert @@ -95,8 +93,7 @@ def attr_to_dtype(cls: Any): def usable_cpu_count() -> int: - """ - Gets number of CPUs usable by the current process. + """Gets number of CPUs usable by the current process. Takes into consideration cpusets restrictions. @@ -114,8 +111,7 @@ def usable_cpu_count() -> int: def save_dict_to_hdf5(h5file: h5.File, path: str, dic: dict): - """ - Saves dictionary to an HDF5 file. + """Saves dictionary to an HDF5 file. Calls itself recursively if items in dictionary are not `np.ndarray`, `np.int64`, `np.float64`, `str`, or bytes. @@ -162,8 +158,7 @@ def save_dict_to_hdf5(h5file: h5.File, path: str, dic: dict): def frame_list(frame_str: str) -> Optional[List[int]]: - """ - Converts 'n-m' string to list of ints. + """Converts 'n-m' string to list of ints. Args: frame_str: string representing range @@ -183,8 +178,7 @@ def frame_list(frame_str: str) -> Optional[List[int]]: def uniquify(seq: Iterable[Hashable]) -> List: - """ - Returns unique elements from list, preserving order. + """Returns unique elements from list, preserving order. Note: This will not work on Python 3.5 or lower since dicts don't preserve order. @@ -203,8 +197,7 @@ def uniquify(seq: Iterable[Hashable]) -> List: def weak_filename_match(filename_a: str, filename_b: str) -> bool: - """ - Check if paths probably point to same file. + """Check if paths probably point to same file. Compares the filename and names of two directories up. @@ -228,8 +221,7 @@ def weak_filename_match(filename_a: str, filename_b: str) -> bool: def dict_cut(d: Dict, a: int, b: int) -> Dict: - """ - Helper function for creating subdictionary by numeric indexing of items. + """Helper function for creating subdictionary by numeric indexing of items. Assumes that `dict.items()` will have a fixed order. @@ -246,16 +238,15 @@ def dict_cut(d: Dict, a: int, b: int) -> Dict: def get_package_file(filename: str) -> str: """Returns full path to specified file within sleap package.""" - package_path = Requirement.parse("sleap") - result = resource_filename(package_path, filename) - return result + + data_path: Path = files("sleap").joinpath(filename) + return data_path.as_posix() def get_config_file( shortname: str, ignore_file_not_found: bool = False, get_defaults: bool = False ) -> str: - """ - Returns the full path to the specified config file. + """Returns the full path to the specified config file. The config file will be at ~/.sleap// @@ -276,28 +267,20 @@ def get_config_file( The full path to the specified config file. """ - if not get_defaults: - desired_path = os.path.expanduser( - f"~/.sleap/{sleap_version.__version__}/{shortname}" - ) + desired_path = Path.home() / f".sleap/{sleap_version.__version__}/{shortname}" - # Make sure there's a ~/.sleap// directory to store user version of the - # config file. - try: - os.makedirs(os.path.expanduser(f"~/.sleap/{sleap_version.__version__}")) - except FileExistsError: - pass - - # If we don't care whether the file exists, just return the path - if ignore_file_not_found: - return desired_path + # Make sure there's a ~/.sleap// directory to store user version of the config file. + desired_path.parent.mkdir(parents=True, exist_ok=True) - # If we do care whether the file exists, check the package version of the - # config file if we can't find the user version. + # If we don't care whether the file exists, just return the path + if ignore_file_not_found: + return desired_path - if get_defaults or not os.path.exists(desired_path): - package_path = get_package_file(f"sleap/config/{shortname}") - if not os.path.exists(package_path): + # If we do care whether the file exists, check the package version of the config file if we can't find the user version. + if get_defaults or not desired_path.exists(): + package_path = get_package_file(f"config/{shortname}") + package_path = Path(package_path) + if not package_path.exists(): raise FileNotFoundError( f"Cannot locate {shortname} config file at {desired_path} or {package_path}." ) @@ -352,8 +335,7 @@ def make_scoped_dictionary( def find_files_by_suffix( root_dir: str, suffix: str, prefix: str = "", depth: int = 0 ) -> List[os.DirEntry]: - """ - Returns list of files matching suffix, optionally searching in subdirs. + """Returns list of files matching suffix, optionally searching in subdirs. Args: root_dir: Path to directory where we start searching diff --git a/sleap/version.py b/sleap/version.py index 265563061..698710132 100644 --- a/sleap/version.py +++ b/sleap/version.py @@ -11,8 +11,7 @@ Must be a semver string, "aN" should be appended for alpha releases. """ - -__version__ = "1.2.7" +__version__ = "1.4.1" def versions(): diff --git a/tests/data/csv_format/minimal_instance.000_centered_pair_low_quality.analysis.csv b/tests/data/csv_format/minimal_instance.000_centered_pair_low_quality.analysis.csv new file mode 100644 index 000000000..83d3259be --- /dev/null +++ b/tests/data/csv_format/minimal_instance.000_centered_pair_low_quality.analysis.csv @@ -0,0 +1,2 @@ +track,frame_idx,instance.score,A.x,A.y,A.score,B.x,B.y,B.score +,0,nan,205.9300539013689,187.88964024221963,,278.63521449272383,203.3658657346604, diff --git a/tests/data/dlc/labeled-data/video/CollectedData_LM.csv b/tests/data/dlc/labeled-data/video/CollectedData_LM.csv new file mode 100644 index 000000000..27c86f8af --- /dev/null +++ b/tests/data/dlc/labeled-data/video/CollectedData_LM.csv @@ -0,0 +1,8 @@ +scorer,,,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer +individuals,,,Animal1,Animal1,Animal1,Animal1,Animal1,Animal1,Animal2,Animal2,Animal2,Animal2,Animal2,Animal2,single,single,single,single +bodyparts,,,A,A,B,B,C,C,A,A,B,B,C,C,D,D,E,E +coords,,,x,y,x,y,x,y,x,y,x,y,x,y,x,y,x,y +labeled-data,video,img000.png,0,1,2,3,4,5,6,7,8,9,10,11,,,, +labeled-data,video,img001.png,12,13,,,15,16,17,18,,,20,21,22,23,24,25 +labeled-data,video,img002.png,,,,,,,,,,,, +labeled-data,video,img003.png,26,27,28,29,30,31,,,,,,,32,33,34,35 diff --git a/tests/data/dlc/dlc_testdata.csv b/tests/data/dlc/labeled-data/video/dlc_testdata.csv similarity index 100% rename from tests/data/dlc/dlc_testdata.csv rename to tests/data/dlc/labeled-data/video/dlc_testdata.csv diff --git a/tests/data/dlc/dlc_testdata_v2.csv b/tests/data/dlc/labeled-data/video/dlc_testdata_v2.csv similarity index 100% rename from tests/data/dlc/dlc_testdata_v2.csv rename to tests/data/dlc/labeled-data/video/dlc_testdata_v2.csv diff --git a/tests/data/dlc/img000.png b/tests/data/dlc/labeled-data/video/img000.png similarity index 100% rename from tests/data/dlc/img000.png rename to tests/data/dlc/labeled-data/video/img000.png diff --git a/tests/data/dlc/img001.png b/tests/data/dlc/labeled-data/video/img001.png similarity index 100% rename from tests/data/dlc/img001.png rename to tests/data/dlc/labeled-data/video/img001.png diff --git a/tests/data/dlc/img002.png b/tests/data/dlc/labeled-data/video/img002.png similarity index 100% rename from tests/data/dlc/img002.png rename to tests/data/dlc/labeled-data/video/img002.png diff --git a/tests/data/dlc/img003.png b/tests/data/dlc/labeled-data/video/img003.png similarity index 100% rename from tests/data/dlc/img003.png rename to tests/data/dlc/labeled-data/video/img003.png diff --git a/tests/data/dlc/madlc_testdata.csv b/tests/data/dlc/labeled-data/video/madlc_testdata.csv similarity index 100% rename from tests/data/dlc/madlc_testdata.csv rename to tests/data/dlc/labeled-data/video/madlc_testdata.csv diff --git a/tests/data/dlc/madlc_testdata_v2.csv b/tests/data/dlc/labeled-data/video/madlc_testdata_v2.csv similarity index 100% rename from tests/data/dlc/madlc_testdata_v2.csv rename to tests/data/dlc/labeled-data/video/madlc_testdata_v2.csv diff --git a/tests/data/dlc/labeled-data/video/maudlc_testdata.csv b/tests/data/dlc/labeled-data/video/maudlc_testdata.csv new file mode 100644 index 000000000..4e3e3c28c --- /dev/null +++ b/tests/data/dlc/labeled-data/video/maudlc_testdata.csv @@ -0,0 +1,8 @@ +scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer +individuals,Animal1,Animal1,Animal1,Animal1,Animal1,Animal1,Animal2,Animal2,Animal2,Animal2,Animal2,Animal2,single,single,single,single +bodyparts,A,A,B,B,C,C,A,A,B,B,C,C,D,D,E,E +coords,x,y,x,y,x,y,x,y,x,y,x,y,x,y,x,y +labeled-data/video/img000.png,0,1,2,3,4,5,6,7,8,9,10,11,,,, +labeled-data/video/img001.png,12,13,,,15,16,17,18,,,20,21,22,23,24,25 +labeled-data/video/img002.png,,,,,,,,,,,, +labeled-data/video/img003.png,26,27,28,29,30,31,,,,,,,32,33,34,35 diff --git a/tests/data/dlc/labeled-data/video/maudlc_testdata_v2.csv b/tests/data/dlc/labeled-data/video/maudlc_testdata_v2.csv new file mode 100644 index 000000000..27c86f8af --- /dev/null +++ b/tests/data/dlc/labeled-data/video/maudlc_testdata_v2.csv @@ -0,0 +1,8 @@ +scorer,,,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer,Scorer +individuals,,,Animal1,Animal1,Animal1,Animal1,Animal1,Animal1,Animal2,Animal2,Animal2,Animal2,Animal2,Animal2,single,single,single,single +bodyparts,,,A,A,B,B,C,C,A,A,B,B,C,C,D,D,E,E +coords,,,x,y,x,y,x,y,x,y,x,y,x,y,x,y,x,y +labeled-data,video,img000.png,0,1,2,3,4,5,6,7,8,9,10,11,,,, +labeled-data,video,img001.png,12,13,,,15,16,17,18,,,20,21,22,23,24,25 +labeled-data,video,img002.png,,,,,,,,,,,, +labeled-data,video,img003.png,26,27,28,29,30,31,,,,,,,32,33,34,35 diff --git a/tests/data/dlc/madlc_230_config.yaml b/tests/data/dlc/madlc_230_config.yaml new file mode 100644 index 000000000..01e1d32c1 --- /dev/null +++ b/tests/data/dlc/madlc_230_config.yaml @@ -0,0 +1,69 @@ + # Project definitions (do not edit) +Task: maudlc_2.3.0 +scorer: LM +date: Mar1 +multianimalproject: true +identity: false + + # Project path (change when moving around) +project_path: D:\social-leap-estimates-animal-poses\pull-requests\sleap\tests\data\dlc\maudlc_testdata_v3 + + # Annotation data set configuration (and individual video cropping parameters) +video_sets: + D:\social-leap-estimates-animal-poses\pull-requests\sleap\tests\data\videos\centered_pair_small.mp4: + crop: 0, 384, 0, 384 +individuals: +- individual1 +- individual2 +- individual3 +uniquebodyparts: +- D +- E +multianimalbodyparts: +- A +- B +- C +bodyparts: MULTI! + + # Fraction of video to start/stop when extracting frames for labeling/refinement +start: 0 +stop: 1 +numframes2pick: 20 + + # Plotting configuration +skeleton: +- - A + - B +- - B + - C +- - A + - C +skeleton_color: black +pcutoff: 0.6 +dotsize: 12 +alphavalue: 0.7 +colormap: rainbow + + # Training,Evaluation and Analysis configuration +TrainingFraction: +- 0.95 +iteration: 0 +default_net_type: dlcrnet_ms5 +default_augmenter: multi-animal-imgaug +default_track_method: ellipse +snapshotindex: -1 +batch_size: 8 + + # Cropping Parameters (for analysis and outlier frame detection) +cropping: false + #if cropping is true for analysis, then set the values here: +x1: 0 +x2: 640 +y1: 277 +y2: 624 + + # Refinement configuration (parameters from annotation dataset configuration also relevant in this stage) +corner2move2: +- 50 +- 50 +move2corner: true diff --git a/tests/data/hdf5_format_v1/small_robot.000_small_robot_3_frame.analysis.h5 b/tests/data/hdf5_format_v1/small_robot.000_small_robot_3_frame.analysis.h5 new file mode 100644 index 000000000..d2cec1d1b Binary files /dev/null and b/tests/data/hdf5_format_v1/small_robot.000_small_robot_3_frame.analysis.h5 differ diff --git a/tests/data/models/min_tracks_2node.UNet.bottomup_multiclass/initial_config.json b/tests/data/models/min_tracks_2node.UNet.bottomup_multiclass/initial_config.json index 7e52d1703..2ae0e925c 100644 --- a/tests/data/models/min_tracks_2node.UNet.bottomup_multiclass/initial_config.json +++ b/tests/data/models/min_tracks_2node.UNet.bottomup_multiclass/initial_config.json @@ -128,6 +128,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": false, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/tests/data/models/min_tracks_2node.UNet.bottomup_multiclass/training_config.json b/tests/data/models/min_tracks_2node.UNet.bottomup_multiclass/training_config.json index bcb2f26d5..7b6f817aa 100644 --- a/tests/data/models/min_tracks_2node.UNet.bottomup_multiclass/training_config.json +++ b/tests/data/models/min_tracks_2node.UNet.bottomup_multiclass/training_config.json @@ -191,6 +191,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": false, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/tests/data/models/min_tracks_2node.UNet.topdown_multiclass/initial_config.json b/tests/data/models/min_tracks_2node.UNet.topdown_multiclass/initial_config.json index 045890b21..5d8081628 100644 --- a/tests/data/models/min_tracks_2node.UNet.topdown_multiclass/initial_config.json +++ b/tests/data/models/min_tracks_2node.UNet.topdown_multiclass/initial_config.json @@ -141,7 +141,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": false, - "delete_viz_images": true, + "keep_viz_images": false, "zip_outputs": false, "log_to_csv": true, "checkpointing": { diff --git a/tests/data/models/min_tracks_2node.UNet.topdown_multiclass/training_config.json b/tests/data/models/min_tracks_2node.UNet.topdown_multiclass/training_config.json index 070e9d3c0..9591e5b52 100644 --- a/tests/data/models/min_tracks_2node.UNet.topdown_multiclass/training_config.json +++ b/tests/data/models/min_tracks_2node.UNet.topdown_multiclass/training_config.json @@ -208,7 +208,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": false, - "delete_viz_images": true, + "keep_viz_images": false, "zip_outputs": false, "log_to_csv": true, "checkpointing": { diff --git a/tests/data/models/minimal_instance.UNet.bottomup/initial_config.json b/tests/data/models/minimal_instance.UNet.bottomup/initial_config.json index 8e39fea3f..68e4f894e 100644 --- a/tests/data/models/minimal_instance.UNet.bottomup/initial_config.json +++ b/tests/data/models/minimal_instance.UNet.bottomup/initial_config.json @@ -127,6 +127,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": false, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/tests/data/models/minimal_instance.UNet.bottomup/training_config.json b/tests/data/models/minimal_instance.UNet.bottomup/training_config.json index d1fb718ba..e3bfbc5f8 100644 --- a/tests/data/models/minimal_instance.UNet.bottomup/training_config.json +++ b/tests/data/models/minimal_instance.UNet.bottomup/training_config.json @@ -192,6 +192,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": false, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/tests/data/models/minimal_instance.UNet.centered_instance/initial_config.json b/tests/data/models/minimal_instance.UNet.centered_instance/initial_config.json index 739d8e3e7..f4914aae4 100644 --- a/tests/data/models/minimal_instance.UNet.centered_instance/initial_config.json +++ b/tests/data/models/minimal_instance.UNet.centered_instance/initial_config.json @@ -119,6 +119,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": false, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/tests/data/models/minimal_instance.UNet.centered_instance/training_config.json b/tests/data/models/minimal_instance.UNet.centered_instance/training_config.json index 7b6782a68..e747f6862 100644 --- a/tests/data/models/minimal_instance.UNet.centered_instance/training_config.json +++ b/tests/data/models/minimal_instance.UNet.centered_instance/training_config.json @@ -179,6 +179,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": false, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/tests/data/models/minimal_instance.UNet.centroid/initial_config.json b/tests/data/models/minimal_instance.UNet.centroid/initial_config.json index 41d8ac8c3..977654b2e 100644 --- a/tests/data/models/minimal_instance.UNet.centroid/initial_config.json +++ b/tests/data/models/minimal_instance.UNet.centroid/initial_config.json @@ -118,6 +118,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": false, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/tests/data/models/minimal_instance.UNet.centroid/training_config.json b/tests/data/models/minimal_instance.UNet.centroid/training_config.json index 2d2280a31..02e9683e1 100644 --- a/tests/data/models/minimal_instance.UNet.centroid/training_config.json +++ b/tests/data/models/minimal_instance.UNet.centroid/training_config.json @@ -175,6 +175,7 @@ "runs_folder": "models", "tags": [], "save_visualizations": false, + "keep_viz_images": false, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/tests/data/models/minimal_robot.UNet.single_instance/initial_config.json b/tests/data/models/minimal_robot.UNet.single_instance/initial_config.json index cb2e4f353..f2bb907fa 100644 --- a/tests/data/models/minimal_robot.UNet.single_instance/initial_config.json +++ b/tests/data/models/minimal_robot.UNet.single_instance/initial_config.json @@ -120,6 +120,7 @@ "" ], "save_visualizations": false, + "keep_viz_images": true, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/tests/data/models/minimal_robot.UNet.single_instance/training_config.json b/tests/data/models/minimal_robot.UNet.single_instance/training_config.json index 66901c9f0..dffecc1d9 100644 --- a/tests/data/models/minimal_robot.UNet.single_instance/training_config.json +++ b/tests/data/models/minimal_robot.UNet.single_instance/training_config.json @@ -180,6 +180,7 @@ "" ], "save_visualizations": false, + "keep_viz_images": true, "log_to_csv": true, "checkpointing": { "initial_model": false, diff --git a/tests/data/siv_format_v1/robot_siv.slp b/tests/data/siv_format_v1/small_robot_siv.slp similarity index 100% rename from tests/data/siv_format_v1/robot_siv.slp rename to tests/data/siv_format_v1/small_robot_siv.slp diff --git a/tests/data/siv_format_v2/small_robot_siv_caching.slp b/tests/data/siv_format_v2/small_robot_siv_caching.slp new file mode 100644 index 000000000..864fb9bb5 Binary files /dev/null and b/tests/data/siv_format_v2/small_robot_siv_caching.slp differ diff --git a/tests/data/skeleton/fly_skeleton_legs_pystate_dict.json b/tests/data/skeleton/fly_skeleton_legs_pystate_dict.json new file mode 100644 index 000000000..eae83d6bc --- /dev/null +++ b/tests/data/skeleton/fly_skeleton_legs_pystate_dict.json @@ -0,0 +1 @@ +{"directed": true, "graph": {"name": "skeleton_legs.mat", "num_edges_inserted": 23}, "links": [{"edge_insert_idx": 1, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "neck", "weight": 1.0}}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "head", "weight": 1.0}}, "type": {"py/reduce": [{"py/type": "sleap.skeleton.EdgeType"}, {"py/tuple": [1]}]}}, {"edge_insert_idx": 0, "key": 0, "source": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "thorax", "weight": 1.0}}, "target": {"py/id": 1}, "type": {"py/id": 3}}, {"edge_insert_idx": 2, "key": 0, "source": {"py/id": 4}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "abdomen", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 3, "key": 0, "source": {"py/id": 4}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "wingL", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 4, "key": 0, "source": {"py/id": 4}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "wingR", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 5, "key": 0, "source": {"py/id": 4}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "forelegL1", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 8, "key": 0, "source": {"py/id": 4}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "forelegR1", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 11, "key": 0, "source": {"py/id": 4}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "midlegL1", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 14, "key": 0, "source": {"py/id": 4}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "midlegR1", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 17, "key": 0, "source": {"py/id": 4}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "hindlegL1", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 20, "key": 0, "source": {"py/id": 4}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "hindlegR1", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 6, "key": 0, "source": {"py/id": 8}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "forelegL2", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 7, "key": 0, "source": {"py/id": 14}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "forelegL3", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 9, "key": 0, "source": {"py/id": 9}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "forelegR2", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 10, "key": 0, "source": {"py/id": 16}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "forelegR3", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 12, "key": 0, "source": {"py/id": 10}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "midlegL2", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 13, "key": 0, "source": {"py/id": 18}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "midlegL3", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 15, "key": 0, "source": {"py/id": 11}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "midlegR2", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 16, "key": 0, "source": {"py/id": 20}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "midlegR3", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 18, "key": 0, "source": {"py/id": 12}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "hindlegL2", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 19, "key": 0, "source": {"py/id": 22}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "hindlegL3", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 21, "key": 0, "source": {"py/id": 13}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "hindlegR2", "weight": 1.0}}, "type": {"py/id": 3}}, {"edge_insert_idx": 22, "key": 0, "source": {"py/id": 24}, "target": {"py/object": "sleap.skeleton.Node", "py/state": {"name": "hindlegR3", "weight": 1.0}}, "type": {"py/id": 3}}], "multigraph": true, "nodes": [{"id": {"py/id": 2}}, {"id": {"py/id": 1}}, {"id": {"py/id": 4}}, {"id": {"py/id": 5}}, {"id": {"py/id": 6}}, {"id": {"py/id": 7}}, {"id": {"py/id": 8}}, {"id": {"py/id": 14}}, {"id": {"py/id": 15}}, {"id": {"py/id": 9}}, {"id": {"py/id": 16}}, {"id": {"py/id": 17}}, {"id": {"py/id": 10}}, {"id": {"py/id": 18}}, {"id": {"py/id": 19}}, {"id": {"py/id": 11}}, {"id": {"py/id": 20}}, {"id": {"py/id": 21}}, {"id": {"py/id": 12}}, {"id": {"py/id": 22}}, {"id": {"py/id": 23}}, {"id": {"py/id": 13}}, {"id": {"py/id": 24}}, {"id": {"py/id": 25}}]} \ No newline at end of file diff --git a/tests/data/slp_hdf5/dance.mp4.labels.slp b/tests/data/slp_hdf5/dance.mp4.labels.slp new file mode 100644 index 000000000..bd0626ac3 Binary files /dev/null and b/tests/data/slp_hdf5/dance.mp4.labels.slp differ diff --git a/tests/data/tracks/clip.2node.slp b/tests/data/tracks/clip.2node.slp index ccfaabaca..2d0344f4c 100644 Binary files a/tests/data/tracks/clip.2node.slp and b/tests/data/tracks/clip.2node.slp differ diff --git a/tests/data/tracks/clip.predictions.slp b/tests/data/tracks/clip.predictions.slp new file mode 100644 index 000000000..652e21302 Binary files /dev/null and b/tests/data/tracks/clip.predictions.slp differ diff --git a/tests/data/videos/dance.mp4 b/tests/data/videos/dance.mp4 new file mode 100644 index 000000000..d6b9484d7 Binary files /dev/null and b/tests/data/videos/dance.mp4 differ diff --git a/tests/fixtures/datasets.py b/tests/fixtures/datasets.py index 2660d48e7..c6507caec 100644 --- a/tests/fixtures/datasets.py +++ b/tests/fixtures/datasets.py @@ -19,11 +19,16 @@ TEST_SLP_MIN_LABELS = "tests/data/slp_hdf5/minimal_instance.slp" TEST_MAT_LABELS = "tests/data/mat/labels.mat" TEST_SLP_MIN_LABELS_ROBOT = "tests/data/slp_hdf5/small_robot_minimal.slp" -TEST_SLP_SIV_ROBOT = "tests/data/siv_format_v1/robot_siv.slp" +TEST_SLP_SIV_ROBOT = "tests/data/siv_format_v1/small_robot_siv.slp" +TEST_SLP_SIV_ROBOT_CACHING = "tests/data/siv_format_v2/small_robot_siv_caching.slp" TEST_MIN_TRACKS_2NODE_LABELS = "tests/data/tracks/clip.2node.slp" TEST_MIN_TRACKS_13NODE_LABELS = "tests/data/tracks/clip.slp" TEST_HDF5_PREDICTIONS = "tests/data/hdf5_format_v1/centered_pair_predictions.h5" TEST_SLP_PREDICTIONS = "tests/data/hdf5_format_v1/centered_pair_predictions.slp" +TEST_MIN_DANCE_LABELS = "tests/data/slp_hdf5/dance.mp4.labels.slp" +TEST_CSV_PREDICTIONS = ( + "tests/data/csv_format/minimal_instance.000_centered_pair_low_quality.analysis.csv" +) @pytest.fixture @@ -36,6 +41,13 @@ def centered_pair_predictions(): return Labels.load_file(TEST_JSON_PREDICTIONS) +@pytest.fixture +def centered_pair_predictions_sorted(centered_pair_predictions): + labels: Labels = centered_pair_predictions + labels.labeled_frames.sort(key=lambda lf: lf.frame_idx) + return labels + + @pytest.fixture def min_labels(): return Labels.load_file(TEST_JSON_MIN_LABELS) @@ -59,7 +71,23 @@ def min_labels_robot(): @pytest.fixture def siv_robot(): """Created before grayscale attribute was added to SingleImageVideo backend.""" - return Labels.load_file(TEST_SLP_SIV_ROBOT) + return Labels.load_file(TEST_SLP_SIV_ROBOT, video_search="tests/data/videos/") + + +@pytest.fixture +def siv_robot_caching(): + """Created after caching attribute was added to `SingleImageVideo` backend. + + The typehinting of the `caching` attribute (#1243) caused it to be used by cattrs to + determine which type of dataclass to use. However, the older datasets containing + `SingleImageVideo`s were now being read in as `NumpyVideo`s. Although removing the + typehinting from `caching` seems to do the trick (and never made it into an official + release), this is a fixture to test that datasets created while `caching` was added + into the serialization are read in correctly. + """ + return Labels.load_file( + TEST_SLP_SIV_ROBOT_CACHING, video_search="tests/data/videos/" + ) @pytest.fixture @@ -69,6 +97,20 @@ def min_tracks_2node_labels(): ) +@pytest.fixture +def min_tracks_2node_predictions(): + """ + Generated with: + ``` + sleap-track -m "tests/data/models/min_tracks_2node.UNet.bottomup_multiclass" "tests/data/tracks/clip.mp4" + ``` + """ + return Labels.load_file( + "tests/data/tracks/clip.predictions.slp", + video_search=["tests/data/tracks/clip.mp4"], + ) + + @pytest.fixture def min_tracks_13node_labels(): return Labels.load_file( @@ -229,6 +271,23 @@ def centered_pair_predictions_hdf5_path(): return TEST_HDF5_PREDICTIONS +@pytest.fixture +def minimal_instance_predictions_csv_path(): + return TEST_CSV_PREDICTIONS + + @pytest.fixture def centered_pair_predictions_slp_path(): return TEST_SLP_PREDICTIONS + + +@pytest.fixture +def min_dance_labels(): + return Labels.load_file( + TEST_MIN_DANCE_LABELS, video_search=["tests/data/videos/dance.mp4"] + ) + + +@pytest.fixture +def movenet_video(): + return Video.from_filename("tests/data/videos/dance.mp4") diff --git a/tests/fixtures/instances.py b/tests/fixtures/instances.py index 862577457..78e8f35b8 100644 --- a/tests/fixtures/instances.py +++ b/tests/fixtures/instances.py @@ -1,16 +1,18 @@ import pytest -from sleap.instance import Instance, Point, PredictedInstance +from sleap.instance import Instance, LabeledFrame, Point, PredictedInstance @pytest.fixture -def instances(skeleton): +def instances(skeleton, centered_pair_vid): # Generate some instances NUM_INSTANCES = 500 + video = centered_pair_vid instances = [] for i in range(NUM_INSTANCES): + instance = Instance(skeleton=skeleton) instance["head"] = Point(i * 1, i * 2) instance["left-wing"] = Point(10 + i * 1, 10 + i * 2) @@ -19,6 +21,10 @@ def instances(skeleton): # Lets make an NaN entry to test skip_nan as well instance["thorax"] + # Add a LabeledFrame + labeled_frame = LabeledFrame(video=video, frame_idx=i, instances=[instance]) + instance.frame = labeled_frame + instances.append(instance) return instances diff --git a/tests/fixtures/skeletons.py b/tests/fixtures/skeletons.py index ce214eed2..b432ca2c7 100644 --- a/tests/fixtures/skeletons.py +++ b/tests/fixtures/skeletons.py @@ -3,14 +3,27 @@ from sleap.skeleton import Skeleton TEST_FLY_LEGS_SKELETON = "tests/data/skeleton/fly_skeleton_legs.json" +TEST_FLY_LEGS_SKELETON_DICT = "tests/data/skeleton/fly_skeleton_legs_pystate_dict.json" @pytest.fixture def fly_legs_skeleton_json(): - """Path to fly_skeleton_legs.json""" + """Path to fly_skeleton_legs.json + + This skeleton json has py/state in tuple format. + """ return TEST_FLY_LEGS_SKELETON +@pytest.fixture +def fly_legs_skeleton_dict_json(): + """Path to fly_skeleton_legs_pystate_dict.json + + This skeleton json has py/state dict format. + """ + return TEST_FLY_LEGS_SKELETON_DICT + + @pytest.fixture def stickman(): @@ -48,3 +61,8 @@ def skeleton(): skeleton.add_symmetry(node1="left-wing", node2="right-wing") return skeleton + + +@pytest.fixture +def flies13_skeleton(): + return Skeleton.load_json("sleap/skeletons/flies13.json") diff --git a/tests/fixtures/videos.py b/tests/fixtures/videos.py index 0d13514ba..08974b3de 100644 --- a/tests/fixtures/videos.py +++ b/tests/fixtures/videos.py @@ -1,12 +1,26 @@ import pytest from sleap.io.video import Video +from sleap.io.format.filehandle import FileHandle TEST_H5_FILE = "tests/data/hdf5_format_v1/training.scale=0.50,sigma=10.h5" TEST_H5_DSET = "/box" TEST_H5_CONFMAPS = "/confmaps" TEST_H5_AFFINITY = "/pafs" TEST_H5_INPUT_FORMAT = "channels_first" +TEST_SMALL_ROBOT3_FRAME_H5 = ( + "tests/data/hdf5_format_v1/small_robot.000_small_robot_3_frame.analysis.h5" +) + + +@pytest.fixture +def small_robot_3_frame_hdf5(): + return FileHandle(filename=TEST_SMALL_ROBOT3_FRAME_H5) + + +@pytest.fixture +def hdf5_file_path(): + return TEST_H5_FILE @pytest.fixture @@ -39,11 +53,21 @@ def hdf5_affinity(): TEST_SMALL_CENTERED_PAIR_VID = "tests/data/videos/centered_pair_small.mp4" +@pytest.fixture +def small_robot_mp4_path(): + return TEST_SMALL_ROBOT_MP4_FILE + + @pytest.fixture def small_robot_mp4_vid(): return Video.from_media(TEST_SMALL_ROBOT_MP4_FILE) +@pytest.fixture +def centered_pair_vid_path(): + return TEST_SMALL_CENTERED_PAIR_VID + + @pytest.fixture def centered_pair_vid(): return Video.from_media(TEST_SMALL_CENTERED_PAIR_VID) diff --git a/tests/gui/learning/test_dialog.py b/tests/gui/learning/test_dialog.py new file mode 100644 index 000000000..389bb48a3 --- /dev/null +++ b/tests/gui/learning/test_dialog.py @@ -0,0 +1,451 @@ +import shutil +from typing import Optional, List, Callable, Set +from pathlib import Path +import traceback + +import cattr +import pytest +from qtpy import QtWidgets + +import sleap +from sleap.gui.learning.dialog import LearningDialog, TrainingEditorWidget +from sleap.gui.learning.configs import ( + TrainingConfigFilesWidget, + ConfigFileInfo, + TrainingConfigsGetter, +) +from sleap.gui.learning.scopedkeydict import ( + ScopedKeyDict, + apply_cfg_transforms_to_key_val_dict, +) +from sleap.gui.app import MainWindow +from sleap.io.dataset import Labels +from sleap.nn.config import TrainingJobConfig, UNetConfig +from sleap.util import get_package_file + + +def test_use_hidden_params_from_loaded_config( + qtbot, min_labels_slp, min_bottomup_model_path, tmpdir +): + model_type = Path(min_bottomup_model_path).name + model_path = Path(tmpdir, "models") + model_path.mkdir() + model_path = Path(model_path, model_type) + model_path.mkdir() + + model_dir = str(model_path) + + best_model_path = str(Path(min_bottomup_model_path, "best_model.h5")) + shutil.copy(best_model_path, model_dir) + + cfg_path = str(Path(model_dir, "training_config.json")) + cfg = TrainingJobConfig.load_json(min_bottomup_model_path) + cfg.data.labels.split_by_inds = True + cfg.data.labels.training_inds = [0, 1, 2] + cfg.data.labels.validation_inds = [3, 4, 5] + cfg.data.labels.test_inds = [6, 7, 8] + cfg.filename = cfg_path + + TrainingJobConfig.save_json(cfg, cfg_path) + + # Create a learning dialog + app = MainWindow(no_usage_data=True) + ld = LearningDialog( + mode="training", + labels_filename=model_path.parent.absolute(), # Hack to get correct config + labels=min_labels_slp, + ) + + # Make pipeline_form_widget + ld.pipeline_form_widget.current_pipeline = "bottom-up" + tab_name = "multi_instance" + + # Select a loaded config for pipeline form data + bottom_up_tab: TrainingEditorWidget = ld.tabs[tab_name] + cfg_list_widget: TrainingConfigFilesWidget = bottom_up_tab._cfg_list_widget + cfg_list_widget.update() + training_cfg_info: ConfigFileInfo = list( + filter( + lambda cfg: model_path.name in cfg.path, + cfg_list_widget._cfg_list, + ) + )[0] + training_cfg_info_dict: dict = ScopedKeyDict.from_hierarchical_dict( + cattr.unstructure(training_cfg_info) + ).key_val_dict + menu_idx = cfg_list_widget._cfg_list.index(training_cfg_info) + cfg_list_widget.onSelectionIdxChange(menu_idx) + + # Make some changes to pipeline form data + training_cfg_setting = training_cfg_info.config.data.preprocessing.input_scaling + bottom_up_tab.set_fields_from_key_val_dict( + {"data.preprocessing.input_scaling": training_cfg_setting - 0.1} + ) + + # Create config to use in new round of training + pipeline_form_data = ld.pipeline_form_widget.get_form_data() + config_info = ld.get_every_head_config_data(pipeline_form_data)[0] + config_info_dict: dict = ScopedKeyDict.from_hierarchical_dict( + cattr.unstructure(config_info) + ).key_val_dict + + # Load pipeline form data + tab_cfg_key_val_dict = bottom_up_tab.get_all_form_data() + apply_cfg_transforms_to_key_val_dict(tab_cfg_key_val_dict) + assert ( + tab_cfg_key_val_dict["data.preprocessing.input_scaling"] != training_cfg_setting + ) + + # Assert that config info list: + params_set_in_tab = [f"config.{k}" for k in tab_cfg_key_val_dict.keys()] + params_reset = [ + "config.data.labels.validation_labels", + "config.data.labels.test_labels", + "config.data.labels.split_by_inds", + "config.data.labels.skeletons", + "config.outputs.run_name", + "config.outputs.run_name_suffix", + "config.outputs.tags", + "path", + "filename", + ] + for k, _ in config_info_dict.items(): + if k in params_set_in_tab: + # 1. Prefers data from widget over loaded config + try: + assert config_info_dict[k] == tab_cfg_key_val_dict[k[7:]] + except: + assert str(config_info_dict[k]) == tab_cfg_key_val_dict[k[7:]] + elif k not in params_reset: + # 2. Uses hidden parameters from loaded config + assert config_info_dict[k] == training_cfg_info_dict[k] + + +def test_update_loaded_config(): + base_cfg = TrainingJobConfig() + base_cfg.data.preprocessing.input_scaling = 0.5 + base_cfg.model.backbone.unet = UNetConfig(max_stride=32, output_stride=2) + base_cfg.optimization.augmentation_config.rotation_max_angle = 180 + base_cfg.optimization.augmentation_config.rotation_min_angle = -180 + + gui_vals = { + "data.preprocessing.input_scaling": 1.0, + "model.backbone.pretrained_encoder.encoder": "vgg16", + } + + scoped_cfg = LearningDialog.update_loaded_config(base_cfg, gui_vals) + assert scoped_cfg.key_val_dict["data.preprocessing.input_scaling"] == 1.0 + assert scoped_cfg.key_val_dict["model.backbone.unet"] is None + assert ( + scoped_cfg.key_val_dict["model.backbone.pretrained_encoder.encoder"] == "vgg16" + ) + assert ( + scoped_cfg.key_val_dict["optimization.augmentation_config.rotation_max_angle"] + == 180 + ) + assert ( + scoped_cfg.key_val_dict["optimization.augmentation_config.rotation_min_angle"] + == -180 + ) + + +def test_training_editor_checkbox_states( + qtbot, tmpdir, min_labels: Labels, min_centroid_model_path: str +): + """Test that Use Trained Model and Resume Training checkboxes operate correctly.""" + + def assert_checkbox_states( + ted: TrainingEditorWidget, + use_trained: Optional[bool] = None, + resume_training: Optional[bool] = None, + ): + assert ( + ted._use_trained_model.isChecked() == use_trained + if use_trained is not None + else True + ) + assert ( + ted._resume_training.isChecked() == resume_training + if resume_training is not None + else True + ) + + def switch_states( + ted: TrainingEditorWidget, + prev_use_trained: Optional[bool] = None, + prev_resume_training: Optional[bool] = None, + new_use_trained: Optional[bool] = None, + new_resume_training: Optional[bool] = None, + ): + """Switch the states of the checkboxes.""" + + # Assert previous checkbox state + assert_checkbox_states( + ted, use_trained=prev_use_trained, resume_training=prev_resume_training + ) + + # Switch states + if new_use_trained is not None: + ted._use_trained_model.setChecked(new_use_trained) + if new_resume_training is not None: + ted._resume_training.setChecked(new_resume_training) + + # Assert new checkbox state + assert_checkbox_states( + ted, use_trained=new_use_trained, resume_training=new_resume_training + ) + + def check_resume_training( + ted: TrainingEditorWidget, prev_use_trained: Optional[bool] = None + ): + """Check the Resume Training checkbox.""" + switch_states( + ted, + prev_use_trained=prev_use_trained, + new_use_trained=True, + new_resume_training=True, + ) + assert not ted.use_trained + assert ted.resume_training + + def check_resume_training_00(ted: TrainingEditorWidget): + """Check the Resume Training checkbox when Use Trained is unchecked.""" + check_resume_training(ted, prev_use_trained=False) + + def check_resume_training_10(ted: TrainingEditorWidget): + """Check the Resume Training checkbox when Use Trained is checked.""" + check_resume_training(ted, prev_use_trained=True) + + def check_use_trained(ted: TrainingEditorWidget): + """Check the Use Trained checkbox when Resume Training is unchecked.""" + switch_states(ted, prev_resume_training=False, new_use_trained=True) + assert ted.use_trained + assert not ted.resume_training + + def uncheck_resume_training(ted: TrainingEditorWidget): + """Uncheck the Resume Training checkbox when Use Trained is checked.""" + switch_states(ted, prev_use_trained=True, new_resume_training=False) + assert ted.use_trained + assert not ted.resume_training + + def uncheck_use_trained( + ted: TrainingEditorWidget, prev_resume_training: Optional[bool] = None + ): + """Uncheck the Use Trained checkbox.""" + switch_states( + ted, + prev_resume_training=prev_resume_training, + new_use_trained=False, + new_resume_training=False, + ) + assert not ted.use_trained + assert not ted.resume_training + + def uncheck_use_trained_10(ted: TrainingEditorWidget): + """Uncheck the Use Trained checkbox when Resume Training is unchecked.""" + uncheck_use_trained(ted, prev_resume_training=False) + + def uncheck_use_trained_11(ted: TrainingEditorWidget): + """Uncheck the Use Trained checkbox when Resume Training is checked.""" + uncheck_use_trained(ted, prev_resume_training=True) + + def assert_form_state( + change_state: Callable, + ted: TrainingEditorWidget, + og_form_data: dict, + reset_causing_actions: Set[Callable] = { + check_use_trained, + uncheck_resume_training, + }, + ): + expected_form_data = dict() + + # Read form values before changing state + if change_state not in reset_causing_actions: + expected_form_data = ted.get_all_form_data() + + # Change state + change_state(ted) + + # Modify expected form values depending on state, and check if form is enabled + if ted.resume_training: + for key, val in og_form_data.items(): + if key.startswith("model."): + expected_form_data[key] = val + elif ted.use_trained: + expected_form_data = og_form_data + + # Read form values after changing state + actual_form_data = ted.get_all_form_data() + assert expected_form_data == actual_form_data + + # Load the data + labels: Labels = min_labels + video = labels.video + skeleton = labels.skeleton + model_path = Path(min_centroid_model_path) + + # Spoof an untrained model + untrained_model_path = Path(tmpdir, model_path.parts[-1]) + untrained_model_path.mkdir() + shutil.copy( + Path(model_path, "training_config.json"), + Path(untrained_model_path, "training_config.json"), + ) + + # Create a training TrainingEditorWidget + head_name = (model_path.name).split(".")[-1] + mode = "training" + cfg_getter = TrainingConfigsGetter( + dir_paths=[str(model_path), str(untrained_model_path)], head_filter=head_name + ) + ted = TrainingEditorWidget( + video=video, + skeleton=skeleton, + head=head_name, + cfg_getter=cfg_getter, + require_trained=(mode == "inference"), + ) + ted.update_file_list() + + og_form_data = ted.get_all_form_data() + + # Modify the form data + copy_form_data_everything = og_form_data.copy() + copy_form_data_everything["data.labels.validation_fraction"] = 0.3 + copy_form_data_everything["optimization.augmentation_config.rotate"] = True + copy_form_data_everything["optimization.epochs"] = 50 + copy_form_data_except_model = copy_form_data_everything.copy() + copy_form_data_everything["_backbone_name"] = "leap" + + # The action trajectory below should cover the entire state space of the checkboxes + action_trajectory: List[Callable] = [ + check_resume_training_00, + uncheck_use_trained_11, + check_use_trained, + check_resume_training_10, + uncheck_resume_training, + uncheck_use_trained_10, + ] + + actions_that_allow_change_everything_except_model = { + check_resume_training_00, + check_resume_training_10, + } + actions_that_allow_change_everything = { + uncheck_use_trained_10, + uncheck_use_trained_10, + } + for action in action_trajectory: + assert_form_state(action, ted, og_form_data) + if action in actions_that_allow_change_everything: + ted.set_fields_from_key_val_dict(copy_form_data_everything) + elif action in actions_that_allow_change_everything_except_model: + ted.set_fields_from_key_val_dict(copy_form_data_except_model) + + # Test the case where the user selectes untrained model + ted._cfg_list_widget.setCurrentIndex(1) + assert not ted.has_trained_config_selected + assert not ted._resume_training.isChecked() + assert not ted._resume_training.isVisible() + assert not ted._use_trained_model.isVisible() + assert not ted._use_trained_model.isChecked() + assert not ted.use_trained + assert not ted.resume_training + + # Test the case where the user opts to perform inference + mode = "inference" + ted = TrainingEditorWidget( + video=video, + skeleton=skeleton, + head=head_name, + cfg_getter=cfg_getter, + require_trained=(mode == "inference"), + ) + ted.update_file_list() + assert len(ted._cfg_list_widget._cfg_list) == 1 + assert ted.has_trained_config_selected + assert ted._resume_training is None + assert ted._use_trained_model is None + assert ted.use_trained + assert not ted.resume_training + + +def test_movenet_selection(qtbot, min_dance_labels): + + app = MainWindow(no_usage_data=True) + + # learning dialog expects path to video + video_path = Path(min_dance_labels.video.backend.filename) + + ld = LearningDialog( + mode="inference", labels_filename=video_path, labels=min_dance_labels + ) + + # to make sure combo box has movenet options + combo_box = ld.pipeline_form_widget.pipeline_field.combo_box + model_options = [combo_box.itemText(i) for i in range(combo_box.count())] + + models = ["movenet-lightning", "movenet-thunder"] + + for model in models: + assert model in model_options + + # change model type + combo_box.setCurrentText(model) + + pipeline_form_data = ld.pipeline_form_widget.get_form_data() + + # ensure pipeline version matches model type + assert pipeline_form_data["_pipeline"] == model + + +def test_immutablilty_of_trained_config_info( + qtbot, min_labels_slp, min_bottomup_model_path, tmpdir +): + + model_path = Path(min_bottomup_model_path) + + # Create a learning dialog + app = MainWindow(no_usage_data=True) + ld = LearningDialog( + mode="training", + labels_filename=model_path.parent.absolute(), # Hack to get correct config + labels=min_labels_slp, + ) + + # Select a loaded config for pipeline form data + bottom_up_tab: TrainingEditorWidget = ld.tabs["multi_instance"] + cfg_list_widget: TrainingConfigFilesWidget = bottom_up_tab._cfg_list_widget + cfg_list_widget.update() + pre_config = bottom_up_tab._cfg_list_widget.getSelectedConfigInfo() + post_config = bottom_up_tab.trained_config_info_to_use + + # Check that the config info is not mutated when calling trained_config_info_to_use + # run_name is just one of many parameters that are changed during call + assert pre_config.config.outputs.run_name is not None + assert post_config.config.outputs.run_name is None + + # Previously, trained_config_info_to_use would mutate the config info and fail when + # saving multiple configs from one config info. + ld.save(output_dir=tmpdir) + ld.save(output_dir=tmpdir) + + +def test_validate_id_model(qtbot, min_labels_slp, min_labels_slp_path): + app = MainWindow(no_usage_data=True) + ld = LearningDialog( + mode="training", + labels_filename=Path(min_labels_slp_path), + labels=min_labels_slp, + ) + assert not ld._validate_id_model() + + # Add track but don't assign it to instances + new_track = sleap.Track(name="new_track") + min_labels_slp.tracks.append(new_track) + assert not ld._validate_id_model() + + # Assign track to instances + min_labels_slp[0][0].track = new_track + assert ld._validate_id_model() diff --git a/tests/gui/test_app.py b/tests/gui/test_app.py index 18f96acc7..def835b6e 100644 --- a/tests/gui/test_app.py +++ b/tests/gui/test_app.py @@ -8,7 +8,7 @@ def test_app_workflow( qtbot, centered_pair_vid, small_robot_mp4_vid, min_tracks_2node_labels: Labels ): - app = MainWindow() + app = MainWindow(no_usage_data=True) # Add nodes app.commands.newNode() @@ -33,7 +33,7 @@ def test_app_workflow( assert app.state["skeleton"].nodes[2].name == "c" # Select and delete the third node - app.skeletonNodesTable.selectRowItem(app.state["skeleton"].nodes[2]) + app.skeleton_dock.nodes_table.selectRowItem(app.state["skeleton"].nodes[2]) app.commands.deleteNode() assert len(app.state["skeleton"].nodes) == 2 @@ -60,7 +60,7 @@ def test_app_workflow( assert app.state["skeleton"].get_symmetry("c") is None # Remove an edge - app.skeletonEdgesTable.selectRowItem(dict(source="b", destination="c")) + app.skeleton_dock.edges_table.selectRowItem(dict(source="b", destination="c")) app.commands.deleteEdge() assert len(app.state["skeleton"].edges) == 1 @@ -74,22 +74,48 @@ def test_app_workflow( app.state["video"] = centered_pair_vid + # Prepare to check suggestion ui update upon video state change + def assert_frame_chunk_suggestion_ui_updated( + app, frame_to_spinbox, frame_from_spinbox + ): + assert frame_to_spinbox.maximum() == app.state["video"].num_frames + assert frame_from_spinbox.maximum() == app.state["video"].num_frames + + method_layout = app.suggestions_dock.suggestions_form_widget.form_layout.fields[ + "method" + ] + frame_chunk_layout = method_layout.page_layouts["frame chunk"] + frame_to_spinbox = frame_chunk_layout.fields["frame_to"] + frame_from_spinbox = frame_chunk_layout.fields["frame_from"] + + # Verify the max of frame_chunk spinboxes is updated + assert_frame_chunk_suggestion_ui_updated(app, frame_to_spinbox, frame_from_spinbox) + # Activate video using table - app.videosTable.selectRowItem(small_robot_mp4_vid) - app.videosTable.activateSelected() + app.videos_dock.table.selectRowItem(small_robot_mp4_vid) + app.videos_dock.table.activateSelected() assert app.state["video"] == small_robot_mp4_vid + # Verify the max of frame_to in frame_chunk is updated + assert_frame_chunk_suggestion_ui_updated(app, frame_to_spinbox, frame_from_spinbox) + # Select remaining video - app.videosTable.selectRowItem(small_robot_mp4_vid) + app.videos_dock.table.selectRowItem(small_robot_mp4_vid) assert app.state["selected_video"] == small_robot_mp4_vid + # Verify the max of frame_to in frame_chunk is updated + assert_frame_chunk_suggestion_ui_updated(app, frame_to_spinbox, frame_from_spinbox) + # Delete selected video app.commands.removeVideo() assert len(app.labels.videos) == 1 assert app.state["video"] == centered_pair_vid + # Verify the max of frame_to in frame_chunk is updated + assert_frame_chunk_suggestion_ui_updated(app, frame_to_spinbox, frame_from_spinbox) + # Add instances app.state["frame_idx"] = 27 app.commands.newInstance() @@ -101,7 +127,9 @@ def test_app_workflow( inst_27_1 = app.state["labeled_frame"].instances[1] # Move instance nodes - app.commands.setPointLocations(inst_27_0, {"a": (15, 20)}) + app.commands.setPointLocations( + inst_27_0, {"a": (15, 20), "b": (15, 40), "c": (40, 40)} + ) assert inst_27_0["a"].x == 15 assert inst_27_0["a"].y == 20 @@ -114,6 +142,7 @@ def test_app_workflow( # Select and delete instance app.state["instance"] = inst_27_1 app.commands.deleteSelectedInstance() + assert app.state["instance"] is None assert len(app.state["labeled_frame"].instances) == 1 assert app.state["labeled_frame"].instances == [inst_27_0] @@ -151,6 +180,7 @@ def test_app_workflow( # Delete all instances in track app.commands.deleteSelectedInstanceTrack() + assert app.state["instance"] is None assert len(app.state["labeled_frame"].instances) == 0 app.state["frame_idx"] = 29 @@ -212,9 +242,12 @@ def test_app_workflow( # Set up to test labeled frames data cache app.labels = min_tracks_2node_labels - video = app.labels.video + video_clip = app.labels.video + app.state["labels"] = app.labels + app.state["video"] = video_clip + app.on_data_update([UpdateTopic.all]) num_samples = 5 - frame_delta = video.num_frames // num_samples + frame_delta = video_clip.num_frames // num_samples # Add suggestions app.labels.suggestions = VideoFrameSuggestions.suggest( @@ -230,28 +263,68 @@ def test_app_workflow( # The on_data_update function uses labeled frames cache app.on_data_update([UpdateTopic.suggestions]) - assert len(app.suggestionsTable.model().items) == num_samples - assert f"{num_samples}/{num_samples}" in app.suggested_count_label.text() + assert len(app.suggestions_dock.table.model().items) == num_samples + assert ( + f"{num_samples}/{num_samples}" + in app.suggestions_dock.suggested_count_label.text() + ) # Check that frames returned by labeled frames cache are correct prev_idx = -frame_delta for l_suggestion, st_suggestion in list( - zip(app.labels.get_suggestions(), app.suggestionsTable.model().items) + zip(app.labels.get_suggestions(), app.suggestions_dock.table.model().items) ): assert l_suggestion == st_suggestion["SuggestionFrame"] lf = app.labels.get( (l_suggestion.video, l_suggestion.frame_idx), use_cache=True ) assert type(lf) == LabeledFrame - assert lf.video == video + assert lf.video == video_clip assert lf.frame_idx == prev_idx + frame_delta prev_idx = l_suggestion.frame_idx + # Add video, add frame suggestions, remove the video, verify the frame suggestions are also removed + app.labels.add_video(small_robot_mp4_vid) + app.on_data_update([UpdateTopic.video]) + + assert len(app.labels.videos) == 2 + + # Generate suggested frames in both videos + app.labels.clear_suggestions() + num_samples = 3 + app.labels.suggestions = VideoFrameSuggestions.suggest( + labels=app.labels, + params=dict( + videos=app.labels.videos, + method="sample", + per_video=num_samples, + sampling_method="random", + ), + ) + + # Verify that suggestions contain frames from both videos + video_source = [] + for sugg in app.labels.suggestions: + if not (sugg.video in video_source): + video_source.append(sugg.video) + assert len(video_source) == 2 + + # Remove video 1, keep video 0 + app.videos_dock.table.selectRowItem(small_robot_mp4_vid) + assert app.state["selected_video"] == small_robot_mp4_vid + app.commands.removeVideo() + assert len(app.labels.videos) == 1 + assert app.state["video"] == video_clip + + # Verify frame suggestions from video 1 are removed + for sugg in app.labels.suggestions: + assert sugg.video == video_clip + def test_app_new_window(qtbot): app = QApplication.instance() app.closeAllWindows() - win = MainWindow() + win = MainWindow(no_usage_data=True) assert win.commands.has_any_changes == False assert win.state["project_loaded"] == False @@ -283,7 +356,7 @@ def test_app_new_window(qtbot): ) assert wins == (start_wins + 1) - new_win = MainWindow() + new_win = MainWindow(no_usage_data=True) wins = sum( (1 for widget in app.topLevelWidgets() if isinstance(widget, MainWindow)) @@ -334,13 +407,19 @@ def toggle_and_verify_visibility(expected_visibility: bool = True): # Test hide instances menu action (and its effect on instance color) # Instantiate the window and load labels - window: MainWindow = MainWindow() - window.loadLabelsObject(centered_pair_predictions) + window: MainWindow = MainWindow(no_usage_data=True) + window.commands.loadLabelsObject(centered_pair_predictions) # TODO: window does not seem to show as expected on ubuntu with qtbot.waitActive(window, timeout=2000): window.showNormal() vp = window.player + # Change state and ensure menu-item check updates + color_predicted = window.state["color predicted"] + assert window._menu_actions["color predicted"].isChecked() == color_predicted + window.state["color predicted"] = not color_predicted + assert window._menu_actions["color predicted"].isChecked() == (not color_predicted) + # Enable distinct colors window.state["color predicted"] = True diff --git a/tests/gui/test_commands.py b/tests/gui/test_commands.py index 2747d53b7..e19e00236 100644 --- a/tests/gui/test_commands.py +++ b/tests/gui/test_commands.py @@ -1,30 +1,42 @@ -from tempfile import tempdir +import pytest +import shutil +import sys +import time + +import numpy as np +from pathlib import PurePath, Path +from qtpy import QtCore +from typing import List + +from sleap import Skeleton, Track, PredictedInstance +from sleap.gui.app import MainWindow from sleap.gui.commands import ( + AddInstance, CommandContext, - ImportDeepLabCutFolder, ExportAnalysisFile, + ExportDatasetWithImages, + ImportDeepLabCutFolder, + RemoveVideo, ReplaceVideo, OpenSkeleton, SaveProjectAs, + DeleteFrameLimitPredictions, get_new_version_filename, ) -from sleap.io.format.adaptor import Adaptor +from sleap.instance import Instance, LabeledFrame +from sleap.io.convert import default_analysis_filename from sleap.io.dataset import Labels +from sleap.io.format.adaptor import Adaptor from sleap.io.format.ndx_pose import NDXPoseAdaptor from sleap.io.pathutils import fix_path_separator from sleap.io.video import Video -from sleap.io.convert import default_analysis_filename -from sleap.instance import Instance, LabeledFrame -from sleap import Skeleton, Track +from sleap.util import get_package_file +# These imports cause trouble when running `pytest.main()` from within the file +# Comment out to debug tests file via VSCode's "Debug Python File" from tests.info.test_h5 import extract_meta_hdf5 from tests.io.test_video import assert_video_params - -from pathlib import PurePath, Path -from typing import List - -import shutil -import pytest +from tests.io.test_formats import read_nix_meta def test_delete_user_dialog(centered_pair_predictions): @@ -58,7 +70,7 @@ def test_import_labels_from_dlc_folder(): assert len(labels.videos) == 2 assert len(labels.skeletons) == 1 assert len(labels.nodes) == 3 - assert len(labels.tracks) == 0 + assert len(labels.tracks) == 3 assert set( [fix_path_separator(l.video.backend.filename) for l in labels.labeled_frames] @@ -85,9 +97,49 @@ def test_get_new_version_filename(): ) +def test_RemoveVideo( + centered_pair_predictions: Labels, + small_robot_mp4_vid: Video, + centered_pair_vid: Video, +): + def ask(obj: RemoveVideo, context: CommandContext, params: dict) -> bool: + return True + + RemoveVideo.ask = ask + + labels = centered_pair_predictions.copy() + labels.add_video(small_robot_mp4_vid) + labels.add_video(centered_pair_vid) + + all_videos = labels.videos + assert len(all_videos) == 3 + + video_idxs = [1, 2] + videos_to_remove = [labels.videos[i] for i in video_idxs] + + context = CommandContext.from_labels(labels) + context.state["selected_batch_video"] = video_idxs + context.state["video"] = labels.videos[1] + + context.removeVideo() + + assert len(labels.videos) == 1 + assert context.state["video"] not in videos_to_remove + + +@pytest.mark.parametrize("out_suffix", ["h5", "nix", "csv"]) def test_ExportAnalysisFile( - centered_pair_predictions: Labels, small_robot_mp4_vid: Video, tmpdir + centered_pair_predictions: Labels, + centered_pair_predictions_hdf5_path: str, + small_robot_mp4_vid: Video, + out_suffix: str, + tmpdir, ): + if out_suffix == "csv": + csv = True + else: + csv = False + def ExportAnalysisFile_ask(context: CommandContext, params: dict): """Taken from ExportAnalysisFile.ask()""" @@ -98,7 +150,7 @@ def ask_for_filename(default_name: str) -> str: labels = context.labels if len(labels.labeled_frames) == 0: - return False + raise ValueError("No labeled frames in project. Nothing to export.") if params["all_videos"]: all_videos = context.labels.videos @@ -108,9 +160,9 @@ def ask_for_filename(default_name: str) -> str: # Check for labeled frames in each video videos = [video for video in all_videos if len(labels.get(video)) != 0] if len(videos) == 0: - return False + raise ValueError("No labeled frames in video(s). Nothing to export.") - default_name = context.state["filename"] or "labels" + default_name = "labels" fn = PurePath(tmpdir, default_name) if len(videos) == 1: # Allow user to specify the filename @@ -132,6 +184,7 @@ def ask_for_filename(default_name: str) -> str: video=video, output_path=dirname, output_prefix=str(fn.stem), + format_suffix=out_suffix, ) filename = default_name if use_default else ask_for_filename(default_name) @@ -152,11 +205,11 @@ def assert_videos_written(num_videos: int, labels_path: str = None): assert Path(output_path).exists() output_paths.append(output_path) - if labels_path is not None: - read_meta = extract_meta_hdf5( - output_path, dset_names_in=["labels_path"] - ) - assert read_meta["labels_path"] == labels_path + if labels_path is not None and not params["csv"]: + meta_reader = extract_meta_hdf5 if out_suffix == "h5" else read_nix_meta + labels_key = "labels_path" if out_suffix == "h5" else "project" + read_meta = meta_reader(output_path, dset_names_in=["labels_path"]) + assert read_meta[labels_key] == labels_path assert len(output_paths) == num_videos, "Wrong number of outputs written" assert len(set(output_paths)) == num_videos, "Some output paths overwritten" @@ -167,8 +220,20 @@ def assert_videos_written(num_videos: int, labels_path: str = None): context = CommandContext.from_labels(labels) context.state["filename"] = None + if csv: + + context.state["filename"] = centered_pair_predictions_hdf5_path + + params = {"all_videos": True, "csv": csv} + okay = ExportAnalysisFile_ask(context=context, params=params) + assert okay == True + ExportAnalysisFile.do_action(context=context, params=params) + assert_videos_written(num_videos=1, labels_path=context.state["filename"]) + + return + # Test with all_videos False (single video) - params = {"all_videos": False} + params = {"all_videos": False, "csv": csv} okay = ExportAnalysisFile_ask(context=context, params=params) assert okay == True ExportAnalysisFile.do_action(context=context, params=params) @@ -176,7 +241,7 @@ def assert_videos_written(num_videos: int, labels_path: str = None): # Add labels path and test with all_videos True (single video) context.state["filename"] = str(tmpdir.with_name("path.to.labels")) - params = {"all_videos": True} + params = {"all_videos": True, "csv": csv} okay = ExportAnalysisFile_ask(context=context, params=params) assert okay == True ExportAnalysisFile.do_action(context=context, params=params) @@ -185,7 +250,7 @@ def assert_videos_written(num_videos: int, labels_path: str = None): # Add a video (no labels) and test with all_videos True labels.add_video(small_robot_mp4_vid) - params = {"all_videos": True} + params = {"all_videos": True, "csv": csv} okay = ExportAnalysisFile_ask(context=context, params=params) assert okay == True ExportAnalysisFile.do_action(context=context, params=params) @@ -197,7 +262,7 @@ def assert_videos_written(num_videos: int, labels_path: str = None): labels.add_instance(frame=labeled_frame, instance=instance) labels.append(labeled_frame) - params = {"all_videos": False} + params = {"all_videos": False, "csv": csv} okay = ExportAnalysisFile_ask(context=context, params=params) assert okay == True ExportAnalysisFile.do_action(context=context, params=params) @@ -206,14 +271,14 @@ def assert_videos_written(num_videos: int, labels_path: str = None): # Add specific video and test with all_videos False context.state["videos"] = labels.videos[1] - params = {"all_videos": False} + params = {"all_videos": False, "csv": csv} okay = ExportAnalysisFile_ask(context=context, params=params) assert okay == True ExportAnalysisFile.do_action(context=context, params=params) assert_videos_written(num_videos=1, labels_path=context.state["filename"]) # Test with all videos True - params = {"all_videos": True} + params = {"all_videos": True, "csv": csv} okay = ExportAnalysisFile_ask(context=context, params=params) assert okay == True ExportAnalysisFile.do_action(context=context, params=params) @@ -231,7 +296,7 @@ def assert_videos_written(num_videos: int, labels_path: str = None): labels.videos[0].backend.filename = str(tmpdir / "session1" / "video.mp4") labels.videos[1].backend.filename = str(tmpdir / "session2" / "video.mp4") - params = {"all_videos": True} + params = {"all_videos": True, "csv": csv} okay = ExportAnalysisFile_ask(context=context, params=params) assert okay == True ExportAnalysisFile.do_action(context=context, params=params) @@ -242,9 +307,9 @@ def assert_videos_written(num_videos: int, labels_path: str = None): for video in all_videos: labels.remove_video(labels.videos[-1]) - params = {"all_videos": True} - okay = ExportAnalysisFile_ask(context=context, params=params) - assert okay == False + params = {"all_videos": True, "csv": csv} + with pytest.raises(ValueError): + okay = ExportAnalysisFile_ask(context=context, params=params) def test_ToggleGrayscale(centered_pair_predictions: Labels): @@ -374,9 +439,7 @@ def test_OpenSkeleton( ): def assert_skeletons_match(new_skeleton: Skeleton, skeleton: Skeleton): # Node names match - for new_node, node in zip(new_skeleton.nodes, skeleton.nodes): - assert new_node.name == node.name - + assert len(set(new_skeleton.nodes) - set(skeleton.nodes)) # Edges match for (new_src, new_dst), (src, dst) in zip(new_skeleton.edges, skeleton.edges): assert new_src.name == src.name @@ -391,10 +454,14 @@ def assert_skeletons_match(new_skeleton: Skeleton, skeleton: Skeleton): def OpenSkeleton_ask(context: CommandContext, params: dict) -> bool: """Implement `OpenSkeleton.ask` without GUI elements.""" - - # Original function opens FileDialog here - filename = params["filename_in"] - + template = ( + context.app.currentText + ) # Original function uses `QComboBox.currentText()` + if template == "Custom": + # Original function opens FileDialog here + filename = params["filename_in"] + else: + filename = get_package_file(f"skeletons/{template}.json") if len(filename) == 0: return False @@ -406,14 +473,20 @@ def OpenSkeleton_ask(context: CommandContext, params: dict) -> bool: # Load new skeleton and compare new_skeleton = OpenSkeleton.load_skeleton(filename) - (delete_nodes, add_nodes) = OpenSkeleton.compare_skeletons( + (rename_nodes, delete_nodes, add_nodes) = OpenSkeleton.compare_skeletons( skeleton, new_skeleton ) # Original function shows pop-up warning here if (len(delete_nodes) > 0) or (len(add_nodes) > 0): - # Warn about mismatching skeletons - pass + linked_nodes = { + "abdomen": "body", + "wingL": "left-arm", + "wingR": "right-arm", + } + delete_nodes = list(set(delete_nodes) - set(linked_nodes.values())) + add_nodes = list(set(add_nodes) - set(linked_nodes.keys())) + params["linked_nodes"] = linked_nodes params["delete_nodes"] = delete_nodes params["add_nodes"] = add_nodes @@ -425,7 +498,7 @@ def OpenSkeleton_ask(context: CommandContext, params: dict) -> bool: skeleton = labels.skeleton skeleton.add_symmetry(skeleton.nodes[0].name, skeleton.nodes[1].name) context = CommandContext.from_labels(labels) - + context.app.__setattr__("currentText", "Custom") # Add multiple skeletons to and ensure the unused skeleton is removed labels.skeletons.append(stickman) @@ -447,9 +520,20 @@ def OpenSkeleton_ask(context: CommandContext, params: dict) -> bool: params = {"filename_in": fly_legs_skeleton_json} OpenSkeleton_ask(context, params) assert params["filename"] == fly_legs_skeleton_json + assert len(set(params["delete_nodes"]) & set(params["linked_nodes"])) == 0 + assert len(set(params["add_nodes"]) & set(params["linked_nodes"])) == 0 OpenSkeleton.do_action(context, params) assert_skeletons_match(new_skeleton, stickman) + # Run again with template set + context.app.currentText = "fly32" + fly32_json = get_package_file(f"skeletons/fly32.json") + OpenSkeleton_ask(context, params) + assert params["filename"] == fly32_json + fly32_skeleton = Skeleton.load_json(fly32_json) + OpenSkeleton.do_action(context, params) + assert_skeletons_match(labels.skeleton, fly32_skeleton) + def test_SaveProjectAs(centered_pair_predictions: Labels, tmpdir): """Test that project can be saved as default slp extension""" @@ -495,3 +579,470 @@ def test_SetSelectedInstanceTrack(centered_pair_predictions: Labels): # Ensure that both instance and predicted instance have same track assert new_instance.track == track assert pred_inst.track == new_instance.track + + +def test_DeleteMultipleTracks(min_tracks_2node_labels: Labels): + """Test that deleting multiple tracks works as expected.""" + labels = min_tracks_2node_labels + tracks = labels.tracks + tracks.append(Track(name="unused", spawned_on=0)) + assert len(tracks) == 3 + + # Set-up command context + context: CommandContext = CommandContext.from_labels(labels) + context.state["labels"] = labels + + # Delete unused tracks + context.deleteMultipleTracks(delete_all=False) + assert len(labels.tracks) == 2 + + # Add back an unused track and delete all tracks + tracks.append(Track(name="unused", spawned_on=0)) + assert len(tracks) == 3 + context.deleteMultipleTracks(delete_all=True) + assert len(labels.tracks) == 0 + + +def test_CopyInstance(min_tracks_2node_labels: Labels): + """Test that copying an instance works as expected.""" + labels = min_tracks_2node_labels + instance = labels[0].instances[0] + + # Set-up command context + context: CommandContext = CommandContext.from_labels(labels) + + # Copy instance + assert context.state["instance"] is None + context.copyInstance() + assert context.state["clipboard_instance"] is None + + # Copy instance + context.state["instance"] = instance + context.copyInstance() + assert context.state["clipboard_instance"] == instance + + +def test_PasteInstance(min_tracks_2node_labels: Labels): + """Test that pasting an instance works as expected.""" + labels = min_tracks_2node_labels + lf_to_copy: LabeledFrame = labels.labeled_frames[0] + instance: Instance = lf_to_copy.instances[0] + + # Set-up command context + context: CommandContext = CommandContext.from_labels(labels) + + def paste_instance( + lf_to_paste: LabeledFrame, assertions_pre_paste, assertions_post_paste + ): + """Helper function to test pasting an instance.""" + instances_checkpoint = list(lf_to_paste.instances) + assertions_pre_paste(instance, lf_to_copy) + + context.pasteInstance() + assertions_post_paste(instances_checkpoint, lf_to_copy, lf_to_paste) + + # Case 1: No instance copied, but frame selected + + def assertions_prior(*args): + assert context.state["clipboard_instance"] is None + + def assertions_post(instances_checkpoint, lf_to_copy, *args): + assert instances_checkpoint == lf_to_copy.instances + + context.state["labeled_frame"] = lf_to_copy + paste_instance(lf_to_copy, assertions_prior, assertions_post) + + # Case 2: No frame selected, but instance copied + + def assertions_prior(*args): + assert context.state["labeled_frame"] is None + + context.state["labeled_frame"] = None + context.state["clipboard_instance"] = instance + paste_instance(lf_to_copy, assertions_prior, assertions_post) + + # Case 3: Instance copied and current frame selected + + def assertions_prior(instance, lf_to_copy, *args): + assert context.state["clipboard_instance"] == instance + assert context.state["labeled_frame"] == lf_to_copy + + def assertions_post(instances_checkpoint, lf_to_copy, lf_to_paste, *args): + lf_checkpoint_tracks = [ + inst.track for inst in instances_checkpoint if inst.track is not None + ] + lf_to_copy_tracks = [ + inst.track for inst in lf_to_copy.instances if inst.track is not None + ] + assert len(lf_checkpoint_tracks) == len(lf_to_copy_tracks) + assert len(lf_to_paste.instances) == len(instances_checkpoint) + 1 + assert lf_to_paste.instances[-1].points == instance.points + + context.state["labeled_frame"] = lf_to_copy + context.state["clipboard_instance"] = instance + paste_instance(lf_to_copy, assertions_prior, assertions_post) + + # Case 4: Instance copied and different frame selected, but new frame has same track + + def assertions_prior(instance, lf_to_copy, *args): + assert context.state["clipboard_instance"] == instance + assert context.state["labeled_frame"] != lf_to_copy + lf_to_paste = context.state["labeled_frame"] + tracks_in_lf_to_paste = [ + inst.track for inst in lf_to_paste.instances if inst.track is not None + ] + assert instance.track in tracks_in_lf_to_paste + + lf_to_paste = labels.labeled_frames[1] + context.state["labeled_frame"] = lf_to_paste + paste_instance(lf_to_paste, assertions_prior, assertions_post) + + # Case 5: Instance copied and different frame selected, and track not in new frame + + def assertions_prior(instance, lf_to_copy, *args): + assert context.state["clipboard_instance"] == instance + assert context.state["labeled_frame"] != lf_to_copy + lf_to_paste = context.state["labeled_frame"] + tracks_in_lf_to_paste = [ + inst.track for inst in lf_to_paste.instances if inst.track is not None + ] + assert instance.track not in tracks_in_lf_to_paste + + def assertions_post(instances_checkpoint, lf_to_copy, lf_to_paste, *args): + assert len(lf_to_paste.instances) == len(instances_checkpoint) + 1 + assert lf_to_paste.instances[-1].points == instance.points + assert lf_to_paste.instances[-1].track == instance.track + + lf_to_paste = labels.labeled_frames[2] + context.state["labeled_frame"] = lf_to_paste + for inst in lf_to_paste.instances: + inst.track = None + paste_instance(lf_to_paste, assertions_prior, assertions_post) + + # Case 6: Instance copied, different frame selected, and frame not in Labels + + def assertions_prior(instance, lf_to_copy, *args): + assert context.state["clipboard_instance"] == instance + assert context.state["labeled_frame"] != lf_to_copy + assert context.state["labeled_frame"] not in labels.labeled_frames + + def assertions_post(instances_checkpoint, lf_to_copy, lf_to_paste, *args): + assert len(lf_to_paste.instances) == len(instances_checkpoint) + 1 + assert lf_to_paste.instances[-1].points == instance.points + assert lf_to_paste.instances[-1].track == instance.track + assert lf_to_paste in labels.labeled_frames + + lf_to_paste = labels.get((labels.video, 3)) + labels.labeled_frames.remove(lf_to_paste) + lf_to_paste.instances = [] + context.state["labeled_frame"] = lf_to_paste + paste_instance(lf_to_paste, assertions_prior, assertions_post) + + +def test_CopyInstanceTrack(min_tracks_2node_labels: Labels): + """Test that copying a track from one instance to another works.""" + labels = min_tracks_2node_labels + instance = labels.labeled_frames[0].instances[0] + + # Set-up CommandContext + context: CommandContext = CommandContext.from_labels(labels) + + # Case 1: No instance selected + context.copyInstanceTrack() + assert context.state["clipboard_track"] is None + + # Case 2: Instance selected and track + context.state["instance"] = instance + context.copyInstanceTrack() + assert context.state["clipboard_track"] == instance.track + + # Case 3: Instance selected and no track + instance.track = None + context.copyInstanceTrack() + assert context.state["clipboard_track"] is None + + +def test_PasteInstanceTrack(min_tracks_2node_labels: Labels): + """Test that pasting a track from one instance to another works.""" + labels = min_tracks_2node_labels + instance = labels.labeled_frames[0].instances[0] + + # Set-up CommandContext + context: CommandContext = CommandContext.from_labels(labels) + + # Case 1: No instance selected + context.state["clipboard_track"] = instance.track + + context.pasteInstanceTrack() + assert context.state["instance"] is None + + # Case 2: Instance selected and track + lf_to_paste = labels.labeled_frames[1] + instance_with_same_track = lf_to_paste.instances[0] + instance_to_paste = lf_to_paste.instances[1] + context.state["instance"] = instance_to_paste + assert instance_to_paste.track != instance.track + assert instance_with_same_track.track == instance.track + + context.pasteInstanceTrack() + assert instance_to_paste.track == instance.track + assert instance_with_same_track.track != instance.track + + # Case 3: Instance selected and no track + lf_to_paste = labels.labeled_frames[2] + instance_to_paste = lf_to_paste.instances[0] + instance.track = None + + context.pasteInstanceTrack() + assert isinstance(instance_to_paste.track, Track) + + +@pytest.mark.skipif( + sys.platform.startswith("win"), + reason="Files being using in parallel by linux CI tests via Github Actions " + "(and linux tests give us codecov reports)", +) +@pytest.mark.parametrize("video_move_case", ["new_directory", "new_name"]) +def test_LoadProjectFile( + centered_pair_predictions_slp_path: str, + video_move_case, + tmpdir, +): + """Test that changing a labels object on load flags any changes.""" + + def ask_LoadProjectFile(params): + """Implement `LoadProjectFile.ask` without GUI elements.""" + filename: Path = params["filename"] + gui_video_callback = Labels.make_video_callback( + search_paths=[str(filename)], context=params + ) + labels = Labels.load_file( + centered_pair_predictions_slp_path, video_search=gui_video_callback + ) + return labels + + def load_and_assert_changes(new_video_path: Path): + # Load the project + params = {"filename": new_video_path} + ask_LoadProjectFile(params) + + # Assert project has changes + assert params["changed_on_load"] + + # Get labels and video path + labels = Labels.load_file(centered_pair_predictions_slp_path) + expected_video_path = Path(labels.video.backend.filename) + + # Move video to new location based on case + if video_move_case == "new_directory": # Needs to have same name + new_video_path = Path(tmpdir, expected_video_path.name) + else: # Needs to have different name + new_video_path = expected_video_path.with_name("new_name.mp4") + shutil.move(expected_video_path, new_video_path) # Move video to new location + + # Shorten video path if using directory location only + search_path = ( + new_video_path.parent if video_move_case == "new_directory" else new_video_path + ) + + # Load project and assert changes + try: + load_and_assert_changes(search_path) + finally: # Move video back to original location - for ease of re-testing + shutil.move(new_video_path, expected_video_path) + + +def test_DeleteFrameLimitPredictions( + centered_pair_predictions: Labels, centered_pair_vid: Video +): + """Test deleting instances beyond a certain frame limit.""" + labels = centered_pair_predictions + + # Set-up command context + context = CommandContext.from_labels(labels) + context.state["video"] = centered_pair_vid + + # Set-up params for the command + params = {"min_frame_idx": 900, "max_frame_idx": 1000} + + instances_to_delete = DeleteFrameLimitPredictions.get_frame_instance_list( + context, params + ) + + assert len(instances_to_delete) == 2070 + + +@pytest.mark.parametrize("export_extension", [".json.zip", ".slp"]) +def test_exportLabelsPackage(export_extension, centered_pair_labels: Labels, tmpdir): + def assert_loaded_package_similar(path_to_pkg: Path, sugg=False, pred=False): + """Assert that the loaded labels are similar to the original.""" + + # Load the labels, but first copy file to a location (which pytest can and will + # keep in memory, but won't affect our re-use of the original file name) + filename_for_pytest_to_hoard: Path = path_to_pkg.with_name( + f"pytest_labels_{time.perf_counter_ns()}{export_extension}" + ) + shutil.copyfile(path_to_pkg.as_posix(), filename_for_pytest_to_hoard.as_posix()) + labels_reload: Labels = Labels.load_file( + filename_for_pytest_to_hoard.as_posix() + ) + + assert len(labels_reload.labeled_frames) == len(centered_pair_labels) + assert len(labels_reload.videos) == len(centered_pair_labels.videos) + assert len(labels_reload.suggestions) == len(centered_pair_labels.suggestions) + assert len(labels_reload.tracks) == len(centered_pair_labels.tracks) + assert len(labels_reload.skeletons) == len(centered_pair_labels.skeletons) + assert ( + len( + set(labels_reload.skeleton.node_names) + - set(centered_pair_labels.skeleton.node_names) + ) + == 0 + ) + num_images = len(labels_reload) + if sugg: + num_images += len(lfs_sugg) + if not pred: + num_images -= len(lfs_pred) + assert labels_reload.video.num_frames == num_images + + # Set-up CommandContext + path_to_pkg = Path(tmpdir, "test_exportLabelsPackage.ext") + path_to_pkg = path_to_pkg.with_suffix(export_extension) + + def no_gui_ask(cls, context, params): + """No GUI version of `ExportDatasetWithImages.ask`.""" + params["filename"] = path_to_pkg.as_posix() + params["verbose"] = False + return True + + ExportDatasetWithImages.ask = no_gui_ask + + # Remove frames we want to use for suggestions and predictions + lfs_sugg = [centered_pair_labels[idx] for idx in [-1, -2]] + lfs_pred = [centered_pair_labels[idx] for idx in [-3, -4]] + centered_pair_labels.remove_frames(lfs_sugg) + + # Add suggestions + for lf in lfs_sugg: + centered_pair_labels.add_suggestion(centered_pair_labels.video, lf.frame_idx) + + # Add predictions and remove user instances from those frames + for lf in lfs_pred: + predicted_inst = PredictedInstance.from_instance(lf.instances[0], score=0.5) + centered_pair_labels.add_instance(lf, predicted_inst) + for inst in lf.user_instances: + centered_pair_labels.remove_instance(lf, inst) + context = CommandContext.from_labels(centered_pair_labels) + + # Case 1: Export user-labeled frames with image data into a single SLP file. + context.exportUserLabelsPackage() + assert path_to_pkg.exists() + assert_loaded_package_similar(path_to_pkg) + + # Case 2: Export user-labeled frames and suggested frames with image data. + context.exportTrainingPackage() + assert_loaded_package_similar(path_to_pkg, sugg=True) + + # Case 3: Export all frames and suggested frames with image data. + context.exportFullPackage() + assert_loaded_package_similar(path_to_pkg, sugg=True, pred=True) + + +def test_newInstance(qtbot, centered_pair_predictions: Labels): + + # Get the data + labels = centered_pair_predictions + lf = labels[0] + pred_inst = lf.instances[0] + video = labels.video + + # Set-up command context + main_window = MainWindow(labels=labels) + context = main_window.commands + context.state["labeled_frame"] = lf + context.state["frame_idx"] = lf.frame_idx + context.state["skeleton"] = labels.skeleton + context.state["video"] = labels.videos[0] + + # Case 1: Double clicking a prediction results in no offset for new instance + + # Double click on prediction + assert len(lf.instances) == 2 + main_window._handle_instance_double_click(instance=pred_inst) + + # Check new instance + assert len(lf.instances) == 3 + new_inst = lf.instances[-1] + assert new_inst.from_predicted is pred_inst + assert np.array_equal(new_inst.numpy(), pred_inst.numpy()) # No offset + + # Case 2: Using Ctrl + I (or menu "Add Instance" button) + + # Connect the action to a slot + add_instance_menu_action = main_window._menu_actions["add instance"] + triggered = False + + def on_triggered(): + nonlocal triggered + triggered = True + + add_instance_menu_action.triggered.connect(on_triggered) + + # Find which instance we are going to copy from + ( + copy_instance, + from_predicted, + from_prev_frame, + ) = AddInstance.find_instance_to_copy_from( + context, copy_instance=None, init_method="best" + ) + + # Click on the menu action + assert len(lf.instances) == 3 + add_instance_menu_action.trigger() + assert triggered, "Action not triggered" + + # Check new instance + assert len(lf.instances) == 4 + new_inst = lf.instances[-1] + offset = 10 + np.nan_to_num(new_inst.numpy() - copy_instance.numpy(), nan=offset) + assert np.all( + np.nan_to_num(new_inst.numpy() - copy_instance.numpy(), nan=offset) == offset + ) + + # Case 3: Using right click and "Default" option + + # Find which instance we are going to copy from + ( + copy_instance, + from_predicted, + from_prev_frame, + ) = AddInstance.find_instance_to_copy_from( + context, copy_instance=None, init_method="best" + ) + + video_player = main_window.player + right_click_location_x = video.shape[2] / 2 + right_click_location_y = video.shape[1] / 2 + right_click_location = QtCore.QPointF( + right_click_location_x, right_click_location_y + ) + video_player.create_contextual_menu(scene_pos=right_click_location) + default_action = video_player._menu_actions["Default"] + default_action.trigger() + + # Check new instance + assert len(lf.instances) == 5 + new_inst = lf.instances[-1] + reference_node_idx = np.where( + np.all( + new_inst.numpy() == [right_click_location_x, right_click_location_y], axis=1 + ) + )[0][0] + offset = ( + new_inst.numpy()[reference_node_idx] - copy_instance.numpy()[reference_node_idx] + ) + diff = np.nan_to_num(new_inst.numpy() - copy_instance.numpy(), nan=offset) + assert np.all(diff == offset) diff --git a/tests/gui/test_dataviews.py b/tests/gui/test_dataviews.py index 7a89b1ab2..9c62daf88 100644 --- a/tests/gui/test_dataviews.py +++ b/tests/gui/test_dataviews.py @@ -20,7 +20,9 @@ def test_skeleton_nodes(qtbot, centered_pair_predictions): assert table.model().data(table.currentIndex()) == "thorax" table = GenericTableView( - row_name="video", model=VideosTableModel(items=centered_pair_predictions.videos) + row_name="video", + model=VideosTableModel(items=centered_pair_predictions.videos), + multiple_selection=True, ) table.selectRow(0) assert ( diff --git a/tests/gui/test_dialogs.py b/tests/gui/test_dialogs.py new file mode 100644 index 000000000..611a73c85 --- /dev/null +++ b/tests/gui/test_dialogs.py @@ -0,0 +1,113 @@ +"""Module to test the dialogs of the GUI (contained in sleap/gui/dialogs).""" + +import os +from pathlib import Path + +import pytest +from qtpy.QtWidgets import QComboBox + +import sleap +from sleap.skeleton import Skeleton +from sleap.io.dataset import Labels +from sleap.gui.commands import OpenSkeleton +from sleap.gui.dialogs.merge import ReplaceSkeletonTableDialog + + +def test_ReplaceSkeletonTableDialog( + qtbot, centered_pair_labels: Labels, flies13_skeleton: Skeleton +): + """Test ReplaceSkeletonTableDialog.""" + + def get_combo_box_items(combo_box: QComboBox) -> set: + return set([combo_box.itemText(i) for i in range(combo_box.count())]) + + def predict_combo_box_items( + combo_box: QComboBox, base=None, include=None, exclude=None + ) -> set: + if isinstance(include, str): + include = [include] + if isinstance(exclude, str): + exclude = [exclude] + predicted = set([combo_box.currentText(), ""]) + predicted = predicted if base is None else predicted | set(base) + predicted = predicted if include is None else predicted | set(include) + predicted = predicted if exclude is None else predicted - set(exclude) + return predicted + + labels = centered_pair_labels + skeleton = labels.skeletons[0] + + skeleton_new = flies13_skeleton + rename_nodes, delete_nodes, add_nodes = OpenSkeleton.compare_skeletons( + skeleton, skeleton_new + ) + + win = ReplaceSkeletonTableDialog( + rename_nodes, + delete_nodes=[], + add_nodes=[], + ) + + assert win.table is None + + win = ReplaceSkeletonTableDialog( + rename_nodes, + delete_nodes, + add_nodes, + ) + + # Check that all nodes are in the table + assert win.table.rowCount() == len(rename_nodes) + len(add_nodes) + + # Check table initialized correctly + for i in range(win.table.rowCount()): + table_item = win.table.item(i, 0) + combo_box: QComboBox = win.table.cellWidget(i, 1) + + # Expect combo box to contain all `add_nodes` plus current text and `""` + combo_box_text: str = combo_box.currentText() + combo_box_items = get_combo_box_items(combo_box) + expected_combo_box_items = predict_combo_box_items(combo_box, base=delete_nodes) + assert combo_box_items == expected_combo_box_items + + # Expect rename nodes to be preset to combo with same node name + if table_item.text() in rename_nodes: + assert combo_box_text == table_item.text() + else: + assert table_item.text() in add_nodes + assert combo_box_text == "" + + assert win.result() == {} + + # Change combo box for one row + combo_box: QComboBox = win.table.cellWidget(0, 1) + combo_box_text = combo_box.currentText() + new_text = combo_box.itemText(len(rename_nodes)) + combo_box.setCurrentText(new_text) + + # Check that combo boxes update correctly + assert get_combo_box_items(combo_box) == predict_combo_box_items( + combo_box, base=delete_nodes, include=combo_box_text + ) + for i in range(1, win.table.rowCount()): + combo_box: QComboBox = win.table.cellWidget(i, 1) + assert get_combo_box_items(combo_box) == predict_combo_box_items( + combo_box, base=delete_nodes, include=combo_box_text, exclude=new_text + ) + + # Check that error occurs if trying to ONLY rename nodes to existing node names + assert win.table.item(0, 0).text() in skeleton.node_names + with pytest.raises(ValueError): + data = win.result() + + # Change combo box of a delete node to a new node + combo_box: QComboBox = win.table.cellWidget(len(rename_nodes), 1) + combo_box_text = combo_box.currentText() + new_text = combo_box.itemText(3) + combo_box.setCurrentText(new_text) + + # This operation should be allowed since we are linking old nodes to new nodes + # (not just renaming) + assert win.table.item(len(rename_nodes), 0).text() not in skeleton.node_names + data = win.result() + assert data == {"head1": "forelegL2", "forelegL1": "forelegR3"} diff --git a/tests/gui/test_filedialog.py b/tests/gui/test_filedialog.py index d70a413db..8d90ff817 100644 --- a/tests/gui/test_filedialog.py +++ b/tests/gui/test_filedialog.py @@ -3,26 +3,38 @@ from qtpy import QtWidgets -from sleap.gui.dialogs.filedialog import FileDialog +from sleap.gui.dialogs.filedialog import os_specific_method, FileDialog def test_non_native_dialog(): - save_env_non_native = os.environ.get("USE_NON_NATIVE_FILE", None) + @os_specific_method + def dummy_function(cls, *args, **kwargs): + """This function returns the `kwargs` modified by the wrapper. - os.environ["USE_NON_NATIVE_FILE"] = "" + Args: + cls: The `FileDialog` class. + Returns: + kwargs: Modified by the wrapper. + """ + return kwargs + + FileDialog.dummy_function = dummy_function + save_env_non_native = os.environ.get("USE_NON_NATIVE_FILE", None) + os.environ["USE_NON_NATIVE_FILE"] = "" d = dict() - FileDialog._non_native_if_set(d) + + # Wrapper doesn't mutate `d` outside of scope, so need to return `modified_d` + modified_d = FileDialog.dummy_function(FileDialog, d) is_linux = sys.platform.startswith("linux") if is_linux: - assert d["options"] == QtWidgets.QFileDialog.DontUseNativeDialog + assert modified_d["options"] == QtWidgets.QFileDialog.DontUseNativeDialog else: - assert "options" not in d + assert "options" not in modified_d os.environ["USE_NON_NATIVE_FILE"] = "1" - d = dict() - FileDialog._non_native_if_set(d) - assert d["options"] == QtWidgets.QFileDialog.DontUseNativeDialog + modified_d = FileDialog.dummy_function(FileDialog, d) + assert modified_d["options"] == QtWidgets.QFileDialog.DontUseNativeDialog if save_env_non_native is not None: os.environ["USE_NON_NATIVE_FILE"] = save_env_non_native diff --git a/tests/gui/test_grid_system.py b/tests/gui/test_grid_system.py index c768e04f6..85419a467 100644 --- a/tests/gui/test_grid_system.py +++ b/tests/gui/test_grid_system.py @@ -4,8 +4,8 @@ def test_grid_system_midpoint_gui(qtbot, midpoint_grid_labels): - app = MainWindow() - app.loadLabelsObject(midpoint_grid_labels) + app = MainWindow(no_usage_data=True) + app.commands.loadLabelsObject(midpoint_grid_labels) assert len(app.state["labeled_frame"]) == 1 lf = app.state["labeled_frame"] @@ -40,8 +40,8 @@ def test_grid_system_midpoint_gui(qtbot, midpoint_grid_labels): def test_grid_system_legacy_gui(qtbot, legacy_grid_labels): - app = MainWindow() - app.loadLabelsObject(legacy_grid_labels) + app = MainWindow(no_usage_data=True) + app.commands.loadLabelsObject(legacy_grid_labels) assert len(app.state["labeled_frame"]) == 1 lf = app.state["labeled_frame"] diff --git a/tests/gui/test_import.py b/tests/gui/test_import.py index 85b2c0bf3..f9f10589a 100644 --- a/tests/gui/test_import.py +++ b/tests/gui/test_import.py @@ -7,6 +7,7 @@ def test_gui_import(qtbot): file_names = [ "tests/data/hdf5_format_v1/training.scale=0.50,sigma=10.h5", "tests/data/videos/small_robot.mp4", + "tests/data/videos/robot0.jpg", ] importer = ImportParamDialog(file_names) @@ -15,24 +16,24 @@ def test_gui_import(qtbot): qtbot.addWidget(importer) data = importer.get_data() - assert len(data) == 2 + assert len(data) == len(file_names) assert len(data[0]["params"]) > 1 - for import_item in importer.import_widgets: + for import_item in importer.import_widgets[:2]: btn = import_item.enabled_checkbox_widget - with qtbot.waitSignal(btn.stateChanged, timeout=10): + with qtbot.waitSignal(btn.stateChanged, timeout=100): qtbot.mouseClick(btn, QtCore.Qt.LeftButton) assert not import_item.is_enabled() - assert len(importer.get_data()) == 0 + assert len(importer.get_data()) == 1 - for import_item in importer.import_widgets: + for import_item in importer.import_widgets[:2]: btn = import_item.enabled_checkbox_widget with qtbot.waitSignal(btn.stateChanged, timeout=10): qtbot.mouseClick(btn, QtCore.Qt.LeftButton) assert import_item.is_enabled() - assert len(importer.get_data()) == 2 + assert len(importer.get_data()) == len(file_names) def test_video_import_detect_grayscale(): diff --git a/tests/gui/test_inference_gui.py b/tests/gui/test_inference_gui.py index 16c989b71..ef3716895 100644 --- a/tests/gui/test_inference_gui.py +++ b/tests/gui/test_inference_gui.py @@ -41,17 +41,21 @@ def test_scoped_key_dict(): @pytest.mark.parametrize( - "labels_path, video_path", [("labels.slp", "video.mp4"), (None, "video.mp4")] + "labels_path, video_path, max_instances, frames", + [ + ("labels.slp", "video.mp4", None, [0, 1, 2]), + (None, "video.mp4", 1, [0, -1]), + (None, "video.mp4", 2, [1, -4]), + ], ) -def test_inference_cli_builder(labels_path, video_path): - +def test_inference_cli_builder(labels_path, video_path, max_instances, frames): inference_task = runners.InferenceTask( trained_job_paths=["model1", "model2"], - inference_params={"tracking.tracker": "simple"}, + inference_params={"tracking.tracker": "simple", "max_instances": max_instances}, ) item_for_inference = runners.VideoItemForInference( - video=Video.from_filename(video_path), frames=[1, 2, 3], labels_path=labels_path + video=Video.from_filename(video_path), frames=frames, labels_path=labels_path ) cli_args, output_path = inference_task.make_predict_cli_call(item_for_inference) @@ -62,7 +66,20 @@ def test_inference_cli_builder(labels_path, video_path): assert "model1" in cli_args assert "model2" in cli_args assert "--frames" in cli_args + + frames_idx = cli_args.index("--frames") + if -1 in frames: + assert cli_args[frames_idx + 1] == "0" # No redundant frames + elif -4 in frames: + assert cli_args[frames_idx + 1] == "1,-3" # Ordered correctly + else: + assert cli_args[frames_idx + 1] == ",".join([str(f) for f in frames]) assert "--tracking.tracker" in cli_args + assert ( + "--max_instances" in cli_args + if max_instances is not None + else max_instances is None + ) assert output_path.startswith(data_path) assert output_path.endswith("predictions.slp") @@ -153,3 +170,27 @@ def test_inference_merging(): assert len(labels[2].user_instances) == 1 # Only predicted instances with graphable points should be merged assert len(labels[2].predicted_instances) == 2 + + +def test_inference_movenet_cli(movenet_video): + + models = ["movenet-lightning", "movenet-thunder"] + + for model in models: + + inference_task = runners.InferenceTask( + trained_job_paths=[model], + inference_params={"tracking.tracker": None}, + ) + + item_for_inference = runners.VideoItemForInference( + video=movenet_video, frames=[1, 2, 3] + ) + + cli_args, output_path = inference_task.make_predict_cli_call(item_for_inference) + + # make sure cli call contains model + assert cli_args[0] == "sleap-track" + assert model in cli_args + assert "--frames" in cli_args + assert "--tracking.tracker" in cli_args diff --git a/tests/gui/test_monitor.py b/tests/gui/test_monitor.py index 51af0ca92..e0abea692 100644 --- a/tests/gui/test_monitor.py +++ b/tests/gui/test_monitor.py @@ -1,4 +1,3 @@ -from turtle import title from sleap.gui.widgets.monitor import LossViewer from sleap import TrainingJobConfig @@ -12,6 +11,9 @@ def test_monitor_release(qtbot, min_centroid_model_path): win.reset(what="Model Type", config=config) assert win.config.optimization.early_stopping.plateau_patience == 10 + # Ensure zmq port is set correctly + assert win.zmq_ports["controller_port"] == 9000 + assert win.zmq_ports["publish_port"] == 9001 # Ensure all lines of update_runtime() are run error-free win.is_running = True win.t0 = 0 @@ -28,13 +30,17 @@ def test_monitor_release(qtbot, min_centroid_model_path): # Enter "bes_val_x" conditional win.best_val_x = 0 win.best_val_y = win.last_epoch_val_loss - win.update_runtime() + win._update_runtime() win.close() # Make sure the first monitor released its zmq socket - win2 = LossViewer() + controller_port = 9191 + zmq_ports = dict(controller_port=controller_port) + win2 = LossViewer(zmq_ports=zmq_ports) win2.show() + assert win2.zmq_ports["controller_port"] == controller_port + assert win2.zmq_ports["publish_port"] == 9001 # Make sure batches to show field is working correction @@ -47,3 +53,14 @@ def test_monitor_release(qtbot, min_centroid_model_path): assert win2.batches_to_show == 200 win2.close() + + # Ensure zmq port is set correctly + controller_port = 9191 + publish_port = 9101 + zmq_ports = dict(controller_port=controller_port, publish_port=publish_port) + win3 = LossViewer(zmq_ports=zmq_ports) + win3.show() + assert win3.zmq_ports["controller_port"] == controller_port + assert win3.zmq_ports["publish_port"] == publish_port + + win3.close() diff --git a/tests/gui/test_state.py b/tests/gui/test_state.py index ff69b97ed..4f2caae84 100644 --- a/tests/gui/test_state.py +++ b/tests/gui/test_state.py @@ -50,9 +50,14 @@ def set_y_from_val_param_callback(x): assert times_x_changed == 4 assert state["x"] == 2 + # Test incrementing value with modulus of 1 + state.increment("x", mod=1) + assert times_x_changed == 5 + assert state["x"] == 0 + # test emitting callbacks without changing value state.emit("x") - assert times_x_changed == 5 + assert times_x_changed == 6 def test_gui_state_bool(): diff --git a/tests/gui/test_suggestions.py b/tests/gui/test_suggestions.py index 5630e3ce8..196ff2d35 100644 --- a/tests/gui/test_suggestions.py +++ b/tests/gui/test_suggestions.py @@ -6,6 +6,7 @@ from sleap.instance import LabeledFrame, PredictedInstance, Track, PredictedPoint from sleap.io.dataset import Labels from sleap.skeleton import Skeleton +import numpy as np def test_velocity_suggestions(centered_pair_predictions): @@ -23,6 +24,20 @@ def test_velocity_suggestions(centered_pair_predictions): assert suggestions[1].frame_idx == 45 +def test_max_point_displacement_suggestions(centered_pair_predictions): + suggestions = VideoFrameSuggestions.suggest( + labels=centered_pair_predictions, + params=dict( + videos=centered_pair_predictions.videos, + method="max_point_displacement", + displacement_threshold=6, + ), + ) + assert len(suggestions) == 19 + assert suggestions[0].frame_idx == 28 + assert suggestions[1].frame_idx == 82 + + def test_frame_increment(centered_pair_predictions: Labels): # Testing videos that have less frames than desired Samples per Video (stride) # Expected result is there should be n suggestions where n is equal to the frames @@ -81,11 +96,13 @@ def test_frame_increment(centered_pair_predictions: Labels): print(centered_pair_predictions.videos) -def test_video_selection(centered_pair_predictions: Labels): +def test_video_selection( + centered_pair_predictions: Labels, small_robot_3_frame_vid: Video +): # Testing the functionality of choosing a specific video in a project and # only generating suggestions for the video - centered_pair_predictions.add_video(Video.from_filename(filename="test.mp4")) + centered_pair_predictions.add_video(small_robot_3_frame_vid) # Testing suggestion generation from Image Features suggestions = VideoFrameSuggestions.suggest( labels=centered_pair_predictions, @@ -128,7 +145,8 @@ def test_video_selection(centered_pair_predictions: Labels): "videos": [centered_pair_predictions.videos[0]], "method": "prediction_score", "score_limit": 2, - "instance_limit": 1, + "instance_limit_upper": 2, + "instance_limit_lower": 1, }, ) @@ -150,6 +168,86 @@ def test_video_selection(centered_pair_predictions: Labels): # Confirming every suggestion is only for the video that is chosen and no other videos assert suggestions[i].video == centered_pair_predictions.videos[0] + # Ensure video target works given suggestions from another video already exist + centered_pair_predictions.set_suggestions(suggestions) + suggestions = VideoFrameSuggestions.suggest( + labels=centered_pair_predictions, + params={ + "videos": [centered_pair_predictions.videos[1]], + "method": "sample", + "per_video": 3, + "sampling_method": "random", + }, + ) + + # Testing suggestion generation from frame chunk targeting selected video or all videos + suggestions = VideoFrameSuggestions.suggest( + labels=centered_pair_predictions, + params={ + "videos": [centered_pair_predictions.videos[1]], + "method": "frame_chunk", + "frame_from": 1, + "frame_to": 3, + }, + ) + # Verify that frame 1-3 of video 1 are selected + for i in range(len(suggestions)): + assert suggestions[i].video == centered_pair_predictions.videos[1] + + # Testing suggestion generation from frame chunk targeting all videos + # Clear existing suggestions so that generated suggestions will be kept intact at the uniqueness check step + centered_pair_predictions.clear_suggestions() + suggestions = VideoFrameSuggestions.suggest( + labels=centered_pair_predictions, + params={ + "videos": centered_pair_predictions.videos, + "method": "frame_chunk", + "frame_from": 1, + "frame_to": 20, + }, + ) + # Verify that frame 1-20 of video 0 and 1-3 of video 1 are selected + assert len(suggestions) == 23 + + correct_sugg = True + for i in range(len(suggestions)): + if ( + suggestions[i].video == centered_pair_predictions.videos[1] + and suggestions[i].frame_idx > 2 + ): + correct_sugg = False + break + elif ( + suggestions[i].video == centered_pair_predictions.videos[0] + and suggestions[i].frame_idx > 19 + ): + correct_sugg = False + break + + assert correct_sugg + + # Testing when range exceeds video 1, only frames from video 0 are selected + suggestions = VideoFrameSuggestions.suggest( + labels=centered_pair_predictions, + params={ + "videos": centered_pair_predictions.videos, + "method": "frame_chunk", + "frame_from": 501, + "frame_to": 510, + }, + ) + # Verify that frame 501-600 of video 0 are selected + assert len(suggestions) == 10 + correct_sugg = True + for i in range(len(suggestions)): + if suggestions[i].video == centered_pair_predictions.videos[1]: + correct_sugg = False + break + elif suggestions[i].frame_idx < 500 or suggestions[i].frame_idx > 509: + correct_sugg = False + break + assert correct_sugg + def assert_suggestions_unique(labels: Labels, new_suggestions: List[SuggestionFrame]): for sugg in labels.suggestions: @@ -335,7 +433,8 @@ def test_append_suggestions(small_robot_3_frame_vid: Video, stickman: Skeleton): params={ "method": "prediction_score", "score_limit": 1, - "instance_limit": 1, + "instance_limit_upper": 2, + "instance_limit_lower": 1, "videos": labels.videos, }, ) @@ -352,3 +451,74 @@ def test_append_suggestions(small_robot_3_frame_vid: Video, stickman: Skeleton): }, ) assert_suggestions_unique(labels, suggestions) + + +def test_limits_prediction_score(centered_pair_predictions: Labels): + """Testing suggestion generation using instance limits and prediction score.""" + labels = centered_pair_predictions + score_limit = 20 + instance_lower_limit = 3 + instance_upper_limit = 3 + + # Generate suggestions + suggestions = VideoFrameSuggestions.suggest( + labels=labels, + params={ + "videos": labels.videos, + "method": "prediction_score", + "score_limit": score_limit, + "instance_limit_upper": instance_upper_limit, + "instance_limit_lower": instance_lower_limit, + }, + ) + + # Confirming every suggested frame meets criteria + for sugg in suggestions: + lf = labels.get((sugg.video, sugg.frame_idx)) + pred_instances = [ + inst for inst in lf.instances_to_show if isinstance(inst, PredictedInstance) + ] + n_instance_below_score = np.nansum( + [True for inst in pred_instances if inst.score <= score_limit] + ) + assert n_instance_below_score >= instance_lower_limit + assert n_instance_below_score <= instance_upper_limit + + # Confirming all frames meeting the criteria are captured + def check_all_predicted_instances(sugg, labels): + lfs = labels.labeled_frames + for lf in lfs: + pred_instances = [ + inst + for inst in lf.instances_to_show + if isinstance(inst, PredictedInstance) + ] + n_instance_below_score = np.nansum( + [True for inst in pred_instances if inst.score <= score_limit] + ) + if ( + n_instance_below_score <= instance_upper_limit + and n_instance_below_score >= instance_lower_limit + ): + temp_suggest = SuggestionFrame( + labels.video, pred_instances[0].frame_idx + ) + if not (temp_suggest in sugg): + return False + + return True + + suggestions_correct = check_all_predicted_instances(suggestions, labels) + assert suggestions_correct + + # Generate suggestions using frame chunk + suggestions = VideoFrameSuggestions.suggest( + labels=labels, + params={ + "method": "frame_chunk", + "frame_from": 1, + "frame_to": 15, + "videos": labels.videos, + }, + ) + assert_suggestions_unique(labels, suggestions) diff --git a/tests/gui/test_video_player.py b/tests/gui/test_video_player.py index 52ca49e68..c246f0489 100644 --- a/tests/gui/test_video_player.py +++ b/tests/gui/test_video_player.py @@ -3,13 +3,13 @@ from sleap.gui.widgets.video import ( QtVideoPlayer, GraphicsView, - QtInstance, QtVideoPlayer, QtTextWithBackground, + VisibleBoundingBox, ) from qtpy import QtCore, QtWidgets -from qtpy.QtGui import QColor +from qtpy.QtGui import QColor, QWheelEvent def test_gui_video(qtbot): @@ -19,10 +19,6 @@ def test_gui_video(qtbot): assert vp.close() - # Click the button 20 times - # for i in range(20): - # qtbot.mouseClick(vp.btn, QtCore.Qt.LeftButton) - def test_gui_video_instances(qtbot, small_robot_mp4_vid, centered_pair_labels): vp = QtVideoPlayer(small_robot_mp4_vid) @@ -110,3 +106,73 @@ def test_QtTextWithBackground(qtbot): scene.addItem(txt) qtbot.addWidget(view) + + +def test_VisibleBoundingBox(qtbot, centered_pair_labels): + vp = QtVideoPlayer(centered_pair_labels.video) + + test_idx = 27 + for instance in centered_pair_labels.labeled_frames[test_idx].instances: + vp.addInstance(instance) + + inst = vp.instances[0] + + # Check if type of bounding box is correct + assert type(inst.box) == VisibleBoundingBox + + # Scale the bounding box + start_top_left = inst.box.rect().topLeft() + start_bottom_right = inst.box.rect().bottomRight() + initial_width = inst.box.rect().width() + initial_height = inst.box.rect().height() + + dx = 5 + dy = 10 + + end_top_left = QtCore.QPointF(start_top_left.x() - dx, start_top_left.y() - dy) + end_bottom_right = QtCore.QPointF( + start_bottom_right.x() + dx, start_bottom_right.y() + dy + ) + + inst.box.setRect(QtCore.QRectF(end_top_left, end_bottom_right)) + + # Check if bounding box scaled appropriately + assert inst.box.rect().width() - initial_width == 2 * dx + assert inst.box.rect().height() - initial_height == 2 * dy + + +def test_wheelEvent(qtbot): + """Test the wheelEvent method of the GraphicsView class.""" + graphics_view = GraphicsView() + + # Create a QWheelEvent + position = QtCore.QPointF(100, 100) # The position of the wheel event + global_position = QtCore.QPointF(100, 100) # The global position of the wheel event + pixel_delta = QtCore.QPoint(0, 120) # The distance in pixels the wheel is rotated + angle_delta = QtCore.QPoint(0, 120) # The distance in degrees the wheel is rotated + buttons = QtCore.Qt.NoButton # No mouse button is pressed + modifiers = QtCore.Qt.NoModifier # No keyboard modifier is pressed + phase = QtCore.Qt.ScrollUpdate # The phase of the scroll event + inverted = False # The scroll direction is not inverted + source = ( + QtCore.Qt.MouseEventNotSynthesized + ) # The event is not synthesized from a touch or tablet event + + event = QWheelEvent( + position, + global_position, + pixel_delta, + angle_delta, + buttons, + modifiers, + phase, + inverted, + source, + ) + + # Call the wheelEvent method + print( + "Testing GraphicsView.wheelEvent which will result in exit code 127 " + "originating from a segmentation fault if it fails." + ) + graphics_view.wheelEvent(event) diff --git a/tests/gui/test_release_checker.py b/tests/gui/test_web.py similarity index 91% rename from tests/gui/test_release_checker.py rename to tests/gui/test_web.py index 4fd3ee3b3..cf6bf45ec 100644 --- a/tests/gui/test_release_checker.py +++ b/tests/gui/test_web.py @@ -1,5 +1,5 @@ import pandas as pd -from sleap.gui.release_checker import ReleaseChecker, Release +from sleap.gui.web import ReleaseChecker, Release, get_analytics_data, ping_analytics import pytest @@ -70,3 +70,8 @@ def test_release_checker(): assert len(checker.releases) == 2 assert checker.releases[0] != rls_test assert checker.releases[1] != rls_test + + +def test_get_analytics_data(): + analytics_data = get_analytics_data() + assert "platform" in analytics_data diff --git a/tests/gui/widgets/test_docks.py b/tests/gui/widgets/test_docks.py new file mode 100644 index 000000000..d5c16a763 --- /dev/null +++ b/tests/gui/widgets/test_docks.py @@ -0,0 +1,135 @@ +"""Module for testing dock widgets for the `MainWindow`.""" + +from pathlib import Path + +import numpy as np + +from sleap import Labels, Video +from sleap.gui.app import MainWindow +from sleap.gui.commands import AddInstance, OpenSkeleton +from sleap.gui.widgets.docks import ( + InstancesDock, + SkeletonDock, + SuggestionsDock, + VideosDock, +) + + +def test_videos_dock( + qtbot, + centered_pair_predictions: Labels, + small_robot_mp4_vid: Video, + centered_pair_vid: Video, + small_robot_3_frame_vid: Video, +): + """Test the `DockWidget` class.""" + + # Add some extra videos to the labels + labels = centered_pair_predictions + labels.add_video(small_robot_3_frame_vid) + labels.add_video(centered_pair_vid) + labels.add_video(small_robot_mp4_vid) + assert len(labels.videos) == 4 + + # Create the dock + main_window = MainWindow() + + # Use commands to set the labels instead of setting it directly + # To make sure other dependent instances like color_manager are also set + main_window.commands.loadLabelsObject(labels) + + video_state = labels.videos[-1] + main_window.state["video"] = video_state + dock = VideosDock(main_window) + + # Test that the dock was created correctly + assert dock.name == "Videos" + assert dock.main_window is main_window + assert dock.wgt_layout is dock.widget().layout() + + # Test that videos can be removed + + # No videos selected, won't remove anything + dock.main_window._buttons["remove video"].click() + assert len(labels.videos) == 4 + + # Select the last video, should remove that one and update state + + dock.main_window.videos_dock.table.selectRowItem(small_robot_mp4_vid) + dock.main_window._buttons["remove video"].click() + assert len(labels.videos) == 3 + assert video_state not in labels.videos + assert main_window.state["video"] == labels.videos[-1] + + # Select the last two videos, should remove those two and update state + idxs = [1, 2] + videos_to_be_removed = [labels.videos[i] for i in idxs] + main_window.state["selected_batch_video"] = idxs + dock.main_window._buttons["remove video"].click() + assert len(labels.videos) == 1 + assert ( + videos_to_be_removed[0] not in labels.videos + and videos_to_be_removed[1] not in labels.videos + ) + assert main_window.state["video"] == labels.videos[-1] + + +def test_skeleton_dock(qtbot): + """Test the `DockWidget` class.""" + main_window = MainWindow() + dock = SkeletonDock(main_window) + + assert dock.name == "Skeleton" + assert dock.main_window is main_window + assert dock.wgt_layout is dock.widget().layout() + + # This method should get called when we click the load button, but let's just call + # the non-gui parts directly + fn = Path( + OpenSkeleton.get_template_skeleton_filename(context=dock.main_window.commands) + ) + assert fn.name == f"{dock.skeleton_templates.currentText()}.json" + + +def test_suggestions_dock(qtbot): + """Test the `DockWidget` class.""" + main_window = MainWindow() + dock = SuggestionsDock(main_window) + + assert dock.name == "Labeling Suggestions" + assert dock.main_window is main_window + assert dock.wgt_layout is dock.widget().layout() + + +def test_instances_dock(qtbot, centered_pair_predictions: Labels): + """Test the `DockWidget` class.""" + main_window = MainWindow(labels=centered_pair_predictions) + labels = main_window.labels + context = main_window.commands + lf = context.state["labeled_frame"] + dock = InstancesDock(main_window) + + assert dock.name == "Instances" + assert dock.main_window is main_window + assert dock.wgt_layout is dock.widget().layout() + + # Test new instance button + + offset = 10 + + # Find instance that we will copy from + ( + copy_instance, + from_predicted, + from_prev_frame, + ) = AddInstance.find_instance_to_copy_from( + context, copy_instance=None, init_method="best" + ) + n_instance = len(lf.instances) + dock.main_window._buttons["new instance"].click() + + # Check that new instance was added with offset + assert len(lf.instances) == n_instance + 1 + new_inst = lf.instances[-1] + diff = np.nan_to_num(new_inst.numpy() - copy_instance.numpy(), nan=offset) + assert np.all(diff == offset) diff --git a/tests/info/test_metrics.py b/tests/info/test_metrics.py new file mode 100644 index 000000000..0d2e097e6 --- /dev/null +++ b/tests/info/test_metrics.py @@ -0,0 +1,55 @@ +import numpy as np + +from sleap import Labels +from sleap.info.metrics import ( + match_instance_lists_nodewise, + matched_instance_distances, +) + + +def test_matched_instance_distances(centered_pair_labels, centered_pair_predictions): + labels_gt = centered_pair_labels + labels_pr = centered_pair_predictions + + # Match each ground truth instance node to the closest corresponding node + # from any predicted instance in the same frame. + + inst_matching_func = match_instance_lists_nodewise + + # Calculate distances + frame_idxs, D, points_gt, points_pr = matched_instance_distances( + labels_gt, labels_pr, inst_matching_func + ) + + # Show mean difference for each node + node_names = labels_gt.skeletons[0].node_names + expected_values = { + "head": 0.872426920709296, + "neck": 0.8016280746914615, + "thorax": 0.8602021363390538, + "abdomen": 1.01012200038258, + "wingL": 1.1297727023475939, + "wingR": 1.0869857897008424, + "forelegL1": 0.780584225081443, + "forelegL2": 1.170805798894702, + "forelegL3": 1.1020486509389473, + "forelegR1": 0.9014698776116817, + "forelegR2": 0.9448001033112047, + "forelegR3": 1.308385214215777, + "midlegL1": 0.9095691623265347, + "midlegL2": 1.2203595627907582, + "midlegL3": 0.9813843358470163, + "midlegR1": 0.9871017182813739, + "midlegR2": 1.0209829335569256, + "midlegR3": 1.0990681234096988, + "hindlegL1": 1.0005335192834348, + "hindlegL2": 1.273539518539708, + "hindlegL3": 1.1752245985832817, + "hindlegR1": 1.1402833959265248, + "hindlegR2": 1.3143221301212737, + "hindlegR3": 1.0441458592503365, + } + + for node_idx, node_name in enumerate(node_names): + mean_d = np.nanmean(D[..., node_idx]) + assert np.isclose(mean_d, expected_values[node_name], atol=1e-6) diff --git a/tests/info/test_summary.py b/tests/info/test_summary.py index 2cf76c166..672d97e63 100644 --- a/tests/info/test_summary.py +++ b/tests/info/test_summary.py @@ -37,6 +37,19 @@ def test_frame_statistics(simple_predictions): x = stats.get_point_displacement_series(video, "max") assert len(x) == 2 - assert len(x) == 2 assert x[0] == 0 assert x[1] == 18.0 + + +def test_get_tracking_score_series(min_tracks_2node_predictions): + + stats = StatisticSeries(min_tracks_2node_predictions) + x = stats.get_tracking_score_series(min_tracks_2node_predictions.video, "min") + assert len(x) == 1500 + assert x[0] == 0.9999966621398926 + assert x[1000] == 0.9998022317886353 + + x = stats.get_tracking_score_series(min_tracks_2node_predictions.video, "mean") + assert len(x) == 1500 + assert x[0] == 0.9999983310699463 + assert x[1000] == 0.9999011158943176 diff --git a/tests/io/test_asyncvideo.py b/tests/io/test_asyncvideo.py deleted file mode 100644 index 1bc3f19c8..000000000 --- a/tests/io/test_asyncvideo.py +++ /dev/null @@ -1,31 +0,0 @@ -import pytest -import sys -from sleap import Video -from sleap.io.asyncvideo import AsyncVideo - - -@pytest.mark.skipif( - sys.platform.startswith("win"), reason="ZMQ testing breaks locally on Windows" -) -def test_async_video(centered_pair_vid, small_robot_mp4_vid): - async_video = AsyncVideo.from_video(centered_pair_vid, frames_per_chunk=23) - - all_idxs = [] - for idxs, frames in async_video.chunks: - assert len(idxs) in (23, 19) # 19 for last chunk - all_idxs.extend(idxs) - - assert frames.shape[0] == len(idxs) - assert frames.shape[1:] == centered_pair_vid.shape[1:] - - assert len(all_idxs) == centered_pair_vid.num_frames - - # make sure we can load another video (i.e., previous video closed) - - async_video = AsyncVideo.from_video( - small_robot_mp4_vid, frame_idxs=range(0, 10, 2), frames_per_chunk=10 - ) - - for idxs, frames in async_video.chunks: - # there should only be single chunk - assert idxs == list(range(0, 10, 2)) diff --git a/tests/io/test_convert.py b/tests/io/test_convert.py index 0d7114635..738c3d625 100644 --- a/tests/io/test_convert.py +++ b/tests/io/test_convert.py @@ -8,29 +8,33 @@ import pytest +@pytest.mark.parametrize("format", ["analysis", "analysis.nix", "analysis.csv"]) def test_analysis_format( min_labels_slp: Labels, min_labels_slp_path: Labels, small_robot_mp4_vid: Video, + format: str, tmpdir, ): labels = min_labels_slp slp_path = PurePath(min_labels_slp_path) tmpdir = PurePath(tmpdir) - def generate_filenames(paths): + def generate_filenames(paths, format="analysis"): output_paths = [path for path in paths] # Generate filenames if user has not specified (enough) output filenames labels_path = str(slp_path) fn = re.sub("(\\.json(\\.zip)?|\\.h5|\\.slp)$", "", labels_path) fn = PurePath(fn) + out_suffix = "nix" if "nix" in format else "csv" if "csv" in format else "h5" default_names = [ default_analysis_filename( labels=labels, video=video, output_path=str(fn.parent), output_prefix=str(fn.stem), + format_suffix=out_suffix, ) for video in labels.videos[len(paths) :] ] @@ -38,8 +42,8 @@ def generate_filenames(paths): output_paths.extend(default_names) return output_paths - def assert_analysis_existance(output_paths: list): - output_paths = generate_filenames(output_paths) + def assert_analysis_existance(output_paths: list, format="analysis"): + output_paths = generate_filenames(output_paths, format) for video, path in zip(labels.videos, output_paths): video_exists = Path(path).exists() if len(labels.get(video)) == 0: @@ -47,21 +51,21 @@ def assert_analysis_existance(output_paths: list): else: assert video_exists - def sleap_convert_assert(output_paths, slp_path): + def sleap_convert_assert(output_paths, slp_path, format="analysis"): output_args = "" for path in output_paths: output_args += f"-o {path} " - args = f"--format analysis {output_args}{slp_path}".split() + args = f"--format {format} {output_args}{slp_path}".split() sleap_convert(args) - assert_analysis_existance(output_paths) + assert_analysis_existance(output_paths, format) # No output specified output_paths = [] - sleap_convert_assert(output_paths, slp_path) + sleap_convert_assert(output_paths, slp_path, format) # Specify output and retest output_paths = [str(tmpdir.with_name("prefix")), str(tmpdir.with_name("prefix2"))] - sleap_convert_assert(output_paths, slp_path) + sleap_convert_assert(output_paths, slp_path, format) # Add video and retest labels.add_video(small_robot_mp4_vid) @@ -69,7 +73,7 @@ def sleap_convert_assert(output_paths, slp_path): labels.save(filename=slp_path) output_paths = [str(tmpdir.with_name("prefix"))] - sleap_convert_assert(output_paths, slp_path) + sleap_convert_assert(output_paths, slp_path, format) # Add labeled frame to video and retest labeled_frame = labels.find(video=labels.videos[1], frame_idx=0, return_new=True)[0] @@ -80,7 +84,7 @@ def sleap_convert_assert(output_paths, slp_path): labels.save(filename=slp_path) output_paths = [str(tmpdir.with_name("prefix"))] - sleap_convert_assert(output_paths, slp_path) + sleap_convert_assert(output_paths, slp_path, format) def test_sleap_format( diff --git a/tests/io/test_dataset.py b/tests/io/test_dataset.py index 5745e6e6e..d71d4cc83 100644 --- a/tests/io/test_dataset.py +++ b/tests/io/test_dataset.py @@ -1,9 +1,11 @@ import os +import pandas as pd import pytest import numpy as np from pathlib import Path, PurePath import sleap +from sleap.info.write_tracking_h5 import get_nodes_as_np_strings from sleap.skeleton import Skeleton from sleap.instance import Instance, Point, LabeledFrame, PredictedInstance, Track from sleap.io.video import Video, MediaVideo @@ -1234,7 +1236,7 @@ def test_has_frame(): @pytest.fixture def removal_test_labels(): skeleton = Skeleton() - video = Video(backend=MediaVideo(filename="test")) + video = Video(backend=MediaVideo(filename="test.mp4")) lf_user_only = LabeledFrame( video=video, frame_idx=0, instances=[Instance(skeleton=skeleton)] ) @@ -1332,7 +1334,7 @@ def test_remove_predictions_with_new_labels(removal_test_labels): assert labels[1].has_predicted_instances -def test_labels_numpy(centered_pair_predictions): +def test_labels_numpy(centered_pair_predictions: Labels): trx = centered_pair_predictions.numpy(video=None, all_frames=False, untracked=False) assert trx.shape == (1100, 27, 24, 2) @@ -1349,6 +1351,13 @@ def test_labels_numpy(centered_pair_predictions): trx = centered_pair_predictions.numpy(video=None, all_frames=True, untracked=False) assert trx.shape == (1100, 27, 24, 2) + centered_pair_predictions.remove_frame(centered_pair_predictions[-1]) + trx = centered_pair_predictions.numpy(video=None, all_frames=False, untracked=False) + assert trx.shape == (1098, 27, 24, 2) + + trx = centered_pair_predictions.numpy(video=None, all_frames=True, untracked=False) + assert trx.shape == (1100, 27, 24, 2) + labels_single = Labels( [ LabeledFrame( @@ -1359,13 +1368,47 @@ def test_labels_numpy(centered_pair_predictions): ) assert labels_single.numpy().shape == (1100, 1, 24, 2) - assert centered_pair_predictions.numpy(untracked=True).shape == (1100, 5, 24, 2) + assert centered_pair_predictions.numpy(untracked=True).shape == (1100, 4, 24, 2) for lf in centered_pair_predictions: for inst in lf: inst.track = None centered_pair_predictions.tracks = [] assert centered_pair_predictions.numpy(untracked=False).shape == (1100, 0, 24, 2) + # Test labels.numpy prefers user instances + skeleton = centered_pair_predictions.skeleton + lf = centered_pair_predictions.labeled_frames[0] + user_inst = Instance( + skeleton=skeleton, points={node: Point(1, 1) for node in skeleton.nodes} + ) + lf.instances.append(user_inst) + labels_np = centered_pair_predictions.numpy(untracked=True, return_confidence=True) + np.testing.assert_array_equal(labels_np[lf.frame_idx, 0, :, :-1], user_inst.numpy()) + + +def test_add_track(centered_pair_labels: Labels, small_robot_mp4_vid: Video): + labels = centered_pair_labels + new_video = small_robot_mp4_vid + + track = Track() + labels.add_track(new_video, track) + assert track in labels.tracks + assert new_video in labels._cache._track_occupancy + assert track in labels._cache._track_occupancy[new_video] + + +def test_add_instance(centered_pair_labels: Labels): + labels = centered_pair_labels + lf = labels[0] + track = Track() + inst = Instance(skeleton=labels.skeleton, track=track, frame=lf) + + labels.add_instance(lf, inst) + assert inst in labels.instances() + assert inst in lf.instances + assert track in labels.tracks + assert track in labels._cache._track_occupancy[lf.video] + def test_remove_track(centered_pair_predictions): labels = centered_pair_predictions @@ -1390,6 +1433,17 @@ def test_remove_all_tracks(centered_pair_predictions): assert all(inst.track is None for inst in labels.instances()) +def test_remove_unused_tracks(min_tracks_2node_labels: Labels): + labels = min_tracks_2node_labels + assert len(labels.tracks) == 2 + + labels.tracks.append(Track(name="unused", spawned_on=0)) + assert len(labels.tracks) == 3 + + labels.remove_unused_tracks() + assert len(labels.tracks) == 2 + + def test_remove_empty_frames(min_labels): min_labels.append(sleap.LabeledFrame(video=min_labels.video, frame_idx=2)) assert len(min_labels) == 2 @@ -1507,3 +1561,45 @@ def test_export_nwb(centered_pair_predictions: Labels, tmpdir): # Read from NWB file read_labels = NDXPoseAdaptor.read(NDXPoseAdaptor, filehandle.FileHandle(filename)) assert_read_labels_match(centered_pair_predictions, read_labels) + + +@pytest.mark.parametrize( + "labels_fixture_name", + [ + "centered_pair_labels", + "centered_pair_predictions", + "min_labels", + "min_labels_slp", + "min_labels_robot", + ], +) +def test_export_csv(labels_fixture_name, tmpdir, request): + # Retrieve Labels fixture by name + labels_fixture = request.getfixturevalue(labels_fixture_name) + + # Generate the filename for the CSV file + csv_filename = Path(tmpdir) / (labels_fixture_name + "_export.csv") + + # Export to CSV file + labels_fixture.export_csv(str(csv_filename)) + + # Assert that the CSV file was created + assert csv_filename.is_file(), f"CSV file '{csv_filename}' was not created" + + +def test_exported_csv(tmpdir, min_labels_slp, minimal_instance_predictions_csv_path): + # Construct the filename for the CSV file + filename_csv = Path(tmpdir) / "minimal_instance_predictions_export.csv" + labels = min_labels_slp + # Export to CSV file + labels.export_csv(filename_csv) + # Read the CSV file + labels_csv = pd.read_csv(filename_csv) + + # Read the csv file fixture + csv_predictions = pd.read_csv(minimal_instance_predictions_csv_path) + + assert labels_csv.equals(csv_predictions) + + # check number of cols + assert len(labels_csv.columns) - 3 == len(get_nodes_as_np_strings(labels)) * 3 diff --git a/tests/io/test_formats.py b/tests/io/test_formats.py index ec94bc4c3..cee754b7c 100644 --- a/tests/io/test_formats.py +++ b/tests/io/test_formats.py @@ -1,20 +1,37 @@ +import os +from pathlib import Path, PurePath + +import numpy as np +import pandas as pd +from numpy.testing import assert_array_equal +import pytest +import nixio + +from sleap.io.video import Video from sleap.instance import Instance, LabeledFrame, PredictedInstance, Track from sleap.io.dataset import Labels from sleap.io.format import read, dispatch, adaptor, text, genericjson, hdf5, filehandle from sleap.io.format.adaptor import SleapObjectType from sleap.io.format.alphatracker import AlphaTrackerAdaptor from sleap.io.format.ndx_pose import NDXPoseAdaptor +from sleap.io.format.nix import NixAdaptor from sleap.gui.commands import ImportAlphaTracker from sleap.gui.app import MainWindow from sleap.gui.state import GuiState +from sleap.info.write_tracking_h5 import get_nodes_as_np_strings +from sleap.io.format.sleap_analysis import SleapAnalysisAdaptor -import pytest -import os -from pathlib import Path, PurePath -import numpy as np -from numpy.testing import assert_array_equal -from sleap.io.video import Video +def test_sleap_analysis_read(small_robot_3_frame_vid, small_robot_3_frame_hdf5): + + # Single instance hdf5 analysis file test + read_labels = SleapAnalysisAdaptor.read( + file=small_robot_3_frame_hdf5, video=small_robot_3_frame_vid + ) + + assert len(read_labels.videos) == 1 + assert len(read_labels.tracks) == 1 + assert len(read_labels.skeletons) == 1 def test_text_adaptor(tmpdir): @@ -124,6 +141,24 @@ def test_hdf5_v1_filehandle(centered_pair_predictions_hdf5_path): ) +def test_csv(tmpdir, min_labels_slp, minimal_instance_predictions_csv_path): + from sleap.info.write_tracking_h5 import main as write_analysis + + filename_csv = str(tmpdir + "\\analysis.csv") + write_analysis(min_labels_slp, output_path=filename_csv, all_frames=True, csv=True) + + labels_csv = pd.read_csv(filename_csv) + + csv_predictions = pd.read_csv(minimal_instance_predictions_csv_path) + + assert labels_csv.equals(csv_predictions) + + labels = min_labels_slp + + # check number of cols + assert len(labels_csv.columns) - 3 == len(get_nodes_as_np_strings(labels)) * 3 + + def test_analysis_hdf5(tmpdir, centered_pair_predictions): from sleap.info.write_tracking_h5 import main as write_analysis @@ -174,8 +209,8 @@ def test_matching_adaptor(centered_pair_predictions_hdf5_path): @pytest.mark.parametrize( "test_data", [ - "tests/data/dlc/madlc_testdata.csv", - "tests/data/dlc/madlc_testdata_v2.csv", + "tests/data/dlc/labeled-data/video/madlc_testdata.csv", + "tests/data/dlc/labeled-data/video/madlc_testdata_v2.csv", ], ) def test_madlc(test_data): @@ -211,7 +246,82 @@ def test_madlc(test_data): @pytest.mark.parametrize( "test_data", - ["tests/data/dlc/dlc_testdata.csv", "tests/data/dlc/dlc_testdata_v2.csv"], + [ + "tests/data/dlc/labeled-data/video/maudlc_testdata.csv", + "tests/data/dlc/labeled-data/video/maudlc_testdata_v2.csv", + "tests/data/dlc/madlc_230_config.yaml", + ], +) +def test_maudlc(test_data): + labels = read( + test_data, + for_object="labels", + as_format="deeplabcut", + ) + + assert labels.skeleton.node_names == ["A", "B", "C", "D", "E"] + assert len(labels.videos) == 1 + assert len(labels.video.filenames) == 4 + assert labels.videos[0].filenames[0].endswith("img000.png") + assert labels.videos[0].filenames[1].endswith("img001.png") + assert labels.videos[0].filenames[2].endswith("img002.png") + assert labels.videos[0].filenames[3].endswith("img003.png") + + # Assert frames without any coor are not labeled + assert len(labels) == 3 + + # Assert number of instances per frame is correct + assert len(labels[0]) == 2 + assert len(labels[1]) == 3 + assert len(labels[2]) == 2 + + assert_array_equal( + labels[0][0].numpy(), + [[0, 1], [2, 3], [4, 5], [np.nan, np.nan], [np.nan, np.nan]], + ) + assert_array_equal( + labels[0][1].numpy(), + [[6, 7], [8, 9], [10, 11], [np.nan, np.nan], [np.nan, np.nan]], + ) + assert_array_equal( + labels[1][0].numpy(), + [[12, 13], [np.nan, np.nan], [15, 16], [np.nan, np.nan], [np.nan, np.nan]], + ) + assert_array_equal( + labels[1][1].numpy(), + [[17, 18], [np.nan, np.nan], [20, 21], [np.nan, np.nan], [np.nan, np.nan]], + ) + assert_array_equal( + labels[1][2].numpy(), + [[np.nan, np.nan], [np.nan, np.nan], [np.nan, np.nan], [22, 23], [24, 25]], + ) + assert_array_equal( + labels[2][0].numpy(), + [[26, 27], [28, 29], [30, 31], [np.nan, np.nan], [np.nan, np.nan]], + ) + assert_array_equal( + labels[2][1].numpy(), + [[np.nan, np.nan], [np.nan, np.nan], [np.nan, np.nan], [32, 33], [34, 35]], + ) + assert labels[2].frame_idx == 3 + + # Assert tracks are correct + assert len(labels.tracks) == 3 + sorted_animals = sorted(["Animal1", "Animal2", "single"]) + assert sorted([t.name for t in labels.tracks]) == sorted_animals + for t in labels.tracks: + if t.name == "single": + assert t.spawned_on == 1 + else: + assert t.spawned_on == 0 + + +@pytest.mark.parametrize( + "test_data", + [ + "tests/data/dlc/labeled-data/video/dlc_testdata.csv", + "tests/data/dlc/labeled-data/video/dlc_testdata_v2.csv", + ], ) def test_sadlc(test_data): labels = read( @@ -288,7 +398,7 @@ def test_alphatracker(qtbot): # Run through GUI display - app = MainWindow() + app = MainWindow(no_usage_data=True) app.state = GuiState() app.state["filename"] = filename @@ -397,3 +507,85 @@ def test_nwb( labels.instances = [] with pytest.raises(TypeError): NDXPoseAdaptor.write(NDXPoseAdaptor, filename, labels) + + +def test_nix_adaptor( + centered_pair_predictions: Labels, + small_robot_mp4_vid: Video, + tmpdir, +): + # general tests + na = NixAdaptor() + assert na.default_ext == "nix" + assert "nix" in na.all_exts + assert len(na.name) > 0 + assert na.can_write_filename("somefile.nix") + assert not na.can_write_filename("somefile.slp") + assert NixAdaptor.does_read() == False + assert NixAdaptor.does_write() == True + + with pytest.raises(NotImplementedError): + NixAdaptor.read("some file") + + print("writing test predictions to nix file...") + filename = str(PurePath(tmpdir, "ndx_pose_test.nix")) + with pytest.raises(ValueError): + NixAdaptor.write(filename, centered_pair_predictions, video=small_robot_mp4_vid) + NixAdaptor.write(filename, centered_pair_predictions) + NixAdaptor.write( + filename, centered_pair_predictions, video=centered_pair_predictions.videos[0] + ) + + # basic read tests using the generic nix library + import nixio + + file = nixio.File.open(filename, nixio.FileMode.ReadOnly) + try: + file_meta = file.sections[0] + assert file_meta["format"] == "nix.tracking" + assert "sleap" in file_meta["writer"].lower() + + assert len([b for b in file.blocks if b.type == "nix.tracking_results"]) > 0 + b = file.blocks[0] + assert ( + len( + [ + da + for da in b.data_arrays + if da.type == "nix.tracking.instance_position" + ] + ) + == 1 + ) + assert ( + len( + [ + da + for da in b.data_arrays + if da.type == "nix.tracking.instance_frameidx" + ] + ) + == 1 + ) + + inst_positions = b.data_arrays["position"] + assert len(inst_positions.shape) == 3 + assert len(inst_positions.shape) == len(inst_positions.dimensions) + assert inst_positions.shape[2] == len(centered_pair_predictions.nodes) + + frame_indices = b.data_arrays["frame"] + assert len(frame_indices.shape) == 1 + assert frame_indices.shape[0] == inst_positions.shape[0] + except Exception as e: + file.close() + raise e + + +def read_nix_meta(filename, *args, **kwargs): + file = nixio.File.open(filename, nixio.FileMode.ReadOnly) + try: + file_meta = file_meta = file.sections[0] + except Exception: + file.close() + + return file_meta diff --git a/tests/io/test_video.py b/tests/io/test_video.py index 46ce1b55c..4c3f8a5e9 100644 --- a/tests/io/test_video.py +++ b/tests/io/test_video.py @@ -12,10 +12,8 @@ DummyVideo, load_video, ) -from tests.fixtures.datasets import TEST_SLP_SIV_ROBOT + from tests.fixtures.videos import ( - TEST_H5_FILE, - TEST_SMALL_ROBOT_MP4_FILE, TEST_H5_DSET, TEST_H5_INPUT_FORMAT, TEST_SMALL_CENTERED_PAIR_VID, @@ -31,20 +29,25 @@ # See: https://github.com/pytest-dev/pytest/issues/349 -def test_from_filename(): - assert type(Video.from_filename(TEST_H5_FILE).backend) == HDF5Video - assert type(Video.from_filename(TEST_SMALL_ROBOT_MP4_FILE).backend) == MediaVideo +def test_from_filename(hdf5_file_path, small_robot_mp4_path): + assert type(Video.from_filename(hdf5_file_path).backend) == HDF5Video + assert type(Video.from_filename(small_robot_mp4_path).backend) == MediaVideo + assert ( + type(Video.from_filename(TEST_SMALL_ROBOT_SIV_FILE0).backend) + == SingleImageVideo + ) + with pytest.raises(ValueError): + Video.from_filename("this_has_no_video_extension") -def test_backend_extra_kwargs(): - Video.from_filename(TEST_H5_FILE, grayscale=True, another_kwarg=False) - Video.from_filename( - TEST_SMALL_ROBOT_MP4_FILE, dataset="no dataset", fake_kwarg=True - ) +def test_backend_extra_kwargs(hdf5_file_path, small_robot_mp4_path): + Video.from_filename(hdf5_file_path, grayscale=True, another_kwarg=False) + Video.from_filename(small_robot_mp4_path, dataset="no dataset", fake_kwarg=True) -def test_grayscale_video(): - assert Video.from_filename(TEST_SMALL_ROBOT_MP4_FILE, grayscale=True).shape[-1] == 1 + +def test_grayscale_video(small_robot_mp4_path): + assert Video.from_filename(small_robot_mp4_path, grayscale=True).shape[-1] == 1 def test_hdf5_get_shape(hdf5_vid): @@ -123,14 +126,12 @@ def test_numpy_frames(small_robot_mp4_vid): assert np.all(np.equal(np_vid.get_frame(1), small_robot_mp4_vid.get_frame(7))) -def test_is_missing(): - vid = Video.from_media(TEST_SMALL_ROBOT_MP4_FILE) +def test_is_missing(small_robot_mp4_path): + vid = Video.from_media(small_robot_mp4_path) assert not vid.is_missing vid = Video.from_media("non-existent-filename.mp4") assert vid.is_missing - vid = Video.from_numpy( - Video.from_media(TEST_SMALL_ROBOT_MP4_FILE).get_frames((3, 7, 9)) - ) + vid = Video.from_numpy(Video.from_media(small_robot_mp4_path).get_frames((3, 7, 9))) assert not vid.is_missing @@ -331,8 +332,8 @@ def test_hdf5_indexing(small_robot_mp4_vid, tmpdir): hdf5_vid2.get_frames([0, 1, 2]) -def test_hdf5_vid_from_open_dataset(): - with h5py.File(TEST_H5_FILE, "r") as f: +def test_hdf5_vid_from_open_dataset(hdf5_file_path): + with h5py.File(hdf5_file_path, "r") as f: dataset = f[TEST_H5_DSET] vid = Video( @@ -497,7 +498,7 @@ def test_reset_video_mp4(small_robot_mp4_vid: Video): assert_video_params(video=video, filename=filename, bgr=True, reset=True) -def test_reset_video_siv(small_robot_single_image_vid: Video, siv_robot: Labels): +def test_reset_video_siv(small_robot_single_image_vid: Video, siv_robot): video = small_robot_single_image_vid filename = video.backend.filename @@ -549,9 +550,50 @@ def test_reset_video_siv(small_robot_single_image_vid: Video, siv_robot: Labels) video.backend.reset(filename=filename, filenames=filenames) assert_video_params(video=video, filenames=filenames, reset=True) - # Test reset does not break deserialization of older slp - labels: Labels = Labels.load_file(TEST_SLP_SIV_ROBOT) + # Test reset does not break deserialization of older slp. + labels = siv_robot # This is actually tested upon passing in the fixture. video: Video = labels.video filename = labels.video.backend.filename labels.video.backend.reset(filename=filename, grayscale=True) assert_video_params(video=video, filenames=filenames, grayscale=True, reset=True) + + +def test_singleimagevideo_caching(siv_robot_caching): + # Test that older `SingleImageVideo` with type-hinted `caching` can be read in. + siv_robot_caching # This is actually tested upon passing in the fixture. + + # The below tests are for depreciated `SingleImageVideo.CACHING` functionality. + + # With caching + filename = siv_robot_caching.video.backend.filename + video = Video.from_filename(filename) + SingleImageVideo.CACHING = True + assert video.backend.test_frame_ is None + assert len(video.backend.cache_) == 0 + assert video.backend.channels_ is None + + assert video.backend.test_frame.shape == (320, 560, 3) + assert video.backend.test_frame_ is not None # Test frame stored! + assert len(video.backend.cache_) == 0 + assert video.backend.channels_ == 3 + + assert video[0].shape == (1, 320, 560, 3) + assert len(video.backend.cache_) == 1 # Loaded frame stored! + + # No caching + video = Video.from_filename(filename) + SingleImageVideo.CACHING = False + assert video.backend.test_frame_ is None + assert len(video.backend.cache_) == 0 + assert video.backend.channels_ is None + + assert video.backend.test_frame.shape == (320, 560, 3) + assert video.backend.test_frame_ is None # Test frame not stored! + assert len(video.backend.cache_) == 0 + assert video.backend.channels_ == 3 + + assert video.shape == (1, 320, 560, 3) + assert video.backend.test_frame_ is None # Test frame not stored! + + assert video[0].shape == (1, 320, 560, 3) + assert len(video.backend.cache_) == 0 # Loaded frame not stored! diff --git a/tests/io/test_videowriter.py b/tests/io/test_videowriter.py index dea193117..35d9bc6df 100644 --- a/tests/io/test_videowriter.py +++ b/tests/io/test_videowriter.py @@ -1,5 +1,7 @@ import os -from sleap.io.videowriter import VideoWriter, VideoWriterOpenCV +import cv2 +from pathlib import Path +from sleap.io.videowriter import VideoWriter, VideoWriterOpenCV, VideoWriterImageio def test_video_writer(tmpdir, small_robot_mp4_vid): @@ -38,3 +40,62 @@ def test_cv_video_writer(tmpdir, small_robot_mp4_vid): writer.close() assert os.path.exists(out_path) + + +def test_imageio_video_writer_avi(tmpdir, small_robot_mp4_vid): + out_path = Path(tmpdir) / "clip.avi" + + # Make sure imageio video writer works + writer = VideoWriterImageio( + out_path, + height=small_robot_mp4_vid.height, + width=small_robot_mp4_vid.width, + fps=small_robot_mp4_vid.fps, + ) + + writer.add_frame(small_robot_mp4_vid[0][0]) + writer.add_frame(small_robot_mp4_vid[1][0]) + + writer.close() + + assert os.path.exists(out_path) + # Check attributes + assert writer.height == small_robot_mp4_vid.height + assert writer.width == small_robot_mp4_vid.width + assert writer.fps == small_robot_mp4_vid.fps + assert writer.filename == out_path + assert writer.crf == 21 + assert writer.preset == "superfast" + + +def test_imageio_video_writer_odd_size(tmpdir, movenet_video): + out_path = Path(tmpdir) / "clip.mp4" + + # Reduce the size of the video frames by 1 pixel in each dimension + reduced_height = movenet_video.height - 1 + reduced_width = movenet_video.width - 1 + + # Initialize the writer with the reduced dimensions + writer = VideoWriterImageio( + out_path, + height=reduced_height, + width=reduced_width, + fps=movenet_video.fps, + ) + + # Resize frames and add them to the video + for i in range(len(movenet_video) - 1): + frame = movenet_video[i][0] # Access the actual frame object + reduced_frame = cv2.resize(frame, (reduced_width, reduced_height)) + writer.add_frame(reduced_frame) + + writer.close() + + # Assertions to validate the test + assert os.path.exists(out_path) + assert writer.height == reduced_height + assert writer.width == reduced_width + assert writer.fps == movenet_video.fps + assert writer.filename == out_path + assert writer.crf == 21 + assert writer.preset == "superfast" diff --git a/tests/io/test_visuals.py b/tests/io/test_visuals.py index c92af29dc..a1223bfdf 100644 --- a/tests/io/test_visuals.py +++ b/tests/io/test_visuals.py @@ -1,6 +1,7 @@ import numpy as np import os import pytest +import cv2 from sleap.io.dataset import Labels from sleap.io.visuals import ( save_labeled_video, @@ -63,15 +64,57 @@ def test_serial_pipeline(centered_pair_predictions, tmpdir): ) +@pytest.mark.parametrize("background", ["original", "black", "white", "grey"]) +def test_sleap_render_with_different_backgrounds(background): + args = ( + f"-o test_{background}.avi -f 2 --scale 1.2 --frames 1,2 --video-index 0 " + f"--background {background} " + "tests/data/json_format_v2/centered_pair_predictions.json".split() + ) + sleap_render(args) + assert ( + os.path.exists(f"test_{background}.avi") + and os.path.getsize(f"test_{background}.avi") > 0 + ) + + # Check if the background is set correctly if not original background + if background != "original": + saved_video_path = f"test_{background}.avi" + cap = cv2.VideoCapture(saved_video_path) + ret, frame = cap.read() + + # Calculate mean color of the channels + b, g, r = cv2.split(frame) + mean_b = np.mean(b) + mean_g = np.mean(g) + mean_r = np.mean(r) + + # Set threshold values. Color is white if greater than white threshold, black + # if less than grey threshold and grey if in between both threshold values. + white_threshold = 240 + grey_threshold = 40 + + # Check if the average color is white, grey, or black + if all(val > white_threshold for val in [mean_b, mean_g, mean_r]): + background_color = "white" + elif all(val < grey_threshold for val in [mean_b, mean_g, mean_r]): + background_color = "black" + else: + background_color = "grey" + assert background_color == background + + def test_sleap_render(centered_pair_predictions): - args = f"-o testvis.avi -f 2 --scale 1.2 --frames 1,2 --video-index 0 tests/data/json_format_v2/centered_pair_predictions.json".split() + args = ( + "-o testvis.avi -f 2 --scale 1.2 --frames 1,2 --video-index 0 " + "tests/data/json_format_v2/centered_pair_predictions.json".split() + ) sleap_render(args) assert os.path.exists("testvis.avi") @pytest.mark.parametrize("crop", ["Half", "Quarter", None]) def test_write_visuals(tmpdir, centered_pair_predictions: Labels, crop: str): - labels = centered_pair_predictions video = centered_pair_predictions.videos[0] # Determine crop size relative to original size and scale @@ -90,6 +133,7 @@ def test_write_visuals(tmpdir, centered_pair_predictions: Labels, crop: str): video=video, frames=(0, 1, 2), fps=15, + edge_is_wedge=True, crop_size_xy=crop_size_xy, ) assert os.path.exists(path) diff --git a/tests/nn/architectures/test_common.py b/tests/nn/architectures/test_common.py index a40d621ef..96db870ea 100644 --- a/tests/nn/architectures/test_common.py +++ b/tests/nn/architectures/test_common.py @@ -2,7 +2,7 @@ import tensorflow as tf from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test from sleap.nn.architectures import common diff --git a/tests/nn/architectures/test_encoder_decoder.py b/tests/nn/architectures/test_encoder_decoder.py index 3ce019371..8b8f51f0a 100644 --- a/tests/nn/architectures/test_encoder_decoder.py +++ b/tests/nn/architectures/test_encoder_decoder.py @@ -2,7 +2,7 @@ import tensorflow as tf from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test from sleap.nn.architectures import encoder_decoder diff --git a/tests/nn/architectures/test_hourglass.py b/tests/nn/architectures/test_hourglass.py index 4efe79a1c..c45ff1b91 100644 --- a/tests/nn/architectures/test_hourglass.py +++ b/tests/nn/architectures/test_hourglass.py @@ -2,7 +2,7 @@ import tensorflow as tf from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test from sleap.nn.architectures import hourglass from sleap.nn.config import HourglassConfig diff --git a/tests/nn/architectures/test_leap.py b/tests/nn/architectures/test_leap.py index edf07396b..9a73c80d5 100644 --- a/tests/nn/architectures/test_leap.py +++ b/tests/nn/architectures/test_leap.py @@ -2,7 +2,7 @@ import tensorflow as tf from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test from sleap.nn.architectures import leap from sleap.nn.config import LEAPConfig diff --git a/tests/nn/architectures/test_pretrained_encoders.py b/tests/nn/architectures/test_pretrained_encoders.py index f318754ac..b1f7e0af8 100644 --- a/tests/nn/architectures/test_pretrained_encoders.py +++ b/tests/nn/architectures/test_pretrained_encoders.py @@ -3,7 +3,7 @@ import pytest from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test from sleap.nn.architectures import UnetPretrainedEncoder from sleap.nn.config import PretrainedEncoderConfig diff --git a/tests/nn/architectures/test_resnet.py b/tests/nn/architectures/test_resnet.py index 965ea3b72..b0d9d26eb 100644 --- a/tests/nn/architectures/test_resnet.py +++ b/tests/nn/architectures/test_resnet.py @@ -2,7 +2,7 @@ import tensorflow as tf from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test from sleap.nn.architectures import upsampling from sleap.nn.architectures import resnet diff --git a/tests/nn/architectures/test_unet.py b/tests/nn/architectures/test_unet.py index 98b6d7768..1dad7ea05 100644 --- a/tests/nn/architectures/test_unet.py +++ b/tests/nn/architectures/test_unet.py @@ -2,7 +2,7 @@ import tensorflow as tf from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test from sleap.nn.architectures import unet from sleap.nn.config import UNetConfig diff --git a/tests/nn/config/test_config_utils.py b/tests/nn/config/test_config_utils.py index 69e8ddec8..64d83a141 100644 --- a/tests/nn/config/test_config_utils.py +++ b/tests/nn/config/test_config_utils.py @@ -4,7 +4,7 @@ from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test from sleap.nn.config import utils diff --git a/tests/nn/data/test_augmentation.py b/tests/nn/data/test_augmentation.py index d2b468522..2b95a01a3 100644 --- a/tests/nn/data/test_augmentation.py +++ b/tests/nn/data/test_augmentation.py @@ -1,3 +1,4 @@ +import pytest import numpy as np import tensorflow as tf import sleap @@ -9,14 +10,95 @@ from sleap.nn.data import augmentation +@pytest.fixture +def dummy_instances_data_nans(): + return np.full((2, 2), np.nan, dtype=np.float32) + + +@pytest.fixture +def dummy_instances_data_mixed(): + return np.array([[0.1, np.nan], [0.0, 0.8]], dtype=np.float32) + + +@pytest.fixture +def dummy_image_data(): + return np.zeros((100, 100, 3), dtype=np.uint8) + + +@pytest.fixture +def dummy_instances_data_zeros(): + return np.zeros((2, 2), dtype=np.float32) + + +@pytest.fixture +def rotation_min_angle(): + return 90 + + +@pytest.fixture +def rotation_max_angle(): + return 90 + + +@pytest.fixture +def augmentation_config(rotation_min_angle, rotation_max_angle): + return augmentation.AugmentationConfig( + rotate=True, + rotation_min_angle=rotation_min_angle, + rotation_max_angle=rotation_max_angle, + ) + + +@pytest.fixture +def dummy_dataset(dummy_image_data, dummy_instances_data_zeros): + dataset = tf.data.Dataset.from_tensor_slices( + {"image": [dummy_image_data], "instances": [dummy_instances_data_zeros]} + ) + return dataset + + +@pytest.fixture +def augmenter(augmentation_config): + return augmentation.AlbumentationsAugmenter.from_config(augmentation_config) + + +# Test class instantiation and augmentation +@pytest.mark.parametrize( + "dummy_instances_data", + [ + pytest.param("dummy_instances_data_zeros", id="zeros"), + pytest.param("dummy_instances_data_nans", id="nans"), + pytest.param("dummy_instances_data_mixed", id="mixed"), + ], +) +def test_albumentations_augmenter( + dummy_image_data, dummy_instances_data, augmenter, dummy_dataset +): + # Apply augmentation + augmented_dataset = augmenter.transform_dataset(dummy_dataset) + + # Check if augmentation is applied + augmented_example = next(iter(augmented_dataset)) + assert augmented_example["image"].shape == (100, 100, 3) + assert augmented_example["instances"].shape == (2, 2) + + +# Test class method from_config +def test_albumentations_augmenter_from_config(augmentation_config): + augmenter = augmentation.AlbumentationsAugmenter.from_config(augmentation_config) + assert isinstance(augmenter, augmentation.AlbumentationsAugmenter) + assert augmenter.image_key == "image" + assert augmenter.instances_key == "instances" + + def test_augmentation(min_labels): labels_reader = providers.LabelsReader.from_user_instances(min_labels) ds = labels_reader.make_dataset() example_preaug = next(iter(ds)) - augmenter = augmentation.ImgaugAugmenter.from_config( + augmenter = augmentation.AlbumentationsAugmenter.from_config( augmentation.AugmentationConfig( - rotate=True, rotation_min_angle=-90, rotation_max_angle=-90 + rotate=True, rotation_min_angle=90, rotation_max_angle=90 ) ) ds = augmenter.transform_dataset(ds) @@ -52,13 +134,39 @@ def test_augmentation_with_no_instances(min_labels): ) p = min_labels.to_pipeline(user_labeled_only=False) - p += augmentation.ImgaugAugmenter.from_config( + p += augmentation.AlbumentationsAugmenter.from_config( augmentation.AugmentationConfig(rotate=True) ) exs = p.run() assert exs[-1]["instances"].shape[0] == 0 +def test_augmentation_edges(min_labels): + # Tests 1722 + height, width = min_labels[0].video.shape[1:3] + min_labels[0].instances.append( + sleap.Instance.from_numpy( + [[0, 0], [width, height]], + skeleton=min_labels.skeleton, + ) + ) + + labels_reader = providers.LabelsReader.from_user_instances(min_labels) + ds = labels_reader.make_dataset() + example_preaug = next(iter(ds)) + + augmenter = augmentation.AlbumentationsAugmenter.from_config( + augmentation.AugmentationConfig( + rotate=True, rotation_min_angle=90, rotation_max_angle=90 + ) + ) + ds = augmenter.transform_dataset(ds) + + example = next(iter(ds)) + # TODO: check for correctness + assert example["instances"].shape == (3, 2, 2) + + def test_random_cropper(min_labels): cropper = augmentation.RandomCropper(crop_height=64, crop_width=32) assert "image" in cropper.input_keys diff --git a/tests/nn/data/test_data_training.py b/tests/nn/data/test_data_training.py index eb79464e0..c90a29365 100644 --- a/tests/nn/data/test_data_training.py +++ b/tests/nn/data/test_data_training.py @@ -3,7 +3,7 @@ from sleap.nn.data.training import split_labels_train_val -sleap.use_cpu_only() # hide GPUs for test +# sleap.use_cpu_only() # hide GPUs for test def test_split_labels_train_val(): diff --git a/tests/nn/data/test_edge_maps.py b/tests/nn/data/test_edge_maps.py index 295360538..5eb13f9b8 100644 --- a/tests/nn/data/test_edge_maps.py +++ b/tests/nn/data/test_edge_maps.py @@ -2,7 +2,7 @@ import tensorflow as tf from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test from sleap.nn.data import providers from sleap.nn.data import edge_maps diff --git a/tests/nn/data/test_identity.py b/tests/nn/data/test_identity.py index 52d25dd1b..224eff0ba 100644 --- a/tests/nn/data/test_identity.py +++ b/tests/nn/data/test_identity.py @@ -10,7 +10,7 @@ ) -sleap.use_cpu_only() +# sleap.use_cpu_only() def test_make_class_vectors(): diff --git a/tests/nn/data/test_instance_centroids.py b/tests/nn/data/test_instance_centroids.py index 78dee251c..2d8f57627 100644 --- a/tests/nn/data/test_instance_centroids.py +++ b/tests/nn/data/test_instance_centroids.py @@ -3,7 +3,7 @@ import tensorflow as tf from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test import sleap from sleap.nn.data import providers diff --git a/tests/nn/data/test_instance_cropping.py b/tests/nn/data/test_instance_cropping.py index b54fb0e99..688f50dbd 100644 --- a/tests/nn/data/test_instance_cropping.py +++ b/tests/nn/data/test_instance_cropping.py @@ -3,7 +3,7 @@ import tensorflow as tf from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test from sleap.nn.data import providers from sleap.nn.data import instance_centroids diff --git a/tests/nn/data/test_normalization.py b/tests/nn/data/test_normalization.py index 20a1df4ec..d2eb7c290 100644 --- a/tests/nn/data/test_normalization.py +++ b/tests/nn/data/test_normalization.py @@ -3,7 +3,7 @@ import tensorflow as tf from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test from sleap.nn.data import normalization from sleap.nn.data import providers diff --git a/tests/nn/data/test_offset_regression.py b/tests/nn/data/test_offset_regression.py index 31e688839..ce63894d6 100644 --- a/tests/nn/data/test_offset_regression.py +++ b/tests/nn/data/test_offset_regression.py @@ -4,7 +4,7 @@ from sleap.nn.data import offset_regression -sleap.use_cpu_only() # hide GPUs for test +# sleap.use_cpu_only() # hide GPUs for test def test_make_offsets(): diff --git a/tests/nn/data/test_pipelines.py b/tests/nn/data/test_pipelines.py index 30b67e13c..7d442c32d 100644 --- a/tests/nn/data/test_pipelines.py +++ b/tests/nn/data/test_pipelines.py @@ -3,7 +3,7 @@ import tensorflow as tf from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test import sleap from sleap.nn.data import pipelines diff --git a/tests/nn/data/test_providers.py b/tests/nn/data/test_providers.py index 10fff1ef5..f30216e6a 100644 --- a/tests/nn/data/test_providers.py +++ b/tests/nn/data/test_providers.py @@ -2,8 +2,7 @@ import tensorflow as tf from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test -from tests.fixtures.videos import TEST_H5_FILE, TEST_SMALL_ROBOT_MP4_FILE +# use_cpu_only() # hide GPUs for test import sleap from sleap.nn.data import providers @@ -81,8 +80,8 @@ def test_labels_reader_subset(min_labels): assert examples[1]["example_ind"] == 1 -def test_video_reader_mp4(): - video_reader = providers.VideoReader.from_filepath(TEST_SMALL_ROBOT_MP4_FILE) +def test_video_reader_mp4(small_robot_mp4_path): + video_reader = providers.VideoReader.from_filepath(small_robot_mp4_path) ds = video_reader.make_dataset() example = next(iter(ds)) @@ -101,9 +100,9 @@ def test_video_reader_mp4(): assert example["scale"].dtype == tf.float32 -def test_video_reader_mp4_subset(): +def test_video_reader_mp4_subset(small_robot_mp4_path): video_reader = providers.VideoReader.from_filepath( - TEST_SMALL_ROBOT_MP4_FILE, example_indices=[2, 1, 4] + small_robot_mp4_path, example_indices=[2, 1, 4] ) assert len(video_reader) == 3 @@ -117,9 +116,9 @@ def test_video_reader_mp4_subset(): assert examples[2]["frame_ind"] == 4 -def test_video_reader_mp4_grayscale(): +def test_video_reader_mp4_grayscale(small_robot_mp4_path): video_reader = providers.VideoReader.from_filepath( - TEST_SMALL_ROBOT_MP4_FILE, grayscale=True + small_robot_mp4_path, grayscale=True ) ds = video_reader.make_dataset() example = next(iter(ds)) @@ -133,9 +132,9 @@ def test_video_reader_mp4_grayscale(): np.testing.assert_array_equal(example["raw_image_size"], (320, 560, 1)) -def test_video_reader_hdf5(): +def test_video_reader_hdf5(hdf5_file_path): video_reader = providers.VideoReader.from_filepath( - TEST_H5_FILE, dataset="/box", input_format="channels_first" + hdf5_file_path, dataset="/box", input_format="channels_first" ) ds = video_reader.make_dataset() example = next(iter(ds)) @@ -149,16 +148,14 @@ def test_video_reader_hdf5(): np.testing.assert_array_equal(example["raw_image_size"], (512, 512, 1)) -def test_labels_reader_multi_size(): +def test_labels_reader_multi_size(small_robot_mp4_path, hdf5_file_path): # Create some fake data using two different size videos. skeleton = sleap.Skeleton.from_names_and_edge_inds(["A"]) labels = sleap.Labels( [ sleap.LabeledFrame( frame_idx=0, - video=sleap.Video.from_filename( - TEST_SMALL_ROBOT_MP4_FILE, grayscale=True - ), + video=sleap.Video.from_filename(small_robot_mp4_path, grayscale=True), instances=[ sleap.Instance.from_pointsarray( np.array([[128, 128]]), skeleton=skeleton @@ -168,7 +165,7 @@ def test_labels_reader_multi_size(): sleap.LabeledFrame( frame_idx=0, video=sleap.Video.from_filename( - TEST_H5_FILE, dataset="/box", input_format="channels_first" + hdf5_file_path, dataset="/box", input_format="channels_first" ), instances=[ sleap.Instance.from_pointsarray( diff --git a/tests/nn/data/test_resizing.py b/tests/nn/data/test_resizing.py index e0f63ebbb..6ef15c2f1 100644 --- a/tests/nn/data/test_resizing.py +++ b/tests/nn/data/test_resizing.py @@ -1,20 +1,14 @@ import pytest import numpy as np import tensorflow as tf -from sleap.nn.system import use_cpu_only - -use_cpu_only() # hide GPUs for test - import sleap from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test from sleap.nn.data import resizing from sleap.nn.data import providers from sleap.nn.data.resizing import SizeMatcher -from tests.fixtures.videos import TEST_H5_FILE, TEST_SMALL_ROBOT_MP4_FILE - def test_find_padding_for_stride(): assert resizing.find_padding_for_stride( @@ -132,16 +126,14 @@ def test_resizer_from_config(): ) -def test_size_matcher(): +def test_size_matcher(small_robot_mp4_path, hdf5_file_path): # Create some fake data using two different size videos. skeleton = sleap.Skeleton.from_names_and_edge_inds(["A"]) labels = sleap.Labels( [ sleap.LabeledFrame( frame_idx=0, - video=sleap.Video.from_filename( - TEST_SMALL_ROBOT_MP4_FILE, grayscale=True - ), + video=sleap.Video.from_filename(small_robot_mp4_path, grayscale=True), instances=[ sleap.Instance.from_pointsarray( np.array([[128, 128]]), skeleton=skeleton @@ -151,7 +143,7 @@ def test_size_matcher(): sleap.LabeledFrame( frame_idx=0, video=sleap.Video.from_filename( - TEST_H5_FILE, dataset="/box", input_format="channels_first" + hdf5_file_path, dataset="/box", input_format="channels_first" ), instances=[ sleap.Instance.from_pointsarray( @@ -213,3 +205,19 @@ def check_padding(image, from_y, to_y, from_x, to_x): check_padding(im1, 700, 750, 0, 750) im2 = next(transform_iter)["image"] assert im2.shape == (750, 750, 1) + + # Check SizeMatcher when target is larger in both dimensions + size_matcher = SizeMatcher( + max_image_height=560, max_image_width=560, center_pad=True + ) + transform_iter = iter(size_matcher.transform_dataset(ds)) + ex = next(transform_iter) + im1 = ex["image"] + assert im1.shape == (560, 560, 1) + # Check padding is on the top and bottom + check_padding(im1, 440, 560, 0, 560) + check_padding(im1, 0, 120, 0, 560) + assert ex["offset_x"] == 0 + assert ex["offset_y"] == 120 + im2 = next(transform_iter)["image"] + assert im2.shape == (560, 560, 1) diff --git a/tests/nn/data/test_utils.py b/tests/nn/data/test_utils.py index 213e357e8..7fa98a57a 100644 --- a/tests/nn/data/test_utils.py +++ b/tests/nn/data/test_utils.py @@ -2,7 +2,7 @@ import tensorflow as tf from sleap.nn.system import use_cpu_only -use_cpu_only() # hide GPUs for test +# use_cpu_only() # hide GPUs for test from sleap.nn.data import utils diff --git a/tests/nn/test_evals.py b/tests/nn/test_evals.py index 297fec36a..48f0d69f8 100644 --- a/tests/nn/test_evals.py +++ b/tests/nn/test_evals.py @@ -1,9 +1,148 @@ +from pathlib import Path import numpy as np +import tensorflow as tf + +from typing import List, Tuple + import sleap -from sleap.nn.evals import load_metrics +from sleap import Instance, PredictedInstance +from sleap.instance import Point +from sleap.nn.config.training_job import TrainingJobConfig +from sleap.nn.data.providers import LabelsReader +from sleap.nn.evals import ( + compute_dists, + compute_dist_metrics, + compute_oks, + load_metrics, + evaluate_model, +) +from sleap.nn.model import Model + + +# sleap.use_cpu_only() + + +def test_compute_oks(): + # Test compute_oks function with the cocoutils implementation + inst_gt = np.array([[0, 0], [1, 1], [2, 2]]).astype("float32") + inst_pr = np.array([[0, 0], [1, 1], [2, 2]]).astype("float32") + oks = compute_oks(inst_gt, inst_pr) + np.testing.assert_allclose(oks, 1) + + inst_pr = np.array([[0, 0], [1, 1], [np.nan, np.nan]]).astype("float32") + oks = compute_oks(inst_gt, inst_pr) + np.testing.assert_allclose(oks, 2 / 3) + + inst_gt = np.array([[0, 0], [1, 1], [np.nan, np.nan]]).astype("float32") + inst_pr = np.array([[0, 0], [1, 1], [2, 2]]).astype("float32") + oks = compute_oks(inst_gt, inst_pr) + np.testing.assert_allclose(oks, 1) + + inst_gt = np.array([[0, 0], [1, 1], [np.nan, np.nan]]).astype("float32") + inst_pr = np.array([[0, 0], [1, 1], [np.nan, np.nan]]).astype("float32") + oks = compute_oks(inst_gt, inst_pr) + np.testing.assert_allclose(oks, 1) + + # Test compute_oks function with the implementation from the paper + inst_gt = np.array([[0, 0], [1, 1], [2, 2]]).astype("float32") + inst_pr = np.array([[0, 0], [1, 1], [2, 2]]).astype("float32") + oks = compute_oks(inst_gt, inst_pr, False) + np.testing.assert_allclose(oks, 1) + + inst_pr = np.array([[0, 0], [1, 1], [np.nan, np.nan]]).astype("float32") + oks = compute_oks(inst_gt, inst_pr, False) + np.testing.assert_allclose(oks, 2 / 3) + + inst_gt = np.array([[0, 0], [1, 1], [np.nan, np.nan]]).astype("float32") + inst_pr = np.array([[0, 0], [1, 1], [2, 2]]).astype("float32") + oks = compute_oks(inst_gt, inst_pr, False) + np.testing.assert_allclose(oks, 1) + + inst_gt = np.array([[0, 0], [1, 1], [np.nan, np.nan]]).astype("float32") + inst_pr = np.array([[0, 0], [1, 1], [np.nan, np.nan]]).astype("float32") + oks = compute_oks(inst_gt, inst_pr, False) + np.testing.assert_allclose(oks, 1) + + +def test_compute_dists(instances, predicted_instances): + # Make some changes to the instances + error_start = 10 + error_end = 20 + expected_dists = [] + for offset, zipped_insts in enumerate( + zip( + instances[error_start:error_end], predicted_instances[error_start:error_end] + ) + ): + + inst, pred_inst = zipped_insts + for node_name in inst.skeleton.node_names: + pred_point = pred_inst[node_name] + if pred_point != np.NaN: + inst[node_name] = Point( + pred_point.x + offset, pred_point.y + offset + 1 + ) + + error = ((offset ** 2) + (offset + 1) ** 2) ** (1 / 2) + expected_dists.append(error) + + best_match_oks = np.NaN + positive_pairs: List[Tuple[Instance, PredictedInstance]] = [ + (inst, pred_inst, best_match_oks) + for inst, pred_inst in zip(instances, predicted_instances) + ] + + dists_dict = compute_dists(positive_pairs=positive_pairs) + dists = dists_dict["dists"] + + # Replace nan to 0 + dists_no_nan = np.nan_to_num(dists, nan=0) + np.testing.assert_allclose(dists_no_nan[0:10], 0) + + # Replace nan to negative (which we never see in a norm) + dists_no_nan = np.nan_to_num(dists, nan=-1) + + # Check distances are as expected + for idx, error in enumerate(expected_dists): + idx += error_start + dists_idx = dists_no_nan[idx] + dists_idx = dists_idx[dists_idx >= 0] + np.testing.assert_allclose(dists_idx, error) + + # Check instances are as expected + dists_metric = compute_dist_metrics(dists_dict) + for idx, zipped_metrics in enumerate( + zip(dists_metric["dist.frame_idxs"], dists_metric["dist.video_paths"]) + ): + frame_idx, video_path = zipped_metrics + assert frame_idx == instances[idx].frame.frame_idx + assert video_path == instances[idx].frame.video.backend.filename + + +def test_evaluate_model(min_labels_slp, min_bottomup_model_path): + + labels_reader = LabelsReader(labels=min_labels_slp, user_instances_only=True) + model_dir: str = min_bottomup_model_path + cfg = TrainingJobConfig.load_json(str(Path(model_dir, "training_config.json"))) + model = Model.from_config( + config=cfg.model, + skeleton=labels_reader.labels.skeletons[0], + tracks=labels_reader.labels.tracks, + update_config=True, + ) + model.keras_model = tf.keras.models.load_model( + Path(model_dir) / "best_model.h5", compile=False + ) -sleap.use_cpu_only() + labels_pr, metrics = evaluate_model( + cfg=cfg, + labels_gt=labels_reader, + model=model, + save=True, + split_name="test", + ) + assert metrics is not None # If metrics is None, then the metrics were not saved def test_load_metrics(min_centered_instance_model_path): diff --git a/tests/nn/test_heads.py b/tests/nn/test_heads.py index 02fbc2737..a4acbb15f 100644 --- a/tests/nn/test_heads.py +++ b/tests/nn/test_heads.py @@ -21,7 +21,7 @@ ) -sleap.use_cpu_only() +# sleap.use_cpu_only() def test_single_instance_confmaps_head(): diff --git a/tests/nn/test_inference.py b/tests/nn/test_inference.py index 85773436c..0a978de0a 100644 --- a/tests/nn/test_inference.py +++ b/tests/nn/test_inference.py @@ -1,22 +1,31 @@ import ast -import pytest -import numpy as np import json -from sleap.io.dataset import Labels +import zipfile +from pathlib import Path +from typing import cast +import shutil +import csv + +import numpy as np +import pytest +import pandas as pd import tensorflow as tf -import sleap from numpy.testing import assert_array_equal, assert_allclose -from pathlib import Path +from sleap.io.video import available_video_exts +import sleap +from sleap.gui.learning import runners +from sleap.io.dataset import Labels from sleap.nn.data.confidence_maps import ( make_confmaps, make_grid_vectors, make_multi_confmaps, ) - from sleap.nn.inference import ( InferenceLayer, InferenceModel, + Predictor, + _make_predictor_from_cli, get_model_output_stride, find_head, SingleInstanceInferenceLayer, @@ -34,16 +43,28 @@ BottomUpPredictor, BottomUpMultiClassPredictor, TopDownMultiClassPredictor, + MoveNetPredictor, + MoveNetInferenceLayer, + MoveNetInferenceModel, + MOVENET_MODELS, load_model, export_model, _make_cli_parser, _make_tracker_from_cli, main as sleap_track, + export_cli as sleap_export, + _make_export_cli_parser, +) +from sleap.nn.tracking import ( + MatchedFrameInstance, + FlowCandidateMaker, + FlowMaxTracksCandidateMaker, + Tracker, ) +from sleap.instance import Track -from sleap.gui.learning import runners -sleap.nn.system.use_cpu_only() +# sleap.nn.system.use_cpu_only() @pytest.fixture @@ -381,7 +402,11 @@ def test_inference_layer(): x = tf.keras.layers.Lambda(lambda x: x)(x_in) keras_model = tf.keras.Model(x_in, x) layer = sleap.nn.inference.InferenceLayer( - keras_model=keras_model, input_scale=1.0, pad_to_stride=1, ensure_grayscale=None + keras_model=keras_model, + input_scale=1.0, + pad_to_stride=1, + ensure_grayscale=None, + ensure_float=True, ) data = tf.cast(tf.fill([1, 4, 4, 1], 255), tf.uint8) out = layer(data) @@ -389,6 +414,23 @@ def test_inference_layer(): assert tuple(out.shape) == (1, 4, 4, 1) assert tf.reduce_all(out == 1.0) + # Not convert to float + x_in = tf.keras.layers.Input([4, 4, 1], dtype="uint8") + x = tf.keras.layers.Lambda(lambda x: x)(x_in) + keras_model = tf.keras.Model(x_in, x) + layer = sleap.nn.inference.InferenceLayer( + keras_model=keras_model, + input_scale=1.0, + pad_to_stride=1, + ensure_grayscale=True, + ensure_float=False, + ) + data = tf.cast(tf.fill([1, 4, 4, 1], 255), tf.uint8) + out = layer(data) + assert out.dtype == tf.uint8 + assert tuple(out.shape) == (1, 4, 4, 1) + assert tf.reduce_all(out == 255) + # Convert from rgb to grayscale, infer ensure grayscale x_in = tf.keras.layers.Input([4, 4, 1]) x = tf.keras.layers.Lambda(lambda x: x)(x_in) @@ -571,20 +613,32 @@ def test_single_instance_predictor( def test_single_instance_predictor_high_peak_thresh( min_labels_robot, min_single_instance_robot_model_path ): + predictor = SingleInstancePredictor.from_trained_models( + min_single_instance_robot_model_path, peak_threshold=0 + ) + predictor.verbosity = "none" + labels_pr = predictor.predict(min_labels_robot) + assert len(labels_pr) == 2 + assert len(labels_pr[0]) == 1 + assert labels_pr[0][0].n_visible_points == 2 + assert len(labels_pr[1]) == 1 + assert labels_pr[1][0].n_visible_points == 2 + predictor = SingleInstancePredictor.from_trained_models( min_single_instance_robot_model_path, peak_threshold=1.5 ) predictor.verbosity = "none" labels_pr = predictor.predict(min_labels_robot) assert len(labels_pr) == 2 - assert labels_pr[0][0].n_visible_points == 0 - assert labels_pr[1][0].n_visible_points == 0 + assert len(labels_pr[0]) == 0 + assert len(labels_pr[1]) == 0 def test_topdown_predictor_centroid(min_labels, min_centroid_model_path): predictor = TopDownPredictor.from_trained_models( centroid_model_path=min_centroid_model_path ) + predictor.verbosity = "none" labels_pr = predictor.predict(min_labels) assert len(labels_pr) == 1 @@ -602,12 +656,38 @@ def test_topdown_predictor_centroid(min_labels, min_centroid_model_path): assert_allclose(points_gt[inds1.numpy()], points_pr[inds2.numpy()], atol=1.5) +def test_topdown_predictor_centroid_max_instances(min_labels, min_centroid_model_path): + predictor = TopDownPredictor.from_trained_models( + centroid_model_path=min_centroid_model_path + ) + + # Test max_instances <, =, and > than number of expected instances + for i in [1, 2, 3]: + predictor._initialize_inference_model() + predictor.inference_model.centroid_crop.max_instances = i + labels_pr = predictor.predict(min_labels) + + assert len(labels_pr) == 1 + assert len(labels_pr[0].instances) == min(i, 2) + + +def test_topdown_predictor_centroid_high_threshold(min_labels, min_centroid_model_path): + predictor = TopDownPredictor.from_trained_models( + centroid_model_path=min_centroid_model_path, peak_threshold=1.5 + ) + predictor.verbosity = "none" + labels_pr = predictor.predict(min_labels) + assert len(labels_pr) == 1 + assert len(labels_pr[0].instances) == 0 + + def test_topdown_predictor_centered_instance( min_labels, min_centered_instance_model_path ): predictor = TopDownPredictor.from_trained_models( confmap_model_path=min_centered_instance_model_path ) + predictor.verbosity = "none" labels_pr = predictor.predict(min_labels) assert len(labels_pr) == 1 @@ -625,6 +705,18 @@ def test_topdown_predictor_centered_instance( assert_allclose(points_gt[inds1.numpy()], points_pr[inds2.numpy()], atol=1.5) +def test_topdown_predictor_centered_instance_high_threshold( + min_labels, min_centered_instance_model_path +): + predictor = TopDownPredictor.from_trained_models( + confmap_model_path=min_centered_instance_model_path, peak_threshold=1.5 + ) + predictor.verbosity = "none" + labels_pr = predictor.predict(min_labels) + assert len(labels_pr) == 1 + assert len(labels_pr[0].instances) == 0 + + def test_bottomup_predictor(min_labels, min_bottomup_model_path): predictor = BottomUpPredictor.from_trained_models( model_path=min_bottomup_model_path @@ -655,6 +747,16 @@ def test_bottomup_predictor(min_labels, min_bottomup_model_path): assert len(labels_pr[0]) == 0 +def test_bottomup_predictor_high_peak_thresh(min_labels, min_bottomup_model_path): + predictor = BottomUpPredictor.from_trained_models( + model_path=min_bottomup_model_path, peak_threshold=1.5 + ) + predictor.verbosity = "none" + labels_pr = predictor.predict(min_labels) + assert len(labels_pr) == 1 + assert len(labels_pr[0].instances) == 0 + + def test_bottomup_multiclass_predictor( min_tracks_2node_labels, min_bottomup_multiclass_model_path ): @@ -687,6 +789,20 @@ def test_bottomup_multiclass_predictor( labels_pr[0][1].track.name == "male" +def test_bottomup_multiclass_predictor_high_threshold( + min_tracks_2node_labels, min_bottomup_multiclass_model_path +): + labels_gt = sleap.Labels(min_tracks_2node_labels[[0]]) + predictor = BottomUpMultiClassPredictor.from_trained_models( + model_path=min_bottomup_multiclass_model_path, + peak_threshold=1.5, + integral_refinement=False, + ) + labels_pr = predictor.predict(labels_gt) + assert len(labels_pr) == 1 + assert len(labels_pr[0].instances) == 0 + + def test_topdown_multiclass_predictor( min_tracks_2node_labels, min_topdown_multiclass_model_path ): @@ -713,34 +829,147 @@ def test_topdown_multiclass_predictor( ) -def test_load_model( - min_single_instance_robot_model_path, - min_centroid_model_path, - min_centered_instance_model_path, - min_bottomup_model_path, - min_topdown_multiclass_model_path, - min_bottomup_multiclass_model_path, +def test_topdown_multiclass_predictor_high_threshold( + min_tracks_2node_labels, min_topdown_multiclass_model_path ): - predictor = load_model(min_single_instance_robot_model_path) - assert isinstance(predictor, SingleInstancePredictor) + labels_gt = sleap.Labels(min_tracks_2node_labels[[0]]) + predictor = TopDownMultiClassPredictor.from_trained_models( + confmap_model_path=min_topdown_multiclass_model_path, + peak_threshold=1.5, + integral_refinement=False, + ) + labels_pr = predictor.predict(labels_gt) + assert len(labels_pr) == 1 + assert len(labels_pr[0].instances) == 0 + + +def zip_directory_with_itself(src_dir, output_path): + """Zip a directory, including the directory itself. + + Args: + src_dir: Path to directory to zip. + output_path: Path to output zip file. + """ + + src_path = Path(src_dir) + with zipfile.ZipFile(output_path, "w", zipfile.ZIP_DEFLATED) as zipf: + for file_path in src_path.rglob("*"): + arcname = src_path.name / file_path.relative_to(src_path) + zipf.write(file_path, arcname) + + +def zip_directory_contents(src_dir, output_path): + """Zip the contents of a directory, not the directory itself. + + Args: + src_dir: Path to directory to zip. + output_path: Path to output zip file. + """ - predictor = load_model([min_centroid_model_path, min_centered_instance_model_path]) - assert isinstance(predictor, TopDownPredictor) + src_path = Path(src_dir) + with zipfile.ZipFile(output_path, "w", zipfile.ZIP_DEFLATED) as zipf: + for file_path in src_path.rglob("*"): + arcname = file_path.relative_to(src_path) + zipf.write(file_path, arcname) - predictor = load_model(min_bottomup_model_path) - assert isinstance(predictor, BottomUpPredictor) - predictor = load_model([min_centroid_model_path, min_topdown_multiclass_model_path]) - assert isinstance(predictor, TopDownMultiClassPredictor) +@pytest.mark.parametrize( + "zip_func", [zip_directory_with_itself, zip_directory_contents] +) +def test_load_model_zipped(tmpdir, min_centroid_model_path, zip_func): + mp = Path(min_centroid_model_path) + zip_dir = Path(tmpdir, mp.name).with_name(mp.name + ".zip") + zip_func(mp, zip_dir) + + predictor = load_model(str(zip_dir)) + + +@pytest.mark.parametrize("resize_input_shape", [True, False]) +@pytest.mark.parametrize( + "model_fixture_name", + [ + "min_centroid_model_path", + "min_centered_instance_model_path", + "min_bottomup_model_path", + "min_single_instance_robot_model_path", + "min_bottomup_multiclass_model_path", + "min_topdown_multiclass_model_path", + ], +) +def test_load_model(resize_input_shape, model_fixture_name, request): + model_path = request.getfixturevalue(model_fixture_name) + fname_mname_ptype_ishape = [ + ("centroid", "centroid_model", TopDownPredictor, (None, 384, 384, 1)), + ("centered_instance", "confmap_model", TopDownPredictor, (None, 96, 96, 1)), + ("bottomup_model", "bottomup_model", BottomUpPredictor, (None, 384, 384, 1)), + ( + "single_instance", + "confmap_model", + SingleInstancePredictor, + (None, 160, 280, 3), + ), + ( + "bottomup_multiclass", + "model", + BottomUpMultiClassPredictor, + (None, 512, 512, 1), + ), + ( + "topdown_multiclass", + "confmap_model", + TopDownMultiClassPredictor, + (None, 128, 128, 1), + ), + ] + expected_model_name = None + expected_predictor_type = None + input_shape = None + + # Create predictor + predictor = load_model(model_path, resize_input_layer=resize_input_shape) + + # Determine predictor type + for fname, mname, ptype, ishape in fname_mname_ptype_ishape: + if fname in model_fixture_name: + expected_model_name = mname + expected_predictor_type = ptype + input_shape = ishape + break + + # Assert predictor type and model input shape are correct + assert isinstance(predictor, expected_predictor_type) + keras_model = getattr(predictor, expected_model_name).keras_model + if resize_input_shape: + assert keras_model.input_shape == (None, None, None, input_shape[-1]) + else: + assert keras_model.input_shape == input_shape + + +def test_topdown_multi_size_inference( + min_centroid_model_path, + min_centered_instance_model_path, + centered_pair_labels, + min_tracks_2node_labels, +): + imgs = centered_pair_labels.video[:2] + assert imgs.shape == (2, 384, 384, 1) + + predictor = load_model( + [min_centroid_model_path, min_centered_instance_model_path], + resize_input_layer=True, + ) + preds = predictor.predict(imgs) + assert len(preds) == 2 - predictor = load_model(min_bottomup_multiclass_model_path) - assert isinstance(predictor, BottomUpMultiClassPredictor) + imgs = min_tracks_2node_labels.video[:2] + assert imgs.shape == (2, 1024, 1024, 1) + preds = predictor.predict(imgs) + assert len(preds) == 2 def test_ensure_numpy( min_centroid_model_path, min_centered_instance_model_path, min_labels_slp ): - model = load_model([min_centroid_model_path, min_centered_instance_model_path]) # each frame has same number of instances @@ -811,7 +1040,6 @@ def test_ensure_numpy( def test_centroid_inference(): - xv, yv = make_grid_vectors(image_height=12, image_width=12, output_stride=1) points = tf.cast([[[1.75, 2.75]], [[3.75, 4.75]], [[5.75, 6.75]]], tf.float32) cms = tf.expand_dims(make_multi_confmaps(points, xv, yv, sigma=1.5), axis=0) @@ -857,9 +1085,16 @@ def test_centroid_inference(): assert preds["centroids"].shape == (1, 3, 2) assert preds["centroid_vals"].shape == (1, 3) + # test max instances (>3 will fail) + layer.max_instances = 3 + out = layer(cms) -def export_frozen_graph(model, preds, output_path): + model = CentroidInferenceModel(layer) + + preds = model.predict(cms) + +def export_frozen_graph(model, preds, output_path): tensors = {} for key, val in preds.items(): @@ -886,7 +1121,6 @@ def export_frozen_graph(model, preds, output_path): info = json.load(json_file) for tensor_info in info["frozen_model_inputs"] + info["frozen_model_outputs"]: - saved_name = ( tensor_info.split("Tensor(")[1].split(", shape")[0].replace('"', "") ) @@ -903,7 +1137,6 @@ def export_frozen_graph(model, preds, output_path): def test_single_instance_save(min_single_instance_robot_model_path, tmp_path): - single_instance_model = tf.keras.models.load_model( min_single_instance_robot_model_path + "/best_model.h5", compile=False ) @@ -918,7 +1151,6 @@ def test_single_instance_save(min_single_instance_robot_model_path, tmp_path): def test_centroid_save(min_centroid_model_path, tmp_path): - centroid_model = tf.keras.models.load_model( min_centroid_model_path + "/best_model.h5", compile=False ) @@ -937,7 +1169,6 @@ def test_centroid_save(min_centroid_model_path, tmp_path): def test_topdown_save( min_centroid_model_path, min_centered_instance_model_path, min_labels_slp, tmp_path ): - centroid_model = tf.keras.models.load_model( min_centroid_model_path + "/best_model.h5", compile=False ) @@ -961,7 +1192,6 @@ def test_topdown_save( def test_topdown_id_save( min_centroid_model_path, min_topdown_multiclass_model_path, min_labels_slp, tmp_path ): - centroid_model = tf.keras.models.load_model( min_centroid_model_path + "/best_model.h5", compile=False ) @@ -983,74 +1213,158 @@ def test_topdown_id_save( def test_single_instance_predictor_save(min_single_instance_robot_model_path, tmp_path): - # directly initialize predictor predictor = SingleInstancePredictor.from_trained_models( - min_single_instance_robot_model_path + min_single_instance_robot_model_path, resize_input_layer=False ) predictor.export_model(save_path=tmp_path.as_posix()) # high level load to predictor - predictor = load_model(min_single_instance_robot_model_path) + predictor = load_model( + min_single_instance_robot_model_path, resize_input_layer=False + ) predictor.export_model(save_path=tmp_path.as_posix()) - # high level export - + # high level export (with unragging) export_model(min_single_instance_robot_model_path, save_path=tmp_path.as_posix()) + cmd = f"-m {min_single_instance_robot_model_path} -e {tmp_path.as_posix()}" + sleap_export(cmd.split()) + + # high level export (without unragging) + export_model( + min_single_instance_robot_model_path, + save_path=tmp_path.as_posix(), + unrag_outputs=False, + ) + + # max_instances should raise an exception for single instance + with pytest.raises(Exception): + export_model( + min_single_instance_robot_model_path, + save_path=tmp_path.as_posix(), + unrag_outputs=False, + max_instances=1, + ) + + +def test_make_export_cli(): + models_path = r"psuedo/models/path" + export_path = r"psuedo/test/path" + max_instances = 5 + + parser = _make_export_cli_parser() + + # Test default values + args = None + args, _ = parser.parse_known_args(args=args) + assert args.models is None + assert args.export_path == "exported_model" + assert not args.ragged + assert args.max_instances is None + + # Test all arguments + cmd = f"-m {models_path} -e {export_path} -r -n {max_instances}" + args, _ = parser.parse_known_args(args=cmd.split()) + assert args.models == [models_path] + assert args.export_path == export_path + assert args.ragged + assert args.max_instances == max_instances def test_topdown_predictor_save( min_centroid_model_path, min_centered_instance_model_path, tmp_path ): - # directly initialize predictor predictor = TopDownPredictor.from_trained_models( centroid_model_path=min_centroid_model_path, confmap_model_path=min_centered_instance_model_path, + resize_input_layer=False, ) predictor.export_model(save_path=tmp_path.as_posix()) # high level load to predictor - predictor = load_model([min_centroid_model_path, min_centered_instance_model_path]) + predictor = load_model( + [min_centroid_model_path, min_centered_instance_model_path], + resize_input_layer=False, + ) predictor.export_model(save_path=tmp_path.as_posix()) - # high level export + # high level export (with unragging) + export_model( + [min_centroid_model_path, min_centered_instance_model_path], + save_path=tmp_path.as_posix(), + ) + + # high level export (without unragging) export_model( [min_centroid_model_path, min_centered_instance_model_path], save_path=tmp_path.as_posix(), + unrag_outputs=False, + ) + + # test max instances + export_model( + [min_centroid_model_path, min_centered_instance_model_path], + save_path=tmp_path.as_posix(), + unrag_outputs=False, + max_instances=4, ) def test_topdown_id_predictor_save( min_centroid_model_path, min_topdown_multiclass_model_path, tmp_path ): - # directly initialize predictor predictor = TopDownMultiClassPredictor.from_trained_models( centroid_model_path=min_centroid_model_path, confmap_model_path=min_topdown_multiclass_model_path, + resize_input_layer=False, ) predictor.export_model(save_path=tmp_path.as_posix()) # high level load to predictor - predictor = load_model([min_centroid_model_path, min_topdown_multiclass_model_path]) + predictor = load_model( + [min_centroid_model_path, min_topdown_multiclass_model_path], + resize_input_layer=False, + ) predictor.export_model(save_path=tmp_path.as_posix()) - # high level export + # high level export (with unragging) + export_model( + [min_centroid_model_path, min_topdown_multiclass_model_path], + save_path=tmp_path.as_posix(), + ) + + # high level export (without unragging) + export_model( + [min_centroid_model_path, min_topdown_multiclass_model_path], + save_path=tmp_path.as_posix(), + unrag_outputs=False, + ) + + # test max instances export_model( [min_centroid_model_path, min_topdown_multiclass_model_path], save_path=tmp_path.as_posix(), + unrag_outputs=False, + max_instances=4, ) @pytest.mark.parametrize( - "output_path,tracker_method", [("not_default", "flow"), (None, "simple")] + "output_path,tracker_method", + [ + ("not_default", "flow"), + ("not_default", "flowmaxtracks"), + (None, "simple"), + (None, "simplemaxtracks"), + ], ) def test_retracking( centered_pair_predictions: Labels, tmpdir, output_path, tracker_method @@ -1059,13 +1373,15 @@ def test_retracking( labels: Labels = Labels.save(centered_pair_predictions, slp_path) # Create sleap-track command - cmd = f"{slp_path} --tracking.tracker {tracker_method} --frames 1-3 --cpu" cmd = ( f"{slp_path} --tracking.tracker {tracker_method} --video.index 0 --frames 1-3 " - "--cpu" + "--tracking.similarity object_keypoint --cpu" ) if tracker_method == "flow": cmd += " --tracking.save_shifted_instances 1" + elif tracker_method == "simplemaxtracks" or tracker_method == "flowmaxtracks": + cmd += " --tracking.max_tracking 1" + cmd += " --tracking.max_tracks 2" if output_path == "not_default": output_path = Path(tmpdir, "tracked_slp.slp") cmd += f" --output {output_path}" @@ -1079,6 +1395,8 @@ def test_retracking( parser = _make_cli_parser() args, _ = parser.parse_known_args(args=args) tracker = _make_tracker_from_cli(args) + # Additional check for similarity method + assert tracker.similarity_function.__name__ == "object_keypoint_similarity" output_path = f"{slp_path}.{tracker.get_name()}.slp" # Assert tracked predictions file exists @@ -1095,17 +1413,97 @@ def load_instance(labels_in: Labels): assert new_inst.track != old_inst.track -def test_sleap_track( +@pytest.mark.parametrize("cmd", ["--max_instances 1", "-n 1"]) +def test_valid_cli_command(cmd): + """Test that sleap-track CLI command is valid.""" + parser = _make_cli_parser() + args = parser.parse_args(cmd.split()) + assert args.max_instances == 1 + + +def test_make_predictor_from_cli( centered_pair_predictions: Labels, min_centroid_model_path: str, min_centered_instance_model_path: str, + min_bottomup_model_path: str, tmpdir, ): slp_path = str(Path(tmpdir, "old_slp.slp")) - labels: Labels = Labels.save(centered_pair_predictions, slp_path) + Labels.save(centered_pair_predictions, slp_path) + + # Create sleap-track command + model_args = [ + f"--model {min_centroid_model_path} --model {min_centered_instance_model_path}", + f"--model {min_bottomup_model_path}", + ] + for model_arg in model_args: + args = ( + f"{slp_path} {model_arg} --video.index 0 --frames 1-3 " + "--cpu --max_instances 5" + ).split() + parser = _make_cli_parser() + args, _ = parser.parse_known_args(args=args) + + # Create predictor + predictor = _make_predictor_from_cli(args=args) + if isinstance(predictor, TopDownPredictor): + assert predictor.inference_model.centroid_crop.max_instances == 5 + elif isinstance(predictor, BottomUpPredictor): + assert predictor.max_instances == 5 + + +def test_make_predictor_from_cli_mult_input( + centered_pair_predictions: Labels, + min_centroid_model_path: str, + min_centered_instance_model_path: str, + min_bottomup_model_path: str, + tmpdir, +): + slp_path = tmpdir.mkdir("slp_directory") + + slp_file = slp_path / "old_slp.slp" + Labels.save(centered_pair_predictions, slp_file) + + # Copy and paste the video into the temp dir multiple times + num_copies = 3 + for i in range(num_copies): + # Construct the destination path with a unique name for the video + + # Construct the destination path with a unique name for the SLP file + slp_dest_path = slp_path / f"old_slp_copy_{i}.slp" + shutil.copy(slp_file, slp_dest_path) + + # Create sleap-track command + model_args = [ + f"--model {min_centroid_model_path} --model {min_centered_instance_model_path}", + f"--model {min_bottomup_model_path}", + ] + for model_arg in model_args: + args = ( + f"{slp_path} {model_arg} --video.index 0 --frames 1-3 " + "--cpu --max_instances 5" + ).split() + parser = _make_cli_parser() + args, _ = parser.parse_known_args(args=args) + + # Create predictor + predictor = _make_predictor_from_cli(args=args) + if isinstance(predictor, TopDownPredictor): + assert predictor.inference_model.centroid_crop.max_instances == 5 + elif isinstance(predictor, BottomUpPredictor): + assert predictor.max_instances == 5 + + +def test_sleap_track_single_input( + centered_pair_predictions: Labels, + min_centroid_model_path: str, + min_centered_instance_model_path: str, + tmpdir, +): + slp_path = str(Path(tmpdir, "old_slp.slp")) + Labels.save(centered_pair_predictions, slp_path) # Create sleap-track command - args = f"{slp_path} --model {min_centered_instance_model_path} --frames 1-3 --cpu".split() args = ( f"{slp_path} --model {min_centroid_model_path} " f"--model {min_centered_instance_model_path} --video.index 0 --frames 1-3 --cpu" @@ -1115,10 +1513,564 @@ def test_sleap_track( sleap_track(args=args) # Assert predictions file exists - output_path = f"{slp_path}.predictions.slp" + output_path = Path(slp_path).with_suffix(".predictions.slp") assert Path(output_path).exists() # Create invalid sleap-track command args = [slp_path, "--cpu"] with pytest.raises(ValueError): sleap_track(args=args) + + +@pytest.mark.parametrize("tracking", ["simple", "flow", "None"]) +def test_sleap_track_mult_input_slp( + min_centroid_model_path: str, + min_centered_instance_model_path: str, + tmpdir, + centered_pair_predictions: Labels, + tracking, +): + # Create temporary directory with the structured video files + slp_path = tmpdir.mkdir("slp_directory") + + slp_file = slp_path / "old_slp.slp" + Labels.save(centered_pair_predictions, slp_file) + + slp_path_obj = Path(slp_path) + + # Copy and paste the video into the temp dir multiple times + num_copies = 3 + for i in range(num_copies): + # Construct the destination path with a unique name for the SLP file + slp_dest_path = slp_path / f"old_slp_copy_{i}.slp" + shutil.copy(slp_file, slp_dest_path) + + # Create sleap-track command + args = ( + f"{slp_path} --model {min_centroid_model_path} " + f"--tracking.tracker {tracking} " + f"--model {min_centered_instance_model_path} --video.index 0 --frames 1-3 --cpu" + ).split() + + slp_path_list = [file for file in slp_path_obj.iterdir() if file.is_file()] + + # Run inference + sleap_track(args=args) + + # Assert predictions file exists + expected_extensions = available_video_exts() + + for file_path in slp_path_list: + if file_path.suffix in expected_extensions: + expected_output_file = Path(file_path).with_suffix(".predictions.slp") + assert Path(expected_output_file).exists() + + +@pytest.mark.parametrize("tracking", ["simple", "flow", "None"]) +def test_sleap_track_mult_input_slp_mp4( + min_centroid_model_path: str, + min_centered_instance_model_path: str, + centered_pair_vid_path, + tracking, + tmpdir, + centered_pair_predictions: Labels, +): + # Create temporary directory with the structured video files + slp_path = tmpdir.mkdir("slp_mp4_directory") + + slp_file = slp_path / "old_slp.slp" + Labels.save(centered_pair_predictions, slp_file) + + # Copy and paste the video into temp dir multiple times + num_copies = 3 + for i in range(num_copies): + # Construct the destination path with a unique name + dest_path = slp_path / f"centered_pair_vid_copy_{i}.mp4" + shutil.copy(centered_pair_vid_path, dest_path) + + slp_path_obj = Path(slp_path) + + # Create sleap-track command + args = ( + f"{slp_path} --model {min_centroid_model_path} " + f"--tracking.tracker {tracking} " + f"--model {min_centered_instance_model_path} --video.index 0 --frames 1-3 --cpu" + ).split() + + slp_path_list = [file for file in slp_path_obj.iterdir() if file.is_file()] + + # Run inference + sleap_track(args=args) + + expected_extensions = available_video_exts() + + for file_path in slp_path_list: + if file_path.suffix in expected_extensions: + expected_output_file = Path(file_path).with_suffix(".predictions.slp") + assert Path(expected_output_file).exists() + + +@pytest.mark.parametrize("tracking", ["simple", "flow", "None"]) +def test_sleap_track_mult_input_mp4( + min_centroid_model_path: str, + min_centered_instance_model_path: str, + centered_pair_vid_path, + tracking, + tmpdir, +): + + # Create temporary directory with the structured video files + slp_path = tmpdir.mkdir("mp4_directory") + + # Copy and paste the video into the temp dir multiple times + num_copies = 3 + for i in range(num_copies): + # Construct the destination path with a unique name + dest_path = slp_path / f"centered_pair_vid_copy_{i}.mp4" + shutil.copy(centered_pair_vid_path, dest_path) + + slp_path_obj = Path(slp_path) + + # Create sleap-track command + args = ( + f"{slp_path} --model {min_centroid_model_path} " + f"--tracking.tracker {tracking} " + f"--model {min_centered_instance_model_path} --video.index 0 --frames 1-3 --cpu" + ).split() + + slp_path_list = [file for file in slp_path_obj.iterdir() if file.is_file()] + + # Run inference + sleap_track(args=args) + + # Assert predictions file exists + expected_extensions = available_video_exts() + + for file_path in slp_path_list: + if file_path.suffix in expected_extensions: + expected_output_file = Path(file_path).with_suffix(".predictions.slp") + assert Path(expected_output_file).exists() + + +def test_sleap_track_output_mult( + min_centroid_model_path: str, + min_centered_instance_model_path: str, + centered_pair_vid_path, + tmpdir, +): + + output_path = tmpdir.mkdir("output_directory") + output_path_obj = Path(output_path) + + # Create temporary directory with the structured video files + slp_path = tmpdir.mkdir("mp4_directory") + + # Copy and paste the video into the temp dir multiple times + num_copies = 3 + for i in range(num_copies): + # Construct the destination path with a unique name + dest_path = slp_path / f"centered_pair_vid_copy_{i}.mp4" + shutil.copy(centered_pair_vid_path, dest_path) + + slp_path_obj = Path(slp_path) + + # Create sleap-track command + args = ( + f"{slp_path} --model {min_centroid_model_path} " + f"--tracking.tracker simple " + f"-o {output_path} " + f"--model {min_centered_instance_model_path} --video.index 0 --frames 1-3 --cpu" + ).split() + + slp_path_list = [file for file in slp_path_obj.iterdir() if file.is_file()] + + # Run inference + sleap_track(args=args) + slp_path = Path(slp_path) + + # Check if there are any files in the directory + expected_extensions = available_video_exts() + + for file_path in slp_path_list: + if file_path.suffix in expected_extensions: + expected_output_file = output_path_obj / ( + file_path.stem + ".predictions.slp" + ) + assert Path(expected_output_file).exists() + + +def test_sleap_track_invalid_output( + min_centroid_model_path: str, + min_centered_instance_model_path: str, + centered_pair_vid_path, + centered_pair_predictions: Labels, + tmpdir, +): + + output_path = Path(tmpdir, "output_file.slp").as_posix() + Labels.save(centered_pair_predictions, output_path) + + # Create temporary directory with the structured video files + slp_path = tmpdir.mkdir("mp4_directory") + + # Copy and paste the video into the temp dir multiple times + num_copies = 3 + for i in range(num_copies): + # Construct the destination path with a unique name + dest_path = slp_path / f"centered_pair_vid_copy_{i}.mp4" + shutil.copy(centered_pair_vid_path, dest_path) + + # Create sleap-track command + args = ( + f"{slp_path} --model {min_centroid_model_path} " + f"--tracking.tracker simple " + f"-o {output_path} " + f"--model {min_centered_instance_model_path} --video.index 0 --frames 1-3 --cpu" + ).split() + + # Run inference + with pytest.raises(ValueError): + sleap_track(args=args) + + +def test_sleap_track_invalid_input( + min_centroid_model_path: str, + min_centered_instance_model_path: str, +): + + slp_path = "" + + # Create sleap-track command + args = ( + f"{slp_path} --model {min_centroid_model_path} " + f"--tracking.tracker simple " + f"--model {min_centered_instance_model_path} --video.index 0 --frames 1-3 --cpu" + ).split() + + # Run inference + with pytest.raises(ValueError): + sleap_track(args=args) + + # Test with a non-existent path + slp_path = "/path/to/nonexistent/file.mp4" + + # Create sleap-track command for non-existent path + args = ( + f"{slp_path} --model {min_centroid_model_path} " + f"--tracking.tracker simple " + f"--model {min_centered_instance_model_path} --video.index 0 --frames 1-3 --cpu" + ).split() + + # Run inference and expect a ValueError for non-existent path + with pytest.raises(ValueError): + sleap_track(args=args) + + +def test_sleap_track_csv_input( + min_centroid_model_path: str, + min_centered_instance_model_path: str, + centered_pair_vid_path, + tmpdir, +): + + # Create temporary directory with the structured video files + slp_path = Path(tmpdir.mkdir("mp4_directory")) + + # Copy and paste the video into the temp dir multiple times + num_copies = 3 + file_paths = [] + for i in range(num_copies): + # Construct the destination path with a unique name + dest_path = slp_path / f"centered_pair_vid_copy_{i}.mp4" + shutil.copy(centered_pair_vid_path, dest_path) + file_paths.append(dest_path) + + # Generate output paths for each data_path + output_paths = [ + file_path.with_suffix(".TESTpredictions.slp") for file_path in file_paths + ] + + # Create a CSV file with the file paths + csv_file_path = slp_path / "file_paths.csv" + with open(csv_file_path, mode="w", newline="") as csv_file: + csv_writer = csv.writer(csv_file) + csv_writer.writerow(["data_path", "output_path"]) + for data_path, output_path in zip(file_paths, output_paths): + csv_writer.writerow([data_path, output_path]) + + slp_path_obj = Path(slp_path) + + # Create sleap-track command + args = ( + f"{csv_file_path} --model {min_centroid_model_path} " + f"--tracking.tracker simple " + f"--model {min_centered_instance_model_path} --video.index 0 --frames 1-3 --cpu" + ).split() + + slp_path_list = [file for file in slp_path_obj.iterdir() if file.is_file()] + + # Run inference + sleap_track(args=args) + + # Assert predictions file exists + expected_extensions = available_video_exts() + + for file_path in slp_path_list: + if file_path.suffix in expected_extensions: + expected_output_file = file_path.with_suffix(".TESTpredictions.slp") + assert Path(expected_output_file).exists() + + +def test_sleap_track_invalid_csv( + min_centroid_model_path: str, + min_centered_instance_model_path: str, + tmpdir, +): + + # Create a CSV file with nonexistant data files + csv_nonexistant_files_path = tmpdir / "nonexistant_files.csv" + df_nonexistant_files = pd.DataFrame( + {"data_path": ["video1.mp4", "video2.mp4", "video3.mp4"]} + ) + df_nonexistant_files.to_csv(csv_nonexistant_files_path, index=False) + + # Create an empty CSV file + csv_empty_path = tmpdir / "empty.csv" + open(csv_empty_path, "w").close() + + # Create sleap-track command for missing 'data_path' column + args_missing_column = ( + f"{csv_nonexistant_files_path} --model {min_centroid_model_path} " + f"--tracking.tracker simple " + f"--model {min_centered_instance_model_path} --video.index 0 --frames 1-3 --cpu" + ).split() + + # Run inference and expect ValueError for missing 'data_path' column + with pytest.raises( + ValueError, + ): + sleap_track(args=args_missing_column) + + # Create sleap-track command for empty CSV file + args_empty = ( + f"{csv_empty_path} --model {min_centroid_model_path} " + f"--tracking.tracker simple " + f"--model {min_centered_instance_model_path} --video.index 0 --frames 1-3 --cpu" + ).split() + + # Run inference and expect ValueError for empty CSV file + with pytest.raises(ValueError): + sleap_track(args=args_empty) + + +def test_sleap_track_text_file_input( + min_centroid_model_path: str, + min_centered_instance_model_path: str, + centered_pair_vid_path, + tmpdir, +): + + # Create temporary directory with the structured video files + slp_path = Path(tmpdir.mkdir("mp4_directory")) + + # Copy and paste the video into the temp dir multiple times + num_copies = 3 + file_paths = [] + for i in range(num_copies): + # Construct the destination path with a unique name + dest_path = slp_path / f"centered_pair_vid_copy_{i}.mp4" + shutil.copy(centered_pair_vid_path, dest_path) + file_paths.append(dest_path) + + # Create a text file with the file paths + txt_file_path = slp_path / "file_paths.txt" + with open(txt_file_path, mode="w") as txt_file: + for file_path in file_paths: + txt_file.write(f"{file_path}\n") + + slp_path_obj = Path(slp_path) + + # Create sleap-track command + args = ( + f"{txt_file_path} --model {min_centroid_model_path} " + f"--tracking.tracker simple " + f"--model {min_centered_instance_model_path} --video.index 0 --frames 1-3 --cpu" + ).split() + + slp_path_list = [file for file in slp_path_obj.iterdir() if file.is_file()] + + # Run inference + sleap_track(args=args) + + # Assert predictions file exists + expected_extensions = available_video_exts() + + for file_path in slp_path_list: + if file_path.suffix in expected_extensions: + expected_output_file = Path(file_path).with_suffix(".predictions.slp") + assert Path(expected_output_file).exists() + + +def test_flow_tracker(centered_pair_predictions_sorted: Labels, tmpdir): + """Test flow tracker instances are pruned.""" + labels: Labels = centered_pair_predictions_sorted + track_window = 5 + + # Setup tracker + tracker: Tracker = Tracker.make_tracker_by_name( + tracker="flow", track_window=track_window, save_shifted_instances=True + ) + tracker.candidate_maker = cast(FlowCandidateMaker, tracker.candidate_maker) + + # Run tracking + frames = labels.labeled_frames + + # Run tracking on subset of frames using psuedo-implementation of + # sleap.nn.tracking.run_tracker + for lf in frames[:20]: + # Clear the tracks + for inst in lf.instances: + inst.track = None + + track_args = dict( + untracked_instances=lf.instances, + img=lf.video[lf.frame_idx], + img_hw=lf.image.shape[-3:-1], + ) + tracker.track(**track_args) + + # Check that saved instances are pruned to track window + for key in tracker.candidate_maker.shifted_instances.keys(): + assert lf.frame_idx - key[0] <= track_window # Keys are pruned + assert abs(key[0] - key[1]) <= track_window # References within window + + +@pytest.mark.parametrize( + "max_tracks, trackername", + [ + (2, "flowmaxtracks"), + (2, "simplemaxtracks"), + ], +) +def test_max_tracks_matching_queue( + centered_pair_predictions: Labels, max_tracks, trackername +): + """Test flow max tracks instance generation.""" + labels: Labels = centered_pair_predictions + max_tracking = True + track_window = 5 + + # Setup flow max tracker + tracker: Tracker = Tracker.make_tracker_by_name( + tracker=trackername, + track_window=track_window, + save_shifted_instances=True, + max_tracking=max_tracking, + max_tracks=max_tracks, + ) + + tracker.candidate_maker = cast(FlowMaxTracksCandidateMaker, tracker.candidate_maker) + + # Run tracking + frames = sorted(labels.labeled_frames, key=lambda lf: lf.frame_idx) + + for lf in frames[:20]: + # Clear the tracks + for inst in lf.instances: + inst.track = None + + track_args = dict( + untracked_instances=lf.instances, + img=lf.video[lf.frame_idx], + img_hw=lf.image.shape[-3:-1], + ) + tracker.track(**track_args) + + if trackername == "flowmaxtracks": + # Check that saved instances are pruned to track window + for key in tracker.candidate_maker.shifted_instances.keys(): + assert lf.frame_idx - key[0] <= track_window # Keys are pruned + assert abs(key[0] - key[1]) <= track_window + + # Check if the length of each of the tracks is not more than the track window + for track in tracker.track_matching_queue_dict.keys(): + assert len(tracker.track_matching_queue_dict[track]) <= track_window + + # Check if number of tracks that are generated are not more than the maximum tracks + assert len(tracker.track_matching_queue_dict) <= max_tracks + + +def test_movenet_inference(movenet_video): + inference_layer = MoveNetInferenceLayer(model_name="lightning") + inference_model = MoveNetInferenceModel(inference_layer) + + p = sleap.pipelines.Pipeline( + sleap.pipelines.VideoReader(video=movenet_video, example_indices=[0]) + ) + p += sleap.pipelines.SizeMatcher( + points_key=None, + max_image_width=inference_model.image_size, + max_image_height=inference_model.image_size, + center_pad=True, + ) + p += sleap.pipelines.Batcher(batch_size=4) + + ex = p.peek(1) + preds = inference_model.predict_on_batch(ex) + assert preds["instance_peaks"].shape == (1, 1, 17, 2) + + +def test_movenet_predictor(min_dance_labels, movenet_video): + predictor = MoveNetPredictor.from_trained_models("thunder") + predictor.verbosity = "none" + assert predictor.is_grayscale == False + labels_pr = predictor.predict(min_dance_labels) + + vr = sleap.pipelines.VideoReader(video=movenet_video, example_indices=[0, 1, 2]) + labels_pr = predictor.predict(data=vr) + + assert len(labels_pr) == 3 + assert len(labels_pr[0].instances) == 1 + + points_gt = np.concatenate( + [min_dance_labels[0][0].numpy(), min_dance_labels[1][0].numpy()], axis=0 + ) + points_pr = np.concatenate( + [labels_pr[0][0].numpy(), labels_pr[1][0].numpy()], axis=0 + ) + + np.testing.assert_allclose(points_gt, points_pr, atol=0.75) + + +@pytest.mark.parametrize( + "loading_function", ["load_model", "Predictor.from_model_paths"] +) +@pytest.mark.parametrize("movenet_name", ["thunder", "lightning"]) +def test_movenet_load_model(loading_function, movenet_name): + model_path = f"movenet-{movenet_name}" + model_name = model_path.split("-")[-1] + assert model_name == movenet_name + + if loading_function == "load_model": + predictor = load_model(model_path) + else: + predictor = Predictor.from_model_paths(model_path) + assert predictor.model_paths == MOVENET_MODELS[model_name]["model_path"] + assert isinstance(predictor, MoveNetPredictor) + assert predictor.model_name == model_name + + +def test_top_down_model(min_tracks_2node_labels: Labels, min_centroid_model_path: str): + labels = min_tracks_2node_labels + video = sleap.load_video(labels.videos[0].backend.filename) + predictor = sleap.load_model(min_centroid_model_path, batch_size=16) + + # Preload images + imgs = video[:3] + + # Raise better error message + with pytest.raises(ValueError): + predictor.predict(imgs[:1]) + + # Runs without error message + predictor.predict(labels.extract(inds=[0, 1])) diff --git a/tests/nn/test_inference_identity.py b/tests/nn/test_inference_identity.py index 22be152ea..aaacfef61 100644 --- a/tests/nn/test_inference_identity.py +++ b/tests/nn/test_inference_identity.py @@ -9,7 +9,7 @@ ) -sleap.use_cpu_only() +# sleap.use_cpu_only() def test_group_class_peaks(): diff --git a/tests/nn/test_model.py b/tests/nn/test_model.py index 329e5528f..6c60cb354 100644 --- a/tests/nn/test_model.py +++ b/tests/nn/test_model.py @@ -15,7 +15,7 @@ ModelConfig, ) -sleap.use_cpu_only() +# sleap.use_cpu_only() def test_model_from_config(): diff --git a/tests/nn/test_nn_utils.py b/tests/nn/test_nn_utils.py index 8644f6cbe..4e8703c05 100644 --- a/tests/nn/test_nn_utils.py +++ b/tests/nn/test_nn_utils.py @@ -1,10 +1,12 @@ import sleap import tensorflow as tf import numpy as np +import pytest from numpy.testing import assert_array_equal, assert_allclose -from sleap.nn.utils import tf_linear_sum_assignment, match_points +from sleap.nn.inference import TopDownPredictor +from sleap.nn.utils import tf_linear_sum_assignment, match_points, reset_input_layer -sleap.use_cpu_only() +# sleap.use_cpu_only() def test_tf_linear_sum_assignment(): @@ -20,3 +22,27 @@ def test_match_points(): assert_array_equal(inds1, [0, 1]) assert_array_equal(inds2, [1, 0]) + + +def test_reset_input_layer(min_centroid_model_path): + """Verify that input layer size is reset.""" + + predictor = TopDownPredictor.from_trained_models( + centroid_model_path=min_centroid_model_path, resize_input_layer=False + ) + og_keras_model: tf.keras.Model = predictor.centroid_model.keras_model + og_weights = [layer.get_weights() for layer in og_keras_model.layers[1:]] + assert og_keras_model.input_shape == (None, 384, 384, 1) + + keras_model = reset_input_layer(keras_model=og_keras_model) + new_weights = [layer.get_weights() for layer in keras_model.layers[1:]] + assert keras_model.input_shape == (None, None, None, 1) + assert len(keras_model.layers) == len(og_keras_model.layers) + for og_weight, new_weight in zip(og_weights, new_weights): + for ogw, nw in zip(og_weight, new_weight): + assert ogw.shape == nw.shape + np.testing.assert_array_equal(ogw.flatten(), nw.flatten()) + + new_shape = (None, 384, 384, 1) + keras_model = reset_input_layer(keras_model=keras_model, new_shape=new_shape) + assert keras_model.input_shape == new_shape diff --git a/tests/nn/test_paf_grouping.py b/tests/nn/test_paf_grouping.py index 4856c1fed..d9578bfa9 100644 --- a/tests/nn/test_paf_grouping.py +++ b/tests/nn/test_paf_grouping.py @@ -22,7 +22,7 @@ assign_connections_to_instances, ) -sleap.nn.system.use_cpu_only() +# sleap.nn.system.use_cpu_only() def test_get_connection_candidates(): diff --git a/tests/nn/test_peak_finding.py b/tests/nn/test_peak_finding.py index 93beaa193..243653202 100644 --- a/tests/nn/test_peak_finding.py +++ b/tests/nn/test_peak_finding.py @@ -22,7 +22,7 @@ ) -sleap.nn.system.use_cpu_only() +# sleap.nn.system.use_cpu_only() def test_find_local_offsets(): diff --git a/tests/nn/test_system.py b/tests/nn/test_system.py new file mode 100644 index 000000000..7b16f1219 --- /dev/null +++ b/tests/nn/test_system.py @@ -0,0 +1,115 @@ +"""Tests for sleap.nn.system module. + +Note: Most of this module cannot be tested effectively in CI since it expects GPUs to +be available. +""" + +from sleap.nn.system import ( + get_gpu_memory, + get_all_gpus, + use_cpu_only, + use_gpu, + is_gpu_system, +) +import os +import pytest +import subprocess +import tensorflow as tf +import shutil +import platform + + +def test_get_gpu_memory(): + # Make sure this doesn't throw an exception + memory = get_gpu_memory() + + +@pytest.mark.parametrize("cuda_visible_devices", ["0", "1", "0,1"]) +def test_get_gpu_memory_visible(cuda_visible_devices): + if shutil.which("nvidia-smi") is None: + pytest.skip("nvidia-smi not available.") + + # Get GPU indices from nvidia-smi + command = ["nvidia-smi", "--query-gpu=index", "--format=csv,noheader"] + nvidia_indices = ( + subprocess.check_output(command).decode("utf-8").strip().split("\n") + ) + + # Set parameterized CUDA visible devices + os.environ["CUDA_VISIBLE_DEVICES"] = cuda_visible_devices + + gpu_memory = get_gpu_memory() + + if nvidia_indices == "0" or nvidia_indices == "1": + assert len(gpu_memory) > 0 + assert len(gpu_memory) == 1 + + elif nvidia_indices == "0,1": + assert len(gpu_memory) > 0 + assert len(gpu_memory) == 2 + + +def test_get_gpu_memory_no_nvidia_smi(): + # Backup current PATH + old_path = os.environ["PATH"] + + # Set PATH to an empty string to simulate that nvidia-smi is not available + os.environ["PATH"] = "" + + memory = get_gpu_memory() + + # Restore the original PATH + os.environ["PATH"] = old_path + + assert memory == [] + + +@pytest.mark.parametrize("cuda_visible_devices", ["invalid", "3,5", "-1"]) +def test_get_gpu_memory_invalid_cuda_visible_devices(cuda_visible_devices): + for value in cuda_visible_devices: + os.environ["CUDA_VISIBLE_DEVICES"] = value + + memory = get_gpu_memory() + + # Cleanup CUDA_VISIBLE_DEVICES variable after the test + os.environ.pop("CUDA_VISIBLE_DEVICES", None) + + assert len(memory) == 0 + + +def test_gpu_order_and_length(): + if shutil.which("nvidia-smi") is None: + pytest.skip("nvidia-smi not available.") + + # Get GPU indices from sleap.nn.system.get_all_gpus + sleap_indices = [int(gpu.name.split(":")[-1]) for gpu in get_all_gpus()] + + # Get GPU indices from nvidia-smi + command = ["nvidia-smi", "--query-gpu=index", "--format=csv,noheader"] + nvidia_indices = ( + subprocess.check_output(command).decode("utf-8").strip().split("\n") + ) + nvidia_indices = [int(idx) for idx in nvidia_indices] + + # Assert that the order and length of GPU indices match + assert sleap_indices == nvidia_indices + + +def test_gpu_device_order(): + """Indirectly tests GPU device order by ensuring environment variable is set.""" + + assert os.environ["CUDA_DEVICE_ORDER"] == "PCI_BUS_ID" + + +@pytest.mark.skipif( + not ("arm64" in platform.platform()), + reason="Only test on macosx-arm64", +) +def test_reinitialize(): + """This test tries to change the devices after they have been initialized.""" + assert is_gpu_system() + use_gpu(0) + tf.zeros((1,)) + tf.ones((1,)) + # The following would normally throw: + # RuntimeError: Visible devices cannot be modified after being initialized + use_cpu_only() diff --git a/tests/nn/test_tracker_components.py b/tests/nn/test_tracker_components.py index 869ebc85c..0c7ba2b0a 100644 --- a/tests/nn/test_tracker_components.py +++ b/tests/nn/test_tracker_components.py @@ -9,21 +9,82 @@ FrameMatches, greedy_matching, ) +from sleap.io.dataset import Labels from sleap.instance import PredictedInstance from sleap.skeleton import Skeleton -@pytest.mark.parametrize("tracker", ["simple", "flow"]) -@pytest.mark.parametrize("similarity", ["instance", "iou", "centroid"]) +def tracker_by_name(frames=None, **kwargs): + t = Tracker.make_tracker_by_name(**kwargs) + print(kwargs) + print(t.candidate_maker) + if frames is None: + t.track([]) + t.final_pass([]) + return + + for lf in frames: + # Clear the tracks + for inst in lf.instances: + inst.track = None + + track_args = dict(untracked_instances=lf.instances, img=lf.video[lf.frame_idx]) + t.track(**track_args, img_hw=(1, 1)) + t.final_pass(frames) + + +@pytest.mark.parametrize( + "tracker", ["simple", "flow", "simplemaxtracks", "flowmaxtracks"] +) +@pytest.mark.parametrize( + "similarity", + ["instance", "normalized_instance", "iou", "centroid", "object_keypoint"], +) @pytest.mark.parametrize("match", ["greedy", "hungarian"]) @pytest.mark.parametrize("count", [0, 2]) -def test_tracker_by_name(tracker, similarity, match, count): - t = Tracker.make_tracker_by_name( - "flow", "instance", "greedy", clean_instance_count=2 +def test_tracker_by_name( + centered_pair_predictions_sorted, + tracker, + similarity, + match, + count, +): + # This is slow, so limit to 5 time points + frames = centered_pair_predictions_sorted[:5] + + tracker_by_name( + frames=frames, + tracker=tracker, + similarity=similarity, + match=match, + max_tracks=count, + ) + + +@pytest.mark.parametrize( + "tracker", ["simple", "flow", "simplemaxtracks", "flowmaxtracks"] +) +@pytest.mark.parametrize("oks_score_weighting", ["True", "False"]) +@pytest.mark.parametrize("oks_normalization", ["all", "ref", "union"]) +def test_oks_tracker_by_name( + centered_pair_predictions_sorted, + tracker, + oks_score_weighting, + oks_normalization, +): + # This is slow, so limit to 5 time points + frames = centered_pair_predictions_sorted[:5] + + tracker_by_name( + frames=frames, + tracker=tracker, + similarity="object_keypoint", + matching="greedy", + oks_score_weighting=oks_score_weighting, + oks_normalization=oks_normalization, + max_tracks=2, ) - t.track([]) - t.final_pass([]) def test_cull_instances(centered_pair_predictions): @@ -166,3 +227,222 @@ def test_frame_match_object(): assert matches[1].track == "track b" assert matches[1].instance == "instance b" + + +def make_insts(trx): + skel = Skeleton.from_names_and_edge_inds( + ["A", "B", "C"], edge_inds=[[0, 1], [1, 2]] + ) + + def make_inst(x, y): + pts = np.array([[-0.1, -0.1], [0.0, 0.0], [0.1, 0.1]]) + np.array([[x, y]]) + return PredictedInstance.from_numpy(pts, [1, 1, 1], 1, skel) + + insts = [] + for frame in trx: + insts_frame = [] + for x, y in frame: + insts_frame.append(make_inst(x, y)) + insts.append(insts_frame) + return insts + + +def test_max_tracking_large_gap_single_track(): + # Track 2 instances with gap > window size + preds = make_insts( + [ + [ + (0, 0), + (0, 1), + ], + [ + (0.1, 0), + (0.1, 1), + ], + [ + (0.2, 0), + (0.2, 1), + ], + [ + (0.3, 0), + ], + [ + (0.4, 0), + ], + [ + (0.5, 0), + (0.5, 1), + ], + [ + (0.6, 0), + (0.6, 1), + ], + ] + ) + + tracker = Tracker.make_tracker_by_name( + tracker="simple", + # tracker="simplemaxtracks", + match="hungarian", + track_window=2, + # max_tracks=2, + # max_tracking=True, + ) + + tracked = [] + for insts in preds: + tracked_insts = tracker.track(insts, img_hw=(1, 1)) + tracked.append(tracked_insts) + all_tracks = list(set([inst.track for frame in tracked for inst in frame])) + + assert len(all_tracks) == 3 + + tracker = Tracker.make_tracker_by_name( + # tracker="simple", + tracker="simplemaxtracks", + match="hungarian", + track_window=2, + max_tracks=2, + max_tracking=True, + ) + + tracked = [] + for insts in preds: + tracked_insts = tracker.track(insts, img_hw=(1, 1)) + tracked.append(tracked_insts) + all_tracks = list(set([inst.track for frame in tracked for inst in frame])) + + assert len(all_tracks) == 2 + + +def test_max_tracking_small_gap_on_both_tracks(): + # Test 2 instances with both tracks with gap > window size + preds = make_insts( + [ + [ + (0, 0), + (0, 1), + ], + [ + (0.1, 0), + (0.1, 1), + ], + [ + (0.2, 0), + (0.2, 1), + ], + [], + [], + [ + (0.5, 0), + (0.5, 1), + ], + [ + (0.6, 0), + (0.6, 1), + ], + ] + ) + + tracker = Tracker.make_tracker_by_name( + tracker="simple", + # tracker="simplemaxtracks", + match="hungarian", + track_window=2, + # max_tracks=2, + # max_tracking=True, + ) + + tracked = [] + for insts in preds: + tracked_insts = tracker.track(insts, img_hw=(1, 1)) + tracked.append(tracked_insts) + all_tracks = list(set([inst.track for frame in tracked for inst in frame])) + + assert len(all_tracks) == 4 + + tracker = Tracker.make_tracker_by_name( + # tracker="simple", + tracker="simplemaxtracks", + match="hungarian", + track_window=2, + max_tracks=2, + max_tracking=True, + ) + + tracked = [] + for insts in preds: + tracked_insts = tracker.track(insts, img_hw=(1, 1)) + tracked.append(tracked_insts) + all_tracks = list(set([inst.track for frame in tracked for inst in frame])) + + assert len(all_tracks) == 2 + + +def test_max_tracking_extra_detections(): + # Test having more than 2 detected instances in a frame + preds = make_insts( + [ + [ + (0, 0), + (0, 1), + ], + [ + (0.1, 0), + (0.1, 1), + ], + [ + (0.2, 0), + (0.2, 1), + ], + [ + (0.3, 0), + ], + [ + (0.4, 0), + ], + [ + (0.5, 0), + (0.5, 1), + ], + [ + (0.6, 0), + (0.6, 1), + (0.6, 0.5), + ], + ] + ) + + tracker = Tracker.make_tracker_by_name( + tracker="simple", + # tracker="simplemaxtracks", + match="hungarian", + track_window=2, + # max_tracks=2, + # max_tracking=True, + ) + + tracked = [] + for insts in preds: + tracked_insts = tracker.track(insts, img_hw=(1, 1)) + tracked.append(tracked_insts) + all_tracks = list(set([inst.track for frame in tracked for inst in frame])) + + assert len(all_tracks) == 4 + + tracker = Tracker.make_tracker_by_name( + # tracker="simple", + tracker="simplemaxtracks", + match="hungarian", + track_window=2, + max_tracks=2, + max_tracking=True, + ) + + tracked = [] + for insts in preds: + tracked_insts = tracker.track(insts, img_hw=(1, 1)) + tracked.append(tracked_insts) + all_tracks = list(set([inst.track for frame in tracked for inst in frame])) + + assert len(all_tracks) == 2 diff --git a/tests/nn/test_tracking_integration.py b/tests/nn/test_tracking_integration.py index 829b7c3cb..625302fd0 100644 --- a/tests/nn/test_tracking_integration.py +++ b/tests/nn/test_tracking_integration.py @@ -3,10 +3,42 @@ import os import time +import sleap +from sleap.nn.inference import main as inference_cli import sleap.nn.tracker.components from sleap.io.dataset import Labels, LabeledFrame +def test_simple_tracker(tmpdir, centered_pair_predictions_slp_path): + cli = ( + "--tracking.tracker simple " + "--frames 200-300 " + f"-o {tmpdir}/simpletracks.slp " + f"{centered_pair_predictions_slp_path}" + ) + inference_cli(cli.split(" ")) + + labels = sleap.load_file(f"{tmpdir}/simpletracks.slp") + assert len(labels.tracks) == 27 + + +def test_simplemax_tracker(tmpdir, centered_pair_predictions_slp_path): + cli = ( + "--tracking.tracker simplemaxtracks " + "--tracking.max_tracking 1 --tracking.max_tracks 2 " + "--frames 200-300 " + f"-o {tmpdir}/simplemaxtracks.slp " + f"{centered_pair_predictions_slp_path}" + ) + inference_cli(cli.split(" ")) + + labels = sleap.load_file(f"{tmpdir}/simplemaxtracks.slp") + assert len(labels.tracks) == 2 + + +# TODO: Refactor the below things into a real test suite. + + def make_ground_truth(frames, tracker, gt_filename): t0 = time.time() new_labels = run_tracker(frames, tracker) @@ -70,7 +102,7 @@ def run_tracker(frames, tracker): new_lf = LabeledFrame( frame_idx=lf.frame_idx, video=lf.video, - instances=tracker.track(**track_args), + instances=tracker.track(**track_args, img_hw=lf.image.shape[-3:-1]), ) new_lfs.append(new_lf) @@ -95,6 +127,8 @@ def main(f, dir): trackers = dict( simple=sleap.nn.tracker.simple.SimpleTracker, flow=sleap.nn.tracker.flow.FlowTracker, + simplemaxtracks=sleap.nn.tracker.SimpleMaxTracker, + flowmaxtracks=sleap.nn.tracker.FlowMaxTracker, ) matchers = dict( hungarian=sleap.nn.tracker.components.hungarian_matching, @@ -104,17 +138,29 @@ def main(f, dir): instance=sleap.nn.tracker.components.instance_similarity, centroid=sleap.nn.tracker.components.centroid_distance, iou=sleap.nn.tracker.components.instance_iou, + normalized_instance=sleap.nn.tracker.components.normalized_instance_similarity, + object_keypoint=sleap.nn.tracker.components.factory_object_keypoint_similarity(), ) scales = ( 1, 0.25, ) - def make_tracker(tracker_name, matcher_name, sim_name, scale=0): - tracker = trackers[tracker_name]( - matching_function=matchers[matcher_name], - similarity_function=similarities[sim_name], - ) + def make_tracker( + tracker_name, matcher_name, sim_name, max_tracks, max_tracking=False, scale=0 + ): + if tracker_name == "simplemaxtracks" or tracker_name == "flowmaxtracks": + tracker = trackers[tracker_name]( + matching_function=matchers[matcher_name], + similarity_function=similarities[sim_name], + max_tracks=max_tracks, + max_tracking=max_tracking, + ) + else: + tracker = trackers[tracker_name]( + matching_function=matchers[matcher_name], + similarity_function=similarities[sim_name], + ) if scale: tracker.candidate_maker.img_scale = scale return tracker @@ -145,6 +191,28 @@ def make_tracker_and_filename(*args, **kwargs): scale=scale, ) f(frames, tracker, gt_filename) + elif tracker_name == "flowmaxtracks": + # If this tracker supports scale, try multiple scales + for scale in scales: + tracker, gt_filename = make_tracker_and_filename( + tracker_name=tracker_name, + matcher_name=matcher_name, + sim_name=sim_name, + max_tracks=2, + max_tracking=True, + scale=scale, + ) + f(frames, tracker, gt_filename) + elif tracker_name == "simplemaxtracks": + tracker, gt_filename = make_tracker_and_filename( + tracker_name=tracker_name, + matcher_name=matcher_name, + sim_name=sim_name, + max_tracks=2, + max_tracking=True, + scale=0, + ) + f(frames, tracker, gt_filename) else: tracker, gt_filename = make_tracker_and_filename( tracker_name=tracker_name, diff --git a/tests/nn/test_training.py b/tests/nn/test_training.py index 4b923c811..72db17bb5 100644 --- a/tests/nn/test_training.py +++ b/tests/nn/test_training.py @@ -1,4 +1,7 @@ +from pathlib import Path + import pytest + import sleap from sleap.io.dataset import Labels from sleap.nn.config.data import LabelsConfig @@ -19,9 +22,10 @@ TopdownConfmapsModelTrainer, TopDownMultiClassModelTrainer, Trainer, + create_trainer_using_cli as sleap_train, ) -sleap.use_cpu_only() +# sleap.use_cpu_only() @pytest.fixture @@ -40,7 +44,7 @@ def cfg(): cfg = TrainingJobConfig() cfg.data.instance_cropping.center_on_part = "A" cfg.model.backbone.unet = UNetConfig( - max_stride=8, output_stride=1, filters=8, filters_rate=1.0 + max_stride=8, output_stride=1, filters=2, filters_rate=1.0 ) cfg.optimization.preload_data = False cfg.optimization.batch_size = 1 @@ -63,8 +67,28 @@ def test_data_reader(min_labels_slp_path): ex = next(iter(data_readers.validation_labels_reader.make_dataset())) assert ex["image"].shape == (384, 384, 1) + # Test DataReaders using split_by_inds + data_readers = DataReaders.from_config( + labels_config=LabelsConfig( + split_by_inds=True, validation_inds=[0], test_inds=[0], training_inds=[0] + ), + training=min_labels_slp_path, + validation=None, + ) + assert data_readers.training_labels_reader.example_indices == [0] + assert data_readers.validation_labels_reader.example_indices == [0] + assert data_readers.test_labels_reader.example_indices == [0] + + +def test_train_load_single_instance( + min_labels_robot: Labels, cfg: TrainingJobConfig, tmp_path: str +): + # set save directory + cfg.outputs.run_name = "test_run" + cfg.outputs.runs_folder = str(tmp_path / "training_runs") # ensure it's a string + cfg.outputs.save_outputs = True # enable saving + cfg.outputs.checkpointing.latest_model = True # save latest model -def test_train_single_instance(min_labels_robot, cfg): cfg.model.heads.single_instance = SingleInstanceConfmapsHeadConfig( sigma=1.5, output_stride=1, offset_refinement=False ) @@ -73,25 +97,87 @@ def test_train_single_instance(min_labels_robot, cfg): ) trainer.setup() trainer.train() + + # now load a new model and resume the checkpoint + # set the model checkpoint folder + cfg.model.base_checkpoint = cfg.outputs.run_path + # unset save directory + cfg.outputs.run_name = None + cfg.outputs.runs_folder = None + cfg.outputs.save_outputs = False # disable saving + cfg.outputs.checkpointing.latest_model = False # disable saving latest model + + trainer2 = SingleInstanceModelTrainer.from_config( + cfg, training_labels=min_labels_robot + ) + trainer2.setup() + + # check the weights are the same + for layer, layer2 in zip(trainer.keras_model.layers, trainer2.keras_model.layers): + # grabbing the weights from the first model + weights = layer.get_weights() + # grabbing the weights from the second model + weights2 = layer2.get_weights() + # check the weights are the same + for w, w2 in zip(weights, weights2): + assert (w == w2).all() + + +def test_train_single_instance(min_labels_robot, cfg, tmp_path): + cfg.model.heads.single_instance = SingleInstanceConfmapsHeadConfig( + sigma=1.5, output_stride=1, offset_refinement=False + ) + + # Set save directory + cfg.outputs.run_name = "test_run" + cfg.outputs.runs_folder = str(tmp_path / "training_runs") # ensure it's a string + cfg.outputs.save_visualizations = True + cfg.outputs.keep_viz_images = True + cfg.outputs.save_outputs = True # enable saving + + trainer = SingleInstanceModelTrainer.from_config( + cfg, training_labels=min_labels_robot + ) + trainer.setup() + trainer.train() + + run_path = Path(cfg.outputs.runs_folder, cfg.outputs.run_name) + viz_path = run_path / "viz" + assert trainer.keras_model.output_names[0] == "SingleInstanceConfmapsHead" assert tuple(trainer.keras_model.outputs[0].shape) == (None, 320, 560, 2) + assert viz_path.exists() -def test_train_single_instance_with_offset(min_labels_robot, cfg): +def test_train_single_instance_with_offset(min_labels_robot, cfg, tmp_path): cfg.model.heads.single_instance = SingleInstanceConfmapsHeadConfig( sigma=1.5, output_stride=1, offset_refinement=True ) + + # Set save directory + cfg.outputs.run_name = "test_run" + cfg.outputs.runs_folder = str(tmp_path / "training_runs") # ensure it's a string + cfg.outputs.save_visualizations = False + cfg.outputs.keep_viz_images = False + cfg.outputs.save_outputs = True # enable saving + trainer = SingleInstanceModelTrainer.from_config( cfg, training_labels=min_labels_robot ) trainer.setup() trainer.train() + + run_path = Path(cfg.outputs.runs_folder, cfg.outputs.run_name) + viz_path = run_path / "viz" + assert trainer.keras_model.output_names[0] == "SingleInstanceConfmapsHead" assert tuple(trainer.keras_model.outputs[0].shape) == (None, 320, 560, 2) assert trainer.keras_model.output_names[1] == "OffsetRefinementHead" assert tuple(trainer.keras_model.outputs[1].shape) == (None, 320, 560, 4) + assert not viz_path.exists() + def test_train_centroids(training_labels, cfg): cfg.model.heads.centroid = CentroidsHeadConfig( @@ -192,12 +278,12 @@ def test_train_bottomup_with_offset(training_labels, cfg): def test_train_bottomup_multiclass(min_tracks_2node_labels, cfg): labels = min_tracks_2node_labels - cfg.data.preprocessing.input_scaling = 0.5 + cfg.data.preprocessing.input_scaling = 0.25 cfg.model.heads.multi_class_bottomup = sleap.nn.config.MultiClassBottomUpConfig( confmaps=sleap.nn.config.MultiInstanceConfmapsHeadConfig( - output_stride=2, offset_refinement=False + output_stride=4, offset_refinement=False ), - class_maps=sleap.nn.config.ClassMapsHeadConfig(output_stride=2), + class_maps=sleap.nn.config.ClassMapsHeadConfig(output_stride=4), ) trainer = sleap.nn.training.BottomUpMultiClassModelTrainer.from_config( cfg, training_labels=labels @@ -207,8 +293,8 @@ def test_train_bottomup_multiclass(min_tracks_2node_labels, cfg): assert trainer.keras_model.output_names[0] == "MultiInstanceConfmapsHead" assert trainer.keras_model.output_names[1] == "ClassMapsHead" - assert tuple(trainer.keras_model.outputs[0].shape) == (None, 256, 256, 2) - assert tuple(trainer.keras_model.outputs[1].shape) == (None, 256, 256, 2) + assert tuple(trainer.keras_model.outputs[0].shape) == (None, 64, 64, 2) + assert tuple(trainer.keras_model.outputs[1].shape) == (None, 64, 64, 2) def test_train_topdown_multiclass(min_tracks_2node_labels, cfg): @@ -255,3 +341,72 @@ def test_train_cropping( trainer.config.data.instance_cropping.crop_size % trainer.model.maximum_stride == 0 ) + + +@pytest.mark.parametrize("base_checkpoint_path", [None, ""]) +def test_resume_training_cli( + base_checkpoint_path, + min_single_instance_robot_model_path: str, + small_robot_mp4_path: str, + tmp_path: str, +): + """Test CLI to resume training.""" + cfg_dir = min_single_instance_robot_model_path + base_checkpoint_path = ( + min_single_instance_robot_model_path + if base_checkpoint_path is not None + else base_checkpoint_path + ) + + cfg = TrainingJobConfig.load_json(str(Path(cfg_dir, "training_config.json"))) + cfg.optimization.preload_data = False + cfg.optimization.batch_size = 1 + cfg.optimization.batches_per_epoch = 2 + cfg.optimization.epochs = 1 + cfg.outputs.save_outputs = False + cfg.model.base_checkpoint = base_checkpoint_path + + # Save training config to tmp folder + cfg_path = str(Path(tmp_path, "training_config.json")) + cfg.save_json(cfg_path) + + # We need to do this reload because we save absolute paths (for the video). + labels_path = str(Path(cfg_dir, "labels_gt.train.slp")) + labels: Labels = sleap.load_file(labels_path, search_paths=[small_robot_mp4_path]) + labels_path = str(Path(tmp_path, "labels_gt.train.slp")) + labels.save_file(labels, labels_path) + + # Check that base_checkpoint is set correctly (not overridden by CLI) + cli_args = [cfg_path, labels_path] + trainer = sleap_train(cli_args) + assert trainer.config.model.base_checkpoint == base_checkpoint_path + + # Check that base_checkpoint is set correctly (overridden by CLI) + if base_checkpoint_path is not None: + cli_args = [cfg_path, labels_path, "--base_checkpoint", base_checkpoint_path] + + trainer = sleap_train(cli_args) + assert trainer.config.model.base_checkpoint == base_checkpoint_path + + +@pytest.mark.parametrize("keep_viz_cli", ["", "--keep_viz"]) +def test_keep_viz_cli( + keep_viz_cli, + min_single_instance_robot_model_path: str, + tmp_path: str, +): + """Test training CLI for --keep_viz option.""" + cfg_dir = min_single_instance_robot_model_path + cfg = TrainingJobConfig.load_json(str(Path(cfg_dir, "training_config.json"))) + + # Save training config to tmp folder + cfg_path = str(Path(tmp_path, "training_config.json")) + cfg.save_json(cfg_path) + + cli_args = [cfg_path, keep_viz_cli] + trainer = sleap_train(cli_args) + + # Check that --keep_viz is set correctly + assert trainer.config.outputs.keep_viz_images == ( + True if keep_viz_cli == "--keep_viz" else False + ) diff --git a/tests/nn/test_viz.py b/tests/nn/test_viz.py new file mode 100644 index 000000000..f611cae9b --- /dev/null +++ b/tests/nn/test_viz.py @@ -0,0 +1,30 @@ +"""Module to test all functions in sleap.nn.viz module.""" + +import sleap +from sleap.instance import LabeledFrame, Track +from sleap.io.dataset import Labels +from sleap.nn.viz import generate_skeleton_preview_image + + +def test_generate_skeleton_preview_image( + centered_pair_predictions_slp_path: str, + centered_pair_vid_path: str, +): + """Encode preview images for all skeletons in sleap.skeletons directory.""" + + video_file = centered_pair_vid_path + labels: Labels = sleap.load_file( + centered_pair_predictions_slp_path, search_paths=[video_file] + ) + lf: LabeledFrame = labels.labeled_frames[0] + track: Track = labels.tracks[0] + + if track is None: + inst = lf.instances[0] + else: + inst = next( + instance for instance in lf.instances if instance.track.matches(track) + ) + + img_b64: bytes = generate_skeleton_preview_image(inst) + assert isinstance(img_b64, bytes) diff --git a/tests/test_instance.py b/tests/test_instance.py index 74a8b192e..58a630a8b 100644 --- a/tests/test_instance.py +++ b/tests/test_instance.py @@ -1,19 +1,21 @@ -import os -import math import copy +import math +import os +from typing import List -import pytest import numpy as np +import pytest -from sleap.skeleton import Skeleton +from sleap import Labels from sleap.instance import ( Instance, - PredictedInstance, + InstancesList, + LabeledFrame, Point, + PredictedInstance, PredictedPoint, - LabeledFrame, ) -from sleap import Labels +from sleap.skeleton import Skeleton def test_instance_node_get_set_item(skeleton): @@ -310,6 +312,8 @@ def test_frame_merge_predicted_and_user(skeleton, centered_pair_vid): # and we want to retain both even though they perfectly match. assert user_inst in user_frame.instances assert pred_inst in user_frame.instances + assert user_inst.frame == user_frame + assert pred_inst.frame == user_frame assert len(user_frame.instances) == 2 @@ -529,3 +533,216 @@ def test_instance_structuring_from_predicted(centered_pair_predictions): # Unstructure -> structure labels_copy = labels.copy() + + +def test_instances_list(centered_pair_predictions): + + labels = centered_pair_predictions + + def test_extend(instances: InstancesList, list_of_instances: List[Instance]): + instances.extend(list_of_instances) + assert len(instances) == len(list_of_instances) + for instance in instances: + assert isinstance(instance, PredictedInstance) + if instances.labeled_frame is None: + assert instance.frame is None + else: + assert instance.frame == instances.labeled_frame + + def test_append(instances: InstancesList, instance: Instance): + prev_len = len(instances) + instances.append(instance) + assert len(instances) == prev_len + 1 + assert instances[-1] == instance + assert instance.frame == instances.labeled_frame + + def test_labeled_frame_setter( + instances: InstancesList, labeled_frame: LabeledFrame + ): + instances.labeled_frame = labeled_frame + for instance in instances: + assert instance.frame == labeled_frame + + # Case 1: Create an empty instances list + labeled_frame = labels.labeled_frames[0] + list_of_instances = list(labeled_frame.instances) + instances = InstancesList() + assert len(instances) == 0 + assert instances._labeled_frame is None + assert instances.labeled_frame is None + + # Extend instances list + assert not isinstance(list_of_instances, InstancesList) + assert isinstance(list_of_instances, list) + test_extend(instances, list_of_instances) + + # Set the labeled frame + test_labeled_frame_setter(instances, labeled_frame) + + # Case 2: Create an empy instances list but initialize the labeled frame + instances = InstancesList(labeled_frame=labeled_frame) + assert len(instances) == 0 + assert instances._labeled_frame == labeled_frame + assert instances.labeled_frame == labeled_frame + + # Extend instances to the list from a different labeled frame + labeled_frame = labels.labeled_frames[1] + list_of_instances = list(labeled_frame.instances) + test_extend(instances, list_of_instances) + + # Add instance to the list + instance = list_of_instances[0] + instance.frame = None + test_append(instances, instance) + + # Set the labeled frame + test_labeled_frame_setter(instances, labeled_frame) + + # Test InstancesList.copy + instances_copy = instances.copy() + assert len(instances_copy) == len(instances) + assert not isinstance(instances_copy, InstancesList) + assert isinstance(instances_copy, list) + + # Test InstancesList.clear + instances_in_instances = list(instances) + instances.clear() + assert len(instances) == 0 + for instance in instances_in_instances: + assert instance.frame is None + + # Case 3: Create an instances list with a list of instances + labeled_frame = labels.labeled_frames[0] + list_of_instances = list(labeled_frame.instances) + instances = InstancesList(list_of_instances) + assert len(instances) == len(list_of_instances) + assert instances._labeled_frame is None + assert instances.labeled_frame is None + for instance in instances: + assert instance.frame is None + + # Add instance to the list + instance = list_of_instances[0] + test_append(instances, instance) + + # Case 4: Create an instances list with a list of instances and initialize the frame + labeled_frame_1 = labels.labeled_frames[0] + labeled_frame_2 = labels.labeled_frames[1] + list_of_instances = list(labeled_frame_2.instances) + instances = InstancesList(list_of_instances, labeled_frame=labeled_frame_1) + assert len(instances) == len(list_of_instances) + assert instances._labeled_frame == labeled_frame + assert instances.labeled_frame == labeled_frame + for instance in instances: + assert instance.frame == labeled_frame + + # Test InstancesList.__delitem__ + instance_to_remove = instances[0] + del instances[0] + assert instance_to_remove not in instances + assert instance_to_remove.frame is None + + # Test InstancesList.insert + instances.insert(0, instance_to_remove) + assert instances[0] == instance_to_remove + assert instance_to_remove.frame == instances.labeled_frame + + # Test InstancesList.__setitem__ + new_instance = labeled_frame_1.instances[0] + new_instance.frame = None + instances[0] = new_instance + assert instances[0] == new_instance + assert new_instance.frame == instances.labeled_frame + + # Test InstancesList.pop + popped_instance = instances.pop(0) + assert popped_instance.frame is None + + # Test InstancesList.remove + instance_to_remove = instances[0] + instances.remove(instance_to_remove) + assert instance_to_remove.frame is None + assert instance_to_remove not in instances + + # Case 5: Create an instances list from an instances list + instances_1 = InstancesList(list_of_instances, labeled_frame=labeled_frame_1) + instances = InstancesList(instances_1) + assert len(instances) == len(instances_1) + assert instances._labeled_frame is None + assert instances.labeled_frame is None + for instance in instances: + assert instance.frame is None + + +def test_instances_list_with_labeled_frame(centered_pair_predictions): + labels: Labels = centered_pair_predictions + labels_lf_0: LabeledFrame = labels.labeled_frames[0] + video = labels_lf_0.video + frame_idx = labels_lf_0.frame_idx + + def test_post_init(labeled_frame: LabeledFrame): + for instance in labeled_frame.instances: + assert instance.frame == labeled_frame + + # Create labeled frame from list of instances + instances = list(labels_lf_0.instances) + for instance in instances: + instance.frame = None # Change frame to None to test if it is set correctly + labeled_frame = LabeledFrame(video=video, frame_idx=frame_idx, instances=instances) + assert isinstance(labeled_frame.instances, InstancesList) + assert len(labeled_frame.instances) == len(instances) + test_post_init(labeled_frame) + + # Create labeled frame from instances list + instances = InstancesList(labels_lf_0.instances) + labeled_frame = LabeledFrame(video=video, frame_idx=frame_idx, instances=instances) + assert isinstance(labeled_frame.instances, InstancesList) + assert len(labeled_frame.instances) == len(instances) + test_post_init(labeled_frame) + + # Test LabeledFrame.__len__ + assert len(labeled_frame.instances) == len(instances) + + # Test LabeledFrame.__getitem__ + assert labeled_frame[0] == instances[0] + + # Test LabeledFrame.index + assert labeled_frame.index(instances[0]) == instances.index(instances[0]) == 0 + + # Test LabeledFrame.__delitem__ + instance_to_remove = labeled_frame[0] + del labeled_frame[0] + assert instance_to_remove not in labeled_frame.instances + assert instance_to_remove.frame is None + + # Test LabeledFrame.__repr__ + print(labeled_frame) + + # Test LabeledFrame.insert + labeled_frame.insert(0, instance_to_remove) + assert labeled_frame[0] == instance_to_remove + assert instance_to_remove.frame == labeled_frame + + # Test LabeledFrame.__setitem__ + new_instance = instances[1] + new_instance.frame = None + labeled_frame[0] = new_instance + assert labeled_frame[0] == new_instance + assert new_instance.frame == labeled_frame + + # Test instances.setter (empty list) + labeled_frame.instances = [] + assert len(labeled_frame.instances) == 0 + assert labeled_frame.instances.labeled_frame == labeled_frame + # Test instances.setter (InstancesList) + labeled_frame.instances = labels.labeled_frames[1].instances + assert len(labeled_frame.instances) == len(labels.labeled_frames[1].instances) + assert labeled_frame.instances.labeled_frame == labeled_frame + for instance in labeled_frame.instances: + assert instance.frame == labeled_frame + # Test instances.setter (populated list) + labeled_frame.instances = list(labels.labeled_frames[1].instances) + assert len(labeled_frame.instances) == len(labels.labeled_frames[1].instances) + assert labeled_frame.instances.labeled_frame == labeled_frame + for instance in labeled_frame.instances: + assert instance.frame == labeled_frame diff --git a/tests/test_message.py b/tests/test_message.py index 7351b6a89..c4b79ee6c 100644 --- a/tests/test_message.py +++ b/tests/test_message.py @@ -1,10 +1,9 @@ from sleap.message import PairedSender, PairedReceiver import time +from multiprocessing import Process def run_send(): - from time import sleep - sender = PairedSender.from_defaults() sender.setup() @@ -46,8 +45,6 @@ def run_receive(): def test_send_receive_pair(): - from multiprocessing import Process - # run "sender" in a separate process Process(target=run_send).start() diff --git a/tests/test_skeleton.py b/tests/test_skeleton.py index e35aa5bec..2320342f6 100644 --- a/tests/test_skeleton.py +++ b/tests/test_skeleton.py @@ -1,9 +1,74 @@ -import os import copy - +import os import pytest +import json + +from networkx.readwrite import json_graph +from sleap.skeleton import Skeleton, SkeletonDecoder +from sleap.skeleton import SkeletonEncoder + + +def test_decoded_encoded_Skeleton_from_load_json(fly_legs_skeleton_json): + """ + Test Skeleton decoded from SkeletonEncoder.encode matches the original Skeleton. + """ + # Get the skeleton from the fixture + skeleton = Skeleton.load_json(fly_legs_skeleton_json) + # Get the graph from the skeleton + indexed_node_graph = skeleton._graph + graph = json_graph.node_link_data(indexed_node_graph) + + # Encode the graph as a json string to test .encode method + encoded_json_str = SkeletonEncoder.encode(graph) -from sleap.skeleton import Skeleton + # Get the skeleton from the encoded json string + decoded_skeleton = Skeleton.from_json(encoded_json_str) + + # Check that the decoded skeleton is the same as the original skeleton + assert skeleton.matches(decoded_skeleton) + + +@pytest.mark.parametrize( + "skeleton_fixture_name", ["flies13_skeleton", "skeleton", "stickman"] +) +def test_decoded_encoded_Skeleton(skeleton_fixture_name, request): + """ + Test Skeleton decoded from SkeletonEncoder.encode matches the original Skeleton. + """ + # Use request.getfixturevalue to get the actual fixture value by name + skeleton = request.getfixturevalue(skeleton_fixture_name) + + # Get the graph from the skeleton + indexed_node_graph = skeleton._graph + graph = json_graph.node_link_data(indexed_node_graph) + + # Encode the graph as a json string to test .encode method + encoded_json_str = SkeletonEncoder.encode(graph) + + # Assert that the encoded json has keys in sorted order (backwards compatibility) + encoded_dict = json.loads(encoded_json_str) + sorted_keys = sorted(encoded_dict.keys()) + assert list(encoded_dict.keys()) == sorted_keys + for key, value in encoded_dict.items(): + if isinstance(value, dict): + assert list(value.keys()) == sorted(value.keys()) + elif isinstance(value, list): + for item in value: + if isinstance(item, dict): + assert list(item.keys()) == sorted(item.keys()) + + # Get the skeleton from the encoded json string + decoded_skeleton = Skeleton.from_json(encoded_json_str) + + # Check that the decoded skeleton is the same as the original skeleton + assert skeleton.matches(decoded_skeleton) + + # Now make everything into a JSON string + skeleton_json_str = skeleton.to_json() + decoded_skeleton_json_str = decoded_skeleton.to_json() + + # Check that the JSON strings are the same + assert json.loads(skeleton_json_str) == json.loads(decoded_skeleton_json_str) def test_add_dupe_node(skeleton): @@ -169,13 +234,50 @@ def test_symmetry(): with pytest.raises(ValueError): s1.delete_symmetry("1", "5") + s2 = Skeleton() + s2.add_nodes(["1", "2", "3"]) + s2.add_edge("1", "2") + s2.add_edge("2", "3") + s2.add_symmetry("1", "3") + assert s2.graph.number_of_edges() == 2 + assert s2.graph_symmetry.number_of_edges() == 2 + assert list(s2.graph_symmetry.edges()) == [ + (s2.nodes[0], s2.nodes[2]), + (s2.nodes[2], s2.nodes[0]), + ] -def test_json(skeleton, tmpdir): - """ - Test saving and loading a Skeleton object in JSON. - """ + +def test_json(skeleton: Skeleton, tmpdir): + """Test saving and loading a Skeleton object in JSON.""" JSON_TEST_FILENAME = os.path.join(tmpdir, "skeleton.json") + # Test that `to_json` does not save unused `None` fields (to ensure backwards data + # format compatibility) + skeleton.description = ( + "Test that description is not saved when given (if is_template is False)." + ) + assert skeleton.is_template == False + json_str = skeleton.to_json() + json_dict = SkeletonDecoder.decode(json_str) + json_dict_keys = list(json_dict.keys()) + assert "nx_graph" in json_dict_keys # SkeletonDecoder adds this key + assert "preview_image" not in json_dict_keys + assert "description" not in json_dict_keys + + # Test that `is_template` can only be set to True + # when has both `description` and `preview_image` + with pytest.raises(ValueError): + skeleton.is_template = True + assert skeleton.is_template == False + + skeleton._is_template = True + json_str = skeleton.to_json() + json_dict = SkeletonDecoder.decode(json_str) + json_dict_keys = list(json_dict.keys()) + assert "nx_graph" in json_dict_keys + assert "preview_image" in json_dict_keys + assert "description" in json_dict_keys + # Save it to a JSON filename skeleton.save_json(JSON_TEST_FILENAME) @@ -186,6 +288,26 @@ def test_json(skeleton, tmpdir): assert skeleton.matches(skeleton_copy) +def test_decode_preview_image(flies13_skeleton: Skeleton): + skeleton = flies13_skeleton + img_b64 = skeleton.preview_image + img = SkeletonDecoder.decode_preview_image(img_b64) + assert img.mode == "RGBA" + + +def test_skeleton_decoder(fly_legs_skeleton_json, fly_legs_skeleton_dict_json): + """Test that SkeletonDecoder can decode both tuple and dict py/state formats.""" + + skeleton_tuple_pystate = Skeleton.load_json(fly_legs_skeleton_json) + assert isinstance(skeleton_tuple_pystate, Skeleton) + + skeleton_dict_pystate = Skeleton.load_json(fly_legs_skeleton_dict_json) + assert isinstance(skeleton_dict_pystate, Skeleton) + + # These are the same skeleton, so they should match + assert skeleton_dict_pystate.matches(skeleton_tuple_pystate) + + def test_hdf5(skeleton, stickman, tmpdir): filename = os.path.join(tmpdir, "skeleton.h5") @@ -254,6 +376,9 @@ def dict_match(dict1, dict2): def test_graph_property(skeleton): assert [node for node in skeleton.graph.nodes()] == skeleton.nodes + no_edge_skel = Skeleton.from_names_and_edge_inds(["A", "B"]) + assert [node for node in no_edge_skel.graph.nodes()] == no_edge_skel.nodes + def test_load_mat_format(): skeleton = Skeleton.load_mat( @@ -396,3 +521,13 @@ def test_arborescence(): assert len(skeleton.cycles) == 0 assert len(skeleton.root_nodes) == 1 assert len(skeleton.in_degree_over_one) == 1 + + # symmetry edges should be ignored + skeleton = Skeleton() + skeleton.add_node("a") + skeleton.add_node("b") + skeleton.add_node("c") + skeleton.add_edge("a", "b") + skeleton.add_edge("b", "c") + skeleton.add_symmetry("a", "c") + assert skeleton.is_arborescence