From a3420fd7b722d1ff14ffe7c588ae2225a37f2763 Mon Sep 17 00:00:00 2001 From: Stephen Fleming <sjfleming@users.noreply.github.com> Date: Sun, 6 Aug 2023 01:12:39 -0400 Subject: [PATCH 01/19] Update to v0.3.0 (#237) * Checkpointing, more input formats, HTML report, test suite, documentation, new posterior and estimators, fix readthedocs, improve prior heuristics, Github actions for tests, address memory issues --- .dockerignore | 10 + .dockstore.yml | 6 + .github/workflows/miniwdl_check.yml | 17 + .github/workflows/run_packaging_check.yml | 45 + .github/workflows/run_pytest.yml | 32 + .gitignore | 6 + MANIFEST.in | 5 +- README.rst | 138 +- REQUIREMENTS-DOCKER.txt | 9 - REQUIREMENTS.txt | 13 - build_docker_local.sh | 8 + build_docker_release.sh | 10 + cellbender/__init__.py | 1 + cellbender/base_cli.py | 40 +- cellbender/monitor.py | 41 + cellbender/remove_background/argparse.py | 166 -- cellbender/remove_background/argparser.py | 284 +++ cellbender/remove_background/checkpoint.py | 368 ++++ cellbender/remove_background/cli.py | 231 +- cellbender/remove_background/consts.py | 68 +- cellbender/remove_background/data/dataprep.py | 106 +- cellbender/remove_background/data/dataset.py | 1763 ++++----------- .../remove_background/data/extras/simulate.py | 1200 +++++++---- cellbender/remove_background/data/io.py | 1207 +++++++++++ cellbender/remove_background/data/priors.py | 391 ++++ .../NegativeBinomialPoissonConvApprox.py | 2 +- cellbender/remove_background/downstream.py | 479 +++++ cellbender/remove_background/estimation.py | 902 ++++++++ cellbender/remove_background/exceptions.py | 13 +- cellbender/remove_background/infer.py | 781 ------- cellbender/remove_background/model.py | 452 ++-- cellbender/remove_background/posterior.py | 1708 +++++++++++++++ cellbender/remove_background/report.ipynb | 133 ++ cellbender/remove_background/report.py | 1888 +++++++++++++++++ cellbender/remove_background/run.py | 779 +++++++ cellbender/remove_background/sparse_utils.py | 101 + .../tests/benchmarking/README.md | 62 + .../tests/benchmarking/benchmark.wdl | 29 + .../tests/benchmarking/benchmark_inputs.json | 19 + .../tests/benchmarking/cuda_check_inputs.json | 4 + .../docker_image_check_cuda_status.wdl | 38 + .../tests/benchmarking/run_benchmark.py | 225 ++ .../run_benchmark_result_tabulation.py | 146 ++ .../benchmarking/run_usual_benchmarks.sh | 74 + .../remove_background/tests/conftest.py | 202 ++ .../tests/mckp_memory_profiling.py | 146 ++ .../tests/miniwdl_check_wdl.sh | 13 + cellbender/remove_background/tests/test.py | 193 -- .../tests/test_checkpoint.py | 626 ++++++ .../remove_background/tests/test_dataprep.py | 101 + .../remove_background/tests/test_dataset.py | 40 + .../tests/test_downstream.py | 119 ++ .../tests/test_estimation.py | 358 ++++ .../remove_background/tests/test_infer.py | 301 +++ .../tests/test_integration.py | 52 + cellbender/remove_background/tests/test_io.py | 223 ++ .../remove_background/tests/test_monitor.py | 21 + .../remove_background/tests/test_posterior.py | 428 ++++ .../tests/test_sparse_utils.py | 203 ++ .../remove_background/tests/test_train.py | 135 ++ cellbender/remove_background/train.py | 362 ++-- cellbender/remove_background/vae/base.py | 164 ++ cellbender/remove_background/vae/decoder.py | 42 +- cellbender/remove_background/vae/encoder.py | 258 ++- docker/Dockerfile | 65 +- docker/DockerfileGit | 35 + .../PCL_rat_A_LA6_learning_curve.png | Bin 0 -> 23433 bytes .../remove_background/bad_learning_curves.png | Bin 0 -> 214054 bytes .../simulated_s6_learning_curve.png | Bin 0 -> 30054 bytes docs/source/_static/theme_overrides.css | 15 - docs/source/changelog/index.rst | 85 + docs/source/citation/index.rst | 13 +- docs/source/conf.py | 7 +- docs/source/contributing/index.rst | 10 +- docs/source/getting_started/index.rst | 11 - .../remove_background/index.rst | 138 -- docs/source/help_and_reference/index.rst | 10 - .../remove_background/index.rst | 81 - docs/source/index.rst | 25 +- docs/source/installation/index.rst | 76 +- docs/source/introduction/index.rst | 20 +- docs/source/reference/index.rst | 188 ++ .../license/index.rst | 0 docs/source/troubleshooting/index.rst | 426 ++++ docs/source/tutorial/index.rst | 224 ++ docs/source/usage/index.rst | 49 +- examples/remove_background/.gitignore | 8 +- .../generate_tiny_10x_dataset.py | 79 + .../generate_tiny_10x_pbmc.py | 103 - readthedocs.yml | 2 +- REQUIREMENTS-RTD.txt => requirements-rtd.txt | 0 requirements.txt | 15 + setup.py | 56 +- wdl/README.rst | 86 +- wdl/cellbender_remove_background.wdl | 309 ++- 95 files changed, 15843 insertions(+), 4280 deletions(-) create mode 100644 .dockerignore create mode 100644 .dockstore.yml create mode 100644 .github/workflows/miniwdl_check.yml create mode 100644 .github/workflows/run_packaging_check.yml create mode 100644 .github/workflows/run_pytest.yml delete mode 100644 REQUIREMENTS-DOCKER.txt delete mode 100644 REQUIREMENTS.txt create mode 100755 build_docker_local.sh create mode 100755 build_docker_release.sh create mode 100644 cellbender/monitor.py delete mode 100644 cellbender/remove_background/argparse.py create mode 100644 cellbender/remove_background/argparser.py create mode 100644 cellbender/remove_background/checkpoint.py create mode 100644 cellbender/remove_background/data/io.py create mode 100644 cellbender/remove_background/data/priors.py create mode 100644 cellbender/remove_background/downstream.py create mode 100644 cellbender/remove_background/estimation.py delete mode 100644 cellbender/remove_background/infer.py create mode 100644 cellbender/remove_background/posterior.py create mode 100644 cellbender/remove_background/report.ipynb create mode 100644 cellbender/remove_background/report.py create mode 100644 cellbender/remove_background/run.py create mode 100644 cellbender/remove_background/sparse_utils.py create mode 100644 cellbender/remove_background/tests/benchmarking/README.md create mode 100644 cellbender/remove_background/tests/benchmarking/benchmark.wdl create mode 100644 cellbender/remove_background/tests/benchmarking/benchmark_inputs.json create mode 100644 cellbender/remove_background/tests/benchmarking/cuda_check_inputs.json create mode 100644 cellbender/remove_background/tests/benchmarking/docker_image_check_cuda_status.wdl create mode 100644 cellbender/remove_background/tests/benchmarking/run_benchmark.py create mode 100644 cellbender/remove_background/tests/benchmarking/run_benchmark_result_tabulation.py create mode 100755 cellbender/remove_background/tests/benchmarking/run_usual_benchmarks.sh create mode 100644 cellbender/remove_background/tests/conftest.py create mode 100644 cellbender/remove_background/tests/mckp_memory_profiling.py create mode 100755 cellbender/remove_background/tests/miniwdl_check_wdl.sh delete mode 100644 cellbender/remove_background/tests/test.py create mode 100644 cellbender/remove_background/tests/test_checkpoint.py create mode 100644 cellbender/remove_background/tests/test_dataprep.py create mode 100644 cellbender/remove_background/tests/test_dataset.py create mode 100644 cellbender/remove_background/tests/test_downstream.py create mode 100644 cellbender/remove_background/tests/test_estimation.py create mode 100644 cellbender/remove_background/tests/test_infer.py create mode 100644 cellbender/remove_background/tests/test_integration.py create mode 100644 cellbender/remove_background/tests/test_io.py create mode 100644 cellbender/remove_background/tests/test_monitor.py create mode 100644 cellbender/remove_background/tests/test_posterior.py create mode 100644 cellbender/remove_background/tests/test_sparse_utils.py create mode 100644 cellbender/remove_background/tests/test_train.py create mode 100644 cellbender/remove_background/vae/base.py create mode 100644 docker/DockerfileGit create mode 100644 docs/source/_static/remove_background/PCL_rat_A_LA6_learning_curve.png create mode 100644 docs/source/_static/remove_background/bad_learning_curves.png create mode 100644 docs/source/_static/remove_background/simulated_s6_learning_curve.png delete mode 100644 docs/source/_static/theme_overrides.css create mode 100644 docs/source/changelog/index.rst delete mode 100644 docs/source/getting_started/index.rst delete mode 100644 docs/source/getting_started/remove_background/index.rst delete mode 100644 docs/source/help_and_reference/index.rst delete mode 100644 docs/source/help_and_reference/remove_background/index.rst create mode 100644 docs/source/reference/index.rst rename docs/source/{help_and_reference => reference}/license/index.rst (100%) create mode 100644 docs/source/troubleshooting/index.rst create mode 100644 docs/source/tutorial/index.rst create mode 100755 examples/remove_background/generate_tiny_10x_dataset.py delete mode 100755 examples/remove_background/generate_tiny_10x_pbmc.py rename REQUIREMENTS-RTD.txt => requirements-rtd.txt (100%) create mode 100644 requirements.txt diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..186f305f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +**/.git +.github +examples +docs +wdl +dist +cellbender.egg-info +.pytest_cache +*.h5 +*.tar.gz \ No newline at end of file diff --git a/.dockstore.yml b/.dockstore.yml new file mode 100644 index 00000000..0f2192a5 --- /dev/null +++ b/.dockstore.yml @@ -0,0 +1,6 @@ +version: 1.2 + +workflows: + - subclass: WDL + primaryDescriptorPath: /wdl/cellbender_remove_background.wdl + name: cellbender_remove_background diff --git a/.github/workflows/miniwdl_check.yml b/.github/workflows/miniwdl_check.yml new file mode 100644 index 00000000..8a8de2c8 --- /dev/null +++ b/.github/workflows/miniwdl_check.yml @@ -0,0 +1,17 @@ +name: 'validate WDL' +on: [pull_request] +env: + MINIWDL_VERSION: 1.8.0 +jobs: + miniwdl-check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.7' + - name: 'Install miniwdl and Run Validation Test' + run: | + pip install miniwdl==$MINIWDL_VERSION; + ./cellbender/remove_background/tests/miniwdl_check_wdl.sh; + shell: bash diff --git a/.github/workflows/run_packaging_check.yml b/.github/workflows/run_packaging_check.yml new file mode 100644 index 00000000..8a9fc1cd --- /dev/null +++ b/.github/workflows/run_packaging_check.yml @@ -0,0 +1,45 @@ +# Package for PyPI + +name: 'packaging' + +on: pull_request + +jobs: + build: + + runs-on: 'ubuntu-latest' + strategy: + matrix: + python-version: ['3.7'] + + steps: + - name: 'Checkout repo' + uses: actions/checkout@v3 + + - name: 'Set up Python ${{ matrix.python-version }}' + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + + - name: 'Install packaging software' + run: pip install --upgrade setuptools build twine + + - name: 'Print package versions' + run: pip list + + - name: 'Package code using build' + run: python -m build + + - name: 'Check package using twine' + run: python -m twine check dist/* + + - name: 'Extract branch name' + shell: bash + run: echo "branch=$(echo ${GITHUB_REF#refs/heads/})" >>$GITHUB_OUTPUT + id: extract_branch + + - name: 'Install from github branch and run a test' + run: | + pip install pytest git+https://github.com/broadinstitute/CellBender@${{ steps.extract_branch.outputs.branch }} + cellbender -v diff --git a/.github/workflows/run_pytest.yml b/.github/workflows/run_pytest.yml new file mode 100644 index 00000000..37e652b0 --- /dev/null +++ b/.github/workflows/run_pytest.yml @@ -0,0 +1,32 @@ +# Run cellbender's tests + +name: 'pytest' + +on: pull_request + +jobs: + build: + + runs-on: 'ubuntu-latest' + strategy: + matrix: + python-version: ['3.7'] + + steps: + - name: 'Checkout repo' + uses: actions/checkout@v3 + + - name: 'Set up Python ${{ matrix.python-version }}' + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + + - name: 'Install package including pytest' + run: pip install .[dev] + + - name: 'Print package versions' + run: pip list + + - name: 'Test with pytest' + run: pytest -v diff --git a/.gitignore b/.gitignore index b1e889ac..80b6c0c2 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,9 @@ dist/ .eggs/ .idea/ *.iml +*.h5 +*.h5ad +*.tsv +*.csv +*.npz +*.tar.gz diff --git a/MANIFEST.in b/MANIFEST.in index c4bf4561..66e89a17 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1,4 @@ -include README.rst \ No newline at end of file +include README.rst +include LICENSE +include requirements.txt +include requirements-rtd.txt \ No newline at end of file diff --git a/README.rst b/README.rst index a12cd22e..ea39e2ca 100644 --- a/README.rst +++ b/README.rst @@ -1,11 +1,27 @@ CellBender ========== +.. image:: https://img.shields.io/github/license/broadinstitute/CellBender?color=white + :target: LICENSE + :alt: License + .. image:: https://readthedocs.org/projects/cellbender/badge/?version=latest :target: https://cellbender.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status -.. image:: https://github.com/broadinstitute/CellBender/blob/master/docs/source/_static/design/logo_250_185.png +.. image:: https://img.shields.io/pypi/v/CellBender.svg + :target: https://pypi.org/project/CellBender + :alt: PyPI + +.. image:: https://static.pepy.tech/personalized-badge/cellbender?period=total&units=international_system&left_color=grey&right_color=blue&left_text=pypi%20downloads + :target: https://pepy.tech/project/CellBender + :alt: Downloads + +.. image:: https://img.shields.io/github/stars/broadinstitute/CellBender?color=yellow&logoColor=yellow) + :target: https://github.com/broadinstitute/CellBender/stargazers + :alt: Stars + +.. image:: docs/source/_static/design/logo_250_185.png :alt: CellBender Logo CellBender is a software package for eliminating technical artifacts from @@ -16,67 +32,123 @@ The current release contains the following modules. More modules will be added i * ``remove-background``: This module removes counts due to ambient RNA molecules and random barcode swapping from (raw) - UMI-based scRNA-seq count matrices. At the moment, only the count matrices produced by the - CellRanger ``count`` pipeline is supported. Support for additional tools and protocols will be - added in the future. A quick start tutorial can be found - `here <https://cellbender.readthedocs.io/en/latest/getting_started/remove_background/index.html>`_. + UMI-based scRNA-seq count matrices. Also works for snRNA-seq and CITE-seq. -Please refer to the `documentation <https://cellbender.readthedocs.io/en/latest/>`_ for a quick start tutorial on using CellBender. +Please refer to `the documentation <https://cellbender.readthedocs.io/en/latest/>`_ for a quick start tutorial. Installation and Usage ---------------------- -Manual installation -~~~~~~~~~~~~~~~~~~~ +CellBender can be installed via + +.. code-block:: console + + $ pip install cellbender + +(and we recommend installing in its own ``conda`` environment to prevent +conflicts with other software). + +CellBender is run as a command-line tool, as in + +.. code-block:: console + + (cellbender) $ cellbender remove-background \ + --cuda \ + --input my_raw_count_matrix_file.h5 \ + --output my_cellbender_output_file.h5 + +See `the usage documentation <https://cellbender.readthedocs.io/en/latest/usage/index.html>`_ +for details. + + +Using The Official Docker Image +------------------------------- + +A GPU-enabled docker image is available from the Google Container Registry (GCR) as: + +``us.gcr.io/broad-dsde-methods/cellbender:latest`` + +Available image tags track release tags in GitHub, and include ``latest``, +``0.1.0``, ``0.2.0``, ``0.2.1``, ``0.2.2``, and ``0.3.0``. + + +WDL Users +--------- + +A workflow written in the +`workflow description language (WDL) <https://github.com/openwdl/wdl>`_ +is available for CellBender remove-background. + +For `Terra <https://app.terra.bio>`_ users, a workflow called +``cellbender/remove-background`` is +`available from the Broad Methods repository +<https://portal.firecloud.org/#methods/cellbender/remove-background/>`_. + +There is also a `version available on Dockstore +<https://dockstore.org/workflows/github.com/broadinstitute/CellBender>`_. -The recommended installation is as follows. Create a conda environment and activate it: -.. code-block:: bash +Advanced installation +--------------------- - $ conda create -n cellbender python=3.7 - $ source activate cellbender +From source for development +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Create a conda environment and activate it: + +.. code-block:: console + + $ conda create -n cellbender python=3.7 + $ conda activate cellbender Install the `pytables <https://www.pytables.org>`_ module: -.. code-block:: bash +.. code-block:: console + + (cellbender) $ conda install -c anaconda pytables - (cellbender) $ conda install -c anaconda pytables +Install `pytorch <https://pytorch.org>`_ via +`these instructions <https://pytorch.org/get-started/locally/>`_, for example: -Install `pytorch <https://pytorch.org>`_ (shown below for CPU; if you have a CUDA-ready GPU, please skip -this part and follow `these <https://pytorch.org/get-started/locally/>`_ instructions instead): +.. code-block:: console -.. code-block:: bash + (cellbender) $ pip install torch - (cellbender) $ conda install pytorch torchvision -c pytorch +and ensure that your installation is appropriate for your hardware (i.e. that +the relevant CUDA drivers get installed and that ``torch.cuda.is_available()`` +returns ``True`` if you have a GPU available. -Clone this repository and install CellBender: +Clone this repository and install CellBender (in editable ``-e`` mode): -.. code-block:: bash +.. code-block:: console + (cellbender) $ git clone https://github.com/broadinstitute/CellBender.git (cellbender) $ pip install -e CellBender -Using The Official Docker Image -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A GPU-enabled docker image is available from the Google Container Registry (GCR) as: +From a specific commit +~~~~~~~~~~~~~~~~~~~~~~ -``us.gcr.io/broad-dsde-methods/cellbender:latest`` +This can be achieved via -Terra Users -~~~~~~~~~~~ +.. code-block:: console -For `Terra <https://app.terra.bio>`_ users, a `workflow <https://portal.firecloud.org/#methods/cellbender/remove-background/>`_ -is available as: + (cellbender) $ pip install --no-cache-dir -U git+https://github.com/broadinstitute/CellBender.git@<SHA> -``cellbender/remove-background`` +where ``<SHA>`` must be replaced by any reference to a particular git commit, +such as a tag, a branch name, or a commit sha. Citing CellBender ----------------- If you use CellBender in your research (and we hope you will), please consider -citing `our paper on bioRxiv <https://doi.org/10.1101/791699>`_. +citing our paper in Nature Methods: + +Stephen J Fleming, Mark D Chaffin, Alessandro Arduini, Amer-Denis Akkad, +Eric Banks, John C Marioni, Anthony A Phillipakis, Patrick T Ellinor, +and Mehrtash Babadi. Unsupervised removal of systematic background noise from +droplet-based single-cell experiments using CellBender. +`Nature Methods` (in press), 2023. -Stephen J Fleming, John C Marioni, and Mehrtash Babadi. CellBender remove-background: -a deep generative model for unsupervised removal of background noise from scRNA-seq -datasets. bioRxiv 791699; doi: `https://doi.org/10.1101/791699 <https://doi.org/10.1101/791699>`_ +See also `our preprint on bioRxiv <https://doi.org/10.1101/791699>`_. diff --git a/REQUIREMENTS-DOCKER.txt b/REQUIREMENTS-DOCKER.txt deleted file mode 100644 index 3884f08e..00000000 --- a/REQUIREMENTS-DOCKER.txt +++ /dev/null @@ -1,9 +0,0 @@ -anndata>=0.7 -numpy -scipy -tables -pandas -pyro-ppl>=0.3.2 -torch>=1.9.0 -scikit-learn -matplotlib diff --git a/REQUIREMENTS.txt b/REQUIREMENTS.txt deleted file mode 100644 index 535e3e78..00000000 --- a/REQUIREMENTS.txt +++ /dev/null @@ -1,13 +0,0 @@ -anndata>=0.7 -numpy -scipy -tables -pandas -pyro-ppl>=0.3.2 -scikit-learn -matplotlib -sphinx>=2.1 -sphinx-rtd-theme -sphinx-autodoc-typehints -sphinxcontrib-programoutput -sphinx-argparse diff --git a/build_docker_local.sh b/build_docker_local.sh new file mode 100755 index 00000000..c89367ff --- /dev/null +++ b/build_docker_local.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +tag=$(cat cellbender/__init__.py | sed -e 's?__version__ = ??' | sed "s/^'\(.*\)'$/\1/") + +docker build \ + -t us.gcr.io/broad-dsde-methods/cellbender:${tag} \ + -f docker/Dockerfile \ + . diff --git a/build_docker_release.sh b/build_docker_release.sh new file mode 100755 index 00000000..ff0511fc --- /dev/null +++ b/build_docker_release.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +tag=$(cat cellbender/__init__.py | sed -e 's?__version__ = ??' | sed "s/^'\(.*\)'$/\1/") +release=v${tag} + +docker build \ + -t us.gcr.io/broad-dsde-methods/cellbender:${tag} \ + --build-arg GIT_SHA=${release} \ + -f docker/DockerfileGit \ + . diff --git a/cellbender/__init__.py b/cellbender/__init__.py index e69de29b..0404d810 100644 --- a/cellbender/__init__.py +++ b/cellbender/__init__.py @@ -0,0 +1 @@ +__version__ = '0.3.0' diff --git a/cellbender/base_cli.py b/cellbender/base_cli.py index 1489772c..bf5a71b3 100644 --- a/cellbender/base_cli.py +++ b/cellbender/base_cli.py @@ -5,16 +5,32 @@ """ import sys +import os import argparse from abc import ABC, abstractmethod from typing import Dict import importlib - +import codecs # New tools should be added to this list. TOOL_NAME_LIST = ['remove-background'] +def read(rel_path): + here = os.path.abspath(os.path.dirname(__file__)) + with codecs.open(os.path.join(here, rel_path), 'r') as fp: + return fp.read() + + +def get_version() -> str: + for line in read('__init__.py').splitlines(): + if line.startswith('__version__'): + delim = '"' if '"' in line else "'" + return line.split(delim)[1] + else: + raise RuntimeError("Unable to find version string.") + + class AbstractCLI(ABC): """Abstract class for cellbender command-line interface tools. @@ -29,13 +45,15 @@ def get_name(self) -> str: """Return the command-line name of the tool.""" pass + @staticmethod @abstractmethod - def validate_args(self, parser: argparse): + def validate_args(parser: argparse) -> argparse.Namespace: """Do tool-specific argument validation, returning args.""" pass + @staticmethod @abstractmethod - def run(self, args): + def run(args): """Run the tool using the parsed arguments.""" pass @@ -62,8 +80,12 @@ def get_populated_argparser() -> argparse.ArgumentParser: # Set up argument parser. parser = argparse.ArgumentParser( prog="cellbender", - description="CellBender is a software package for eliminating technical artifacts from high-throughput " - "single-cell RNA sequencing (scRNA-seq) data.") + description="CellBender is a software package for eliminating technical " + "artifacts from high-throughput single-cell RNA sequencing " + "(scRNA-seq) data.") + + # Add the ability to display the version. + parser.add_argument('-v', '--version', action='version', version=get_version()) # Declare the existence of sub-parsers. subparsers = parser.add_subparsers( @@ -72,7 +94,7 @@ def get_populated_argparser() -> argparse.ArgumentParser: dest="tool") for tool_name in TOOL_NAME_LIST: - module_argparse_str_list = ["cellbender", tool_name.replace("-", "_"), "argparse"] + module_argparse_str_list = ["cellbender", tool_name.replace("-", "_"), "argparser"] module_argparse = importlib.import_module('.'.join(module_argparse_str_list)) subparsers = module_argparse.add_subparser_args(subparsers) @@ -103,3 +125,9 @@ def main(): else: parser.print_help() + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/cellbender/monitor.py b/cellbender/monitor.py new file mode 100644 index 00000000..e7dca617 --- /dev/null +++ b/cellbender/monitor.py @@ -0,0 +1,41 @@ +"""Utility functions for hardware monitoring""" + +# Inspiration for the nvidia-smi command comes from here: +# https://pytorch-lightning.readthedocs.io/en/latest/_modules/pytorch_lightning/callbacks/gpu_stats_monitor.html#GPUStatsMonitor +# but here it is stripped down to the absolute minimum + +import torch +import psutil +from psutil._common import bytes2human +import shutil +import subprocess + + +def get_hardware_usage(use_cuda: bool) -> str: + """Get a current snapshot of RAM, CPU, GPU memory, and GPU utilization as a string""" + + mem = psutil.virtual_memory() + + if use_cuda: + # Run nvidia-smi to get GPU utilization + gpu_query = 'utilization.gpu' + format = 'csv,nounits,noheader' + result = subprocess.run( + [shutil.which("nvidia-smi"), f"--query-gpu={gpu_query}", f"--format={format}"], + encoding="utf-8", + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, # for backward compatibility with python version 3.6 + check=True, + ) + pct_gpu_util = result.stdout.strip() + gpu_string = (f'Volatile GPU utilization: {pct_gpu_util} %\n' + f'GPU memory reserved: {torch.cuda.memory_reserved() / 1e9} GB\n' + f'GPU memory allocated: {torch.cuda.memory_allocated() / 1e9} GB\n') + else: + gpu_string = '' + + cpu_string = (f'Avg CPU load over past minute: ' + f'{psutil.getloadavg()[0] / psutil.cpu_count() * 100:.1f} %\n' + f'RAM in use: {bytes2human(mem.used)} ({mem.percent} %)') + + return gpu_string + cpu_string diff --git a/cellbender/remove_background/argparse.py b/cellbender/remove_background/argparse.py deleted file mode 100644 index a52a3eb8..00000000 --- a/cellbender/remove_background/argparse.py +++ /dev/null @@ -1,166 +0,0 @@ -import argparse -from cellbender.remove_background import consts - - -def add_subparser_args(subparsers: argparse) -> argparse: - """Add tool-specific arguments for remove-background. - - Args: - subparsers: Parser object before addition of arguments specific to - remove-background. - - Returns: - parser: Parser object with additional parameters. - - """ - - subparser = subparsers.add_parser("remove-background", - description="Remove background RNA " - "from count matrix.", - help="Remove background ambient RNA " - "and barcode-swapped reads from " - "a count matrix, producing a " - "new count matrix and " - "determining which barcodes " - "contain real cells.") - - subparser.add_argument("--input", nargs=None, type=str, - dest='input_file', default=None, - required=True, - help="Data file on which to run tool, as either " - "_raw_gene_barcode_matrices_h5.h5 file, or " - "as the path containing the raw " - "matrix.mtx, barcodes.tsv, and genes.tsv " - "files. Supported for outputs of " - "CellRanger v2 and v3.") - subparser.add_argument("--output", nargs=None, type=str, - dest='output_file', default=None, - required=True, - help="Output file location (the path must " - "exist, and the file name must have .h5 " - "extension).") - subparser.add_argument("--expected-cells", nargs=None, type=int, - default=None, - dest="expected_cell_count", - help="Number of cells expected in the dataset " - "(a rough estimate within a factor of 2 " - "is sufficient).") - subparser.add_argument("--total-droplets-included", - nargs=None, type=int, - default=consts.TOTAL_DROPLET_DEFAULT, - dest="total_droplets", - help="The number of droplets from the " - "rank-ordered UMI plot that will be " - "analyzed. The largest 'total_droplets' " - "droplets will have their cell " - "probabilities inferred as an output. (default: %(default)s)") - subparser.add_argument("--model", nargs=None, type=str, - default="full", - choices=["simple", "ambient", "swapping", "full"], - dest="model", - help="Which model is being used for count data. " - " 'simple' does not model either ambient " - "RNA or random barcode swapping (for " - "debugging purposes -- not recommended). " - "'ambient' assumes background RNA is " - "incorporated into droplets. 'swapping' " - "assumes background RNA comes from random " - "barcode swapping. 'full' uses a " - "combined ambient and swapping model. " - "(default: %(default)s)") - subparser.add_argument("--epochs", nargs=None, type=int, default=150, - dest="epochs", - help="Number of epochs to train. (default: %(default)s)") - subparser.add_argument("--cuda", - dest="use_cuda", action="store_true", - help="Including the flag --cuda will run the " - "inference on a GPU.") - subparser.add_argument("--low-count-threshold", type=int, - default=consts.LOW_UMI_CUTOFF, - dest="low_count_threshold", - help="Droplets with UMI counts below this " - "number are completely excluded from the " - "analysis. This can help identify the " - "correct prior for empty droplet counts " - "in the rare case where empty counts " - "are extremely high (over 200). (default: %(default)s)") - subparser.add_argument("--z-dim", type=int, default=100, - dest="z_dim", - help="Dimension of latent variable z. (default: %(default)s)") - subparser.add_argument("--z-layers", nargs="+", type=int, default=[500], - dest="z_hidden_dims", - help="Dimension of hidden layers in the encoder " - "for z. (default: %(default)s)") - subparser.add_argument("--training-fraction", - type=float, nargs=None, - default=consts.TRAINING_FRACTION, - dest="training_fraction", - help="Training detail: the fraction of the " - "data used for training. The rest is never " - "seen by the inference algorithm. Speeds up " - "learning. (default: %(default)s)") - subparser.add_argument("--empty-drop-training-fraction", - type=float, nargs=None, - default=consts.FRACTION_EMPTIES, - dest="fraction_empties", - help="Training detail: the fraction of the " - "training data each epoch " - "that is drawn (randomly sampled) from " - "surely empty droplets. (default: %(default)s)") - subparser.add_argument("--blacklist-genes", nargs="+", type=int, - default=[], - dest="blacklisted_genes", - help="Integer indices of genes to ignore " - "entirely. In the output count matrix, " - "the counts for these genes will be set " - "to zero.") - subparser.add_argument("--fpr", nargs="+", - type=float, default=[0.01], - dest="fpr", - help="Target false positive rate in (0, 1). A false " - "positive is a true signal count that is " - "erroneously removed. More background removal " - "is accompanied by more signal removal " - "at high values of FPR. You can specify " - "multiple values, which will create multiple " - "output files. (default: %(default)s)") - subparser.add_argument("--exclude-antibody-capture", - dest="exclude_antibodies", action="store_true", - help="Including the flag --exclude-antibody-capture " - "will cause remove-background to operate on " - "gene counts only, ignoring other features.") - subparser.add_argument("--learning-rate", nargs=None, - type=float, default=1e-4, - dest="learning_rate", - help="Training detail: lower learning rate for " - "inference. A OneCycle learning rate schedule " - "is used, where the upper learning rate is ten " - "times this value. (For this value, probably " - "do not exceed 1e-3). (default: %(default)s)") - subparser.add_argument("--final-elbo-fail-fraction", type=float, - help="Training is considered to have failed if " - "(best_test_ELBO - final_test_ELBO)/(best_test_DLBO - initial_train_ELBO) > FINAL_ELBO_FAIL_FRACTION." - "(default: do not fail training based on final_training_ELBO)") - subparser.add_argument("--epoch-elbo-fail-fraction", type=float, - help="Training is considered to have failed if " - "(previous_epoch_test_ELBO - current_epoch_test_ELBO)/(previous_epoch_test_ELBO - initial_train_ELBO) > EPOCH_ELBO_FAIL_FRACTION." - "(default: do not fail training based on epoch_training_ELBO)") - subparser.add_argument("--num-training-tries", type=int, default=1, - help="Number of times to attempt to train the model. Each subsequent " - "attempt the learning rate is multiplied by LEARNING_RATE_RETRY_MULT. " - "(default: %(default)s)") - subparser.add_argument("--learning-rate-retry-mult", type=float, default=0.5, - help="Learning rate is multiplied by this amount each time " - "(default: %(default)s)") - - subparser.add_argument("--posterior-batch-size", type=int, default=consts.PROP_POSTERIOR_BATCH_SIZE, - dest="posterior_batch_size", - help="Size of batches when creating the posterior. Reduce this to avoid " - "running out of GPU memory creating the posterior (will be slower). " - "(default: %(default)s)") - subparser.add_argument("--cells-posterior-reg-calc", type=int, default=consts.CELLS_POSTERIOR_REG_CALC, - dest="cells_posterior_reg_calc", - help="Number of cells used to estimate posterior regularization lambda. " - "(default: %(default)s)") - - return subparsers diff --git a/cellbender/remove_background/argparser.py b/cellbender/remove_background/argparser.py new file mode 100644 index 00000000..d53aca3c --- /dev/null +++ b/cellbender/remove_background/argparser.py @@ -0,0 +1,284 @@ +import argparse +from cellbender.remove_background import consts + + +def add_subparser_args(subparsers: argparse) -> argparse: + """Add tool-specific arguments for remove-background. + + Args: + subparsers: Parser object before addition of arguments specific to + remove-background. + + Returns: + parser: Parser object with additional parameters. + + """ + + subparser = subparsers.add_parser("remove-background", + description="Remove background RNA " + "from count matrix.", + help="Remove background ambient RNA " + "and barcode-swapped reads from " + "a count matrix, producing a " + "new count matrix and " + "determining which barcodes " + "contain real cells.", + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + + subparser.add_argument("--input", nargs=None, type=str, + dest='input_file', + required=True, + help="Data file on which to run tool. Data must be " + "un-filtered: it should include empty droplets. " + "The following input formats are supported: " + "CellRanger v2 and v3 (.h5 or the directory that " + "contains the .mtx file), Dropseq " + "DGE (.txt or .txt.gz), BD Rhapsody (.csv or " + ".csv.gz), AnnData (.h5ad), and Loom (.loom).") + subparser.add_argument("--output", nargs=None, type=str, + dest='output_file', + required=True, + help="Output file location (the path must " + "exist, and the file name must have .h5 " + "extension).") + subparser.add_argument("--cuda", + dest="use_cuda", action="store_true", + help="Including the flag --cuda will run the " + "inference on a GPU.") + subparser.add_argument("--checkpoint", nargs=None, type=str, + dest='input_checkpoint_tarball', + required=False, default=consts.CHECKPOINT_FILE_NAME, + help="Checkpoint tarball produced by the same version " + "of CellBender remove-background. If present, " + "and the workflow hashes match, training will " + "restart from this checkpoint.") + subparser.add_argument("--expected-cells", nargs=None, type=int, + default=None, + dest="expected_cell_count", + help="Number of cells expected in the dataset " + "(a rough estimate within a factor of 2 " + "is sufficient).") + subparser.add_argument("--total-droplets-included", + nargs=None, type=int, default=None, + dest="total_droplets", + help="The number of droplets from the " + "rank-ordered UMI plot that will have their " + "cell probabilities inferred as an output. " + "Include the droplets which might contain " + "cells. Droplets beyond TOTAL_DROPLETS_INCLUDED " + "should be 'surely empty' droplets.") + subparser.add_argument("--force-cell-umi-prior", + nargs=None, type=float, default=None, + dest="force_cell_umi_prior", + help="Ignore CellBender's heuristic prior estimation, " + "and use this prior for UMI counts in cells.") + subparser.add_argument("--force-empty-umi-prior", + nargs=None, type=float, default=None, + dest="force_empty_umi_prior", + help="Ignore CellBender's heuristic prior estimation, " + "and use this prior for UMI counts in empty droplets.") + subparser.add_argument("--model", nargs=None, type=str, + default="full", + choices=["naive", "simple", "ambient", "swapping", "full"], + dest="model", + help="Which model is being used for count data. " + "'naive' subtracts the estimated ambient profile." + " 'simple' does not model either ambient " + "RNA or random barcode swapping (for " + "debugging purposes -- not recommended). " + "'ambient' assumes background RNA is " + "incorporated into droplets. 'swapping' " + "assumes background RNA comes from random " + "barcode swapping (via PCR chimeras). 'full' " + "uses a combined ambient and swapping model.") + subparser.add_argument("--epochs", nargs=None, type=int, default=150, + dest="epochs", + help="Number of epochs to train.") + subparser.add_argument("--low-count-threshold", type=int, + default=consts.LOW_UMI_CUTOFF, + dest="low_count_threshold", + help="Droplets with UMI counts below this " + "number are completely excluded from the " + "analysis. This can help identify the " + "correct prior for empty droplet counts " + "in the rare case where empty counts " + "are extremely high (over 200).") + subparser.add_argument("--z-dim", type=int, default=64, + dest="z_dim", + help="Dimension of latent variable z.") + subparser.add_argument("--z-layers", nargs="+", type=int, default=[512], + dest="z_hidden_dims", + help="Dimension of hidden layers in the encoder for z.") + subparser.add_argument("--training-fraction", + type=float, nargs=None, + default=consts.TRAINING_FRACTION, + dest="training_fraction", + help="Training detail: the fraction of the " + "data used for training. The rest is never " + "seen by the inference algorithm. Speeds up " + "learning.") + subparser.add_argument("--empty-drop-training-fraction", + type=float, nargs=None, + default=consts.FRACTION_EMPTIES, + dest="fraction_empties", + help="Training detail: the fraction of the " + "training data each epoch " + "that is drawn (randomly sampled) from " + "surely empty droplets.") + subparser.add_argument("--ignore-features", nargs="+", type=int, + default=[], + dest="blacklisted_genes", + help="Integer indices of features to ignore " + "entirely. In the output count matrix, the " + "counts for these features will be unchanged.") + subparser.add_argument("--fpr", nargs="+", + default=[0.01], + dest="fpr", + help="Target 'delta' false positive rate in [0, 1). " + "Use 0 for a cohort of samples which will be " + "jointly analyzed for differential expression. " + "A false positive is a true signal count that is " + "erroneously removed. More background removal " + "is accompanied by more signal removal " + "at high values of FPR. You can specify " + "multiple values, which will create multiple " + "output files.") + subparser.add_argument("--exclude-feature-types", + type=str, nargs="+", default=[], + dest="exclude_features", + help="Feature types to ignore during the analysis. " + "These features will be left unchanged in the " + "output file.") + subparser.add_argument("--projected-ambient-count-threshold", + type=float, nargs=None, + default=consts.AMBIENT_COUNTS_IN_CELLS_LOW_LIMIT, + dest="ambient_counts_in_cells_low_limit", + help="Controls how many features are included in the " + "analysis, which can lead to a large speedup. " + "If a feature is expected to have less than " + "PROJECTED_AMBIENT_COUNT_THRESHOLD counts total " + "in all cells (summed), then that gene is " + "excluded, and it will be unchanged in the " + "output count matrix. For example, " + "PROJECTED_AMBIENT_COUNT_THRESHOLD = 0 will " + "include all features which have even a single " + "count in any empty droplet.") + subparser.add_argument("--learning-rate", + type=float, default=1e-4, + dest="learning_rate", + help="Training detail: lower learning rate for " + "inference. A OneCycle learning rate schedule " + "is used, where the upper learning rate is ten " + "times this value. (For this value, probably " + "do not exceed 1e-3).") + subparser.add_argument("--checkpoint-mins", + type=float, default=7., + dest="checkpoint_min", + help="Checkpoint file will be saved periodically, " + "with this many minutes between each checkpoint.") + subparser.add_argument("--final-elbo-fail-fraction", type=float, + dest="final_elbo_fail_fraction", + help="Training is considered to have failed if " + "(best_test_ELBO - final_test_ELBO)/(best_test_ELBO " + "- initial_test_ELBO) > FINAL_ELBO_FAIL_FRACTION. Training will " + "automatically re-run if --num-training-tries > " + "1. By default, will not fail training based " + "on final_training_ELBO.") + subparser.add_argument("--epoch-elbo-fail-fraction", type=float, + dest="epoch_elbo_fail_fraction", + help="Training is considered to have failed if " + "(previous_epoch_test_ELBO - current_epoch_test_ELBO)" + "/(previous_epoch_test_ELBO - initial_train_ELBO) " + "> EPOCH_ELBO_FAIL_FRACTION. Training will " + "automatically re-run if --num-training-tries > " + "1. By default, will not fail training based " + "on epoch_training_ELBO.") + subparser.add_argument("--num-training-tries", type=int, default=1, + dest="num_training_tries", + help="Number of times to attempt to train the model. " + "At each subsequent attempt, the learning rate is " + "multiplied by LEARNING_RATE_RETRY_MULT.") + subparser.add_argument("--learning-rate-retry-mult", type=float, default=0.2, + dest="learning_rate_retry_mult", + help="Learning rate is multiplied by this amount each " + "time a new training attempt is made. (This " + "parameter is only used if training fails based " + "on EPOCH_ELBO_FAIL_FRACTION or " + "FINAL_ELBO_FAIL_FRACTION and NUM_TRAINING_TRIES" + " is > 1.)") + subparser.add_argument("--posterior-batch-size", type=int, + default=consts.PROB_POSTERIOR_BATCH_SIZE, + dest="posterior_batch_size", + help="Training detail: size of batches when creating " + "the posterior. Reduce this to avoid running " + "out of GPU memory creating the posterior " + "(will be slower).") + subparser.add_argument("--posterior-regularization", type=str, + default=None, + choices=["PRq", "PRmu", "PRmu_gene"], + dest="posterior_regularization", + help="Posterior regularization method. (For experts: " + "not required for normal usage, see " + "documentation). PRq is approximate quantile-" + "targeting. PRmu is approximate mean-targeting " + "aggregated over genes (behavior of v0.2.0). " + "PRmu_gene is approximate mean-targeting per " + "gene.") + subparser.add_argument("--alpha", + type=float, default=None, + dest="prq_alpha", + help="Tunable parameter alpha for the PRq posterior " + "regularization method (not normally used: see " + "documentation).") + subparser.add_argument("--q", + type=float, default=None, + dest="cdf_threshold_q", + help="Tunable parameter q for the CDF threshold " + "estimation method (not normally used: see " + "documentation).") + subparser.add_argument("--estimator", type=str, + default="mckp", + choices=["map", "mean", "cdf", "sample", "mckp"], + dest="estimator", + help="Output denoised count estimation method. (For " + "experts: not required for normal usage, see " + "documentation).") + subparser.add_argument("--estimator-multiple-cpu", + dest="use_multiprocessing_estimation", action="store_true", + default=False, + help="Including the flag --estimator-multiple-cpu will " + "use more than one CPU to compute the MCKP " + "output count estimator in parallel (does " + "nothing for other estimators).") + subparser.add_argument("--constant-learning-rate", + dest="constant_learning_rate", action="store_true", + default=False, + help="Including the flag --constant-learning-rate will " + "use the ClippedAdam optimizer instead of the " + "OneCycleLR learning rate schedule, which is " + "the default. Learning is faster with the " + "OneCycleLR schedule. However, training can " + "easily be continued from a checkpoint for more " + "epochs than the initial command specified when " + "using ClippedAdam. On the other hand, if using " + "the OneCycleLR schedule with 150 epochs " + "specified, it is not possible to pick up from " + "that final checkpoint and continue training " + "until 250 epochs.") + subparser.add_argument("--cpu-threads", + type=int, default=None, + dest="n_threads", + help="Number of threads to use when pytorch is run " + "on CPU. Defaults to the number of logical cores.") + subparser.add_argument("--debug", + dest="debug", action="store_true", + help="Including the flag --debug will log " + "extra messages useful for debugging.") + subparser.add_argument("--truth", + type=str, default=None, + dest="truth_file", + help="This is only used by developers for report " + "generation. Truth h5 file (for " + "simulated data only).") + + return subparsers diff --git a/cellbender/remove_background/checkpoint.py b/cellbender/remove_background/checkpoint.py new file mode 100644 index 00000000..5b0903de --- /dev/null +++ b/cellbender/remove_background/checkpoint.py @@ -0,0 +1,368 @@ +"""Handle the saving and loading of models from checkpoint files.""" + +from cellbender.remove_background import consts +from cellbender.remove_background.data.dataprep import DataLoader + +import torch +import numpy as np +from typing import Tuple, List, Optional, Union, Dict +import logging +import argparse +import hashlib +import os +import tarfile +import glob +import random +import pickle +import tempfile +import shutil +import traceback + + +logger = logging.getLogger('cellbender') + +USE_PYRO = True +try: + import pyro +except ImportError: + USE_PYRO = False +USE_CUDA = torch.cuda.is_available() + + +def save_random_state(filebase: str) -> List[str]: + """Write states of various random number generators to files. + + NOTE: the pyro.util.get_rng_state() is a compilation of python, numpy, and + torch random states. Here, we save the three explicitly ourselves. + This is useful for potential future usages outside of pyro. + """ + # https://stackoverflow.com/questions/32808686/storing-a-random-state/32809283 + + file_dict = {} + + # Random state information + if USE_PYRO: + pyro_random_state = pyro.util.get_rng_state() # this is shorthand for the following + file_dict.update({filebase + '_random.pyro': pyro_random_state}) + else: + python_random_state = random.getstate() + numpy_random_state = np.random.get_state() + torch_random_state = torch.get_rng_state() + file_dict.update({filebase + '_random.python': python_random_state, + filebase + '_random.numpy': numpy_random_state, + filebase + '_random.torch': torch_random_state}) + if USE_CUDA: + cuda_random_state = torch.cuda.get_rng_state_all() + file_dict.update({filebase + '_random.cuda': cuda_random_state}) + + # Save it + for file, state in file_dict.items(): + with open(file, 'wb') as f: + pickle.dump(state, f) + + return list(file_dict.keys()) + + +def load_random_state(filebase: str): + """Load random states from files and update generators with them.""" + + if USE_PYRO: + with open(filebase + '_random.pyro', 'rb') as f: + pyro_random_state = pickle.load(f) + pyro.util.set_rng_state(pyro_random_state) + + else: + with open(filebase + '_random.python', 'rb') as f: + python_random_state = pickle.load(f) + random.setstate(python_random_state) + + with open(filebase + '_random.numpy', 'rb') as f: + numpy_random_state = pickle.load(f) + np.random.set_state(numpy_random_state) + + with open(filebase + '_random.torch', 'rb') as f: + torch_random_state = pickle.load(f) + torch.set_rng_state(torch_random_state) + + if USE_CUDA: + with open(filebase + '_random.cuda', 'rb') as f: + cuda_random_state = pickle.load(f) + torch.cuda.set_rng_state_all(cuda_random_state) + + +def save_checkpoint(filebase: str, + model_obj: 'RemoveBackgroundPyroModel', + scheduler: pyro.optim.PyroOptim, + args: argparse.Namespace, + train_loader: Optional[DataLoader] = None, + test_loader: Optional[DataLoader] = None, + tarball_name: str = consts.CHECKPOINT_FILE_NAME) -> bool: + """Save trained model and optimizer state in a checkpoint file. + Any hyperparameters or metadata should be part of the model object.""" + + logger.info(f'Saving a checkpoint...') + + try: + + # Work in a temporary directory. + with tempfile.TemporaryDirectory() as tmp_dir: + + basename = os.path.basename(filebase) + filebase = os.path.join(tmp_dir, basename) + + file_list = save_random_state(filebase=filebase) + + torch.save(model_obj, filebase + '_model.torch') + torch.save(scheduler, filebase + '_optim.torch') + scheduler.save(filebase + '_optim.pyro') # use PyroOptim method + pyro.get_param_store().save(filebase + '_params.pyro') + file_list = file_list + [filebase + '_model.torch', + filebase + '_optim.torch', + filebase + '_optim.pyro', + filebase + '_params.pyro'] + + if train_loader is not None: + # train_loader_file = save_dataloader_state(filebase=filebase, + # data_loader_state=train_loader.get_state(), + # name='train') + torch.save(train_loader, filebase + '_train.loaderstate') + file_list.append(filebase + '_train.loaderstate') + if test_loader is not None: + # test_loader_file = save_dataloader_state(filebase=filebase, + # data_loader_state=test_loader.get_state(), + # name='test') + torch.save(test_loader, filebase + '_test.loaderstate') + file_list.append(filebase + '_test.loaderstate') + + np.save(filebase + '_args.npy', args) + file_list.append(filebase + '_args.npy') + + make_tarball(files=file_list, tarball_name=tarball_name) + + logger.info(f'Saved checkpoint as {os.path.abspath(tarball_name)}') + return True + + except KeyboardInterrupt: + logger.warning('Keyboard interrupt: will not save checkpoint') + return False + + except Exception: + logger.warning('Could not save checkpoint') + logger.warning(traceback.format_exc()) + return False + + +def load_checkpoint(filebase: Optional[str], + tarball_name: str = consts.CHECKPOINT_FILE_NAME, + force_device: Optional[str] = None)\ + -> Dict[str, Union['RemoveBackgroundPyroModel', pyro.optim.PyroOptim, DataLoader, bool]]: + """Load checkpoint and prepare a RemoveBackgroundPyroModel and optimizer.""" + + out = load_from_checkpoint( + filebase=filebase, + tarball_name=tarball_name, + to_load=['model', 'optim', 'param_store', 'dataloader', 'args', 'random_state'], + force_device=force_device, + ) + out.update({'loaded': True}) + logger.info(f'Loaded partially-trained checkpoint from {tarball_name}') + return out + + +def load_from_checkpoint(filebase: Optional[str], + tarball_name: str = consts.CHECKPOINT_FILE_NAME, + to_load: List[str] = ['model'], + force_device: Optional[str] = None) -> Dict: + """Load specific files from a checkpoint tarball.""" + + load_kwargs = {} + if force_device is not None: + load_kwargs.update({'map_location': torch.device(force_device)}) + + # Work in a temporary directory. + with tempfile.TemporaryDirectory() as tmp_dir: + + # Unpack the checkpoint tarball. + logger.info(f'Attempting to unpack tarball "{tarball_name}" to {tmp_dir}') + success = unpack_tarball(tarball_name=tarball_name, directory=tmp_dir) + if success: + unpacked_files = '\n'.join(glob.glob(os.path.join(tmp_dir, "*"))) + logger.info(f'Successfully unpacked tarball to {tmp_dir}\n' + f'{unpacked_files}') + else: + # no tarball loaded, so do not continue trying to load files + raise FileNotFoundError + + # See if files have a hash matching input filebase. + if filebase is not None: + basename = os.path.basename(filebase) + filebase = os.path.join(tmp_dir, basename) + logger.debug(f'Looking for files with base name matching {filebase}*') + if not os.path.exists(filebase + '_model.torch'): + logger.info('Workflow hash does not match that of checkpoint.') + raise ValueError('Workflow hash does not match that of checkpoint.') + else: + filebase = (glob.glob(os.path.join(tmp_dir, '*_model.torch'))[0] + .replace('_model.torch', '')) + logger.debug(f'Accepting any file hash, so loading {filebase}*') + + out = {} + + # Load the saved model. + if 'model' in to_load: + model_obj = torch.load(filebase + '_model.torch', **load_kwargs) + logger.debug('Model loaded from ' + filebase + '_model.torch') + out.update({'model': model_obj}) + + # Load the saved optimizer. + if 'optim' in to_load: + scheduler = torch.load(filebase + '_optim.torch', **load_kwargs) + scheduler.load(filebase + '_optim.pyro', **load_kwargs) # use PyroOptim method + logger.debug('Optimizer loaded from ' + filebase + '_optim.*') + out.update({'optim': scheduler}) + + # Load the pyro param store. + if 'param_store' in to_load: + pyro.get_param_store().load(filebase + '_params.pyro', map_location=force_device) + logger.debug('Pyro param store loaded from ' + filebase + '_params.pyro') + + # Load dataloader states. + if 'dataloader' in to_load: + # load_dataloader_state(data_loader=train_loader, file=filebase + '_train.loaderstate') + # load_dataloader_state(data_loader=test_loader, file=filebase + '_test.loaderstate') + train_loader = None + test_loader = None + if os.path.exists(filebase + '_train.loaderstate'): + train_loader = torch.load(filebase + '_train.loaderstate', **load_kwargs) + logger.debug('Train loader loaded from ' + filebase + '_train.loaderstate') + out.update({'train_loader': train_loader}) + if os.path.exists(filebase + '_test.loaderstate'): + test_loader = torch.load(filebase + '_test.loaderstate', **load_kwargs) + logger.debug('Test loader loaded from ' + filebase + '_test.loaderstate') + out.update({'test_loader': test_loader}) + + # Load args, which can be modified in the case of auto-learning-rate updates. + if 'args' in to_load: + args = np.load(filebase + '_args.npy', allow_pickle=True).item() + out.update({'args': args}) + + # Update states of random number generators across the board. + if 'random_state' in to_load: + load_random_state(filebase=filebase) + logger.debug('Loaded random state globally for python, numpy, pytorch, and cuda') + + # Copy the posterior file outside the temp dir so it can be loaded later. + if 'posterior' in to_load: + posterior_file = os.path.join(os.path.dirname(filebase), 'posterior.h5') + if os.path.exists(posterior_file): + shutil.copyfile(posterior_file, 'posterior.h5') + out.update({'posterior_file': 'posterior.h5'}) + logger.debug(f'Copied posterior file from {posterior_file} to posterior.h5') + else: + logger.debug('Trying to load posterior in load_from_checkpoint(), but posterior ' + 'is not present in checkpoint tarball.') + + return out + + +def attempt_load_checkpoint(filebase: str, + tarball_name: str = consts.CHECKPOINT_FILE_NAME, + force_device: Optional[str] = None)\ + -> Dict[str, Union['RemoveBackgroundPyroModel', pyro.optim.PyroOptim, DataLoader, bool]]: + """Load checkpoint and prepare a RemoveBackgroundPyroModel and optimizer, + or return the inputs if loading fails.""" + + try: + logger.debug('Attempting to load checkpoint from ' + tarball_name) + return load_checkpoint(filebase=filebase, + tarball_name=tarball_name, + force_device=force_device) + + except FileNotFoundError: + logger.debug('No tarball found') + return {'loaded': False} + + except ValueError: + logger.debug('Unpacked tarball files have a different workflow hash: will not load') + return {'loaded': False} + + +def make_tarball(files: List[str], tarball_name: str) -> bool: + """Tar and gzip a list of files as a checkpoint tarball. + NOTE: used by automated checkpoint handling in Cromwell + NOTE2: .tmp file is used so that incomplete checkpoint files do not exist + even temporarily + """ + with tarfile.open(tarball_name + '.tmp', 'w:gz', compresslevel=1) as tar: + for file in files: + # without arcname, unpacking results in unpredictable file locations! + tar.add(file, arcname=os.path.basename(file)) + os.rename(tarball_name + '.tmp', tarball_name) + return True + + +def unpack_tarball(tarball_name: str, directory: str) -> bool: + """Untar a checkpoint tarball and put the files in directory.""" + if not os.path.exists(tarball_name): + logger.info("No saved checkpoint.") + return False + + try: + with tarfile.open(tarball_name, 'r:gz') as tar: + tar.extractall(path=directory) + return True + + except Exception: + logger.warning("Failed to unpack existing tarball.") + return False + + +def create_workflow_hashcode(module_path: str, + args: argparse.Namespace, + args_to_remove: List[str] = ['epochs', 'fpr'], + name: str = 'md5', + verbose: bool = False) -> str: + """Create a hash blob from cellbender python code plus input arguments.""" + + hasher = hashlib.new(name=name) + + files_safe_to_ignore = ['infer.py', 'simulate.py', 'report.py', + 'downstream.py', 'monitor.py', 'fpr.py', + 'posterior.py', 'estimation.py', 'sparse_utils.py'] + + if not os.path.exists(module_path): + return '' + + try: + + # files + for root, _, files in os.walk(module_path): + for file in files: + if not file.endswith('.py'): + continue + if file in files_safe_to_ignore: + continue + if 'test' in file: + continue + if verbose: + print(file) + with open(os.path.join(root, file), 'rb') as f: + buf = b'\n'.join(f.readlines()) + hasher.update(buf) # encode python files + + # inputs + args_dict = vars(args).copy() + for arg in args_to_remove: + args_dict.pop(arg, None) + hasher.update(str(args_dict).encode('utf-8')) # encode parsed input args + + # input file + # TODO + # this is probably not necessary for real data... why would two different + # files have the same name? + # but it's useful for development where simulated datasets change + + except Exception: + return '' + + return hasher.hexdigest() diff --git a/cellbender/remove_background/cli.py b/cellbender/remove_background/cli.py index 16e93e88..ad49c018 100644 --- a/cellbender/remove_background/cli.py +++ b/cellbender/remove_background/cli.py @@ -1,15 +1,17 @@ """Command-line tool functionality for remove-background.""" import torch -from cellbender.remove_background.data.dataset import SingleCellRNACountsDataset -from cellbender.remove_background.train import run_inference -from cellbender.base_cli import AbstractCLI -from cellbender.remove_background import consts +import cellbender + +from cellbender.base_cli import AbstractCLI, get_version +from cellbender.remove_background.checkpoint import create_workflow_hashcode +from cellbender.remove_background.run import run_remove_background +from cellbender.remove_background.posterior import Posterior import logging import os import sys -from datetime import datetime +import argparse class CLI(AbstractCLI): @@ -22,16 +24,25 @@ def __init__(self): def get_name(self) -> str: return self.name - def validate_args(self, args): + @staticmethod + def validate_args(args) -> argparse.Namespace: """Validate parsed arguments.""" # Ensure that if there's a tilde for $HOME in the file path, it works. try: args.input_file = os.path.expanduser(args.input_file) args.output_file = os.path.expanduser(args.output_file) + if args.truth_file is not None: + args.truth_file = os.path.expanduser(args.truth_file) except TypeError: raise ValueError("Problem with provided input and output paths.") + # Ensure that if truth data is specified, it is accessible + if args.truth_file is not None: + assert os.access(args.truth_file, os.R_OK), \ + f"Cannot read specified simulated truth file {args.truth_file}. " \ + f"Ensure the file exists and is read accessible." + # Ensure write access to the save directory. file_dir, _ = os.path.split(args.output_file) # Get the output directory if file_dir: @@ -76,6 +87,10 @@ def validate_args(self, args): "significant speed-ups.\n\n") sys.stdout.flush() # Write immediately + # Make sure n_threads makes sense. + if args.n_threads is not None: + assert args.n_threads > 0, "--cpu-threads must be an integer >= 1" + # Ensure all network layer dimensions are positive. for n in args.z_hidden_dims: assert n > 0, "--z-layers must be all positive integers." @@ -88,117 +103,131 @@ def validate_args(self, args): args.use_jit = False # Ensure false positive rate is between zero and one. + fpr_list_correct_dtypes = [] # for a mix of floats and strings later on for fpr in args.fpr: - assert (fpr > 0.) and (fpr < 1.), \ - "False positive rate --fpr must be between 0 and 1." - - assert args.num_training_tries > 0, "num-training-tries must be > 0" - assert args.epoch_elbo_fail_fraction is None or args.epoch_elbo_fail_fraction > 0., \ - "--epoch-elbo-fail-fraction must be > 0" - assert args.final_elbo_fail_fraction is None or args.final_elbo_fail_fraction > 0., \ - "--epoch-elbo-fail-fraction must be > 0" - - self.args = args + try: + fpr = float(fpr) + assert (fpr >= 0.) and (fpr < 1.), \ + "False positive rate --fpr must be in [0, 1)" + except ValueError: + # the input is not a float + assert fpr == 'cohort', \ + "The only allowed non-float value for FPR is the word 'cohort'." + fpr_list_correct_dtypes.append(fpr) + args.fpr = fpr_list_correct_dtypes + + # Ensure that "exclude_features" specifies allowed features. + # As of CellRanger 6.0, the possible features are: + # Gene Expression + # Antibody Capture + # CRISPR Guide Capture + # Custom + # Peaks + allowed_features = ['Gene Expression', 'Antibody Capture', + 'CRISPR Guide Capture', 'Custom', 'Peaks'] + for feature in args.exclude_features: + if feature not in allowed_features: + sys.stdout.write(f"Specified '{feature}' using --exclude-feature-types, " + f"but this is not a valid CellRanger feature " + f"designation: {allowed_features}. Ensure that " + f"this feature appears in your dataset, and " + f"ensure that this log file makes note of the " + f"exclusion of the appropriate features below.\n\n") + sys.stdout.flush() # Write immediately + if 'Gene Expression' in args.exclude_features: + sys.stdout.write("WARNING: Excluding 'Gene Expression' features from the analysis " + "is not recommended, since other features alone are typically " + "too sparse to form a good prior on cell type, and CellBender " + "relies on being able to construct this sort of prior\n\n") + sys.stdout.flush() # Write immediately + + # Automatic training failures and restarts. + assert args.num_training_tries > 0, "--num-training-tries must be > 0 (default 1)" + if args.epoch_elbo_fail_fraction is not None: + assert (args.epoch_elbo_fail_fraction > 0.), \ + "--epoch-elbo-fail-fraction must be in > 0" + if args.final_elbo_fail_fraction is not None: + assert (args.final_elbo_fail_fraction > 0.), \ + "--final-elbo-fail-fraction must be in > 0" + + # Ensure timing of checkpoints is within bounds. + assert args.checkpoint_min > 0, "--checkpoint-min must be > 0" + if args.checkpoint_min > 15: + sys.stdout.write(f"Warning: Timing between checkpoints is specified as " + f"{args.checkpoint_min} minutes. Consider reducing " + f"this number if you are concerned about the " + f"possibility of lost work upon preemption.\n\n") + sys.stdout.flush() # Write immediately + + # Posterior regularization checking. + if args.cdf_threshold_q is not None: + assert (args.cdf_threshold_q >= 0.) and (args.cdf_threshold_q <= 1.), \ + f"Argument --q must be in range [0, 1] since it is a CDF threshold." + if args.posterior_regularization == 'PRq': + # We need q for the CDF threshold estimator. + assert args.prq_alpha is not None, \ + 'Input argument --alpha must be specified when using ' \ + '--posterior-regularization PRq' + + # Estimator checking. + if args.estimator == 'cdf': + # We need q for the CDF threshold estimator. + assert args.cdf_threshold_q is not None, \ + 'Input argument --q must be specified when using --estimator cdf' return args - def run(self, args): + @staticmethod + def run(args) -> Posterior: """Run the main tool functionality on parsed arguments.""" # Run the tool. - main(args) - + return main(args) -def run_remove_background(args): - """The full script for the command line tool to remove background RNA. - Args: - args: Inputs from the command line, already parsed using argparse. - - Note: Returns nothing, but writes output to a file(s) specified from - command line. - - """ - - # Load dataset, run inference, and write the output to a file. +def setup_and_logging(args): + """Take command-line input, parse arguments, and run tests or tool.""" # Send logging messages to stdout as well as a log file. file_dir, file_base = os.path.split(args.output_file) file_name = os.path.splitext(os.path.basename(file_base))[0] log_file = os.path.join(file_dir, file_name + ".log") - logging.basicConfig(level=logging.INFO, - format="cellbender:remove-background: %(message)s", - filename=log_file, - filemode="w") - console = logging.StreamHandler() - formatter = logging.Formatter("cellbender:remove-background: " - "%(message)s") - console.setFormatter(formatter) # Use the same format for stdout. - logging.getLogger('').addHandler(console) # Log to stdout and a file. + logger = logging.getLogger('cellbender') # name of the logger + logger.setLevel(logging.INFO if not args.debug else logging.DEBUG) + formatter = logging.Formatter('cellbender:remove-background: %(message)s') + file_handler = logging.FileHandler(filename=log_file, mode='w', encoding='UTF-8') + console_handler = logging.StreamHandler() + file_handler.setFormatter(formatter) # set the file format + console_handler.setFormatter(formatter) # use the same format for stdout + logger.addHandler(file_handler) # log to file + logger.addHandler(console_handler) # log to stdout # Log the command as typed by user. - logging.info("Command:\n" + ' '.join(['cellbender', 'remove-background'] - + sys.argv[2:])) - - # Log the start time. - logging.info(datetime.now().strftime('%Y-%m-%d %H:%M:%S')) - - logging.info("Running remove-background") - - # Load data from file and choose barcodes and genes to analyze. - try: - dataset_obj = \ - SingleCellRNACountsDataset(input_file=args.input_file, - expected_cell_count=args.expected_cell_count, - total_droplet_barcodes=args.total_droplets, - fraction_empties=args.fraction_empties, - model_name=args.model, - gene_blacklist=args.blacklisted_genes, - exclude_antibodies=args.exclude_antibodies, - low_count_threshold=args.low_count_threshold, - fpr=args.fpr) - - except OSError: - logging.error(f"OSError: Unable to open file {args.input_file}.") - sys.exit(1) - - # Instantiate latent variable model and run full inference procedure. - inferred_model = run_inference(dataset_obj, args) - - # Write outputs to file. - try: - dataset_obj.save_to_output_file(args.output_file, - inferred_model, - posterior_batch_size=args.posterior_batch_size, - cells_posterior_reg_calc=args.cells_posterior_reg_calc, - save_plots=True) - - logging.info("Completed remove-background.") - logging.info(datetime.now().strftime('%Y-%m-%d %H:%M:%S\n')) - - # The exception allows user to end inference prematurely with CTRL-C. - except KeyboardInterrupt: - - # If partial output has been saved, delete it. - full_file = args.output_file - - # Name of the filtered (cells only) file. - file_dir, file_base = os.path.split(full_file) - file_name = os.path.splitext(os.path.basename(file_base))[0] - filtered_file = os.path.join(file_dir, - file_name + "_filtered.h5") - - if os.path.exists(full_file): - os.remove(full_file) - - if os.path.exists(filtered_file): - os.remove(filtered_file) - - logging.info("Keyboard interrupt. Terminated without saving.\n") - - -def main(args): + logger.info("Command:\n" + + ' '.join(['cellbender', 'remove-background'] + sys.argv[2:])) + logger.info("CellBender " + get_version()) + + # Set up checkpointing by creating a unique workflow hash. + hashcode = create_workflow_hashcode( + module_path=os.path.dirname(cellbender.__file__), + args_to_remove=(['output_file', 'fpr', 'input_checkpoint_tarball', 'debug', + 'posterior_batch_size', 'checkpoint_min', 'truth_file', + 'posterior_regularization', 'cdf_threshold_q', 'prq_alpha', + 'estimator', 'use_multiprocessing_estimation', 'cpu_threads'] + + (['epochs'] if args.constant_learning_rate else [])), + args=args)[:10] + args.checkpoint_filename = hashcode # store this in args + logger.info(f'(Workflow hash {hashcode})') + return args, file_handler + + +def main(args) -> Posterior: """Take command-line input, parse arguments, and run tests or tool.""" + args, file_handler = setup_and_logging(args) + # Run the tool. - run_remove_background(args) + posterior = run_remove_background(args) + file_handler.close() + + return posterior diff --git a/cellbender/remove_background/consts.py b/cellbender/remove_background/consts.py index 2874913a..ee5fc11c 100644 --- a/cellbender/remove_background/consts.py +++ b/cellbender/remove_background/consts.py @@ -1,13 +1,21 @@ """Constant numbers used in remove-background.""" +# Seed for random number generators. +RANDOM_SEED = 1234 + # Factor by which the mode UMI count of the empty droplet plateau is # multiplied to come up with a UMI cutoff below which no barcodes are used. EMPIRICAL_LOW_UMI_TO_EMPTY_DROPLET_THRESHOLD = 0.5 +# Features with fewer than this many counts summed over all empty droplets +# are ignored during analysis, and the output count matrix for these features +# is identical to the input. +COUNTS_IN_EMPTIES_LOW_LIMIT = 0 +AMBIENT_COUNTS_IN_CELLS_LOW_LIMIT = 0.1 + # Default prior for the standard deviation of the LogNormal distribution for # cell size, used only in the case of the 'simple' model. SIMPLE_MODEL_D_STD_PRIOR = 0.2 -D_STD_PRIOR = 0.02 # Probability cutoff for determining which droplets contain cells and which # are empty. The droplets n with inferred probability q_n > CELL_PROB_CUTOFF @@ -16,7 +24,7 @@ # Default UMI cutoff. Droplets with UMI less than this will be completely # excluded from the analysis. -LOW_UMI_CUTOFF = 15 +LOW_UMI_CUTOFF = 5 # Default total number of droplets to include in the analysis. TOTAL_DROPLET_DEFAULT = 25000 @@ -28,32 +36,34 @@ DEFAULT_BATCH_SIZE = 128 # Fraction of totally empty droplets that makes up each minibatch, by default. -FRACTION_EMPTIES = 0.5 +FRACTION_EMPTIES = 0.2 # Prior on rho, the swapping fraction: the two concentration parameters alpha and beta. -RHO_ALPHA_PRIOR = 18. -RHO_BETA_PRIOR = 200. +RHO_ALPHA_PRIOR = 1.5 +RHO_BETA_PRIOR = 50. # Constraints on rho posterior latents. -RHO_PARAM_MIN = 1. +RHO_PARAM_MIN = 0.001 RHO_PARAM_MAX = 1000. # Prior on epsilon, the RT efficiency concentration parameter [Gamma(alpha, alpha)]. -EPSILON_PRIOR = 500. +EPSILON_PRIOR = 50. # Prior used for the global overdispersion parameter. PHI_LOC_PRIOR = 0.2 PHI_SCALE_PRIOR = 0.2 +# Prior for mixture weights in Gaussian mixture model. +GMM_ALPHA_PRIOR = 1e-1 +GMM_COMPONENTS = 10 +GMM_EPOCHS = 500 + # Initial value of global latent scale for d_cell. D_CELL_SCALE_INIT = 0.02 # Scale used to regularize values of logit cell probability (mean zero). P_LOGIT_SCALE = 2. -# Hidden layer sizes of non-z latent encoder neural network. -ENC_HIDDEN_DIMS = [100, 50] - # False to use an approximate log_prob computation which is much faster. USE_EXACT_LOG_PROB = False @@ -64,23 +74,43 @@ NBPC_MU_EPS_SAFEGAURD = 1e-10 NBPC_ALPHA_EPS_SAFEGAURD = 1e-10 NBPC_LAM_EPS_SAFEGAURD = 1e-10 +POISSON_EPS_SAFEGAURD = 1e-10 # Scale factors for loss function regularization terms: semi-supervision. REG_SCALE_AMBIENT_EXPRESSION = 0.01 -REG_SCALE_EMPTY_PROB = 1.0 -REG_SCALE_CELL_PROB = 10.0 +REG_SCALE_SOFT_SUPERVISION = 10.0 + +# Regularize logit probabilities toward this lognormal distribution. +REG_LOGIT_MEAN = 10.0 +REG_LOGIT_SCALE = 0.2 +REG_LOGIT_SOFT_SCALE = 1.0 -# Number of cells used to estimate posterior regularization lambda. Memory hungry. +# Number of cells used to esitmate posterior regularization lambda. Memory hungry. CELLS_POSTERIOR_REG_CALC = 100 # Posterior regularization constant's upper and lower bounds. -POSTERIOR_REG_MIN = 0.1 +POSTERIOR_REG_MIN = 0.01 POSTERIOR_REG_MAX = 500 -POSTERIOR_REG_SEARCH_MAX_ITER = 20 +POSTERIOR_REG_SEARCH_MAX_ITER = 50 -# Minimum number of barcodes we expect in an unfiltered `h5ad` input file. -# Throws a warning if the input has fewer than this number. +# For AnnData h5ad files, fewer than this many barcodes will trigger a warning, +# since it indicates that the file might be "filtered" to cells only. MINIMUM_BARCODES_H5AD = 1e5 -# reduce this if running out of GPU memory https://github.com/broadinstitute/CellBender/issues/67 -PROP_POSTERIOR_BATCH_SIZE = 20 +# Batch size for posterior inference. +PROB_POSTERIOR_BATCH_SIZE = 128 + +# Name of checkpoint file. +CHECKPOINT_FILE_NAME = 'ckpt.tar.gz' + +# Whether to create an extended report (for development purposes). +EXTENDED_REPORT = False + +# Maximum batch size +MAX_BATCH_SIZE = 256 +SMALLEST_ALLOWED_BATCH = 4 # BatchNorm chokes if there is only 1 cell in last batch + +# Guesses during prior estimation +MAX_TOTAL_DROPLETS_GUESSED = 70000 +MAX_EMPTIES_TO_INCLUDE = 20000 +NUM_EMPTIES_INCREMENT = 20000 # if input expected_cells > heuristic prior total_drops diff --git a/cellbender/remove_background/data/dataprep.py b/cellbender/remove_background/data/dataprep.py index b53003fd..00e1d5d8 100644 --- a/cellbender/remove_background/data/dataprep.py +++ b/cellbender/remove_background/data/dataprep.py @@ -1,5 +1,8 @@ """Helper functions for preparing dataloaders, as well as a class to implement loading data from a sparse matrix in mini-batches. + +Intentionally uses global random state, and does not keep its own random number +generator, in order to facilitate checkpointing. """ import numpy as np @@ -10,7 +13,11 @@ import torch import torch.utils.data -from typing import Tuple, List, Optional +import logging +from typing import Tuple, List, Optional, Callable + + +logger = logging.getLogger('cellbender') class SparseDataset(torch.utils.data.Dataset): @@ -51,9 +58,37 @@ def __init__(self, batch_size: int = consts.DEFAULT_BATCH_SIZE, fraction_empties: float = consts.FRACTION_EMPTIES, shuffle: bool = True, + sort_by: Optional[Callable[[sp.csr_matrix], np.ndarray]] = None, use_cuda: bool = True): + """ + Args: + dataset: Droplet count matrix [cell, gene] + empty_drop_dataset: Surely empty droplets count matrix + batch_size: Number of droplets in minibatch + fraction_empties: Fraction of each minibatch that will consist of + surely empty droplets + shuffle: True to shuffle data. Incompatible with sort_by. + sort_by: Lambda function which, when applied to the sparse matrix, + will return values that can be sorted to give a sort order to + the dataset. Dataloader will load data in order of increasing + values. Object attributes sort_order and unsort_order will be + made available. + use_cuda: True to load data to GPU + """ + if shuffle: + assert sort_by is None, 'Cannot sort_by and shuffle at the same time' + self.sort_fn = sort_by self.dataset = dataset - self.ind_list = np.arange(self.dataset.shape[0]) + if self.sort_fn is not None: + sort_values = self.sort_fn(self.dataset) + sort_order = np.argsort(sort_values) + self.ind_list = sort_order + self.sort_order = sort_order.copy() + self._unsort_dict = {i: val for i, val in enumerate(self.sort_order)} + else: + self.ind_list = np.arange(self.dataset.shape[0]) + self.sort_order = self.ind_list.copy() + self._unsort_dict = {i: i for i in self.ind_list} self.empty_drop_dataset = empty_drop_dataset if self.empty_drop_dataset is None: self.empty_ind_list = np.array([]) @@ -63,27 +98,64 @@ def __init__(self, self.fraction_empties = fraction_empties self.cell_batch_size = int(batch_size * (1. - fraction_empties)) self.shuffle = shuffle - self.random = np.random.RandomState(seed=1234) self.device = 'cpu' self.use_cuda = use_cuda if self.use_cuda: self.device = 'cuda' + self._length = None self._reset() + @torch.no_grad() + def unsort_inds(self, bcs): + if self.sort_fn is None: + return bcs # just for speed + else: + return torch.tensor([self._unsort_dict[bc.item()] for bc in bcs], device='cpu') + def _reset(self): if self.shuffle: - self.random.shuffle(self.ind_list) # Shuffle cell inds in place + np.random.shuffle(self.ind_list) # Shuffle cell inds in place self.ptr = 0 + def get_state(self): + """Internal state of the data loader, used for checkpointing""" + return {'ind_list': self.ind_list, 'ptr': self.ptr} + + def set_state(self, ind_list: np.ndarray, ptr: int): + self.ind_list = ind_list + self.ptr = ptr + assert self.ptr <= len(self.ind_list), \ + f'Problem setting dataloader state: pointer ({ptr}) is outside the ' \ + f'length of the ind_list ({len(ind_list)})' + + def reset_ptr(self): + self.ptr = 0 + + @property + def length(self): + if self._length is None: + self._length = self._get_length() + return self._length + + def _get_length(self): + # avoid the potential for an off-by-one error by just going through it + i = 0 + for _ in self: + i += 1 + return i + def __len__(self): - return int(self.ind_list.size * - (1 + (self.fraction_empties / (1 - self.fraction_empties)))) # ...ish + return self.length def __iter__(self): return self def __next__(self): - if self.ptr == self.ind_list.size: + # Skip last batch if the size is < smallest allowed batch + remaining_cells = self.ind_list.size - self.ptr + if remaining_cells < consts.SMALLEST_ALLOWED_BATCH: + if remaining_cells > 0: + logger.debug(f'Dropped last minibatch of {remaining_cells} cells') self._reset() raise StopIteration() @@ -101,9 +173,9 @@ def __next__(self): (1 - self.fraction_empties))) if self.empty_ind_list.size > 0: # This does not happen for 'simple' model. - empty_inds = self.random.choice(self.empty_ind_list, - size=n_empties, - replace=True) + empty_inds = np.random.choice(self.empty_ind_list, + size=n_empties, + replace=True) if empty_inds.size > 0: csr_list = [self.dataset[cell_inds, :], @@ -121,9 +193,8 @@ def __next__(self): return dense_tensor.to(device=self.device) -def prep_sparse_data_for_training(dataset: sp.csr.csr_matrix, - empty_drop_dataset: sp.csr.csr_matrix, - random_state: np.random.RandomState, +def prep_sparse_data_for_training(dataset: sp.csr_matrix, + empty_drop_dataset: sp.csr_matrix, training_fraction: float = consts.TRAINING_FRACTION, fraction_empties: float = consts.FRACTION_EMPTIES, batch_size: int = consts.DEFAULT_BATCH_SIZE, @@ -144,8 +215,6 @@ def prep_sparse_data_for_training(dataset: sp.csr.csr_matrix, columns are genes. empty_drop_dataset: Matrix of gene counts, where rows are surely-empty droplet barcodes and columns are genes. - random_state: numpy.random.RandomState from the Dataset object, for - deterministic outputs. training_fraction: Fraction of data to use as the training set. The rest becomes the test set. fraction_empties: Fraction of each minibatch to be composed of empty @@ -167,15 +236,14 @@ def prep_sparse_data_for_training(dataset: sp.csr.csr_matrix, """ # Choose train and test indices from analysis dataset. - training_mask = random_state.rand(dataset.shape[0]) < training_fraction + training_mask = np.random.rand(dataset.shape[0]) < training_fraction training_indices = [idx for idx in range(dataset.shape[0]) if training_mask[idx]] test_indices = [idx for idx in range(dataset.shape[0]) if not training_mask[idx]] # Choose train and test indices from empty drop dataset. - training_mask_empty = (random_state.rand(empty_drop_dataset.shape[0]) - < training_fraction) + training_mask_empty = (np.random.rand(empty_drop_dataset.shape[0]) < training_fraction) training_indices_empty = [idx for idx in range(empty_drop_dataset.shape[0]) if training_mask_empty[idx]] test_indices_empty = [idx for idx in range(empty_drop_dataset.shape[0]) @@ -204,7 +272,7 @@ def prep_sparse_data_for_training(dataset: sp.csr.csr_matrix, return train_loader, test_loader -def sparse_collate(batch: List[Tuple[sp.csr.csr_matrix]]) -> torch.Tensor: +def sparse_collate(batch: List[Tuple[sp.csr_matrix]]) -> torch.Tensor: """Load a minibatch of sparse data as a dense torch.Tensor in memory. Puts each data field into a tensor with leftmost dimension batch size. diff --git a/cellbender/remove_background/data/dataset.py b/cellbender/remove_background/data/dataset.py index a4eb84b2..4a9f97e7 100644 --- a/cellbender/remove_background/data/dataset.py +++ b/cellbender/remove_background/data/dataset.py @@ -1,26 +1,25 @@ """Class and functions for working with a count matrix dataset.""" -import tables import numpy as np import scipy.sparse as sp -import scipy.io as io -from scipy.stats import mode -from sklearn.decomposition import PCA import torch -import anndata -import cellbender.remove_background.model import cellbender.remove_background.consts as consts -from cellbender.remove_background.infer import ProbPosterior from cellbender.remove_background.data.dataprep import DataLoader - -from typing import Dict, List, Union, Tuple, Optional +from cellbender.remove_background.data.io import load_data +from cellbender.remove_background.data.priors import get_priors, \ + get_cell_count_given_expected_cells, \ + get_empty_count_given_expected_cells_and_total_droplets, \ + compute_crossover_surely_empty_and_stds +from cellbender.remove_background.sparse_utils import csr_set_rows_to_zero, \ + overwrite_matrix_with_columns_from_another + +from typing import Dict, List, Optional, Iterable, Callable import logging -import os +import argparse + -import matplotlib -matplotlib.use('Agg') -import matplotlib.pyplot as plt # This needs to be after matplotlib.use('Agg') +logger = logging.getLogger('cellbender') class SingleCellRNACountsDataset: @@ -32,12 +31,18 @@ class SingleCellRNACountsDataset: expected_cell_count: Expected number of real cells a priori. total_droplet_barcodes: Total number of droplets to include in the cell-calling analysis. + force_cell_umi_prior: User wants to force cell UMI prior to be this + force_empty_umi_prior: User wants to force empty UMI prior to be this + ambient_counts_in_cells_low_limit: Limit to determine how many features + are included in the analysis model_name: Model to use. gene_blacklist: List of integer indices of genes to exclude entirely. + exclude_features: List of feature types to exclude from the analysis. + Must be in ['Gene Expression', 'Antibody Capture', + 'CRISPR Guide Capture', 'Custom'] low_count_threshold: Droplets with UMI counts below this number are excluded entirely from the analysis. - lambda_multiplier: Float that multiplies background estimate before - MAP estimation. + fpr: Target expected false positive rate. Attributes: input_file: Name of data source file. @@ -52,7 +57,7 @@ class SingleCellRNACountsDataset: trim_dataset_for_analysis(). model_name: Name of model being run. priors: Priors estimated from the data useful for modelling. - posterior: Posterior estimated after inference. + posterior: BasePosterior estimated after inference. empty_UMI_threshold: This UMI count is the maximum UMI count in the user-defined surely empty droplets. @@ -64,397 +69,388 @@ class SingleCellRNACountsDataset: def __init__(self, input_file: str, model_name: str, - exclude_antibodies: bool, + exclude_features: List[str], low_count_threshold: int, fpr: List[float], expected_cell_count: Optional[int] = None, - total_droplet_barcodes: int = consts.TOTAL_DROPLET_DEFAULT, + total_droplet_barcodes: Optional[int] = None, + force_cell_umi_prior: Optional[float] = None, + force_empty_umi_prior: Optional[float] = None, fraction_empties: Optional[float] = None, + ambient_counts_in_cells_low_limit: float = consts.AMBIENT_COUNTS_IN_CELLS_LOW_LIMIT, gene_blacklist: List[int] = []): assert input_file is not None, "Attempting to load data, but no " \ "input file was specified." self.input_file = input_file self.analyzed_barcode_inds = np.array([]) # Barcodes trained each epoch - self.analyzed_gene_inds = np.array([]) - self.empty_barcode_inds = np.array([]) # Barcodes randomized each epoch + self.empty_barcode_inds = np.array([]) # Barcodes sampled randomly each epoch + self.low_count_cutoff = low_count_threshold self.data = None - self.exclude_antibodies = exclude_antibodies + self.gmm = None + self.exclude_features = exclude_features self.model_name = model_name self.fraction_empties = fraction_empties self.is_trimmed = False self.low_count_threshold = low_count_threshold - self.priors = {'n_cells': expected_cell_count} # Expected cells could be None. + self.ambient_counts_in_cells_low_limit = ambient_counts_in_cells_low_limit + self.priors = {} self.posterior = None self.fpr = fpr - self.random = np.random.RandomState(seed=1234) - self.EMPIRICAL_LOW_UMI_TO_EMPTY_DROPLET_THRESHOLD = \ - consts.EMPIRICAL_LOW_UMI_TO_EMPTY_DROPLET_THRESHOLD - self.SIMPLE_MODEL_D_STD_PRIOR = consts.SIMPLE_MODEL_D_STD_PRIOR - self.CELL_PROB_CUTOFF = consts.CELL_PROB_CUTOFF - - # Load the dataset. - self._load_data() - - # Trim the dataset. - self._trim_dataset_for_analysis(total_droplet_barcodes=total_droplet_barcodes, - low_UMI_count_cutoff=low_count_threshold, - gene_blacklist=gene_blacklist) - - # Estimate priors. - self._estimate_priors() - def _detect_input_data_type(self) -> str: - """Detect the type of input data.""" - - # Error if no input data file has been specified. - assert self.input_file is not None, \ - "Attempting to load data, but no input file was specified." - - # Detect type. - if os.path.isdir(self.input_file): - return 'cellranger_mtx' - - elif os.path.splitext(self.input_file)[1] == '.h5ad': - # assume unfiltered AnnData object, e.g. from kallisto | bustools - return 'anndata' - - else: - return 'cellranger_h5' - - def _load_data(self): - """Load a dataset into the SingleCellRNACountsDataset object from - the self.input_file""" - - # Detect input data type. - data_type = self._detect_input_data_type() + # Are empty droplets included in this model? + self.include_empties = False if (self.model_name in ['simple']) else True # Load the dataset. - if data_type == 'cellranger_mtx': + self.data = load_data(self.input_file) + self.analyzed_gene_logic = True - logging.info(f"Loading data from directory {self.input_file}") - self.data = get_matrix_from_cellranger_mtx(self.input_file) + # Eliminate feature types not used in the analysis. + self._exclude_feature_types() - elif data_type == 'cellranger_h5': + # Eliminate zero-count features and blacklisted features. + self._clean_features(gene_blacklist=gene_blacklist) - logging.info(f"Loading data from file {self.input_file}") - self.data = get_matrix_from_cellranger_h5(self.input_file) - - elif data_type == 'anndata': - - logging.info(f"Loading data from file {self.input_file}") - self.data = get_matrix_from_anndata(self.input_file) + # Estimate priors. + counts = np.array(self.data['matrix'] + [:, self.analyzed_gene_logic].sum(axis=1)).squeeze() + self.priors = get_priors(umi_counts=counts, low_count_threshold=low_count_threshold) + + # Overwrite heuristic priors with user inputs. + if expected_cell_count is not None: + logger.debug(f'Fixing expected_cells at {expected_cell_count}') + self.priors['expected_cells'] = expected_cell_count + self.priors.update( + get_cell_count_given_expected_cells( + umi_counts=counts, expected_cells=expected_cell_count, + ) + ) + if (expected_cell_count + consts.NUM_EMPTIES_INCREMENT) > self.priors['total_droplets']: + # Bump this up to avoid an immediate error + total_drops = expected_cell_count + consts.NUM_EMPTIES_INCREMENT + self.priors['total_droplets'] = total_drops + logger.debug(f'Incrementing total_droplets to be {total_drops}') + if total_droplet_barcodes is None: + # If this isn't getting recomputed next, recompute now + self.priors.update( + get_empty_count_given_expected_cells_and_total_droplets( + umi_counts=counts, expected_cells=self.priors['expected_cells'], + total_droplets=total_drops, + ) + ) + if total_droplet_barcodes is not None: + logger.debug(f'Fixing total_droplets at {total_droplet_barcodes}') + self.priors['total_droplets'] = total_droplet_barcodes + self.priors.update( + get_empty_count_given_expected_cells_and_total_droplets( + umi_counts=counts, expected_cells=self.priors['expected_cells'], + total_droplets=total_droplet_barcodes, + ) + ) + + # Force priors if user elects to do so. + if force_cell_umi_prior is not None: + logger.debug(f'Forcing cell UMI count prior to be {force_cell_umi_prior}') + self.priors['cell_counts'] = force_cell_umi_prior + if force_empty_umi_prior is not None: + logger.debug(f'Forcing empty droplet UMI count prior to be {force_empty_umi_prior}') + self.priors['empty_counts'] = force_empty_umi_prior + middle = np.sqrt(self.priors['cell_counts'] * force_empty_umi_prior) + self.priors['empty_count_upper_limit'] = min(middle, 2 * force_empty_umi_prior) + + # Recompute a few quantities if some things were replaced by user input. + compute_crossover_surely_empty_and_stds(umi_counts=counts, priors=self.priors) + logger.info(f"Prior on counts for cells is {int(self.priors['cell_counts'])}") + logger.info(f"Prior on counts for empty droplets is {int(self.priors['empty_counts'])}") + logger.debug('\n'.join(['Priors:'] + [f'{k}: {v}' for k, v in self.priors.items()])) + + # Do not analyze features which are not expected to contribute to noise. + self._trim_noiseless_features() + self.analyzed_gene_inds = np.where(self.analyzed_gene_logic)[0].astype(dtype=int) + logger.info(f"Including {len(self.analyzed_gene_inds)} features in the analysis.") + + # Determine barcodes to be analyzed. + self._trim_droplets() + self.is_trimmed = True - else: - raise NotImplementedError + # Estimate gene expression priors. + self.priors.update(self._estimate_chi_ambient()) - def _trim_dataset_for_analysis( - self, - total_droplet_barcodes: int = consts.TOTAL_DROPLET_DEFAULT, - low_UMI_count_cutoff: int = consts.LOW_UMI_CUTOFF, - gene_blacklist: List[int] = []): - """Trim the dataset for inference, choosing barcodes and genes to use. + logger.debug('\n'.join(['Priors:'] + [f'{k}: {v}' for k, v in self.priors.items()])) - Sets the values of self.analyzed_barcode_inds, and - self.empty_barcode_inds, which are used throughout training. + def _exclude_feature_types(self): + """Exclude feature types as specified by user. + Sets the value of self.analyzed_gene_logic + """ + + # Skip if feature types are not specified. + if self.data['feature_types'] is None: + if len(self.exclude_features) > 0: + logger.warning(f"WARNING: specified --exclude-feature-types " + f"{self.exclude_features} but no feature_type " + f"information was found in the input file. Proceeding " + f"without excluding any features. If this is not the " + f"intended outcome, please check your input file " + f"format.") + else: + logger.info('No feature type information specified in the input ' + 'file. Including all features in the analysis.') + return + + # Feature types are specified. + dtype = type(self.data['feature_types'][0]) + is_bytestring = (dtype != str) and (dtype != np.str_) + + def convert(s): + if is_bytestring: + return str(s, encoding='utf-8') + return s + + feature_type_array = np.array([convert(f) for f in self.data['feature_types']], dtype=str) + feature_types = np.unique(feature_type_array) + feature_info = [f"{(feature_type_array == f).sum()} {f}" for f in feature_types] + logger.info(f"Features in dataset: {', '.join(feature_info)}") + + # Keep track of a logical array for which features to include. + inclusion_logic = np.ones(len(feature_type_array), dtype=bool) # all True + + for feature in self.exclude_features: + logger.info(f"Excluding {feature} features (output will equal input).") + logic = np.array([f not in self.exclude_features + for f in feature_type_array], dtype=bool) + inclusion_logic = np.logical_and(inclusion_logic, logic) + logger.info(f" - This results in the exclusion of " + f"{len(feature_type_array) - logic.sum()} " + f"features.") + + # Update self.analyzed_gene_logic + self.analyzed_gene_logic = np.logical_and( + self.analyzed_gene_logic, + inclusion_logic, + ) + + def _clean_features(self, gene_blacklist: List[int] = []): + """Trim the dataset by removing zero-count and blacklisted features. + Sets the value of self.analyzed_gene_logic Args: - total_droplet_barcodes: Number of total droplets to include - during inference each epoch, and for which to make cell calls. - low_UMI_count_cutoff: Barcodes with total UMI counts below - this number are excluded. gene_blacklist: List of gene indices to trim out and exclude. - - Note: - self.priors['n_cells'] is only used to choose which barcodes to - include in the analysis, as well as to estimate the sizes of cells - and empty droplets (elsewhere). It need only be a reasonable guess. - The full analysis makes inferences about which barcodes contain - cells, and ultimately will determine this number. - However, if running only the 'simple' model, the expected_cell_count - is taken to be the true number of cells, since empty droplets are - not part of the 'simple' model. - """ - logging.info("Trimming dataset for inference.") + logger.info("Trimming features for inference.") # Get data matrix and barcode order that sorts barcodes by UMI count. matrix = self.data['matrix'] - umi_counts = np.array(matrix.sum(axis=1)).squeeze() - umi_count_order = np.argsort(umi_counts)[::-1] - - # Initially set the default to be the whole dataset. - self.analyzed_barcode_inds = np.arange(start=0, stop=matrix.shape[0]) - self.analyzed_gene_inds = np.arange(start=0, stop=matrix.shape[1]) - - # Expected cells must not exceed nonzero count barcodes. - num_nonzero_barcodes = np.sum(umi_counts > 0).item() # Choose which genes to use based on their having nonzero counts. # (All barcodes must be included so that inference can generalize.) - gene_counts_per_barcode = np.array(matrix.sum(axis=0)).squeeze() - if self.exclude_antibodies: - antibody_logic = (self.data['feature_types'] == b'Antibody Capture') - # Exclude these by setting their counts to zero - logging.info(f"Excluding {antibody_logic.sum()} features that " - f"correspond to antibody capture.") - gene_counts_per_barcode[antibody_logic] = 0 - nonzero_gene_counts = (gene_counts_per_barcode > 0) - self.analyzed_gene_inds = np.where(nonzero_gene_counts)[0].astype(dtype=int) - - if self.analyzed_gene_inds.size == 0: - logging.warning("During data loading, found no genes with > 0 " - "counts. Terminating analysis.") - raise AssertionError("No genes with nonzero counts. Check the " - "input data file.") + feature_counts_per_barcode = np.array(matrix.sum(axis=0)).squeeze() + inclusion_logic = (feature_counts_per_barcode > 0) + + # Update self.analyzed_gene_inds + self.analyzed_gene_logic = np.logical_and(self.analyzed_gene_logic, inclusion_logic) # Remove blacklisted genes. if len(gene_blacklist) > 0: - - # Make gene_blacklist a set for fast inclusion testing. gene_blacklist = set(gene_blacklist) + inclusion_logic = np.array([g not in gene_blacklist + for g in range(len(self.analyzed_gene_logic))]) + logger.info(f"Ignoring {np.logical_not(inclusion_logic).sum()} " + f"specified features.") + self.analyzed_gene_logic = np.logical_and( + self.analyzed_gene_logic, + inclusion_logic, + ) + + if self.analyzed_gene_logic.sum() == 0: + logger.warning("No features remain after eliminating zero-count " + "and ignored features. Terminating analysis.") + raise AssertionError("No features with nonzero counts remain. Check " + "the input data file and check " + "--exclude-feature-types and --ignore-features") + + logger.info(f"{self.analyzed_gene_logic.sum()} features have nonzero counts.") + + def _trim_noiseless_features(self): + """Trim the dataset for inference, choosing genes to use. + + To be run after trimming features first, then trimming barcodes. + + Sets the value of self.analyzed_gene_inds + """ - # Ensure genes on the blacklist are excluded. - self.analyzed_gene_inds = np.array([g for g in - self.analyzed_gene_inds - if g not in gene_blacklist]) - - if self.analyzed_gene_inds.size == 0: - logging.warning("All nonzero genes have been blacklisted. " - "Terminating analysis.") - raise AssertionError("All genes with nonzero counts have been " - "blacklisted. Examine the dataset and " - "reduce the blacklist.") - - logging.info(f"Including {self.analyzed_gene_inds.size} genes that have" - f" nonzero counts.") - - # Estimate priors on cell size and 'empty' droplet size. - self.priors['cell_counts'], self.priors['empty_counts'] = \ - get_d_priors_from_dataset(self) # After gene trimming + assert len(self.priors.keys()) > 0, 'Run self.priors = get_priors() before ' \ + 'self._trim_noiseless_features()' + + # Find average counts per gene in empty droplets. + count_matrix = self.data['matrix'][:, self.analyzed_gene_logic] + counts = np.array(count_matrix.sum(axis=1)).squeeze() + cutoff = self.priors['empty_count_upper_limit'] + count_matrix_empties = count_matrix[(counts < cutoff) + & (counts > self.low_count_threshold), :] + mean_counts_per_empty_g = np.array(count_matrix_empties.mean(axis=0)).squeeze() + + # Estimate counts in cells, but use a minimum number of cells just as a floor. + ambient_counts_in_cells_g = (max(self.priors['expected_cells'], 5000) + * mean_counts_per_empty_g) + + # Include features that are projected to have noise above the low limit. + inclusion_logic_subset = (ambient_counts_in_cells_g + > self.ambient_counts_in_cells_low_limit) + inclusion_logic = np.ones(len(self.analyzed_gene_logic), dtype=bool) + inclusion_logic[self.analyzed_gene_logic] = inclusion_logic_subset + + # Record in self.analyzed_gene_logic + self.analyzed_gene_logic = np.logical_and( + self.analyzed_gene_logic, + inclusion_logic, + ) + logger.info(f"Excluding {np.logical_not(inclusion_logic).sum()} features that " + f"are estimated to have <= {self.ambient_counts_in_cells_low_limit} " + f"background counts in cells.") + + def _trim_droplets(self): + """Trim the dataset for inference, choosing barcodes to use. - # Estimate the number of real cells if it was not specified. - if self.priors['n_cells'] is None: - self.priors['n_cells'] = estimate_cell_count_from_dataset(self) + Sets the values of self.analyzed_barcode_inds, and + self.empty_barcode_inds, which are used throughout training. + """ - # n_cells is at most the number of nonzero barcodes. - n_cells = min(self.priors['n_cells'], num_nonzero_barcodes) + logger.info("Trimming barcodes for inference.") - assert n_cells > 0, "No cells identified. Try to use the option " \ - "--expected-cells to specify a prior on cell " \ - "count. Also ensure that --low-count-threshold " \ - "is not too large (less than empty droplets)." + # Get data matrix and barcode order that sorts barcodes by UMI count. + matrix = self.get_count_matrix_all_barcodes() # self.data['matrix'] + umi_counts = np.array(matrix.sum(axis=1)).squeeze() + # umi_counts_features_trimmed = self.get_count_matrix_all_barcodes() + umi_count_order = np.argsort(umi_counts)[::-1] + n_cells = self.priors['expected_cells'] + total_droplet_barcodes = self.priors['total_droplets'] # If running the simple model, just use the expected cells, no more. - if self.model_name == "simple": + if not self.include_empties: self.analyzed_barcode_inds = np.array(umi_count_order[:n_cells], dtype=int) - logging.info(f"Simple model: using " - f"{self.analyzed_barcode_inds.size} cell barcodes.") + logger.info(f"Excluding empty droplets due to '{self.model_name}' model: " + f"using {self.analyzed_barcode_inds.size} cell barcodes.") # If not using the simple model, include empty droplets. else: - # Get the cell barcodes. - cell_barcodes = umi_count_order[:n_cells] + assert total_droplet_barcodes - n_cells > 0, \ + f"The number of cells is {n_cells}, but the " \ + f"number of total droplets included is " \ + f"{total_droplet_barcodes}. Increase " \ + f"--total_droplet_barcodes above {n_cells}, or " \ + f"specify a different number of expected cells using " \ + f"--expected-cells" # Set the low UMI count cutoff to be the greater of either # the user input value, or an empirically-derived value. - empirical_low_UMI = int(self.priors['empty_counts'] * - self.EMPIRICAL_LOW_UMI_TO_EMPTY_DROPLET_THRESHOLD) - low_UMI_count_cutoff = max(low_UMI_count_cutoff, - empirical_low_UMI) - logging.info(f"Excluding barcodes with counts below " - f"{low_UMI_count_cutoff}") + factor = consts.EMPIRICAL_LOW_UMI_TO_EMPTY_DROPLET_THRESHOLD + empirical_low_count_cutoff = int(self.priors['empty_counts'] * factor) + low_count_cutoff = max(self.low_count_threshold, empirical_low_count_cutoff) + self.low_count_cutoff = low_count_cutoff + logger.info(f"Excluding barcodes with counts below {low_count_cutoff}") # See how many barcodes there are to work with total. - num_barcodes_above_umi_cutoff = \ - np.sum(umi_counts > low_UMI_count_cutoff).item() + num_barcodes_above_umi_cutoff = np.sum(umi_counts > low_count_cutoff).item() assert num_barcodes_above_umi_cutoff > 0, \ f"There are no barcodes with UMI counts over the lower " \ - f"cutoff of {low_UMI_count_cutoff}" + f"cutoff of {low_count_cutoff}" assert num_barcodes_above_umi_cutoff > n_cells, \ f"There are no empty droplets with UMI counts over the lower " \ - f"cutoff of {low_UMI_count_cutoff}. Some empty droplets are " \ + f"cutoff of {low_count_cutoff}. Some empty droplets are " \ f"necessary for the analysis. Reduce the " \ f"--low-count-threshold parameter." - # Get a number of transition-region barcodes. - num_transition_barcodes = (total_droplet_barcodes - - cell_barcodes.size) - - assert num_transition_barcodes > 0, \ - f"The number of cells is {cell_barcodes.size}, but the " \ - f"number of total droplets included is " \ - f"{total_droplet_barcodes}. Increase " \ - f"--total_droplet_barcodes above {cell_barcodes.size}, or " \ - f"specify a different number of expected cells using " \ - f"--expected-cells" - - num = min(num_transition_barcodes, - num_barcodes_above_umi_cutoff - cell_barcodes.size) - num = max(0, num) - transition_barcodes = umi_count_order[n_cells: - (n_cells + num)] - - assert transition_barcodes.size > 0, \ - f"There are no barcodes identified from the transition " \ - f"region between cell and empty. The intended number of " \ - f"transition barcodes was {num_transition_barcodes}. " \ - f"This indicates that the low UMI count cutoff, " \ - f"{low_UMI_count_cutoff}, was likely too high. Try to " \ - f"reduce --low-count-threshold" - # Use the cell barcodes and transition barcodes for analysis. - self.analyzed_barcode_inds = np.concatenate(( - cell_barcodes, - transition_barcodes)).astype(dtype=int) - - # Identify probable empty droplet barcodes. - if num < num_transition_barcodes: + self.analyzed_barcode_inds = umi_count_order[:total_droplet_barcodes] - # This means we already used all the barcodes. - empty_droplet_barcodes = np.array([]) - - else: - - # Decide which empty barcodes to include. - empty_droplet_sorted_barcode_inds = \ - np.arange(n_cells + num, num_barcodes_above_umi_cutoff, - dtype=int) # The entire range - empty_droplet_barcodes = \ - umi_count_order[empty_droplet_sorted_barcode_inds] - - self.empty_barcode_inds = empty_droplet_barcodes\ - .astype(dtype=int) + # Decide which empty barcodes to include. + empty_droplet_sorted_barcode_inds = \ + np.arange(total_droplet_barcodes, num_barcodes_above_umi_cutoff, + dtype=int) # The entire range + self.empty_barcode_inds = umi_count_order[empty_droplet_sorted_barcode_inds] # Find the UMI threshold for surely empty droplets. - last_analyzed_bc = min(cell_barcodes.size + transition_barcodes.size, - umi_count_order.size) - self.empty_UMI_threshold = (umi_counts[umi_count_order] - [last_analyzed_bc]) + self.empty_UMI_threshold = umi_counts[umi_count_order][total_droplet_barcodes] # Find the max UMI count for any cell. self.max_UMI_count = umi_counts.max() - logging.info(f"Using {cell_barcodes.size} probable cell " - f"barcodes, plus an additional " - f"{transition_barcodes.size} barcodes, " - f"and {empty_droplet_barcodes.size} empty " - f"droplets.") - logging.info(f"Largest surely-empty droplet has " - f"{self.empty_UMI_threshold} UMI counts.") - - if ((low_UMI_count_cutoff == self.low_count_threshold) - and (empty_droplet_barcodes.size == 0)): - logging.warning("Warning: few empty droplets identified. Low " - "UMI cutoff may be too high. Check the UMI " - "decay curve, and decrease the " - "--low-count-threshold parameter if necessary.") - - self.is_trimmed = True - - def _estimate_priors(self): - """Estimate relevant priors, populating fields in the self.priors dict. - """ - - # Estimate the log UMI count turning point between cells and 'empties'. - self.priors['log_counts_crossover'] = \ - np.mean(np.log1p([self.priors['cell_counts'], - self.priors['empty_counts']])).item() - - # TODO: overhaul estimation of d_std. add estimate of d_empty_std - - # Estimate prior for the scale param of LogNormal for d. - if self.model_name != "simple": - self.priors['d_std'] = (np.log1p(self.priors['cell_counts']) - - self.priors['log_counts_crossover']) / 5 - else: - # Use a reasonable prior in log space. - self.priors['d_std'] = self.SIMPLE_MODEL_D_STD_PRIOR - - # Priors for models that include empty droplets: - if self.model_name != "simple": - # Estimate fraction of trimmed dataset that contains cells. - # cell_prob = self.priors['n_cells'] - # / self.analyzed_barcode_inds.size - cell_prob = (1 - self.fraction_empties) \ - * (self.priors['n_cells'] - / self.analyzed_barcode_inds.size) - self.priors['cell_prob'] = cell_prob - - assert cell_prob > 0, f"Fraction of trimmed dataset " \ - f"containing cells should be > 0, " \ - f"but is {cell_prob}." - - assert cell_prob <= 1, f"Fraction of trimmed dataset " \ - f"containing cells should be at most 1, " \ - f"but is {cell_prob}." - - # Turn cell probability into logit. - self.priors['cell_logit'] = np.log(cell_prob - / (1 - cell_prob)).item() - - # Estimate the ambient gene expression profile. - self.priors['chi_ambient'], self.priors['chi_bar'] = \ - estimate_chi_ambient_from_dataset(self) - - def get_count_matrix(self) -> sp.csr.csr_matrix: + # Estimate cell logit probability prior. + cell_prob = (n_cells / total_droplet_barcodes) * (1. - self.fraction_empties) + self.priors['cell_logit'] = np.log(cell_prob) - np.log(1. - cell_prob) + + logger.info(f"Using {n_cells} probable cell " + f"barcodes, plus an additional " + f"{total_droplet_barcodes - n_cells} barcodes, " + f"and {len(self.empty_barcode_inds)} empty " + f"droplets.") + logger.info(f"Largest surely-empty droplet has " + f"{int(self.empty_UMI_threshold)} UMI counts.") + + if ((low_count_cutoff == self.low_count_threshold) + and (len(self.empty_barcode_inds) == 0)): + logger.warning("Warning: few empty droplets identified. Low " + "UMI cutoff may be too high. Check the UMI " + "decay curve, and decrease the " + "--low-count-threshold parameter if necessary.") + + def _estimate_chi_ambient(self) -> Dict[str, torch.Tensor]: + """Estimate chi_ambient and chi_bar""" + + matrix = self.data['matrix'].tocsc() + count_matrix = matrix[:, self.analyzed_gene_inds].tocsr() + umi_counts = np.array(count_matrix.sum(axis=1)).squeeze() + + # Estimate the ambient gene expression profile. + ep = np.finfo(np.float32).eps.item() # small value + empty_droplet_logic = ((umi_counts < self.priors['surely_empty_counts']) + & (umi_counts > self.low_count_cutoff)) + chi_ambient = np.array(count_matrix[empty_droplet_logic, :].sum(axis=0)).squeeze() + ep + chi_ambient = torch.tensor(chi_ambient / chi_ambient.sum()).float() + chi_bar = np.array(count_matrix.sum(axis=0)).squeeze() + ep + chi_bar = torch.tensor(chi_bar / chi_bar.sum()).float() + + return {'chi_ambient': chi_ambient, 'chi_bar': chi_bar} + + def get_count_matrix(self) -> sp.csr_matrix: """Get the count matrix, trimmed if trimming has occurred.""" - if self.is_trimmed: - - # Return the count matrix for selected barcodes and genes. - trimmed_bc_matrix = self.data['matrix'][self.analyzed_barcode_inds, - :].tocsc() - trimmed_matrix = trimmed_bc_matrix[:, self.analyzed_gene_inds].tocsr() - return trimmed_matrix + # Return the count matrix for selected barcodes and genes. + trimmed_bc_matrix = self.data['matrix'][self.analyzed_barcode_inds, + :].tocsc() + trimmed_matrix = trimmed_bc_matrix[:, self.analyzed_gene_inds].tocsr() + return trimmed_matrix - else: - logging.warning("Using full count matrix, without any trimming. " - "Could be slow.") - return self.data['matrix'] - - def get_count_matrix_empties(self) -> sp.csr.csr_matrix: + def get_count_matrix_empties(self) -> sp.csr_matrix: """Get the count matrix for empty drops, trimmed if possible.""" - if self.is_trimmed: - - # Return the count matrix for selected barcodes and genes. - trimmed_bc_matrix = self.data['matrix'][self.empty_barcode_inds, - :].tocsc() - trimmed_matrix = trimmed_bc_matrix[:, self.analyzed_gene_inds].tocsr() - return trimmed_matrix - - else: - logging.error("Trying to get empty count matrix without " - "trimmed data.") - return self.data['matrix'] + # Return the count matrix for selected barcodes and genes. + trimmed_bc_matrix = self.data['matrix'][self.empty_barcode_inds, + :].tocsc() + trimmed_matrix = trimmed_bc_matrix[:, self.analyzed_gene_inds].tocsr() + return trimmed_matrix - def get_count_matrix_all_barcodes(self) -> sp.csr.csr_matrix: + def get_count_matrix_all_barcodes(self) -> sp.csr_matrix: """Get the count matrix, trimming only genes, not barcodes.""" - if self.is_trimmed: - - # Return the count matrix for selected barcodes and genes. - trimmed_bc_matrix = self.data['matrix'].tocsc() - trimmed_matrix = trimmed_bc_matrix[:, self.analyzed_gene_inds].tocsr() - return trimmed_matrix - - else: - logging.warning("Using full count matrix, without any trimming. " - "Could be slow.") - return self.data['matrix'] + # Return the count matrix for selected barcodes and genes. + trimmed_bc_matrix = self.data['matrix'].tocsc() + trimmed_matrix = trimmed_bc_matrix[:, self.analyzed_gene_inds].tocsr() + return trimmed_matrix def get_dataloader(self, use_cuda: bool = True, batch_size: int = 200, shuffle: bool = False, - analyzed_bcs_only: bool = True) -> DataLoader: + analyzed_bcs_only: bool = True, + sort_by: Optional[Callable[[sp.csr_matrix], float]] = None, + ) -> DataLoader: """Return a dataloader for the count matrix. Args: @@ -463,6 +459,10 @@ def get_dataloader(self, shuffle: Whether dataloader should shuffle the data. analyzed_bcs_only: Only include the barcodes that have been analyzed, not the surely empty droplets. + sort_by: Lambda function which, when applied to the sparse matrix, + will return values that can be sorted to give a sort order to + the dataset. Dataloader will load data in order of increasing + values. Returns: data_loader: A dataloader that yields the entire dataset in batches. @@ -474,1083 +474,66 @@ def get_dataloader(self, else: count_matrix = self.get_count_matrix_all_barcodes() - return DataLoader(count_matrix, - empty_drop_dataset=None, - batch_size=batch_size, - fraction_empties=0., - shuffle=shuffle, - use_cuda=use_cuda) - - def save_to_output_file( + data_loader = DataLoader( + count_matrix, + empty_drop_dataset=None, + batch_size=batch_size, + fraction_empties=0., + shuffle=shuffle, + sort_by=sort_by, + use_cuda=use_cuda, + ) + return data_loader + + def restore_eliminated_features_in_cells( self, - output_file: str, - inferred_model: 'RemoveBackgroundPyroModel', - posterior_batch_size: int, - cells_posterior_reg_calc: int, - save_plots: bool = False) -> bool: - """Write the results of an inference procedure to an output file. - - Output is an HDF5 file. To be written: - Inferred ambient-subtracted UMI count matrix. - Inferred probabilities that each barcode contains a real cell. - Inferred cell size scale factors. - Inferred ambient gene expression count vector for droplets without - cells. - Inferred contamination fraction hyperparameters. - Embeddings of gene expression of cells into a low-dimensional latent - space. + inferred_count_matrix: sp.csc_matrix, + cell_probabilities_analyzed_bcs: np.ndarray + ) -> sp.csc_matrix: + """Add the data back in for any features not used during inference, + (the used features being defined in self.analyzed_gene_inds), + so that the output for these features exactly matches the input. Args: - inferred_model: RemoveBackgroundPyroModel which has - already had the inference procedure run. - output_file: Name of output .h5 file - save_plots: Setting this to True will save plots of outputs. + inferred_count_matrix: A sparse count matrix + cell_probabilities_analyzed_bcs: Cell probabilities for the subset of + barcodes that were analyzed. Returns: - True if the output was written to file successfully. + output: A sparse count matrix, with the unused feature values filled + in with the raw data. """ - logging.info("Preparing to write outputs to file...") - - # Create posterior. - self.posterior = ProbPosterior(dataset_obj=self, - vi_model=inferred_model, - fpr=self.fpr[0], - batch_size=posterior_batch_size, - cells_posterior_reg_calc=cells_posterior_reg_calc) - - # Encoded values of latent variables. - enc = self.posterior.latents - z = enc['z'] - d = enc['d'] - p = enc['p'] - epsilon = enc['epsilon'] - phi_params = enc['phi_loc_scale'] - - # Estimate the ambient-background-subtracted UMI count matrix. - if self.model_name != "simple": - - inferred_count_matrix = self.posterior.mean - - else: - - # No need to generate a new count matrix for simple model. - inferred_count_matrix = self.data['matrix'].tocsc() - logging.info("Simple model: outputting un-altered count matrix.") - - # Inferred ambient gene expression vector. - ambient_expression_trimmed = cellbender.remove_background.model.\ - get_ambient_expression() - - # Convert the indices from trimmed gene set to original gene indices. - ambient_expression = np.zeros(self.data['matrix'].shape[1]) - ambient_expression[self.analyzed_gene_inds] = ambient_expression_trimmed - - # Figure out the indices of barcodes that have cells. - if p is not None: - p[np.isnan(p)] = 0. - cell_barcode_inds = self.analyzed_barcode_inds - if np.sum(p > 0.5) == 0: - logging.warning("Warning: Found no cells!") - filtered_inds_of_analyzed_barcodes = p > self.CELL_PROB_CUTOFF - else: - cell_barcode_inds = self.analyzed_barcode_inds - filtered_inds_of_analyzed_barcodes = np.arange(0, d.size) - - # CellRanger version (format output like input). - if self._detect_input_data_type() == 'cellranger_h5': - cellranger_version = detect_cellranger_version_h5(self.input_file) - elif self._detect_input_data_type() == 'anndata': - # Arbitrarily peg output format for anndata inputs to be CellRanger v3 format - cellranger_version = 3 - else: - cellranger_version = detect_cellranger_version_mtx(self.input_file) - - # Write to output file, for each lambda specified by user. - if len(self.fpr) == 1: - write_succeeded = write_matrix_to_cellranger_h5( - cellranger_version=cellranger_version, - output_file=output_file, - gene_names=self.data['gene_names'], - gene_ids=self.data['gene_ids'], - feature_types=self.data['feature_types'], - genomes=self.data['genomes'], - barcodes=self.data['barcodes'], - inferred_count_matrix=inferred_count_matrix, - cell_barcode_inds=cell_barcode_inds, - ambient_expression=ambient_expression, - z=z, d=d, p=p, phi=phi_params, epsilon=epsilon, - rho=cellbender.remove_background.model.get_rho(), - fpr=self.fpr[0], - lambda_multiplier=self.posterior.lambda_multiplier, - loss=inferred_model.loss) - - # Generate filename for filtered matrix output. - file_dir, file_base = os.path.split(output_file) - file_name = os.path.splitext(os.path.basename(file_base))[0] - filtered_output_file = os.path.join(file_dir, file_name + "_filtered.h5") - - # Write filtered matrix (cells only) to output file. - if self.model_name != "simple": - cell_barcode_inds = \ - self.analyzed_barcode_inds[filtered_inds_of_analyzed_barcodes] - - cell_barcodes = self.data['barcodes'][cell_barcode_inds] - - write_matrix_to_cellranger_h5( - cellranger_version=cellranger_version, - output_file=filtered_output_file, - gene_names=self.data['gene_names'], - gene_ids=self.data['gene_ids'], - feature_types=self.data['feature_types'], - genomes=self.data['genomes'], - barcodes=cell_barcodes, - inferred_count_matrix=inferred_count_matrix[cell_barcode_inds, :], - cell_barcode_inds=None, - ambient_expression=ambient_expression, - z=z[filtered_inds_of_analyzed_barcodes, :], - d=d[filtered_inds_of_analyzed_barcodes], - p=p[filtered_inds_of_analyzed_barcodes], - phi=phi_params, - epsilon=epsilon[filtered_inds_of_analyzed_barcodes], - rho=cellbender.remove_background.model.get_rho(), - fpr=self.fpr[0], - lambda_multiplier=self.posterior.lambda_multiplier, - loss=inferred_model.loss) - - else: - - file_dir, file_base = os.path.split(output_file) - file_name = os.path.splitext(os.path.basename(file_base))[0] - - for i, fpr in enumerate(self.fpr): - - if i > 0: # first FPR has already been computed - - # Re-compute posterior counts for each new lambda. - self.posterior.fpr = fpr # reach in and change the FPR - self.posterior._get_mean() # force re-computation of posterior - inferred_count_matrix = self.posterior.mean - - # Create an output filename for this lambda value. - temp_output_filename = os.path.join(file_dir, file_name + f"_FPR_{fpr}.h5") - - write_succeeded = write_matrix_to_cellranger_h5( - cellranger_version=cellranger_version, - output_file=temp_output_filename, - gene_names=self.data['gene_names'], - gene_ids=self.data['gene_ids'], - feature_types=self.data['feature_types'], - genomes=self.data['genomes'], - barcodes=self.data['barcodes'], - inferred_count_matrix=inferred_count_matrix, - cell_barcode_inds=self.analyzed_barcode_inds, - ambient_expression=ambient_expression, - z=z, d=d, p=p, phi=phi_params, epsilon=epsilon, - rho=cellbender.remove_background.model.get_rho(), - fpr=fpr, - lambda_multiplier=self.posterior.lambda_multiplier, - loss=inferred_model.loss) - - # Generate filename for filtered matrix output. - filtered_output_file = os.path.join(file_dir, file_name + f"_FPR_{fpr}_filtered.h5") - - # Write filtered matrix (cells only) to output file. - if self.model_name != "simple": - cell_barcode_inds = \ - self.analyzed_barcode_inds[filtered_inds_of_analyzed_barcodes] - - cell_barcodes = self.data['barcodes'][cell_barcode_inds] - - write_matrix_to_cellranger_h5( - cellranger_version=cellranger_version, - output_file=filtered_output_file, - gene_names=self.data['gene_names'], - gene_ids=self.data['gene_ids'], - feature_types=self.data['feature_types'], - genomes=self.data['genomes'], - barcodes=cell_barcodes, - inferred_count_matrix=inferred_count_matrix[cell_barcode_inds, :], - cell_barcode_inds=None, - ambient_expression=ambient_expression, - z=z[filtered_inds_of_analyzed_barcodes, :], - d=d[filtered_inds_of_analyzed_barcodes], - p=p[filtered_inds_of_analyzed_barcodes], - phi=phi_params, - epsilon=epsilon[filtered_inds_of_analyzed_barcodes], - rho=cellbender.remove_background.model.get_rho(), - fpr=fpr, - lambda_multiplier=self.posterior.lambda_multiplier, - loss=inferred_model.loss) - - # Save barcodes determined to contain cells as _cell_barcodes.csv - try: - barcode_names = np.array([str(cell_barcodes[i], - encoding='UTF-8') - for i in range(cell_barcodes.size)]) - except UnicodeDecodeError: - # necessary if barcodes are ints - barcode_names = cell_barcodes - except TypeError: - # necessary if barcodes are already decoded - barcode_names = cell_barcodes - bc_file_name = os.path.join(file_dir, - file_name + "_cell_barcodes.csv") - np.savetxt(bc_file_name, barcode_names, delimiter=',', fmt='%s') - logging.info(f"Saved cell barcodes in {bc_file_name}") - - try: - # Save plots, if called for. - if save_plots: - plt.figure(figsize=(6, 18)) - - # Plot the train error. - plt.subplot(3, 1, 1) - plt.plot(inferred_model.loss['train']['elbo'], '.--', - label='Train') - - # Plot the test error, if there was held-out test data. - if 'test' in inferred_model.loss.keys(): - if len(inferred_model.loss['test']['epoch']) > 0: - plt.plot(inferred_model.loss['test']['epoch'], - inferred_model.loss['test']['elbo'], 'o:', - label='Test') - plt.legend() - - plt.gca().set_ylim(bottom=max(inferred_model.loss['train'] - ['elbo'][0], - inferred_model.loss['train'] - ['elbo'][-1] - 2000)) - plt.xlabel('Epoch') - plt.ylabel('ELBO') - plt.title('Progress of the training procedure') - - # Plot the barcodes used, along with the inferred - # cell probabilities. - plt.subplot(3, 1, 2) - count_mat = self.get_count_matrix() - counts = np.array(count_mat.sum(axis=1)).squeeze() - count_order = np.argsort(counts)[::-1] - plt.semilogy(counts[count_order], color='black') - plt.ylabel('UMI counts') - plt.xlabel('Barcode index, sorted by UMI count') - if p is not None: # The case of a simple model. - plt.gca().twinx() - plt.plot(p[count_order], '.:', color='red', alpha=0.3) - plt.ylabel('Cell probability', color='red') - plt.ylim([-0.05, 1.05]) - plt.title('Determination of which barcodes contain cells') - else: - plt.title('The subset of barcodes used for training') - - # Plot the latent encoding via PCA. - plt.subplot(3, 1, 3) - pca = PCA(n_components=2) - if p is None: - p = np.ones_like(d) - z_pca = pca.fit_transform(z[p >= 0.5]) - plt.plot(z_pca[:, 0], z_pca[:, 1], - '.', ms=3, color='black', alpha=0.3) - plt.ylabel('PC 1') - plt.xlabel('PC 0') - plt.title('PCA of latent encoding of cell gene expression') - - file_dir, file_base = os.path.split(output_file) - file_name = os.path.splitext(os.path.basename(file_base))[0] - fig_name = os.path.join(file_dir, file_name + ".pdf") - plt.savefig(fig_name, bbox_inches='tight', format='pdf') - logging.info(f"Saved summary plots as {fig_name}") - - except Exception: - logging.warning("Unable to save plot.") - - return write_succeeded - - -def detect_cellranger_version_mtx(filedir: str) -> int: - """Detect which version of CellRanger (2 or 3) created this mtx directory. - - Args: - filedir: string path to .mtx file that contains the raw gene - barcode matrix in a sparse coo text format. - - Returns: - CellRanger version, either 2 or 3, as an integer. - - """ - - assert os.path.isdir(filedir), f"The directory {filedir} is not accessible." - - if os.path.isfile(os.path.join(filedir, 'features.tsv.gz')): - return 3 - - else: - return 2 - - -def get_matrix_from_cellranger_mtx(filedir: str) \ - -> Dict[str, Union[sp.csr.csr_matrix, List[np.ndarray], np.ndarray]]: - """Load a count matrix from an mtx directory from CellRanger's output. - - For CellRanger v2: - The directory must contain three files: - matrix.mtx - barcodes.tsv - genes.tsv - - For CellRanger v3: - The directory must contain three files: - matrix.mtx.gz - barcodes.tsv.gz - features.tsv.gz - - This function returns a dictionary that includes the count matrix, the gene - names (which correspond to columns of the count matrix), and the barcodes - (which correspond to rows of the count matrix). - - Args: - filedir: string path to .mtx file that contains the raw gene - barcode matrix in a sparse coo text format. - - Returns: - out['matrix']: scipy.sparse.csr.csr_matrix of unique UMI counts, with - barcodes as rows and genes as columns - out['barcodes']: numpy array of strings which are the nucleotide - sequences of the barcodes that correspond to the rows in - the out['matrix'] - out['gene_names']: List of numpy arrays, where the number of elements - in the list is the number of genomes in the dataset. Each numpy - array contains the string names of genes in the genome, which - correspond to the columns in the out['matrix']. - out['gene_ids']: List of numpy arrays, where the number of elements - in the list is the number of genomes in the dataset. Each numpy - array contains the string Ensembl ID of genes in the genome, which - also correspond to the columns in the out['matrix']. - out['feature_types']: List of numpy arrays, where the number of elements - in the list is the number of genomes in the dataset. Each numpy - array contains the string feature types of genes (or possibly - antibody capture reads), which also correspond to the columns - in the out['matrix']. - - """ - - assert os.path.isdir(filedir), "The directory {filedir} is not accessible." - - # Decide whether data is CellRanger v2 or v3. - cellranger_version = detect_cellranger_version_mtx(filedir=filedir) - logging.info(f"CellRanger v{cellranger_version} format") - - # CellRanger version 3 - if cellranger_version == 3: - - matrix_file = os.path.join(filedir, 'matrix.mtx.gz') - gene_file = os.path.join(filedir, 'features.tsv.gz') - barcode_file = os.path.join(filedir, 'barcodes.tsv.gz') - - # Read in feature names. - features = np.genfromtxt(fname=gene_file, - delimiter="\t", skip_header=0, - dtype='<U100') - - # Read in gene expression and feature data. - gene_ids = features[:, 0].squeeze() # first column - gene_names = features[:, 1].squeeze() # second column - feature_types = features[:, 2].squeeze() # third column - - # CellRanger version 2 - elif cellranger_version == 2: - - # Read in the count matrix using scipy. - matrix_file = os.path.join(filedir, 'matrix.mtx') - gene_file = os.path.join(filedir, "genes.tsv") - barcode_file = os.path.join(filedir, "barcodes.tsv") - - # Read in gene names. - gene_data = np.genfromtxt(fname=gene_file, - delimiter="\t", skip_header=0, - dtype='<U100') - if len(gene_data.shape) == 1: # custom file format with just gene names - gene_names = gene_data.squeeze() - gene_ids = None - else: # the 10x CellRanger v2 format with two columns - gene_names = gene_data[:, 1].squeeze() # second column - gene_ids = gene_data[:, 0].squeeze() # first column - feature_types = None - - else: - raise NotImplementedError('MTX format was not identifiable as CellRanger ' - 'v2 or v3. Please check 10x Genomics formatting.') - - # For both versions: - - # Read in sparse count matrix. - count_matrix = io.mmread(matrix_file).tocsr().transpose() - - # Read in barcode names. - barcodes = np.genfromtxt(fname=barcode_file, - delimiter="\t", skip_header=0, dtype='<U20') - - # Issue warnings if necessary, based on dimensions matching. - if count_matrix.shape[1] != len(gene_names): - logging.warning(f"Number of gene names in {filedir}/genes.tsv " - f"does not match the number expected from the " - f"count matrix.") - if count_matrix.shape[0] != len(barcodes): - logging.warning(f"Number of barcodes in {filedir}/barcodes.tsv " - f"does not match the number expected from the " - f"count matrix.") - - return {'matrix': count_matrix, - 'gene_names': gene_names, - 'feature_types': feature_types, - 'gene_ids': gene_ids, - 'genomes': None, # TODO: check if this info is available in either version - 'barcodes': barcodes} - - -def detect_cellranger_version_h5(filename: str) -> int: - """Detect which version of CellRanger (2 or 3) created this h5 file. - - Args: - filename: string path to .mtx file that contains the raw gene - barcode matrix in a sparse coo text format. - - Returns: - version: CellRanger version, either 2 or 3, as an integer. - - """ - - with tables.open_file(filename, 'r') as f: - - # For CellRanger v2, each group in the table (other than root) - # contains a genome. - # For CellRanger v3, there is a 'matrix' group that contains 'features'. - - version = 2 - - try: - - # This works for version 3 but not for version 2. - getattr(f.root.matrix, 'features') - version = 3 - - except tables.NoSuchNodeError: - pass - - return version - - -def get_matrix_from_cellranger_h5(filename: str) \ - -> Dict[str, Union[sp.csr.csr_matrix, List[np.ndarray], np.ndarray]]: - """Load a count matrix from an h5 file from CellRanger's output. - - The file needs to be a _raw_gene_bc_matrices_h5.h5 file. This function - returns a dictionary that includes the count matrix, the gene names (which - correspond to columns of the count matrix), and the barcodes (which - correspond to rows of the count matrix). - - This function works for CellRanger v2 and v3 HDF5 formats. - - Args: - filename: string path to .h5 file that contains the raw gene - barcode matrices - - Returns: - out['matrix']: scipy.sparse.csr.csr_matrix of unique UMI counts, with - barcodes as rows and genes as columns - out['barcodes']: numpy array of strings which are the nucleotide - sequences of the barcodes that correspond to the rows in - the out['matrix'] - out['gene_names']: List of numpy arrays, where the number of elements - in the list is the number of genomes in the dataset. Each numpy - array contains the string names of genes in the genome, which - correspond to the columns in the out['matrix']. - out['gene_ids']: List of numpy arrays, where the number of elements - in the list is the number of genomes in the dataset. Each numpy - array contains the string Ensembl ID of genes in the genome, which - also correspond to the columns in the out['matrix']. - out['feature_types']: List of numpy arrays, where the number of elements - in the list is the number of genomes in the dataset. Each numpy - array contains the string feature types of genes (or possibly - antibody capture reads), which also correspond to the columns - in the out['matrix']. - - """ - - # Detect CellRanger version. - cellranger_version = detect_cellranger_version_h5(filename=filename) - logging.info(f"CellRanger v{cellranger_version} format") - - with tables.open_file(filename, 'r') as f: - # Initialize empty lists. - csc_list = [] - barcodes = None - feature_ids = None - feature_types = None - genomes = None - - # CellRanger v2: - # Each group in the table (other than root) contains a genome, - # so walk through the groups to get data for each genome. - if cellranger_version == 2: - - feature_names = [] - feature_ids = [] - - for group in f.walk_groups(): - try: - # Read in data for this genome, and put it into a - # scipy.sparse.csc.csc_matrix - barcodes = getattr(group, 'barcodes').read() - data = getattr(group, 'data').read() - indices = getattr(group, 'indices').read() - indptr = getattr(group, 'indptr').read() - shape = getattr(group, 'shape').read() - csc_list.append(sp.csc_matrix((data, indices, indptr), - shape=shape)) - feature_names.extend(getattr(group, 'gene_names').read()) - feature_ids.extend(getattr(group, 'genes').read()) - - except tables.NoSuchNodeError: - # This exists to bypass the root node, which has no data. - pass - - # Create numpy arrays. - feature_names = np.array(feature_names) - if len(feature_ids) > 0: - feature_ids = np.array(feature_ids) - else: - feature_ids = None - - # CellRanger v3: - # There is only the 'matrix' group. - elif cellranger_version == 3: - - # Read in data for this genome, and put it into a - # scipy.sparse.csc.csc_matrix - barcodes = getattr(f.root.matrix, 'barcodes').read() - data = getattr(f.root.matrix, 'data').read() - indices = getattr(f.root.matrix, 'indices').read() - indptr = getattr(f.root.matrix, 'indptr').read() - shape = getattr(f.root.matrix, 'shape').read() - csc_list.append(sp.csc_matrix((data, indices, indptr), - shape=shape)) - - # Read in 'feature' information - feature_group = f.get_node(f.root.matrix, 'features') - feature_names = getattr(feature_group, 'name').read() - - try: - feature_types = getattr(feature_group, 'feature_type').read() - except tables.NoSuchNodeError: - # This exists in case someone produced a file without feature_type. - pass - try: - feature_ids = getattr(feature_group, 'id').read() - except tables.NoSuchNodeError: - # This exists in case someone produced a file without feature id. - pass - try: - genomes = getattr(feature_group, 'genome').read() - except tables.NoSuchNodeError: - # This exists in case someone produced a file without feature genome. - pass - - # Put the data together (possibly from several genomes for v2 datasets). - count_matrix = sp.vstack(csc_list, format='csc') - count_matrix = count_matrix.transpose().tocsr() - - # Issue warnings if necessary, based on dimensions matching. - if count_matrix.shape[1] != feature_names.size: - logging.warning(f"Number of gene names ({feature_names.size}) in {filename} " - f"does not match the number expected from the count " - f"matrix ({count_matrix.shape[1]}).") - if count_matrix.shape[0] != barcodes.size: - logging.warning(f"Number of barcodes ({barcodes.size}) in {filename} " - f"does not match the number expected from the count " - f"matrix ({count_matrix.shape[0]}).") - - return {'matrix': count_matrix, - 'gene_names': feature_names, - 'gene_ids': feature_ids, - 'genomes': genomes, - 'feature_types': feature_types, - 'barcodes': barcodes} - - -def get_matrix_from_anndata(filename: str) \ - -> Dict[str, Union[sp.csr.csr_matrix, List[np.ndarray], np.ndarray]]: - """Load a count matrix from an h5ad AnnData file. - - The file needs to contain raw counts for all measured barcodes in the - `.X` attribute or a `.layer[{'counts', 'spliced'}]` attribute. This function - returns a dictionary that includes the count matrix, the gene names (which - correspond to columns of the count matrix), and the barcodes (which - correspond to rows of the count matrix). - - This function works for any AnnData object meeting the above requirements, - as generated by alignment methods like `kallisto | bustools`. - - Args: - filename: string path to .h5ad file that contains the raw gene - barcode matrices - - Returns: - out['matrix']: scipy.sparse.csr.csr_matrix of unique UMI counts, with - barcodes as rows and genes as columns - out['barcodes']: numpy array of strings which are the nucleotide - sequences of the barcodes that correspond to the rows in - the out['matrix'] - out['gene_names']: List of numpy arrays, where the number of elements - in the list is the number of genomes in the dataset. Each numpy - array contains the string names of genes in the genome, which - correspond to the columns in the out['matrix']. - out['gene_ids']: List of numpy arrays, where the number of elements - in the list is the number of genomes in the dataset. Each numpy - array contains the string Ensembl ID of genes in the genome, which - also correspond to the columns in the out['matrix']. - out['feature_types']: List of numpy arrays, where the number of elements - in the list is the number of genomes in the dataset. Each numpy - array contains the string feature types of genes (or possibly - antibody capture reads), which also correspond to the columns - in the out['matrix']. - - """ - logging.info(f"Detected AnnData format") - - adata = anndata.read_h5ad(filename) - - if "counts" in adata.layers.keys(): - # this is a common manual setting for users of scVI - # given the manual convention, we prefer this matrix to - # .X since it is less likely to represent something other - # than counts - logging.info("Found `.layers['counts']`. Using for count data.") - count_matrix = adata.layers["counts"] - elif "spliced" in adata.layers.keys() and adata.X is None: - # alignment using kallisto | bustools with intronic counts - # does not populate `.X` by default, but does populate - # `.layers['spliced'], .layers['unspliced']`. - # we use spliced counts for analysis - logging.info("Found `.layers['spliced']`. Using for count data.") - count_matrix = adata.layers["spliced"] - else: - logging.info("Using `.X` for count data.") - count_matrix = adata.X - - # check that `count_matrix` contains a large number of barcodes, - # consistent with a raw single cell experiment - if count_matrix.shape[0] < consts.MINIMUM_BARCODES_H5AD: - # this experiment might be prefiltered - msg = f"Only {count_matrix.shape[0]} barcodes were found.\n" - msg += "This suggests the matrix was prefiltered.\n" - msg += "CellBender requires a raw, unfiltered [Barcodes, Genes] matrix." - logging.warning(msg) - - # AnnData is [Cells, Genes], no need to transpose - # we typecast explicitly in the off chance `count_matrix` was dense. - count_matrix = sp.csr_matrix(count_matrix) - # feature names and ids are not consistently delineated in AnnData objects - # so we attempt to find relevant features using common values. - feature_names = np.array(adata.var_names, dtype=str) - barcodes = np.array(adata.obs_names, dtype=str) - - # Make an attempt to find feature_IDs if they are present. - feature_ids = None - if 'gene_ids' in adata.var.keys(): - feature_ids = np.array(adata.var['gene_ids'].values, dtype=str) - elif 'gene_id' in adata.var.keys(): - feature_ids = np.array(adata.var['gene_id'].values, dtype=str) - - # Make an attempt to find feature_types if they are present. - feature_types = None - if 'feature_types' in adata.var.keys(): - feature_types = np.array(adata.var['feature_types'].values, dtype=str) - elif 'feature_type' in adata.var.keys(): - feature_types = np.array(adata.var['feature_type'].values, dtype=str) - - # Make an attempt to find genomes if they are present. - genomes = None - if 'genomes' in adata.var.keys(): - genomes = np.array(adata.var['genomes'].values, dtype=str) - elif 'genome' in adata.var.keys(): - genomes = np.array(adata.var['genome'].values, dtype=str) - - # Issue warnings if necessary, based on dimensions matching. - if count_matrix.shape[1] != feature_names.size: - logging.warning(f"Number of gene names ({feature_names.size}) in {filename} " - f"does not match the number expected from the count " - f"matrix ({count_matrix.shape[1]}).") - if count_matrix.shape[0] != barcodes.size: - logging.warning(f"Number of barcodes ({barcodes.size}) in {filename} " - f"does not match the number expected from the count " - f"matrix ({count_matrix.shape[0]}).") - - return {'matrix': count_matrix, - 'gene_names': feature_names, - 'gene_ids': feature_ids, - 'genomes': genomes, - 'feature_types': feature_types, - 'barcodes': barcodes} - - -def write_matrix_to_cellranger_h5( - cellranger_version: int, - output_file: str, - gene_names: np.ndarray, - barcodes: np.ndarray, - inferred_count_matrix: sp.csc.csc_matrix, - feature_types: Optional[np.ndarray] = None, - gene_ids: Optional[np.ndarray] = None, - genomes: Optional[np.ndarray] = None, - cell_barcode_inds: Optional[np.ndarray] = None, - ambient_expression: Optional[np.ndarray] = None, - rho: Optional[np.ndarray] = None, - z: Optional[np.ndarray] = None, - d: Optional[np.ndarray] = None, - p: Optional[np.ndarray] = None, - phi: Optional[np.ndarray] = None, - epsilon: Optional[np.ndarray] = None, - fpr: Optional[float] = None, - lambda_multiplier: Optional[float] = None, - loss: Optional[Dict] = None) -> bool: - """Write count matrix data to output HDF5 file using CellRanger format. - - Args: - cellranger_version: Either 2 or 3. Determines the format of the output - h5 file. - output_file: Path to output .h5 file (e.g., 'output.h5'). - gene_names: Name of each gene (column of count matrix). - gene_ids: Ensembl ID of each gene (column of count matrix). - genomes: Name of the genome that each gene comes from. - feature_types: Type of each feature (column of count matrix). - barcodes: Name of each barcode (row of count matrix). - inferred_count_matrix: Count matrix to be written to file, in sparse - format. Rows are barcodes, columns are genes. - cell_barcode_inds: Indices into the original cell barcode array that - were found to contain cells. - ambient_expression: Vector of gene expression of the ambient RNA - background counts that contaminate cell counts. - rho: Hyperparameters for the contamination fraction distribution. - epsilon: Latent encoding of droplet RT efficiency. - z: Latent encoding of gene expression. - d: Latent cell size scale factor. - p: Latent probability that a barcode contains a cell. - phi: Latent global overdispersion mean and scale. - fpr: Target false positive rate for the regularized posterior denoised - counts, where false positives are true counts that are (erroneously) - removed. - lambda_multiplier: The lambda multiplier value used to achieve the - targeted false positive rate. - loss: Training and test error, as ELBO, for each epoch. - - Note: - To match the CellRanger .h5 files, the matrix is stored as its - transpose, with rows as genes and cell barcodes as columns. - - """ - - assert isinstance(inferred_count_matrix, - sp.csc_matrix), "The count matrix must be csc_matrix " \ - "format in order to write to HDF5." - - assert gene_names.size == inferred_count_matrix.shape[1], \ - "The number of gene names must match the number of columns in the " \ - "count matrix." - - if gene_ids is not None: - assert gene_names.size == gene_ids.size, \ - f"The number of gene_names {gene_names.shape} must match " \ - f"the number of gene_ids {gene_ids.shape}." - - if feature_types is not None: - assert gene_names.size == feature_types.size, \ - f"The number of gene_names {gene_names.shape} must match " \ - f"the number of feature_types {feature_types.shape}." - - if genomes is not None: - assert gene_names.size == genomes.size, \ - "The number of gene_names must match the number of genome designations." - - assert barcodes.size == inferred_count_matrix.shape[0], \ - "The number of barcodes must match the number of rows in the count" \ - "matrix." - - # This reverses the role of rows and columns, to match CellRanger format. - inferred_count_matrix = inferred_count_matrix.transpose().tocsc() - - # Write to output file. - try: - with tables.open_file(output_file, "w", - title="CellBender remove-background output") as f: - - if cellranger_version == 2: - - # Create the group where data will be stored. - group = f.create_group("/", "background_removed", - "Counts after background correction") - - # Create arrays within that group for gene info. - f.create_array(group, "gene_names", gene_names) - if gene_ids is not None: - f.create_array(group, "genes", gene_ids) - - elif cellranger_version == 3: - - # Create the group where data will be stored: name is "matrix". - group = f.create_group("/", "matrix", - "Counts after background correction") - - # Create a sub-group called "features" - feature_group = f.create_group(group, "features", - "Genes and other features measured") - - # Create arrays within that group for feature info. - f.create_array(feature_group, "name", gene_names) - if gene_ids is not None: - f.create_array(feature_group, "id", gene_ids) - if feature_types is not None: - f.create_array(feature_group, "feature_type", feature_types) - if genomes is not None: - f.create_array(feature_group, "genome", genomes) - - # Copy the other extraneous information from the input file. - # (Some user might need it for some reason.) - # TODO - - else: - raise NotImplementedError(f'Trying to save to CellRanger ' - f'v{cellranger_version} format, which ' - f'is not implemented.') - - # Code for both versions. - f.create_array(group, "barcodes", barcodes) - - # Create arrays to store the count data. - f.create_array(group, "data", inferred_count_matrix.data) - f.create_array(group, "indices", inferred_count_matrix.indices) - f.create_array(group, "indptr", inferred_count_matrix.indptr) - f.create_array(group, "shape", inferred_count_matrix.shape) - - # Store background gene expression, barcode_inds, z, d, and p. - if cell_barcode_inds is not None: - f.create_array(group, "barcode_indices_for_latents", - cell_barcode_inds) - if ambient_expression is not None: - f.create_array(group, "ambient_expression", ambient_expression) - if z is not None: - f.create_array(group, "latent_gene_encoding", z) - if d is not None: - f.create_array(group, "latent_scale", d) - if p is not None: - f.create_array(group, "latent_cell_probability", p) - if phi is not None: - f.create_array(group, "overdispersion_mean_and_scale", phi) - if rho is not None: - f.create_array(group, "contamination_fraction_params", rho) - if epsilon is not None: - f.create_array(group, "latent_RT_efficiency", epsilon) - if fpr is not None: - f.create_array(group, "target_false_positive_rate", fpr) - if lambda_multiplier is not None: - f.create_array(group, "lambda_multiplier", lambda_multiplier) - if loss is not None: - f.create_array(group, "training_elbo_per_epoch", - np.array(loss['train']['elbo'])) - if 'test' in loss.keys(): - f.create_array(group, "test_elbo", - np.array(loss['test']['elbo'])) - f.create_array(group, "test_epoch", - np.array(loss['test']['epoch'])) - f.create_array(group, "fraction_data_used_for_testing", - 1. - consts.TRAINING_FRACTION) - - logging.info(f"Succeeded in writing CellRanger v{cellranger_version} " - f"format output to file {output_file}") - - return True - - except Exception: - logging.warning(f"Encountered an error writing output to file " - f"{output_file}. " - f"Output may be incomplete.") - - return False - - -def get_d_priors_from_dataset(dataset: SingleCellRNACountsDataset) \ - -> Tuple[float, float]: - """Compute an estimate of reasonable priors on cell size and ambient size. - - Given a dataset (scipy.sparse.csr matrix of counts where - rows are barcodes and columns are genes), and an expected - cell count, compute an estimate of reasonable priors on cell size - and ambient count size. This is done by a series of heuristics. - - Args: - dataset: Dataset object containing a matrix of unique UMI counts, - where rows are barcodes and columns are genes. - - Returns: - cell_counts: Estimated mean number of UMI counts per real cell, in - terms of transformed count data. - empty_counts: Estimated mean number of UMI counts per 'empty' - droplet, in terms of transformed count data. - - NOTE: Picks barcodes using cutoffs in untransformed count data. The output - is in terms of transformed counts. - - """ - - # Count the total unique UMIs per barcode (summing after transforming). - counts = np.array(dataset.data['matrix'] - [:, dataset.analyzed_gene_inds].sum(axis=1)).squeeze() - - # If it's a model that does not model empty droplets, the dataset is cells. - if dataset.model_name == 'simple': - - if dataset.priors['n_cells'] is None: - # No prior on number of cells. Assume all are cells. - dataset.priors['n_cells'] = int(np.sum(counts > 0).item()) - - # Sort order the cells by counts. - sort_order = np.argsort(counts)[::-1] - - # Estimate cell count by median, taking 'cells' to be largest counts. - cell_counts = int(np.median(counts[sort_order] - [:dataset.priors['n_cells']]).item()) - - empty_counts = 0 - - # Models that include both cells and empty droplets. - else: - - # Cutoff for original data. Empirical. - cut = dataset.low_count_threshold - - # Estimate the number of UMI counts in empty droplets. - - # Mode of (rounded) log counts (for counts > cut) is a robust - # empty estimator. - empty_log_counts = mode(np.round(np.log1p(counts[counts > cut]), - decimals=1))[0] - empty_counts = int(np.expm1(empty_log_counts).item()) - - # Estimate the number of UMI counts in cells. - - # Use expected cells if it is available. - if dataset.priors['n_cells'] is not None: - - # Sort order the cells by counts. - sort_order = np.argsort(counts)[::-1] - - cell_counts = int(np.median(counts[sort_order] - [:dataset.priors['n_cells']]).item()) - - else: - - # Median of log counts above 5 * empty counts is a robust - # cell estimator. - cell_log_counts = np.median(np.log1p(counts[counts > 5 * empty_counts])) - cell_counts = int(np.expm1(cell_log_counts).item()) - - logging.info(f"Prior on counts in empty droplets is {empty_counts}") - - logging.info(f"Prior on counts for cells is {cell_counts}") - - return cell_counts, empty_counts - - -def estimate_cell_count_from_dataset(dataset: SingleCellRNACountsDataset) \ - -> int: - """Compute an estimate of number of real cells in a dataset. - - Given a Dataset, compute an estimate of the number of real cells. - - Args: - dataset: Dataset object containing a matrix of unique UMI counts, - where rows are barcodes and columns are genes. - - Returns: - cell_count_est: Estimated number of real cells. - - """ - - # If it's a model that does not model empty droplets, the dataset is cells. - # NOTE: this is overridden if --expected_cells is specified. - if dataset.model_name == 'simple': - return dataset.data['matrix'].shape[0] - - # Count number of UMIs in each barcode. - counts = np.array(dataset.data['matrix'].sum(axis=1), - dtype=int).squeeze() - - # Find mid-way between cell_counts and empty_counts in log space. - midway = np.mean([np.log1p(dataset.priors['cell_counts']), - np.log1p(dataset.priors['empty_counts'])]) - umi_cutoff = np.expm1(midway) - - # Count the number of barcodes with UMI counts above the cutoff. - cell_count_est = int(np.sum(counts > umi_cutoff).item()) - - return cell_count_est - - -def estimate_chi_ambient_from_dataset(dataset: SingleCellRNACountsDataset) \ - -> Tuple[torch.Tensor, torch.Tensor]: - """Compute an estimate of ambient RNA levels. - - Given a Dataset, compute an estimate of the ambient gene expression and - compute the average gene expression. - - Args: - dataset: Dataset object containing a matrix of unique UMI counts, - where rows are barcodes and columns are genes. - - Returns: - chi_ambient_init: Estimated number of real cells. - chi_bar: Average gene expression over dataset. - - NOTE: This must be done on transformed data. - - """ - - # Ensure that an estimate of the log count crossover point between cells - # and empty droplets has already been calculated. - try: - log_crossover = dataset.priors['log_counts_crossover'] - except KeyError: - raise AssertionError("Could not find dataset parameter " - "log_counts_crossover.") - - ep = np.finfo(np.float32).eps.item() # Small value - - # Trimmed and appropriately transformed count matrix. - count_matrix = dataset.get_count_matrix() - - # Empty droplets have log counts < log_crossover. - empty_barcodes = (np.log1p(np.array(count_matrix.sum(axis=1)).squeeze()) - < log_crossover) - - # Sum gene expression for the empty droplets. - gene_expression = np.array(count_matrix[empty_barcodes, :].sum(axis=0))\ - .squeeze() - - # As a vector on a simplex. - gene_expression = gene_expression + ep - chi_ambient_init = \ - torch.Tensor(gene_expression / np.sum(gene_expression)) - - # Full count matrix, appropriately transformed. - full_count_matrix = dataset.get_count_matrix_all_barcodes() - - # Sum all gene expression. - gene_expression_total = np.array(full_count_matrix.sum(axis=0)).squeeze() - - # As a vector on a simplex. - gene_expression_total = gene_expression_total + ep - chi_bar = \ - torch.Tensor(gene_expression_total / np.sum(gene_expression_total)) - - return chi_ambient_init, chi_bar + # Rescue the raw data for ignored features. + out = overwrite_matrix_with_columns_from_another( + mat1=inferred_count_matrix, + mat2=self.data['matrix'], + column_inds=self.analyzed_gene_inds) + + # But ensure that empty droplets are empty in the output. + cell_probabilities_all_bcs = np.zeros(out.shape[0]) + cell_probabilities_all_bcs[self.analyzed_barcode_inds] = cell_probabilities_analyzed_bcs + empty_inds = np.where(cell_probabilities_all_bcs <= consts.CELL_PROB_CUTOFF)[0] + out = csr_set_rows_to_zero(csr=out.tocsr(), row_inds=empty_inds) + + return out.tocsc() + + +def get_dataset_obj(args: argparse.Namespace) -> SingleCellRNACountsDataset: + """Helper function that uses the argparse namespace""" + + return SingleCellRNACountsDataset( + input_file=args.input_file, + expected_cell_count=args.expected_cell_count, + total_droplet_barcodes=args.total_droplets, + force_cell_umi_prior=args.force_cell_umi_prior, + force_empty_umi_prior=args.force_empty_umi_prior, + fraction_empties=args.fraction_empties, + model_name=args.model, + gene_blacklist=args.blacklisted_genes, + exclude_features=args.exclude_features, + low_count_threshold=args.low_count_threshold, + ambient_counts_in_cells_low_limit=args.ambient_counts_in_cells_low_limit, + fpr=args.fpr, + ) diff --git a/cellbender/remove_background/data/extras/simulate.py b/cellbender/remove_background/data/extras/simulate.py index da6d27f1..1654c66f 100644 --- a/cellbender/remove_background/data/extras/simulate.py +++ b/cellbender/remove_background/data/extras/simulate.py @@ -1,382 +1,704 @@ -"""Simulate a basic scRNA-seq count matrix dataset, for unit tests.""" +"""Simulate a basic scRNA-seq count matrix dataset, for tests.""" + +from cellbender.remove_background.model import calculate_mu, calculate_lambda +from cellbender.remove_background.data.io import write_matrix_to_cellranger_h5 +from cellbender.remove_background.checkpoint import load_from_checkpoint import numpy as np import scipy.sparse as sp +from sklearn.cluster import DBSCAN +from sklearn.decomposition import PCA import torch -from typing import Tuple, List, Union +import pyro +import random +import matplotlib.pyplot as plt +from typing import List, Union, Dict, Optional -def simulate_dataset_without_ambient_rna( - n_cells: int = 100, - clusters: int = 1, - n_genes: int = 10000, - cells_in_clusters: Union[List[int], None] = None, - d_cell: int = 5000) -> Tuple[sp.csr.csr_matrix, - np.ndarray, - np.ndarray, - np.ndarray]: - """Simulate a dataset with ambient background RNA counts. +if torch.cuda.is_available(): + USE_CUDA = True + DEVICE = 'cuda' +else: + USE_CUDA = False + DEVICE = 'cpu' + - Empty drops have ambient RNA only, while barcodes with cells have cell RNA - plus some amount of ambient background RNA (in proportion to the sizes of - cell and droplet). +def comprehensive_random_seed(seed, use_cuda=USE_CUDA): + """Establish a base random state + https://pytorch.org/docs/stable/notes/randomness.html + """ + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + pyro.util.set_rng_seed(seed) + if use_cuda: + torch.cuda.manual_seed_all(seed) + + +def generate_sample_inferred_model_dataset( + checkpoint_file: str, + cells_of_each_type: List[int] = [100, 100, 100], + n_droplets: int = 10000, + model_type: str = 'full', + plot_pca: bool = True, + dbscan_eps: float = 0.3, + dbscan_min_samples: int = 10, + random_seed: int = 0) -> Dict[str, Union[float, np.ndarray, sp.csr_matrix]]: + """Create a sample dataset for use as 'truth' data, based on a trained checkpoint. Args: - n_cells: Number of cells. - clusters: Number of distinct cell types to simulate. - n_genes: Number of genes. - d_cell: Cell size scale factor. - cells_in_clusters: Number of cells of each cell type. If specified, - the number of ints in this list must be equal to clusters. + checkpoint_file: ckpt.tar.gz file from a remove-background run + cells_of_each_type: Number of cells of each cell type to simulate + n_droplets: Total number of droplets to simulate + model_type: The --model argument to specify remove-background's model + plot_pca: True to plot the PCA plot used to define "cell types" + dbscan_eps: Smaller makes the clusters finer - Returns: - csr_barcode_gene_synthetic: The simulated barcode by gene matrix of UMI - counts, as a scipy.sparse.csr.csr_matrix. - z: The simulated cell type identities. A numpy array of integers, one - for each barcode. The number 0 is used to denote barcodes - without a cell present. - chi: The simulated gene expression, one corresponding to each z. - Access the vector of gene expression for a given z using chi[z, :]. - d: The simulated size scale factors, one for each barcode. """ - assert d_cell > 0, "Location parameter, d_cell, of LogNormal " \ - "distribution must be greater than zero." - assert clusters > 0, "clusters must be a positive integer." - assert n_cells > 0, "n_cells must be a positive integer." - assert n_genes > 0, "n_genes must be a positive integer." - - # Figure out how many cells are in each cell cluster. - if cells_in_clusters is None: - # No user input: make equal numbers of each cell type - cells_in_clusters = np.ones(clusters) * int(n_cells / clusters) + # Input checking. + assert len(cells_of_each_type) > 0, 'cells_of_each_type must be a List of ints' + n_cell_types = len(cells_of_each_type) + + # Load a trained model from a checkpoint file. + ckpt = load_from_checkpoint( + filebase=None, + tarball_name=checkpoint_file, + to_load=['model', 'dataloader', 'param_store'], + force_device='cpu' if not torch.cuda.is_available() else None) + model = ckpt['model'] + n_genes = model.n_genes + + # Reach in and set model type. + model.model_type = model_type + + # Seed random number generators. + comprehensive_random_seed(seed=random_seed) + + # Find z values for cells. + data_loader = ckpt['train_loader'] + if torch.cuda.is_available(): + data_loader.use_cuda = True + data_loader.device = 'cuda' + model.use_cuda = True + model.device = 'cuda' else: - assert len(cells_in_clusters) == clusters, "len(cells_in_clusters) " \ - "must equal clusters." - assert sum(cells_in_clusters) == n_cells, "sum(cells_in_clusters) " \ - "must equal n_cells." - - # Initialize arrays and lists. - chi = np.zeros((clusters + 1, n_genes)) - csr_list = [] - z = [] - d = [] - - # Get chi for cell expression. - for i in range(clusters): - chi[i, :] = generate_chi(alpha=1.0, n_genes=n_genes) - csr, d_n = sample_expression_from(chi[i, :], - n=int(cells_in_clusters[i]), - d_mu=np.log(d_cell).item()) - csr_list.append(csr) - z = z + [i for _ in range(csr.shape[0])] - d = d + [j for j in d_n] - - # Package the results. - csr_barcode_gene_synthetic = sp.vstack(csr_list) - z = np.array(z) - d = np.array(d) - - # Permute the barcode order and return results. - order = np.random.permutation(z.size) - csr_barcode_gene_synthetic = csr_barcode_gene_synthetic[order, ...] - z = z[order] - d = d[order] - - return csr_barcode_gene_synthetic, z, chi, d - - -def simulate_dataset_with_ambient_rna( - n_cells: int = 150, - n_empty: int = 300, - clusters: int = 3, + data_loader.use_cuda = False + data_loader.device = 'cpu' + model.use_cuda = False + model.device = 'cpu' + z = np.zeros((len(data_loader), model.encoder['z'].output_dim)) + p = np.zeros(len(data_loader)) + chi_ambient = pyro.param('chi_ambient').detach() + for i, data in enumerate(data_loader): + enc = model.encoder(x=data, + chi_ambient=chi_ambient, + cell_prior_log=model.d_cell_loc_prior) + ind = i * data_loader.batch_size + z[ind:(ind + data.shape[0]), :] = enc['z']['loc'].detach().cpu().numpy() + p[ind:(ind + data.shape[0])] = enc['p_y'].sigmoid().detach().cpu().numpy() + z = z[p > 0.5, :] # select cells only + + # Cluster cells based on embeddings. + db = DBSCAN(eps=dbscan_eps, min_samples=dbscan_min_samples).fit(z) + core_samples_mask = np.zeros_like(db.labels_, dtype=bool) + core_samples_mask[db.core_sample_indices_] = True + labels = db.labels_ + n_clusters_ = len(set(labels)) - (1 if -1 in labels else 0) + if n_clusters_ < len(cells_of_each_type): + print(f'WARNING: DBSCAN found only {n_clusters_} clusters, but the input ' + f'cells_of_each_type dictates {len(cells_of_each_type)} cell types ' + f'are required.') + + # Show a plot. + if plot_pca: + pca = PCA(n_components=2).fit_transform(z) + for label in np.unique(labels): + if label == -1: + color = 'lightgray' + else: + color = None + plt.plot(pca[labels == label, 0], pca[labels == label, 1], + '.', color=color, label=label) + plt.title('Embedding PCA') + plt.xlabel('PCA 0') + plt.ylabel('PCA 1') + plt.legend() + plt.show() + + unique_labels = set(np.unique(labels)) - {-1} + print({label: (labels == label).sum() for label in unique_labels}) + + # Sample z values for cells of each cluster based on this posterior. + z_cluster = [] + for label, n_cells in zip(np.unique(labels)[:len(cells_of_each_type)], cells_of_each_type): + if n_cells == 0: + continue + logic = (labels == label) + z_tmp = z[logic][torch.randperm(logic.sum())][:n_cells] + while len(z_tmp) < n_cells: + z_tmp = np.concatenate((z_tmp, z[logic][torch.randperm(logic.sum())][:n_cells]), axis=0) + z_cluster.append(z_tmp[:n_cells]) + + # Account for the possibility that one cell type has zero cells (useful for selecting populations of interest) + cells_of_each_type = [c for c in cells_of_each_type if c > 0] + n_cell_types = len(cells_of_each_type) + + # Prep variables. + c_real = np.zeros((n_droplets, n_genes)) + c_bkg = np.zeros((n_droplets, n_genes)) + labels = np.zeros(n_droplets) + epsilon = np.zeros(n_droplets) + rho = np.zeros(n_droplets) + d_cell = np.zeros(n_droplets) + d_empty = np.zeros(n_droplets) + chi = np.zeros((n_cell_types, n_genes)) + d_cell_type = np.zeros(n_cell_types) + + # Sample counts from cell-containing droplets. + i = 0 + for t, (num_cells, z_chunk) in enumerate(zip(cells_of_each_type, z_cluster)): + sim = sample_from_inferred_model( + num=num_cells, + model=model, + z=torch.tensor(z_chunk).to('cuda' if torch.cuda.is_available() else 'cpu').float(), + y=torch.ones(num_cells).to('cuda' if torch.cuda.is_available() else 'cpu').float(), + ) + c_real[i:(i + num_cells), :] = sim['counts_real'] + c_bkg[i:(i + num_cells), :] = sim['counts_bkg'] + epsilon[i:(i + num_cells)] = sim['epsilon'] + rho[i:(i + num_cells)] = sim['rho'] + d_cell[i:(i + num_cells)] = sim['cell_counts'] + d_empty[i:(i + num_cells)] = sim['empty_counts'] + labels[i:(i + num_cells)] = t + 1 # label cell types with integers > 0 + chi[t, :] = sim['chi'].sum(axis=0) / sim['chi'].sum() + d_cell_type[t] = sim['cell_counts'].mean() + i = i + num_cells + + # Sample counts from empty droplets. + sim = sample_from_inferred_model( + num=n_droplets - i, + model=model, + y=torch.zeros(n_droplets - i).to('cuda' if torch.cuda.is_available() else 'cpu').float(), + ) + c_real[i:, :] = sim['counts_real'] + c_bkg[i:, :] = sim['counts_bkg'] + epsilon[i:] = sim['epsilon'] + rho[i:] = sim['rho'] + + # Get sparse matrices from dense. + counts_true = sp.csr_matrix(c_real, shape=c_real.shape, dtype=int) + counts_bkg = sp.csr_matrix(c_bkg, shape=c_bkg.shape, dtype=int) + + return {'counts_true': counts_true, + 'counts_bkg': counts_bkg, + 'barcodes': np.array([f'bc{n:06d}' for n in np.arange(n_droplets)]), + 'gene_names': model.analyzed_gene_names, + 'chi': {i + 1: chi[i, :] for i in range(chi.shape[0])}, + 'chi_ambient': chi_ambient.detach().cpu().numpy(), + 'droplet_labels': labels.astype(int), + 'd_cell': d_cell, + 'd_empty': d_empty, + 'epsilon': epsilon, + 'rho': rho, + 'cell_mean_umi': {i + 1: u for i, u in enumerate(d_cell_type)}, + 'cell_lognormal_sigma': model.d_cell_scale_prior.item(), + 'empty_mean_umi': model.d_empty_loc_prior.exp().item(), + 'empty_lognormal_sigma': model.d_empty_scale_prior.item(), + 'epsilon_param': model.epsilon_prior.item(), + 'model': [model_type]} + + +def generate_sample_dirichlet_dataset( n_genes: int = 10000, - d_cell: int = 5000, - d_empty: int = 100, - cells_in_clusters: Union[List[int], None] = None, - ambient_different: bool = False, - chi_input: Union[np.ndarray, None] = None) \ - -> Tuple[sp.csr.csr_matrix, np.ndarray, np.ndarray, np.ndarray]: - """Simulate a dataset with ambient background RNA counts. - - Empty drops have ambient RNA only, while barcodes with cells have cell - RNA plus some amount of ambient background RNA (in proportion to the - sizes of cell and droplet). - - Args: - n_cells: Number of cells. - n_empty: Number of empty droplets with only ambient RNA. - clusters: Number of distinct cell types to simulate. - n_genes: Number of genes. - d_cell: Cell size scale factor. - d_empty: Empty droplet size scale factor. - cells_in_clusters: Number of cells of each cell type. If specified, - the number of ints in this list must be equal to clusters. - ambient_different: If False, the gene expression profile of ambient - RNA is drawn from the sum of cellular gene expression. If True, - the ambient RNA expression is completely different from cellular - gene expression. - chi_input: Gene expression arrays in a matrix, with rows as clusters and - columns as genes. Expression should add to one for each row. - Setting chi=None will generate new chi randomly according to a - Dirichlet distribution. - - Returns: - csr_barcode_gene_synthetic: The simulated barcode by gene matrix of - UMI counts, as a scipy.sparse.csr.csr_matrix. - z: The simulated cell type identities. A numpy array of integers, - one for each barcode. The number 0 is used to denote barcodes - without a cell present. - chi: The simulated gene expression, one corresponding to each z. - Access the vector of gene expression for a given z using chi[z, :]. - d: The simulated size scale factors, one for each barcode. - + cells_of_each_type: List[int] = [100, 100, 100], + n_droplets: int = 5000, + model_type: str = 'full', + dirichlet_alpha: Union[float, np.ndarray] = 0.05, + chi: Optional[np.ndarray] = None, + chi_artificial_similarity: float = 0, + vector_to_add_to_chi_ambient: Optional[np.ndarray] = None, + chi_ambient: Optional[np.ndarray] = None, + cell_mean_umi: List[int] = [5000], + cell_lognormal_sigma: float = 0.2, + empty_mean_umi: int = 200, + empty_lognormal_sigma: float = 0.4, + alpha0: float = 5000, + epsilon_param: float = 100, + rho_alpha: float = 3, + rho_beta: float = 80, + random_seed: int = 0) -> Dict[str, Union[float, np.ndarray, sp.csr_matrix]]: + """Create a sample dataset for use as 'truth' data. """ - assert d_cell > 0, "Location parameter, d_cell, of LogNormal " \ - "distribution must be greater than zero." - assert d_empty > 0, "Location parameter, d_cell, of LogNormal " \ - "distribution must be greater than zero." - assert clusters > 0, "clusters must be a positive integer." - assert n_cells > 0, "n_cells must be a positive integer." - assert n_empty > 0, "n_empty must be a positive integer." - assert n_genes > 0, "n_genes must be a positive integer." - if chi_input is not None: - assert chi_input.shape[0] == clusters, "Chi was specified, but the " \ - "number of rows must match " \ - "the number of clusters." - assert chi_input.shape[1] == n_genes, "Chi was specified, but the " \ - "number of columns must match " \ - "the number of genes." - - # Figure out how many cells are in each cell cluster. - if cells_in_clusters is None: - # No user input: make equal numbers of each cell type - cells_in_clusters = (np.ones(clusters, dtype=int) - * int(n_cells/clusters)) + # Input checking. + assert len(cells_of_each_type) > 0, 'cells_of_each_type must be a List of ints' + n_cell_types = len(cells_of_each_type) + if vector_to_add_to_chi_ambient is not None: + assert len(vector_to_add_to_chi_ambient) == n_genes, \ + f'vector_to_add_to_chi_ambient {vector_to_add_to_chi_ambient.shape} must ' \ + f'be of length n_genes ({n_genes})' + if type(dirichlet_alpha) == np.ndarray: + assert dirichlet_alpha.size == n_genes, \ + f'If you input a vector for dirichlet_alpha, its length ' \ + f'({dirichlet_alpha.size}) must be n_genes ({n_genes})' + assert cell_lognormal_sigma > 0, 'cell_lognormal_sigma must be > 0' + assert empty_lognormal_sigma > 0, 'empty_lognormal_sigma must be > 0' + cell_mean_umi = list(cell_mean_umi) + if len(cell_mean_umi) == 1: + cell_mean_umi = cell_mean_umi * n_cell_types # repeat the entry + for umi in cell_mean_umi: + assert umi > empty_mean_umi, \ + f'cell_size_mean_umi ({umi}) must be > empty_mean_umi ({empty_mean_umi})' + assert len(cell_mean_umi) == len(cells_of_each_type), \ + 'cells_of_each_type and cell_mean_umi (if a list) must be of the same length' + assert (chi_artificial_similarity >= 0) and (chi_artificial_similarity <= 1), \ + 'chi_artificial_similarity must be in the range [0, 1]' + + # Seed random number generators. + comprehensive_random_seed(seed=random_seed) + + # Draw gene expression profiles for each cell type. + if chi is None: + chi = np.zeros((n_cell_types, n_genes)) + for i in range(chi.shape[0]): + chi[i, :] = draw_random_chi(alpha=dirichlet_alpha, n_genes=n_genes).cpu().numpy() + if i > 0: + # Make expression profiles similar (if chi_artificial_similarity > 0) via gating. + chi[i, :] = chi[i, :] * (1 - chi_artificial_similarity) + chi[0, :] * chi_artificial_similarity else: - assert len(cells_in_clusters) == clusters, "len(cells_in_clusters) " \ - "must equal clusters." - assert sum(cells_in_clusters) == n_cells, "sum(cells_in_clusters) " \ - "must equal n_cells." - - # Initialize arrays and lists. - chi = np.zeros((clusters+1, n_genes)) - csr_list = [] - z = [] - d = [] - - if chi_input is not None: - - # Go with the chi that was input. - chi[1:, :] = chi_input - + dirichlet_alpha = ['None: chi was input to generate_sample_dataset()'] + + # Get chi_ambient: a weighted average of expression, possibly with extra. + if chi_ambient is None: + chi_ambient = np.zeros(n_genes) + for i in range(n_cell_types): + chi_ambient = chi_ambient + chi[i, :] * cells_of_each_type[i] * cell_mean_umi[i] + if vector_to_add_to_chi_ambient is None: + vector_to_add_to_chi_ambient = np.zeros(n_genes) + chi_ambient = chi_ambient + vector_to_add_to_chi_ambient else: - - # Get chi for cell expression. - for i in range(1, clusters+1): - chi[i, :] = generate_chi(alpha=0.01, n_genes=n_genes) - - # Get chi for ambient expression. This becomes chi[0, :]. - if ambient_different: - - # Ambient expression is unrelated to cells, and is itself random. - chi[0, :] = generate_chi(alpha=0.001, n_genes=n_genes) # Sparse + if vector_to_add_to_chi_ambient is not None: + print('You specified both `chi_ambient` and `vector_to_add_to_chi_ambient`. ' + 'Ignoring `vector_to_add_to_chi_ambient` and using `chi_ambient` ' + 'as provided.') + chi_ambient = chi_ambient / chi_ambient.sum() + + c_real = np.zeros((n_droplets, n_genes)) + c_bkg = np.zeros((n_droplets, n_genes)) + labels = np.zeros(n_droplets) + epsilon = np.zeros(n_droplets) + rho = np.zeros(n_droplets) + d_cell = np.zeros(n_droplets) + d_empty = np.zeros(n_droplets) + + # Sample counts from cell-containing droplets. + i = 0 + for t, (num_cells, celltype_umi) in enumerate(zip(cells_of_each_type, cell_mean_umi)): + sim = sample_from_dirichlet_model( + num=num_cells, + alpha=chi[t, :] * alpha0 + 1e-20, # must be > 0 + d_mu=np.log(celltype_umi), + d_sigma=cell_lognormal_sigma, + v_mu=np.log(empty_mean_umi), + v_sigma=empty_lognormal_sigma, + y=1, # cell present + chi_ambient=chi_ambient, + eps_param=epsilon_param, + rho_alpha=rho_alpha, + rho_beta=rho_beta, + model_type=model_type, + ) + c_real[i:(i + num_cells), :] = sim['counts_real'] + c_bkg[i:(i + num_cells), :] = sim['counts_bkg'] + epsilon[i:(i + num_cells)] = sim['epsilon'] + rho[i:(i + num_cells)] = sim['rho'] + d_cell[i:(i + num_cells)] = sim['cell_counts'] + d_empty[i:(i + num_cells)] = sim['empty_counts'] + labels[i:(i + num_cells)] = t + 1 # label cell types with integers > 0 + i = i + num_cells + + # Sample counts from empty droplets. + sim = sample_from_dirichlet_model( + num=n_droplets - i, + alpha=np.ones(n_genes), # this doesn't get used since y=0 + d_mu=1, # this doesn't get used since y=0 + d_sigma=1, # this doesn't get used since y=0 + v_mu=np.log(empty_mean_umi), + v_sigma=empty_lognormal_sigma, + y=0, # no cell present + chi_ambient=chi_ambient, + eps_param=epsilon_param, + rho_alpha=rho_alpha, + rho_beta=rho_beta, + model_type=model_type, + ) + c_real[i:, :] = sim['counts_real'] + c_bkg[i:, :] = sim['counts_bkg'] + epsilon[i:] = sim['epsilon'] + rho[i:] = sim['rho'] + d_empty[i:] = sim['empty_counts'] + + # Get sparse matrices from dense. + counts_true = sp.csr_matrix(c_real, shape=c_real.shape, dtype=int) + counts_bkg = sp.csr_matrix(c_bkg, shape=c_bkg.shape, dtype=int) + + return {'counts_true': counts_true, + 'counts_bkg': counts_bkg, + 'barcodes': np.array([f'bc{n:06d}' for n in np.arange(n_droplets)]), + 'gene_names': np.array([f'g{n:05d}' for n in np.arange(n_genes)]), + 'chi': {str(i + 1): chi[i, :] for i in range(chi.shape[0])}, + 'chi_ambient': chi_ambient, + 'droplet_labels': labels.astype(int), + 'd_cell': d_cell, + 'd_empty': d_empty, + 'epsilon': epsilon, + 'rho': rho, + 'cell_mean_umi': {str(i + 1): u for i, u in enumerate(cell_mean_umi)}, + 'cell_lognormal_sigma': cell_lognormal_sigma, + 'empty_mean_umi': empty_mean_umi, + 'empty_lognormal_sigma': empty_lognormal_sigma, + 'alpha0': alpha0, + 'epsilon_param': epsilon_param, + 'dirichlet_alpha': dirichlet_alpha, + 'model': [model_type]} + + +@torch.no_grad() +def generate_sample_model_dataset( + n_genes: int = 10000, + cells_of_each_type: List[int] = [100, 100, 100], + n_droplets: int = 5000, + model_type: str = 'full', + dirichlet_alpha: Union[float, np.ndarray] = 0.05, + chi: Optional[np.ndarray] = None, + chi_artificial_similarity: float = 0, + vector_to_add_to_chi_ambient: Optional[np.ndarray] = None, + cell_mean_umi: List[int] = [5000], + cell_lognormal_sigma: float = 0.2, + empty_mean_umi: int = 200, + empty_lognormal_sigma: float = 0.4, + epsilon_param: float = 100, + rho_alpha: float = 3, + rho_beta: float = 80, + phi: float = 0.1, + random_seed: int = 0) -> Dict[str, Union[float, np.ndarray, sp.csr_matrix]]: + """Create a sample dataset for use as 'truth' data. + """ + # Input checking. + assert len(cells_of_each_type) > 0, 'cells_of_each_type must be a List of ints' + n_cell_types = len(cells_of_each_type) + if vector_to_add_to_chi_ambient is not None: + assert len(vector_to_add_to_chi_ambient) == n_genes, \ + f'vector_to_add_to_chi_ambient {vector_to_add_to_chi_ambient.shape} must ' \ + f'be of length n_genes ({n_genes})' + if type(dirichlet_alpha) == np.ndarray: + assert dirichlet_alpha.size == n_genes, \ + f'If you input a vector for dirichlet_alpha, its length ' \ + f'({dirichlet_alpha.size}) must be n_genes ({n_genes})' + assert cell_lognormal_sigma > 0, 'cell_lognormal_sigma must be > 0' + assert empty_lognormal_sigma > 0, 'empty_lognormal_sigma must be > 0' + cell_mean_umi = list(cell_mean_umi) + if len(cell_mean_umi) == 1: + cell_mean_umi = cell_mean_umi * n_cell_types # repeat the entry + for umi in cell_mean_umi: + assert umi > empty_mean_umi, \ + f'cell_size_mean_umi ({umi}) must be > empty_mean_umi ({empty_mean_umi})' + assert len(cell_mean_umi) == len(cells_of_each_type), \ + 'cells_of_each_type and cell_mean_umi (if a list) must be of the same length' + assert (chi_artificial_similarity >= 0) and (chi_artificial_similarity <= 1), \ + 'chi_artificial_similarity must be in the range [0, 1]' + assert phi > 0, 'phi must be > 0' + + # Seed random number generators. + comprehensive_random_seed(seed=random_seed) + + # Draw gene expression profiles for each cell type. + if chi is None: + chi = torch.zeros((n_cell_types, n_genes)).to(DEVICE) + for i in range(chi.shape[0]): + chi[i, :] = draw_random_chi(alpha=dirichlet_alpha, n_genes=n_genes) + if i > 0: + # Make expression profiles similar (if chi_artificial_similarity > 0) via gating. + chi[i, :] = chi[i, :] * (1 - chi_artificial_similarity) + chi[0, :] * chi_artificial_similarity else: - - # Ambient gene expression comes from the sum of cell expression. - for i in range(1, clusters+1): - - chi[0, :] += cells_in_clusters[i-1] * chi[i, :] # Weighted sum - - chi[0, :] = chi[0, :] / np.sum(chi[0, :]) # Normalize - - # Sample gene expression for ambient. - csr, d_n = sample_expression_from(chi[0, :], - n=n_empty, - d_mu=np.log(d_empty).item()) - - # Add data to lists. - csr_list.append(csr) - z = z + [0 for _ in range(csr.shape[0])] - d = d + [i for i in d_n] - - # Sample gene expression for cells. - for i in range(1, clusters+1): - - # Get chi for cells once ambient expression is added. - chi_tilde = chi[i, :] * d_cell + chi[0, :] * d_empty - chi_tilde = chi_tilde / np.sum(chi_tilde) # Normalize - csr, d_n = sample_expression_from(chi_tilde, - n=cells_in_clusters[i-1], - d_mu=np.log(d_cell).item()) - - # Add data to lists. - csr_list.append(csr) - z = z + [i for _ in range(csr.shape[0])] - d = d + [j for j in d_n] - - # Package the results. - csr_barcode_gene_synthetic = sp.vstack(csr_list) - z = np.array(z) - d = np.array(d) - - # Permute the barcode order and return results. - order = np.random.permutation(z.size) - csr_barcode_gene_synthetic = csr_barcode_gene_synthetic[order, ...] - z = z[order] - d = d[order] - - return csr_barcode_gene_synthetic, z, chi, d - - -def generate_chi(alpha: float = 1., n_genes: int = 10000) -> np.ndarray: + dirichlet_alpha = ['None: chi was input to generate_sample_model_dataset()'] + + # Get chi_ambient: a weighted average of expression, possibly with extra. + chi_ambient = torch.zeros(n_genes).to(DEVICE) + for i in range(n_cell_types): + chi_ambient = chi_ambient + chi[i, :] * cells_of_each_type[i] * cell_mean_umi[i] + if vector_to_add_to_chi_ambient is None: + vector_to_add_to_chi_ambient = torch.zeros(n_genes) + chi_ambient = chi_ambient + vector_to_add_to_chi_ambient + chi_ambient = chi_ambient / chi_ambient.sum() + + c_real = torch.zeros((n_droplets, n_genes)).to(DEVICE) + c_bkg = torch.zeros((n_droplets, n_genes)).to(DEVICE) + labels = torch.zeros(n_droplets).to(DEVICE) + epsilon = torch.zeros(n_droplets).to(DEVICE) + rho = torch.zeros(n_droplets).to(DEVICE) + d_cell = torch.zeros(n_droplets).to(DEVICE) + d_empty = torch.zeros(n_droplets).to(DEVICE) + + # Sample counts from cell-containing droplets. + i = 0 + for t, (num_cells, celltype_umi) in enumerate(zip(cells_of_each_type, cell_mean_umi)): + sim = sample_from_model( + num=num_cells, + chi=chi[t, :], + d_mu=np.log(celltype_umi), + d_sigma=cell_lognormal_sigma, + v_mu=np.log(empty_mean_umi), + v_sigma=empty_lognormal_sigma, + y=1, # cell present + chi_ambient=chi_ambient, + eps_param=epsilon_param, + rho_alpha=rho_alpha, + rho_beta=rho_beta, + phi=phi, + model_type=model_type, + ) + c_real[i:(i + num_cells), :] = sim['counts_real'] + c_bkg[i:(i + num_cells), :] = sim['counts_bkg'] + epsilon[i:(i + num_cells)] = sim['epsilon'] + rho[i:(i + num_cells)] = sim['rho'] + d_cell[i:(i + num_cells)] = sim['cell_counts'] + d_empty[i:(i + num_cells)] = sim['empty_counts'] + labels[i:(i + num_cells)] = t + 1 # label cell types with integers > 0 + i = i + num_cells + + # Sample counts from empty droplets. + sim = sample_from_model( + num=n_droplets - i, + chi=chi[0, :], # this doesn't get used since y=0 + d_mu=1, # this doesn't get used since y=0 + d_sigma=1, # this doesn't get used since y=0 + v_mu=np.log(empty_mean_umi), + v_sigma=empty_lognormal_sigma, + y=0, # no cell present + chi_ambient=chi_ambient, + eps_param=epsilon_param, + rho_alpha=rho_alpha, + rho_beta=rho_beta, + phi=phi, + model_type=model_type, + ) + c_real[i:, :] = sim['counts_real'] + c_bkg[i:, :] = sim['counts_bkg'] + epsilon[i:] = sim['epsilon'] + rho[i:] = sim['rho'] + d_empty[i:] = sim['empty_counts'] + + # Get sparse matrices from dense. + counts_true = sp.csr_matrix(c_real.cpu().numpy(), shape=c_real.shape, dtype=int) + counts_bkg = sp.csr_matrix(c_bkg.cpu().numpy(), shape=c_bkg.shape, dtype=int) + + return {'counts_true': counts_true, + 'counts_bkg': counts_bkg, + 'barcodes': np.array([f'bc{n:06d}' for n in np.arange(n_droplets)]), + 'gene_names': np.array([f'g{n:05d}' for n in np.arange(n_genes)]), + 'chi': {str(i + 1): chi[i, :].cpu().numpy() for i in range(chi.shape[0])}, + 'chi_ambient': chi_ambient.cpu().numpy(), + 'droplet_labels': labels.int().cpu().numpy(), + 'd_cell': d_cell.cpu().numpy(), + 'd_empty': d_empty.cpu().numpy(), + 'epsilon': epsilon.cpu().numpy(), + 'rho': rho.cpu().numpy(), + 'cell_mean_umi': {str(i + 1): u for i, u in enumerate(cell_mean_umi)}, + 'cell_lognormal_sigma': cell_lognormal_sigma, + 'empty_mean_umi': empty_mean_umi, + 'empty_lognormal_sigma': empty_lognormal_sigma, + 'epsilon_param': epsilon_param, + 'dirichlet_alpha': dirichlet_alpha, + 'phi': phi, + 'model': [model_type]} + + +def draw_random_chi(alpha: float = 1., + n_genes: int = 10000) -> torch.Tensor: """Sample a gene expression vector, chi, from a Dirichlet prior. - Args: alpha: Concentration parameter for Dirichlet distribution, to be expanded into a vector to use as the Dirichlet concentration parameter. n_genes: Number of genes. - Returns: chi: Vector of fractional gene expression, drawn from a Dirichlet distribution. - """ assert alpha > 0, "Concentration parameter, alpha, must be > 0." assert n_genes > 0, "Number of genes, n_genes, must be > 0." # Draw gene expression from a Dirichlet distribution. - chi = np.random.dirichlet(alpha * np.ones(n_genes), size=1).squeeze() - - # Normalize gene expression and return result. - chi = chi / np.sum(chi) - + chi = torch.distributions.Dirichlet(alpha * torch.ones(n_genes).to(DEVICE)).sample().squeeze() + return chi -def sample_expression_from(chi: np.ndarray, - n: int = 100, - d_mu: float = np.log(5000).item(), - d_sigma: float = 0.2, - phi: float = 0.3) -> Tuple[sp.csr.csr_matrix, - np.ndarray]: - """Generate a count matrix given a mean expression distribution. - +def sample_from_inferred_model(num: int, + model: 'RemoveBackgroundPyroModel', + z: Optional[torch.Tensor] = None, + y: Optional[torch.Tensor] = None) -> Dict[str, np.ndarray]: + """Sample data from the model, where the model is not completely naive, but + uses a decoder trained on real data.""" + + # Run the model, . + data = torch.zeros(size=(num, model.n_genes)) # model uses shape only + tracing_model = model.model + do_list = [] + if z is not None: + tracing_model = pyro.poutine.do(tracing_model, data={'z': z}) + do_list.append('z') + if y is not None: + tracing_model = pyro.poutine.do(tracing_model, data={'y': y}) + do_list.append('z') + + model_trace = pyro.poutine.trace(tracing_model).get_trace(data) + + # Get outputs of model (mu, alpha, lambda). + model_output = model_trace.nodes['_RETURN']['value'] + + # Get traced parameters. + params = {name: (model_trace.nodes[name]['value'].unconstrained() + if (model_trace.nodes[name]['type'] == 'param') + else model_trace.nodes[name]['value']) + for name in ['chi'] + model_trace.param_nodes + model_trace.stochastic_nodes + if (not ('$$$' in name) and name not in do_list)} # the do-samples are dummies + + # Extract latent values. + epsilon = params['epsilon'] + rho = params['rho'] + d = params['d_cell'] + d_empty = params['d_empty'] + y = y if (y is not None) else params['y'] # the "do" does not show up in the trace, apparently + chi = params['chi'] + chi_bar = model.avg_gene_expression + chi_ambient = params['chi_ambient'] # pull from the (loaded) param store + + # Because the model integrates out real counts and noise counts, we sample here. + logit = torch.log(model_output['mu']) - torch.log(model_output['alpha']) + c_real = pyro.distributions.NegativeBinomial(total_count=model_output['alpha'], + logits=logit).to_event(1).sample() + c_bkg = pyro.distributions.Poisson(model_output['lam']).to_event(1).sample() + + # Output observed counts are the sum, but return them separately. + return {'counts_real': c_real.detach().cpu().numpy(), + 'counts_bkg': c_bkg.detach().cpu().numpy(), + 'cell_counts': (d * y).detach().cpu().numpy(), + 'empty_counts': d_empty.detach().cpu().numpy(), + 'epsilon': epsilon.detach().cpu().numpy(), + 'rho': rho.detach().cpu().numpy(), + 'chi': chi.detach().cpu().numpy()} + + +def sample_from_model( + num: int, + chi: torch.Tensor, + d_mu: float, + d_sigma: float, + v_mu: float, + v_sigma: float, + y: int, + chi_ambient: torch.Tensor, + eps_param: float, + model_type: str = 'full', + rho_alpha: float = 3, + rho_beta: float = 80, + phi: float = 0.1, +) -> Dict[str, torch.Tensor]: + """Draw samples of cell expression profiles using the negative binomial - + Poisson sum model. + + NOTE: Single cell type with expression chi. + NOTE: Random number seeding should be done before this function call. + Args: - chi: Normalized gene expression vector (sums to one). - n: Number of desired cells to simulate. - d_mu: Log mean number of UMI counts per cell. - d_sigma: Standard deviation of a normal in log space for the number - of UMI counts per cell. - phi: The overdispersion parameter of a negative binomial, - i.e., variance = mean + phi * mean^2 - + num: Number of expression profiles to draw. + chi: Cell expression profile, size (n_gene). + d_mu: Mean of LogNormal cell size distribution. + d_sigma: Scale parameter of LogNormal cell size distribution. + v_mu: Mean of LogNormal empty size distribution. + v_sigma: Scale parameter of LogNormal empty size distribution. + y: 1 for cell(s), 0 for empties. + chi_ambient: Ambient gene expression profile (sums to one). + eps_param: Parameter for gamma distribution of the epsilon droplet + efficiency factor ~ Gamma(eps_param, 1/eps_param), i.e. mean is 1. + model_type: ['ambient', 'swapping', 'full'] + rho_alpha: Beta distribution param alpha for swapping fraction. + rho_beta: Beta distribution param beta for swapping fraction. + phi: The negative binomial overdispersion parameter. Returns: - csr_cell_gene: scipy.sparse.csr_matrix of gene expression - counts per cell, with cells in axis=0 and genes in axis=1. - - Note: - Draw gene expression from a negative binomial distribution - counts ~ NB(d*chi, phi) - + Tuple of (c_real, c_bkg) + c_real: Count matrix (cells, genes) for real cell counts. + c_bkg: Count matrix (cells, genes) for background RNA. """ - assert phi > 0, "Phi must be greater than zero in the negative binomial." - assert d_sigma > 0, "Scale parameter, d_sigma, of LogNormal distribution " \ - " must be greater than zero." - assert d_mu > 0, "Location parameter, d_mu, of LogNormal distribution " \ - " must be greater than zero." - assert n > 0, "Number of cells to simulate, n, must be a positive integer." - assert chi.min() >= 0, "Minimum allowed value in chi vector is zero." - - n_genes = chi.size # Number of genes - - # Initialize arrays. - barcodes = np.arange(n) - genes = np.arange(n_genes) - predicted_reads = int(np.exp(d_mu) * n * 2) # Guess array sizes - coo_bc_list = np.zeros(predicted_reads, dtype=np.uint32) - coo_gene_list = np.zeros(predicted_reads, dtype=np.uint32) - coo_count_list = np.zeros(predicted_reads, dtype=np.uint32) - d = np.zeros(n) - a = 0 - - # Go barcode by barcode, sampling UMI counts per gene. - for i in range(n): - - # Sample cell size parameter from a LogNormal distribution. - d[i] = np.exp(np.random.normal(loc=d_mu, scale=d_sigma, size=1)) - - # Sample counts from a negative binomial distribution. - gene_counts = neg_binom(d[i] * chi, phi, size=n_genes) - - # Keep only the non-zero counts to populate the sparse matrix. - num_nonzeros = np.sum(gene_counts > 0) - - # Check whether arrays need to be re-sized to accommodate more entries. - if (a + num_nonzeros) < coo_count_list.size: - # Fill in. - coo_bc_list[a:a+num_nonzeros] = barcodes[i] - coo_gene_list[a:a+num_nonzeros] = genes[gene_counts > 0] - coo_count_list[a:a+num_nonzeros] = gene_counts[gene_counts > 0] - else: - # Resize arrays by doubling. - coo_bc_list = np.resize(coo_bc_list, coo_bc_list.size * 2) - coo_gene_list = np.resize(coo_gene_list, coo_gene_list.size * 2) - coo_count_list = np.resize(coo_count_list, coo_count_list.size * 2) - # Fill in. - coo_bc_list[a:a+num_nonzeros] = barcodes[i] - coo_gene_list[a:a+num_nonzeros] = genes[gene_counts > 0] - coo_count_list[a:a+num_nonzeros] = gene_counts[gene_counts > 0] - - a += num_nonzeros - - # Lop off any unused zero entries at the end of the arrays. - coo_bc_list = coo_bc_list[coo_count_list > 0] - coo_gene_list = coo_gene_list[coo_count_list > 0] - coo_count_list = coo_count_list[coo_count_list > 0] - - # Package data into a scipy.sparse.coo.coo_matrix. - count_matrix = sp.coo_matrix((coo_count_list, (coo_bc_list, coo_gene_list)), - shape=(barcodes.size, n_genes), - dtype=np.uint32) - - # Convert to a scipy.sparse.csr.csr_matrix and return. - count_matrix = count_matrix.tocsr() - - return count_matrix, d - - -def neg_binom(mu: float, phi: float, size: int = 1) -> np.ndarray: - """Parameterize numpy's negative binomial distribution - in terms of the mean and the overdispersion. + # Check inputs. + assert y in [0, 1], f'y must be 0 or 1, but was {y}' + assert d_mu > 0, f'd_mu must be > 0, but was {d_mu}' + assert d_sigma > 0, f'd_sigma must be > 0, but was {d_sigma}' + assert v_mu > 0, f'v_mu must be > 0, but was {v_mu}' + assert v_sigma > 0, f'v_sigma must be > 0, but was {v_sigma}' + assert (chi >= 0).all(), 'all chi values must be >= 0.' + assert (chi_ambient >= 0).all(), 'all chi_ambient must be >= 0.' + assert (1. - chi_ambient.sum()).abs() < 1e-6, f'chi_ambient must sum ' \ + f'to 1, but it sums to {chi_ambient.sum()}' + assert len(chi_ambient.shape) == 1, 'chi_ambient should be 1-dimensional.' + assert chi.shape[-1] == chi_ambient.shape[-1], 'chi and chi_ambient must ' \ + 'be the same size in the rightmost dimension.' + assert (1. - chi.sum()).abs() < 1e-6, f'chi must sum ' \ + f'to 1, but it sums to {chi.sum()}' + assert num > 0, f'num must be > 0, but was {num}' + assert eps_param > 1, f'eps_param must be > 1, but was {eps_param}' - Args: - mu: Mean of the distribution - phi: Overdispersion, such that variance = mean + phi * mean^2 - size: How many numbers to return + # Draw epsilon ~ Gamma(eps_param, 1 / eps_param) + epsilon = torch.distributions.Gamma(concentration=eps_param, rate=eps_param).sample([num]) - Returns: - 'size' number of random draws from a negative binomial distribution. + # Draw d ~ LogNormal(d_mu, d_sigma) + d = torch.distributions.LogNormal(loc=d_mu, scale=d_sigma).sample([num]) - Note: - Setting phi=0 turns the negative binomial distribution into a - Poisson distribution. + # Draw d ~ LogNormal(d_mu, d_sigma) + v = torch.distributions.LogNormal(loc=v_mu, scale=v_sigma).sample([num]) - """ + # Draw rho ~ Beta(rho_alpha, rho_beta) + rho = torch.distributions.Beta(rho_alpha, rho_beta).sample([num]) + + mu = calculate_mu(epsilon=epsilon, + d_cell=d, + chi=chi, + y=torch.ones(d.shape).to(DEVICE) * y, + rho=rho, + model_type=model_type) + 1e-30 + + # Draw cell counts ~ NB(mean = y * epsilon * d * chi, overdispersion = phi) + alpha = 1. / phi + logits = (mu.log() - np.log(alpha)) + c_real = torch.distributions.NegativeBinomial(total_count=alpha, + logits=logits).sample() + + lam = calculate_lambda(epsilon=epsilon, + chi_ambient=chi_ambient, + d_cell=d, + d_empty=v, + y=torch.ones(d.shape).to(DEVICE) * y, + rho=rho, + chi_bar=chi_ambient, + model_type=model_type) + 1e-30 - assert phi > 0, "Phi must be greater than zero in the negative binomial." - assert size > 0, "Number of draws from negative binomial, size, must " \ - "be a positive integer." + # Draw empty counts ~ Poisson(epsilon * v * chi_ambient) + c_bkg = torch.distributions.Poisson(rate=lam).sample() - n = 1. / phi - p = n / (mu + n) - return np.random.negative_binomial(n, p, size=size) + # Output observed counts are the sum, but return them separately. + return {'counts_real': c_real, + 'counts_bkg': c_bkg, + 'cell_counts': d * y, + 'empty_counts': v, + 'epsilon': epsilon, + 'rho': rho} def sample_from_dirichlet_model(num: int, @@ -388,14 +710,12 @@ def sample_from_dirichlet_model(num: int, y: int, chi_ambient: np.ndarray, eps_param: float, - random_seed: int = 0, - include_swapping: bool = False, + rng: Optional[np.random.RandomState] = None, + model_type: str = 'full', rho_alpha: float = 3, - rho_beta: float = 80) -> Tuple[np.ndarray, - np.ndarray]: + rho_beta: float = 80) -> Dict[str, np.ndarray]: """Draw samples of cell expression profiles using the Dirichlet-Poisson, Poisson sum model. - Args: num: Number of expression profiles to draw. alpha: Dirichlet concentration parameters for cell expression profile, @@ -408,16 +728,14 @@ def sample_from_dirichlet_model(num: int, chi_ambient: Ambient gene expression profile (sums to one). eps_param: Parameter for gamma distribution of the epsilon droplet efficiency factor ~ Gamma(eps_param, 1/eps_param), i.e. mean is 1. - random_seed: Seed a random number generator. - include_swapping: Whether to include swapping in the model. + rng: A random number generator. + model_type: ['ambient', 'swapping', 'full'] rho_alpha: Beta distribution param alpha for swapping fraction. rho_beta: Beta distribution param beta for swapping fraction. - Returns: Tuple of (c_real, c_bkg) c_real: Count matrix (cells, genes) for real cell counts. c_bkg: Count matrix (cells, genes) for background RNA. - """ # Check inputs. @@ -427,9 +745,9 @@ def sample_from_dirichlet_model(num: int, assert v_mu > 0, f'v_mu must be > 0, but was {v_mu}' assert v_sigma > 0, f'v_sigma must be > 0, but was {v_sigma}' assert np.all(alpha > 0), 'all alphas must be > 0.' - assert np.all(chi_ambient > 0), 'all chi_ambient must be > 0.' - assert np.abs(1. - chi_ambient.sum()) < 1e-10, f'chi_ambient must sum to 1, but it sums ' \ - f'to {chi_ambient.sum()}' + assert np.all(chi_ambient >= 0), 'all chi_ambient must be >= 0.' + assert np.abs(1. - chi_ambient.sum()) < 1e-10, f'chi_ambient must sum ' \ + f'to 1, but it sums to {chi_ambient.sum()}' assert len(chi_ambient.shape) == 1, 'chi_ambient should be 1-dimensional.' assert alpha.shape[0] == chi_ambient.size, 'alpha and chi_ambient must ' \ 'be the same size in the rightmost dimension.' @@ -437,7 +755,8 @@ def sample_from_dirichlet_model(num: int, assert eps_param > 1, f'eps_param must be > 1, but was {eps_param}' # Seed random number generator. - rng = np.random.RandomState(seed=random_seed) + if rng is None: + rng = np.random.RandomState(seed=0) # Draw chi ~ Dir(alpha) chi = rng.dirichlet(alpha=alpha, size=num) @@ -454,91 +773,138 @@ def sample_from_dirichlet_model(num: int, # Draw rho ~ Beta(rho_alpha, rho_beta) rho = rng.beta(a=rho_alpha, b=rho_beta, size=num) - # print(f'eps.shape is {epsilon.shape}') - # print(f'd.shape is {d.shape}') - # print(f'chi.shape is {chi.shape}') - # print(f'rho.shape is {rho.shape}') - - mu = _calculate_mu(model_type='ambient' if not include_swapping else 'full', - epsilon=torch.Tensor(epsilon), - d_cell=torch.Tensor(d), - chi=torch.Tensor(chi), - y=torch.ones(d.shape) * y, - rho=torch.Tensor(rho)).numpy() + mu = calculate_mu(epsilon=torch.tensor(epsilon), + d_cell=torch.tensor(d), + chi=torch.tensor(chi), + y=torch.ones(d.shape) * y, + rho=torch.tensor(rho), + model_type=model_type).numpy() # Draw cell counts ~ Poisson(y * epsilon * d * chi) - c_real = rng.poisson(lam=mu, - size=(num, chi_ambient.size)) - - lam = _calculate_lambda(model_type='ambient' if not include_swapping else 'full', - epsilon=torch.Tensor(epsilon), - chi_ambient=torch.Tensor(chi_ambient), - d_cell=torch.Tensor(d), - d_empty=torch.Tensor(v), - y=torch.ones(d.shape) * y, - rho=torch.Tensor(rho), - chi_bar=torch.Tensor(chi_ambient)).numpy() + c_real = rng.poisson(lam=mu, size=(num, chi_ambient.size)) + + lam = calculate_lambda(epsilon=torch.tensor(epsilon), + chi_ambient=torch.tensor(chi_ambient), + d_cell=torch.tensor(d), + d_empty=torch.tensor(v), + y=torch.ones(d.shape) * y, + rho=torch.tensor(rho), + chi_bar=torch.tensor(chi_ambient), + model_type=model_type).numpy() # Draw empty counts ~ Poisson(epsilon * v * chi_ambient) - c_bkg = rng.poisson(lam=lam, - size=(num, chi_ambient.size)) + c_bkg = rng.poisson(lam=lam, size=(num, chi_ambient.size)) # Output observed counts are the sum, but return them separately. - return c_real, c_bkg - - -def _calculate_lambda(model_type: str, - epsilon: torch.Tensor, - chi_ambient: torch.Tensor, - d_empty: torch.Tensor, - y: Union[torch.Tensor, None] = None, - d_cell: Union[torch.Tensor, None] = None, - rho: Union[torch.Tensor, None] = None, - chi_bar: Union[torch.Tensor, None] = None): - """Calculate noise rate based on the model.""" - - if model_type == "simple" or model_type == "ambient": - lam = epsilon.unsqueeze(-1) * d_empty.unsqueeze(-1) * chi_ambient - - elif model_type == "swapping": - lam = (rho.unsqueeze(-1) * y.unsqueeze(-1) - * epsilon.unsqueeze(-1) * d_cell.unsqueeze(-1) - + d_empty.unsqueeze(-1)) * chi_bar - - elif model_type == "full": - lam = ((1 - rho.unsqueeze(-1)) * d_empty.unsqueeze(-1) * chi_ambient.unsqueeze(0) - + rho.unsqueeze(-1) - * (y.unsqueeze(-1) * epsilon.unsqueeze(-1) * d_cell.unsqueeze(-1) - + d_empty.unsqueeze(-1)) * chi_bar) - else: - raise NotImplementedError(f"model_type was set to {model_type}, " - f"which is not implemented.") + return {'counts_real': c_real, + 'counts_bkg': c_bkg, + 'cell_counts': d * y, + 'empty_counts': v, + 'epsilon': epsilon, + 'rho': rho} - return lam +def get_dataset_dict_as_anndata( + sample_dataset: Dict[str, Union[float, np.ndarray, sp.csr_matrix]] +) -> 'anndata.AnnData': + """Return a simulated dataset as an AnnData object.""" -def _calculate_mu(model_type: str, - epsilon: torch.Tensor, - d_cell: torch.Tensor, - chi: torch.Tensor, - y: Union[torch.Tensor, None] = None, - rho: Union[torch.Tensor, None] = None): - """Calculate mean expression based on the model.""" + import anndata - if model_type == 'simple': - mu = epsilon.unsqueeze(-1) * d_cell.unsqueeze(-1) * chi + d = sample_dataset.copy() - elif model_type == 'ambient': - mu = (y.unsqueeze(-1) * epsilon.unsqueeze(-1) - * d_cell.unsqueeze(-1) * chi) + # counts + if 'counts_true' in d.keys() and 'counts_bkg' in d.keys(): + adata = anndata.AnnData(X=(d['counts_true'] + d['counts_bkg']).astype(np.float32), + obs={'barcode': d.pop('barcodes')}, + var={'gene': d.pop('gene_names')}) + adata.layers['counts_true'] = d.pop('counts_true') + adata.layers['counts'] = adata.layers['counts_true'] + d.pop('counts_bkg') + elif 'matrix' in d.keys(): + adata = anndata.AnnData(X=d.pop('matrix').astype(np.float32), + obs={'barcode': d.pop('barcodes')}, + var={'gene': d.pop('gene_names')}) - elif model_type == 'swapping' or model_type == 'full': - mu = ((1 - rho.unsqueeze(-1)) - * y.unsqueeze(-1) * epsilon.unsqueeze(-1) - * d_cell.unsqueeze(-1) * chi) + # obs + obs_keys = ['droplet_labels', 'd_cell', 'epsilon'] + for key in obs_keys: + adata.obs[key] = d.pop(key, None) - else: - raise NotImplementedError(f"model_type was set to {model_type}, " - f"which is not implemented.") + # uns + for key, value in d.items(): + adata.uns[key] = value + + return adata + + +def write_simulated_data_to_h5(output_file: str, + d: Dict[str, Union[float, np.ndarray, sp.csr_matrix]], + cellranger_version: int = 3) -> bool: + """Helper function to write the full (noisy) simulate dataset to an H5 file. + + Args: + output_file: File name + d: Resulting dict from `generate_sample_dataset` + + Returns: + True if save was successful. + """ + + assert cellranger_version in [2, 3], 'cellranger_version must be 2 or 3' + + return write_matrix_to_cellranger_h5( + output_file=output_file, + gene_names=d['gene_names'], + feature_types=np.array(['Gene Expression'] * d['gene_names'].size), + genomes=(np.array(['simulated'] * d['gene_names'].size) + if ('genome' not in d.keys()) else d['genome']), + barcodes=d['barcodes'], + count_matrix=(d['counts_true'] + d['counts_bkg']).tocsc(), + cellranger_version=cellranger_version, + ) + + +def write_simulated_truth_to_h5(output_file: str, + d: Dict[str, Union[float, np.ndarray, sp.csr_matrix]], + cellranger_version: int = 3) -> bool: + """Helper function to write the full (noisy) simulate dataset to an H5 file. + + Args: + output_file: File name + d: Resulting dict from `generate_sample_dataset` + + Returns: + True if save was successful. + """ - return mu + assert cellranger_version in [2, 3], 'cellranger_version must be 2 or 3' + + latents = set(d.keys()) + extra_latents = latents - {'gene_names', 'genome', 'barcodes', 'counts_true', + 'droplet_labels', 'd_cell', 'd_empty', 'epsilon', 'rho', + 'chi', 'cell_mean_umi', 'counts_bkg'} + global_latents = {f'truth_{key.replace("chi_ambient", "ambient_expression")}': d[key] + for key in extra_latents} + + for i, v in d['chi'].items(): + global_latents.update({f'truth_gene_expression_cell_label_{i}': v}) + for i, v in d['cell_mean_umi'].items(): + global_latents.update({f'truth_mean_umi_cell_label_{i}': v}) + + return write_matrix_to_cellranger_h5( + output_file=output_file, + gene_names=d['gene_names'], + feature_types=np.array(['Gene Expression'] * d['gene_names'].size), + genomes=(np.array(['simulated'] * d['gene_names'].size) + if ('genome' not in d.keys()) else d['genome']), + barcodes=d['barcodes'], + count_matrix=d['counts_true'].tocsc(), # just the truth, no background + cellranger_version=cellranger_version, + local_latents={'truth_cell_label': d['droplet_labels'], + 'truth_cell_size': d['d_cell'], + 'truth_empty_droplet_size': d['d_empty'], + 'truth_droplet_efficiency': d['epsilon'], + 'truth_cell_probability': (d['droplet_labels'] != 0).astype(float), + 'truth_swapping_fraction': d['rho']}, + global_latents=global_latents, + ) diff --git a/cellbender/remove_background/data/io.py b/cellbender/remove_background/data/io.py new file mode 100644 index 00000000..8c1fec7a --- /dev/null +++ b/cellbender/remove_background/data/io.py @@ -0,0 +1,1207 @@ +"""Handle input parsing and output writing.""" + +import tables +import anndata +import numpy as np +import scipy.sparse as sp +import scipy.io as io + +from cellbender.remove_background import consts + +from typing import Dict, Union, List, Optional, Callable +import logging +import os +import gzip +import traceback + + +logger = logging.getLogger('cellbender') + + +class IngestedData(dict): + """Small container object for the results of file loading. This is a way to + ensure that all filetypes are loaded into the same general format that can + be used in dataset.py + + NOTE: This really exists to ensure all these fields are present, and to + force each loader to specify each field + """ + + def __init__(self, matrix, barcodes, + gene_names, gene_ids, feature_types, genomes, + **kwargs): + # Fill in some fields no matter the input source (for loading in scanpy) + blank_array = np.array(['NA'] * len(gene_names)) + if genomes is None: + genomes = blank_array + if gene_ids is None: + gene_ids = blank_array + if feature_types is None: + feature_types = blank_array + + # Warn if file looks filtered. + if len(barcodes) < consts.MINIMUM_BARCODES_H5AD: + logger.warning(f'WARNING: Only {len(barcodes)} barcodes in the input file. ' + f'Ensure this is a raw (unfiltered) file with all barcodes, ' + f'including the empty droplets.') + + # Required values, some of which can be None + super().__init__([('matrix', matrix), + ('barcodes', barcodes), + ('gene_names', gene_names), + ('gene_ids', gene_ids), + ('feature_types', feature_types), + ('genomes', genomes)]) + self.update(**kwargs) # cellranger version, for example, is optional + + +class FileLoader: + """Make explicit guarantees about what a file-loading method yields.""" + + def __init__(self, load_fn): + self.load_fn = load_fn + + def load(self, file) -> IngestedData: + data = self.load_fn(file) + return IngestedData(**data) + + +def write_matrix_to_cellranger_h5( + cellranger_version: int, + output_file: str, + gene_names: np.ndarray, + barcodes: np.ndarray, + count_matrix: sp.csc_matrix, + feature_types: Optional[np.ndarray] = None, + gene_ids: Optional[np.ndarray] = None, + genomes: Optional[np.ndarray] = None, + local_latents: Dict[str, Optional[np.ndarray]] = {}, + global_latents: Dict[str, Optional[np.ndarray]] = {}, + metadata: Dict[str, Optional[Union[np.ndarray, int, str, Dict]]] = {}) -> bool: + """Write count matrix data to output HDF5 file using CellRanger format. + + Args: + cellranger_version: Either 2 or 3. Determines the format of the output + h5 file. + output_file: Path to output .h5 file (e.g., 'output.h5'). + gene_names: Name of each gene (column of count matrix). + gene_ids: Ensembl ID of each gene (column of count matrix). + genomes: Name of the genome that each gene comes from. + feature_types: Type of each feature (column of count matrix). + barcodes: Name of each barcode (row of count matrix). + count_matrix: Count matrix to be written to file, in sparse + format. Rows are barcodes, columns are genes. + local_latents: Local latent variables. Should include one key called + 'barcodes' which specifies the droplets being referred to. + global_latents: Global latent variables. + metadata: Other metadata like loss per epoch and FPR, etc. + + Note: + To match the CellRanger .h5 files, the matrix is stored as its + transpose, with rows as genes and cell barcodes as columns. + + """ + + assert isinstance(count_matrix, sp.csc_matrix), \ + "The count matrix must be csc_matrix format in order to write to HDF5." + + assert gene_names.size == count_matrix.shape[1], \ + "The number of gene names must match the number of columns in the count matrix." + + if gene_ids is not None: + assert gene_names.size == gene_ids.size, \ + f"The number of gene_names {gene_names.shape} must match " \ + f"the number of gene_ids {gene_ids.shape}." + + if feature_types is not None: + assert gene_names.size == feature_types.size, \ + f"The number of gene_names {gene_names.shape} must match " \ + f"the number of feature_types {feature_types.shape}." + + if genomes is not None: + assert gene_names.size == genomes.size, \ + "The number of gene_names must match the number of genome designations." + + assert barcodes.size == count_matrix.shape[0], \ + "The number of barcodes must match the number of rows in the count matrix." + + # This reverses the role of rows and columns, to match CellRanger format. + count_matrix = count_matrix.transpose().tocsc() + + # Write to output file. + filters = tables.Filters(complevel=1, complib='zlib', shuffle=True) + filter_noshuffle = tables.Filters(complevel=1, complib='zlib', shuffle=False) + with tables.open_file(output_file, "w", + title="CellBender remove-background output") as f: + + if cellranger_version == 2: + + # Create the group where count data will be stored + group = f.create_group("/", "matrix_v2", "Counts after background correction") + + # Create arrays within that group for gene info. + f.create_carray(group, "gene_names", obj=gene_names, filters=filters) + if gene_ids is None: + # some R loaders require unique values here + gene_ids = np.array([f'NA_{i}' for i in range(gene_names.size)]) + f.create_carray(group, "genes", obj=gene_ids, filters=filters) + if genomes is None: + genomes = np.array(['NA'] * gene_names.size) + f.create_carray(group, "genome", obj=genomes, filters=filters) + + elif cellranger_version == 3: + + # Create the group where count data will be stored + group = f.create_group("/", "matrix", "Counts after background correction") + + # Create a sub-group called "features" + feature_group = f.create_group(group, "features", + "Genes and other features measured") + + # Create arrays within that group for feature info. + f.create_carray(feature_group, "name", obj=gene_names, filters=filters) + if gene_ids is None: + # some R loaders require unique values here + gene_ids = np.array([f'NA_{i}' for i in range(gene_names.size)]) + f.create_carray(feature_group, "id", obj=gene_ids, filters=filters) + if feature_types is None: + feature_types = np.array(['Gene Expression'] * gene_names.size) + f.create_carray(feature_group, "feature_type", obj=feature_types, filters=filters) + if genomes is None: + genomes = np.array(['NA'] * gene_names.size) + f.create_carray(feature_group, "genome", obj=genomes, filters=filters) + + # TODO: Copy the other extraneous information from the input file. + # (Some user might need it for some reason.) + + else: + raise ValueError(f'Trying to save to CellRanger v{cellranger_version} ' + f'format, which is not implemented.') + + # Code for both versions. + f.create_carray(group, "barcodes", obj=barcodes, filters=filter_noshuffle) + + # Create arrays to store the count data. + f.create_carray(group, "data", obj=count_matrix.data, filters=filters) + f.create_carray(group, "indices", obj=count_matrix.indices, filters=filters) + f.create_carray(group, "indptr", obj=count_matrix.indptr, filters=filters) + f.create_carray(group, "shape", atom=tables.Int32Atom(), + obj=np.array(count_matrix.shape, dtype=np.int32), filters=filters) + + # Store local latent variables. + droplet_latent_group = f.create_group("/", "droplet_latents", "Latent variables per droplet") + for key, value in local_latents.items(): + if value is not None: + f.create_carray(droplet_latent_group, key, obj=value, filters=filters) + + # Store global latent variables. + global_group = f.create_group("/", "global_latents", "Global latent variables") + for key, value in global_latents.items(): + if value is not None: + f.create_array(global_group, key, value) + + def create_nonscalar_metadata_array(f, group, k, v): + """Wrap scalar or string values in lists""" + if v is None: + return + if (type(v) == list) or (type(v) == np.ndarray): + f.create_array(group, k, v) + else: + f.create_array(group, k, [v]) + + # Store metadata. + metadata_group = f.create_group("/", "metadata", "Metadata") + for key, value in metadata.items(): + for k, v in unravel_dict(key, value).items(): + create_nonscalar_metadata_array(f, metadata_group, k, v) + + logger.info(f"Succeeded in writing CellRanger " + f"format output to file {output_file}") + + return True + + +def write_posterior_coo_to_h5( + output_file: str, + posterior_coo: sp.coo_matrix, + noise_count_offsets: Dict[int, int], + latents: Dict[str, np.ndarray], + feature_inds: np.ndarray, + barcode_inds: np.ndarray, + regularized_posterior_coo: Optional[sp.coo_matrix] = None, + posterior_kwargs: Optional[Dict] = None, + regularized_posterior_kwargs: Optional[Dict] = None) -> bool: + """Write sparse COO matrix to an HDF5 file, using compression. + + NOTE: COO matrix is indexed by rows 'm' which each map to a unique + (cell, feature). The cell and feature are denoted in the barcode_inds + and feature_inds arrays. The column indices for the COO matrix are the + number of noise counts for each entry in count matrix, starting with zero, + except these noise count values get added to noise_count_offsets, which is + length m. + + Args: + output_file: Path to output .h5 file (e.g., 'output.h5'). + posterior_coo: Posterior to be written to file, in sparse COO [m, c] + format. Rows are 'm'-index, columns are number of noise counts. + noise_count_offsets: The number of noise counts at which each 'm' starts. + Absence of an 'm'-index from the keys of this dict means that the + corresponding 'm'-index starts at 0 noise counts. + latents: MAP values of latent variables for each analyzed barcode. + barcode_inds: Index of each barcode (row of input count matrix). + feature_inds: Index of each feature (column of input count matrix). + regularized_posterior_coo: Regularized posterior. + posterior_kwargs: Keyword arguments used to generate posterior (for + caching) + regularized_posterior_kwargs: Keyword arguments used to generate + posterior (for caching) + + """ + + assert isinstance(posterior_coo, sp.coo_matrix), \ + "The posterior must be coo_matrix format in order to write to HDF5." + + assert barcode_inds.size == posterior_coo.row.size, \ + "len(barcode_inds) must match the number of entries in the posterior COO" + + assert feature_inds.size == posterior_coo.row.size, \ + "len(feature_inds) must match the number of entries in the posterior COO" + + # Write to output file. + filters = tables.Filters(complevel=1, complib='zlib', shuffle=True) + with tables.open_file( + output_file, + "w", + title="CellBender remove-background posterior noise count probabilities" + ) as f: + + # metadata + extras = f.create_group("/", "metadata", "Posterior metadata") + f.create_carray(extras, "barcode_inds", obj=barcode_inds, filters=filters) + f.create_carray(extras, "feature_inds", obj=feature_inds, filters=filters) + if noise_count_offsets != {}: + f.create_carray(extras, "noise_count_offsets_keys", + obj=list(noise_count_offsets.keys()), filters=filters) + f.create_carray(extras, "noise_count_offsets_values", + obj=list(noise_count_offsets.values()), filters=filters) + + # posterior COO + group = f.create_group("/", "posterior_noise_log_prob", "Posterior noise count log probabilities") + f.create_carray(group, "log_prob", obj=posterior_coo.data, filters=filters) + f.create_carray(group, "m_index", obj=posterior_coo.row, filters=filters) + f.create_carray(group, "noise_count", obj=posterior_coo.col, filters=filters) + f.create_carray(group, "shape", atom=tables.Int64Atom(), + obj=np.array(posterior_coo.shape, dtype=np.int64), filters=filters) + + # regularized posterior COO + if regularized_posterior_coo is not None: + group = f.create_group("/", "regularized_posterior_noise_log_prob", + "Regularized posterior noise count log probabilities") + f.create_carray(group, "log_prob", obj=regularized_posterior_coo.data, filters=filters) + f.create_carray(group, "m_index", obj=regularized_posterior_coo.row, filters=filters) + f.create_carray(group, "noise_count", obj=regularized_posterior_coo.col, filters=filters) + f.create_carray(group, "shape", atom=tables.Int64Atom(), + obj=np.array(regularized_posterior_coo.shape, dtype=np.int64), filters=filters) + + # latents + droplet_latent_group = f.create_group("/", "droplet_latents_map", "Latent variables per droplet") + for key, value in latents.items(): + if value is not None: + f.create_carray(droplet_latent_group, key, obj=value, filters=filters) + + # kwargs + if posterior_kwargs is not None: + kwargs_group = f.create_group("/", "kwargs", "Function arguments for posterior") + for key, value in posterior_kwargs.items(): + for k, v in unravel_dict(key, value).items(): + if type(v) == str: + v = np.array([v], dtype=str) + f.create_array(kwargs_group, k, v) + reg_kwargs_group = f.create_group("/", "kwargs_regularized", + "Function arguments for regularized posterior") + if regularized_posterior_kwargs is not None: + for key, value in regularized_posterior_kwargs.items(): + for k, v in unravel_dict(key, value).items(): + if type(v) == str: + v = np.array([v], dtype=str) + f.create_array(reg_kwargs_group, k, v) + + logger.info(f"Succeeded in writing posterior to file {output_file}") + + return True + + +def load_posterior_from_h5(filename: str) -> Dict[str, Union[sp.coo_matrix, np.ndarray]]: + """Load a posterior noise count COO from an h5 file. + + Args: + filename: string path to .h5 file that contains the raw gene + barcode matrices + + Returns: + Dict with ['coo', 'noise_count_offsets', 'barcode_inds', 'feature_inds'] + Posterior noise count COO + Noise count offsets for COO rows + Droplet indices for COO rows + Feature indices for COO rows + """ + + with tables.open_file(filename, 'r') as f: + + # read metadata + barcode_inds = getattr(f.root.metadata, 'barcode_inds').read() + feature_inds = getattr(f.root.metadata, 'barcode_inds').read() + if hasattr(f.root.metadata, 'noise_count_offsets_keys'): + noise_count_offsets_keys = getattr(f.root.metadata, 'noise_count_offsets_keys').read() + noise_count_offsets_values = getattr(f.root.metadata, 'noise_count_offsets_values').read() + noise_count_offsets = dict(zip(noise_count_offsets_keys, noise_count_offsets_values)) + else: + noise_count_offsets = {} + + def _read_coo(group: tables.Group) -> sp.coo_matrix: + data = getattr(group, 'log_prob').read() + row = getattr(group, 'm_index').read() + col = getattr(group, 'noise_count').read() + shape = getattr(group, 'shape').read() + return sp.coo_matrix((data, (row, col)), shape=shape) + + # read coo + posterior_coo = _read_coo(group=f.root.posterior_noise_log_prob) + + # read regularized coo + if hasattr(f.root, 'regularized_posterior_noise_log_prob'): + regularized_posterior_coo = _read_coo(group=f.root.regularized_posterior_noise_log_prob) + else: + regularized_posterior_coo = None + + def _read_as_dict(group: tables.Group) -> Dict: + d = {} + for n in group._f_walknodes('Leaf'): + val = n.read() + if (type(val) == np.ndarray) and ('S' in val.dtype.kind): + val = val.item().decode() + d.update({n.name: val}) + return d + + # read latents + latents = _read_as_dict(group=f.root.droplet_latents_map) + + # read kwargs + if hasattr(f.root, 'kwargs'): + kwargs = _read_as_dict(group=f.root.kwargs) + else: + kwargs = None + + if hasattr(f.root, 'kwargs_regularized'): + kwargs_regularized = _read_as_dict(group=f.root.kwargs_regularized) + else: + kwargs_regularized = None + + # Issue warnings if necessary, based on dimensions matching. + if posterior_coo.row.size != barcode_inds.size: + logger.warning(f"Number of barcode_inds ({barcode_inds.size}) " + f"in {filename} does not match the number expected from " + f"the sparse COO matrix ({posterior_coo.shape[0]}).") + if posterior_coo.row.size != feature_inds.size: + logger.warning(f"Number of feature_inds ({feature_inds.size}) " + f"in {filename} does not match the number expected from " + f"the sparse COO matrix ({posterior_coo.shape[0]}).") + + return {'coo': posterior_coo, + 'kwargs': kwargs, + 'regularized_coo': regularized_posterior_coo, + 'kwargs_regularized': kwargs_regularized, + 'latents': latents, + 'noise_count_offsets': noise_count_offsets, + 'feature_inds': feature_inds, + 'barcode_inds': barcode_inds} + + +def unravel_dict(pref: str, d: Dict) -> Dict: + """Unravel a nested dict, returning a dict with values that are not dicts""" + + if type(d) != dict: + return {pref: d} + out_d = {} + for k, v in d.items(): + out_d.update({pref + '_' + key: val for key, val in unravel_dict(k, v).items()}) + return out_d + + +def load_data(input_file: str)\ + -> Dict[str, Union[sp.csr_matrix, List[np.ndarray], np.ndarray]]: + """Load a dataset into the SingleCellRNACountsDataset object from + the self.input_file""" + + # Detect input data type. + load_fn = choose_data_loader(input_file=input_file) + + # Load data using the appropriate loader. + logger.info(f"Loading data from {input_file}") + data = FileLoader(load_fn).load(input_file) + + return data + + +def choose_data_loader(input_file: str) -> Callable: + """Detect the type of input data and return the relevant load function.""" + + # Error if no input data file has been specified. + assert input_file is not None, \ + 'Attempting to load data, but no input file was specified.' + + file_ext = os.path.splitext(input_file)[1] + + # Detect type. + if os.path.isdir(input_file): + return get_matrix_from_cellranger_mtx + + elif file_ext == '.h5': + return get_matrix_from_cellranger_h5 + + elif input_file.endswith('.txt.gz') or input_file.endswith('.txt'): + return get_matrix_from_dropseq_dge + + elif input_file.endswith('.csv.gz') or input_file.endswith('.csv'): + return get_matrix_from_bd_rhapsody + + elif file_ext == '.h5ad': + return get_matrix_from_anndata + + elif file_ext == '.loom': + return get_matrix_from_loom + + elif file_ext == '.npz': + return get_matrix_from_npz + + else: + raise ValueError('Failed to determine input file type for ' + + input_file + '\n' + + 'This must either be: a directory that contains ' + 'CellRanger-format MTX outputs; a single CellRanger ' + '".h5" file; a DropSeq-format DGE ".txt.gz" file; ' + 'a BD-Rhapsody-format ".csv" file; a ".h5ad" file ' + 'produced by anndata (include all barcodes); a ' + '".loom" file (include all barcodes); or a ".npz" ' + 'sparse matrix file') + + +def detect_cellranger_version_mtx(filedir: str) -> int: + """Detect which version of CellRanger (2 or 3) created this mtx directory. + + Args: + filedir: string path to .mtx file that contains the raw gene + barcode matrix in a sparse coo text format. + + Returns: + CellRanger version, either 2 or 3, as an integer. + + """ + + assert os.path.isdir(filedir), f"The directory {filedir} is not accessible." + + if os.path.isfile(os.path.join(filedir, 'features.tsv.gz')): + return 3 + + else: + return 2 + + +def detect_cellranger_version_h5(filename: str) -> int: + """Detect which version of CellRanger (2 or 3) created this h5 file. + + Args: + filename: string path to .mtx file that contains the raw gene + barcode matrix in a sparse coo text format. + + Returns: + version: CellRanger version, either 2 or 3, as an integer. + + """ + + with tables.open_file(filename, 'r') as f: + + # For CellRanger v2, each group in the table (other than root) + # contains a genome. + # For CellRanger v3, there is a 'matrix' group that contains 'features'. + + version = 2 + + try: + + # This works for version 3 but not for version 2. + getattr(f.root.matrix, 'features') + version = 3 + + except tables.NoSuchNodeError: + pass + + return version + + +def get_matrix_from_cellranger_mtx(filedir: str) \ + -> Dict[str, Union[sp.csr_matrix, List[np.ndarray], np.ndarray]]: + """Load a count matrix from an mtx directory from CellRanger's output. + + For CellRanger v2: + The directory must contain three files: + matrix.mtx + barcodes.tsv + genes.tsv + + For CellRanger v3: + The directory must contain three files: + matrix.mtx.gz + barcodes.tsv.gz + features.tsv.gz + + This function returns a dictionary that includes the count matrix, the gene + names (which correspond to columns of the count matrix), and the barcodes + (which correspond to rows of the count matrix). + + Args: + filedir: string path to .mtx file that contains the raw gene + barcode matrix in a sparse coo text format. + + Returns: + out['matrix']: scipy.sparse.csr.csr_matrix of unique UMI counts, with + barcodes as rows and genes as columns + out['barcodes']: numpy array of strings which are the nucleotide + sequences of the barcodes that correspond to the rows in + the out['matrix'] + out['gene_names']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string names of genes in the genome, which + correspond to the columns in the out['matrix']. + out['gene_ids']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string Ensembl ID of genes in the genome, which + also correspond to the columns in the out['matrix']. + out['feature_types']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string feature types of genes (or possibly + antibody capture reads), which also correspond to the columns + in the out['matrix']. + + """ + + assert os.path.isdir(filedir), "The directory {filedir} is not accessible." + + # Decide whether data is CellRanger v2 or v3. + cellranger_version = detect_cellranger_version_mtx(filedir=filedir) + logger.info(f"CellRanger v{cellranger_version} format") + + # CellRanger version 3 + if cellranger_version == 3: + + matrix_file = os.path.join(filedir, 'matrix.mtx.gz') + gene_file = os.path.join(filedir, 'features.tsv.gz') + barcode_file = os.path.join(filedir, 'barcodes.tsv.gz') + + # Read in feature names. + features = np.genfromtxt(fname=gene_file, + delimiter="\t", + skip_header=0, + dtype=str) + + # Read in gene expression and feature data. + gene_ids = features[:, 0].squeeze() # first column + gene_names = features[:, 1].squeeze() # second column + feature_types = features[:, 2].squeeze() # third column + + # CellRanger version 2 + elif cellranger_version == 2: + + # Read in the count matrix using scipy. + matrix_file = os.path.join(filedir, 'matrix.mtx') + gene_file = os.path.join(filedir, 'genes.tsv') + barcode_file = os.path.join(filedir, 'barcodes.tsv') + + # Read in gene names. + gene_data = np.genfromtxt(fname=gene_file, + delimiter="\t", + skip_header=0, + dtype=str) + if len(gene_data.shape) == 1: # custom file format with just gene names + gene_names = gene_data.squeeze() + gene_ids = None + else: # the 10x CellRanger v2 format with two columns + gene_names = gene_data[:, 1].squeeze() # second column + gene_ids = gene_data[:, 0].squeeze() # first column + feature_types = None + + else: + raise NotImplementedError('MTX format was not identifiable as CellRanger ' + 'v2 or v3. Please check 10x Genomics formatting.') + + # For both versions: + + # Read in sparse count matrix. + count_matrix = io.mmread(matrix_file).tocsr().transpose() + + # Read in barcode names. + barcodes = np.genfromtxt(fname=barcode_file, + delimiter="\t", + skip_header=0, + dtype=str) + + # Issue warnings if necessary, based on dimensions matching. + if count_matrix.shape[1] != len(gene_names): + logger.warning(f"Number of gene names in {filedir}/genes.tsv " + f"does not match the number expected from the " + f"count matrix.") + if count_matrix.shape[0] != len(barcodes): + logger.warning(f"Number of barcodes in {filedir}/barcodes.tsv " + f"does not match the number expected from the " + f"count matrix.") + + return {'matrix': count_matrix, + 'gene_names': gene_names, + 'feature_types': feature_types, + 'gene_ids': gene_ids, + 'genomes': None, + 'barcodes': barcodes, + 'cellranger_version': cellranger_version} + + +def get_matrix_from_cellranger_h5(filename: str) \ + -> Dict[str, Union[sp.csr_matrix, np.ndarray]]: + """Load a count matrix from an h5 file from CellRanger's output. + + The file needs to be a _raw_gene_bc_matrices_h5.h5 file. This function + returns a dictionary that includes the count matrix, the gene names (which + correspond to columns of the count matrix), and the barcodes (which + correspond to rows of the count matrix). + + This function works for CellRanger v2 and v3 HDF5 formats. + + Args: + filename: string path to .h5 file that contains the raw gene + barcode matrices + + Returns: + out['matrix']: scipy.sparse.csr.csr_matrix of unique UMI counts, with + barcodes as rows and genes as columns + out['barcodes']: numpy array of strings which are the nucleotide + sequences of the barcodes that correspond to the rows in + the out['matrix'] + out['gene_names']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string names of genes in the genome, which + correspond to the columns in the out['matrix']. + out['gene_ids']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string Ensembl ID of genes in the genome, which + also correspond to the columns in the out['matrix']. + out['feature_types']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string feature types of genes (or possibly + antibody capture reads), which also correspond to the columns + in the out['matrix']. + + """ + + # Detect CellRanger version. + cellranger_version = detect_cellranger_version_h5(filename=filename) + logger.info(f"CellRanger v{cellranger_version} format") + + with tables.open_file(filename, 'r') as f: + # Initialize empty lists. + csc_list = [] + barcodes = None + feature_ids = None + feature_types = None + genomes = None + + # CellRanger v2: + # Each group in the table (other than root) contains a genome, + # so walk through the groups to get data for each genome. + if cellranger_version == 2: + + feature_names = [] + feature_ids = [] + genomes = [] + + for group in f.walk_groups(): + try: + # Read in data for this genome, and put it into a + # scipy.sparse.csc.csc_matrix + barcodes = getattr(group, 'barcodes').read() + data = getattr(group, 'data').read() + indices = getattr(group, 'indices').read() + indptr = getattr(group, 'indptr').read() + shape = getattr(group, 'shape').read() + csc_list.append(sp.csc_matrix((data, indices, indptr), + shape=shape)) + fnames_this_genome = getattr(group, 'gene_names').read() + feature_names.extend(fnames_this_genome) + feature_ids.extend(getattr(group, 'genes').read()) + genomes.extend([group._g_gettitle()] * fnames_this_genome.size) + + except tables.NoSuchNodeError: + # This exists to bypass the root node, which has no data. + pass + + # Create numpy arrays. + feature_names = np.array(feature_names, dtype=str) + genomes = np.array(genomes, dtype=str) + if len(feature_ids) > 0: + feature_ids = np.array(feature_ids) + else: + feature_ids = None + + # CellRanger v3: + # There is only the 'matrix' group. + elif cellranger_version == 3: + + # Read in data for this genome, and put it into a + # scipy.sparse.csc.csc_matrix + barcodes = getattr(f.root.matrix, 'barcodes').read() + data = getattr(f.root.matrix, 'data').read() + indices = getattr(f.root.matrix, 'indices').read() + indptr = getattr(f.root.matrix, 'indptr').read() + shape = getattr(f.root.matrix, 'shape').read() + csc_list.append(sp.csc_matrix((data, indices, indptr), + shape=shape)) + + # Read in 'feature' information + feature_group = f.get_node(f.root.matrix, 'features') + feature_names = getattr(feature_group, 'name').read() + + try: + feature_types = getattr(feature_group, 'feature_type').read() + except tables.NoSuchNodeError: + # This exists in case someone produced a file without feature_type. + pass + try: + feature_ids = getattr(feature_group, 'id').read() + except tables.NoSuchNodeError: + # This exists in case someone produced a file without feature id. + pass + try: + genomes = getattr(feature_group, 'genome').read() + except tables.NoSuchNodeError: + # This exists in case someone produced a file without feature genome. + pass + + # Put the data together (possibly from several genomes for v2 datasets). + count_matrix = sp.vstack(csc_list, format='csc') + count_matrix = count_matrix.transpose().tocsr() + + # Issue warnings if necessary, based on dimensions matching. + if count_matrix.shape[1] != feature_names.size: + logger.warning(f"Number of gene names ({feature_names.size}) in {filename} " + f"does not match the number expected from the count " + f"matrix ({count_matrix.shape[1]}).") + if count_matrix.shape[0] != barcodes.size: + logger.warning(f"Number of barcodes ({barcodes.size}) in {filename} " + f"does not match the number expected from the count " + f"matrix ({count_matrix.shape[0]}).") + + return {'matrix': count_matrix, + 'gene_names': feature_names, + 'gene_ids': feature_ids, + 'genomes': genomes, + 'feature_types': feature_types, + 'barcodes': barcodes, + 'cellranger_version': cellranger_version} + + +def get_matrix_from_dropseq_dge(filename: str) \ + -> Dict[str, Union[sp.csr_matrix, np.ndarray]]: + """Load a count matrix from a DropSeq DGE matrix file. + + The file needs to be a gzipped text file in DGE format. This function + returns a dictionary that includes the count matrix, the gene names (which + correspond to columns of the count matrix), and the barcodes (which + correspond to rows of the count matrix). Reads in the file line by line + instead of trying to read in an entire dense matrix at once, which might + require quite a bit of memory. + + Args: + filename: string path to .txt.gz file that contains the raw gene + barcode matrix + + Returns: + out['matrix']: scipy.sparse.csr.csr_matrix of unique UMI counts, with + barcodes as rows and genes as columns + out['barcodes']: numpy array of strings which are the nucleotide + sequences of the barcodes that correspond to the rows in + the out['matrix'] + out['gene_names']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string names of genes in the genome, which + correspond to the columns in the out['matrix']. + out['gene_ids']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string Ensembl ID of genes in the genome, which + also correspond to the columns in the out['matrix']. + + """ + + logger.info(f"DropSeq DGE format") + + load_fcn = gzip.open if filename.endswith('.gz') else open + + with load_fcn(filename, 'rt') as f: + + # Skip the comment '#' lines in header + for header in f: + if header[0] == '#': + continue + else: + break + + # Read in first row with droplet barcodes + barcodes = header.split('\n')[0].split('\t')[1:] + + # Gene names are first entry per row + gene_names = [] + + # Arrays used to construct a sparse matrix + row = [] + col = [] + data = [] + + # Read in rest of file row by row + for i, line in enumerate(f): + # Parse row into gene name and count data + parsed_line = line.split('\n')[0].split('\t') + gene_names.append(parsed_line[0]) + counts = np.array(parsed_line[1:], dtype=int) + + # Create sparse version of data and add to arrays + nonzero_col_inds = np.nonzero(counts)[0] + row.extend([i] * nonzero_col_inds.size) + col.extend(nonzero_col_inds) + data.extend(counts[nonzero_col_inds]) + + count_matrix = sp.csc_matrix((data, (row, col)), + shape=(len(gene_names), len(barcodes)), + dtype=float).transpose() + + return {'matrix': count_matrix, + 'gene_names': np.array(gene_names), + 'gene_ids': None, + 'genomes': None, + 'feature_types': None, + 'barcodes': np.array(barcodes)} + + +def get_matrix_from_bd_rhapsody(filename: str) \ + -> Dict[str, Union[sp.csr_matrix, np.ndarray]]: + """Load a count matrix from a BD Rhapsody MolsPerCell.csv file. + + The file needs to be in MolsPerCell_Unfiltered format, which is comma + separated, where rows are barcodes and columns are genes. Can be gzipped + or not. This function returns a dictionary that includes the count matrix, + the gene names (which correspond to columns of the count matrix), and the + barcodes (which correspond to rows of the count matrix). Reads in the file + line by line instead of trying to read in an entire dense matrix at once, + which might require quite a bit of memory. + + Args: + filename: string path to .csv file that contains the raw gene + barcode matrix MolsPerCell_Unfiltered.csv + + Returns: + out['matrix']: scipy.sparse.csr.csr_matrix of unique UMI counts, with + barcodes as rows and genes as columns + out['barcodes']: numpy array of strings which are the nucleotide + sequences of the barcodes that correspond to the rows in + the out['matrix'] + out['gene_names']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string names of genes in the genome, which + correspond to the columns in the out['matrix']. + out['gene_ids']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string Ensembl ID of genes in the genome, which + also correspond to the columns in the out['matrix']. + + """ + + logger.info(f"BD Rhapsody MolsPerCell_Unfiltered.csv format") + + load_fcn = gzip.open if filename.endswith('.gz') else open + + with load_fcn(filename, 'rt') as f: + + # Skip the comment '#' lines in header + for header in f: + if header[0] == '#': + continue + else: + break + + # Read in first row with gene names + gene_names = header.split('\n')[0].split(',')[1:] + + # Barcode names are first entry per row + barcodes = [] + + # Arrays used to construct a sparse matrix + row = [] + col = [] + data = [] + + # Read in rest of file row by row + for i, line in enumerate(f): + # Parse row into gene name and count data + parsed_line = line.split('\n')[0].split(',') + barcodes.append(parsed_line[0]) + counts = np.array(parsed_line[1:], dtype=np.int) + + # Create sparse version of data and add to arrays + nonzero_col_inds = np.nonzero(counts)[0] + row.extend([i] * nonzero_col_inds.size) + col.extend(nonzero_col_inds) + data.extend(counts[nonzero_col_inds]) + + count_matrix = sp.csc_matrix((data, (row, col)), + shape=(len(barcodes), len(gene_names)), + dtype=np.float) + + return {'matrix': count_matrix, + 'gene_names': np.array(gene_names), + 'gene_ids': None, + 'genomes': None, + 'feature_types': None, + 'barcodes': np.array(barcodes)} + + +def get_matrix_from_npz(filename: str) \ + -> Dict[str, Union[sp.csr_matrix, np.ndarray]]: + """Load a count matrix from a sparse NPZ file, accompanied by barcode and + gene NPY files. + NOTE: This format is one output of the Optimus pipeline. It loads much + faster than a Loom file. The NPZ file requires two accompanying files: + 'col_index.npy' and 'row_index.npy', named exactly as shown, and in the + same directory as the NPZ file. + Args: + filename: string path to .h5ad file that contains the raw gene + barcode matrices + Returns: + out['matrix']: scipy.sparse.csr.csr_matrix of unique UMI counts, with + barcodes as rows and genes as columns + out['barcodes']: numpy array of strings which are the nucleotide + sequences of the barcodes that correspond to the rows in + the out['matrix'] + out['gene_names']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string names of genes in the genome, which + correspond to the columns in the out['matrix']. + out['gene_ids']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string Ensembl ID of genes in the genome, which + also correspond to the columns in the out['matrix']. + out['feature_types']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string feature types of genes (or possibly + antibody capture reads), which also correspond to the columns + in the out['matrix']. + """ + logger.info(f"Optimus sparse NPZ format") + try: + count_matrix = sp.load_npz(file=filename) + file_dir, _ = os.path.split(filename) + gene_ids = np.load(os.path.join(file_dir, 'col_index.npy')) + barcodes = np.load(os.path.join(file_dir, 'row_index.npy')) + except IOError as e: + logger.error('Loading an NPZ file requires two additional files in the ' + f'same directory ({file_dir}): ' + 'one called "col_index.npy" that contains genes, and one ' + 'called "row_index.npy" that contains barcodes.') + logger.error(traceback.format_exc()) + raise e + return {'matrix': count_matrix, + 'gene_names': gene_ids, # that's all we have access to, so we'll use it + 'gene_ids': gene_ids, + 'genomes': None, + 'feature_types': None, + 'barcodes': barcodes} + + +def get_matrix_from_anndata(filename: str) \ + -> Dict[str, Union[sp.csr_matrix, np.ndarray]]: + """Load a count matrix from an h5ad AnnData file. + The file needs to contain raw counts for all measured barcodes in the + `.X` attribute or a `.layer[{'counts', 'spliced'}]` attribute. This function + returns a dictionary that includes the count matrix, the gene names (which + correspond to columns of the count matrix), and the barcodes (which + correspond to rows of the count matrix). + This function works for any AnnData object meeting the above requirements, + as generated by alignment methods like `kallisto | bustools`. + Args: + filename: string path to .h5ad file that contains the raw gene + barcode matrices + Returns: + out['matrix']: scipy.sparse.csr.csr_matrix of unique UMI counts, with + barcodes as rows and genes as columns + out['barcodes']: numpy array of strings which are the nucleotide + sequences of the barcodes that correspond to the rows in + the out['matrix'] + out['gene_names']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string names of genes in the genome, which + correspond to the columns in the out['matrix']. + out['gene_ids']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string Ensembl ID of genes in the genome, which + also correspond to the columns in the out['matrix']. + out['feature_types']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string feature types of genes (or possibly + antibody capture reads), which also correspond to the columns + in the out['matrix']. + """ + logger.info(f"AnnData format") + try: + adata = anndata.read_h5ad(filename) + except anndata._io.utils.AnnDataReadError as e: + logger.error(f'A call to anndata.read_h5ad() with anndata {anndata.__version__} ' + f'threw AnnDataReadError: ') + logger.error(traceback.format_exc()) + raise e + return _dict_from_anndata(adata) + + +def get_matrix_from_loom(filename: str) \ + -> Dict[str, Union[sp.csr_matrix, np.ndarray]]: + """Load a count matrix from a loom file. + The file needs to contain raw counts for all measured barcodes in the + layer '', as in + https://broadinstitute.github.io/warp/docs/Pipelines/Optimus_Pipeline/Loom_schema/ + Returns a dictionary that includes the count matrix, the gene names (which + correspond to columns of the count matrix), and the barcodes (which + correspond to rows of the count matrix). + + Args: + filename: string path to .h5ad file that contains the raw gene + barcode matrices + + Returns: + out['matrix']: scipy.sparse.csr.csr_matrix of unique UMI counts, with + barcodes as rows and genes as columns + out['barcodes']: numpy array of strings which are the nucleotide + sequences of the barcodes that correspond to the rows in + the out['matrix'] + out['gene_names']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string names of genes in the genome, which + correspond to the columns in the out['matrix']. + out['gene_ids']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string Ensembl ID of genes in the genome, which + also correspond to the columns in the out['matrix']. + out['feature_types']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string feature types of genes (or possibly + antibody capture reads), which also correspond to the columns + in the out['matrix']. + """ + logger.info(f"Loom format, expecting Optimus pipeline conventions") + try: + adata = anndata.read_loom(filename, sparse=True, X_name='') + except anndata._io.utils.AnnDataReadError as e: + logger.error(f'A call to anndata.read_loom() with anndata {anndata.__version__} ' + f'threw AnnDataReadError: ') + logger.error(traceback.format_exc()) + raise e + return _dict_from_anndata(adata) + + +def _dict_from_anndata(adata: anndata.AnnData) -> Dict[str, Union[sp.csr_matrix, np.ndarray]]: + """Extract relevant information from AnnData and format it as a dict + + Args: + adata: AnnData object + + Returns: + out['matrix']: scipy.sparse.csr.csr_matrix of unique UMI counts, with + barcodes as rows and genes as columns + out['barcodes']: numpy array of strings which are the nucleotide + sequences of the barcodes that correspond to the rows in + the out['matrix'] + out['gene_names']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string names of genes in the genome, which + correspond to the columns in the out['matrix']. + out['gene_ids']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string Ensembl ID of genes in the genome, which + also correspond to the columns in the out['matrix']. + out['feature_types']: List of numpy arrays, where the number of elements + in the list is the number of genomes in the dataset. Each numpy + array contains the string feature types of genes (or possibly + antibody capture reads), which also correspond to the columns + in the out['matrix'].""" + + if "counts" in adata.layers.keys(): + # this is a common manual setting for users of scVI + # given the manual convention, we prefer this matrix to + # .X since it is less likely to represent something other + # than counts + logger.info("Found `.layers['counts']`. Using for count data.") + count_matrix = adata.layers["counts"] + elif "spliced" in adata.layers.keys() and adata.X is None: + # alignment using kallisto | bustools with intronic counts + # does not populate `.X` by default, but does populate + # `.layers['spliced'], .layers['unspliced']`. + # we use spliced counts for analysis + logger.info("Found `.layers['spliced']`. Using for count data.") + count_matrix = adata.layers["spliced"] + else: + logger.info("Using `.X` for count data.") + count_matrix = adata.X + + # check that `count_matrix` contains a large number of barcodes, + # consistent with a raw single cell experiment + if count_matrix.shape[0] < consts.MINIMUM_BARCODES_H5AD: + # this experiment might be prefiltered + logger.warning(f"Only {count_matrix.shape[0]} barcodes were found.\n" + "This suggests the matrix was prefiltered.\n" + "CellBender requires a raw, unfiltered [Barcodes, Genes] matrix.") + + # AnnData is [Cells, Genes], no need to transpose + # we typecast explicitly in the off chance `count_matrix` was dense. + count_matrix = sp.csr_matrix(count_matrix) + # feature names and ids are not consistently delineated in AnnData objects + # so we attempt to find relevant features using common values. + feature_names = np.array(adata.var_names, dtype=str) + barcodes = np.array(adata.obs_names, dtype=str) + + # Make an attempt to find feature_IDs if they are present. + feature_ids = None + for key in ['gene_id', 'gene_ids', 'ensembl_ids']: + if key in adata.var.keys(): + feature_ids = np.array(adata.var[key].values, dtype=str) + + # Make an attempt to find feature_types if they are present. + feature_types = None + for key in ['feature_type', 'feature_types']: + if key in adata.var.keys(): + feature_types = np.array(adata.var[key].values, dtype=str) + + # Make an attempt to find genomes if they are present. + genomes = None + for key in ['genome', 'genomes']: + if key in adata.var.keys(): + genomes = np.array(adata.var[key].values, dtype=str) + + # Issue warnings if necessary, based on dimensions matching. + if count_matrix.shape[1] != feature_names.size: + logger.warning(f"Number of gene names ({feature_names.size}) " + f"does not match the number expected from the count " + f"matrix ({count_matrix.shape[1]}).") + if count_matrix.shape[0] != barcodes.size: + logger.warning(f"Number of barcodes ({barcodes.size}) " + f"does not match the number expected from the count " + f"matrix ({count_matrix.shape[0]}).") + + return {'matrix': count_matrix, + 'gene_names': feature_names, + 'gene_ids': feature_ids, + 'genomes': genomes, + 'feature_types': feature_types, + 'barcodes': barcodes} diff --git a/cellbender/remove_background/data/priors.py b/cellbender/remove_background/data/priors.py new file mode 100644 index 00000000..39897691 --- /dev/null +++ b/cellbender/remove_background/data/priors.py @@ -0,0 +1,391 @@ +"""Functionality for estimating various priors from the data""" + +import numpy as np +import torch +from scipy.stats import gaussian_kde + +from cellbender.remove_background import consts + +from typing import Dict, Tuple, Union +import logging + + +logger = logging.getLogger('cellbender') + + +def _threshold_otsu(umi_counts: np.ndarray, n_bins: int = 256) -> float: + """Return threshold value based on fast implementation of Otsu's method. + + From skimage, with slight modifications: + https://github.com/scikit-image/scikit-image/blob/ + a4e533ea2a1947f13b88219e5f2c5931ab092413/skimage/filters/thresholding.py#L312 + + Args: + umi_counts: Array of UMI counts + n_bins: Number of bins used to calculate histogram + + Returns: + threshold: Upper threshold value. All droplets with UMI counts greater + than this value are assumed to contain cells. + + References + ---------- + .. [1] Wikipedia, https://en.wikipedia.org/wiki/Otsu's_Method + .. [2] https://scikit-image.org/docs/stable/auto_examples/applications/plot_thresholding.html + + Notes + ----- + The input image must be grayscale. + """ + + # create a UMI count histogram + counts, bin_centers = _create_histogram(umi_counts=umi_counts, n_bins=n_bins) + + # class probabilities for all possible thresholds + weight1 = np.cumsum(counts) + weight2 = np.cumsum(counts[::-1])[::-1] + + # class means for all possible thresholds + mean1 = np.cumsum(counts * bin_centers) / weight1 + mean2 = (np.cumsum((counts * bin_centers)[::-1]) / weight2[::-1])[::-1] + + # Clip ends to align class 1 and class 2 variables: + # The last value of ``weight1``/``mean1`` should pair with zero values in + # ``weight2``/``mean2``, which do not exist. + variance12 = weight1[:-1] * weight2[1:] * (mean1[:-1] - mean2[1:]) ** 2 + + idx = np.argmax(variance12) + threshold = bin_centers[idx] + + return threshold + + +def _create_histogram(umi_counts: np.ndarray, n_bins: int) -> Tuple[np.ndarray, np.ndarray]: + """Return a histogram. + + Args: + umi_counts: Array of UMI counts + n_bins: Number of bins used to calculate histogram + + Returns: + counts: Each element is the number of droplets falling in each UMI + count bin + bin_centers: Each element is the value corresponding to the center of + each UMI count bin + """ + counts, bin_edges = np.histogram(umi_counts.reshape(-1), n_bins) + bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2 + return counts.astype('float32', copy=False), bin_centers + + +def _peak_density_given_cutoff(umi_counts: np.ndarray, + cutoff: float, + cell_count_low_limit: float) -> Tuple[float, float]: + """Run scipy.stats gaussian_kde on part of the UMI curve""" + + # get the UMI count values we are including + noncell_counts = umi_counts[umi_counts <= cutoff] + + # resample them: the magic of looking at a log log plot + n_putative_cells = (umi_counts > cell_count_low_limit).sum() + n_putative_empties = len(noncell_counts) + inds = np.logspace(np.log10(n_putative_cells), + np.log10(n_putative_cells + n_putative_empties), + num=1000, + base=10) + inds = [max(0, min(int(ind - n_putative_cells), len(noncell_counts) - 1)) for ind in inds] + + noncell_counts = np.sort(noncell_counts)[::-1][inds] + + # find the peak density: that is the empty count prior + + # calculate range of data, rounding out to make sure we cover everything + log_noncell_counts = np.log(noncell_counts) + x = np.arange( + np.floor(log_noncell_counts.min()) - 0.01, + np.ceil(log_noncell_counts.max()) + 0.01, + 0.1 + ) + + # fit a KDE to estimate density + k = gaussian_kde(log_noncell_counts) + density = k.evaluate(x) + + # the density peak is almost surely the empty droplets + log_peak_ind = np.argmax(density) + log_peak = x[log_peak_ind] + empty_count_prior = np.exp(log_peak) + + # try to go about 1 stdev up from the peak + peak_density = np.max(density) + one_std_density = 0.6 * peak_density + one_std_inds = np.where(density[log_peak_ind:] < one_std_density)[0] + if len(one_std_inds) > 0: + one_std_ind = one_std_inds[0] + else: + one_std_ind = len(density[log_peak_ind:]) - 1 + empty_count_upper_limit = np.exp(x[log_peak_ind:][one_std_ind]) + + return empty_count_prior, empty_count_upper_limit + + +def get_cell_count_given_expected_cells(umi_counts: np.ndarray, + expected_cells: int) -> Dict[str, float]: + """In the case where a prior is passed in as input, use it + + Args: + umi_counts: Array of UMI counts per droplet, in no particular order + expected_cells: Input by user + + Returns: + Dict with keys ['cell_counts'] + """ + order = np.argsort(umi_counts)[::-1] + cell_counts = np.exp(np.mean(np.log(umi_counts[order][:expected_cells]))).item() + return {'cell_counts': cell_counts} + + +def get_empty_count_given_expected_cells_and_total_droplets( + umi_counts: np.ndarray, + expected_cells: int, + total_droplets: int, +) -> Dict[str, float]: + """In the case where a prior is passed in as input, use it + + Args: + umi_counts: Array of UMI counts per droplet, in no particular order + expected_cells: Input by user, or prior estimate + total_droplets: Input by user + + Returns: + Dict with keys ['empty_counts', 'empty_count_upper_limit'] + """ + + order = np.argsort(umi_counts)[::-1] + starting_point = max(expected_cells, total_droplets - 500) + empty_counts = np.median(umi_counts[order] + [int(starting_point):int(total_droplets)]).item() + + # need to estimate here + cell_counts = np.exp(np.mean(np.log(umi_counts[order][:expected_cells]))).item() + middle = np.sqrt(cell_counts * empty_counts) + empty_count_upper_limit = min(middle, 1.5 * empty_counts) + + return {'empty_counts': empty_counts, + 'empty_count_upper_limit': empty_count_upper_limit} + + +def get_cell_count_empty_count(umi_counts: np.ndarray, + low_count_threshold: float = 15) -> Dict[str, float]: + """Obtain priors on cell counts and empty droplet counts from a UMI curve + using heuristics, and without applying any other prior information. + + Heuristics: + 0. Ignore droplets with counts below low_count_threshold + 1. Use Otsu's method to threshold the log UMI count data (ignoring droplets + past 1/4 of the total droplets above low_count_threshold, as we go down + the UMI curve). This is used as a lower limit on cell counts. + It seems quite robust. + 2. Use the following iterative approach, until converged: + a. Establish an upper cutoff on possible empty droplets, using the + current estimate of empty counts and our cell count prior (the + estimate is 3/4 of the geometric mean of the two). + b. Use gaussian_kde from scipy.stats to create a smooth histogram of + the log UMI counts, for droplets with counts below the cutoff. + - A trick is used to resample the droplets before creating the + histogram, so that it looks more like a log-log plot + c. Identify the peak density of the histogram as the empty count + estimate. + - Convergence happens when our estimate of empty counts stops changing. + + Args: + umi_counts: Array of UMI counts per droplet, in no particular order + low_count_threshold: Ignore droplets with counts below this value + + Returns: + Dict with keys ['cell_counts', 'empty_counts'] + """ + + logger.debug('Beginning priors.get_cell_count_empty_count()') + reverse_sorted_umi_counts = np.sort(umi_counts)[::-1] + umi_counts_for_otsu = reverse_sorted_umi_counts[:(umi_counts > low_count_threshold).sum() // 4] + + log_cell_count_low_limit = _threshold_otsu(np.log(umi_counts_for_otsu)) + cell_count_low_limit = np.exp(log_cell_count_low_limit) + + logger.debug(f'cell_count_low_limit is {cell_count_low_limit}') + cell_count_prior = np.mean(umi_counts[umi_counts > cell_count_low_limit]) + + umi_counts_for_kde = reverse_sorted_umi_counts[reverse_sorted_umi_counts > low_count_threshold] + + # initial conditions for the loop + # start low, but have a failsafe (especially for simulated data) + cutoff = max(0.1 * cell_count_low_limit, umi_counts_for_kde[-100]) + empty_count_prior = -100 + empty_count_upper_limit = None + delta = np.inf + a = 0 + + # iterate to convergence, at most 5 times + while delta > 10: + logger.debug(f'cutoff = {cutoff}') + + # use gaussian_kde to find the peak in the histogram + new_empty_count_prior, empty_count_upper_limit = _peak_density_given_cutoff( + umi_counts=umi_counts_for_kde, + cutoff=cutoff, + cell_count_low_limit=cell_count_low_limit, + ) + logger.debug(f'new_empty_count_prior = {new_empty_count_prior}') + + # 3/4 of the geometric mean is our new upper cutoff + cutoff = 0.75 * np.sqrt(cell_count_prior * new_empty_count_prior) + delta = np.abs(new_empty_count_prior - empty_count_prior) + logger.debug(f'delta = {delta}') + empty_count_prior = new_empty_count_prior + a += 1 + if a >= 5: + logger.debug('Heuristics for determining empty counts exceeded 5 ' + 'iterations without converging') + break + + # do a final estimation of cell counts: + # go to the halfway point and then take the median of the droplets above + count_crossover = np.sqrt(cell_count_prior * empty_count_prior) + cell_count_prior = np.median(umi_counts[umi_counts > count_crossover]) + + logger.debug(f'cell_count_prior is {cell_count_prior}') + logger.debug(f'empty_count_prior is {empty_count_prior}') + logger.debug('End of priors.get_cell_count_empty_count()') + + return {'cell_counts': cell_count_prior, + 'empty_counts': empty_count_prior, + 'empty_count_upper_limit': empty_count_upper_limit} + + +def get_expected_cells_and_total_droplets(umi_counts: np.ndarray, + cell_counts: float, + empty_counts: float, + empty_count_upper_limit: float, + max_empties: int = consts.MAX_EMPTIES_TO_INCLUDE) \ + -> Dict[str, int]: + """Obtain priors on cell counts and empty droplet counts from a UMI curve + using heuristics, and without applying any other prior information. + + NOTE: to be run using inputs from get_cell_count_empty_count() + + Args: + umi_counts: Array of UMI counts per droplet, in no particular order + cell_counts: Prior from get_cell_count_empty_count() + empty_counts: Prior from get_cell_count_empty_count() + empty_count_upper_limit: Prior from get_cell_count_empty_count() + max_empties: Do not include more putative empty droplets than this + + Returns: + Dict with keys ['expected_cells', 'total_droplets', 'transition_point'] + + Example: + >>> priors = get_cell_count_empty_count(umi_counts) + >>> priors.update(get_expected_cells_and_total_droplets(umi_counts, **priors)) + """ + # expected cells does well when you give it a very conservative estimate + expected_cells = (umi_counts >= cell_counts).sum() + + # total droplets will be between empty_count_prior and its upper limit + total_droplets_count_value = np.sqrt(empty_counts * empty_count_upper_limit) + total_droplets = (umi_counts >= total_droplets_count_value).sum() + + # find the transition point + count_crossover = np.sqrt(cell_counts * empty_counts) + transition_point = (umi_counts >= count_crossover).sum() + + logger.debug(f'In get_expected_cells_and_total_droplets(), found transition ' + f'point at droplet {transition_point}') + + # ensure out heuristics don't go too far out datasets with many cells + total_droplets = min(total_droplets, transition_point + max_empties) + + return {'expected_cells': expected_cells, + 'total_droplets': total_droplets, + 'transition_point': transition_point} + + +def get_priors(umi_counts: np.ndarray, + low_count_threshold: float, + max_total_droplets: int = consts.MAX_TOTAL_DROPLETS_GUESSED) \ + -> Dict[str, Union[int, float]]: + """Get all priors using get_cell_count_empty_count() and + get_expected_cells_and_total_droplets(), employing a failsafe if + total_droplets is improbably large. + + Args: + umi_counts: Array of UMI counts per droplet, in no particular order + low_count_threshold: Ignore droplets with counts below this value + max_total_droplets: If the initial heuristics come up with a + total_droplets value greater than this, we re-run the heuristics + with higher low_count_threshold + + Returns: + Dict with keys ['cell_counts', 'empty_counts', + 'empty_count_upper_limit', 'surely_empty_counts', + 'expected_cells', 'total_droplets', 'log_counts_crossover'] + """ + + logger.debug("Computing priors from the UMI curve") + priors = get_cell_count_empty_count( + umi_counts=umi_counts, + low_count_threshold=low_count_threshold, + ) + priors.update(get_expected_cells_and_total_droplets(umi_counts=umi_counts, **priors)) + logger.debug(f'Automatically computed priors: {priors}') + + a = 0 + while priors['total_droplets'] > max_total_droplets: + logger.debug(f'Heuristics for estimating priors resulted in ' + f'{priors["total_droplets"]} total_droplets, which is ' + f'typically too large. Recomputing with ' + f'low_count_threshold = {priors["empty_count_upper_limit"]:.0f}') + priors = get_cell_count_empty_count( + umi_counts=umi_counts, + low_count_threshold=priors['empty_count_upper_limit'], + ) + priors.update(get_expected_cells_and_total_droplets(umi_counts=umi_counts, **priors)) + logger.debug(f'Automatically computed priors: {priors}') + a += 1 + if a > 5: + break + + # compute a few last things + compute_crossover_surely_empty_and_stds(umi_counts=umi_counts, priors=priors) + + return priors + + +def compute_crossover_surely_empty_and_stds(umi_counts, priors): + """Given cell_counts and total_droplets, compute a few more quantities + + Args: + umi_counts: Array of UMI counts per droplet, in no particular order + priors: Dict of priors + + Returns: + None. Modifies priors dict in place. + """ + + assert 'total_droplets' in priors.keys(), \ + 'Need total_droplets in priors to run compute_crossover_surely_empty_and_stds()' + assert 'cell_counts' in priors.keys(), \ + 'Need cell_counts in priors to run compute_crossover_surely_empty_and_stds()' + + # Compute a crossover point in log count space. + reverse_sorted_counts = np.sort(umi_counts)[::-1] + surely_empty_counts = reverse_sorted_counts[priors['total_droplets']] + log_counts_crossover = (np.log(surely_empty_counts) + np.log(priors['cell_counts'])) / 2 + priors.update({'log_counts_crossover': log_counts_crossover, + 'surely_empty_counts': surely_empty_counts}) + + # Compute several other priors. + log_nonzero_umi_counts = np.log(umi_counts[umi_counts > 0]) + d_std = np.std(log_nonzero_umi_counts[log_nonzero_umi_counts > log_counts_crossover]).item() / 5. + d_empty_std = 0.01 # this is basically turned off in favor of epsilon + priors.update({'d_std': d_std, 'd_empty_std': d_empty_std}) diff --git a/cellbender/remove_background/distributions/NegativeBinomialPoissonConvApprox.py b/cellbender/remove_background/distributions/NegativeBinomialPoissonConvApprox.py index 1f08481c..1420df3c 100644 --- a/cellbender/remove_background/distributions/NegativeBinomialPoissonConvApprox.py +++ b/cellbender/remove_background/distributions/NegativeBinomialPoissonConvApprox.py @@ -118,7 +118,7 @@ def log_prob(self, value): value=value) # Use a poisson for small mu, where the above approximation is bad. - empty_indices = (mu < 1e-5) + empty_indices = (mu < 1e-5 * lam) poisson_log_prob = self._poisson_log_prob(lam=lam[empty_indices], value=value[empty_indices]) diff --git a/cellbender/remove_background/downstream.py b/cellbender/remove_background/downstream.py new file mode 100644 index 00000000..7f669379 --- /dev/null +++ b/cellbender/remove_background/downstream.py @@ -0,0 +1,479 @@ +"""Functions for downstream work with outputs of remove-background.""" + +from cellbender.remove_background.data.io import load_data + +import tables +import numpy as np +import scipy.sparse as sp +import anndata +from typing import Dict, Optional + + +def dict_from_h5(file: str) -> Dict[str, np.ndarray]: + """Read in everything from an h5 file and put into a dictionary. + + Args: + file: The h5 file + + Returns: + Dictionary containing all the information from the h5 file + """ + d = {} + with tables.open_file(file) as f: + # read in everything + for array in f.walk_nodes("/", "Array"): + d[array.name] = array.read() + return d + + +def anndata_from_h5(file: str, + analyzed_barcodes_only: bool = True) -> anndata.AnnData: + """Load an output h5 file into an AnnData object for downstream work. + + Args: + file: The h5 file + analyzed_barcodes_only: False to load all barcodes, so that the size of + the AnnData object will match the size of the input raw count matrix. + True to load a limited set of barcodes: only those analyzed by the + algorithm. This allows relevant latent variables to be loaded + properly into adata.obs and adata.obsm, rather than adata.uns. + + Returns: + anndata.AnnData: The anndata object, populated with inferred latent variables + and metadata. + + """ + + d = dict_from_h5(file) + X = sp.csc_matrix((d.pop('data'), d.pop('indices'), d.pop('indptr')), + shape=d.pop('shape')).transpose().tocsr() + + # check and see if we have barcode index annotations, and if the file is filtered + barcode_key = [k for k in d.keys() if (('barcode' in k) and ('ind' in k))] + if len(barcode_key) > 0: + max_barcode_ind = d[barcode_key[0]].max() + filtered_file = (max_barcode_ind >= X.shape[0]) + else: + filtered_file = True + + if analyzed_barcodes_only: + if filtered_file: + # filtered file being read, so we don't need to subset + print('Assuming we are loading a "filtered" file that contains only cells.') + pass + elif 'barcode_indices_for_latents' in d.keys(): + X = X[d['barcode_indices_for_latents'], :] + d['barcodes'] = d['barcodes'][d['barcode_indices_for_latents']] + elif 'barcodes_analyzed_inds' in d.keys(): + X = X[d['barcodes_analyzed_inds'], :] + d['barcodes'] = d['barcodes'][d['barcodes_analyzed_inds']] + else: + print('Warning: analyzed_barcodes_only=True, but the key ' + '"barcodes_analyzed_inds" or "barcode_indices_for_latents" ' + 'is missing from the h5 file. ' + 'Will output all barcodes, and proceed as if ' + 'analyzed_barcodes_only=False') + + # Construct the anndata object. + adata = anndata.AnnData(X=X, + obs={'barcode': d.pop('barcodes').astype(str)}, + var={'gene_name': (d.pop('gene_names') if 'gene_names' in d.keys() + else d.pop('name')).astype(str)}, + dtype=X.dtype) + adata.obs.set_index('barcode', inplace=True) + adata.var.set_index('gene_name', inplace=True) + + # For CellRanger v2 legacy format, "gene_ids" was called "genes"... rename this + if 'genes' in d.keys(): + d['id'] = d.pop('genes') + + # For purely aesthetic purposes, rename "id" to "gene_id" + if 'id' in d.keys(): + d['gene_id'] = d.pop('id') + + # If genomes are empty, try to guess them based on gene_id + if 'genome' in d.keys(): + if np.array([s.decode() == '' for s in d['genome']]).all(): + if '_' in d['gene_id'][0].decode(): + print('Genome field blank, so attempting to guess genomes based on gene_id prefixes') + d['genome'] = np.array([s.decode().split('_')[0] for s in d['gene_id']], dtype=str) + + # Add other information to the anndata object in the appropriate slot. + _fill_adata_slots_automatically(adata, d) + + # Add a special additional field to .var if it exists. + if 'features_analyzed_inds' in adata.uns.keys(): + adata.var['cellbender_analyzed'] = [True if (i in adata.uns['features_analyzed_inds']) + else False for i in range(adata.shape[1])] + elif 'features_analyzed_inds' in adata.var.keys(): + adata.var['cellbender_analyzed'] = [True if (i in adata.var['features_analyzed_inds'].values) + else False for i in range(adata.shape[1])] + + if analyzed_barcodes_only: + for col in adata.obs.columns[adata.obs.columns.str.startswith('barcodes_analyzed') + | adata.obs.columns.str.startswith('barcode_indices')]: + try: + del adata.obs[col] + except Exception: + pass + else: + # Add a special additional field to .obs if all barcodes are included. + if 'barcodes_analyzed_inds' in adata.uns.keys(): + adata.obs['cellbender_analyzed'] = [True if (i in adata.uns['barcodes_analyzed_inds']) + else False for i in range(adata.shape[0])] + elif 'barcodes_analyzed_inds' in adata.obs.keys(): + adata.obs['cellbender_analyzed'] = [True if (i in adata.obs['barcodes_analyzed_inds'].values) + else False for i in range(adata.shape[0])] + + return adata + + +def _fill_adata_slots_automatically(adata, d): + """Add other information to the adata object in the appropriate slot.""" + + # TODO: what about "features_analyzed_inds"? If not all features are analyzed, does this work? + + for key, value in d.items(): + try: + if value is None: + continue + value = np.asarray(value) + if len(value.shape) == 0: + adata.uns[key] = value + elif value.shape[0] == adata.shape[0]: + if (len(value.shape) < 2) or (value.shape[1] < 2): + adata.obs[key] = value + else: + adata.obsm[key] = value + elif value.shape[0] == adata.shape[1]: + if value.dtype.name.startswith('bytes'): + adata.var[key] = value.astype(str) + else: + adata.var[key] = value + else: + adata.uns[key] = value + except Exception: + print('Unable to load data into AnnData: ', key, value, type(value)) + + +def load_anndata_from_input(input_file: str) -> anndata.AnnData: + """Load an input file into an AnnData object (used in report generation). + Equivalent to something like scanpy.read(), but uses cellbender's io. + + Args: + input_file: The raw data file + + Returns: + adata.AnnData: The anndata object + + """ + + # Load data as dict. + d = load_data(input_file=input_file) + + # For purely aesthetic purposes, rename slots from the plural to singluar. + for key in ['gene_id', 'barcode', 'genome', 'feature_type', 'gene_name']: + if key + 's' in d.keys(): + d[key] = d.pop(key + 's') + + # Create anndata object from dict. + adata = anndata.AnnData(X=d.pop('matrix'), + obs={'barcode': d.pop('barcode').astype(str)}, + var={'gene_name': d.pop('gene_name').astype(str)}, + dtype=int) + adata.obs.set_index('barcode', inplace=True) + adata.var.set_index('gene_name', inplace=True) + + # Add other information to the anndata object in the appropriate slot. + _fill_adata_slots_automatically(adata, d) + + return adata + + +def load_anndata_from_input_and_output(input_file: str, + output_file: str, + analyzed_barcodes_only: bool = True, + input_layer_key: str = 'cellranger', + retain_input_metadata: bool = False, + gene_expression_encoding_key: str = 'cellbender_embedding', + truth_file: Optional[str] = None) -> anndata.AnnData: + """Load remove-background output count matrix into an anndata object, + together with remove-background metadata and the raw input counts. + + Args: + input_file: Raw h5 file (or other compatible remove-background input) + used as input for remove-background. + output_file: Output h5 file created by remove-background (can be + filtered or not). + analyzed_barcodes_only: Argument passed to anndata_from_h5(). + False to load all barcodes, so that the size of + the AnnData object will match the size of the input raw count matrix. + True to load a limited set of barcodes: only those analyzed by the + algorithm. This allows relevant latent variables to be loaded + properly into adata.obs and adata.obsm, rather than adata.uns. + input_layer_key: Key of the anndata.layer that is created for the raw + input count matrix. + retain_input_metadata: In addition to loading the CellBender metadata, + which happens automatically, set this to True to retain all the + metadata from the raw input file as well. + gene_expression_encoding_key: The CellBender gene expression embedding + will be loaded into adata.obsm[gene_expression_encoding_key] + truth_file: File containing truth data if this is a simulation + + Return: + anndata.AnnData: AnnData object with counts before and after remove-background, + as well as inferred latent variables from remove-background. + + """ + + # Load input data. + adata_raw = load_anndata_from_input(input_file=input_file) + + # Load remove-background output data. + adata_out = anndata_from_h5(output_file, analyzed_barcodes_only=analyzed_barcodes_only) + + # Subset the raw dataset to the relevant barcodes. + adata_raw = adata_raw[adata_out.obs.index] + + # TODO: keep the stuff from the raw file too: from obs and var and uns + # TODO: maybe use _fill_adata_slots_automatically()? or just copy stuff + + # Put count matrices into 'layers' in anndata for clarity. + adata_out.layers[input_layer_key] = adata_raw.X.copy() + adata_out.layers['cellbender'] = adata_out.X.copy() + + # Pre-compute a bit of metadata. + adata_out.var['n_' + input_layer_key] = \ + np.array(adata_out.layers[input_layer_key].sum(axis=0), dtype=int).squeeze() + adata_out.var['n_cellbender'] = \ + np.array(adata_out.layers['cellbender'].sum(axis=0), dtype=int).squeeze() + adata_out.obs['n_' + input_layer_key] = \ + np.array(adata_out.layers[input_layer_key].sum(axis=1), dtype=int).squeeze() + adata_out.obs['n_cellbender'] = \ + np.array(adata_out.layers['cellbender'].sum(axis=1), dtype=int).squeeze() + + # Load truth data, if present. + if truth_file is not None: + adata_truth = anndata_from_h5(truth_file, analyzed_barcodes_only=False) + adata_truth = adata_truth[adata_out.obs.index] + adata_out.layers['truth'] = adata_truth.X.copy() + adata_out.var['n_truth'] = np.array(adata_out.layers['truth'].sum(axis=0), dtype=int).squeeze() + adata_out.obs['n_truth'] = np.array(adata_out.layers['truth'].sum(axis=1), dtype=int).squeeze() + for key in adata_truth.obs.keys(): + if key.startswith('truth_'): + adata_out.obs[key] = adata_truth.obs[key].copy() + for key in adata_truth.uns.keys(): + if key.startswith('truth_'): + adata_out.uns[key] = adata_truth.uns[key].copy() + for key in adata_truth.var.keys(): + if key.startswith('truth_'): + adata_out.var[key] = adata_truth.var[key].copy() + + # Rename the CellBender encoding of gene expression. + if analyzed_barcodes_only: + slot = adata_out.obsm + else: + slot = adata_out.uns + embedding_key = None + for key in ['gene_expression_encoding', 'latent_gene_encoding']: + if key in slot.keys(): + embedding_key = key + break + if gene_expression_encoding_key != embedding_key: + slot[gene_expression_encoding_key] = slot[embedding_key].copy() + del slot[embedding_key] + + return adata_out + + +def _load_anndata_from_input_and_decontx(input_file: str, + output: str, + input_layer_key: str = 'cellranger', + truth_file: Optional[str] = None) -> anndata.AnnData: + """Load decontX output count matrix into an anndata object, + together with remove-background metadata and the raw input counts. + + NOTE: this is used only for dev purposes and only in the report + + Args: + input_file: Raw h5 file (or other compatible remove-background input) + used as input for remove-background. + output: Output h5 file, or a directory where decontX MTX and TSV files + are stored + input_layer_key: Key of the anndata.layer that is created for the raw + input count matrix. + truth_file: File containing truth data if this is a simulation + + Return: + anndata.AnnData: AnnData object with counts before and after remove-background, + as well as inferred latent variables from remove-background. + + """ + + # Load decontX output data. + print('UNSTABLE FEATURE: Trying to load decontX format MTX output') + adata_out = load_anndata_from_input(input_file=output) + adata_out.var_names_make_unique() + + # Load input data. + adata_raw = load_anndata_from_input(input_file=input_file) + adata_raw.var_names_make_unique() + + adata_raw = adata_raw[:, [g in adata_out.var.index for g in adata_raw.var.index]].copy() + adata_out.var['genome'] = adata_raw.var['genome'].copy() + adata_out.var['feature_type'] = adata_raw.var['feature_type'].copy() + adata_out.var['gene_id'] = adata_raw.var['gene_id'].copy() + + # Subset the raw dataset to the relevant barcodes. + empty_logic = np.array([b not in adata_out.obs.index for b in adata_raw.obs.index]) + empty_counts = np.array(adata_raw.X[empty_logic].sum(axis=1)).squeeze() + approx_ambient = np.array(adata_raw.X[empty_logic][empty_counts > 5].sum(axis=0)).squeeze() + approx_ambient = approx_ambient / (approx_ambient.sum() + 1e-10) + print(f'Estimated that there are about {np.median(empty_counts[empty_counts > 5])} counts in empties') + adata_raw = adata_raw[adata_out.obs.index].copy() + adata_out.uns['empty_droplet_size_lognormal_loc'] = np.log(np.median(empty_counts[empty_counts > 5])) + + # Put count matrices into 'layers' in anndata for clarity. + adata_out.layers[input_layer_key] = adata_raw.X.copy() + adata_out.layers['decontx'] = adata_out.X.copy() + + # Pre-compute a bit of metadata. + adata_out.var['n_' + input_layer_key] = np.array(adata_out.layers[input_layer_key].sum(axis=0)).squeeze() + adata_out.var['n_decontx'] = np.array(adata_out.layers['decontx'].sum(axis=0)).squeeze() + adata_out.obs['n_' + input_layer_key] = np.array(adata_out.layers[input_layer_key].sum(axis=1)).squeeze() + adata_out.obs['n_decontx'] = np.array(adata_out.layers['decontx'].sum(axis=1)).squeeze() + adata_out.obs['cell_probability'] = 1. # because decontx data contains only cells + adata_out.uns['target_false_positive_rate'] = 0.01 # TODO: placeholder + adata_out.uns['approximate_ambient_profile'] = approx_ambient + adata_out.var['ambient_expression'] = np.nan + + # Load truth data, if present. + if truth_file is not None: + adata_truth = anndata_from_h5(truth_file, analyzed_barcodes_only=False) + adata_truth = adata_truth[adata_out.obs.index] + + # TODO; a check + adata_truth = adata_truth[:, [g in adata_out.var.index for g in adata_truth.var.index]].copy() + + adata_out.layers['truth'] = adata_truth.X.copy() + adata_out.var['n_truth'] = np.array(adata_out.layers['truth'].sum(axis=0)).squeeze() + adata_out.obs['n_truth'] = np.array(adata_out.layers['truth'].sum(axis=1)).squeeze() + for key in adata_truth.obs.keys(): + if key.startswith('truth_'): + adata_out.obs[key] = adata_truth.obs[key].copy() + for key in adata_truth.uns.keys(): + if key.startswith('truth_'): + adata_out.uns[key] = adata_truth.uns[key].copy() + for key in adata_truth.var.keys(): + if key.startswith('truth_'): + adata_out.var[key] = adata_truth.var[key].copy() + + return adata_out + + +def load_anndata_from_input_and_outputs(input_file: str, + output_files: Dict[str, str], + analyzed_barcodes_only: bool = True, + input_layer_key: str = 'cellranger', + gene_expression_encoding_key: str = 'cellbender_embedding', + truth_file: Optional[str] = None) -> anndata.AnnData: + """Load remove-background output count matrices into an anndata object, + together with remove-background metadata and the raw input counts. + + The use case would typically be cellbender runs with multiple output files + at different FPRs, which we want to compare. + + Args: + input_file: Raw h5 file (or other compatible remove-background input) + used as input for remove-background. + output_files: Output h5 files created by remove-background (can be + filtered or not) or some other method. Dict whose keys are layer keys + and whose values are file names. + analyzed_barcodes_only: Argument passed to anndata_from_h5(). + False to load all barcodes, so that the size of + the AnnData object will match the size of the input raw count matrix. + True to load a limited set of barcodes: only those analyzed by the + algorithm. This allows relevant latent variables to be loaded + properly into adata.obs and adata.obsm, rather than adata.uns. + input_layer_key: Key of the anndata.layer that is created for the raw + input count matrix. + gene_expression_encoding_key: The CellBender gene expression embedding + will be loaded into adata.obsm[gene_expression_encoding_key] + truth_file: File containing truth data if this is a simulation + + Return: + anndata.AnnData: AnnData object with counts before and after remove-background, + as well as inferred latent variables from remove-background. + + """ + + # Load input data. + adata_raw = load_anndata_from_input(input_file=input_file) + adata_raw.var_names_make_unique() + + # Load remove-background output data. + assert type(output_files) == dict, 'output_files must be a dict whose keys are ' \ + 'layer names and whose values are file paths.' + outs = {} + for key, output_file in output_files.items(): + outs[key] = anndata_from_h5(output_file, analyzed_barcodes_only=analyzed_barcodes_only) + outs[key].var_names_make_unique() + + # Subset all datasets to the relevant barcodes and features. + relevant_barcodes = set(adata_raw.obs_names) + relevant_features = set(adata_raw.var_names) + for key, ad in outs.items(): + relevant_barcodes = relevant_barcodes.intersection(set(ad.obs_names)) + relevant_features = relevant_features.intersection(set(ad.var_names)) + if len(relevant_barcodes) < len(adata_raw): + print(f'Warning: subsetting to barcodes common to all datasets: there ' + f'are {len(relevant_barcodes)}') + if len(relevant_features) < adata_raw.shape[1]: + print(f'Warning: subsetting to features common to all datasets: there ' + f'are {len(relevant_features)}') + adata_raw = adata_raw[list(relevant_barcodes)].copy() + adata_raw = adata_raw[:, list(relevant_features)].copy() + for i, (key, ad) in enumerate(outs.items()): + outs[key] = ad[list(relevant_barcodes)].copy() + outs[key] = outs[key][:, list(relevant_features)].copy() + if i == 0: + print(f'Loading latent variables from one output file: {key}') + adata_out = outs[key].copy() + + # Put count matrices into 'layers' in anndata for clarity. + adata_out.layers[input_layer_key] = adata_raw.X.copy() + for key, ad in outs.items(): + adata_out.layers[key] = ad.X.copy() + + # Load truth data, if present. + if truth_file is not None: + adata_truth = anndata_from_h5(truth_file, analyzed_barcodes_only=False) + adata_truth = adata_truth[adata_out.obs.index] + adata_out.layers['truth'] = adata_truth.X.copy() + adata_out.var['n_truth'] = np.array(adata_out.layers['truth'].sum(axis=0)).squeeze() + adata_out.obs['n_truth'] = np.array(adata_out.layers['truth'].sum(axis=1)).squeeze() + for key in adata_truth.obs.keys(): + if key.startswith('truth_'): + adata_out.obs[key] = adata_truth.obs[key].copy() + for key in adata_truth.uns.keys(): + if key.startswith('truth_'): + adata_out.uns[key] = adata_truth.uns[key].copy() + for key in adata_truth.var.keys(): + if key.startswith('truth_'): + adata_out.var[key] = adata_truth.var[key].copy() + + # Rename the CellBender encoding of gene expression. + if analyzed_barcodes_only: + slot = adata_out.obsm + else: + slot = adata_out.uns + embedding_key = None + for key in ['gene_expression_encoding', 'latent_gene_encoding']: + if key in slot.keys(): + embedding_key = key + break + if gene_expression_encoding_key != embedding_key: + slot[gene_expression_encoding_key] = slot[embedding_key].copy() + del slot[embedding_key] + + return adata_out diff --git a/cellbender/remove_background/estimation.py b/cellbender/remove_background/estimation.py new file mode 100644 index 00000000..24437248 --- /dev/null +++ b/cellbender/remove_background/estimation.py @@ -0,0 +1,902 @@ +"""Classes and methods for estimation of noise counts, given a posterior.""" + +import scipy.sparse as sp +import numpy as np +import pandas as pd +import torch +from torch.distributions.categorical import Categorical + +from cellbender.remove_background.sparse_utils import log_prob_sparse_to_dense + +from abc import ABC, abstractmethod +from functools import partial +from itertools import repeat +import multiprocessing as mp +import concurrent.futures +import time +from datetime import datetime +import logging +from typing import Callable, Union, Dict, Generator, Tuple, List, Optional + + +logger = logging.getLogger('cellbender') + + +class EstimationMethod(ABC): + """Base class for estimation of noise counts, given a posterior.""" + + def __init__(self, index_converter: 'IndexConverter'): + """Instantiate the EstimationMethod. + Args: + index_converter: The IndexConverter that can be used to translate + back and forth between count matrix (n, g) indices, and the + flattened, generalized 'm' indices that index the posterior COO. + """ + self.index_converter = index_converter + super(EstimationMethod, self).__init__() + + @abstractmethod + def estimate_noise(self, + noise_log_prob_coo: sp.coo_matrix, + noise_offsets: Dict[int, int], + **kwargs) -> sp.csr_matrix: + """Given the full probabilistic posterior, compute noise counts. + Args: + noise_log_prob_coo: The noise log prob data structure: log prob + values in a (m, c) COO matrix + noise_offsets: Noise count offset values keyed by 'm'. + """ + pass + + def _estimation_array_to_csr(self, + data: np.ndarray, + m: np.ndarray, + noise_offsets: Optional[Dict[int, int]], + dtype=np.int64) -> sp.csr_matrix: + """Say you have point estimates for each count matrix element (data) and + you have the 'm'-indices for each value (m). This returns a CSR matrix + that has the shape of the count matrix, where duplicate entries have + been summed. + + Args: + data: Point estimates for each nonzero entry of the count matrix, in + a flat format, indexed by 'm'. + m: Array of the same length as data, where each entry is an m-index. + noise_offsets: Noise count offset values keyed by 'm'. + dtype: Data type for sparse matrix. Int32 is too small for 'm' indices. + + Results: + noise_csr: Noise point estimate, as a CSR sparse matrix. + + """ + return _estimation_array_to_csr( + index_converter=self.index_converter, + data=data, + m=m, + noise_offsets=noise_offsets, + dtype=dtype, + ) + # row, col = self.index_converter.get_ng_indices(m_inds=m) + # if noise_offsets is not None: + # data = data + np.array([noise_offsets[i] for i in m]) + # coo = sp.coo_matrix((data.astype(dtype), (row.astype(dtype), col.astype(dtype))), + # shape=self.index_converter.matrix_shape, dtype=dtype) + # coo.sum_duplicates() + # return coo.tocsr() + + +class SingleSample(EstimationMethod): + """A single sample from the noise count posterior""" + + @torch.no_grad() + def estimate_noise(self, + noise_log_prob_coo: sp.coo_matrix, + noise_offsets: Dict[int, int], + device: str = 'cpu', + **kwargs) -> sp.csr_matrix: + """Given the full probabilistic posterior, compute noise counts by + taking a single sample from each probability distribution. + + Args: + noise_log_prob_coo: The noise log prob data structure: log prob + values in a (m, c) COO matrix + noise_offsets: Noise count offset values keyed by 'm'. + device: ['cpu', 'cuda'] - whether to perform the pytorch sampling + operation on CPU or GPU. It's pretty fast on CPU already. + + Returns: + noise_count_csr: Estimated noise count matrix. + """ + def _torch_sample(x): + return Categorical(logits=x, validate_args=False).sample() + + result = apply_function_dense_chunks(noise_log_prob_coo=noise_log_prob_coo, + fun=_torch_sample, + device=device) + return self._estimation_array_to_csr(data=result['result'], m=result['m'], + noise_offsets=noise_offsets) + + +class Mean(EstimationMethod): + """Posterior mean""" + + def estimate_noise(self, + noise_log_prob_coo: sp.coo_matrix, + noise_offsets: Dict[int, int], + device: str = 'cpu', + **kwargs) -> sp.csr_matrix: + """Given the full probabilistic posterior, compute noise counts by + taking the mean of each probability distribution. + + Args: + noise_log_prob_coo: The noise log prob data structure: log prob + values in a (m, c) COO matrix + noise_offsets: Noise count offset values keyed by 'm'. + + Returns: + noise_count_csr: Estimated noise count matrix. + """ + # c = torch.arange(noise_log_prob_coo.shape[1], dtype=float).to(device).t() + + def _torch_mean(x): + c = torch.arange(x.shape[1], dtype=float).to(x.device) + return torch.matmul(x.exp(), c.t()) + + result = apply_function_dense_chunks(noise_log_prob_coo=noise_log_prob_coo, + fun=_torch_mean, + device=device) + return self._estimation_array_to_csr(data=result['result'], m=result['m'], + noise_offsets=noise_offsets, + dtype=np.float32) + + +class MAP(EstimationMethod): + """The canonical maximum a posteriori""" + + @staticmethod + def torch_argmax(x): + return x.argmax(dim=-1) + + def estimate_noise(self, + noise_log_prob_coo: sp.coo_matrix, + noise_offsets: Dict[int, int], + device: str = 'cpu', + **kwargs) -> sp.csr_matrix: + """Given the full probabilistic posterior, compute noise counts by + taking the maximum a posteriori (MAP) of each probability distribution. + + Args: + noise_log_prob_coo: The noise log prob data structure: log prob + values in a (m, c) COO matrix + noise_offsets: Noise count offset values keyed by 'm'. + device: ['cpu', 'cuda'] - whether to perform the pytorch argmax + operation on CPU or GPU. It's pretty fast on CPU already. + + Returns: + noise_count_csr: Estimated noise count matrix. + """ + result = apply_function_dense_chunks(noise_log_prob_coo=noise_log_prob_coo, + fun=self.torch_argmax, + device=device) + return self._estimation_array_to_csr(data=result['result'], m=result['m'], + noise_offsets=noise_offsets) + + +class ThresholdCDF(EstimationMethod): + """Noise estimation via thresholding the noise count CDF""" + + @staticmethod + def torch_cdf_fun(x: torch.Tensor, q: float): + return (x.exp().cumsum(dim=-1) <= q).sum(dim=-1) + + def estimate_noise(self, + noise_log_prob_coo: sp.coo_matrix, + noise_offsets: Dict[int, int], + q: float = 0.5, + device: str = 'cpu', + **kwargs) -> sp.csr_matrix: + """Given the full probabilistic posterior, compute noise counts + + Args: + noise_log_prob_coo: The noise log prob data structure: log prob + values in a (m, c) COO matrix + noise_offsets: Noise count offset values keyed by 'm'. + q: The CDF threshold value. + + Returns: + noise_count_csr: Estimated noise count matrix. + """ + result = apply_function_dense_chunks(noise_log_prob_coo=noise_log_prob_coo, + fun=self.torch_cdf_fun, + device=device, + q=q) + return self._estimation_array_to_csr(data=result['result'], m=result['m'], + noise_offsets=noise_offsets) + + +def _estimation_array_to_csr(index_converter, + data: np.ndarray, + m: np.ndarray, + noise_offsets: Optional[Dict[int, int]], + dtype=np.int64) -> sp.csr_matrix: + """Say you have point estimates for each count matrix element (data) and + you have the 'm'-indices for each value (m). This returns a CSR matrix + that has the shape of the count matrix, where duplicate entries have + been summed. + + Args: + data: Point estimates for each nonzero entry of the count matrix, in + a flat format, indexed by 'm'. + m: Array of the same length as data, where each entry is an m-index. + noise_offsets: Noise count offset values keyed by 'm'. + dtype: Data type for sparse matrix. Int32 is too small for 'm' indices. + + Results: + noise_csr: Noise point estimate, as a CSR sparse matrix. + + """ + row, col = index_converter.get_ng_indices(m_inds=m) + if noise_offsets is not None: + data = data + np.array([noise_offsets.get(i, 0) for i in m]) + coo = sp.coo_matrix((data.astype(dtype), (row.astype(dtype), col.astype(dtype))), + shape=index_converter.matrix_shape, dtype=dtype) + coo.sum_duplicates() + return coo.tocsr() + + +def _mckp_chunk_estimate_noise( + noise_log_prob_coo: sp.coo_matrix, + index_and_logic: Tuple[int, np.ndarray], + noise_offsets: Dict[int, int], + noise_targets_per_gene: np.ndarray, + index_converter: 'IndexConverter', + n_chunks: int, + verbose: bool = False) -> sp.csr_matrix: + """Given the full probabilistic posterior, compute noise counts. This is + to be run for a given chunk of genes at a time. + + Args: + noise_log_prob_coo: The noise log prob data structure: log prob + values in a (m, c) COO matrix. One chunk. + index_and_logic: (chunk_index, logical_coo_indexer) from the chunked + iterator, as you would get from enumerate() + noise_targets_per_gene: Integer noise count target for each gene + noise_offsets: Noise count offset values keyed by 'm'. + index_converter: IndexConverter to go from 'm' to (n, g) + n_chunks: Total chunks, for logging purposes only + verbose: True to print lots of intermediate information (for tests) + + Returns: + noise_count_csr: Estimated noise count matrix. + """ + + i = index_and_logic[0] + + if i == 0: + tt = time.time() + + coo = _subset_coo(noise_log_prob_coo, index_and_logic[1]) + + assert noise_targets_per_gene.size == index_converter.total_n_genes, \ + f'The number of noise count targets ({noise_targets_per_gene.size}) ' \ + f'must match the number of genes ({index_converter.total_n_genes})' + + # First we need to compute the MAP to find out which direction to go. + t = time.time() + map_dict = apply_function_dense_chunks( + noise_log_prob_coo=coo, + fun=MAP.torch_argmax, + device='cpu', + ) + map_csr = _estimation_array_to_csr( + data=map_dict['result'], + m=map_dict['m'], + noise_offsets=noise_offsets, + index_converter=index_converter, + ) + logger.debug(f'{timestamp()} Computed initial MAP estimate') + logger.debug(f'{timestamp()} Time for MAP calculation = {(time.time() - t):.2f} sec') + map_noise_counts_per_gene = np.array(map_csr.sum(axis=0)).squeeze() + additional_noise_counts_per_gene = (noise_targets_per_gene + - map_noise_counts_per_gene).astype(int) + set_positive_genes = set(np.where(additional_noise_counts_per_gene > 0)[0]) + set_negative_genes = set(np.where(additional_noise_counts_per_gene < 0)[0]) # leave out exact matches + abs_additional_noise_counts_per_gene = np.abs(additional_noise_counts_per_gene) + + # Determine which genes need to add and which need to subtract noise counts. + n, g = index_converter.get_ng_indices(m_inds=coo.row) + df = pd.DataFrame(data={'m': coo.row, + 'n': n, + 'g': g, + 'c': coo.col, + 'log_prob': coo.data}) + logger.debug(f'{timestamp()} Computing step directions') + df['positive_step_gene'] = df['g'].apply(lambda gene: gene in set_positive_genes) + df['negative_step_gene'] = df['g'].apply(lambda gene: gene in set_negative_genes) + df['step_direction'] = (df['positive_step_gene'].astype(int) + - df['negative_step_gene'].astype(int)) # -1 or 1 + logger.debug(f'{timestamp()} Step directions done') + + if verbose: + pd.set_option('display.width', 120) + pd.set_option('display.max_columns', 20) + print(df, end='\n\n') + + # Remove all 'm' entries corresponding to genes where target is met by MAP. + df = df[df['step_direction'] != 0] + + # Now we mask out log probs (-np.inf) that represent steps in the wrong direction. + logger.debug(f'{timestamp()} Masking') + lookup_map_from_m = dict(zip(map_dict['m'], map_dict['result'])) + df['map'] = df['m'].apply(lambda x: lookup_map_from_m[x]) + df['mask'] = ((df['negative_step_gene'] & (df['c'] > df['map'])) + | (df['positive_step_gene'] & (df['c'] < df['map']))) # keep MAP + df.loc[df['mask'], 'log_prob'] = -np.inf + logger.debug(f'{timestamp()} Masking done') + + # And we remove those entries. + df = df[~df['mask']] + df = df[[c for c in df.columns if (c != 'mask')]] + + # Sort + logger.debug(f'{timestamp()} Sorting') + df = df.sort_values(by=['m', 'c']) + logger.debug(f'{timestamp()} Sorting done') + + if verbose: + print(df, end='\n\n') + + # Do diff for positive and negative separately, without grouping (faster) + df_positive_steps = df[df['step_direction'] == 1].copy() + df_negative_steps = df[df['step_direction'] == -1].copy() + + logger.debug(f'{timestamp()} Computing deltas') + if len(df_positive_steps > 0): + df_positive_steps.loc[:, 'delta'] = df_positive_steps['log_prob'].diff(periods=1).apply(np.abs) + df_positive_steps.loc[df_positive_steps['c'] == df_positive_steps['map'], 'delta'] = np.nan + if len(df_negative_steps > 0): + df_negative_steps.loc[:, 'delta'] = df_negative_steps['log_prob'].diff(periods=-1).apply(np.abs) + df_negative_steps.loc[df_negative_steps['c'] == df_negative_steps['map'], 'delta'] = np.nan + df = pd.concat([df_positive_steps, df_negative_steps], axis=0) + logger.debug(f'{timestamp()} Computing deltas done') + + if verbose: + print(df, end='\n\n') + + # if this is an empty dataframe, we are not doing anything here beyond MAP + if len(df) == 0: + return map_csr + + # Remove irrelevant entries: those with infinite delta. + df = df[df['delta'].apply(np.isfinite)] + + # if this is an empty dataframe, we are not doing anything here beyond MAP + if len(df) == 0: + return map_csr + + # How many additional noise counts ("steps") we will need for each gene. + logger.debug(f'{timestamp()} Computing nsmallest') + df['topk'] = df['g'].apply(lambda gene: abs_additional_noise_counts_per_gene[gene]) + + if verbose: + print(df, end='\n\n') + + # Now we want the smallest additional_noise_counts_per_gene deltas for each gene. + # https://stackoverflow.com/questions/55179493/ + df_out = df[['m', 'g', 'delta', 'topk']].groupby('g', group_keys=False).apply( + lambda x: x.nsmallest(x['topk'].iat[0], columns='delta') + ) + logger.debug(f'{timestamp()} Computing nsmallest done') + + if verbose: + print(df_out, end='\n\n') + + # if this is an empty dataframe, we are not doing anything here beyond MAP + if len(df_out) == 0: + return map_csr + + # And the number by which to increment noise counts per entry 'm' is + # now the number of times that each m value appears in this dataframe. + logger.debug(f'{timestamp()} Summarizing steps') + vc = df_out['m'].value_counts() + vc_df = pd.DataFrame(data={'m': vc.index, 'steps': vc.values}) + step_direction_lookup_from_m = dict(zip(df['m'], df['step_direction'])) + vc_df['step_direction'] = vc_df['m'].apply(lambda x: step_direction_lookup_from_m[x]) + vc_df['counts'] = vc_df['steps'] * vc_df['step_direction'] + steps_csr = _estimation_array_to_csr( + data=vc_df['counts'], + m=vc_df['m'], + noise_offsets=None, + index_converter=index_converter, + ) + logger.debug(f'{timestamp()} Summarizing steps done') + + if verbose: + print(vc_df, end='\n\n') + print('MAP:') + print(map_csr.todense()) + + logger.info(f'Completed chunk ({i + 1} / {n_chunks})') + print(f'Completed chunk ({i + 1} / {n_chunks})') # because logging from a process does not work right + if i == 0: + logger.info(f' [single chunk took {(time.time() - tt):.2f} mins]') + print(f' [single chunk took {(time.time() - tt):.2f} mins]') + + # The final output is those tabulated steps added to the MAP. + # The MAP already has the noise offsets, so they are not added to steps_csr. + return map_csr + steps_csr + + +class MultipleChoiceKnapsack(EstimationMethod): + """Noise estimation via solving a constrained multiple choice knapsack problem""" + + def estimate_noise(self, + noise_log_prob_coo: sp.coo_matrix, + noise_offsets: Dict[int, int], + noise_targets_per_gene: np.ndarray, + verbose: bool = False, + n_chunks: Optional[int] = None, + use_multiple_processes: bool = False, + **kwargs) -> sp.csr_matrix: + """Given the full probabilistic posterior, compute noise counts + + Args: + noise_log_prob_coo: The noise log prob data structure: log prob + values in a (m, c) COO matrix + noise_targets_per_gene: Integer noise count target for each gene + noise_offsets: Noise count offset values keyed by 'm'. + verbose: True to print lots of intermediate information (for tests) + n_chunks: Target number of chunks over which to split estimation. + If None, targets about 5000 genes per chunk. + use_multiple_processes: True to use multiprocessing. Seems faster + without using it, not entirely clear why + + Returns: + noise_count_csr: Estimated noise count matrix. + """ + if n_chunks is None: + n_chunks = max(1, self.index_converter.total_n_genes // 5000) + logger.debug(f'Running MCKP estimator in {n_chunks} chunks') + + t0 = time.time() + + if use_multiple_processes: + + logger.info('Dividing dataset into chunks of genes') + chunk_logic_list = list( + self._gene_chunk_iterator( + noise_log_prob_coo=noise_log_prob_coo, + n_chunks=n_chunks, + ) + ) + + logger.info('Computing the output in asynchronous chunks in parallel...') + + # with mp.get_context('spawn').Pool(processes=mp.cpu_count()) as pool: + # csr_matrices = pool.starmap( + # _mckp_chunk_estimate_noise, + # zip( + # repeat(noise_log_prob_coo), + # enumerate(chunk_logic_list), + # repeat(noise_offsets), + # repeat(noise_targets_per_gene), + # repeat(self.index_converter), + # repeat(n_chunks), + # repeat(False), # verbose + # ), + # ) + + futures = [] + with concurrent.futures.ProcessPoolExecutor( + max_workers=mp.cpu_count(), + mp_context=mp.get_context('spawn')) as executor: + for i, logic in enumerate(chunk_logic_list): + kwargs = { + 'noise_log_prob_coo': noise_log_prob_coo, + 'index_and_logic': (i, logic), + 'noise_offsets': noise_offsets, + 'noise_targets_per_gene': noise_targets_per_gene, + 'index_converter': self.index_converter, + 'n_chunks': n_chunks, + 'verbose': False, + } + future = executor.submit(_mckp_chunk_estimate_noise, **kwargs) + futures.append(future) + + done, not_done = concurrent.futures.wait( + futures, + return_when=concurrent.futures.ALL_COMPLETED, + ) + csr_matrices = [f.result() for f in futures] + + else: + + t = time.time() + + csr_matrices = [] + for i, logic in enumerate( + self._gene_chunk_iterator( + noise_log_prob_coo=noise_log_prob_coo, + n_chunks=n_chunks, + ) + ): + logger.info(f'Working on chunk ({i + 1}/{n_chunks})') + chunk_csr = self._chunk_estimate_noise( + noise_log_prob_coo=_subset_coo(noise_log_prob_coo, logic), + noise_offsets=noise_offsets, + noise_targets_per_gene=noise_targets_per_gene, + verbose=verbose, + ) + csr_matrices.append(chunk_csr) + if i == 0: + logger.info(f' [{(time.time() - t) / 60:.2f} mins per chunk]') + logger.debug(f'{timestamp()} Estimator chunk {i}: shape is {chunk_csr.shape}') + + logger.info(f'{timestamp()} Total MCKP estimation time = {(time.time() - t0):.2f} sec') + return sum(csr_matrices) + + def _gene_chunk_iterator(self, + noise_log_prob_coo: sp.coo_matrix, + n_chunks: int) \ + -> Generator[np.ndarray, None, None]: + """Yields chunks of the posterior that can be treated as independent, + from the standpoint of MCKP count estimation. That is, they contain all + matrix entries for any genes they include. + + Args: + noise_log_prob_coo: Full noise log prob posterior COO + n_chunks: For testing, force this many chunks + + Yields: + Logical array which indexes elements of coo posterior for the chunk + """ + + # TODO this generator is way too slow + + # approximate number of entries in a chunk + # approx_chunk_entries = (noise_log_prob_coo.data.size - 1) // n_chunks + + # get gene annotations + _, genes = self.index_converter.get_ng_indices(m_inds=noise_log_prob_coo.row) + genes_series = pd.Series(genes) + + # things we need to keep track of for each chunk + # current_chunk_genes = [] + # entry_logic = np.zeros(noise_log_prob_coo.data.size, dtype=bool) + + # TODO eliminate for loop to speed this up + # take the list of genes from the coo, sort it, and divide it evenly + # somehow break ties for genes overlapping boundaries of divisions + sorted_genes = np.sort(genes) + gene_arrays = np.array_split(sorted_genes, n_chunks) + last_gene_set = {} + for gene_array in gene_arrays: + gene_set = set(gene_array) + gene_set = gene_set.difference(last_gene_set) # only the new stuff + # if there is a second chunk, make sure there is a gene unique to it + if (n_chunks > 1) and (len(gene_set) == len(set(genes))): # all genes in first set + # this mainly exists for tests + gene_set = gene_set - {gene_arrays[-1][-1]} + last_gene_set = gene_set + entry_logic = genes_series.isin(gene_set).values + if sum(entry_logic) > 0: + yield entry_logic + + def _chunk_estimate_noise(self, + noise_log_prob_coo: sp.coo_matrix, + noise_offsets: Dict[int, int], + noise_targets_per_gene: np.ndarray, + verbose: bool = False) -> sp.csr_matrix: + """Given the full probabilistic posterior, compute noise counts. This is + to be run for a given chunk of genes at a time. + + Args: + noise_log_prob_coo: The noise log prob data structure: log prob + values in a (m, c) COO matrix. One chunk. + noise_targets_per_gene: Integer noise count target for each gene + noise_offsets: Noise count offset values keyed by 'm'. + verbose: True to print lots of intermediate information (for tests) + + Returns: + noise_count_csr: Estimated noise count matrix. + """ + + assert noise_targets_per_gene.size == self.index_converter.total_n_genes, \ + f'The number of noise count targets ({noise_targets_per_gene.size}) ' \ + f'must match the number of genes ({self.index_converter.total_n_genes})' + + coo = noise_log_prob_coo.copy() # we will be modifying values + + # First we need to compute the MAP to find out which direction to go. + t = time.time() + map_dict = apply_function_dense_chunks(noise_log_prob_coo=noise_log_prob_coo, + fun=MAP.torch_argmax, + device='cpu') + map_csr = self._estimation_array_to_csr(data=map_dict['result'], + m=map_dict['m'], + noise_offsets=noise_offsets) + logger.debug(f'{timestamp()} Computed initial MAP estimate') + logger.debug(f'{timestamp()} Time for MAP calculation = {(time.time() - t):.2f} sec') + map_noise_counts_per_gene = np.array(map_csr.sum(axis=0)).squeeze() + additional_noise_counts_per_gene = (noise_targets_per_gene + - map_noise_counts_per_gene).astype(int) + set_positive_genes = set(np.where(additional_noise_counts_per_gene > 0)[0]) + set_negative_genes = set(np.where(additional_noise_counts_per_gene < 0)[0]) # leave out exact matches + abs_additional_noise_counts_per_gene = np.abs(additional_noise_counts_per_gene) + + # Determine which genes need to add and which need to subtract noise counts. + n, g = self.index_converter.get_ng_indices(m_inds=coo.row) + df = pd.DataFrame(data={'m': coo.row, + 'n': n, + 'g': g, + 'c': coo.col, + 'log_prob': coo.data}) + logger.debug(f'{timestamp()} Computing step directions') + df['positive_step_gene'] = df['g'].apply(lambda gene: gene in set_positive_genes) + df['negative_step_gene'] = df['g'].apply(lambda gene: gene in set_negative_genes) + df['step_direction'] = (df['positive_step_gene'].astype(int) + - df['negative_step_gene'].astype(int)) # -1 or 1 + logger.debug(f'{timestamp()} Step directions done') + + if verbose: + pd.set_option('display.width', 120) + pd.set_option('display.max_columns', 20) + print(df, end='\n\n') + + # Remove all 'm' entries corresponding to genes where target is met by MAP. + df = df[df['step_direction'] != 0] + + # Now we mask out log probs (-np.inf) that represent steps in the wrong direction. + logger.debug(f'{timestamp()} Masking') + lookup_map_from_m = dict(zip(map_dict['m'], map_dict['result'])) + df['map'] = df['m'].apply(lambda x: lookup_map_from_m[x]) + df['mask'] = ((df['negative_step_gene'] & (df['c'] > df['map'])) + | (df['positive_step_gene'] & (df['c'] < df['map']))) # keep MAP + df.loc[df['mask'], 'log_prob'] = -np.inf + logger.debug(f'{timestamp()} Masking done') + + # And we remove those entries. + df = df[~df['mask']] + df = df[[c for c in df.columns if (c != 'mask')]] + + # Sort + logger.debug(f'{timestamp()} Sorting') + df = df.sort_values(by=['m', 'c']) + logger.debug(f'{timestamp()} Sorting done') + + if verbose: + print(df, end='\n\n') + + # Do diff for positive and negative separately, without grouping (faster) + df_positive_steps = df[df['step_direction'] == 1].copy() + df_negative_steps = df[df['step_direction'] == -1].copy() + + logger.debug(f'{timestamp()} Computing deltas') + if len(df_positive_steps > 0): + df_positive_steps.loc[:, 'delta'] = df_positive_steps['log_prob'].diff(periods=1).apply(np.abs) + df_positive_steps.loc[df_positive_steps['c'] == df_positive_steps['map'], 'delta'] = np.nan + if len(df_negative_steps > 0): + df_negative_steps.loc[:, 'delta'] = df_negative_steps['log_prob'].diff(periods=-1).apply(np.abs) + df_negative_steps.loc[df_negative_steps['c'] == df_negative_steps['map'], 'delta'] = np.nan + df = pd.concat([df_positive_steps, df_negative_steps], axis=0) + logger.debug(f'{timestamp()} Computing deltas done') + + if verbose: + print(df, end='\n\n') + + # if this is an empty dataframe, we are not doing anything here beyond MAP + if len(df) == 0: + return map_csr + + # Remove irrelevant entries: those with infinite delta. + df = df[df['delta'].apply(np.isfinite)] + + # if this is an empty dataframe, we are not doing anything here beyond MAP + if len(df) == 0: + return map_csr + + # How many additional noise counts ("steps") we will need for each gene. + logger.debug(f'{timestamp()} Computing nsmallest') + df['topk'] = df['g'].apply(lambda gene: abs_additional_noise_counts_per_gene[gene]) + + if verbose: + print(df, end='\n\n') + + # Now we want the smallest additional_noise_counts_per_gene deltas for each gene. + # https://stackoverflow.com/questions/55179493/ + df_out = df[['m', 'g', 'delta', 'topk']].groupby('g', group_keys=False).apply( + lambda x: x.nsmallest(x['topk'].iat[0], columns='delta') + ) + logger.debug(f'{timestamp()} Computing nsmallest done') + + if verbose: + print(df_out, end='\n\n') + + # if this is an empty dataframe, we are not doing anything here beyond MAP + if len(df_out) == 0: + return map_csr + + # And the number by which to increment noise counts per entry 'm' is + # now the number of times that each m value appears in this dataframe. + logger.debug(f'{timestamp()} Summarizing steps') + vc = df_out['m'].value_counts() + vc_df = pd.DataFrame(data={'m': vc.index, 'steps': vc.values}) + step_direction_lookup_from_m = dict(zip(df['m'], df['step_direction'])) + vc_df['step_direction'] = vc_df['m'].apply(lambda x: step_direction_lookup_from_m[x]) + vc_df['counts'] = vc_df['steps'] * vc_df['step_direction'] + steps_csr = self._estimation_array_to_csr(data=vc_df['counts'], + m=vc_df['m'], + noise_offsets=None) + logger.debug(f'{timestamp()} Summarizing steps done') + + if verbose: + print(vc_df, end='\n\n') + print('MAP:') + print(map_csr.todense()) + + # The final output is those tabulated steps added to the MAP. + # The MAP already has the noise offsets, so they are not added to steps_csr. + return map_csr + steps_csr + + +def chunked_iterator(coo: sp.coo_matrix, + max_dense_batch_size_GB: float = 1.) \ + -> Generator[Tuple[sp.coo_matrix, np.ndarray], None, None]: + """Return an iterator which yields the full dataset in chunks. + + NOTE: Idea is to prevent memory overflow. The use case is for worst-case + scenario algorithms that have to make things into dense matrix chunks in + order to do their compute. + + Args: + coo: Sparse COO matrix with rows as generalized 'm'-indices and + columns as noise count values. + max_dense_batch_size_GB: Size of a batch on disk, in gigabytes. + + Returns: + A generator that yields compact CSR sparse matrices until the whole dataset + has been yielded. "Compact" in the sense that if they are made dense, there + will be no all-zero rows. + Tuple[chunk csr, actual row values in the full matrix] + + """ + n_elements_in_batch = max_dense_batch_size_GB * 1e9 / 4 # torch float32 is 4 bytes + batch_size = max(1, int(np.floor(n_elements_in_batch / coo.shape[1]))) + + # COO rows are not necessarily contiguous or in order + unique_m_values = np.unique(coo.row) + n_chunks = max(1, len(unique_m_values) // batch_size) + row_m_value_chunks = np.array_split(unique_m_values, n_chunks) + coo_row_series = pd.Series(coo.row) + + for row_m_values in row_m_value_chunks: + logic = coo_row_series.isin(set(row_m_values)) + # Map these row values to a compact set of unique integers + unique_row_values, rows = np.unique(coo.row[logic], return_inverse=True) + unique_col_values, cols = np.unique(coo.col[logic], return_inverse=True) + chunk_coo = sp.coo_matrix( + (coo.data[logic], (rows, cols)), + shape=(len(unique_row_values), len(unique_col_values)), + ) + yield (chunk_coo, unique_row_values, unique_col_values) + + +def apply_function_dense_chunks(noise_log_prob_coo: sp.coo_matrix, + fun: Callable[[torch.Tensor], torch.Tensor], + device: str = 'cpu', + **kwargs) \ + -> Dict[str, np.ndarray]: + """Uses chunked_iterator to densify chunked portions of a COO sparse + matrix and then applies a function to the dense chunks, keeping track + of the results per row. + + NOTE: The function should produce one value per row of the dense matrix. + The COO should contain log probability in data. + + Args: + noise_log_prob_coo: The posterior noise count log prob data structure, + indexed by 'm' as rows + fun: Pytorch function that operates on a dense tensor and produces + one value per row + device: ['cpu', 'cuda'] - whether to perform the pytorch sampling + operation on CPU or GPU. It's pretty fast on CPU already. + **kwargs: Passed to fun + + Returns: + Dict containing + 'm': np.ndarray of indices + 'result': the values computed by the function + + """ + array_length = len(np.unique(noise_log_prob_coo.row)) + + m = np.zeros(array_length) + out = np.zeros(array_length) + a = 0 + + for coo, row, col in chunked_iterator(coo=noise_log_prob_coo): + dense_tensor = torch.tensor(log_prob_sparse_to_dense(coo)).to(device) + if torch.numel(dense_tensor) == 0: + # github issue 207 + continue + s = fun(dense_tensor, **kwargs) + if s.ndim == 0: + # avoid "TypeError: len() of a 0-d tensor" + len_s = 1 + else: + len_s = len(s) + m[a:(a + len_s)] = row + out[a:(a + len_s)] = s.detach().cpu().numpy() + a = a + len_s + + return {'m': m.astype(int), 'result': out} + + +def pandas_grouped_apply(coo: sp.coo_matrix, + fun: Callable[[pd.DataFrame], Union[int, float]], + extra_data: Optional[Dict[str, np.ndarray]] = None, + sort_first: bool = False, + parallel: bool = False) -> Dict[str, np.array]: + """Apply function on a sparse COO format (noise log probs) to compute output + noise counts using pandas groupby and apply operations on CPU. + + TODO: consider numpy-groupies or np.ufunc.reduceat or similar + https://stackoverflow.com/questions/31790819/scipy-sparse-csr-matrix-how-to-get-top-ten-values-and-indices + + Args: + coo: COO data structure: (m, c) with 'm'-indexing. + fun: Function to be applied with pandas .apply(): turns + all the values for a matrix entry (m, :) into one number. + extra_data: To include extra information other than 'm', 'c', and the + 'log_prob', you can pass in a dict here with array values the same + length as 'm' and in the same order. + sort_first: Sort the whole dataframe by ['m', 'c'] before applying + function (much faster than sorting inside the function call). + parallel: Use multiprocessing to run on all cores. This is 4x slower for + a dataset of 300 cells. Not clear if it's faster for larger data. + + Returns: + output_csr: The aggregated sparse matrix, in row format + """ + df = pd.DataFrame(data={'m': coo.row, 'c': coo.col, 'log_prob': coo.data}) + if extra_data is not None: + for k, v in extra_data.items(): + df[k] = v + if sort_first: + df = df.sort_values(by=['m', 'c'], ascending=[True, True]) + if parallel: + m, result_per_m = _parallel_pandas_apply(df_grouped=df.groupby('m'), fun=fun) + else: + df = df.groupby('m').apply(fun).reset_index() + m = df['m'].values + result_per_m = df[0].values + return {'m': m, 'result': result_per_m} + + +def _parallel_pandas_apply(df_grouped: pd.core.groupby.DataFrameGroupBy, + fun: Callable[[pd.DataFrame], Union[int, float]])\ + -> Tuple[np.ndarray, np.ndarray]: + """Use multiprocessing to apply a function to a grouped dataframe in pandas. + + Args: + df_grouped: Grouped dataframe, as in df.groupby('m') + fun: Function to be applied to dataframe, as in df.groupby('m').apply(fun) + + Returns: + Tuple of (groupby_value, groupby_apply_output_for_each_value) + + NOTE: see https://stackoverflow.com/questions/26187759/parallelize-apply-after-pandas-groupby + """ + groupby_val, group_df_list = zip(*[(group_val, group_df) + for group_val, group_df in df_grouped]) + with mp.Pool(mp.cpu_count()) as p: + output_list = p.map(fun, group_df_list) + return np.array(groupby_val), np.array(output_list) + + +def _subset_coo(coo: sp.coo_matrix, logic: np.ndarray) -> sp.coo_matrix: + return sp.coo_matrix((coo.data[logic], (coo.row[logic], coo.col[logic]))) + + +def timestamp() -> str: + return datetime.now().strftime('%Y-%m-%d %H:%M:%S') diff --git a/cellbender/remove_background/exceptions.py b/cellbender/remove_background/exceptions.py index 4136b7d7..c8f321d3 100644 --- a/cellbender/remove_background/exceptions.py +++ b/cellbender/remove_background/exceptions.py @@ -1,4 +1,4 @@ -# Exceptions defined by CellBender +"""Exceptions defined by CellBender""" class NanException(ArithmeticError): @@ -11,3 +11,14 @@ class NanException(ArithmeticError): def __init__(self, param: str): self.param = param self.message = 'A wild NaN appeared! In param {' + self.param + '}' + + +class ElboException(ValueError): + """Exception raised when training procedure is failing to meet expectations. + + Attributes: + message: Message to write to log + """ + + def __init__(self, message: str): + self.message = message diff --git a/cellbender/remove_background/infer.py b/cellbender/remove_background/infer.py deleted file mode 100644 index a6a2dac9..00000000 --- a/cellbender/remove_background/infer.py +++ /dev/null @@ -1,781 +0,0 @@ -# Posterior inference. - -import logging -from abc import ABC, abstractmethod -from typing import Tuple, List, Dict, Optional - -import numpy as np -import pyro -import pyro.distributions as dist -import scipy.sparse as sp -import torch - -import cellbender.remove_background.consts as consts - - -class Posterior(ABC): - """Base class Posterior handles posterior count inference. - - Args: - dataset_obj: Dataset object. - vi_model: Trained RemoveBackgroundPyroModel. - counts_dtype: Data type of posterior count matrix. Can be one of - [np.uint32, np.float] - float_threshold: For floating point count matrices, counts below - this threshold will be set to zero, for the purposes of constructing - a sparse matrix. Unused if counts_dtype is np.uint32 - - Properties: - mean: Posterior count mean, as a sparse matrix. - - """ - - def __init__(self, - dataset_obj: 'SingleCellRNACountsDataset', # Dataset - vi_model: 'RemoveBackgroundPyroModel', - counts_dtype: np.dtype = np.uint32, - float_threshold: float = 0.5): - self.dataset_obj = dataset_obj - self.vi_model = vi_model - self.use_cuda = vi_model.use_cuda - self.analyzed_gene_inds = dataset_obj.analyzed_gene_inds - self.count_matrix_shape = dataset_obj.data['matrix'].shape - self.barcode_inds = np.arange(0, self.count_matrix_shape[0]) - self.dtype = counts_dtype - self.float_threshold = float_threshold - self._mean = None - self._latents = None - super(Posterior, self).__init__() - - @abstractmethod - def _get_mean(self): - """Obtain mean posterior counts and store in self._mean""" - pass - - @property - def mean(self) -> sp.csc_matrix: - if self._mean is None: - self._get_mean() - return self._mean - - @property - def latents(self) -> sp.csc_matrix: - if self._latents is None: - self._get_latents() - return self._latents - - @property - def variance(self): - raise NotImplemented("Posterior count variance not implemented.") - - @torch.no_grad() - def _get_latents(self): - """Calculate the encoded latent variables.""" - - data_loader = self.dataset_obj.get_dataloader(use_cuda=self.use_cuda, - analyzed_bcs_only=True, - batch_size=500, - shuffle=False) - - z = np.zeros((len(data_loader), self.vi_model.encoder['z'].output_dim)) - d = np.zeros(len(data_loader)) - p = np.zeros(len(data_loader)) - epsilon = np.zeros(len(data_loader)) - - for i, data in enumerate(data_loader): - - if 'chi_ambient' in pyro.get_param_store().keys(): - chi_ambient = pyro.param('chi_ambient').detach() - else: - chi_ambient = None - - enc = self.vi_model.encoder.forward(x=data, chi_ambient=chi_ambient) - ind = i * data_loader.batch_size - z[ind:(ind + data.shape[0]), :] = enc['z']['loc'].detach().cpu().numpy() - - phi_loc = pyro.param('phi_loc') - phi_scale = pyro.param('phi_scale') - - d[ind:(ind + data.shape[0])] = \ - dist.LogNormal(loc=enc['d_loc'], - scale=pyro.param('d_cell_scale')).mean.detach().cpu().numpy() - - p[ind:(ind + data.shape[0])] = enc['p_y'].sigmoid().detach().cpu().numpy() - - epsilon[ind:(ind + data.shape[0])] = dist.Gamma(enc['epsilon'] * self.vi_model.epsilon_prior, - self.vi_model.epsilon_prior).mean.detach().cpu().numpy() - - self._latents = {'z': z, 'd': d, 'p': p, - 'phi_loc_scale': [phi_loc.item(), phi_scale.item()], - 'epsilon': epsilon} - - @torch.no_grad() - def _param_map_estimates(self, - data: torch.Tensor, - chi_ambient: torch.Tensor) -> Dict[str, torch.Tensor]: - """Calculate MAP estimates of mu, the mean of the true count matrix, and - lambda, the rate parameter of the Poisson background counts. - - Args: - data: Dense tensor minibatch of cell by gene count data. - chi_ambient: Point estimate of inferred ambient gene expression. - - Returns: - mu_map: Dense tensor of Negative Binomial means for true counts. - lambda_map: Dense tensor of Poisson rate params for noise counts. - alpha_map: Dense tensor of Dirichlet concentration params that - inform the overdispersion of the Negative Binomial. - - """ - - # Encode latents. - enc = self.vi_model.encoder.forward(x=data, - chi_ambient=chi_ambient) - z_map = enc['z']['loc'] - - chi_map = self.vi_model.decoder.forward(z_map) - phi_loc = pyro.param('phi_loc') - phi_scale = pyro.param('phi_scale') - phi_conc = phi_loc.pow(2) / phi_scale.pow(2) - phi_rate = phi_loc / phi_scale.pow(2) - alpha_map = 1. / dist.Gamma(phi_conc, phi_rate).mean - - y = (enc['p_y'] > 0).float() - d_empty = dist.LogNormal(loc=pyro.param('d_empty_loc'), - scale=pyro.param('d_empty_scale')).mean - d_cell = dist.LogNormal(loc=enc['d_loc'], - scale=pyro.param('d_cell_scale')).mean - epsilon = dist.Gamma(enc['epsilon'] * self.vi_model.epsilon_prior, - self.vi_model.epsilon_prior).mean - - if self.vi_model.include_rho: - rho = pyro.param("rho_alpha") / (pyro.param("rho_alpha") - + pyro.param("rho_beta")) - else: - rho = None - - # Calculate MAP estimates of mu and lambda. - mu_map = self.vi_model.calculate_mu(epsilon=epsilon, - d_cell=d_cell, - chi=chi_map, - y=y, - rho=rho) - lambda_map = self.vi_model.calculate_lambda(epsilon=epsilon, - chi_ambient=chi_ambient, - d_empty=d_empty, - y=y, - d_cell=d_cell, - rho=rho, - chi_bar=self.vi_model.avg_gene_expression) - - return {'mu': mu_map, 'lam': lambda_map, 'alpha': alpha_map} - - def dense_to_sparse(self, - chunk_dense_counts: np.ndarray) -> Tuple[List, List, List]: - """Distill a batch of dense counts into sparse format. - Barcode numbering is relative to the tensor passed in. - """ - - # TODO: speed up by keeping it a torch tensor as long as possible - - if chunk_dense_counts.dtype != np.int32: - - if self.dtype == np.uint32: - - # Turn the floating point count estimates into integers. - decimal_values, _ = np.modf(chunk_dense_counts) # Stuff after decimal. - roundoff_counts = np.random.binomial(1, p=decimal_values) # Bernoulli. - chunk_dense_counts = np.floor(chunk_dense_counts).astype(dtype=int) - chunk_dense_counts += roundoff_counts - - elif self.dtype == np.float32: - - # Truncate counts at a threshold value. - chunk_dense_counts = (chunk_dense_counts * - (chunk_dense_counts > self.float_threshold)) - - else: - raise NotImplementedError(f"Count matrix dtype {self.dtype} is not " - f"supported. Choose from [np.uint32, " - f"np.float32]") - - # Find all the nonzero counts in this dense matrix chunk. - nonzero_barcode_inds_this_chunk, nonzero_genes_trimmed = \ - np.nonzero(chunk_dense_counts) - nonzero_counts = \ - chunk_dense_counts[nonzero_barcode_inds_this_chunk, - nonzero_genes_trimmed].flatten(order='C') - - # Get the original gene index from gene index in the trimmed dataset. - nonzero_genes = self.analyzed_gene_inds[nonzero_genes_trimmed] - - return nonzero_barcode_inds_this_chunk, nonzero_genes, nonzero_counts - - -class ImputedPosterior(Posterior): - """Posterior count inference using imputation to infer cell mean (d * chi). - - Args: - dataset_obj: Dataset object. - vi_model: Trained RemoveBackgroundPyroModel. - guide: Variational posterior pyro guide function, optional. Only - specify if the required guide function is not vi_model.guide. - encoder: Encoder that provides encodings of data. - counts_dtype: Data type of posterior count matrix. Can be one of - [np.uint32, np.float] - float_threshold: For floating point count matrices, counts below - this threshold will be set to zero, for the purposes of constructing - a sparse matrix. Unused if counts_dtype is np.uint32 - - Properties: - mean: Posterior count mean, as a sparse matrix. - encodings: Encoded latent variables, one per barcode in the dataset. - - """ - - def __init__(self, - dataset_obj: 'SingleCellRNACountsDataset', # Dataset - vi_model: 'RemoveBackgroundPyroModel', # Trained variational inference model - guide=None, - encoder=None, #: Union[CompositeEncoder, None] = None, - counts_dtype: np.dtype = np.uint32, - float_threshold: float = 0.5): - self.vi_model = vi_model - self.use_cuda = vi_model.use_cuda - self.guide = guide if guide is not None else vi_model.encoder - self.encoder = encoder if encoder is not None else vi_model.encoder - self._encodings = None - self._mean = None - super(ImputedPosterior, self).__init__(dataset_obj=dataset_obj, - vi_model=vi_model, - counts_dtype=counts_dtype, - float_threshold=float_threshold) - - @torch.no_grad() - def _get_mean(self): - """Send dataset through a guide that returns mean posterior counts. - - Keep track of only what is necessary to distill a sparse count matrix. - - """ - - data_loader = self.dataset_obj.get_dataloader(use_cuda=self.use_cuda, - analyzed_bcs_only=False, - batch_size=500, - shuffle=False) - - barcodes = [] - genes = [] - counts = [] - ind = 0 - - for data in data_loader: - - # Get return values from guide. - dense_counts_torch = self._param_map_estimates(data=data, - chi_ambient=pyro.param("chi_ambient")) - dense_counts = dense_counts_torch.detach().cpu().numpy() - bcs_i_chunk, genes_i, counts_i = self.dense_to_sparse(dense_counts) - - # Translate chunk barcode inds to overall inds. - bcs_i = self.barcode_inds[bcs_i_chunk + ind] - - # Add sparse matrix values to lists. - barcodes.append(bcs_i) - genes.append(genes_i) - counts.append(counts_i) - - # Increment barcode index counter. - ind += data.shape[0] # Same as data_loader.batch_size - - # Convert the lists to numpy arrays. - counts = np.array(np.concatenate(tuple(counts)), dtype=self.dtype) - barcodes = np.array(np.concatenate(tuple(barcodes)), dtype=np.uint32) - genes = np.array(np.concatenate(tuple(genes)), dtype=np.uint32) - - # Put the counts into a sparse csc_matrix. - self._mean = sp.csc_matrix((counts, (barcodes, genes)), - shape=self.count_matrix_shape) - - -class ProbPosterior(Posterior): - """Posterior count inference using a noise count probability distribution. - - Args: - dataset_obj: Dataset object. - vi_model: Trained model: RemoveBackgroundPyroModel - fpr: Desired false positive rate for construction of the final regularized - posterior on true counts. False positives are true counts that are - (incorrectly) removed from the dataset. - float_threshold: For floating point count matrices, counts below - this threshold will be set to zero, for the purposes of constructing - a sparse matrix. Unused if counts_dtype is np.uint32 - - Properties: - mean: Posterior count mean, as a sparse matrix. - encodings: Encoded latent variables, one per barcode in the dataset. - - """ - - def __init__(self, - dataset_obj: 'SingleCellRNACountsDataset', - vi_model: 'RemoveBackgroundPyroModel', - fpr: float = 0.01, - float_threshold: float = 0.5, - batch_size: int = consts.PROP_POSTERIOR_BATCH_SIZE, - cells_posterior_reg_calc: int = consts.CELLS_POSTERIOR_REG_CALC): - self.vi_model = vi_model - self.use_cuda = vi_model.use_cuda - self.fpr = fpr - self.lambda_multiplier = None - self._encodings = None - self._mean = None - self.batch_size = batch_size - self.cells_posterior_reg_calc = cells_posterior_reg_calc - self.random = np.random.RandomState(seed=1234) - super(ProbPosterior, self).__init__(dataset_obj=dataset_obj, - vi_model=vi_model, - counts_dtype=np.uint32, - float_threshold=float_threshold) - - @torch.no_grad() - def _get_mean(self): - """Send dataset through a guide that returns mean posterior counts. - - Keep track of only what is necessary to distill a sparse count matrix. - - """ - - # Get a dataset of ten cells. - cell_inds = np.where(self.latents['p'] > 0.9)[0] - lambda_mults = np.zeros(5) - - for i in range(lambda_mults.size): - - n_cells = min(self.cells_posterior_reg_calc, cell_inds.size) - if n_cells == 0: - raise ValueError('No cells found! Cannot compute expected FPR.') - cell_ind_subset = self.random.choice(cell_inds, size=n_cells, replace=False) - cell_data = (torch.tensor(np.array(self.dataset_obj.get_count_matrix() - [cell_ind_subset, :].todense()).squeeze()) - .float().to(self.vi_model.device)) - - # Get the latents mu, alpha, and lambda for those cells. - chi_ambient = pyro.param("chi_ambient") - map_est = self._param_map_estimates(data=cell_data, chi_ambient=chi_ambient) - - # Find the optimal lambda_multiplier value using those cells and target FPR. - lambda_mult = self._lambda_binary_search_given_fpr(cell_data=cell_data, - fpr=self.fpr, - mu_est=map_est['mu'], - lambda_est=map_est['lam'], - alpha_est=map_est['alpha']) - lambda_mults[i] = lambda_mult - - optimal_lambda_mult = np.mean(lambda_mults) - self.lambda_multiplier = optimal_lambda_mult - logging.info(f'Optimal posterior regularization factor = {optimal_lambda_mult:.2f}') - - # Compute posterior in mini-batches. - analyzed_bcs_only = True - data_loader = self.dataset_obj.get_dataloader(use_cuda=self.use_cuda, - analyzed_bcs_only=analyzed_bcs_only, - batch_size=self.batch_size, - shuffle=False) - barcodes = [] - genes = [] - counts = [] - ind = 0 - - for data in data_loader: - - # Compute an estimate of the true counts. - dense_counts = self._compute_true_counts(data=data, - chi_ambient=chi_ambient, - lambda_multiplier=optimal_lambda_mult, - use_map=False, - n_samples=9) # must be odd number - bcs_i_chunk, genes_i, counts_i = self.dense_to_sparse(dense_counts) - - # Translate chunk barcode inds to overall inds. - if analyzed_bcs_only: - bcs_i = self.dataset_obj.analyzed_barcode_inds[bcs_i_chunk + ind] - else: - bcs_i = self.barcode_inds[bcs_i_chunk + ind] - - # Add sparse matrix values to lists. - barcodes.append(bcs_i) - genes.append(genes_i) - counts.append(counts_i) - - # Increment barcode index counter. - ind += data.shape[0] # Same as data_loader.batch_size - - # Convert the lists to numpy arrays. - counts = np.array(np.concatenate(tuple(counts)), dtype=self.dtype) - barcodes = np.array(np.concatenate(tuple(barcodes)), dtype=np.uint32) - genes = np.array(np.concatenate(tuple(genes)), dtype=np.uint32) # uint16 is too small! - - # Put the counts into a sparse csc_matrix. - self._mean = sp.csc_matrix((counts, (barcodes, genes)), - shape=self.count_matrix_shape) - - @torch.no_grad() - def _compute_true_counts(self, - data: torch.Tensor, - chi_ambient: torch.Tensor, - lambda_multiplier: float, - use_map: bool = True, - n_samples: int = 1) -> np.ndarray: - """Compute the true de-noised count matrix for this minibatch. - - Can use either a MAP estimate of lambda and mu, or can use a sampling - approach. - - Args: - data: Dense tensor minibatch of cell by gene count data. - chi_ambient: Point estimate of inferred ambient gene expression. - lambda_multiplier: Value by which lambda gets multiplied in order - to compute regularized posterior true counts. - use_map: True to use a MAP estimate of lambda and mu. - n_samples: If not using a MAP estimate, this specifies the number - of samples to use in calculating the posterior mean. - - Returns: - dense_counts: Dense matrix of true de-noised counts. - - """ - - if use_map: - - # Calculate MAP estimates of mu and lambda. - est = self._param_map_estimates(data, chi_ambient) - mu_map = est['mu'] - lambda_map = est['lam'] - alpha_map = est['alpha'] - - # Compute the de-noised count matrix given the MAP estimates. - dense_counts_torch = self._true_counts_from_params(data, - mu_map, - lambda_map * lambda_multiplier + 1e-30, - alpha_map + 1e-30) - - dense_counts = dense_counts_torch.detach().cpu().numpy() - - else: - - assert n_samples > 0, f"Posterior mean estimate needs to be derived " \ - f"from at least one sample: here {n_samples} " \ - f"samples are called for." - - dense_counts_torch = torch.zeros((data.shape[0], - data.shape[1], - n_samples), - dtype=torch.float32).to(data.device) - - for i in range(n_samples): - - # Sample from mu and lambda. - mu_sample, lambda_sample, alpha_sample = \ - self._param_sample(data) - - # Compute the de-noised count matrix given the estimates. - dense_counts_torch[..., i] = \ - self._true_counts_from_params(data, - mu_sample, - lambda_sample * lambda_multiplier + 1e-30, - alpha_sample + 1e-30) - - # Take the median of the posterior true count distribution... torch cuda does not implement mode - dense_counts = dense_counts_torch.median(dim=2, keepdim=False)[0] - dense_counts = dense_counts.detach().cpu().numpy().astype(np.int32) - - return dense_counts - - @torch.no_grad() - def _param_sample(self, - data: torch.Tensor) -> Tuple[torch.Tensor, - torch.Tensor, - torch.Tensor]: - """Calculate a single sample estimate of mu, the mean of the true count - matrix, and lambda, the rate parameter of the Poisson background counts. - - Args: - data: Dense tensor minibatch of cell by gene count data. - - Returns: - mu_sample: Dense tensor sample of Negative Binomial mean for true - counts. - lambda_sample: Dense tensor sample of Poisson rate params for noise - counts. - alpha_sample: Dense tensor sample of Dirichlet concentration params - that inform the overdispersion of the Negative Binomial. - - """ - - # Use pyro poutine to trace the guide and sample parameter values. - guide_trace = pyro.poutine.trace(self.vi_model.guide).get_trace(x=data) - replayed_model = pyro.poutine.replay(self.vi_model.model, guide_trace) - - # Run the model using these sampled values. - replayed_model_output = replayed_model(x=data) - - # The model returns mu, alpha, and lambda. - mu_sample = replayed_model_output['mu'] - lambda_sample = replayed_model_output['lam'] - alpha_sample = replayed_model_output['alpha'] - - return mu_sample, lambda_sample, alpha_sample - - @torch.no_grad() - def _true_counts_from_params(self, - data: torch.Tensor, - mu_est: torch.Tensor, - lambda_est: torch.Tensor, - alpha_est: torch.Tensor) -> torch.Tensor: - """Calculate a single sample estimate of mu, the mean of the true count - matrix, and lambda, the rate parameter of the Poisson background counts. - - Args: - data: Dense tensor minibatch of cell by gene count data. - mu_est: Dense tensor of Negative Binomial means for true counts. - lambda_est: Dense tensor of Poisson rate params for noise counts. - alpha_est: Dense tensor of Dirichlet concentration params that - inform the overdispersion of the Negative Binomial. - - Returns: - dense_counts_torch: Dense matrix of true de-noised counts. - - """ - - # Estimate a reasonable low-end to begin the Poisson summation. - n = min(100., data.max().item()) # No need to exceed the max value - poisson_values_low = (lambda_est.detach() - n / 2).int() - - poisson_values_low = torch.clamp(torch.min(poisson_values_low, - (data - n + 1).int()), min=0).float() - - # Construct a big tensor of possible noise counts per cell per gene, - # shape (batch_cells, n_genes, max_noise_counts) - noise_count_tensor = torch.arange(start=0, end=n) \ - .expand([data.shape[0], data.shape[1], -1]) \ - .float().to(device=data.device) - noise_count_tensor = noise_count_tensor + poisson_values_low.unsqueeze(-1) - - # Compute probabilities of each number of noise counts. - # NOTE: some values will be outside the support (negative values for NB). - # The resulting NaNs are ignored by torch.argmax(). - logits = (mu_est.log() - alpha_est.log()).unsqueeze(-1) - log_prob_tensor = (dist.Poisson(lambda_est.unsqueeze(-1)) - .log_prob(noise_count_tensor) - + dist.NegativeBinomial(total_count=alpha_est.unsqueeze(-1), - logits=logits) - .log_prob(data.unsqueeze(-1) - noise_count_tensor)) - log_prob_tensor = torch.where(noise_count_tensor <= data.unsqueeze(-1), - log_prob_tensor, - torch.ones_like(log_prob_tensor) * -np.inf) - - # Find the most probable number of noise counts per cell per gene. - noise_count_map = torch.argmax(log_prob_tensor, - dim=-1, - keepdim=False).float() - - # Handle the cases where y = 0 (no cell): all counts are noise. - noise_count_map = torch.where(mu_est == 0, - data, - noise_count_map) - - # Compute the number of true counts. - dense_counts_torch = torch.clamp(data - noise_count_map, min=0.) - - return dense_counts_torch - - @torch.no_grad() - def _calculate_expected_fpr_from_map(self, - data: torch.Tensor, - data_map: torch.Tensor) -> torch.Tensor: - """Given inferred latent variables and observed total counts, - generate a MAP estimate for noise counts. Use that MAP estimate to - compute the expected false positive rate. - - Args: - data: Dense tensor tiny minibatch of cell by gene count data. - data_map: Dense tensor tiny minibatch of MAP output for that data. - - Returns: - fpr: Expected false positive rate. - - """ - - counts_per_cell = data.sum(dim=-1) - map_counts_per_cell = data_map.sum(dim=-1) - fraction_counts_removed_per_cell = (counts_per_cell - map_counts_per_cell) / counts_per_cell - empty_droplet_mean_counts = dist.LogNormal(loc=pyro.param('d_empty_loc'), - scale=pyro.param('d_empty_scale')).mean - ambient_fraction = empty_droplet_mean_counts / counts_per_cell - if self.vi_model.include_rho: - swapping_fraction = dist.Beta(pyro.param('rho_alpha'), pyro.param('rho_beta')).mean - else: - swapping_fraction = 0. - - mean_cell_epsilon = (self.latents['epsilon'][self.latents['p'] > 0.5]).mean() - target_fraction_counts_removed_per_cell = (ambient_fraction - + swapping_fraction) / mean_cell_epsilon - fpr_expectation = (fraction_counts_removed_per_cell - target_fraction_counts_removed_per_cell).mean() - - fpr_expectation = torch.clamp(fpr_expectation, min=0.) - - return fpr_expectation.mean() - - @torch.no_grad() - def _calculate_expected_fpr_given_lambda_mult(self, - data: torch.Tensor, - lambda_mult: float, - mu_est: torch.Tensor, - alpha_est: torch.Tensor, - lambda_est: torch.Tensor) -> torch.Tensor: - """Given a float lambda_mult, calculate a MAP estimate of output counts, - and use that estimate to calculate an expected false positive rate. - - Args: - data: Dense tensor tiny minibatch of cell by gene count data. - lambda_mult: Value of the lambda multiplier. - mu_est: Dense tensor of Negative Binomial means for true counts. - lambda_est: Dense tensor of Poisson rate params for noise counts. - alpha_est: Dense tensor of Dirichlet concentration params that - inform the overdispersion of the Negative Binomial. - - Returns: - fpr: Expected false positive rate. - - """ - - # Compute MAP estimate of true de-noised counts. - data_map = self._true_counts_from_params(data=data, - mu_est=mu_est, - lambda_est=lambda_est * lambda_mult, - alpha_est=alpha_est) - - # Compute expected false positive rate. - expected_fpr = self._calculate_expected_fpr_from_map(data=data, - data_map=data_map) - - return expected_fpr - - @torch.no_grad() - def _lambda_binary_search_given_fpr(self, - cell_data: torch.Tensor, - fpr: float, - mu_est: torch.Tensor, - lambda_est: torch.Tensor, - alpha_est: torch.Tensor, - lam_mult_init: float = 1., - fpr_tolerance: Optional[float] = None, - max_iterations: int = consts.POSTERIOR_REG_SEARCH_MAX_ITER) -> float: - """Perform a binary search for the appropriate lambda-multiplier which will - achieve a desired false positive rate. - - NOTE: It is assumed that - expected_fpr(lam_mult_bracket[0]) < fpr < expected_fpr(lam_mult_bracket[1]). - If this is not the case, the algorithm will produce an output close to one - of the brackets, and FPR control will not be achieved. - - Args: - cell_data: Data from a fraction of the total number of cells. - fpr: Desired false positive rate. - mu_est: Dense tensor of Negative Binomial means for true counts. - lambda_est: Dense tensor of Poisson rate params for noise counts. - alpha_est: Dense tensor of Dirichlet concentration params that - inform the overdispersion of the Negative Binomial. - lam_mult_init: Initial value of the lambda multiplier, hopefully - close to the unknown target value. - fpr_tolerance: Tolerated error in expected false positive rate. If - input is None, defaults to 0.001 or fpr / 10, whichever is - smaller. - max_iterations: A cutoff to ensure termination. Even if a tolerable - solution is not found, the algorithm will stop after this many - iterations and return the best answer so far. - - Returns: - lam_mult: Value of the lambda-multiplier. - - """ - - assert (fpr > 0) and (fpr < 1), "Target FPR should be in the interval (0, 1)." - if fpr_tolerance is None: - fpr_tolerance = min(fpr / 10., 0.001) - - # Begin at initial value. - lam_mult = lam_mult_init - - # Calculate an expected false positive rate for this lam_mult value. - expected_fpr = self._calculate_expected_fpr_given_lambda_mult( - data=cell_data, - lambda_mult=lam_mult, - mu_est=mu_est, - lambda_est=lambda_est, - alpha_est=alpha_est) - - # Find out what direction we need to move in. - residual = fpr - expected_fpr - initial_residual_sign = residual.sign() # plus or minus one - if initial_residual_sign.item() == 0: - # In the unlikely event that we hit the value exactly. - return lam_mult - - # Travel in one direction until the direction of FPR error changes. - lam_limit = lam_mult_init - i = 0 - while ((lam_limit < consts.POSTERIOR_REG_MAX) - and (lam_limit > consts.POSTERIOR_REG_MIN) - and (residual.sign() == initial_residual_sign) - and (i < max_iterations)): - - lam_limit = lam_limit * (initial_residual_sign * 2).exp().item() - - # Calculate an expected false positive rate for this lam_mult value. - expected_fpr = self._calculate_expected_fpr_given_lambda_mult( - data=cell_data, - lambda_mult=lam_limit, - mu_est=mu_est, - lambda_est=lambda_est, - alpha_est=alpha_est) - - residual = fpr - expected_fpr - i = i + 1 # one dataset had this go into an infinite loop, taking lam_limit -> 0 - - # Define the values that bracket the correct answer. - lam_mult_bracket = np.sort(np.array([lam_mult_init, lam_limit])) - - # Binary search algorithm. - for i in range(max_iterations): - - # Current test value for the lambda-multiplier. - lam_mult = np.mean(lam_mult_bracket) - - # Calculate an expected false positive rate for this lam_mult value. - expected_fpr = self._calculate_expected_fpr_given_lambda_mult( - data=cell_data, - lambda_mult=lam_mult, - mu_est=mu_est, - lambda_est=lambda_est, - alpha_est=alpha_est) - - # Check on false positive rate and update our bracket values. - if (expected_fpr < (fpr + fpr_tolerance)) and (expected_fpr > (fpr - fpr_tolerance)): - break - elif expected_fpr > fpr: - lam_mult_bracket[1] = lam_mult - elif expected_fpr < fpr: - lam_mult_bracket[0] = lam_mult - - # If we stopped due to iteration limit, take the average lam_mult value. - if i == max_iterations: - lam_mult = np.mean(lam_mult_bracket) - - # Check to see if we have achieved the desired FPR control. - if not ((expected_fpr < (fpr + fpr_tolerance)) and (expected_fpr > (fpr - fpr_tolerance))): - print(f'FPR control not achieved in {max_iterations} attempts. ' - f'Output FPR is esitmated to be {expected_fpr.item():.4f}') - - return lam_mult diff --git a/cellbender/remove_background/model.py b/cellbender/remove_background/model.py index 30f5d448..205e886f 100644 --- a/cellbender/remove_background/model.py +++ b/cellbender/remove_background/model.py @@ -20,10 +20,66 @@ from cellbender.remove_background.distributions.NullDist import NullDist from cellbender.remove_background.exceptions import NanException -from typing import Optional, Union +from typing import Optional, Union, Dict, Callable from numbers import Number +def calculate_lambda(model_type: str, + epsilon: torch.Tensor, + chi_ambient: torch.Tensor, + d_empty: torch.Tensor, + y: Union[torch.Tensor, None] = None, + d_cell: Union[torch.Tensor, None] = None, + rho: Union[torch.Tensor, None] = None, + chi_bar: Union[torch.Tensor, None] = None): + """Calculate noise rate based on the model.""" + + if model_type == "simple" or model_type == "ambient": + lam = epsilon.unsqueeze(-1) * d_empty.unsqueeze(-1) * chi_ambient + + elif model_type == "swapping": + lam = (rho.unsqueeze(-1) * chi_bar * epsilon.unsqueeze(-1) * + (y.unsqueeze(-1) * d_cell.unsqueeze(-1) + d_empty.unsqueeze(-1))) + + elif model_type == "full": + lam = (epsilon.unsqueeze(-1) + * ((1. - rho.unsqueeze(-1)) * chi_ambient * d_empty.unsqueeze(-1) + + rho.unsqueeze(-1) * chi_bar * (y.unsqueeze(-1) * d_cell.unsqueeze(-1) + + d_empty.unsqueeze(-1)))) + else: + raise NotImplementedError(f"model_type was set to {model_type}, " + f"which is not implemented.") + + return lam + + +def calculate_mu(model_type: str, + epsilon: torch.Tensor, + d_cell: torch.Tensor, + chi: torch.Tensor, + y: Union[torch.Tensor, None] = None, + rho: Union[torch.Tensor, None] = None): + """Calculate mean expression based on the model.""" + + if model_type == 'simple': + mu = epsilon.unsqueeze(-1) * d_cell.unsqueeze(-1) * chi + + elif model_type == 'ambient': + mu = (y.unsqueeze(-1) * epsilon.unsqueeze(-1) + * d_cell.unsqueeze(-1) * chi) + + elif model_type == 'swapping' or model_type == 'full': + mu = ((1. - rho.unsqueeze(-1)) + * y.unsqueeze(-1) * epsilon.unsqueeze(-1) + * d_cell.unsqueeze(-1) * chi) + + else: + raise NotImplementedError(f"model_type was set to {model_type}, " + f"which is not implemented.") + + return mu + + class RemoveBackgroundPyroModel(nn.Module): """Class that contains the model and guide used for variational inference. @@ -32,8 +88,10 @@ class RemoveBackgroundPyroModel(nn.Module): 'swapping', 'full']. encoder: An instance of an encoder object. Can be a CompositeEncoder. decoder: An instance of a decoder object. - dataset_obj: Dataset object which contains relevant priors. + dataset_obj_priors: Dict which contains relevant priors. use_cuda: Will use GPU if True. + analyzed_gene_names: Here only so that when we save a checkpoint, if we + ever want to look at it, we will know which genes are which. phi_loc_prior: Mean of gamma distribution for global overdispersion. phi_scale_prior: Scale of gamma distribution for global overdispersion. rho_alpha_prior: Param of beta distribution for swapping fraction. @@ -52,12 +110,18 @@ def __init__(self, model_type: str, encoder: Union[nn.Module, encoder_module.CompositeEncoder], decoder: nn.Module, - dataset_obj: 'SingleCellRNACountsDataset', + dataset_obj_priors: Dict[str, float], + n_analyzed_genes: int, + n_droplets: int, + analyzed_gene_names: np.ndarray, + empty_UMI_threshold: int, + log_counts_crossover: float, use_cuda: bool, phi_loc_prior: float = consts.PHI_LOC_PRIOR, phi_scale_prior: float = consts.PHI_SCALE_PRIOR, rho_alpha_prior: float = consts.RHO_ALPHA_PRIOR, rho_beta_prior: float = consts.RHO_BETA_PRIOR, + epsilon_prior: float = consts.EPSILON_PRIOR, use_exact_log_prob: bool = consts.USE_EXACT_LOG_PROB): super(RemoveBackgroundPyroModel, self).__init__() @@ -69,13 +133,19 @@ def __init__(self, if (self.model_type == "full") or (self.model_type == "swapping"): self.include_rho = True - self.n_genes = dataset_obj.analyzed_gene_inds.size + self.n_genes = n_analyzed_genes + self.n_droplets = n_droplets + self.analyzed_gene_names = analyzed_gene_names self.z_dim = decoder.input_dim self.encoder = encoder self.decoder = decoder self.use_exact_log_prob = use_exact_log_prob self.loss = {'train': {'epoch': [], 'elbo': []}, - 'test': {'epoch': [], 'elbo': []}} + 'test': {'epoch': [], 'elbo': []}, + 'learning_rate': {'epoch': [], 'value': []}} + self.empty_UMI_threshold = empty_UMI_threshold + self.log_counts_crossover = log_counts_crossover + self.counts_crossover = np.exp(log_counts_crossover) # Determine whether we are working on a GPU. if use_cuda: @@ -93,21 +163,20 @@ def __init__(self, self.use_cuda = use_cuda # Priors - assert dataset_obj.priors['d_std'] > 0, \ - f"Issue with prior: d_std is {dataset_obj.priors['d_std']}, " \ + assert dataset_obj_priors['d_std'] > 0, \ + f"Issue with prior: d_std is {dataset_obj_priors['d_std']}, " \ f"but should be > 0." - assert dataset_obj.priors['cell_counts'] > 0, \ + assert dataset_obj_priors['cell_counts'] > 0, \ f"Issue with prior: cell_counts is " \ - f"{dataset_obj.priors['cell_counts']}, but should be > 0." + f"{dataset_obj_priors['cell_counts']}, but should be > 0." - self.d_cell_loc_prior = torch.tensor(np.log1p(dataset_obj.priors['cell_counts']))\ + self.d_cell_loc_prior = torch.tensor(np.log1p(dataset_obj_priors['cell_counts']))\ .float().to(self.device) - self.d_cell_scale_prior = (torch.tensor(consts.D_STD_PRIOR).to(self.device)) + self.d_cell_scale_prior = torch.tensor(dataset_obj_priors['d_std']).to(self.device) self.z_loc_prior = torch.zeros(torch.Size([self.z_dim])).to(self.device) - self.z_scale_prior = torch.ones(torch.Size([self.z_dim]))\ - .to(self.device) - self.epsilon_prior = torch.tensor(consts.EPSILON_PRIOR).to(self.device) + self.z_scale_prior = torch.ones(torch.Size([self.z_dim])).to(self.device) + self.epsilon_prior = torch.tensor(epsilon_prior).to(self.device) self.phi_loc_prior = (phi_loc_prior * torch.ones(torch.Size([])).to(self.device)) @@ -120,100 +189,46 @@ def __init__(self, if self.model_type != "simple": - assert dataset_obj.priors['empty_counts'] > 0, \ + assert dataset_obj_priors['empty_counts'] > 0, \ f"Issue with prior: empty_counts should be > 0, but is " \ - f"{dataset_obj.priors['empty_counts']}" - chi_ambient_sum = dataset_obj.priors['chi_ambient'].sum() + f"{dataset_obj_priors['empty_counts']}" + chi_ambient_sum = dataset_obj_priors['chi_ambient'].sum() assert np.isclose(a=chi_ambient_sum, b=[1.], atol=1e-5), \ f"Issue with prior: chi_ambient should sum to 1, but it sums " \ f"to {chi_ambient_sum}" - chi_bar_sum = dataset_obj.priors['chi_bar'].sum() + chi_bar_sum = dataset_obj_priors['chi_bar'].sum() assert np.isclose(a=chi_bar_sum, b=[1.], atol=1e-5), \ f"Issue with prior: chi_bar should sum to 1, but is {chi_bar_sum}" - self.d_empty_loc_prior = (np.log1p(dataset_obj - .priors['empty_counts'], + self.d_empty_loc_prior = (np.log1p(dataset_obj_priors['empty_counts'], dtype=np.float32).item() * torch.ones(torch.Size([])) .to(self.device)) - self.d_empty_scale_prior = (np.array(dataset_obj.priors['d_std'], - dtype=np.float32).item() + self.d_empty_scale_prior = (dataset_obj_priors['d_empty_std'] * torch.ones(torch.Size([])).to(self.device)) - self.p_logit_prior = (dataset_obj.priors['cell_logit'] + self.p_logit_prior = (dataset_obj_priors['cell_logit'] * torch.ones(torch.Size([])).to(self.device)) - self.chi_ambient_init = dataset_obj.priors['chi_ambient']\ - .to(self.device) - self.avg_gene_expression = dataset_obj.priors['chi_bar'] \ - .to(self.device) + self.chi_ambient_init = dataset_obj_priors['chi_ambient'].to(self.device) + self.avg_gene_expression = dataset_obj_priors['chi_bar'].to(self.device) - self.empty_UMI_threshold = (torch.tensor(dataset_obj.empty_UMI_threshold) + self.empty_UMI_threshold = (torch.tensor(empty_UMI_threshold) .float().to(self.device)) else: self.avg_gene_expression = None - self.rho_alpha_prior = (rho_alpha_prior - * torch.ones(torch.Size([])).to(self.device)) - self.rho_beta_prior = (rho_beta_prior - * torch.ones(torch.Size([])).to(self.device)) + self.rho_alpha_prior = rho_alpha_prior * torch.ones(torch.Size([])).to(self.device) + self.rho_beta_prior = rho_beta_prior * torch.ones(torch.Size([])).to(self.device) - def calculate_lambda(self, - epsilon: torch.Tensor, - chi_ambient: torch.Tensor, - d_empty: torch.Tensor, - y: Optional[torch.Tensor] = None, - d_cell: Optional[torch.Tensor] = None, - rho: Optional[torch.Tensor] = None, - chi_bar: Optional[torch.Tensor] = None): - """Calculate noise rate based on the model.""" - - if self.model_type == "simple" or self.model_type == "ambient": - lam = epsilon.unsqueeze(-1) * d_empty.unsqueeze(-1) * chi_ambient - - elif self.model_type == "swapping": - lam = (rho.unsqueeze(-1) * chi_bar * - (y.unsqueeze(-1) * d_cell.unsqueeze(-1) + d_empty.unsqueeze(-1))) - - elif self.model_type == "full": - lam = (epsilon.unsqueeze(-1) - * ((1. - rho.unsqueeze(-1)) * chi_ambient * d_empty.unsqueeze(-1) - + rho.unsqueeze(-1) * chi_bar * (y.unsqueeze(-1) * d_cell.unsqueeze(-1) - + d_empty.unsqueeze(-1)))) - else: - raise ValueError(f"model_type was set to {self.model_type}, " - f"which is not implemented.") + def _calculate_mu(self, **kwargs): + return calculate_mu(model_type=self.model_type, **kwargs) - return lam - - def calculate_mu(self, - epsilon: torch.Tensor, - d_cell: torch.Tensor, - chi: torch.Tensor, - y: Optional[torch.Tensor] = None, - rho: Optional[torch.Tensor] = None): - """Calculate mean expression based on the model.""" - - if self.model_type == 'simple': - mu = epsilon.unsqueeze(-1) * d_cell.unsqueeze(-1) * chi - - elif self.model_type == 'ambient': - mu = (y.unsqueeze(-1) * epsilon.unsqueeze(-1) - * d_cell.unsqueeze(-1) * chi) - - elif self.model_type == 'swapping' or self.model_type == 'full': - mu = ((1. - rho.unsqueeze(-1)) - * y.unsqueeze(-1) * epsilon.unsqueeze(-1) - * d_cell.unsqueeze(-1) * chi) - - else: - raise NotImplementedError(f"model_type was set to {self.model_type}, " - f"which is not implemented.") - - return mu + def _calculate_lambda(self, **kwargs): + return calculate_lambda(model_type=self.model_type, **kwargs) def model(self, x: torch.Tensor): """Data likelihood model. @@ -224,7 +239,7 @@ def model(self, x: torch.Tensor): """ # Register the decoder with pyro. - pyro.module("decoder", self.decoder) + pyro.module("decoder", self.decoder, update_module_params=True) # Register the hyperparameter for ambient gene expression. if self.include_empties: @@ -235,13 +250,16 @@ def model(self, x: torch.Tensor): else: chi_ambient = None - # Sample phi from Gamma prior. - phi = pyro.sample("phi", - dist.Gamma(self.phi_conc_prior, - self.phi_rate_prior)) + POISSON_APPROX = False + + if not POISSON_APPROX: + # Sample phi from Gamma prior. + phi = pyro.sample("phi", + dist.Gamma(self.phi_conc_prior, + self.phi_rate_prior)) # Happens in parallel for each data point (cell barcode) independently: - with pyro.plate("data", x.size(0), + with pyro.plate("data", x.shape[0], use_cuda=self.use_cuda, device=self.device): # Sample z from prior. @@ -251,7 +269,7 @@ def model(self, x: torch.Tensor): .expand_by([x.size(0)]).to_event(1)) # Decode the latent code z to get fractional gene expression, chi. - chi = self.decoder.forward(z) + chi = pyro.deterministic("chi", self.decoder(z)) # Sample d_cell based on priors. d_cell = pyro.sample("d_cell", @@ -283,53 +301,62 @@ def model(self, x: torch.Tensor): .expand_by([x.size(0)])) # Sample y, the presence of a real cell, based on p_logit_prior. - y = pyro.sample("y", - dist.Bernoulli(logits=self.p_logit_prior - 100.) # TODO - .expand_by([x.size(0)])) + p_logit_prior = get_p_logit_prior( + log_counts=x.sum(dim=-1).log(), + log_cell_prior_counts=self.d_cell_loc_prior, + surely_empty_counts=self.empty_UMI_threshold, + naive_p_logit_prior=self.p_logit_prior, + ) + y = pyro.sample("y", dist.Bernoulli(logits=p_logit_prior)) else: d_empty = None y = None # Calculate the mean gene expression counts (for each barcode). - mu_cell = self.calculate_mu(epsilon=epsilon, - d_cell=d_cell, - chi=chi, - y=y, - rho=rho) + mu_cell = self._calculate_mu(epsilon=epsilon, + d_cell=d_cell, + chi=chi, + y=y, + rho=rho) if self.include_empties: # Calculate the background rate parameter (for each barcode). - lam = self.calculate_lambda(epsilon=epsilon, - chi_ambient=chi_ambient, - d_empty=d_empty, - y=y, - d_cell=d_cell, - rho=rho, - chi_bar=self.avg_gene_expression) + lam = self._calculate_lambda(epsilon=epsilon, + chi_ambient=chi_ambient, + d_empty=d_empty, + y=y, + d_cell=d_cell, + rho=rho, + chi_bar=self.avg_gene_expression) else: lam = torch.zeros([self.n_genes]).to(self.device) - alpha = phi.reciprocal() - - if self.use_exact_log_prob: - - # Sample gene expression from our Negative Binomial Poisson - # Convolution distribution, and compare with observed data. - c = pyro.sample("obs", NBPC(mu=mu_cell + consts.NBPC_MU_EPS_SAFEGAURD, - alpha=alpha + consts.NBPC_ALPHA_EPS_SAFEGAURD, - lam=lam + consts.NBPC_LAM_EPS_SAFEGAURD, - max_poisson=consts.NBPC_EXACT_N_TERMS).to_event(1), + if POISSON_APPROX: + # Data distributed as the sum of two Poissons. + c = pyro.sample("obs", + dist.Poisson(rate=mu_cell + lam + consts.POISSON_EPS_SAFEGAURD).to_event(1), obs=x.reshape(-1, self.n_genes)) + alpha = None else: + alpha = phi.reciprocal() - # Use a negative binomial approximation as the observation model. - c = pyro.sample("obs", NBPCapprox(mu=mu_cell + consts.NBPC_MU_EPS_SAFEGAURD, - alpha=alpha + consts.NBPC_ALPHA_EPS_SAFEGAURD, - lam=lam + consts.NBPC_LAM_EPS_SAFEGAURD).to_event(1), - obs=x.reshape(-1, self.n_genes)) + if not consts.USE_EXACT_LOG_PROB: + + # Use a negative binomial approximation as the observation model. + c = pyro.sample("obs", NBPCapprox(mu=mu_cell + consts.NBPC_MU_EPS_SAFEGAURD, + alpha=alpha + consts.NBPC_ALPHA_EPS_SAFEGAURD, + lam=lam + consts.NBPC_LAM_EPS_SAFEGAURD).to_event(1), + obs=x.reshape(-1, self.n_genes)) + + else: + c = pyro.sample("obs", NBPC(mu=mu_cell + consts.NBPC_MU_EPS_SAFEGAURD, + alpha=alpha + consts.NBPC_ALPHA_EPS_SAFEGAURD, + lam=lam + consts.NBPC_LAM_EPS_SAFEGAURD, + max_poisson=100).to_event(1), + obs=x.reshape(-1, self.n_genes)) if self.include_empties: @@ -341,10 +368,9 @@ def model(self, x: torch.Tensor): # Additionally use the surely empty droplets for regularization, # since we know these droplets by their UMI counts. counts = x.sum(dim=-1, keepdim=False) - surely_empty_mask = ((counts < self.empty_UMI_threshold) - .bool().to(self.device)) + surely_cell_mask = (counts >= self.d_cell_loc_prior.exp()).bool().to(self.device) - with poutine.mask(mask=surely_empty_mask): + with poutine.mask(mask=y.detach().bool().logical_not()): # surely_empty_mask): with poutine.scale(scale=consts.REG_SCALE_AMBIENT_EXPRESSION): @@ -353,45 +379,57 @@ def model(self, x: torch.Tensor): else: r = None - # Semi-supervision of ambient expression. - lam = self.calculate_lambda(epsilon=epsilon.detach(), - chi_ambient=chi_ambient, - d_empty=d_empty, - y=torch.zeros_like(d_empty), - d_cell=d_cell.detach(), - rho=r, - chi_bar=self.avg_gene_expression) + # Semi-supervision of ambient expression using all empties. + lam = self._calculate_lambda(epsilon=torch.tensor(1.).to(d_empty.device), # epsilon.detach(), + chi_ambient=chi_ambient, + d_empty=d_empty, + y=torch.zeros_like(d_empty), + d_cell=d_cell.detach(), + rho=r, + chi_bar=self.avg_gene_expression) pyro.sample("obs_empty", - dist.Poisson(rate=lam + 1e-10).to_event(1), + dist.Poisson(rate=lam + consts.POISSON_EPS_SAFEGAURD).to_event(1), obs=x.reshape(-1, self.n_genes)) - # Semi-supervision of cell probabilities. - with poutine.scale(scale=consts.REG_SCALE_EMPTY_PROB): - - p_logit_posterior = pyro.sample("p_passback", - NullDist(torch.zeros(1) - .to(self.device)) - .expand_by([x.size(0)])) - - pyro.sample("obs_empty_y", - dist.Normal(loc=p_logit_posterior, - scale=1.), - obs=torch.ones_like(y) * -5.) - - # Additionally use some high-count droplets for cell prob regularization. - surely_cell_mask = (torch.where(counts >= self.d_cell_loc_prior.exp(), - torch.ones_like(counts), - torch.zeros_like(counts)) - .bool().to(self.device)) - - with poutine.mask(mask=surely_cell_mask): - with poutine.scale(scale=consts.REG_SCALE_CELL_PROB): - pyro.sample("obs_cell_y", - dist.Normal(loc=p_logit_posterior, - scale=1.), - obs=torch.ones_like(y) * 5.) - - return {'mu': mu_cell, 'lam': lam, 'alpha': alpha, 'counts': c} + # Grab our posterior for the logit cell probability (this is a workaround). + p_logit_posterior = pyro.sample("p_passback", + NullDist(torch.zeros(1).to(self.device)) + .expand_by([x.size(0)])) + + # Softer semi-supervision to encourage cell probabilities to do the right thing. + probably_empty_mask = (counts < self.counts_crossover).bool().to(self.device) + probably_cell_mask = (counts >= self.counts_crossover).bool().to(self.device) + + with poutine.mask(mask=probably_empty_mask): + with poutine.scale(scale=consts.REG_SCALE_SOFT_SUPERVISION): + pyro.sample("obs_probably_empty_y", + dist.Normal(loc=-1 * torch.ones_like(y) * consts.REG_LOGIT_MEAN, + scale=consts.REG_LOGIT_SOFT_SCALE), + obs=p_logit_posterior) + + with poutine.mask(mask=probably_cell_mask): + with poutine.scale(scale=consts.REG_SCALE_SOFT_SUPERVISION): + pyro.sample("obs_probably_cell_y", + dist.Normal(loc=torch.ones_like(y) * consts.REG_LOGIT_MEAN, + scale=consts.REG_LOGIT_SOFT_SCALE), + obs=p_logit_posterior) + + # Regularization of epsilon.mean() + if surely_cell_mask.sum() >= 2: + epsilon_median = epsilon[probably_cell_mask].median() + # with poutine.scale(scale=probably_cell_mask.sum() / 10.): + pyro.sample("epsilon_mean", + dist.Normal(loc=epsilon_median, scale=0.01), + obs=torch.ones_like(epsilon_median)) + + epsilon_median_empty = epsilon[probably_empty_mask].median() + # with poutine.scale(scale=probably_cell_mask.sum() / 10.): + pyro.sample("epsilon_empty_mean", + dist.Normal(loc=epsilon_median_empty, scale=0.01), + obs=torch.ones_like(epsilon_median_empty)) + + return {'chi_ambient': chi_ambient, 'z': z, + 'mu': mu_cell, 'lam': lam, 'alpha': alpha, 'counts': c} @config_enumerate(default='parallel') def guide(self, x: torch.Tensor): @@ -411,7 +449,7 @@ def guide(self, x: torch.Tensor): # Register the encoder(s) with pyro. for name, module in self.encoder.items(): - pyro.module("encoder_" + name, module) + pyro.module("encoder_" + name, module, update_module_params=True) # Initialize variational parameters for d_cell. d_cell_scale = pyro.param("d_cell_scale", @@ -466,7 +504,7 @@ def guide(self, x: torch.Tensor): pyro.sample("phi", dist.Gamma(phi_conc, phi_rate)) # Happens in parallel for each data point (cell barcode) independently: - with pyro.plate("data", x.size(0), + with pyro.plate("data", x.shape[0], use_cuda=self.use_cuda, device=self.device): # Sample swapping fraction rho. @@ -483,10 +521,14 @@ def guide(self, x: torch.Tensor): scale=d_empty_scale) .expand_by([x.size(0)])) - enc = self.encoder.forward(x=x, chi_ambient=chi_ambient) + enc = self.encoder(x=x, + chi_ambient=chi_ambient.detach(), + cell_prior_log=self.d_cell_loc_prior) else: - enc = self.encoder.forward(x=x, chi_ambient=None) + enc = self.encoder(x=x, + chi_ambient=None, + cell_prior_log=self.d_cell_loc_prior) # Code specific to models with empty droplets. if self.include_empties: @@ -500,63 +542,52 @@ def guide(self, x: torch.Tensor): # Sample the Bernoulli y from encoded p(y). y = pyro.sample("y", dist.Bernoulli(logits=enc['p_y'])) - # Gate d_cell_loc so empty droplets do not give big gradients. - prob = enc['p_y'].sigmoid() # Logits to probability - d_cell_loc_gated = (prob * enc['d_loc'] + (1 - prob) - * self.d_cell_loc_prior) # NOTE: necessary to pass on sim6 - - # Sample d based on the encoding. - d_cell = pyro.sample("d_cell", dist.LogNormal(loc=d_cell_loc_gated, - scale=d_cell_scale)) + # Get cell probabilities for gating. + prob = enc['p_y'].sigmoid().detach() # Logits to probability # Mask out empty droplets. - with poutine.mask(mask=y.bool()): + with poutine.mask(mask=y.bool().detach()): # Sample latent code z for the barcodes containing cells. - pyro.sample("z", - dist.Normal(loc=enc['z']['loc'], - scale=enc['z']['scale']) - .to_event(1)) + z = pyro.sample("z", dist.Normal(loc=enc['z']['loc'], scale=enc['z']['scale']) + .to_event(1)) - # Gate epsilon and sample. - epsilon_gated = (prob * enc['epsilon'] + (1 - prob) * 1.) + # Gate d based and sample. + d_cell_loc_gated = (prob * enc['d_loc'] + (1 - prob) + * self.d_cell_loc_prior) # NOTE: necessary to pass on sim6 + d_cell = pyro.sample("d_cell", dist.LogNormal(loc=d_cell_loc_gated, + scale=d_cell_scale)) - epsilon = pyro.sample("epsilon", - dist.Gamma(epsilon_gated * self.epsilon_prior, - self.epsilon_prior)) + # Gate epsilon and sample. + epsilon_gated = (prob * enc['epsilon'] + (1 - prob) * 1.) + epsilon = pyro.sample("epsilon", + dist.Gamma(concentration=epsilon_gated * self.epsilon_prior, + rate=self.epsilon_prior)) else: # Sample d based on the encoding. - pyro.sample("d_cell", dist.LogNormal(loc=enc['d_loc'], - scale=d_cell_scale)) + pyro.sample("d_cell", dist.LogNormal(loc=enc['d_loc'], scale=d_cell_scale)) # Sample latent code z for each cell. - pyro.sample("z", - dist.Normal(loc=enc['z']['loc'], - scale=enc['z']['scale']) + pyro.sample("z", dist.Normal(loc=enc['z']['loc'], scale=enc['z']['scale']) .to_event(1)) -def get_ambient_expression() -> Optional[np.ndarray]: - """Get ambient RNA expression for 'empty' droplets. - - Return: - chi_ambient: The ambient gene expression profile, as a normalized - vector that sums to one. - - Note: - Inference must have been performed on a model with a 'chi_ambient' - hyperparameter prior to making this call. - - """ - - chi_ambient = None - - if 'chi_ambient' in pyro.get_param_store().keys(): - chi_ambient = to_ndarray(pyro.param('chi_ambient')).squeeze() - - return chi_ambient +def get_p_logit_prior(log_counts: torch.Tensor, + log_cell_prior_counts: float, + surely_empty_counts: torch.Tensor, + naive_p_logit_prior: float) -> torch.Tensor: + """Compute the logit cell probability prior per droplet based on counts""" + ones = torch.ones_like(log_counts) + p_logit_prior = ones * naive_p_logit_prior + p_logit_prior = torch.where(log_counts <= (surely_empty_counts.log() + log_cell_prior_counts) / 2, + ones * -100., + p_logit_prior) + p_logit_prior = torch.where(log_counts >= log_cell_prior_counts, + ones * consts.REG_LOGIT_MEAN, + p_logit_prior) + return p_logit_prior def get_rho() -> Optional[np.ndarray]: @@ -582,6 +613,15 @@ def get_rho() -> Optional[np.ndarray]: return rho +def get_param_store_key(key: str) -> Union[np.ndarray, None]: + val = None + + if key in pyro.get_param_store().keys(): + val = to_ndarray(pyro.param(key)).squeeze() + + return val + + def to_ndarray(x: Union[Number, np.ndarray, torch.Tensor]) -> np.ndarray: """Convert a numeric value or array to a numpy array on cpu.""" diff --git a/cellbender/remove_background/posterior.py b/cellbender/remove_background/posterior.py new file mode 100644 index 00000000..37587026 --- /dev/null +++ b/cellbender/remove_background/posterior.py @@ -0,0 +1,1708 @@ +"""Posterior generation and regularization.""" + +import pyro +import pyro.distributions as dist +import torch +import numpy as np +import scipy.sparse as sp +import pandas as pd + +import cellbender.remove_background.consts as consts +from cellbender.remove_background.model import calculate_mu, calculate_lambda +from cellbender.monitor import get_hardware_usage +from cellbender.remove_background.data.dataprep import DataLoader +from cellbender.remove_background.data.dataset import get_dataset_obj +from cellbender.remove_background.estimation import EstimationMethod, \ + MultipleChoiceKnapsack, Mean, MAP, apply_function_dense_chunks +from cellbender.remove_background.sparse_utils import dense_to_sparse_op_torch, \ + log_prob_sparse_to_dense, csr_set_rows_to_zero +from cellbender.remove_background.checkpoint import load_from_checkpoint, \ + unpack_tarball, make_tarball, load_checkpoint +from cellbender.remove_background.data.io import \ + write_posterior_coo_to_h5, load_posterior_from_h5 + +from typing import Tuple, List, Dict, Optional, Union, Callable +from abc import ABC, abstractmethod +import logging +import argparse +import tempfile +import shutil +import time +import os + + +logger = logging.getLogger('cellbender') + + +def load_or_compute_posterior_and_save(dataset_obj: 'SingleCellRNACountsDataset', + inferred_model: 'RemoveBackgroundPyroModel', + args: argparse.Namespace) -> 'Posterior': + """After inference, compute the full posterior noise count log probability + distribution. Save it and make it part of the checkpoint file. + + NOTE: Loads posterior from checkpoint file if available. + NOTE: Saves posterior as args.output_file + '_posterior.npz' and adds this + file to the checkpoint tarball as well. + + Args: + dataset_obj: Input data in the form of a SingleCellRNACountsDataset + object. + inferred_model: Model after inference is complete. + args: Input command line parsed arguments. + + Returns: + posterior: Posterior object with noise count log prob computed, as well + as regularization if called for. + + """ + + assert os.path.exists(args.input_checkpoint_tarball), \ + f'Checkpoint file {args.input_checkpoint_tarball} does not exist, ' \ + f'presumably because saving of the checkpoint file has been manually ' \ + f'interrupted. load_or_compute_posterior_and_save() will not work ' \ + f'properly without an existing checkpoint file. Please re-run and ' \ + f'allow a checkpoint file to be saved.' + + def _do_posterior_regularization(posterior: Posterior): + + # Optional posterior regularization. + if args.posterior_regularization is not None: + if args.posterior_regularization == 'PRq': + posterior.regularize_posterior( + regularization=PRq, + alpha=args.prq_alpha, + device='cuda', + ) + elif args.posterior_regularization == 'PRmu': + posterior.regularize_posterior( + regularization=PRmu, + raw_count_matrix=dataset_obj.data['matrix'], + fpr=args.fpr[0], + per_gene=False, + device='cuda', + ) + elif args.posterior_regularization == 'PRmu_gene': + posterior.regularize_posterior( + regularization=PRmu, + raw_count_matrix=dataset_obj.data['matrix'], + fpr=args.fpr[0], + per_gene=True, + device='cuda', + ) + else: + raise ValueError(f'Got a posterior regularization input of ' + f'"{args.posterior_regularization}", which is not ' + f'allowed. Use ["PRq", "PRmu", "PRmu_gene"]') + + else: + # Delete a pre-existing posterior regularization in case an old one was saved. + posterior.clear_regularized_posterior() + + posterior = Posterior( + dataset_obj=dataset_obj, + vi_model=inferred_model, + posterior_batch_size=args.posterior_batch_size, + debug=args.debug, + ) + try: + ckpt_posterior = load_from_checkpoint(tarball_name=args.input_checkpoint_tarball, + filebase=args.checkpoint_filename, + to_load=['posterior']) + except ValueError: + # input checkpoint tarball was not a match for this workflow + # but we still may have saved a new tarball + ckpt_posterior = load_from_checkpoint(tarball_name=consts.CHECKPOINT_FILE_NAME, + filebase=args.checkpoint_filename, + to_load=['posterior']) + if os.path.exists(ckpt_posterior.get('posterior_file', 'does_not_exist')): + # Load posterior if it was saved in the checkpoint. + posterior.load(file=ckpt_posterior['posterior_file']) + _do_posterior_regularization(posterior) + else: + + # Compute posterior. + logger.info('Posterior not currently included in checkpoint.') + posterior.cell_noise_count_posterior_coo() + _do_posterior_regularization(posterior) + + # Save posterior and add it to checkpoint tarball. + posterior_file = args.output_file[:-3] + '_posterior.h5' + saved = posterior.save(file=posterior_file) + success = False + if saved: + with tempfile.TemporaryDirectory() as tmp_dir: + unpacked = unpack_tarball(tarball_name=args.input_checkpoint_tarball, + directory=tmp_dir) + if unpacked: + shutil.copy(posterior_file, os.path.join(tmp_dir, 'posterior.h5')) + all_ckpt_files = [os.path.join(tmp_dir, f) for f in os.listdir(tmp_dir) + if os.path.isfile(os.path.join(tmp_dir, f))] + success = make_tarball(files=all_ckpt_files, + tarball_name=args.input_checkpoint_tarball) + if success: + logger.info('Added posterior object to checkpoint file.') + else: + logger.warning('Failed to add posterior object to checkpoint file.') + + return posterior + + +class Posterior: + """Posterior handles posteriors on latent variables and denoised counts. + + Args: + dataset_obj: Dataset object. + vi_model: Trained RemoveBackgroundPyroModel. + posterior_batch_size: Number of barcodes in a minibatch, used to + calculate posterior probabilities (memory hungry). + counts_dtype: Data type of posterior count matrix. Can be one of + [np.uint32, np.float] + float_threshold: For floating point count matrices, counts below + this threshold will be set to zero, for the purposes of constructing + a sparse matrix. Unused if counts_dtype is np.uint32 + debug: True to print debugging messages (involves extra compute) + + Properties: + full_noise_count_posterior_csr: The posterior noise log probability + distribution, as a sparse matrix. + latents_map: MAP estimate of latent variables + + Examples: + + posterior = Posterior() + + """ + + def __init__(self, + dataset_obj: Optional['SingleCellRNACountsDataset'], # Dataset + vi_model: Optional['RemoveBackgroundPyroModel'], + posterior_batch_size: int = 128, + counts_dtype: np.dtype = np.uint32, + float_threshold: Optional[float] = 0.5, + debug: bool = False): + self.dataset_obj = dataset_obj + self.vi_model = vi_model + if vi_model is not None: + self.vi_model.eval() + self.vi_model.encoder['z'].eval() + self.vi_model.encoder['other'].eval() + self.vi_model.decoder.eval() + self.use_cuda = (torch.cuda.is_available() if vi_model is None + else vi_model.use_cuda) + self.device = 'cuda' if self.use_cuda else 'cpu' + self.analyzed_gene_inds = (None if (dataset_obj is None) + else dataset_obj.analyzed_gene_inds) + self.count_matrix_shape = (None if (dataset_obj is None) + else dataset_obj.data['matrix'].shape) + self.barcode_inds = (None if (dataset_obj is None) + else np.arange(0, self.count_matrix_shape[0])) + self.dtype = counts_dtype + self.debug = debug + self.float_threshold = float_threshold + self.posterior_batch_size = posterior_batch_size + self._noise_count_posterior_coo = None + self._noise_count_posterior_kwargs = None + self._noise_count_posterior_coo_offsets = None + self._noise_count_regularized_posterior_coo = None + self._noise_count_regularized_posterior_kwargs = None + self._latents = None + if dataset_obj is not None: + self.index_converter = IndexConverter( + total_n_cells=dataset_obj.data['matrix'].shape[0], + total_n_genes=dataset_obj.data['matrix'].shape[1], + ) + + def save(self, file: str) -> bool: + """Save the full posterior in HDF5 format.""" + + if self._noise_count_posterior_coo is None: + self.cell_noise_count_posterior_coo() + + n, g = self.index_converter.get_ng_indices(self._noise_count_posterior_coo.row) + + d = {'posterior_coo': self._noise_count_posterior_coo, + 'noise_count_offsets': self._noise_count_posterior_coo_offsets, + 'posterior_kwargs': self._noise_count_posterior_kwargs, + 'regularized_posterior_coo': self._noise_count_regularized_posterior_coo, + 'regularized_posterior_kwargs': self._noise_count_regularized_posterior_kwargs, + 'latents': self.latents_map, + 'feature_inds': g, + 'barcode_inds': n} + + try: + logger.info(f'Writing full posterior to {file}') + return write_posterior_coo_to_h5(output_file=file, **d) + except MemoryError: + logger.warning('Attempting to save the posterior as an h5 file ' + 'resulted in an out-of-memory error. Please report ' + 'this as a github issue.') + return False + + def load(self, file: str) -> bool: + """Load a saved posterior in compressed array .npz format.""" + + d = load_posterior_from_h5(filename=file) + self._noise_count_posterior_coo = d['coo'] + self._noise_count_posterior_coo_offsets = d['noise_count_offsets'] + self._noise_count_posterior_kwargs = d['kwargs'] + self._noise_count_regularized_posterior_coo = d['regularized_coo'] + self._noise_count_regularized_posterior_kwargs = d['kwargs_regularized'] + self._latents = d['latents'] + logger.info(f'Loaded pre-computed posterior from {file}') + return True + + def compute_denoised_counts(self, + estimator_constructor: EstimationMethod, + **kwargs) -> sp.csc_matrix: + """Probably the most important method: computation of the clean output count matrix. + + Args: + estimator_constructor: A noise count estimator class derived from + the EstimationMethod base class, and implementing the + .estimate_noise() method, which creates a point estimate of + noise. Pass in the constructor, not an object. + **kwargs: Keyword arguments for estimator_constructor().estimate_noise() + + Returns: + denoised_counts: Denoised output CSC sparse matrix (CSC for saving) + + """ + + # Only compute using defaults if the cache is empty. + if self._noise_count_regularized_posterior_coo is not None: + # Priority is taken by a regularized posterior, since presumably + # the user computed it for a reason. + logger.debug('Using regularized posterior to compute denoised counts') + logger.debug(self._noise_count_regularized_posterior_kwargs) + posterior_coo = self._noise_count_regularized_posterior_coo + else: + # Use exact posterior if a regularized version is not computed. + posterior_coo = (self._noise_count_posterior_coo + if (self._noise_count_posterior_coo is not None) + else self.cell_noise_count_posterior_coo()) + + # Instantiate Estimator object. + estimator = estimator_constructor(index_converter=self.index_converter) + + # Compute point estimate of noise in cells. + noise_csr = estimator.estimate_noise( + noise_log_prob_coo=posterior_coo, + noise_offsets=self._noise_count_posterior_coo_offsets, + **kwargs, + ) + + # Subtract cell noise from observed cell counts. + count_matrix = self.dataset_obj.data['matrix'] # all barcodes + cell_inds = self.dataset_obj.analyzed_barcode_inds[self.latents_map['p'] + > consts.CELL_PROB_CUTOFF] + empty_inds = set(range(count_matrix.shape[0])) - set(cell_inds) + cell_counts = csr_set_rows_to_zero(csr=count_matrix, row_inds=empty_inds) + denoised_counts = cell_counts - noise_csr + + return denoised_counts.tocsc() + + def regularize_posterior(self, + regularization: 'PosteriorRegularization', + **kwargs) -> sp.coo_matrix: + """Do posterior regularization. This modifies self._noise_count_regularized_posterior_coo + in place, and returns it. + + Args: + regularization: A particular PosteriorRegularization ['PRmu', 'PRq'] + **kwargs: Arguments passed to the PosteriorRegularization's + .regularize() method + + Returns: + Returns the regularized posterior, which is also stored in + self._noise_count_regularized_posterior_coo + + """ + + # Check if this posterior regularization has already been computed. + currently_cached = False if self._noise_count_regularized_posterior_kwargs is None else True + if currently_cached: + # Check if it's the right thing. + for k, v in self._noise_count_regularized_posterior_kwargs.items(): + if k == 'method': + if v != regularization.name(): + currently_cached = False + break + elif k not in kwargs.keys(): + currently_cached = False + break + elif kwargs[k] != v: + currently_cached = False + break + if currently_cached: + # What's been requested is what's cached. + logger.debug('Regularized posterior is already cached') + return self._noise_count_regularized_posterior_coo + + # Compute the regularized posterior. + self._noise_count_regularized_posterior_coo = regularization.regularize( + noise_count_posterior_coo=self._noise_count_posterior_coo, + noise_offsets=self._noise_count_posterior_coo_offsets, + index_converter=self.index_converter, + **kwargs, + ) + kwargs.update({'method': regularization.name()}) + kwargs.pop('raw_count_matrix', None) # do not store a copy here + self._noise_count_regularized_posterior_kwargs = kwargs + logger.debug('Updated posterior after performing regularization') + return self._noise_count_regularized_posterior_coo + + def clear_regularized_posterior(self): + """Remove the saved regularized posterior (so that compute_denoised_counts() + will not default to using it). + """ + self._noise_count_regularized_posterior_coo = None + self._noise_count_regularized_posterior_kwargs = None + + def cell_noise_count_posterior_coo(self, **kwargs) -> sp.coo_matrix: + """Compute the full-blown posterior on noise counts for all cells, + and store it in COO sparse format on CPU, and cache in + self._noise_count_posterior_csr + + NOTE: This is the main entrypoint for this class. + + Args: + **kwargs: Passed to _get_cell_noise_count_posterior_coo() + + Returns: + self._noise_count_posterior_coo: This sparse COO object contains all + the information about the posterior noise count distribution, + but it is a bit complicated. The data per entry (m, c) are + stored in COO format. The rows "m" represent a combined + cell-and-gene index, with a one-to-one mapping from m to + (n, g). The columns "c" represent noise count values. Values + are the log probabilities of a noise count value. A smaller + matrix can be constructed by increasing the threshold + smallest_log_probability. + """ + + if ((self._noise_count_posterior_coo is None) + or (kwargs != self._noise_count_posterior_kwargs)): + logger.debug('Running _get_cell_noise_count_posterior_coo() to compute posterior') + self._get_cell_noise_count_posterior_coo(**kwargs) + self._noise_count_posterior_kwargs = kwargs + + return self._noise_count_posterior_coo + + @property + def latents_map(self) -> Dict[str, np.ndarray]: + if self._latents is None: + self._get_latents_map() + return self._latents + + @torch.no_grad() + def _get_cell_noise_count_posterior_coo( + self, + n_samples: int = 20, + y_map: bool = True, + n_counts_max: int = 20, + smallest_log_probability: float = -10.) -> sp.coo_matrix: # TODO: default -7 ? + """Compute the full-blown posterior on noise counts for all cells, + and store log probability in COO sparse format on CPU. + + Args: + n_samples: Number of samples to use to compute the posterior log + probability distribution. Samples have high variance, so it is + important to use at least 20. However, they are expensive. + y_map: Use the MAP value for y (cell / no cell) when sampling, to + avoid samples with a cell and samples without a cell. + n_counts_max: Maximum number of noise counts. + smallest_log_probability: Do not store log prob values smaller than + this -- they get set to zero (saves space) + + Returns: + noise_count_posterior_coo: This sparse CSR object contains all + the information about the posterior noise count distribution, + but it is a bit complicated. The data per entry (m, c) are + stored in COO format. The rows "m" represent a combined + cell-and-gene index, and there is a one-to-one mapping from m to + (n, g). The columns "c" represent noise count values. Values + are the log probabilities of a noise count value. A smaller + matrix can be constructed by increasing the threshold + smallest_log_probability. + + """ + + logger.debug('Computing full posterior noise counts') + + # Compute posterior in mini-batches. + torch.cuda.empty_cache() + + # Dataloader for cells only. + analyzed_bcs_only = True + count_matrix = self.dataset_obj.get_count_matrix() # analyzed barcodes + cell_logic = (self.latents_map['p'] > consts.CELL_PROB_CUTOFF) + + # Raise an error if there are no cells found. + if cell_logic.sum() == 0: + logger.error(f'ERROR: Found zero droplets with posterior cell ' + f'probability > {consts.CELL_PROB_CUTOFF}. Please ' + f'check the log for estimated priors on expected cells, ' + f'total droplets included, UMI counts per cell, and ' + f'UMI counts in empty droplets, and see whether these ' + f'values make sense. Consider using additional input ' + f'arguments like --expected-cells, ' + f'--total-droplets-included, --force-cell-umi-prior, ' + f'and --force-empty-umi-prior, to make these values ' + f'accurate for your dataset.') + raise RuntimeError('Zero cells found!') + + dataloader_index_to_analyzed_bc_index = np.where(cell_logic)[0] + cell_data_loader = DataLoader( + count_matrix[cell_logic], + empty_drop_dataset=None, + batch_size=self.posterior_batch_size, + fraction_empties=0., + shuffle=False, + use_cuda=self.use_cuda, + ) + + bcs = [] # barcode index + genes = [] # gene index + c = [] # noise count value + c_offset = [] # noise count offsets from zero + log_probs = [] + ind = 0 + n_minibatches = len(cell_data_loader) + + logger.info('Computing posterior noise count probabilities in mini-batches.') + + for i, data in enumerate(cell_data_loader): + + if i == 0: + t = time.time() + elif i == 1: + logger.info(f' [{(time.time() - t) / 60:.2f} mins per chunk]') + logger.info(f'Working on chunk ({i + 1}/{n_minibatches})') + + if self.debug: + logger.debug(f'Posterior minibatch starting with droplet {ind}') + logger.debug('\n' + get_hardware_usage(use_cuda=self.use_cuda)) + + # Compute noise count probabilities. + noise_log_pdf_NGC, noise_count_offset_NG = self.noise_log_pdf( + data=data, + n_samples=n_samples, + y_map=y_map, + n_counts_max=n_counts_max, + ) + + # Compute a tensor to indicate sparsity. + # First we want data = 0 to be all zeros + # We also want anything below the threshold to be a zero + tensor_for_nonzeros = noise_log_pdf_NGC.clone().exp() # probability + tensor_for_nonzeros.data[data == 0, :] = 0. # remove data = 0 + tensor_for_nonzeros.data[noise_log_pdf_NGC < smallest_log_probability] = 0. + + # Convert to sparse format using "m" indices. + bcs_i_chunk, genes_i_analyzed, c_i, log_prob_i = dense_to_sparse_op_torch( + noise_log_pdf_NGC, + tensor_for_nonzeros=tensor_for_nonzeros, + ) + + # Get the original gene index from gene index in the trimmed dataset. + genes_i = self.analyzed_gene_inds[genes_i_analyzed] + + # Barcode index in the dataloader. + bcs_i = bcs_i_chunk + ind + + # Obtain the real barcode index since we only use cells. + bcs_i = dataloader_index_to_analyzed_bc_index[bcs_i] + + # Translate chunk barcode inds to overall inds. + if analyzed_bcs_only: + bcs_i = self.dataset_obj.analyzed_barcode_inds[bcs_i] + else: + bcs_i = self.barcode_inds[bcs_i] + + # Add sparse matrix values to lists. + try: + bcs.extend(bcs_i.tolist()) + genes.extend(genes_i.tolist()) + c.extend(c_i.tolist()) + log_probs.extend(log_prob_i.tolist()) + c_offset.extend(noise_count_offset_NG[bcs_i_chunk, genes_i_analyzed] + .detach().cpu().numpy()) + except TypeError as e: + # edge case of a single value + bcs.append(bcs_i) + genes.append(genes_i) + c.append(c_i) + log_probs.append(log_prob_i) + c_offset.append(noise_count_offset_NG[bcs_i_chunk, genes_i_analyzed] + .detach().cpu().numpy()) + + # Increment barcode index counter. + ind += data.shape[0] # Same as data_loader.batch_size + + # Convert the lists to numpy arrays. + log_probs = np.array(log_probs, dtype=float) + c = np.array(c, dtype=np.uint32) + barcodes = np.array(bcs, dtype=np.uint64) # uint32 is too small! + genes = np.array(genes, dtype=np.uint64) # use same as above for IndexConverter + noise_count_offsets = np.array(c_offset, dtype=np.uint32) + + # Translate (barcode, gene) inds to 'm' format index. + m = self.index_converter.get_m_indices(cell_inds=barcodes, gene_inds=genes) + + # Put the counts into a sparse csr_matrix. + self._noise_count_posterior_coo = sp.coo_matrix( + (log_probs, (m, c)), + shape=[np.prod(self.count_matrix_shape), n_counts_max], + ) + noise_offset_dict = dict(zip(m, noise_count_offsets)) + nonzero_noise_offset_dict = {k: v for k, v in noise_offset_dict.items() if (v > 0)} + self._noise_count_posterior_coo_offsets = nonzero_noise_offset_dict + return self._noise_count_posterior_coo + + @torch.no_grad() + def sample(self, data, lambda_multiplier=1., y_map: bool = False) -> torch.Tensor: + """Draw a single posterior sample for the count matrix conditioned on data + + Args: + data: Count matrix (slice: some droplets, all genes) + lambda_multiplier: BasePosterior regularization multiplier + y_map: True to enforce the use of the MAP estimate of y, cell or + no cell. Useful in the case where many samples are collected, + since typically in those cases it is confusing to have samples + where a droplet is both cell-containing and empty. + + Returns: + denoised_output_count_matrix: Single sample of the denoised output + count matrix, sampling all stochastic latent variables in the model. + + """ + + # Sample all the latent variables in the model and get mu, lambda, alpha. + mu_sample, lambda_sample, alpha_sample = self.sample_mu_lambda_alpha(data, y_map=y_map) + + # Compute the big tensor of log probabilities of possible c_{ng}^{noise} values. + log_prob_noise_counts_NGC, poisson_values_low_NG = self._log_prob_noise_count_tensor( + data=data, + mu_est=mu_sample + 1e-30, + lambda_est=lambda_sample * lambda_multiplier + 1e-30, + alpha_est=alpha_sample + 1e-30, + debug=self.debug, + ) + + # Use those probabilities to draw a sample of c_{ng}^{noise} + noise_count_increment_NG = dist.Categorical(logits=log_prob_noise_counts_NGC).sample() + noise_counts_NG = noise_count_increment_NG + poisson_values_low_NG + + # Subtract from data to get the denoised output counts. + denoised_output_count_matrix = data - noise_counts_NG + + return denoised_output_count_matrix + + @torch.no_grad() + def map_denoised_counts_from_sampled_latents(self, + data, + n_samples: int, + lambda_multiplier: float = 1., + y_map: bool = False) -> torch.Tensor: + """Draw posterior samples for all stochastic latent variables in the model + and use those values to compute a MAP estimate of the denoised count + matrix conditioned on data. + + Args: + data: Count matrix (slice: some droplets, all genes) + lambda_multiplier: BasePosterior regularization multiplier + y_map: True to enforce the use of the MAP estimate of y, cell or + no cell. Useful in the case where many samples are collected, + since typically in those cases it is confusing to have samples + where a droplet is both cell-containing and empty. + + Returns: + denoised_output_count_matrix: MAP estimate of the denoised output + count matrix, sampling all stochastic latent variables in the model. + + """ + + noise_log_pdf, offset_noise_counts = self.noise_log_pdf( + data=data, + n_samples=n_samples, + lambda_multiplier=lambda_multiplier, + y_map=y_map, + ) + + noise_counts = torch.argmax(noise_log_pdf, dim=-1) + offset_noise_counts + denoised_output_count_matrix = torch.clamp(data - noise_counts, min=0.) + + return denoised_output_count_matrix + + @torch.no_grad() + def noise_log_pdf(self, + data, + n_samples: int = 1, + lambda_multiplier=1., + y_map: bool = True, + n_counts_max: int = 50) -> Tuple[torch.Tensor, torch.Tensor]: + """Compute the posterior noise-count probability density function + using n_samples samples. This is a big matrix [n, g, c] where the last + dimension c is of variable size depending on the computation in + _log_prob_noise_count_tensor(), but is limited there to be no more than + 100. The c dimension represents an index to the number of noise counts + in [n, g]: specifically, the noise count once poisson_values_low_NG is added + + Args: + data: Count matrix (slice: some droplets, all genes) + n_samples: Number of samples (of all stochastic latent variables in + the model) used to generate the CDF + lambda_multiplier: BasePosterior regularization multiplier + y_map: True to enforce the use of the MAP estimate of y, cell or + no cell. Useful in the case where many samples are collected, + since typically in those cases it is confusing to have samples + where a droplet is both cell-containing and empty. + n_counts_max: Size of count axis (need not start at zero noise + counts, but should be enough to cover the meat of the posterior) + + Returns: + noise_log_pdf_NGC: Consensus noise count log_pdf (big tensor) from the samples. + noise_count_offset_NG: The offset for the noise count axis [n, g]. + + """ + + noise_log_pdf_NGC = None + noise_count_offset_NG = None + + for s in range(1, n_samples + 1): + + # Sample all the latent variables in the model and get mu, lambda, alpha. + mu_sample, lambda_sample, alpha_sample = self.sample_mu_lambda_alpha(data, y_map=y_map) + + # Compute the big tensor of log probabilities of possible c_{ng}^{noise} values. + log_prob_noise_counts_NGC, noise_count_offset_NG = self._log_prob_noise_count_tensor( + data=data, + mu_est=mu_sample + 1e-30, + lambda_est=lambda_sample * lambda_multiplier + 1e-30, + alpha_est=alpha_sample + 1e-30, + n_counts_max=n_counts_max, + debug=self.debug, + ) + + # Normalize the PDFs (not necessarily normalized over the count range). + log_prob_noise_counts_NGC = (log_prob_noise_counts_NGC + - torch.logsumexp(log_prob_noise_counts_NGC, + dim=-1, keepdim=True)) + + # Add the probability from this sample to our running total. + # Update rule is + # log_prob_total_n = LAE [ log(1 - 1/n) + log_prob_total_{n-1}, log(1/n) + log_prob_sample ] + if s == 1: + noise_log_pdf_NGC = log_prob_noise_counts_NGC + else: + # This is a (normalized) running sum over samples in log-probability space. + noise_log_pdf_NGC = torch.logaddexp( + noise_log_pdf_NGC + torch.log(torch.tensor(1. - 1. / s).to(device=data.device)), + log_prob_noise_counts_NGC + torch.log(torch.tensor(1. / s).to(device=data.device)), + ) + + return noise_log_pdf_NGC, noise_count_offset_NG + + @torch.no_grad() + def sample_mu_lambda_alpha(self, + data: torch.Tensor, + y_map: bool) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]: + """Calculate a single sample estimate of mu, the mean of the true count + matrix, and lambda, the rate parameter of the Poisson background counts. + + Args: + data: Dense tensor minibatch of cell by gene count data. + y_map: True to enforce the use of a MAP estimate of y rather than + sampling y. This prevents some samples from having a cell and + some not, which can lead to strange summary statistics over + many samples. + + Returns: + mu_sample: Dense tensor sample of Negative Binomial mean for true + counts. + lambda_sample: Dense tensor sample of Poisson rate params for noise + counts. + alpha_sample: Dense tensor sample of Dirichlet concentration params + that inform the overdispersion of the Negative Binomial. + + """ + + logger.debug('Replaying model with guide to sample mu, alpha, lambda') + + # Use pyro poutine to trace the guide and sample parameter values. + guide_trace = pyro.poutine.trace(self.vi_model.guide).get_trace(x=data) + + # If using MAP for y (so that you never get samples of cell and no cell), + # then intervene and replace a sampled y with the MAP + if y_map: + guide_trace.nodes['y']['value'] = ( + guide_trace.nodes['p_passback']['value'] > 0 + ).clone().detach() + + replayed_model = pyro.poutine.replay(self.vi_model.model, guide_trace) + + # Run the model using these sampled values. + replayed_model_output = replayed_model(x=data) + + # The model returns mu, alpha, and lambda. + mu_sample = replayed_model_output['mu'] + lambda_sample = replayed_model_output['lam'] + alpha_sample = replayed_model_output['alpha'] + + return mu_sample, lambda_sample, alpha_sample + + @staticmethod + @torch.no_grad() + def _log_prob_noise_count_tensor(data: torch.Tensor, + mu_est: torch.Tensor, + lambda_est: torch.Tensor, + alpha_est: Optional[torch.Tensor], + n_counts_max: int = 100, + debug: bool = False) -> Tuple[torch.Tensor, torch.Tensor]: + """Compute the log prob of noise counts [n, g, c] given mu, lambda, alpha, and the data. + + NOTE: this is un-normalized log probability + + Args: + data: Dense tensor minibatch of cell by gene count data. + mu_est: Dense tensor of Negative Binomial means for true counts. + lambda_est: Dense tensor of Poisson rate params for noise counts. + alpha_est: Dense tensor of Dirichlet concentration params that + inform the overdispersion of the Negative Binomial. None will + use an all-Poisson model + n_counts_max: Size of noise count dimension c + debug: True will go slow and check for NaNs and zero-probability entries + + Returns: + log_prob_tensor: Probability of each noise count value. + poisson_values_low: The starting point for noise counts for each + cell and gene, because they can be different. + + """ + + # Estimate a reasonable low-end to begin the Poisson summation. + n = min(n_counts_max, data.max().item()) # No need to exceed the max value + poisson_values_low = (lambda_est.detach() - n / 2).int() + + poisson_values_low = torch.clamp(torch.min(poisson_values_low, + (data - n + 1).int()), min=0).float() + + # Construct a big tensor of possible noise counts per cell per gene, + # shape (batch_cells, n_genes, max_noise_counts) + noise_count_tensor = torch.arange(start=0, end=n) \ + .expand([data.shape[0], data.shape[1], -1]) \ + .float().to(device=data.device) + noise_count_tensor = noise_count_tensor + poisson_values_low.unsqueeze(-1) + + # Compute probabilities of each number of noise counts. + # NOTE: some values will be outside the support (negative values for NB). + # This results in NaNs. + if alpha_est is None: + # Poisson only model + log_prob_tensor = (dist.Poisson(lambda_est.unsqueeze(-1), validate_args=False) + .log_prob(noise_count_tensor) + + dist.Poisson(mu_est.unsqueeze(-1), validate_args=False) + .log_prob(data.unsqueeze(-1) - noise_count_tensor)) + logger.debug('Using all poisson model (since alpha is not supplied to posterior)') + else: + logits = (mu_est.log() - alpha_est.log()).unsqueeze(-1) + log_prob_tensor = (dist.Poisson(lambda_est.unsqueeze(-1), validate_args=False) + .log_prob(noise_count_tensor) + + dist.NegativeBinomial(total_count=alpha_est.unsqueeze(-1), + logits=logits, + validate_args=False) + .log_prob(data.unsqueeze(-1) - noise_count_tensor)) + + # Set log_prob to -inf if noise > data. + neg_inf_tensor = torch.ones_like(log_prob_tensor) * -np.inf + log_prob_tensor = torch.where((noise_count_tensor <= data.unsqueeze(-1)), + log_prob_tensor, + neg_inf_tensor) + + logger.debug(f'Prob computation with tensor of shape {log_prob_tensor.shape}') + + if debug: + assert not torch.isnan(log_prob_tensor).any(), \ + 'log_prob_tensor contains a NaN' + if torch.isinf(log_prob_tensor).all(dim=-1).any(): + print(torch.where(torch.isinf(log_prob_tensor).all(dim=-1))) + raise AssertionError('There is at least one log_prob_tensor[n, g, :] ' + 'that has all-zero probability') + + return log_prob_tensor, poisson_values_low + + @torch.no_grad() + def _get_latents_map(self): + """Calculate the encoded latent variables.""" + + logger.debug('Computing latent variables') + + if self.vi_model is None: + self._latents = {'z': None, 'd': None, 'p': None, 'phi_loc_scale': None, 'epsilon': None} + return None + + data_loader = self.dataset_obj.get_dataloader(use_cuda=self.use_cuda, + analyzed_bcs_only=True, + batch_size=500, + shuffle=False) + + n_analyzed = data_loader.dataset.shape[0] + + z = np.zeros((n_analyzed, self.vi_model.encoder['z'].output_dim)) + d = np.zeros(n_analyzed) + p = np.zeros(n_analyzed) + epsilon = np.zeros(n_analyzed) + + phi_loc = pyro.param('phi_loc') + phi_scale = pyro.param('phi_scale') + if 'chi_ambient' in pyro.get_param_store().keys(): + chi_ambient = pyro.param('chi_ambient').detach() + else: + chi_ambient = None + + start = 0 + for i, data in enumerate(data_loader): + + end = start + data.shape[0] + + enc = self.vi_model.encoder(x=data, + chi_ambient=chi_ambient, + cell_prior_log=self.vi_model.d_cell_loc_prior) + z[start:end, :] = enc['z']['loc'].detach().cpu().numpy() + + d[start:end] = \ + dist.LogNormal(loc=enc['d_loc'], + scale=pyro.param('d_cell_scale')).mean.detach().cpu().numpy() + + p[start:end] = enc['p_y'].sigmoid().detach().cpu().numpy() + + epsilon[start:end] = \ + dist.Gamma(enc['epsilon'] * self.vi_model.epsilon_prior, + self.vi_model.epsilon_prior).mean.detach().cpu().numpy() + + start = end + + self._latents = {'z': z, + 'd': d, + 'p': p, + 'phi_loc_scale': [phi_loc.item(), phi_scale.item()], + 'epsilon': epsilon} + + @torch.no_grad() + def _get_mu_alpha_lambda_map(self, + data: torch.Tensor, + chi_ambient: torch.Tensor) -> Dict[str, torch.Tensor]: + """Calculate MAP estimates of mu, the mean of the true count matrix, and + lambda, the rate parameter of the Poisson background counts. + + Args: + data: Dense tensor minibatch of cell by gene count data. + chi_ambient: Point estimate of inferred ambient gene expression. + + Returns: + mu_map: Dense tensor of Negative Binomial means for true counts. + lambda_map: Dense tensor of Poisson rate params for noise counts. + alpha_map: Dense tensor of Dirichlet concentration params that + inform the overdispersion of the Negative Binomial. + + """ + + logger.debug('Computing MAP esitmate of mu, lambda, alpha') + + # Encode latents. + enc = self.vi_model.encoder(x=data, + chi_ambient=chi_ambient, + cell_prior_log=self.vi_model.d_cell_loc_prior) + z_map = enc['z']['loc'] + + chi_map = self.vi_model.decoder(z_map) + phi_loc = pyro.param('phi_loc') + phi_scale = pyro.param('phi_scale') + phi_conc = phi_loc.pow(2) / phi_scale.pow(2) + phi_rate = phi_loc / phi_scale.pow(2) + alpha_map = 1. / dist.Gamma(phi_conc, phi_rate).mean + + y = (enc['p_y'] > 0).float() + d_empty = dist.LogNormal(loc=pyro.param('d_empty_loc'), + scale=pyro.param('d_empty_scale')).mean + d_cell = dist.LogNormal(loc=enc['d_loc'], + scale=pyro.param('d_cell_scale')).mean + epsilon = dist.Gamma(enc['epsilon'] * self.vi_model.epsilon_prior, + self.vi_model.epsilon_prior).mean + + if self.vi_model.include_rho: + rho = pyro.param("rho_alpha") / (pyro.param("rho_alpha") + + pyro.param("rho_beta")) + else: + rho = None + + # Calculate MAP estimates of mu and lambda. + mu_map = calculate_mu( + epsilon=epsilon, + d_cell=d_cell, + chi=chi_map, + y=y, + rho=rho, + ) + lambda_map = calculate_lambda( + epsilon=epsilon, + chi_ambient=chi_ambient, + d_empty=d_empty, + y=y, + d_cell=d_cell, + rho=rho, + chi_bar=self.vi_model.avg_gene_expression, + ) + + return {'mu': mu_map, 'lam': lambda_map, 'alpha': alpha_map} + + +class PosteriorRegularization(ABC): + + def __init__(self): + super(PosteriorRegularization, self).__init__() + + @staticmethod + @abstractmethod + def name(): + """Short name of this regularization method""" + pass + + @staticmethod + @abstractmethod + def regularize(noise_count_posterior_coo: sp.coo_matrix, + noise_offsets: Dict[int, int], + **kwargs) -> sp.coo_matrix: + """Perform posterior regularization""" + pass + + +class PRq(PosteriorRegularization): + """Approximate noise CDF quantile targeting: + + E_reg[noise_counts] >= E[noise_counts] + \alpha * Std[noise_counts] + + """ + + @staticmethod + def name(): + return 'PRq' + + @staticmethod + def _log_mean_plus_alpha_std(log_prob: torch.Tensor, alpha: float): + c = torch.arange(log_prob.shape[1]).float().to(log_prob.device).unsqueeze(0) + prob = log_prob.exp() + mean = (c * prob).sum(dim=-1) + std = (((c - mean.unsqueeze(-1)).pow(2) * prob).sum(dim=-1)).sqrt() + return (mean + alpha * std).log() + + @staticmethod + def _compute_log_target_dict(noise_count_posterior_coo: sp.coo_matrix, + alpha: float) -> Dict[int, float]: + """Given the noise count posterior, return log(mean + alpha * std) + for each 'm' index + + NOTE: noise_log_pdf_BC should be normalized + + Args: + noise_count_posterior_coo: The noise count posterior data structure + alpha: The tunable parameter of mean-targeting posterior + regularization. The output distribution has a mean which is + input_mean + alpha * input_std (if possible) + + Returns: + log_mean_plus_alpha_std: Dict keyed by 'm', where values are + log(mean + alpha * std) + + """ + result = apply_function_dense_chunks(noise_log_prob_coo=noise_count_posterior_coo, + fun=PRq._log_mean_plus_alpha_std, + alpha=alpha) + return dict(zip(result['m'], result['result'])) + + @staticmethod + def _get_alpha_log_constraint_violation_given_beta( + beta_B: torch.Tensor, + log_pdf_noise_counts_BC: torch.Tensor, + noise_count_BC: torch.Tensor, + log_mu_plus_alpha_sigma_B: torch.Tensor) -> torch.Tensor: + r"""Returns log constraint violation for the regularized posterior of p(x), which + here is p(\omega) = p(x) e^{\beta x}, and we want + E[\omega] = E[x] + \alpha * Std[x] = log_mu_plus_alpha_sigma_B.exp() + + NOTE: Binary search to find the root of this function can yield a value for beta_B. + + Args: + beta_B: The parameter of the regularized posterior, with batch dimension + log_pdf_noise_counts_BC: The probability density of noise counts, with batch + and count dimensions + noise_count_BC: Noise counts, with batch and count dimensions + log_mu_plus_alpha_sigma_B: The constraint value to be satisfied, with batch dimension + + Returns: + The amount by which the desired equality with log_mu_plus_alpha_sigma_B is violated, + with batch dimension + + """ + + log_numerator_B = torch.logsumexp( + noise_count_BC.log() + log_pdf_noise_counts_BC + beta_B.unsqueeze(-1) * noise_count_BC, + dim=-1, + ) + log_denominator_B = torch.logsumexp( + log_pdf_noise_counts_BC + beta_B.unsqueeze(-1) * noise_count_BC, + dim=-1, + ) + return log_numerator_B - log_denominator_B - log_mu_plus_alpha_sigma_B + + @staticmethod + def _chunked_compute_regularized_posterior( + noise_count_posterior_coo: sp.coo_matrix, + noise_offsets: Dict[int, int], + log_constraint_violation_fcn: Callable[[torch.Tensor, torch.Tensor, + torch.Tensor, torch.Tensor], torch.Tensor], + log_target_M: torch.Tensor, + target_tolerance: float = 0.001, + device: str = 'cpu', + n_chunks: Optional[int] = None, + ) -> sp.coo_matrix: + """Go through posterior in chunks and compute regularized posterior, + using the defined targets""" + + # Compute using dense chunks, chunked on m-index. + if n_chunks is None: + dense_size_gb = (len(np.unique(noise_count_posterior_coo.row)) + * (noise_count_posterior_coo.shape[1] + + np.array(list(noise_offsets.values())).max())) * 4 / 1e9 # GB + n_chunks = max(1, int(dense_size_gb // 1)) # approx 1 GB each + + # Make the sparse matrix compact in the sense that it should use contiguous row values. + unique_rows, densifiable_coo_rows = np.unique(noise_count_posterior_coo.row, return_inverse=True) + densifiable_csr = sp.csr_matrix((noise_count_posterior_coo.data, + (densifiable_coo_rows, noise_count_posterior_coo.col)), + shape=[len(unique_rows), noise_count_posterior_coo.shape[1]]) + chunk_size = int(np.ceil(densifiable_csr.shape[0] / n_chunks)) + + m = [] + c = [] + log_prob_reg = [] + + for i in range(n_chunks): + # B index here represents a batch: the re-defined m-index + log_pdf_noise_counts_BC = torch.tensor( + log_prob_sparse_to_dense(densifiable_csr[(i * chunk_size):((i + 1) * chunk_size)]) + ).to(device) + noise_count_BC = (torch.arange(log_pdf_noise_counts_BC.shape[1]) + .to(log_pdf_noise_counts_BC.device) + .unsqueeze(0) + .expand(log_pdf_noise_counts_BC.shape)) + m_indices_for_chunk = unique_rows[(i * chunk_size):((i + 1) * chunk_size)] + noise_count_BC = noise_count_BC + (torch.tensor([noise_offsets.get(m, 0) + for m in m_indices_for_chunk], + dtype=torch.float) + .unsqueeze(-1) + .to(device)) + + # Parallel binary search for beta for each entry of count matrix + beta_B = torch_binary_search( + evaluate_outcome_given_value=lambda x: + log_constraint_violation_fcn( + beta_B=x, + log_pdf_noise_counts_BC=log_pdf_noise_counts_BC, + noise_count_BC=noise_count_BC, + log_mu_plus_alpha_sigma_B=log_target_M[(i * chunk_size):((i + 1) * chunk_size)], + ), + target_outcome=torch.zeros(noise_count_BC.shape[0]).to(device), + init_range=(torch.tensor([-100., 100.]) + .to(device) + .unsqueeze(0) + .expand((noise_count_BC.shape[0],) + (2,))), + target_tolerance=target_tolerance, + max_iterations=100, + ) + + # Generate regularized posteriors. + log_pdf_reg_BC = log_pdf_noise_counts_BC + beta_B.unsqueeze(-1) * noise_count_BC + log_pdf_reg_BC = log_pdf_reg_BC - torch.logsumexp(log_pdf_reg_BC, -1, keepdims=True) + + # Store sparse COO values in lists. + tensor_for_nonzeros = log_pdf_reg_BC.clone().exp() # probability + m_i, c_i, log_prob_reg_i = dense_to_sparse_op_torch( + log_pdf_reg_BC, + tensor_for_nonzeros=tensor_for_nonzeros, + ) + m_i = np.array([m_indices_for_chunk[j] for j in m_i]) # chunk m to actual m + + # Add sparse matrix values to lists. + try: + m.extend(m_i.tolist()) + c.extend(c_i.tolist()) + log_prob_reg.extend(log_prob_reg_i.tolist()) + except TypeError as e: + # edge case of a single value + m.append(m_i) + c.append(c_i) + log_prob_reg.append(log_prob_reg_i) + + reg_noise_count_posterior_coo = sp.coo_matrix((log_prob_reg, (m, c)), + shape=noise_count_posterior_coo.shape) + return reg_noise_count_posterior_coo + + @staticmethod + @torch.no_grad() + def regularize(noise_count_posterior_coo: sp.coo_matrix, + noise_offsets: Dict[int, int], + alpha: float, + device: str = 'cuda', + target_tolerance: float = 0.001, + n_chunks: Optional[int] = None, + **kwargs) -> sp.coo_matrix: + """Perform posterior regularization using approximate quantile-targeting. + + Args: + noise_count_posterior_coo: Noise count posterior log prob COO + noise_offsets: Offset noise counts per 'm' index + alpha: The tunable parameter of quantile-targeting posterior + regularization. The output distribution has a mean which is + input_mean + alpha * input_std (if possible) + device: Where to perform tensor operations: ['cuda', 'cpu'] + target_tolerance: Tolerance when searching using binary search + n_chunks: For testing only - the number of chunks used to + compute the result when iterating over the posterior + + Results: + reg_noise_count_posterior_coo: The regularized noise count + posterior data structure + + """ + logger.info(f'Regularizing noise count posterior using approximate quantile-targeting with alpha={alpha}') + + # Compute the expectation for the mean post-regularization. + log_target_dict = PRq._compute_log_target_dict( + noise_count_posterior_coo=noise_count_posterior_coo, + alpha=alpha, + ) + log_target_M = torch.tensor(list(log_target_dict.values())).to(device) + + reg_noise_count_posterior_coo = PRq._chunked_compute_regularized_posterior( + noise_count_posterior_coo=noise_count_posterior_coo, + noise_offsets=noise_offsets, + log_target_M=log_target_M, + log_constraint_violation_fcn=PRq._get_alpha_log_constraint_violation_given_beta, + device=device, + target_tolerance=target_tolerance, + n_chunks=n_chunks, + ) + + return reg_noise_count_posterior_coo + + +class PRmu(PosteriorRegularization): + r"""Approximate noise mean targeting: + + Overall (default): + E_reg[\sum_{n} \sum_{g} noise_counts_{ng}] = + E[\sum_{n} \sum_{g} noise_counts_{ng}] + nFPR * \sum_{n} \sum_{g} raw_counts_{ng} + + Per-gene: + E_reg[\sum_{n} noise_counts_{ng}] = + E[\sum_{n} noise_counts_{ng}] + nFPR * \sum_{n} raw_counts_{ng} + + """ + + @staticmethod + def name(): + return 'PRmu' + + @staticmethod + def _binary_search_for_posterior_regularization_factor( + noise_count_posterior_coo: sp.coo_matrix, + noise_offsets: Dict[int, int], + index_converter: 'IndexConverter', + target_removal: torch.Tensor, + shape: int, + target_tolerance: float = 100, + max_iterations: int = 20, + device: str = 'cpu', + ) -> torch.Tensor: + """Go through posterior and compute regularization factor(s), + using the defined targets""" + + def summarize_map_noise_counts(x: torch.Tensor, + per_gene: bool) -> torch.Tensor: + """Given a (subset of the) noise posterior, compute the MAP estimate + and summarize it either as the overall sum or per-gene. + """ + + # Regularize posterior. + regularized_noise_posterior_coo = PRmu._chunked_compute_regularized_posterior( + noise_count_posterior_coo=noise_count_posterior_coo, + noise_offsets=noise_offsets, + index_converter=index_converter, + beta=x, + device=device, + ) + + # Compute MAP. + estimator = MAP(index_converter=index_converter) + map_noise_csr = estimator.estimate_noise( + noise_log_prob_coo=regularized_noise_posterior_coo, + noise_offsets=noise_offsets, + device=device, + ) + + # Summarize removal. + if per_gene: + noise_counts = np.array(map_noise_csr.sum(axis=0)).squeeze() + else: + noise_counts = map_noise_csr.sum() + + return torch.tensor(noise_counts).to(device) + + # Perform binary search for beta. + per_gene = False + if target_removal.dim() > 0: + if len(target_removal) > 1: + per_gene = True + + beta = torch_binary_search( + evaluate_outcome_given_value=lambda x: + summarize_map_noise_counts(x=x, per_gene=per_gene), + target_outcome=target_removal, + init_range=(torch.tensor([-100., 200.]) + .to(device) + .unsqueeze(0) + .expand((shape,) + (2,))), + target_tolerance=target_tolerance, + max_iterations=max_iterations, + debug=True, + ) + return beta + + @staticmethod + def _chunked_compute_regularized_posterior( + noise_count_posterior_coo: sp.coo_matrix, + noise_offsets: Dict[int, int], + index_converter: 'IndexConverter', + beta: torch.Tensor, + device: str = 'cpu', + n_chunks: Optional[int] = None, + ) -> sp.coo_matrix: + """Go through posterior in chunks and compute regularized posterior, + using the defined targets""" + + # Compute using dense chunks, chunked on m-index. + if n_chunks is None: + dense_size_gb = (len(np.unique(noise_count_posterior_coo.row)) + * (noise_count_posterior_coo.shape[1] + + np.array(list(noise_offsets.values())).max())) * 4 / 1e9 # GB + n_chunks = max(1, int(dense_size_gb // 1)) # approx 1 GB each + + # Make the sparse matrix compact in the sense that it should use contiguous row values. + unique_rows, densifiable_coo_rows = np.unique(noise_count_posterior_coo.row, return_inverse=True) + densifiable_csr = sp.csr_matrix((noise_count_posterior_coo.data, + (densifiable_coo_rows, noise_count_posterior_coo.col)), + shape=[len(unique_rows), noise_count_posterior_coo.shape[1]]) + chunk_size = int(np.ceil(densifiable_csr.shape[0] / n_chunks)) + + m = [] + c = [] + log_prob_reg = [] + + for i in range(n_chunks): + # B index here represents a batch: the re-defined m-index + log_pdf_noise_counts_BC = torch.tensor( + log_prob_sparse_to_dense(densifiable_csr[(i * chunk_size):((i + 1) * chunk_size)]) + ).to(device) + noise_count_BC = (torch.arange(log_pdf_noise_counts_BC.shape[1]) + .to(log_pdf_noise_counts_BC.device) + .unsqueeze(0) + .expand(log_pdf_noise_counts_BC.shape)) + m_indices_for_chunk = unique_rows[(i * chunk_size):((i + 1) * chunk_size)] + noise_count_BC = noise_count_BC + (torch.tensor([noise_offsets.get(m, 0) + for m in m_indices_for_chunk], + dtype=torch.float) + .unsqueeze(-1) + .to(device)) + + # Get beta for this chunk. + if len(beta) == 1: + # posterior regularization factor is a single scalar + beta_B = beta + else: + # per-gene mode + n, g = index_converter.get_ng_indices(m_inds=m_indices_for_chunk) + beta_B = torch.tensor([beta[gene] for gene in g]) + + # Generate regularized posteriors. + log_pdf_reg_BC = log_pdf_noise_counts_BC + beta_B.unsqueeze(-1) * noise_count_BC + log_pdf_reg_BC = log_pdf_reg_BC - torch.logsumexp(log_pdf_reg_BC, -1, keepdims=True) + + # Store sparse COO values in lists. + tensor_for_nonzeros = log_pdf_reg_BC.clone().exp() # probability + # tensor_for_nonzeros.data[data == 0, :] = 0. # remove data = 0 + m_i, c_i, log_prob_reg_i = dense_to_sparse_op_torch( + log_pdf_reg_BC, + tensor_for_nonzeros=tensor_for_nonzeros, + ) + m_i = np.array([m_indices_for_chunk[j] for j in m_i]) # chunk m to actual m + + # Add sparse matrix values to lists. + try: + m.extend(m_i.tolist()) + c.extend(c_i.tolist()) + log_prob_reg.extend(log_prob_reg_i.tolist()) + except TypeError as e: + # edge case of a single value + m.append(m_i) + c.append(c_i) + log_prob_reg.append(log_prob_reg_i) + + reg_noise_count_posterior_coo = sp.coo_matrix((log_prob_reg, (m, c)), + shape=noise_count_posterior_coo.shape) + return reg_noise_count_posterior_coo + + @staticmethod + def _subset_posterior_by_cells(noise_count_posterior_coo: sp.coo_matrix, + index_converter: 'IndexConverter', + n_cells: int) -> sp.coo_matrix: + """Return a random slice of the full posterior with a specified number + of cells. + + NOTE: Assumes that all the entries in noise_count_posterior_coo are for + cell-containing droplets, and not empty droplets. + + Args: + noise_count_posterior_coo: The noise count posterior data structure + n_cells: The number of cells in the output subset + + Returns: + subset_coo: Posterior for a random subset of cells, in COO format + """ + + # Choose cells that will be included. + m = noise_count_posterior_coo.row + n, g = index_converter.get_ng_indices(m_inds=m) + unique_cell_inds = np.unique(n) + if n_cells > len(unique_cell_inds): + logger.debug(f'Limiting n_cells during PRmu regularizer binary search to {unique_cell_inds}') + n_cells = len(unique_cell_inds) + chosen_n_values = set(np.random.choice(unique_cell_inds, size=n_cells, replace=False)) + element_logic = [val in chosen_n_values for val in n] + + # Subset the posterior. + data_subset = noise_count_posterior_coo.data[element_logic] + row_subset = noise_count_posterior_coo.row[element_logic] + col_subset = noise_count_posterior_coo.col[element_logic] + return sp.coo_matrix((data_subset, (row_subset, col_subset)), + shape=noise_count_posterior_coo.shape) + + @staticmethod + @torch.no_grad() + def regularize(noise_count_posterior_coo: sp.coo_matrix, + noise_offsets: Dict[int, int], + index_converter: 'IndexConverter', + raw_count_matrix: sp.csr_matrix, + fpr: float, + per_gene: bool = False, + device: str = 'cuda', + target_tolerance: float = 0.5, + n_cells: int = 1000, + n_chunks: Optional[int] = None, + **kwargs) -> sp.coo_matrix: + """Perform posterior regularization using mean-targeting. + + Args: + noise_count_posterior_coo: Noise count posterior log prob COO + noise_offsets: Offset noise counts per 'm' index + index_converter: IndexConverter object from 'm' to (n, g) and back + raw_count_matrix: The raw count matrix + fpr: The tunable parameter of mean-targeting posterior + regularization. The output, summed over cells, has a removed + gene count distribution similar to what would be expected from + the noise model, plus this nominal false positive rate. + per_gene: True to find one posterior regularization factor for each + gene, False to find one overall scalar (behavior of v0.2.0) + device: Where to perform tensor operations: ['cuda', 'cpu'] + target_tolerance: Tolerance when searching using binary search. + In units of counts, so this really should not be less than 0.5 + n_cells: To save time, use only this many cells to estimate removal + n_chunks: For testing only - the number of chunks used to + compute the result when iterating over the posterior + + Results: + reg_noise_count_posterior_coo: The regularized noise count + posterior data structure + + """ + + logger.info('Regularizing noise count posterior using mean-targeting') + + # Use a subset of the data to find regularization factors, to reduce time. + logger.debug(f'Subsetting posterior to {n_cells} cells for this computation') + posterior_subset_coo = PRmu._subset_posterior_by_cells( + noise_count_posterior_coo=noise_count_posterior_coo, + index_converter=index_converter, + n_cells=n_cells, + ) + + # Compute target removal for MAP estimate using regularized posterior. + n, g = index_converter.get_ng_indices(m_inds=posterior_subset_coo.row) + included_cells = set(np.unique(n)) + excluded_barcode_inds = set(range(raw_count_matrix.shape[0])) - included_cells + raw_count_csr_for_cells = csr_set_rows_to_zero(csr=raw_count_matrix, + row_inds=excluded_barcode_inds) + # print(raw_count_csr_for_cells) + logger.debug('Computing target removal') + target_fun = compute_mean_target_removal_as_function( + noise_count_posterior_coo=posterior_subset_coo, + noise_offsets=noise_offsets, + index_converter=index_converter, + raw_count_csr_for_cells=raw_count_csr_for_cells, + n_cells=len(included_cells), + device=device, + per_gene=per_gene, + ) + target_removal = target_fun(fpr) * len(included_cells) + logger.debug(f'Target removal is {target_removal}') + + # Find the posterior regularization factor(s). + if per_gene: + logger.debug('Computing optimal posterior regularization factors for each gene') + shape = index_converter.total_n_genes + else: + logger.debug('Computing optimal posterior regularization factor') + shape = 1 + beta = PRmu._binary_search_for_posterior_regularization_factor( + noise_count_posterior_coo=posterior_subset_coo, + noise_offsets=noise_offsets, + index_converter=index_converter, + target_removal=target_removal, + device=device, + target_tolerance=target_tolerance, + shape=shape, + ) + logger.debug(f'Optimal posterior regularization factor\n{beta}') + + # Compute the posterior using the regularization factor(s). + logger.debug('Computing full regularized posterior') + regularized_noise_posterior_coo = PRmu._chunked_compute_regularized_posterior( + noise_count_posterior_coo=noise_count_posterior_coo, + noise_offsets=noise_offsets, + index_converter=index_converter, + beta=beta, + device=device, + ) + + return regularized_noise_posterior_coo + + +class IndexConverter: + + def __init__(self, total_n_cells: int, total_n_genes: int): + """Convert between (n, g) indices and flattened 'm' indices + + Args: + total_n_cells: Total rows in the full sparse matrix + total_n_genes: Total columns in the full sparse matrix + + """ + self.total_n_cells = total_n_cells + self.total_n_genes = total_n_genes + self.matrix_shape = (total_n_cells, total_n_genes) + + def __repr__(self): + return (f'IndexConverter with' + f'\n\ttotal_n_cells: {self.total_n_cells}' + f'\n\ttotal_n_genes: {self.total_n_genes}' + f'\n\tmatrix_shape: {self.matrix_shape}') + + def get_m_indices(self, cell_inds: np.ndarray, gene_inds: np.ndarray) -> np.ndarray: + """Given arrays of cell indices and gene indices, suitable for a sparse matrix, + convert them to 'm' index values. + """ + if not ((cell_inds >= 0) & (cell_inds < self.total_n_cells)).all(): + raise ValueError(f'Requested cell_inds out of range: ' + f'{cell_inds[(cell_inds < 0) | (cell_inds >= self.total_n_cells)]}') + if not ((gene_inds >= 0) & (gene_inds < self.total_n_genes)).all(): + raise ValueError(f'Requested gene_inds out of range: ' + f'{gene_inds[(gene_inds < 0) | (gene_inds >= self.total_n_genes)]}') + return cell_inds * self.total_n_genes + gene_inds + + def get_ng_indices(self, m_inds: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + """Given a list of 'm' index values, return two arrays: cell index values + and gene index values, suitable for a sparse matrix. + """ + if not ((m_inds >= 0) & (m_inds < self.total_n_cells * self.total_n_genes)).all(): + raise ValueError(f'Requested m_inds out of range: ' + f'{m_inds[(m_inds < 0) | (m_inds >= self.total_n_cells * self.total_n_genes)]}') + return np.divmod(m_inds, self.total_n_genes) + + +def compute_mean_target_removal_as_function(noise_count_posterior_coo: sp.coo_matrix, + noise_offsets: Dict[int, int], + index_converter: IndexConverter, + raw_count_csr_for_cells: sp.csr_matrix, + n_cells: int, + device: str, + per_gene: bool) -> Callable[[float], torch.Tensor]: + """Given the noise count posterior, return a function that computes target + removal (either overall or per-gene) as a function of FPR. + + NOTE: computes the value "per cell", i.e. dividing + by the number of cells, so that total removal can be computed by + multiplying this by the number of cells in question. + + Args: + noise_count_posterior_coo: Noise count posterior log prob COO + noise_offsets: Offset noise counts per 'm' index + index_converter: IndexConverter object from 'm' to (n, g) and back + raw_count_csr_for_cells: The input count matrix for only the cells + included in the posterior + n_cells: Number of cells included in the posterior, same number as in + raw_count_csr_for_cells + device: 'cpu' or 'cuda' + per_gene: True to come up with one target per gene + + Returns: + target_removal_scaled_per_cell: Noise count removal target + + """ + + # TODO: s1.h5 with FPR 0.99 only removes 50% of signal + + # Compute the expected noise using mean summarization. + estimator = Mean(index_converter=index_converter) + mean_noise_csr = estimator.estimate_noise( + noise_log_prob_coo=noise_count_posterior_coo, + noise_offsets=noise_offsets, + device=device, + ) + logger.debug(f'Total counts in raw matrix for cells = {raw_count_csr_for_cells.sum()}') + logger.debug(f'Total noise counts from mean noise estimator = {mean_noise_csr.sum()}') + + # Compute the target removal. + approx_signal_csr = raw_count_csr_for_cells - mean_noise_csr + logger.debug(f'Approximate signal has total counts = {approx_signal_csr.sum()}') + logger.debug(f'Number of cells = {n_cells}') + + def _target_fun(fpr: float) -> torch.Tensor: + """The function which gets returned""" + if per_gene: + target = np.array(mean_noise_csr.sum(axis=0)).squeeze() + target = target + fpr * np.array(approx_signal_csr.sum(axis=0)).squeeze() + else: + target = mean_noise_csr.sum() + target = target + fpr * approx_signal_csr.sum() + + # Return target scaled to be per-cell. + return torch.tensor(target / n_cells).to(device) + + return _target_fun + + +@torch.no_grad() +def torch_binary_search( + evaluate_outcome_given_value: Callable[[torch.Tensor], torch.Tensor], + target_outcome: torch.Tensor, + init_range: torch.Tensor, + target_tolerance: Optional[float] = 0.001, + max_iterations: int = consts.POSTERIOR_REG_SEARCH_MAX_ITER, + debug: bool = False, +) -> torch.Tensor: + """Perform a binary search, given a target and an evaluation function. + + NOTE: evaluate_outcome_given_value(value) should increase monotonically + with the input value. It is assumed that + consts.POSTERIOR_REG_MIN < output_value < consts.POSTERIOR_REG_MAX. + If this is not the case, the algorithm will produce an output close to one + of those endpoints, and target_tolerance will not be achieved. + Moreover, output_value must be positive (due to how we search for limits). + + Args: + evaluate_outcome_given_value: Function that takes a value as its + input and produces the outcome, which is the target we are + trying to control. Should increase monotonically with value. + target_outcome: Desired outcome value from evaluate_outcome_given_value(value). + init_range: Search range, for each value. + target_tolerance: Tolerated error in the target value. + max_iterations: A cutoff to ensure termination. Even if a tolerable + solution is not found, the algorithm will stop after this many + iterations and return the best answer so far. + debug: Print debugging messages. + + Returns: + value: Result of binary search. Same shape as init_value. + + """ + + logger.debug('Binary search commencing') + + assert (target_tolerance > 0), 'target_tolerance should be > 0.' + assert len(init_range.shape) > 1, 'init_range must be at least two-dimensional ' \ + '(last dimension contains lower and upper bounds)' + assert init_range.shape[-1] == 2, 'Last dimension of init_range should be 2: low and high' + + value_bracket = init_range.clone() + + # Binary search algorithm. + for i in range(max_iterations): + + logger.debug(f'Binary search limits [batch_dim=0, :]: ' + f'{value_bracket.reshape(-1, value_bracket.shape[-1])[0, :]}') + + # Current test value. + value = value_bracket.mean(dim=-1) + + # Calculate an expected false positive rate for this lam_mult value. + outcome = evaluate_outcome_given_value(value) + residual = target_outcome - outcome + + # Check on residual and update our bracket values. + stop_condition = (residual.abs() < target_tolerance).all() + if stop_condition: + break + else: + value_bracket[..., 0] = torch.where(outcome < target_outcome - target_tolerance, + value, + value_bracket[..., 0]) + value_bracket[..., 1] = torch.where(outcome > target_outcome + target_tolerance, + value, + value_bracket[..., 1]) + + # If we stopped due to iteration limit, take the average value. + if i == max_iterations: + value = value_bracket.mean(dim=-1) + logger.warning(f'Binary search target not achieved in {max_iterations} attempts. ' + f'Output is estimated to be {outcome.mean().item():.4f}') + + # Warn if we railed out at the limits of the search + if debug: + if (value - target_tolerance <= init_range[..., 0]).sum() > 0: + logger.debug(f'{(value - target_tolerance <= init_range[..., 0]).sum()} ' + f'entries in the binary search hit the lower limit') + logger.debug(value[value - target_tolerance <= init_range[..., 0]]) + if (value + target_tolerance >= init_range[..., 1]).sum() > 0: + logger.debug(f'{(value + target_tolerance >= init_range[..., 1]).sum()} ' + f'entries in the binary search hit the upper limit') + logger.debug(value[value + target_tolerance >= init_range[..., 1]]) + + return value + + +def restore_from_checkpoint(tarball_name: str, input_file: str) \ + -> Tuple['SingleCellRNACountsDataset', 'RemoveBackgroundPyroModel', Posterior]: + """Convenience function not used by the codebase""" + + d = load_checkpoint(filebase=None, tarball_name=tarball_name) + d.update(load_from_checkpoint(filebase=None, tarball_name=tarball_name, to_load=['posterior'])) + d['args'].input_file = input_file + + dataset_obj = get_dataset_obj(args=d['args']) + + posterior = Posterior( + dataset_obj=dataset_obj, + vi_model=d['model'], + ) + posterior.load(file=d['posterior_file']) + return dataset_obj, d['model'], posterior diff --git a/cellbender/remove_background/report.ipynb b/cellbender/remove_background/report.ipynb new file mode 100644 index 00000000..b091c1b8 --- /dev/null +++ b/cellbender/remove_background/report.ipynb @@ -0,0 +1,133 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# CellBender `remove-background` report" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This output report from `cellbender remove-background` contains a summary of the run, including counts remaining, counts removed, further analyses, and any warnings or suggestions if the run seems to be abnormal.\n", + "\n", + "This HTML report is created from a jupyter notebook at \n", + "\n", + "`cellbender/cellbender/remove-background/report.ipynb`\n", + "\n", + "within the CellBender codebase. Feel free to run the notebook yourself and make any changes you see fit, or use it as a starting point for further analyses." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*The commentary in this report is generated using automated heuristics and best guesses based on hundreds of real datasets. If any of the automated commentary in this report seems incorrect for your dataset, please submit a question or an issue at our github repository https://github.com/broadinstitute/CellBender*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Cellarium Lab .. Methods Group .. Data Sciences Platform .. Broad Institute" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "-----------" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from cellbender.remove_background.report import generate_summary_plots" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Input and output files" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(Modify this section if you run this notebook yourself.)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Allows us to get the filenames without needing to rewrite this notebook\n", + "\n", + "import os\n", + "input_file = os.environ['INPUT_FILE']\n", + "output_file = os.environ['OUTPUT_FILE']\n", + "\n", + "# For the case of a simulated dataset where we have the ground truth\n", + "try:\n", + " truth_file = os.environ['TRUTH_FILE']\n", + "except KeyError:\n", + " truth_file = None\n", + "\n", + "print(f'Input file: {input_file}')\n", + "print(f'Output file: {output_file}')\n", + "if truth_file is not None:\n", + " print(f'Simulated truth file: {truth_file}')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Report" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "generate_summary_plots(input_file=input_file, \n", + " output_file=output_file,\n", + " truth_file=truth_file)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/cellbender/remove_background/report.py b/cellbender/remove_background/report.py new file mode 100644 index 00000000..f1a34cb9 --- /dev/null +++ b/cellbender/remove_background/report.py @@ -0,0 +1,1888 @@ +"""Functions for creation of an HTML report that plots and explains output.""" + +from cellbender.remove_background.downstream import \ + load_anndata_from_input, \ + load_anndata_from_input_and_output, \ + _load_anndata_from_input_and_decontx +from cellbender.base_cli import get_version +from cellbender.remove_background import consts +import matplotlib.pyplot as plt +import numpy as np +import torch +import scipy.sparse as sp +import scipy.stats +from IPython.display import display, Markdown, HTML + +import subprocess +import datetime +import os +import logging +from typing import Dict, Optional + + +logger = logging.getLogger('cellbender') +warnings = [] +TIMEOUT = 1200 # twenty minutes should always be way more than enough + +# counteract an error when I run locally +# https://stackoverflow.com/questions/53014306/error-15-initializing-libiomp5-dylib-but-found-libiomp5-dylib-already-initial +os.environ['KMP_DUPLICATE_LIB_OK'] = 'True' + +run_notebook_str = lambda file: \ + f'jupyter nbconvert ' \ + f'--ExecutePreprocessor.timeout={TIMEOUT} ' \ + f'--to notebook ' \ + f'--allow-errors ' \ + f'--execute {file}' +to_html_str = lambda file, output: \ + f'jupyter nbconvert ' \ + f'--to html ' \ + f'--TemplateExporter.exclude_input=True ' \ + f'{file}' + + +def _run_notebook(file): + subprocess.run(f'cp {file} tmp.report.ipynb', shell=True) + subprocess.run(run_notebook_str(file='tmp.report.ipynb'), shell=True) + subprocess.run(f'rm tmp.report.ipynb', shell=True) + return 'tmp.report.nbconvert.ipynb' + + +def _to_html(file, output) -> str: + subprocess.run(to_html_str(file=file, output=output), shell=True) + subprocess.run(f'mv {file.replace(".ipynb", ".html")} {output}', shell=True) + subprocess.run(f'rm {file}', shell=True) + return output + + +def _postprocess_html(file: str, title: str): + with open(file, mode='r') as f: + html = f.read() + html = html.replace('<title>tmp.report.nbconvert</title>', + f'<title>{title}</title>') + with open(file, mode='w') as f: + f.write(html) + + +def run_notebook_make_html(file, output) -> str: + """Run Jupyter notebook to populate report and then convert to HTML. + + Args: + file: Notebook file + output: Output file. Should end in ".html" + + Returns: + output: Output file + + """ + assert output.endswith('.html'), 'Output HTML filename should end with .html' + html_file = _to_html(file=_run_notebook(file), output=output) + _postprocess_html( + file=html_file, + title=('CellBender: ' + os.path.basename(output).replace('_report.html', '')), + ) + return html_file + + +def generate_summary_plots(input_file: str, + output_file: str, + truth_file: Optional[Dict] = None, + dev_mode: bool = consts.EXTENDED_REPORT): + """Read in cellbender's output file and generate summary plots. + + Args: + input_file: Raw CellRanger + + """ + + global warnings + warnings = [] + + display(Markdown(f'### CellBender version {get_version()}')) + display(Markdown(str(datetime.datetime.now()).split('.')[0])) + display(Markdown(f'# {os.path.basename(output_file)}')) + + # load datasets, before and after CellBender + input_layer_key = 'raw' + if os.path.isdir(output_file): + adata = _load_anndata_from_input_and_decontx(input_file=input_file, + output_mtx_directory=output_file, + input_layer_key=input_layer_key, + truth_file=truth_file) + out_key = 'decontx' + else: + adata = load_anndata_from_input_and_output(input_file=input_file, + output_file=output_file, + analyzed_barcodes_only=True, + input_layer_key=input_layer_key, + truth_file=truth_file) + out_key = 'cellbender' + + # need to make any duplicate var indices unique (for pandas manipulations) + adata.var_names_make_unique() + + display(Markdown('## Loaded dataset')) + print(adata) + + # bit of pre-compute + cells = (adata.obs['cell_probability'] > consts.CELL_PROB_CUTOFF) + adata.var['n_removed'] = adata.var[f'n_{input_layer_key}'] - adata.var[f'n_{out_key}'] + adata.var['fraction_removed'] = adata.var['n_removed'] / (adata.var[f'n_{input_layer_key}'] + 1e-5) + adata.var['fraction_remaining'] = adata.var[f'n_{out_key}'] / (adata.var[f'n_{input_layer_key}'] + 1e-5) + adata.var[f'n_{input_layer_key}_cells'] = np.array(adata.layers[input_layer_key][cells].sum(axis=0)).squeeze() + adata.var[f'n_{out_key}_cells'] = np.array(adata.layers[out_key][cells].sum(axis=0)).squeeze() + adata.var['n_removed_cells'] = (adata.var[f'n_{input_layer_key}_cells'] + - adata.var[f'n_{out_key}_cells']) + adata.var['fraction_removed_cells'] = (adata.var['n_removed_cells'] + / (adata.var[f'n_{input_layer_key}_cells'] + 1e-5)) + adata.var['fraction_remaining_cells'] = (adata.var[f'n_{out_key}_cells'] + / (adata.var[f'n_{input_layer_key}_cells'] + 1e-5)) + + # this inline command is necessary after cellbender imports + plt.rcParams.update({'font.size': 12}) + + # input UMI curve + raw_full_adata = plot_input_umi_curve(input_file) + + # prove that remove-background is only subtracting counts, never adding + if out_key == 'cellbender': + assert (adata.layers[input_layer_key] < adata.layers[out_key]).sum() == 0, \ + "There is an entry in the output greater than the input" + else: + if (adata.layers[input_layer_key] < adata.layers[out_key]).sum() == 0: + display(Markdown('WARNING: There is an entry in the output greater than the input')) + + display(Markdown('## Examine how many counts were removed in total')) + try: + assess_overall_count_removal(adata, raw_full_adata=raw_full_adata, out_key=out_key) + except ValueError: + display(Markdown('Skipping assessment over overall count removal. Presumably ' + 'this is due to including the whole dataset in ' + '--total-droplets-included.')) + + # plot learning curve + if out_key == 'cellbender': + try: + assess_learning_curve(adata) + except Exception: + pass + else: + display(Markdown('Skipping learning curve assessment.')) + + # look at per-gene count removal + assess_count_removal_per_gene(adata, raw_full_adata=raw_full_adata, extended=dev_mode) + + if dev_mode: + display(Markdown('## Histograms of counts per cell for several genes')) + plot_gene_removal_histograms(adata, out_layer_key=out_key) + display(Markdown('Typically we see that some of the low-count cells have ' + 'their counts removed, since they were background noise.')) + + # plot UMI curve and cell probabilities + if out_key == 'cellbender': + display(Markdown('## Cell probabilities')) + display(Markdown('The inferred posterior probability ' + 'that each droplet is non-empty.')) + display(Markdown('*<span style="color:gray">We sometimes write "non-empty" ' + 'instead of "cell" because dead cells and other cellular ' + 'debris can still lead to a "non-empty" droplet, which will ' + 'have a high posterior cell probability. But these ' + 'kinds of low-quality droplets should be removed during ' + 'cell QC to retain only high-quality cells for downstream ' + 'analyses.</span>*')) + plot_counts_and_probs_per_cell(adata) + else: + display(Markdown('Skipping cell probability assessment.')) + + # concordance of data before and after + display(Markdown('## Concordance of data before and after `remove-background`')) + plot_validation_plots(adata, output_layer_key=out_key, extended=dev_mode) + + # PCA of gene expression + if out_key == 'cellbender': + display(Markdown('## PCA of encoded gene expression')) + plot_gene_expression_pca(adata, extended=dev_mode) + else: + display(Markdown('Skipping gene expression embedding assessment.')) + + # "mixed species" plots + mixed_species_plots(adata, input_layer_key=input_layer_key, output_layer_key=out_key) + + if dev_mode and (truth_file is not None): + + # accuracy plots ========================================== + + display(Markdown('# Comparison with truth data')) + + display(Markdown('## Removal per gene')) + + display(Markdown('Counts per gene are summed over cell-containing droplets')) + plt.figure(figsize=(10, 4)) + plt.subplot(1, 2, 1) + plt.plot(adata.var['n_truth'].values, adata.var[f'n_{out_key}_cells'].values, '.', color='k') + plt.plot([0, adata.var['n_truth'].max()], [0, adata.var['n_truth'].max()], + color='lightgray', alpha=0.5) + plt.xlabel('True counts per gene') + plt.ylabel(f'{out_key} counts per gene') + plt.subplot(1, 2, 2) + logic = (adata.var['n_truth'].values > 0) + plt.plot(adata.var['n_truth'].values[logic], + ((adata.var[f'n_{out_key}_cells'].values[logic] - adata.var['n_truth'].values[logic]) + / adata.var['n_truth'].values[logic]), + '.', color='k') + plt.plot([0, adata.var['n_truth'].max()], [0, 0], + color='lightgray', alpha=0.5) + plt.xlabel('True counts per gene') + plt.ylabel(f'{out_key}: residual count ratio per gene\n({out_key} - truth) / truth') + plt.tight_layout() + plt.show() + + adata.var['fraction_remaining_cells_truth'] = (adata.var[f'n_truth'] + / (adata.var[f'n_{input_layer_key}_cells'] + 1e-5)) + + plt.figure(figsize=(10, 4)) + plt.subplot(1, 2, 1) + plt.semilogx(adata.var[f'n_{input_layer_key}_cells'], + adata.var['fraction_remaining_cells'], 'k.', ms=1) + plt.ylim([-0.05, 1.05]) + plt.xlabel('Number of counts in raw data') + plt.ylabel('Fraction of counts remaining') + plt.title('Genes: removal of counts\nfrom (inferred) cell-containing droplets') + plt.subplot(1, 2, 2) + plt.semilogx(adata.var[f'n_{input_layer_key}_cells'], + adata.var['fraction_remaining_cells_truth'], 'k.', ms=1) + plt.ylim([-0.05, 1.05]) + plt.xlabel('Number of counts in raw data') + plt.ylabel('Truth: fraction of counts remaining') + plt.title('Genes: truth') + plt.tight_layout() + plt.show() + + plt.figure(figsize=(10, 4)) + plt.subplot(1, 2, 1) + plt.semilogx(adata.var[f'n_{input_layer_key}_cells'], + adata.var['fraction_remaining_cells'] - adata.var['fraction_remaining_cells_truth'], + 'k.', ms=1) + plt.ylim([-1.05, 1.05]) + plt.xlabel('Number of counts in raw data') + plt.ylabel('Residual fraction of counts remaining') + plt.title('Genes: residual') + plt.subplot(1, 2, 2) + plt.semilogx(adata.var[f'n_{input_layer_key}_cells'], + adata.var[f'n_{input_layer_key}_cells'] - adata.var['n_truth'], + 'k.', ms=1, label='raw') + plt.semilogx(adata.var[f'n_{input_layer_key}_cells'], + adata.var[f'n_{out_key}_cells'] - adata.var['n_truth'], + 'r.', ms=1, label=f'{out_key}') + plt.legend() + plt.xlabel('Number of counts in raw data') + plt.ylabel('Residual counts remaining') + plt.title('Genes: residual') + plt.tight_layout() + plt.show() + + display(Markdown('## Revisiting histograms of counts per cell')) + display(Markdown('Now showing the truth in addition to the `remove-background` ' + 'output.')) + plot_gene_removal_histograms(adata, plot_truth=True, out_layer_key=out_key) + + # plot z, and comparisons of learned to true gene expression + if out_key == 'cellbender': + cluster_and_compare_expression_to_truth(adata=adata) + else: + display(Markdown('Skipping gene expression embedding assessment.')) + + # gene expression as images: visualize changes + display(Markdown('## Visualization just for fun')) + display(Markdown('This is a strange but somewhat fun way to visualize what ' + 'is going on with the data for each cell. We look at one ' + 'cell at a time, and visualize gene expression as an ' + 'image, where pixels are ordered by their true expression ' + 'in the ambient RNA, where upper left is most expressed ' + 'in ambient. We plot the output gene expression in ' + 'blue/yellow, and then we look at three residuals (in red):' + '\n\n1. (raw - truth): what was supposed to be removed' + '\n2. (raw - posterior): what was actually removed' + '\n3. (truth - posterior): the residual, ' + 'where red means too little was removed and blue means too ' + 'much was removed.')) + try: + show_gene_expression_before_and_after(adata=adata, num=5) + except: + display(Markdown('WARNING: skipped showing gene expression as images, due to an error')) + + if dev_mode: + + # inference of latents + if out_key == 'cellbender': + compare_latents(adata) + else: + display(Markdown('Skipping gene expression embedding assessment.')) + + if truth_file is not None: + + # ROC curves + display(Markdown('## Quantification of performance')) + display(Markdown('Here we take a look at removal of noise counts from cell ' + 'containing droplets only.')) + true_fpr = cell_roc_count_roc( + output_csr=adata.layers[out_key], + input_csr=adata.layers[input_layer_key], + truth_csr=adata.layers['truth'], + cell_calls=(adata.obs['cell_probability'] > 0.5), + truth_cell_labels=adata.obs['truth_cell_label'], + ) + if type(adata.uns['target_false_positive_rate'][0]) == np.float64: + if true_fpr > adata.uns['target_false_positive_rate'][0]: + warnings.append('FPR exceeds target FPR.') + display(Markdown(f'WARNING: FPR of {true_fpr:.4f} exceeds target FPR of ' + f'{adata.uns["target_false_positive_rate"]}. Keep ' + f'in mind however that the target FPR is meant to ' + f'target false positives over and above some ' + f'basal level (dataset dependent), so the ' + f'measured FPR should exceed the target by some ' + f'amount.')) + + display(Markdown('# Summary of warnings:')) + if len(warnings) == 0: + display(Markdown('None.')) + else: + for warning in warnings: + display(Markdown(warning)) + + +def plot_input_umi_curve(inputfile): + adata = load_anndata_from_input(inputfile) + plt.loglog(sorted(np.array(adata.X.sum(axis=1)).squeeze(), reverse=True)) + plt.xlabel('Ranked Barcode ID') + plt.ylabel('UMI counts') + plt.title(f'UMI curve\nRaw input data: {os.path.basename(inputfile)}') + plt.show() + return adata + + +def assess_overall_count_removal(adata, raw_full_adata, input_layer_key='raw', out_key='cellbender'): + global warnings + cells = (adata.obs['cell_probability'] > 0.5) + initial_counts = adata.layers[input_layer_key][cells].sum() + removed_counts = initial_counts - adata.layers[out_key][cells].sum() + removed_percentage = removed_counts / initial_counts * 100 + print(f'removed {removed_counts:.0f} counts from non-empty droplets') + print(f'removed {removed_percentage:.2f}% of the counts in non-empty droplets') + + from scipy.stats import norm + + log_counts = np.log10(np.array(adata.layers[input_layer_key].sum(axis=1)).squeeze()) + empty_log_counts = np.array(raw_full_adata.X[ + [bc not in adata.obs_names + for bc in raw_full_adata.obs_names] + ].sum(axis=1)).squeeze() + empty_log_counts = np.log10(empty_log_counts[empty_log_counts > consts.LOW_UMI_CUTOFF]) + bins = np.linspace(empty_log_counts.min(), log_counts.max(), 100) + # binwidth = bins[1] - bins[0] + + # def plot_normal_fit(x, loc, scale, n, label): + # plt.plot(x, n * binwidth * norm.pdf(x=x, loc=loc, scale=scale), label=label) + + plt.hist(empty_log_counts.tolist() + log_counts[~cells].tolist(), + histtype='step', label='empty droplets', bins=bins) + plt.hist(log_counts[cells], histtype='step', label='non-empty droplets', bins=bins) + xx = np.linspace(plt.gca().get_xlim()[0], plt.gca().get_xlim()[-1], 100) + # if 'cell_size' in adata.obs.keys(): + # plt.hist(np.log10(adata.obs['cell_size'][cells]), + # histtype='step', label='inferred cell sizes', bins=bins) + # plot_normal_fit(x=xx, + # loc=np.log10(adata.obs['cell_size'][cells]).mean(), + # scale=np.log10(adata.obs['cell_size'][cells]).std(), + # n=cells.sum(), + # label='inferred cell sizes') + # if (('empty_droplet_size_lognormal_loc' in adata.uns.keys()) + # and ('empty_droplet_size_lognormal_scale' in adata.uns.keys())): + # plot_normal_fit(x=xx, + # loc=np.log10(np.exp(adata.uns['empty_droplet_size_lognormal_loc'])), + # scale=np.log10(np.exp(adata.uns['empty_droplet_size_lognormal_scale'])), + # n=(~cells).sum() + len(empty_log_counts), + # label='inferred empty sizes') + plt.ylabel('Number of droplets') + plt.legend(loc='center left', bbox_to_anchor=(1, 0.5)) + plt.ylim(bottom=1) + plt.yscale('log') + # x-axis log10 to regular number + plt.xticks(plt.gca().get_xticks(), + [f'{n:.0f}' for n in np.power(10, plt.gca().get_xticks())], rotation=90) + plt.xlim(left=empty_log_counts.min()) + plt.xlabel('UMI counts per droplet') + plt.show() + + estimated_ambient_per_droplet = np.exp(adata.uns['empty_droplet_size_lognormal_loc']).item() + expected_fraction_removed_from_cells = estimated_ambient_per_droplet * cells.sum() / initial_counts + + fpr = adata.uns['target_false_positive_rate'].item() # this is an np.ndarray with one element + cohort_mode = False + if type(fpr) != float: + cohort_mode = True + + print('Rough estimate of expectations based on nothing but the plot above:') + print(f'roughly {estimated_ambient_per_droplet * cells.sum():.0f} noise counts ' + f'should be in non-empty droplets') + print(f'that is approximately {expected_fraction_removed_from_cells * 100:.2f}% of ' + f'the counts in non-empty droplets') + + if not cohort_mode: + expected_percentage = (expected_fraction_removed_from_cells + fpr) * 100 + print(f'with a false positive rate [FPR] of {fpr * 100}%, we would expect to remove about ' + f'{expected_percentage:.2f}% of the counts in non-empty droplets') + else: + expected_percentage = expected_fraction_removed_from_cells * 100 + print(f'ran in cohort mode, so no false positive rate [FPR] target was set, ' + f'but we would still expect to remove about ' + f'{expected_percentage:.2f}% of the counts in non-empty droplets') + + display(Markdown('\n')) + + if np.abs(expected_percentage - removed_percentage) <= 0.5: + display(Markdown('It looks like the algorithm did a great job meeting that expectation.')) + elif np.abs(expected_percentage - removed_percentage) <= 1: + display(Markdown('It looks like the algorithm did a decent job meeting that expectation.')) + elif np.abs(expected_percentage - removed_percentage) <= 5: + if removed_percentage < expected_percentage: + display(Markdown('The algorithm removed a bit less than naive expectations ' + 'would indicate, but this is likely okay. If removal ' + 'seems insufficient, the FPR can be increased.')) + else: + display(Markdown('The algorithm removed a bit more than naive expectations ' + 'would indicate, but this is likely okay. Spot-check ' + 'removal of a few top-removed genes as a QC measure. ' + 'If less removal is desired, decrease the FPR.')) + elif removed_percentage - expected_percentage > 5: + display(Markdown('The algorithm seems to have removed more overall counts ' + 'than would be naively expected.')) + warnings.append('Algorithm removed more counts overall than naive expectations.', ) + elif expected_percentage - removed_percentage > 5: + display(Markdown('The algorithm seems to have removed fewer overall counts ' + 'than would be naively expected.')) + warnings.append('Algorithm removed fewer counts overall than naive expectations.', ) + + +def assess_learning_curve(adata, + spike_size: float = 0.5, + deviation_size: float = 0.25, + monotonicity_cutoff: float = 0.1): + global warnings + display(Markdown('## Assessing convergence of the algorithm')) + plot_learning_curve(adata) + if 'learning_curve_train_elbo' not in adata.uns.keys(): + return + display(Markdown( + '*<span style="color:gray">The learning curve tells us about the progress of the algorithm in ' + 'inferring all the latent variables in our model. We want to see ' + 'the ELBO increasing as training epochs increase. Generally it is ' + 'desirable for the ELBO to converge at some high plateau, and be fairly ' + 'stable.</span>*')) + display(Markdown( + '*<span style="color:gray">What to watch out for:</span>*' + )) + display(Markdown( + '*<span style="color:gray">1. large downward spikes in the ELBO (of value more than a few hundred)</span>*\n' + '*<span style="color:gray">2. the test ELBO can be smaller than the train ELBO, but generally we ' + 'want to see both curves increasing and reaching a stable plateau. We ' + 'do not want the test ELBO to dip way back down at the end.</span>*\n' + '*<span style="color:gray">3. lack of convergence, where it looks like the ELBO would change ' + 'quite a bit if training went on for more epochs.</span>*' + )) + + if adata.uns['learning_curve_train_epoch'][-1] < 50: + display(Markdown('Short run. Will not analyze the learning curve.')) + warnings.append(f'Short run of only {adata.uns["learning_curve_train_epoch"][-1]} epochs') + return + + train_elbo_min_max = np.percentile(adata.uns['learning_curve_train_elbo'], q=[5, 95]) + train_elbo_range = train_elbo_min_max.max() - train_elbo_min_max.min() + + # look only from epoch 45 onward for spikes in train ELBO + large_spikes_in_train = np.any((adata.uns['learning_curve_train_elbo'][46:] + - adata.uns['learning_curve_train_elbo'][45:-1]) + < -train_elbo_range * spike_size) + + second_half_train_elbo = (adata.uns['learning_curve_train_elbo'] + [(len(adata.uns['learning_curve_train_elbo']) // 2):]) + large_deviation_in_train = np.any(second_half_train_elbo + < np.median(second_half_train_elbo) + - train_elbo_range * deviation_size) + + half = len(adata.uns['learning_curve_train_elbo']) // 2 + threequarter = len(adata.uns['learning_curve_train_elbo']) * 3 // 4 + typical_end_variation = np.std(adata.uns['learning_curve_train_elbo'][half:threequarter]) + low_end_in_train = (adata.uns['learning_curve_train_elbo'][-1] + < adata.uns['learning_curve_train_elbo'].max() - 5 * typical_end_variation) + + # look only from epoch 45 onward for spikes in train ELBO + non_monotonicity = ((adata.uns['learning_curve_train_elbo'][46:] + - adata.uns['learning_curve_train_elbo'][45:-1]) + < -3 * typical_end_variation).sum() / len(adata.uns['learning_curve_train_elbo']) + non_monotonic = (non_monotonicity > monotonicity_cutoff) + + def windowed_cumsum(x, n=20): + return np.array([np.cumsum(x[i:(i + n)])[-1] for i in range(len(x) - n)]) + + windowsize = 20 + tracking_trace = windowed_cumsum(adata.uns['learning_curve_train_elbo'][1:] + - adata.uns['learning_curve_train_elbo'][:-1], + n=windowsize) + big_dip = -1 * (adata.uns['learning_curve_train_elbo'][-1] + - adata.uns['learning_curve_train_elbo'][5]) / 10 + backtracking = (tracking_trace.min() < big_dip) + backtracking_ind = np.argmin(tracking_trace) + windowsize + + halftest = len(adata.uns['learning_curve_test_elbo']) // 2 + threequartertest = len(adata.uns['learning_curve_test_elbo']) * 3 // 4 + typical_end_variation_test = np.std(adata.uns['learning_curve_test_elbo'][halftest:threequartertest]) + runaway_test = (adata.uns['learning_curve_test_elbo'][-1] + < adata.uns['learning_curve_test_elbo'].max() - 4 * typical_end_variation_test) + + non_convergence = (np.mean([adata.uns['learning_curve_train_elbo'][-1] + - adata.uns['learning_curve_train_elbo'][-2], + adata.uns['learning_curve_train_elbo'][-2] + - adata.uns['learning_curve_train_elbo'][-3]]) + > 2 * typical_end_variation) + + display(Markdown('**Automated assessment** --------')) + if large_spikes_in_train: + warnings.append('Large spikes in training ELBO.') + display(Markdown('- *WARNING*: Large spikes detected in the training ELBO.')) + if large_deviation_in_train: + warnings.append('Large deviation in training ELBO from max value late in learning.') + display(Markdown('- *WARNING*: The training ELBO deviates quite a bit from ' + 'the max value during the second half of training.')) + if low_end_in_train: + warnings.append('Large deviation in training ELBO from max value at end.') + display(Markdown('- The training ELBO deviates quite a bit from ' + 'the max value at the last epoch.')) + if non_monotonic: + warnings.append('Non-monotonic training ELBO.') + display(Markdown('- We typically expect to see the training ELBO increase almost ' + 'monotonically. This curve seems to have a lot more downward ' + 'motion than we like to see.')) + if backtracking: + warnings.append('Back-tracking in training ELBO.') + display(Markdown('- We typically expect to see the training ELBO increase almost ' + 'monotonically. This curve seems to have a concerted ' + f'period of motion in the wrong direction near epoch {backtracking_ind}. ' + f'If this is early in training, this is probably okay.')) + if runaway_test: + warnings.append('Final test ELBO is much lower than the max test ELBO.') + display(Markdown('- We hope to see the test ELBO follow the training ELBO, ' + 'increasing almost monotonically (though there will be ' + 'deviations, and that is expected). There may be a large ' + 'gap, and that is okay. However, this curve ' + 'ends with a low test ELBO compared to the max test ELBO ' + 'value during training. The output could be suboptimal.')) + if non_convergence: + warnings.append('Non-convergence of training ELBO.') + display(Markdown('- We typically expect to see the training ELBO come to a ' + 'stable plateau value near the end of training. Here ' + 'the training ELBO is still moving quite a bit.')) + + display(Markdown('**Summary**:')) + if large_spikes_in_train or large_deviation_in_train: + display(Markdown('This is unusual behavior, and a reduced --learning-rate ' + 'is indicated. Re-run with half the current learning ' + 'rate and compare the results.')) + elif low_end_in_train or non_monotonic or runaway_test: + display(Markdown('This is slightly unusual behavior, and a reduced ' + '--learning-rate might be indicated. Consider re-running ' + 'with half the current learning rate to compare the results.')) + elif non_convergence: + display(Markdown('This is slightly unusual behavior, and more training ' + '--epochs might be indicated. Consider re-running ' + 'for more epochs to compare the results.')) + else: + display(Markdown('This learning curve looks normal.')) + + +def plot_learning_curve(adata): + + if 'learning_curve_train_elbo' not in adata.uns.keys(): + print('No learning curve recorded!') + return + + def _mkplot(): + plt.plot(adata.uns['learning_curve_train_epoch'], + adata.uns['learning_curve_train_elbo'], label='train') + try: + plt.plot(adata.uns['learning_curve_test_epoch'], + adata.uns['learning_curve_test_elbo'], '.:', label='test') + plt.legend() + except Exception: + pass + plt.title('Learning curve') + plt.ylabel('ELBO') + plt.xlabel('Epoch') + + if len(adata.uns['learning_curve_train_elbo']) > 20: + + # two panels: zoom on the right-hand side + plt.figure(figsize=(10, 4)) + plt.subplot(1, 2, 1) + _mkplot() + plt.subplot(1, 2, 2) + _mkplot() + plt.title('Learning curve (zoomed in)') + low = np.percentile(adata.uns['learning_curve_train_elbo'], q=10) + if (len(adata.uns['learning_curve_train_elbo']) > 0) \ + and (len(adata.uns['learning_curve_test_elbo']) > 0): + high = max(adata.uns['learning_curve_train_elbo'].max(), + adata.uns['learning_curve_test_elbo'].max()) + else: + high = adata.uns['learning_curve_train_elbo'].max() + plt.ylim([low, high + (high - low) / 10]) + plt.tight_layout() + plt.show() + + else: + _mkplot() + plt.show() + + +def assess_count_removal_per_gene(adata, + raw_full_adata, + input_layer_key='raw', + r_squared_cutoff=0.5, + extended=True): + + global warnings + display(Markdown('## Examine count removal per gene')) + + # how well does it correlate with our expectation about the ambient RNA profile? + cells = (adata.obs['cell_probability'] > 0.5) + counts = np.array(raw_full_adata.X.sum(axis=1)).squeeze() + clims = [adata.obs[f'n_{input_layer_key}'][~cells].mean() / 2, + np.percentile(adata.obs[f'n_{input_layer_key}'][cells].values, q=2)] + # if all are called "cells" then clims[0] will be a nan + if np.isnan(clims[0]): + clims[0] = counts.min() + if 'approximate_ambient_profile' in adata.uns.keys(): + approximate_ambient_profile = adata.uns['approximate_ambient_profile'] + else: + empty_count_matrix = raw_full_adata[(counts > clims[0]) & (counts < clims[1])].X + if empty_count_matrix.shape[0] > 100: + approximate_ambient_profile = np.array(raw_full_adata[(counts > clims[0]) + & (counts < clims[1])].X.mean(axis=0)).squeeze() + else: + # a very rare edge case I've seen once + display(Markdown('Having some trouble finding the empty droplets via heuristics. ' + 'The "approximate background estimated from empty droplets" may be inaccurate.')) + approximate_ambient_profile = np.array(raw_full_adata[counts < clims[1]].X.mean(axis=0)).squeeze() + approximate_ambient_profile = approximate_ambient_profile / approximate_ambient_profile.sum() + y = adata.var['n_removed'] / adata.var['n_removed'].sum() + maxval = (approximate_ambient_profile / approximate_ambient_profile.sum()).max() + + def _plot_identity(maxval): + plt.plot([0, maxval], [0, maxval], 'lightgray') + + if extended: + + plt.figure(figsize=(12, 4)) + plt.subplot(1, 2, 1) + plt.plot(approximate_ambient_profile, adata.var['ambient_expression'], '.', ms=2) + _plot_identity(maxval) + plt.xlabel('Approximate background per gene\nestimated from empty droplets') + plt.ylabel('Inferred ambient profile') + plt.title('Genes: inferred ambient') + + plt.subplot(1, 2, 2) + plt.plot(approximate_ambient_profile, y, '.', ms=2) + _plot_identity(maxval) + plt.xlabel('Approximate background per gene\nestimated from empty droplets') + plt.ylabel('Removal per gene') + plt.title('Genes: removal') + plt.tight_layout() + plt.show() + + else: + + plt.plot(approximate_ambient_profile, y, '.', ms=2) + _plot_identity(maxval) + plt.xlabel('Approximate background per gene\nestimated from empty droplets') + plt.ylabel('Removal per gene') + plt.title('Genes: removal') + plt.tight_layout() + plt.show() + + cutoff = 1e-6 + logic = np.logical_not((approximate_ambient_profile < cutoff) | (y < cutoff)) + r_squared_result = scipy.stats.pearsonr(np.log(approximate_ambient_profile[logic]), + np.log(y[logic])) + if hasattr(r_squared_result, 'statistic'): + # scipy version 1.9.0+ + r_squared = r_squared_result.statistic + else: + r_squared = r_squared_result[0] + display(Markdown(f'Pearson correlation coefficient for the above is {r_squared:.4f}')) + if r_squared > r_squared_cutoff: + display(Markdown('This meets expectations.')) + else: + warnings.append('Per-gene removal does not closely match a naive estimate ' + 'of ambient RNA from empty droplets. Does it look like ' + 'CellBender correctly identified the empty droplets?') + display(Markdown('WARNING: This deviates from expectations, and may ' + 'indicate that the run did not go well')) + + percentile = 90 + genecount_lowlim = int(np.percentile(adata.var[f'n_{input_layer_key}'], q=percentile)) + display(Markdown('### Table of top genes removed\n\nRanked by fraction removed, ' + f'and excluding genes with fewer than {genecount_lowlim} ' + f'total raw counts ({percentile}th percentile)')) + df = adata.var[adata.var['cellbender_analyzed']] # exclude omitted features + df = df[[c for c in df.columns if (c != 'features_analyzed_inds')]] + display(HTML(df[df[f'n_{input_layer_key}'] > genecount_lowlim] + .sort_values(by='fraction_removed', ascending=False).head(10).to_html())) + + for g in adata.var[(adata.var[f'n_{input_layer_key}_cells'] > genecount_lowlim) + & (adata.var['fraction_removed'] > 0.8)].index: + warnings.append(f'Expression of gene {g} decreases quite a bit') + display(Markdown(f'**WARNING**: The expression of the highly-expressed ' + f'gene {g} decreases quite markedly after CellBender. ' + f'Check to ensure this makes sense!')) + + if extended: + + plt.figure(figsize=(12, 4)) + plt.subplot(1, 2, 1) + plt.semilogx(adata.var[f'n_{input_layer_key}'], + adata.var['fraction_remaining'], 'k.', ms=1) + plt.ylim([-0.05, 1.05]) + plt.xlabel('Number of counts in raw data') + plt.ylabel('Fraction of counts remaining') + plt.title('Genes: removal of counts\nfrom the entire dataset') + plt.subplot(1, 2, 2) + plt.semilogx(adata.var[f'n_{input_layer_key}_cells'], + adata.var['fraction_remaining_cells'], 'k.', ms=1) + plt.ylim([-0.05, 1.05]) + plt.xlabel('Number of counts in raw data') + plt.ylabel('Fraction of counts remaining') + plt.title('Genes: removal of counts\nfrom (inferred) cell-containing droplets') + plt.show() + + +def plot_counts_and_probs_per_cell(adata, input_layer_key='raw'): + + limit_to_features_analyzed = True + + if limit_to_features_analyzed: + var_logic = adata.var['cellbender_analyzed'] + else: + var_logic = ... + + in_counts = np.array(adata.layers[input_layer_key][:, var_logic].sum(axis=1)).squeeze() + # cellbender_counts = np.array(adata.layers['cellbender'][:, var_logic].sum(axis=1)).squeeze() + order = np.argsort(in_counts)[::-1] + # plt.semilogy(cellbender_counts[order], '.:', ms=3, color='lightgray', alpha=0.5, label='cellbender') + plt.semilogy(in_counts[order], 'k-', lw=1, label=input_layer_key) + plt.xlabel('Sorted barcode ID') + plt.ylabel('Unique UMI counts' + ('\n(for features analyzed by CellBender)' + if limit_to_features_analyzed else '')) + plt.legend(loc='lower left', title='UMI counts') + plt.gca().twinx() + plt.plot(adata.obs['cell_probability'][order].values, '.', ms=2, alpha=0.2, color='red') + plt.ylabel('Inferred cell probability', color='red') + plt.yticks([0, 0.25, 0.5, 0.75, 1.0], color='red') + plt.ylim([-0.05, 1.05]) + plt.show() + + +def plot_validation_plots(adata, input_layer_key='raw', + output_layer_key='cellbender', + extended=True): + + display(Markdown('*<span style="color:gray">The intent is to change the input ' + 'data as little as possible while achieving noise removal. ' + 'These plots show general summary statistics about similarity ' + 'of the input and output data. We expect to see the data ' + 'lying close to a straight line (gray). There may be ' + 'outlier genes/features, which are often those highest-' + 'expressed in the ambient RNA.</span>*')) + display(Markdown('The plots here show data ' + 'for inferred cell-containing droplets, and exclude the ' + 'empty droplets.')) + + cells = (adata.obs['cell_probability'] > 0.5) + + # counts per barcode + plt.figure(figsize=(9, 4)) + plt.subplot(1, 2, 1) + plt.loglog(adata.obs[f'n_{input_layer_key}'][cells].values, + adata.obs[f'n_{output_layer_key}'][cells].values, + '.', ms=3, alpha=0.8, rasterized=True) + minmax = [adata.obs[f'n_{input_layer_key}'][cells].min() / 10, + adata.obs[f'n_{input_layer_key}'][cells].max() * 10] + plt.loglog(minmax, minmax, lw=1, color='gray', alpha=0.5) + plt.xlabel('Input counts per barcode') + plt.ylabel(f'{output_layer_key} counts per barcode') + plt.title('Droplet count concordance\nin inferred cell-containing droplets') + plt.axis('equal') + + # counts per gene + plt.subplot(1, 2, 2) + plt.loglog(adata.var[f'n_{input_layer_key}_cells'], + adata.var[f'n_{output_layer_key}_cells'], + '.', ms=3, alpha=0.8, rasterized=True) + minmax = [adata.var[f'n_{input_layer_key}_cells'].min() / 10, + adata.var[f'n_{input_layer_key}_cells'].max() * 10] + plt.loglog(minmax, minmax, lw=1, color='gray', alpha=0.5) + plt.xlabel('Input counts per gene') + plt.ylabel(f'{output_layer_key} counts per gene') + plt.title('Gene count concordance\nin inferred cell-containing droplets') + plt.axis('equal') + plt.tight_layout() + plt.show() + + cells = (adata.obs['cell_probability'] >= 0.5) + + if extended: + + # Fano factor per barcode + plt.figure(figsize=(9, 4)) + plt.subplot(1, 2, 1) + plt.loglog(fano(adata.layers[input_layer_key][cells], axis=1), + fano(adata.layers[output_layer_key][cells], axis=1), '.', ms=1) + plt.loglog([1e0, 1e3], [1e0, 1e3], lw=1, color='gray', alpha=0.5) + plt.xlabel('Input Fano factor per droplet') + plt.ylabel(f'{output_layer_key} Fano factor per droplet') + plt.title('Droplet count variance\nin inferred cell-containing droplets') + plt.axis('equal') + + # Fano factor per gene + plt.subplot(1, 2, 2) + plt.loglog(fano(adata.layers[input_layer_key][cells], axis=0), + fano(adata.layers[output_layer_key][cells], axis=0), '.', ms=1) + plt.loglog([1e0, 1e3], [1e0, 1e3], lw=1, color='gray', alpha=0.5) + plt.xlabel('Input Fano factor per gene') + plt.ylabel(f'{output_layer_key} Fano factor per gene') + plt.title('Gene count variance\nin inferred cell-containing droplets') + plt.axis('equal') + plt.tight_layout() + plt.show() + + # histogram of per-cell cosine distances + # cells_in_data = latents['barcodes_analyzed_inds'][latents['cell_probability'] >= 0.5] + cosine_dist = [] + for bc in np.random.permutation(np.where(cells)[0])[:300]: + cosine_dist.append(cosine(np.array(adata.layers[input_layer_key][bc, :].todense()).squeeze(), + np.array(adata.layers[output_layer_key][bc, :].todense()).squeeze())) + cosine_dist = np.array(cosine_dist) + plt.hist(cosine_dist, bins=100) + plt.xlabel('Cosine distance between cell before and after') + plt.ylabel('Number of cells') + plt.title('Per-cell expression changes') + plt.show() + + print(f'cosine_dist.mean = {cosine_dist.mean():.4f}') + + display(Markdown('We want this cosine distance to be as small as it can be ' + '(though it cannot be zero, since we are removing counts). ' + 'There is no specific threshold value above which we are ' + 'concerned, but typically we see values below 0.05.')) + + +def plot_gene_removal_histograms(adata, input_layer_key='raw', plot_truth=False, out_layer_key='cellbender'): + order_gene = np.argsort(np.array(adata.var[f'n_{input_layer_key}']))[::-1] + bins = np.arange(50) - 0.5 + + plt.figure(figsize=(14, 6)) + for i, g_ind in enumerate([0, 5, 10, 20, 100, 1000]): + if g_ind >= len(order_gene): + break + plt.subplot(2, 3, i + 1) + plt.hist(np.array(adata.layers[input_layer_key][:, order_gene[g_ind]].todense()).squeeze(), + bins=bins, log=True, label=input_layer_key, histtype='step') + plt.hist(np.array(adata.layers[out_layer_key][:, order_gene[g_ind]].todense()).squeeze(), + bins=bins, log=True, label=out_layer_key, alpha=0.75, histtype='step') + if plot_truth: + plt.hist(np.array(adata.layers['truth'][:, order_gene[g_ind]].todense()).squeeze(), + bins=bins, log=True, label='truth', alpha=0.5, histtype='step') + plt.xlabel('counts per cell', fontsize=12) + plt.title(f'{adata.var_names[order_gene[g_ind]]}: rank {g_ind} in ambient', fontsize=12) + plt.ylabel('number of cells', fontsize=12) + plt.legend() + plt.tight_layout() + plt.show() + + +def show_gene_expression_before_and_after(adata, + input_layer_key: str = 'raw', + num: int = 10): + """Display gene expression as an image. + Show what was removed. + Show what should have been removed. + Show residual. + """ + + inds = np.where(adata.obs['cell_probability'] > 0.5)[0][:num] + + # ambient sort order + order = np.argsort(adata.var['truth_ambient_expression'])[::-1] + + for i in inds: + + raw = np.array(adata.layers[input_layer_key][i, :].todense(), dtype=float).squeeze() + + # size of images + nz_inds = np.where(raw[order] > 0)[0] + nrows = int(np.floor(np.sqrt(nz_inds.size)).item()) + imsize = (nrows, int(np.ceil(nz_inds.size / max(1, nrows)).item())) + + raw = np.resize(raw[order][nz_inds], imsize[0] * imsize[1]).reshape(imsize) + overflow = (imsize[0] * imsize[1]) - nz_inds.size + 1 + raw[-1, -overflow:] = 0. + post = np.array(adata.layers['cellbender'][i, :].todense(), dtype=float).squeeze() + post = np.resize(post[order][nz_inds], imsize[0] * imsize[1]).reshape(imsize) + post[-1, -overflow:] = 0. + + true_ambient = np.resize(adata.var['truth_ambient_expression'][order][nz_inds], + imsize[0] * imsize[1]).reshape(imsize) + true_ambient[-1, -overflow:] = 0. + + true = np.array(adata.layers['truth'][i, :].todense(), dtype=float).squeeze() + true = np.resize(true[order][nz_inds], imsize[0] * imsize[1]).reshape(imsize) + true[-1, -overflow:] = 0. + lim = max(np.log1p(post).max(), np.log1p(true).max(), np.log1p(raw).max()) + + plt.figure(figsize=(14, 3)) + + # plt.subplot(1, 4, 1) + # plt.imshow(np.log1p(raw), vmin=1, vmax=lim) + # plt.title(f'log raw [{np.expm1(lim):.1f}]') + # plt.xticks([]) + # plt.yticks([]) + + plt.subplot(1, 4, 1) + plt.imshow(np.log1p(post), vmin=1, vmax=lim) + plt.title(f'log posterior [{np.expm1(lim):.1f}]') + plt.xticks([]) + plt.yticks([]) + + plt.subplot(1, 4, 2) + dat = (raw - true) + minmax = max(-1 * dat.min(), dat.max()) + plt.imshow(dat, cmap='seismic', vmin=-1 * minmax, vmax=minmax) + plt.title(f'raw - truth [{minmax:.1f}]') + plt.xticks([]) + plt.yticks([]) + + plt.subplot(1, 4, 3) + dat = (raw - post) + # minmax = max(-1*dat.min(), dat.max()) + cmap = plt.get_cmap('seismic', 2 * minmax + 1) + plt.imshow(dat, cmap=cmap, vmin=-1 * minmax, vmax=minmax) + plt.title(f'raw - posterior [{minmax}]') + plt.xticks([]) + plt.yticks([]) + + plt.subplot(1, 4, 4) + dat = (true - post) + thisminmax = max(-1 * dat.min(), dat.max()) + minmax = max(thisminmax, minmax) + plt.imshow(-dat, cmap='seismic', vmin=-1 * minmax, vmax=minmax) + if minmax == dat.max(): + plt.title(f'truth - posterior [- {minmax:.1f}]') + else: + plt.title(f'truth - posterior [{minmax:.1f}]') + plt.xticks([]) + plt.yticks([]) + + plt.show() + + ambient_counts = raw - true + removed_counts = raw - post + removed_ambient = np.sum(np.minimum(removed_counts[ambient_counts > 0], ambient_counts[ambient_counts > 0])) + + print(f'Fraction of ambient counts removed: {removed_ambient / np.sum(ambient_counts):.2f}') + print(f'Ambient counts removed: {int(removed_ambient)}') + print(f'Remaining ambient counts: {- int(np.sum(dat[dat < 0]))}') + print(f'Erroneously subtracted real counts: {int(np.sum(dat[dat > 0]))}') + + +def plot_gene_expression_pca(adata, key='cellbender_embedding', + input_layer_key='raw', extended=True): + + cells = (adata.obs['cell_probability'] > 0.5) + adata.obsm['X_pca'] = pca_2d(adata.obsm[key]).detach().numpy() + + # plot z PCA colored by latent size + sizeorder = np.argsort(adata.obs['cell_size'][cells]) + s = plt.scatter(x=adata.obsm['X_pca'][:, 0][cells][sizeorder], + y=adata.obsm['X_pca'][:, 1][cells][sizeorder], + c=np.log10(adata.obs['cell_size'][cells][sizeorder]), + s=2, + cmap='brg', + alpha=0.5) + plt.title('Gene expression embedding\ncolored by log10 inferred cell size $d_n$') + plt.xlabel('PCA 0') + plt.ylabel('PCA 1') + plt.xticks([]) + plt.yticks([]) + plt.gcf().colorbar(s, pad=0.1, label='log10 cell size') + plt.show() + + display(Markdown('*<span style="color:gray">We are not looking for anything ' + 'specific in the PCA plot ' + 'of the gene expression embedding, but often we see clusters ' + 'that correspond to different cell types. If you see only ' + 'a single large blob, then the dataset might contain only ' + 'one cell type, or perhaps there are few counts per ' + 'droplet.</span>*')) + + if extended: + + # plot z PCA colored by a few features + def _pca_color(g: int, layer): + outcounts = np.array(adata.layers['cellbender'][:, adata.var_names == g].todense()).squeeze() + rawcounts = np.array(adata.layers[input_layer_key][:, adata.var_names == g].todense()).squeeze() + # cmax = 2 * (rawcounts - outcounts)[rawcounts > 0].mean() + cmax = np.percentile(rawcounts[rawcounts > 0], q=80) + if layer == 'cellbender': + counts = outcounts + else: + counts = rawcounts + order = np.argsort(counts[cells]) + + s = plt.scatter(x=adata.obsm['X_pca'][:, 0][cells][order], + y=adata.obsm['X_pca'][:, 1][cells][order], + c=counts[cells][order], + s=10, + vmin=0, + vmax=cmax, # min(20, max(1, cmax)), + cmap='Oranges', + alpha=0.25) + plt.title(f'{g}: {layer}') + plt.xlabel('PCA 0') + plt.ylabel('PCA 1') + plt.gcf().colorbar(s, pad=0.05, label='Counts (truncated)') + + percentile = 90 + genecount_lowlim = int(np.percentile(adata.var[f'n_{input_layer_key}'], q=percentile)) + if 'feature_type' in adata.var.keys(): + feature_logic = (adata.var['feature_type'] == 'Gene Expression') + else: + feature_logic = True + features = (adata.var[feature_logic + & (adata.var['n_cellbender'] > genecount_lowlim)] + .sort_values(by='fraction_removed', ascending=False) + .groupby('genome') + .head(2) + .index + .values + .tolist()) + if 'feature_type' in adata.var.keys(): + if (adata.var['feature_type'] != 'Gene Expression').sum() > 0: + features.extend(adata.var[(adata.var['feature_type'] != 'Gene Expression') + & (adata.var['n_cellbender'] > genecount_lowlim)] + .sort_values(by='fraction_removed', ascending=False) + .groupby('feature_type') + .head(2) + .index + .values + .tolist()) + + display(Markdown('### Visualization of a few features')) + display(Markdown('Focusing on a few top features which were removed the most.')) + + for g in features: + plt.figure(figsize=(11, 4)) + plt.subplot(1, 2, 1) + _pca_color(g, layer=input_layer_key) + plt.subplot(1, 2, 2) + _pca_color(g, layer='cellbender') + plt.tight_layout() + plt.show() + + display(Markdown('*<span style="color:gray">We typically see selective ' + 'removal of some genes from ' + 'particular cell types. The genes above have been picked ' + 'randomly based on fraction_removed, and so might not be ' + 'the best genes for visualization. These sorts of plots ' + 'can be an interesting way to visualize what ' + '`remove-background` does.</span>*')) + + +def cluster_cells(adata, embedding_key='cellbender_embedding', n=2): + """Run PCA (if not done) and use spectral clustering to label cells. + Returns: + cluster: np.ndarray of cluster labels as ints + """ + from sklearn.cluster import SpectralClustering + + cells = (adata.obs['cell_probability'] > 0.5) + + if 'X_pca' not in adata.obsm.keys(): + from sklearn.decomposition import PCA + z = adata.obsm[embedding_key] + adata.obsm['X_pca'] = PCA(n_components=20).fit_transform(z) + + if 'truth_cell_probability' in adata.obs.keys(): + # if truth exists, use it + n_cell_labels = np.array([k.startswith('truth_gene_expression_cell_label_') + for k in adata.var.keys()]).sum() + else: + n_cell_labels = n + spec = (SpectralClustering(n_clusters=n_cell_labels, random_state=0) + .fit_predict(adata.obsm[embedding_key][cells, :])) + cluster = np.zeros(adata.shape[0]) + cluster[cells] = spec + 1 # offset by 1 so that empty is 0 + return cluster.astype(int) + + +def cluster_and_compare_expression_to_truth(adata, embedding_key='cellbender_embedding'): + + cluster = cluster_cells(adata, embedding_key=embedding_key) + adata.obs['cluster'] = cluster + cells = (adata.obs['cell_probability'] > 0.5) + + display(Markdown('## Gene expression embedding, $z_n$')) + display(Markdown('Here we find cluster labels *de novo* using spectral clustering, ' + 'in order to compare learned profiles with the truth. There ' + 'is inherently an issue of non-identifiabiity, where we cannot ' + 'know the order of the true cluster labels')) + + # plot z PCA colored by spectral cluster + plt.figure(figsize=(4, 4)) + for k in np.unique(adata.obs['cluster'][cells]): + plt.plot(adata.obsm['X_pca'][adata.obs['cluster'] == k, 0], + adata.obsm['X_pca'][adata.obs['cluster'] == k, 1], + '.', ls='', ms=5, alpha=0.25) + plt.title('Gene expression embedding,\ncolored by spectral clustering') + plt.xlabel('PC 0') + plt.ylabel('PC 1') + plt.show() + + display(Markdown('## Agreement of per-celltype gene expression with truth')) + display(Markdown('We can now compare the gene expression profile of cells ' + 'from the same cluster (found *de novo*) before and after ' + 'CellBender. We expect to see the ambient profile match, ' + 'and we expect that each *de novo* cluster will match the ' + 'gene expression of one of the "truth" clusters, although ' + 'the label order may be swapped. Here are three ways to ' + 'visualize this same data.')) + + # load truth data into a matrix + true_chi = np.zeros((np.unique(cluster).size, adata.shape[1])) + true_chi[0, :] = adata.var['truth_ambient_expression'] + for i in range(1, np.unique(cluster).size): + true_chi[i, :] = adata.var[f'truth_gene_expression_cell_label_{i}'] + + # figure out the learned expression profiles chi + learned_chi = np.zeros((np.unique(cluster).size, true_chi.shape[1])) + learned_chi[0, :] = adata.var['ambient_expression'] + for k in adata.obs['cluster'].unique(): + if k == 0: + continue + # get chi from mean cell expression in that cluster + summmed_expression = np.array(adata.layers['cellbender'][adata.obs['cluster'] == k, :] + .sum(axis=0)).squeeze() + learned_chi[k, :] = summmed_expression / summmed_expression.sum() + + # compare learned expression to the underlying true expression + def _gridplot(adata, upper_lim=1e-1, scale='linear'): + plt.figure(figsize=(10, 9)) + n_clusters = adata.obs['cluster'].nunique() + for k in adata.obs['cluster'].unique(): + for j in adata.obs['cluster'].unique(): + plt.subplot(n_clusters, + n_clusters, + n_clusters * k + j + 1) + plt.plot([1e-7, 1e-1], [1e-7, 1e-1], color='black', lw=0.2) + plt.plot(true_chi[j, :], learned_chi[k, :], '.', ls='', ms=1, alpha=0.5) + plt.ylim([1e-6, upper_lim]) + plt.xlim([1e-6, upper_lim]) + plt.xscale(scale) + plt.yscale(scale) + if j == 0: + plt.ylabel(f'Learned {k if k > 0 else "ambient"}') + else: + plt.yticks([]) + if k == n_clusters - 1: + plt.xlabel(f'True {j if j > 0 else "ambient"}') + else: + plt.xticks([]) + plt.show() + + _gridplot(adata, scale='log') + _gridplot(adata, upper_lim=1e-2,) + + # same in the format of cosine distance + n_clusters = adata.obs['cluster'].nunique() + dist = np.zeros((n_clusters, n_clusters)) + for k in adata.obs['cluster'].unique(): + for j in adata.obs['cluster'].unique(): + u, v = true_chi[j, :], learned_chi[k, :] + # cosine distance + dist[k, j] = cosine(u, v) + + fig = plt.figure(figsize=(5, 5)) + if dist.max() > 0.9: + plt.imshow(dist, vmin=0, vmax=dist[dist < 0.9].max() + 0.1, + cmap=plt.cm.gray_r) + else: + plt.imshow(dist, vmin=0, + cmap=plt.cm.gray_r) + + for i in range(dist.shape[0]): + for j in range(dist.shape[1]): + plt.text(i - 0.3, j + 0.05, f'{dist[j, i]:.3f}', fontsize=14, color='gray') + + plt.xticks(range(n_clusters), ['BKG'] + [i + 1 for i in range(n_clusters - 1)]) + # plt.gca().xaxis.set_ticks_position('top') + # plt.gca().xaxis.set_label_position('top') + plt.yticks(range(n_clusters), ['BKG'] + [i + 1 for i in range(n_clusters - 1)]) + plt.ylim(plt.gca().get_xlim()[::-1]) + plt.xlabel('True') + plt.ylabel('Inferred') + plt.title('Cosine distance between\ntrue and inferred expression') + + from mpl_toolkits.axes_grid1 import make_axes_locatable + + divider = make_axes_locatable(plt.gca()) + cax = divider.append_axes("right", size="5%", pad=0.05) + plt.colorbar(cax=cax, format='%.2f') + + plt.tight_layout() + plt.show() + + return learned_chi + + +def cosine(u: np.ndarray, v: np.ndarray): + return 1 - np.dot(u, v) / (np.sqrt(np.dot(u, u)) * np.sqrt(np.dot(v, v)) + 1e-10) + + +def fano(count_matrix_csr, axis=0): + """Calculate Fano factor for count matrix, either per gene or per cell, + as specified by axis. + """ + + mean = np.array(count_matrix_csr.mean(axis=axis)).squeeze() + square_mean = np.array(count_matrix_csr.power(2).mean(axis=axis)).squeeze() + var = square_mean - np.power(mean, 2) + return var / (mean + 1e-10) + + +def plot_counts_per_gene(adata): + + order_gene = np.argsort(adata.var['n_cellbender'])[::-1] + plt.loglog(adata.var['n_cellbender'][order_gene]) + plt.loglog(adata.var['n_cellbender'][order_gene], ':', alpha=0.5) + plt.xlabel('Sorted gene ID') + plt.ylabel('Unique UMI counts') + plt.show() + + +def compare_latents(adata, input_layer_key='raw'): + """Compare inferred latents to truth""" + + truth_exists = ('truth_cell_probability' in adata.obs.keys()) + + display(Markdown('## Inference of latent variables (for experts)')) + + if not truth_exists: + display(Markdown('This section deals with particular details of the ' + 'latent variables in the `remove-background` model. ' + 'This analysis is provided for interested experts, but ' + 'is not necessary for judging the success of a run.')) + + display(Markdown('### Ambient gene expression profile')) + plt.figure(figsize=(12, 3)) + plt.plot(adata.var['ambient_expression'].values) + plt.ylabel('Fractional expression') + plt.xlabel('Gene') + plt.title('Inferred ambient profile') + plt.show() + + if truth_exists: + plt.figure(figsize=(12, 3)) + plt.plot(adata.var['ambient_expression'].values + - adata.var['truth_ambient_expression'].values) + plt.ylabel('Residual: inferred - true') + plt.xlabel('Gene') + plt.title('Inferred ambient profile') + plt.show() + + display(Markdown('### Swapping fraction, rho')) + + rho = adata.uns.get('swapping_fraction_dist_params', None) + if rho is None: + display(Markdown('Swapping fraction not inferred. `--model` may have ' + 'been "ambient" instead of "swapping" or "full"')) + else: + from scipy.stats import beta + nbins = 100 + xx = np.linspace(0, 1, nbins) + if truth_exists: + plt.hist(adata.obs['truth_swapping_fraction'].values, + bins=xx, label='Truth', alpha=0.5) + plt.plot(xx, (adata.shape[0] / nbins + * beta.pdf(xx, consts.RHO_ALPHA_PRIOR, consts.RHO_BETA_PRIOR)), + label='Prior', color='k') + plt.plot(xx, (adata.shape[0] / nbins + * beta.pdf(xx, rho[0], rho[1])), label='Inferred', color='r') + plt.title('Inferred distribution for swapping fraction') + plt.legend(loc='center left', bbox_to_anchor=(1, 0.5)) + plt.xlabel('Swapping fraction rho') + plt.ylabel('Number of droplets') + plt.show() + + if truth_exists: + + display(Markdown('### Droplet efficiency and cell size latents')) + display(Markdown('Including empty droplets')) + keys = ['droplet_efficiency', 'cell_size'] + + plt.figure(figsize=(5 * len(keys), 4)) + for i, key in enumerate(keys): + plt.subplot(1, len(keys), i + 1) + otherkey = 'droplet_efficiency' if (key == 'cell_size') else 'cell_size' + plt.scatter(adata.obs[f'truth_{key}'], adata.obs[key], + c=adata.obs[otherkey], s=5, cmap='coolwarm', alpha=0.5) + cbar = plt.colorbar() + cbar.set_label(otherkey.capitalize().replace('_', ' ')) + xx = [adata.obs[f'truth_{key}'].min(), adata.obs[f'truth_{key}'].max()] + plt.plot(xx, xx, color='lightgray') + plt.title(key.capitalize().replace('_', ' ')) + plt.xlabel('truth') + plt.ylabel('cellbender') + plt.axis('equal') + plt.tight_layout() + plt.show() + + display(Markdown('Cells only')) + cells = (adata.obs['cell_probability'] > 0.5) + plt.figure(figsize=(5 * len(keys), 4)) + for i, key in enumerate(keys): + plt.subplot(1, len(keys), i + 1) + for c in sorted(adata.obs['truth_cell_label'][cells].unique()): + ctype = (adata.obs['truth_cell_label'] == c) + plt.plot(adata.obs[f'truth_{key}'][cells & ctype], + adata.obs[key][cells & ctype], '.', + label=f'{c} ({ctype.sum()} cells)', alpha=0.5) + xx = [adata.obs[f'truth_{key}'][cells].min(), + adata.obs[f'truth_{key}'][cells].max()] + plt.plot(xx, xx, color='lightgray') + plt.title(key.capitalize().replace('_', ' ') + ': cells') + plt.xlabel('truth') + plt.ylabel('cellbender') + plt.axis('equal') + plt.legend(loc='center left', bbox_to_anchor=(1, 0.5), title='Cell type') + plt.tight_layout() + plt.show() + + display(Markdown(r'### Droplet efficiency $\epsilon$')) + if truth_exists: + display(Markdown('Comparison with the truth.')) + + order = np.argsort(adata.obs[f'n_{input_layer_key}'].values)[::-1] + plt.figure(figsize=(6, 4)) + plt.semilogy(adata.obs[f'n_{input_layer_key}'].values[order], 'k', lw=2) + plt.ylabel('UMI counts') + plt.xlabel('Droplet') + + plt.gca().twinx() + if truth_exists: + plt.plot(adata.obs['truth_droplet_efficiency'].values[order], + label='truth', alpha=0.5) + plt.plot(adata.obs['droplet_efficiency'].values[order], + 'r', label='inferred', alpha=0.5) + plt.ylabel(r'$\epsilon$', fontsize=18, color='r') + plt.legend() + plt.show() + + display(Markdown('Comparison with the prior.')) + from numpy.random import gamma + rh = consts.EPSILON_PRIOR + delta = 0.01 + xx = np.arange(0, 2.1, step=delta) + + if truth_exists: + cells = (adata.obs['truth_cell_probability'] == 1) + yy, _ = np.histogram( + gamma(adata.uns['truth_epsilon_param'], + scale=1. / adata.uns['truth_epsilon_param'], size=[50000]), + bins=xx, + ) + plt.step(xx[:-1], yy / np.sum(yy * delta), label='truth', color='r') + else: + cells = (adata.obs['cell_probability'] > 0.5) + + yy, _ = np.histogram(gamma(rh, scale=1. / rh, size=[50000]), bins=xx) + plt.step(xx[:-1], yy / np.sum(yy * delta), label='prior', color='k') + + yy, _ = np.histogram(adata.obs['droplet_efficiency'][cells], bins=xx) + plt.step(xx[:-1], yy / np.sum(yy * delta), alpha=0.5, label='posterior: cells') + + yy, _ = np.histogram(adata.obs['droplet_efficiency'][~cells], bins=xx) + plt.step(xx[:-1], yy / np.sum(yy * delta), alpha=0.5, label='posterior: empties') + + plt.ylabel('Probability density') + plt.xlabel(r'$\epsilon$', fontsize=18) + plt.legend(loc='center left', bbox_to_anchor=(1, 0.5)) + plt.show() + + display(Markdown('### Cell size $d$')) + if truth_exists: + display(Markdown('Comparison with the truth.')) + cell_order = np.argsort(adata.obs[f'n_{input_layer_key}'].values[cells])[::-1] + plt.figure(figsize=(6, 4)) + plt.semilogy(adata.obs[f'n_{input_layer_key}'].values[cells][cell_order], 'k', lw=2) + plt.ylabel('UMI counts') + plt.xlabel('Droplet') + + plt.gca().twinx() + if truth_exists: + plt.semilogy(adata.obs['truth_cell_size'].values[cells][cell_order], + label='truth', alpha=0.5) + plt.semilogy(adata.obs['cell_size'].values[cells][cell_order], + 'r', label='inferred', alpha=0.5) + plt.ylabel('$d$', fontsize=18, color='r') + plt.legend() + plt.show() + + display(Markdown(r'### The combination $d \epsilon$')) + display(Markdown('It is easier for the model to nail this down, since there ' + 'is less degeneracy.')) + + plt.figure(figsize=(6, 4)) + plt.semilogy(adata.obs[f'n_{input_layer_key}'].values[cells][cell_order], 'k', lw=2) + plt.ylabel('UMI counts') + plt.xlabel('Droplet') + + plt.gca().twinx() + if truth_exists: + plt.semilogy((adata.obs['truth_cell_size'].values[cells][cell_order] + * adata.obs['truth_droplet_efficiency'].values[cells][cell_order]), + label='truth', alpha=0.5) + plt.semilogy((adata.obs['cell_size'].values[cells][cell_order] + * adata.obs['droplet_efficiency'].values[cells][cell_order]), + 'r', label='inferred', alpha=0.5) + plt.ylabel(r'$d \epsilon$', fontsize=18, color='r') + plt.legend() + plt.show() + + display(Markdown(r'### Joint distributions of $d$ and $\epsilon$')) + if truth_exists: + display(Markdown('In true cells')) + else: + display(Markdown('In inferred cells')) + if truth_exists: + plt.figure(figsize=(9, 4)) + plt.subplot(1, 2, 1) + for c in sorted(adata.obs['truth_cell_label'][cells].unique()): + ctype = (adata.obs['truth_cell_label'] == c) + plt.semilogy(adata.obs['truth_droplet_efficiency'][ctype], + adata.obs['truth_cell_size'][ctype], + '.', alpha=0.5) + plt.ylabel('$d$', fontsize=18) + plt.xlabel(r'$\epsilon$', fontsize=18) + plt.title('Truth') + plt.subplot(1, 2, 2) + for c in sorted(adata.obs['truth_cell_label'][cells].unique()): + ctype = (adata.obs['truth_cell_label'] == c) + plt.semilogy(adata.obs['droplet_efficiency'][ctype], + adata.obs['cell_size'][ctype], + '.', label=f'{c} ({ctype.sum()} cells)', alpha=0.5) + plt.legend(loc='center left', bbox_to_anchor=(1, 0.5), title='Cell type') + else: + plt.figure(figsize=(4, 4)) + plt.semilogy(adata.obs['droplet_efficiency'][cells], + adata.obs['cell_size'][cells], + 'k.', ms=1, alpha=0.5) + plt.ylabel('$d$', fontsize=18) + plt.xlabel(r'$\epsilon$', fontsize=18) + plt.title('Inferred') + plt.tight_layout() + plt.show() + + +def mixed_species_plots(adata, input_layer_key='raw', output_layer_key='cellbender', + ngene_cutoff=5000, count_cutoff=500): + """Make mixed species plots if it seems appropriate""" + + # find a list of genes with expression exclusive to a cell type + if 'genome' not in adata.var.keys(): + return + + if ('feature_type' in adata.var.keys()) and ('Gene Expression' in adata.var['feature_type'].values): + genomes = adata.var[adata.var['feature_type'] == 'Gene Expression']['genome'].unique() + else: + genomes = adata.var['genome'].unique() + cells = (adata.obs['cell_probability'] > 0.5) + + if len(genomes) != 2: + return + + display(Markdown('## "Mixed species" analysis')) + display(Markdown('There are multiple genomes in the dataset, so we can ' + 'analyze these genes assuming they were from a "mixed ' + 'species" experiment, where we know that certain genes ' + 'come only from certain celltypes.')) + + for genome in genomes: + if 'feature_type' in adata.var.keys(): + if 'Gene Expression' in adata.var["feature_type"].values: + var_subset = adata.var[(adata.var["genome"] == genome) + & (adata.var["feature_type"] == "Gene Expression")] + else: + var_subset = adata.var[(adata.var["genome"] == genome)] + else: + var_subset = adata.var[(adata.var["genome"] == genome)] + print(f'Genome "{genome}" has {len(var_subset)} genes: ' + f'{", ".join(var_subset.index.values[:3])} ...') + + for i, genome1 in enumerate(genomes): + for genome2 in genomes[(i + 1):]: + plt.figure(figsize=(5, 5)) + for k in [input_layer_key, output_layer_key]: + x = np.array(adata.layers[k] + [:, (adata.var['genome'] == genome1)].sum(axis=1)).squeeze() + y = np.array(adata.layers[k] + [:, (adata.var['genome'] == genome2)].sum(axis=1)).squeeze() + plt.plot(x + 1, + y + 1, + '.', ms=2, label=k, alpha=0.3, + color='k' if (k == input_layer_key) else 'r') + x = x[cells] + y = y[cells] + contam_x = (y / (y + x + 1e-10))[x > (10 * y)] + contam_y = (x / (x + y + 1e-10))[y > (10 * x)] + contam = np.concatenate((contam_x, contam_y), axis=0) + display(Markdown(f'Mean "contamination" per droplet in {k} data: ' + f'{contam.mean() * 100:.2f} %')) + display(Markdown(f'Median "contamination" per droplet in {k} data: ' + f'{np.median(contam) * 100:.2f} %')) + plt.xscale('log') + plt.yscale('log') + plt.ylim(bottom=0.55) + plt.xlim(left=0.55) + plt.xlabel(f'{genome1} counts (+1)') + plt.ylabel(f'{genome2} counts (+1)') + plt.title(f'Counts per droplet: {output_layer_key}') + lgnd = plt.legend(loc='center left', bbox_to_anchor=(1, 0.5)) + _set_legend_dot_size(lgnd, size=10) + plt.show() + + +def _set_legend_dot_size(lgnd, size: int): + """Set dot size in a matplotlib legend. + Different versions of matplotlib seem to need different things. + Just give up and move on if it doesn't work. + I know this is a bit ridiculous but so is matplotlib. + """ + for h in lgnd.legendHandles: + worked = False + try: + h._legmarker.set_markersize(size) + worked = True + except AttributeError: + pass + if worked: + continue + try: + h.set_sizes([size]) + worked = True + except AttributeError: + pass + if worked: + continue + try: + h._sizes = [size] + worked = True + except AttributeError: + pass + if worked: + continue + try: + h.set_markersize(size) + worked = True + except AttributeError: + pass + + +def cell_roc_count_roc(output_csr: sp.csr_matrix, + input_csr: sp.csr_matrix, + truth_csr: sp.csr_matrix, + cell_calls: np.ndarray, + truth_cell_labels: np.ndarray = None) -> float: # 0 = empty, nonzero = cell + """Plot a ROC curve (point) for cell identification, and plot + a second for noise count identification. + + Returns: + fpr: Acutal false positive rate for counts in cells + + Note: + True positive = a noise count that has been removed + True negative = a real count that has not been removed + False positive = a real count that has been removed + False negative = a noise count that has not been removed + + | noise | real | + ------------------------------------ + removed | TP | FP | + -------------|----------o----------| + not removed | FN | TN | + ------------------------------------ + + For the cell identification case: + + True positive = a cell called a cell + True negative = an empty called empty + False positive = an empty called a cell + False negative = a cell called empty + + | cell | empty | + -------------------------------------- + called a cell | TP | FP | + ---------------|----------o----------| + called empty | FN | TN | + -------------------------------------- + + """ + + assert cell_calls.size == truth_csr.shape[0], "Cell calls must be number of barcodes." + + # find the real cells as things with counts in truth data + cell_truth = (np.array(truth_csr.sum(axis=1)).squeeze() > 0) + called_cell = (cell_calls != 0) + + display(Markdown('### Identification of non-empty droplets')) + display(Markdown('TPR = true positive rate\n\nFPR = false positive rate')) + + # cell breakdown + tpr = np.logical_and(cell_truth, called_cell).sum() / cell_truth.sum() + fpr = np.logical_and(np.logical_not(cell_truth), called_cell).sum() / called_cell.sum() + print(f'\nCell identification TPR = {tpr:.3f}') + print(f'Cell identification FPR = {fpr:.3f}') + + fig = plt.figure(figsize=(5, 5)) + plt.plot(fpr, tpr, 'o') + plt.ylabel('fraction of true cells called') + plt.xlabel('fraction of called cells that are really empty') + plt.ylim([-0.05, 1.05]) + plt.xlim([-0.05, 1.05]) + plt.title('Cell identification') + plt.show() + + # counts + # just work with cells + cell_inds = np.where(cell_truth)[0] + real_counts = truth_csr[cell_inds] + removed_counts = input_csr[cell_inds] - output_csr[cell_inds] + noise_counts = input_csr[cell_inds] - truth_csr[cell_inds] + + # count breakdown + tp = (np.array(noise_counts + .minimum(removed_counts) + .sum(axis=1)).squeeze()) + erroneously_removed_counts = removed_counts - noise_counts + erroneously_removed_counts[erroneously_removed_counts < 0] = 0 + fp = np.array(erroneously_removed_counts.sum(axis=1)).squeeze() + noise_remaining = noise_counts - removed_counts + noise_remaining[noise_remaining < 0] = 0 + fn = np.array(noise_remaining.sum(axis=1)).squeeze() + tn = np.array(real_counts.minimum(output_csr[cell_inds]).sum(axis=1)).squeeze() + + display(Markdown('Take a look at the statistics of count removal, with the ' + 'following definitions:\n\n- TP = true positive: a noise ' + 'count (correctly) removed\n- FP = false positive: a real ' + 'count (incorrectly) removed\n- TN = true negative: a real ' + 'count (correctly) not removed\n- FN = false negative: a ' + 'noise count (incorrectly) not removed')) + + print(f'max ambient counts in any matrix entry is {(input_csr - truth_csr).max()}') + + plt.figure(figsize=(8, 1)) + plt.hist(tp, bins=100) + plt.title('TP: noise counts removed per cell') + plt.show() + + plt.figure(figsize=(8, 1)) + plt.hist(fp, bins=100) + plt.title('FP: real counts removed per cell') + plt.show() + + plt.figure(figsize=(8, 1)) + plt.hist(tn, bins=100) + plt.title('TN: real counts not removed per cell') + plt.show() + + plt.figure(figsize=(8, 1)) + plt.hist(fn, bins=100) + plt.title('FN: noise counts not removed per cell') + plt.show() + + plot_roc_points(tp, fp, tn, fn, point_colors=np.array(truth_cell_labels)[cell_truth], + title='Background removal from cells', color='black', show=False) + plt.show() + + display(Markdown('### Summary statistics for noise removal')) + + print(f'Cell background removal TPR = {(tp / (tp + fn)).mean():.3f}' + f' +/- {(tp / (tp + fn)).std():.3f}') + print(f'Cell background removal FPR = {1 - (tn / (tn + fp)).mean():.3f}' + f' +/- {(tn / (tn + fp)).std():.3f}') + + display(Markdown('And finally one more way to quanitify the amount of noise remaining:')) + + contam_cell_raw = (np.array(noise_counts.sum(axis=1)).squeeze() + / np.array(real_counts.sum(axis=1)).squeeze()) + contam_cell_after = (np.array(noise_remaining.sum(axis=1)).squeeze() + / np.array(real_counts.sum(axis=1)).squeeze()) + print(f'Per cell contamination fraction raw = {contam_cell_raw.mean():.3f}' + f' +/- {contam_cell_raw.std():.3f}') + print(f'Per cell contamination fraction after = {contam_cell_after.mean():.3f}' + f' +/- {contam_cell_after.std():.3f}') + + return 1 - (tn / (tn + fp)).mean() # FPR + + +def plot_roc_points(tp: np.ndarray, + fp: np.ndarray, + tn: np.ndarray, + fn: np.ndarray, + point_colors: np.ndarray, + title: str = 'roc', + show: bool = True, + **kwargs): + """Plot points (and one summary point with error bars) on a ROC curve, + where the x-axis is FPR and the y-axis is TPR. + + Args: + tp: True positives, multiple measurements of the same value. + fp: False positives + tn: True negatives + fn: False negatives + point_colors: Color for each point + title: Plot title + show: True to show plot + kwargs: Passed to the plotter for the summary point with error bars + + """ + + fig = plt.figure(figsize=(5, 5)) + sensitivity = tp / (tp + fn) + specificity = tn / (tn + fp) + sens_mean = sensitivity.mean() + sens_stdv = sensitivity.std() + spec_mean = specificity.mean() + spec_stdv = specificity.std() + # individual points + if type(point_colors) == str: + point_colors = np.array([point_colors] * len(sensitivity)) + else: + assert len(point_colors) == len(sensitivity), 'point_colors is wrong length' + unique_colors = np.unique(point_colors) + for c in unique_colors: + plt.plot((1 - specificity)[point_colors == c], + sensitivity[point_colors == c], + '.', ms=1, alpha=0.5, label=c) + lgnd = plt.legend(loc='center left', bbox_to_anchor=(1, 0.5)) + _set_legend_dot_size(lgnd, size=15) + # midpoint + plt.plot(1 - spec_mean, sens_mean, 'o', **kwargs) + # errorbars + plt.plot([1 - (spec_mean - spec_stdv), + 1 - (spec_mean + spec_stdv)], + [sens_mean, sens_mean], **kwargs) + plt.plot([1 - spec_mean, 1 - spec_mean], + [sens_mean - sens_stdv, + sens_mean + sens_stdv], **kwargs) + plt.ylabel('sensitivity = TP / (TP + FN)\ntrue positive rate') + plt.xlabel('1 - specificity = 1 - TN / (TN + FP)\nfalse positive rate') + plt.ylim([-0.05, 1.05]) + plt.xlim([-0.05, 1.05]) + plt.title(title) + + if show: + plt.show() + else: + return fig + + +def pca_2d(mat: np.ndarray) -> torch.Tensor: + """Perform PCA using pytorch and return top 2 PCs + + Args: + mat: matrix where rows are observations and columns are features + + Returns: + out: matrix where rows are observations and columns are top 2 PCs + """ + + A = torch.as_tensor(mat).float() + U, S, V = torch.pca_lowrank(A) + return torch.matmul(A, V[:, :2]) + + +def plot_summary(loss: Dict[str, Dict[str, np.ndarray]], + umi_counts: np.ndarray, + p: np.ndarray, + z: np.ndarray): + """Output summary plot with three panels: training, cells, latent z.""" + + fig = plt.figure(figsize=(6, 18)) + + # Plot the train error. + plt.subplot(3, 1, 1) + try: + plt.plot(loss['train']['elbo'], '.--', label='Train') + + # Plot the test error, if there was held-out test data. + if 'test' in loss.keys(): + if len(loss['test']['epoch']) > 0: + plt.plot(loss['test']['epoch'], + loss['test']['elbo'], 'o:', label='Test') + plt.legend() + + ylim_low = max(loss['train']['elbo'][0], loss['train']['elbo'][-1] - 2000) + try: + ylim_high = max(max(loss['train']['elbo']), max(loss['test']['elbo'])) + except ValueError: + ylim_high = max(loss['train']['elbo']) + ylim_high = ylim_high + (ylim_high - ylim_low) / 20 + plt.gca().set_ylim([ylim_low, ylim_high]) + except: + logger.warning('Error plotting the learning curve. Skipping.') + pass + + plt.xlabel('Epoch') + plt.ylabel('ELBO') + plt.title('Progress of the training procedure') + + # Plot the barcodes used, along with the inferred + # cell probabilities. + plt.subplot(3, 1, 2) + count_order = np.argsort(umi_counts)[::-1] + plt.semilogy(umi_counts[count_order], color='black') + plt.ylabel('UMI counts') + plt.xlabel('Barcode index, sorted by UMI count') + if p is not None: # The case of a simple model. + plt.gca().twinx() + plt.plot(p[count_order], '.:', color='red', alpha=0.3, rasterized=True) + plt.ylabel('Cell probability', color='red') + plt.ylim([-0.05, 1.05]) + plt.title('Determination of which barcodes contain cells') + else: + plt.title('The subset of barcodes used for training') + + plt.subplot(3, 1, 3) + if p is None: + p = np.ones(z.shape[0]) + + # Do PCA on the latent encoding z. + z_pca = pca_2d(z[p >= consts.CELL_PROB_CUTOFF]) + + # Plot the latent encoding via PCA. + plt.plot(z_pca[:, 0], z_pca[:, 1], + '.', ms=3, color='black', alpha=0.3, rasterized=True) + plt.ylabel('PC 1') + plt.xlabel('PC 0') + plt.title('PCA of latent encoding of gene expression in cells') + + return fig diff --git a/cellbender/remove_background/run.py b/cellbender/remove_background/run.py new file mode 100644 index 00000000..7b777e4e --- /dev/null +++ b/cellbender/remove_background/run.py @@ -0,0 +1,779 @@ +"""Single run of remove-background, given input arguments.""" + +from cellbender.remove_background.model import RemoveBackgroundPyroModel +from cellbender.remove_background.data.dataset import get_dataset_obj, \ + SingleCellRNACountsDataset +from cellbender.remove_background.vae.decoder import Decoder +from cellbender.remove_background.vae.encoder \ + import EncodeZ, CompositeEncoder, EncodeNonZLatents +from cellbender.remove_background.data.dataprep import \ + prep_sparse_data_for_training as prep_data_for_training +from cellbender.remove_background.checkpoint import attempt_load_checkpoint, \ + save_checkpoint +import cellbender.remove_background.consts as consts +from cellbender.remove_background.data.dataprep import DataLoader +from cellbender.remove_background.train import run_training +from cellbender.remove_background.posterior import Posterior, PRq, PRmu, \ + compute_mean_target_removal_as_function, load_or_compute_posterior_and_save +from cellbender.remove_background.estimation import MultipleChoiceKnapsack, \ + MAP, Mean, SingleSample, ThresholdCDF +from cellbender.remove_background.exceptions import ElboException +from cellbender.remove_background.sparse_utils import csr_set_rows_to_zero +from cellbender.remove_background.data.io import write_matrix_to_cellranger_h5 +from cellbender.remove_background.report import run_notebook_make_html, plot_summary + +import pyro +from pyro.infer import SVI, JitTraceEnum_ELBO, JitTrace_ELBO, \ + TraceEnum_ELBO, Trace_ELBO +from pyro.optim import ClippedAdam +import numpy as np +import scipy.sparse as sp +import pandas as pd +import torch + +import os +import sys +import logging +import argparse +import traceback +import psutil +from datetime import datetime +from typing import Tuple, Optional, Dict, Union + +import matplotlib +matplotlib.use('Agg') +import matplotlib.pyplot as plt # This needs to be after matplotlib.use('Agg') + + +logger = logging.getLogger('cellbender') + + +def run_remove_background(args: argparse.Namespace) -> Posterior: + """The full script for the command line tool to remove background RNA. + + Args: + args: Inputs from the command line, already parsed using argparse. + + Note: Returns nothing, but writes output to a file(s) specified from + command line. + + """ + + # Handle initial random state. + pyro.util.set_rng_seed(consts.RANDOM_SEED) + if torch.cuda.is_available(): + torch.cuda.manual_seed_all(consts.RANDOM_SEED) + + # Load dataset, run inference, and write the output to a file. + + # Log the start time. + logger.info(datetime.now().strftime('%Y-%m-%d %H:%M:%S')) + logger.info("Running remove-background") + + # Run pytorch multithreaded if running on CPU: but this makes little difference in runtime. + if not args.use_cuda: + if args.n_threads is not None: + n_jobs = args.n_threads + else: + n_jobs = psutil.cpu_count(logical=True) + torch.set_num_threads(n_jobs) + logger.debug(f'Set pytorch to use {n_jobs} threads') + + # Load data from file and choose barcodes and genes to analyze. + try: + dataset_obj = get_dataset_obj(args=args) + + except OSError: + logger.error(f"OSError: Unable to open file {args.input_file}.") + logger.error(traceback.format_exc()) + sys.exit(1) + + # Instantiate latent variable model and run full inference procedure. + if args.model == 'naive': + inferred_model = None + else: + inferred_model, _, _, _ = run_inference(dataset_obj=dataset_obj, args=args) + inferred_model.eval() + + try: + + file_dir, file_base = os.path.split(args.output_file) + file_name = os.path.splitext(os.path.basename(file_base))[0] + + # Create the posterior and save it. + posterior = load_or_compute_posterior_and_save( + dataset_obj=dataset_obj, + inferred_model=inferred_model, + args=args, + ) + logger.info(datetime.now().strftime('%Y-%m-%d %H:%M:%S\n')) + + # Save output plots. + save_output_plots( + file_dir=file_dir, + file_name=file_name, + dataset_obj=dataset_obj, + inferred_model=inferred_model, + p=posterior.latents_map['p'], + z=posterior.latents_map['z'], + ) + + # Save cell barcodes in a CSV file. + analyzed_barcode_logic = (posterior.latents_map['p'] > consts.CELL_PROB_CUTOFF) + cell_barcodes = (dataset_obj.data['barcodes'] + [dataset_obj.analyzed_barcode_inds[analyzed_barcode_logic]]) + bc_file_name = os.path.join(file_dir, file_name + "_cell_barcodes.csv") + write_cell_barcodes_csv(bc_file_name=bc_file_name, cell_barcodes=cell_barcodes) + + # Compute estimates of denoised count matrix for each FPR and save them. + compute_output_denoised_counts_reports_metrics( + posterior=posterior, + args=args, + file_dir=file_dir, + file_name=file_name, + ) + + logger.info("Completed remove-background.") + logger.info(datetime.now().strftime('%Y-%m-%d %H:%M:%S\n')) + + return posterior + + # The exception allows user to end inference prematurely with CTRL-C. + except KeyboardInterrupt: + + # If partial output has been saved, delete it. + full_file = args.output_file + + # Name of the filtered (cells only) file. + file_dir, file_base = os.path.split(full_file) + file_name = os.path.splitext(os.path.basename(file_base))[0] + filtered_file = os.path.join(file_dir, file_name + "_filtered.h5") + + if os.path.exists(full_file): + os.remove(full_file) + + if os.path.exists(filtered_file): + os.remove(filtered_file) + + logger.info("Keyboard interrupt. Terminated without saving.\n") + + +def save_output_plots(file_dir: str, + file_name: str, + dataset_obj: SingleCellRNACountsDataset, + inferred_model: RemoveBackgroundPyroModel, + p: np.ndarray, + z: np.ndarray) -> bool: + """Save the UMI histogram and the three-panel output summary PDF""" + + try: + # File naming. + summary_fig_name = os.path.join(file_dir, file_name + ".pdf") + + # Three-panel output summary plot. + counts = np.array(dataset_obj.get_count_matrix().sum(axis=1)).squeeze() + fig = plot_summary(loss=inferred_model.loss, umi_counts=counts, p=p, z=z) + fig.savefig(summary_fig_name, bbox_inches='tight', format='pdf') + logger.info(f"Saved summary plots as {summary_fig_name}") + return True + + except Exception: + logger.warning("Unable to save all plots.") + logger.warning(traceback.format_exc()) + return False + + +def compute_output_denoised_counts_reports_metrics(posterior: Posterior, + args: argparse.Namespace, + file_dir: str, + file_name: str) -> bool: + """Handle the estimation of the output denoised count matrix, given a + posterior. Compute the estimate for all specified FPR values. Save each + as we go. Create reports and save, and aggregate metrics and save as we go. + + Args: + posterior: Posterior object + args: Argparser namespace with all parsed input args + file_dir: + file_name: + + Returns: + True iff all files write correctly + + """ + + # Ensure that the posterior distribution has been computed. + # TODO: when we make the properties non-private, then this should become obsolete + posterior.cell_noise_count_posterior_coo() + + # Choose output count matrix estimation method. + noise_target_fun = None + if args.estimator == 'map': + estimator = MAP + elif args.estimator == 'mean': + estimator = Mean + elif args.estimator == 'sample': + estimator = SingleSample + elif args.estimator == 'cdf': + estimator = ThresholdCDF + elif args.estimator == 'mckp': + estimator = MultipleChoiceKnapsack + + # Prep specific for MCKP: target estimation. + logger.info('Computing target noise counts per gene for MCKP estimator') + count_matrix = posterior.dataset_obj.data['matrix'] # all barcodes + cell_inds = posterior.dataset_obj.analyzed_barcode_inds[posterior.latents_map['p'] + > consts.CELL_PROB_CUTOFF] + empty_inds = set(range(count_matrix.shape[0])) - set(cell_inds) + cell_counts = csr_set_rows_to_zero(csr=count_matrix, row_inds=empty_inds) + + noise_target_fun_per_cell = compute_mean_target_removal_as_function( + noise_count_posterior_coo=posterior._noise_count_posterior_coo, + noise_offsets=posterior._noise_count_posterior_coo_offsets, + index_converter=posterior.index_converter, + raw_count_csr_for_cells=cell_counts, + n_cells=len(cell_inds), + device='cuda' if args.use_cuda else 'cpu', # TODO check this + per_gene=True, + ) + noise_target_fun = lambda x: noise_target_fun_per_cell(x) * len(cell_inds) + else: + raise ValueError(f'Input --estimator must be one of ' + f'["map", "mean", "sample", "cdf", "mckp"]') + + # Save denoised count matrix outputs (for each FPR if applicable). + success = True + for fpr in args.fpr: + + logger.debug(f'Working on FPR {fpr}') + + # Regularize posterior again at this FPR, if needed. + if args.posterior_regularization in ['PRmu', 'PRmu_gene']: + # TODO: currently this re-calculates the first FPR which is not necessary + posterior.regularize_posterior( + regularization=PRmu, + raw_count_matrix=posterior.dataset_obj.data['matrix'], + fpr=fpr, + per_gene=True if (args.posterior_regularization == 'PRmu_gene') else False, + device='cuda', + ) + else: + # Other posterior regularizations were already performed in + # posterior.load_or_compute_posterior_and_save() + pass + + # If using MCKP, recompute noise targets for this FPR. + if noise_target_fun is not None: + noise_targets = noise_target_fun(fpr).detach().cpu().numpy() + logger.debug(f'Computed noise targets for FPR {fpr}:\n{noise_targets}') + logger.info(f'Using MCKP noise targets computed for FPR {fpr}') + else: + noise_targets = None + + # Compute denoised counts. + logger.info(f'Computing denoised counts using {args.estimator} estimator') + denoised_counts = posterior.compute_denoised_counts( + estimator_constructor=estimator, + noise_targets_per_gene=noise_targets, + q=args.cdf_threshold_q, + alpha=args.prq_alpha, + device='cuda' if args.use_cuda else 'cpu', + use_multiple_processes=args.use_multiprocessing_estimation, + ) + + # Restore eliminated features in cells. + logger.debug('Restoring eliminated features in cells') + denoised_counts = posterior.dataset_obj.restore_eliminated_features_in_cells( + denoised_counts, + posterior.latents_map['p'], + ) + + # TODO: correct cell probabilities so that any zero-count droplet becomes "empty" + + # Save denoised count matrix. + name_suffix = (f'_FPR_{fpr}' if len(args.fpr) > 1 else '') + fpr_output_filename = os.path.join(file_dir, file_name + name_suffix + '.h5') + filtered_output_file = os.path.join(file_dir, file_name + name_suffix + '_filtered.h5') + + def _writer_helper(file, **kwargs) -> bool: + return write_denoised_count_matrix( + file=file, + denoised_count_matrix=denoised_counts, + posterior_regularization=args.posterior_regularization, + posterior_regularization_kwargs=posterior._noise_count_regularized_posterior_kwargs, + estimator=args.estimator, + estimator_kwargs=None if (args.cdf_threshold_q is None) else {'q': args.cdf_threshold_q}, + latents=posterior.latents_map, + dataset_obj=posterior.dataset_obj, + learning_curve=posterior.vi_model.loss, + fpr=fpr, + **kwargs, + ) + + # Full count matrix. + write_succeeded = _writer_helper(file=fpr_output_filename) + success = success and write_succeeded + + # Count matrix filtered to cells only. + analyzed_barcode_logic = (posterior.latents_map['p'] > consts.CELL_PROB_CUTOFF) + write_succeeded = _writer_helper( + file=filtered_output_file, + analyzed_barcode_logic=analyzed_barcode_logic, + barcode_inds=posterior.dataset_obj.analyzed_barcode_inds[analyzed_barcode_logic], + ) + success = success and write_succeeded + + # Compile and save metrics. + try: + df = collect_output_metrics( + dataset_obj=posterior.dataset_obj, + inferred_count_matrix=denoised_counts, + fpr=fpr, + cell_logic=(posterior.latents_map['p'] >= consts.CELL_PROB_CUTOFF), + loss=posterior.vi_model.loss, + ) + metrics_file_name = os.path.join(file_dir, file_name + name_suffix + '_metrics.csv') + df.to_csv(metrics_file_name, index=True, header=False, float_format='%.3f') + logger.info(f'Saved output metrics as {metrics_file_name}') + except Exception: + logger.warning("Unable to collect output metrics.") + logger.warning(traceback.format_exc()) + + # Create report. + try: + os.environ['INPUT_FILE'] = os.path.abspath(os.path.join(os.getcwd(), args.input_file)) + os.environ['OUTPUT_FILE'] = os.path.abspath(os.path.join(os.getcwd(), fpr_output_filename)) + if args.truth_file is not None: + os.environ['TRUTH_FILE'] = os.path.abspath(os.path.join(os.getcwd(), args.truth_file)) + html_report_file = os.path.join(file_dir, file_name + name_suffix + '_report.html') + run_notebook_make_html( + file=os.path.abspath(os.path.join(os.path.dirname(__file__), 'report.ipynb')), + output=html_report_file, + ) + logger.info(f'Succeeded in writing report to {html_report_file}') + + except Exception: + logger.warning("Unable to create report.") + logger.warning(traceback.format_exc()) + + return success + + +def write_denoised_count_matrix(file: str, + denoised_count_matrix: sp.csr_matrix, + posterior_regularization: Optional[str], + posterior_regularization_kwargs: Optional[Dict[str, float]], + estimator: str, + estimator_kwargs: Optional[Dict[str, float]], + latents: Dict[str, np.ndarray], + dataset_obj: SingleCellRNACountsDataset, + learning_curve: Dict[str, np.ndarray], # inferred_model.loss + fpr: float, + analyzed_barcode_logic: np.ndarray = ..., + barcode_inds: np.ndarray = ...) -> bool: + """Helper function for writing output h5 files""" + + z = latents['z'][analyzed_barcode_logic, :] + d = latents['d'][analyzed_barcode_logic] + p = latents['p'][analyzed_barcode_logic] + epsilon = latents['epsilon'][analyzed_barcode_logic] + + # Inferred ambient gene expression vector. + ambient_expression_trimmed = pyro.param('chi_ambient').detach().cpu().numpy() + + # Convert the indices from trimmed gene set to original gene indices. + ambient_expression = np.zeros(dataset_obj.data['matrix'].shape[1]) + ambient_expression[dataset_obj.analyzed_gene_inds] = ambient_expression_trimmed + + # Some summary statistics: + # Fraction of counts in each droplet that were removed. + raw_count_matrix = dataset_obj.data['matrix'][dataset_obj.analyzed_barcode_inds, :] # need all genes + raw_counts_droplet = np.array(raw_count_matrix.sum(axis=1)).squeeze() + out_counts_droplet = np.array(denoised_count_matrix[dataset_obj.analyzed_barcode_inds, :] + .sum(axis=1)).squeeze() + background_fraction = ((raw_counts_droplet - out_counts_droplet) / + (raw_counts_droplet + 0.001))[analyzed_barcode_logic] + + # Handle the optional rho parameters. + rho = None + if (('rho_alpha' in pyro.get_param_store().keys()) + and ('rho_beta' in pyro.get_param_store().keys())): + rho = np.array([pyro.param('rho_alpha').detach().cpu().numpy().item(), + pyro.param('rho_beta').detach().cpu().numpy().item()]) + + # Determine metadata fields. + # Wrap in lists to avoid scanpy loading bug + # which may already be fixed by https://github.com/scverse/scanpy/pull/2344 + metadata = {'learning_curve': learning_curve, + 'barcodes_analyzed': dataset_obj.data['barcodes'][dataset_obj.analyzed_barcode_inds], + 'barcodes_analyzed_inds': dataset_obj.analyzed_barcode_inds, + 'features_analyzed_inds': dataset_obj.analyzed_gene_inds, + 'fraction_data_used_for_testing': 1. - consts.TRAINING_FRACTION, + 'target_false_positive_rate': fpr} + for k in ['posterior_regularization', 'posterior_regularization_kwargs', + 'estimator', 'estimator_kwargs']: + val = locals().get(k) # give me the input variable with this name + if val is not None: + if type(val) != dict: + if type(val) != list: + val = [val] # wrap in a list, unless it's a dict + metadata.update({k: val}) + + # Write h5. + write_succeeded = write_matrix_to_cellranger_h5( + cellranger_version=3, # always write v3 format output + output_file=file, + gene_names=dataset_obj.data['gene_names'], + gene_ids=dataset_obj.data['gene_ids'], + feature_types=dataset_obj.data['feature_types'], + genomes=dataset_obj.data['genomes'], + barcodes=dataset_obj.data['barcodes'][barcode_inds], + count_matrix=denoised_count_matrix[barcode_inds, :], + local_latents={'barcode_indices_for_latents': dataset_obj.analyzed_barcode_inds, + 'gene_expression_encoding': z, + 'cell_size': d, + 'cell_probability': p, + 'droplet_efficiency': epsilon, + 'background_fraction': background_fraction}, + global_latents={'ambient_expression': ambient_expression, + 'empty_droplet_size_lognormal_loc': pyro.param('d_empty_loc').item(), + 'empty_droplet_size_lognormal_scale': pyro.param('d_empty_scale').item(), + 'cell_size_lognormal_std': pyro.param('d_cell_scale').item(), + 'swapping_fraction_dist_params': rho}, + metadata=metadata, + ) + return write_succeeded + + +def collect_output_metrics(dataset_obj: SingleCellRNACountsDataset, + inferred_count_matrix: sp.csr_matrix, + fpr: Union[float, str], + cell_logic, + loss) -> pd.DataFrame: + """Create a table with a few output metrics. The idea is for these to + potentially be used by people creating automated pipelines.""" + + # Compute some metrics + input_count_matrix = dataset_obj.data['matrix'][dataset_obj.analyzed_barcode_inds, :] + total_raw_counts = dataset_obj.data['matrix'].sum() + total_output_counts = inferred_count_matrix.sum() + total_counts_removed = total_raw_counts - total_output_counts + fraction_counts_removed = total_counts_removed / total_raw_counts + total_raw_counts_in_nonempty_droplets = input_count_matrix[cell_logic].sum() + total_counts_removed_from_nonempty_droplets = \ + total_raw_counts_in_nonempty_droplets - inferred_count_matrix.sum() + fraction_counts_removed_from_nonempty_droplets = \ + total_counts_removed_from_nonempty_droplets / total_raw_counts_in_nonempty_droplets + average_counts_removed_per_nonempty_droplet = \ + total_counts_removed_from_nonempty_droplets / cell_logic.sum() + expected_cells = dataset_obj.priors['expected_cells'] + found_cells = cell_logic.sum() + average_counts_per_cell = inferred_count_matrix.sum() / found_cells + ratio_of_found_cells_to_expected_cells = \ + None if (expected_cells is None) else (found_cells / expected_cells) + found_empties = len(dataset_obj.analyzed_barcode_inds) - found_cells + fraction_of_analyzed_droplets_that_are_nonempty = \ + found_cells / len(dataset_obj.analyzed_barcode_inds) + if len(loss['train']['elbo']) > 20: + # compare mean ELBO increase over last 3 steps to the typical end(ish) fluctuations + convergence_indicator = (np.mean(np.abs([(loss['train']['elbo'][i] + - loss['train']['elbo'][i - 1]) + for i in range(-3, -1)])) + / np.std(loss['train']['elbo'][-20:])) + else: + convergence_indicator = 'not enough training epochs to compute (requires more than 20)' + if len(loss['train']['elbo']) > 0: + overall_change_in_train_elbo = loss['train']['elbo'][-1] - loss['train']['elbo'][0] + else: + overall_change_in_train_elbo = 0 # zero epoch initialization + + all_metrics_dict = \ + {'total_raw_counts': total_raw_counts, + 'total_output_counts': total_output_counts, + 'total_counts_removed': total_counts_removed, + 'fraction_counts_removed': fraction_counts_removed, + 'total_raw_counts_in_cells': + total_raw_counts_in_nonempty_droplets, + 'total_counts_removed_from_cells': + total_counts_removed_from_nonempty_droplets, + 'fraction_counts_removed_from_cells': + fraction_counts_removed_from_nonempty_droplets, + 'average_counts_removed_per_cell': + average_counts_removed_per_nonempty_droplet, + 'target_fpr': fpr, + 'expected_cells': expected_cells, + 'found_cells': found_cells, + 'output_average_counts_per_cell': average_counts_per_cell, + 'ratio_of_found_cells_to_expected_cells': + ratio_of_found_cells_to_expected_cells, + 'found_empties': found_empties, + 'fraction_of_analyzed_droplets_that_are_nonempty': + fraction_of_analyzed_droplets_that_are_nonempty, + 'convergence_indicator': convergence_indicator, + 'overall_change_in_train_elbo': overall_change_in_train_elbo} + + return pd.DataFrame(data=all_metrics_dict, + index=['metric']).transpose() + + +def write_cell_barcodes_csv(bc_file_name: str, cell_barcodes: np.ndarray): + """Write the cell barcode CSV file. + + Args: + bc_file_name: Output CSV file + cell_barcodes: Array of the cell barcode names + + """ + + # Save barcodes determined to contain cells as _cell_barcodes.csv + try: + barcode_names = np.array([str(cell_barcodes[i], encoding='UTF-8') + for i in range(cell_barcodes.size)]) + except UnicodeDecodeError: + # necessary if barcodes are ints + barcode_names = cell_barcodes + except TypeError: + # necessary if barcodes are already decoded + barcode_names = cell_barcodes + np.savetxt(bc_file_name, barcode_names, delimiter=',', fmt='%s') + logger.info(f"Saved cell barcodes in {bc_file_name}") + + +def get_optimizer(n_batches: int, + batch_size: int, + epochs: int, + learning_rate: float, + constant_learning_rate: bool, + total_epochs_for_testing_only: Optional[int] = None) \ + -> Union[pyro.optim.PyroOptim, pyro.optim.lr_scheduler.PyroLRScheduler]: + """Get optimizer or learning rate scheduler (if using one)""" + + # Set up the optimizer. + optimizer = pyro.optim.clipped_adam.ClippedAdam # just ClippedAdam does not work + optimizer_args = {'lr': learning_rate, 'clip_norm': 10.} + + # Set up a learning rate scheduler. + if total_epochs_for_testing_only is not None: + total_steps = n_batches * total_epochs_for_testing_only + else: + total_steps = n_batches * epochs + scheduler_args = {'optimizer': optimizer, + 'max_lr': learning_rate * 10, + 'total_steps': total_steps, + 'optim_args': optimizer_args} + scheduler = pyro.optim.OneCycleLR(scheduler_args) + + # Constant learning rate overrides the above and uses no scheduler. + if constant_learning_rate: + logger.info('Using ClippedAdam --constant-learning-rate rather than ' + 'the OneCycleLR schedule. This is not usually recommended.') + scheduler = ClippedAdam(optimizer_args) + + return scheduler + + +def run_inference(dataset_obj: SingleCellRNACountsDataset, + args: argparse.Namespace, + output_checkpoint_tarball: str = consts.CHECKPOINT_FILE_NAME, + total_epochs_for_testing_only: Optional[int] = None)\ + -> Tuple[RemoveBackgroundPyroModel, pyro.optim.PyroOptim, DataLoader, DataLoader]: + """Run a full inference procedure, training a latent variable model. + + Args: + dataset_obj: Input data in the form of a SingleCellRNACountsDataset + object. + args: Input command line parsed arguments. + output_checkpoint_tarball: Intended checkpoint tarball filepath. + total_epochs_for_testing_only: Hack for testing code using LR scheduler + + Returns: + model: cellbender.model.RemoveBackgroundPyroModel that has had + inference run. + + """ + + # Get the checkpoint file base name with hash, which we stored in args. + checkpoint_filename = args.checkpoint_filename + + # Configure pyro options (skip validations to improve speed). + pyro.enable_validation(False) + pyro.distributions.enable_validation(False) + + # Set random seed, updating global state of python, numpy, and torch RNGs. + pyro.clear_param_store() + pyro.set_rng_seed(consts.RANDOM_SEED) + if args.use_cuda: + torch.cuda.manual_seed_all(consts.RANDOM_SEED) + + # Attempt to load from a previously-saved checkpoint. + ckpt = attempt_load_checkpoint(filebase=checkpoint_filename, + tarball_name=args.input_checkpoint_tarball, + force_device='cuda:0' if args.use_cuda else 'cpu') + ckpt_loaded = ckpt['loaded'] # True if a checkpoint was loaded successfully + + if ckpt_loaded: + + model = ckpt['model'] + scheduler = ckpt['optim'] + train_loader = ckpt['train_loader'] + test_loader = ckpt['test_loader'] + if hasattr(ckpt['args'], 'num_failed_attempts'): + # update this from the checkpoint file, if present + args.num_failed_attempts = ckpt['args'].num_failed_attempts + for obj in [model, scheduler, train_loader, test_loader, args]: + assert obj is not None, \ + f'Expected checkpoint to contain model, scheduler, train_loader, ' \ + f'test_loader, and args; but some are None:\n{ckpt}' + logger.info('Checkpoint loaded successfully.') + + else: + + logger.info('No checkpoint loaded.') + + # Get the trimmed count matrix (transformed if called for). + count_matrix = dataset_obj.get_count_matrix() + + # Set up the variational autoencoder: + + # Encoder. + encoder_z = EncodeZ(input_dim=count_matrix.shape[1], + hidden_dims=args.z_hidden_dims, + output_dim=args.z_dim, + use_batch_norm=False, + use_layer_norm=False, + input_transform='normalize') + + encoder_other = EncodeNonZLatents(n_genes=count_matrix.shape[1], + z_dim=args.z_dim, + log_count_crossover=dataset_obj.priors['log_counts_crossover'], + prior_log_cell_counts=np.log1p(dataset_obj.priors['cell_counts']), + empty_log_count_threshold=np.log1p(dataset_obj.empty_UMI_threshold), + prior_logit_cell_prob=dataset_obj.priors['cell_logit'], + input_transform='log_normalize') + + encoder = CompositeEncoder({'z': encoder_z, + 'other': encoder_other}) + + # Decoder. + decoder = Decoder(input_dim=args.z_dim, + hidden_dims=args.z_hidden_dims[::-1], + use_batch_norm=True, + use_layer_norm=False, + output_dim=count_matrix.shape[1]) + + # Set up the pyro model for variational inference. + model = RemoveBackgroundPyroModel(model_type=args.model, + encoder=encoder, + decoder=decoder, + dataset_obj_priors=dataset_obj.priors, + n_analyzed_genes=dataset_obj.analyzed_gene_inds.size, + n_droplets=dataset_obj.analyzed_barcode_inds.size, + analyzed_gene_names=dataset_obj.data['gene_names'][dataset_obj.analyzed_gene_inds], + empty_UMI_threshold=dataset_obj.empty_UMI_threshold, + log_counts_crossover=dataset_obj.priors['log_counts_crossover'], + use_cuda=args.use_cuda) + + # Load the dataset into DataLoaders. + frac = args.training_fraction # Fraction of barcodes to use for training + batch_size = int(min(consts.MAX_BATCH_SIZE, frac * dataset_obj.analyzed_barcode_inds.size / 2)) + + # Set up dataloaders. + train_loader, test_loader = \ + prep_data_for_training(dataset=count_matrix, + empty_drop_dataset=dataset_obj.get_count_matrix_empties(), + batch_size=batch_size, + training_fraction=frac, + fraction_empties=args.fraction_empties, + shuffle=True, + use_cuda=args.use_cuda) + + # Set up optimizer (optionally wrapped in a learning rate scheduler). + scheduler = get_optimizer( + n_batches=len(train_loader), + batch_size=train_loader.batch_size, + epochs=args.epochs, + learning_rate=args.learning_rate, + constant_learning_rate=args.constant_learning_rate, + total_epochs_for_testing_only=total_epochs_for_testing_only, + ) + + # Determine the loss function. + if args.use_jit: + + # Call guide() once as a warm-up. + # model.guide(torch.zeros([10, dataset_obj.analyzed_gene_inds.size]).to(model.device)) + + if args.model == "simple": + loss_function = JitTrace_ELBO() + else: + loss_function = JitTraceEnum_ELBO(max_plate_nesting=1, + strict_enumeration_warning=False) + else: + + if args.model == "simple": + loss_function = Trace_ELBO() + else: + loss_function = TraceEnum_ELBO(max_plate_nesting=1) + + # Set up the inference process. + svi = SVI(model.model, model.guide, scheduler, loss=loss_function) + + # Run training. + if args.epochs == 0: + logger.info("Zero epochs specified... will only initialize the model.") + model.guide(train_loader.__next__()) + train_loader.reset_ptr() + + # Even though it's not much of a checkpoint, we still need one for subsequent steps. + save_checkpoint(filebase=checkpoint_filename, + tarball_name=output_checkpoint_tarball, + args=args, + model_obj=model, + scheduler=svi.optim, + train_loader=train_loader, + test_loader=test_loader) + + else: + logger.info("Running inference...") + try: + run_training(model=model, + args=args, + svi=svi, + train_loader=train_loader, + test_loader=test_loader, + epochs=args.epochs, + test_freq=5, + output_filename=checkpoint_filename, + ckpt_tarball_name=output_checkpoint_tarball, + checkpoint_freq=args.checkpoint_min, + epoch_elbo_fail_fraction=args.epoch_elbo_fail_fraction, + final_elbo_fail_fraction=args.final_elbo_fail_fraction) + + except ElboException: + + logger.warning(traceback.format_exc()) + + # Keep track of number of failed attempts. + if not hasattr(args, 'num_failed_attempts'): + args.num_failed_attempts = 1 + else: + args.num_failed_attempts = args.num_failed_attempts + 1 + logger.debug(f'Training failed, and the number of failed attempts ' + f'on record is {args.num_failed_attempts}') + + # Retry training with reduced learning rate, if indicated by user. + logger.debug(f'Number of times to retry training is {args.num_training_tries}') + if args.num_failed_attempts < args.num_training_tries: + args.learning_rate = args.learning_rate * args.learning_rate_retry_mult + logger.info(f'Restarting training: attempt {args.num_failed_attempts + 1}, ' + f'learning_rate = {args.learning_rate}') + run_remove_background(args) # start from scratch + sys.exit(0) + else: + logger.info(f'No more attempts are specified by --num-training-tries. ' + f'Therefore the workflow will abort here.') + sys.exit(1) + + logger.info("Inference procedure complete.") + + return model, scheduler, train_loader, test_loader diff --git a/cellbender/remove_background/sparse_utils.py b/cellbender/remove_background/sparse_utils.py new file mode 100644 index 00000000..4a0f26fa --- /dev/null +++ b/cellbender/remove_background/sparse_utils.py @@ -0,0 +1,101 @@ +"""Utility functions for working with scipy sparse matrices""" + +import torch +import numpy as np +import scipy.sparse as sp + +from typing import Optional, Tuple, Iterable + + +@torch.no_grad() +def dense_to_sparse_op_torch(t: torch.Tensor, + tensor_for_nonzeros: Optional[torch.Tensor] = None) \ + -> Tuple[np.ndarray, ...]: + """Converts dense matrix to sparse COO format tuple of numpy arrays (*indices, data) + + Args: + t: The Tensor + tensor_for_nonzeros: If this is not None, then this tensor will be used + to determine nonzero indices, while the values will come from t. + + Returns: + Tuple of + (nonzero_inds_dim0, nonzero_inds_dim1, ...) + (nonzero_values, ) + + """ + + if tensor_for_nonzeros is None: + tensor_for_nonzeros = t + + nonzero_inds_tuple = torch.nonzero(tensor_for_nonzeros, as_tuple=True) + nonzero_values = t[nonzero_inds_tuple].flatten() + + return tuple([ten.cpu().numpy() for ten in (nonzero_inds_tuple + (nonzero_values,))]) + + +def log_prob_sparse_to_dense(coo: sp.coo_matrix) -> np.ndarray: + """Densify a sparse log prob COO data structure. Same as coo_matrix.todense() + except it fills missing entries with -np.inf instead of 0, since 0 is a + very meaningful quantity for log prob. + """ + return todense_fill(coo=coo, fill_value=-np.inf) + + +def todense_fill(coo: sp.coo_matrix, fill_value: float) -> np.ndarray: + """Densify a sparse COO matrix. Same as coo_matrix.todense() + except it fills missing entries with fill_value instead of 0. + """ + dummy_value = np.nan if not np.isnan(fill_value) else np.inf + dummy_check = np.isnan if np.isnan(dummy_value) else np.isinf + coo = coo.copy().astype(float) + coo.data[coo.data == 0] = dummy_value + out = np.array(coo.todense()).squeeze() + out[out == 0] = fill_value + out[dummy_check(out)] = 0 + return out + + +def csr_set_rows_to_zero(csr: sp.csr_matrix, + row_inds: Iterable[int]) -> sp.csr_matrix: + """Set all nonzero elements in rows "row_inds" to zero. + Happens in-place, although output is returned as well. + + https://stackoverflow.com/questions/12129948/scipy-sparse-set-row-to-zeros + """ + + if not isinstance(csr, sp.csr_matrix): + try: + csr = csr.tocsr() + except Exception: + raise ValueError('Matrix given must be of CSR format.') + for row in row_inds: + csr.data[csr.indptr[row]:csr.indptr[row + 1]] = 0 + csr.eliminate_zeros() + return csr + + +def overwrite_matrix_with_columns_from_another(mat1: sp.csc_matrix, + mat2: sp.csc_matrix, + column_inds: np.ndarray) -> sp.csc_matrix: + """Given two sparse matrices of the same shape, replace columns that are not + in `column_inds` in `mat1` with the entries from `mat2`. + """ + column_inds = set(column_inds) + + mat1 = mat1.copy().tocsr() + mat2 = mat2.copy().tocsr() # failure to copy could overwrite actual count data + + # Zero out values in mat2 that are in the specified columns. + inds = np.where([i in column_inds for i in mat2.indices])[0] + mat2.data[inds] = 0 + mat2.eliminate_zeros() + + # Zero out values in mat1 that are not in the specified columns. + inds = np.where([i not in column_inds for i in mat1.indices])[0] + mat1.data[inds] = 0 + mat1.eliminate_zeros() + + # Put in the new values by addition. + output = mat1 + mat2 + + return output.tocsc() diff --git a/cellbender/remove_background/tests/benchmarking/README.md b/cellbender/remove_background/tests/benchmarking/README.md new file mode 100644 index 00000000..e52c1423 --- /dev/null +++ b/cellbender/remove_background/tests/benchmarking/README.md @@ -0,0 +1,62 @@ +# Benchmarking CellBender versions and changes + +## Running benchmarking tests + +There is a benchmarking WDL in /cellbender/remove_background/tests/benchmarking called +`benchmark.wdl`. This can be run using a local installation of cromshell +(`conda install -c bioconda cromshell`) by running the python script in +`run_benchmark.py` as in + +```console +python run_benchmark.py \ + --git "v0.2.1" \ + --input "gs://broad-dsde-methods-sfleming/cellbender_test/pbmc8k_raw_gene_bc_matrices.h5" \ + --sample pbmc8k +``` + +The `--git` input can be a full commit sha or a tag or a branch. Anything that +can be pip installed via `pip install -y git+https://github.com/broadinstitute/CellBender.git@<SOMETHING>` + +(The caveat here is that older versions of CellBender cannot be installed from +github in this way, so this is a test that will work moving forward from +commit `cb2d209d5aedffe71e28947bc5b7859600aef64d`) + +### Datasets from the paper + +To re-run the datasets that were analyzed in the CellBender paper, plus +several other interesting benchmarks, try running + +```console +./run_usual_benchmarks.sh b9d2953c76c538d13549290bd986af4e6a1780d5 +``` + +You can check their status via `cromshell` using + +```console +cromshell list -u | tail -n 5 +``` + +## Validation of outputs + +Validation is comprised of a Terra notebook in the following workspace: +https://app.terra.bio/#workspaces/broad-firecloud-dsde-methods/sfleming_dev + +To prepare a data table for the Terra workspace (once all jobs +have completed): + +```console +python run_benchmark_result_tabulation.py \ + --workflows b9d2953c76c538d13549290bd986af4e6a1780d5 \ + --output samples.tsv +``` + +where, for example, `b9d2953c76c538d13549290bd986af4e6a1780d5` is +the git hash used to run `run_usual_benchmarks.sh`. (The script will `grep` +the local cromshell database for all runs that match. More than one search +term can be used.) + +Then manually upload the `samples.tsv` to Terra as a data table. + +Open the validation notebook and enter the git commit +`b9d2953c76c538d13549290bd986af4e6a1780d5` at the top. Then +run the entire notebook to produce plots. diff --git a/cellbender/remove_background/tests/benchmarking/benchmark.wdl b/cellbender/remove_background/tests/benchmarking/benchmark.wdl new file mode 100644 index 00000000..6a0781b8 --- /dev/null +++ b/cellbender/remove_background/tests/benchmarking/benchmark.wdl @@ -0,0 +1,29 @@ +version 1.0 + +import "cellbender_remove_background.wdl" as cellbender + +## Copyright Broad Institute, 2023 +## +## LICENSING : +## This script is released under the WDL source code license (BSD-3) +## (see LICENSE in https://github.com/openwdl/wdl). + + +workflow run_cellbender_benchmark { + input { + String? git_hash + } + + call cellbender.run_cellbender_remove_background_gpu as cb { + input: + dev_git_hash__=git_hash + + } + + output { + File log = cb.log + File summary_pdf = cb.pdf + Array[File] html_report_array = cb.report_array + Array[File] h5_array = cb.h5_array + } +} diff --git a/cellbender/remove_background/tests/benchmarking/benchmark_inputs.json b/cellbender/remove_background/tests/benchmarking/benchmark_inputs.json new file mode 100644 index 00000000..dea4a2e5 --- /dev/null +++ b/cellbender/remove_background/tests/benchmarking/benchmark_inputs.json @@ -0,0 +1,19 @@ +{ + "run_cellbender_benchmark.git_hash": "GIT_HASH", + "run_cellbender_benchmark.cb.input_file_unfiltered": "INPUT_GSURL", + "run_cellbender_benchmark.cb.sample_name": "SAMPLE_NAME", + "run_cellbender_benchmark.cb.truth_file": "TRUTH_GSURL", + "run_cellbender_benchmark.cb.exclude_feature_types": "Peaks", + "run_cellbender_benchmark.cb.expected_cells": null, + "run_cellbender_benchmark.cb.total_droplets_included": null, + "run_cellbender_benchmark.cb.low_count_threshold": null, + "run_cellbender_benchmark.cb.fpr": "FPR", + "run_cellbender_benchmark.cb.debug": false, + "run_cellbender_benchmark.cb.checkpoint_mins": 200, + "run_cellbender_benchmark.cb.checkpoint_file": null, + "run_cellbender_benchmark.cb.hardware_preemptible_tries": 0, + "run_cellbender_benchmark.cb.hardware_cpu_count": 8, + "run_cellbender_benchmark.cb.hardware_memory_GB": 64, + "run_cellbender_benchmark.cb.estimator_multiple_cpu": null, + "run_cellbender_benchmark.cb.docker_image": "us.gcr.io/broad-dsde-methods/cellbender:0.2.1" +} \ No newline at end of file diff --git a/cellbender/remove_background/tests/benchmarking/cuda_check_inputs.json b/cellbender/remove_background/tests/benchmarking/cuda_check_inputs.json new file mode 100644 index 00000000..b9a3c46b --- /dev/null +++ b/cellbender/remove_background/tests/benchmarking/cuda_check_inputs.json @@ -0,0 +1,4 @@ +{ + "check_pytorch_cuda_status.run_check_pytorch_cuda_status.docker_image": "us.gcr.io/broad-dsde-methods/cellbender:20230427" +} + diff --git a/cellbender/remove_background/tests/benchmarking/docker_image_check_cuda_status.wdl b/cellbender/remove_background/tests/benchmarking/docker_image_check_cuda_status.wdl new file mode 100644 index 00000000..8763bfe9 --- /dev/null +++ b/cellbender/remove_background/tests/benchmarking/docker_image_check_cuda_status.wdl @@ -0,0 +1,38 @@ +version 1.0 + +## Copyright Broad Institute, 2023 +## +## LICENSING : +## This script is released under the WDL source code license (BSD-3) +## (see LICENSE in https://github.com/openwdl/wdl). + +task run_check_pytorch_cuda_status { + input { + String docker_image + Int? hardware_boot_disk_size_GB = 20 + String? hardware_zones = "us-east1-d us-east1-c us-central1-a us-central1-c us-west1-b" + String? hardware_gpu_type = "nvidia-tesla-t4" + String? nvidia_driver_version = "470.82.01" # need >=465.19.01 for CUDA 11.3 + } + command { + set -e + python <<CODE + import torch + assert torch.cuda.is_available() + CODE + } + runtime { + docker: "${docker_image}" + bootDiskSizeGb: hardware_boot_disk_size_GB + zones: "${hardware_zones}" + gpuCount: 1 + gpuType: "${hardware_gpu_type}" + nvidiaDriverVersion: "${nvidia_driver_version}" + maxRetries: 0 + } +} + + +workflow check_pytorch_cuda_status { + call run_check_pytorch_cuda_status +} diff --git a/cellbender/remove_background/tests/benchmarking/run_benchmark.py b/cellbender/remove_background/tests/benchmarking/run_benchmark.py new file mode 100644 index 00000000..efb8520a --- /dev/null +++ b/cellbender/remove_background/tests/benchmarking/run_benchmark.py @@ -0,0 +1,225 @@ +"""Run a github commit of CellBender on test data for benchmarking purposes +Example: + $ conda activate cromshell + $ python run_benchmark.py \ + --git 2927346f4c513a217ac8ad076e494dd1adbf70e1 \ + --input "gs://path" \ + --sample "name" \ + --truth "gs://path_to_truth" +""" + +import tempfile +import json +import os +import sys +import subprocess +import shutil +import random +import argparse +from typing import Tuple, Dict, Optional, List + + +def get_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + description="Benchmark a specific commit of CellBender on a dataset " + "using cromshell.", + ) + + parser.add_argument('-g', '--git', + type=str, + required=False, + default=None, + dest='git_hash', + help='Specific github commit from the CellBender repo: ' + 'can be a tag, a branch, or a commit sha. Not ' + 'including the flag will run using the base ' + 'docker image specified in benchmark_inputs.json') + parser.add_argument('-i', '--input', + type=str, + required=True, + dest='input_file', + help='Input path (must be a gsURL, i.e. ' + '"gs://bucket/path/file.h5")') + parser.add_argument('-s', '--sample', + type=str, + required=True, + dest='sample', + help='Sample name: used to create output file names') + parser.add_argument('-t', '--truth', + type=str, + required=False, + default=None, + dest='truth_file', + help='Truth data path for simulated data (must be a ' + 'gsURL, i.e. "gs://bucket/path/file.h5")') + parser.add_argument('-f', '--fpr', + type=str, + required=False, + default="0.01", + dest='fpr', + help='FPR for CellBender') + parser.add_argument('-q', '--quiet', + action='store_true', + default=False, + dest='quiet', + help='Include this flag to avoid printing to stdout') + + return parser + + +def update_input_json(template_file: str, + substitutions: Dict[str, str], + tmpdir: tempfile.TemporaryDirectory, + verbose: bool = True) -> Tuple[str, str]: + """Create a new input json for a Cromwell run based on a template""" + + # read template into dict + with open(template_file, mode='r') as f: + template = json.load(f) + + # perform substitutions + for key, value in template.items(): + replacement = substitutions.get(value, '__absent') + template[key] = replacement if (replacement != '__absent') else value + + # write filled-in input json + json_inputs_file = os.path.join(tmpdir, 'inputs.json') + with open(json_inputs_file, mode='w') as f: + json.dump(template, f, indent=2) + + # write options json that disables call-caching + json_options_file = os.path.join(tmpdir, 'options.json') + options_dict = { + "write_to_cache": False, + "read_from_cache": False, + } + with open(json_options_file, mode='w') as f: + json.dump(options_dict, f, indent=2) + + if verbose: + print('Contents of inputs.json:') + subprocess.run(['cat', json_inputs_file]) + print('', end='\n') + + if verbose: + print('Contents of options.json:') + subprocess.run(['cat', json_options_file]) + print('', end='\n') + + return json_inputs_file, json_options_file + + +def cromshell_submit(wdl: str, + inputs: str, + options: str, + dependencies: List[str], + tmpdir: tempfile.TemporaryDirectory, + alias: Optional[str] = None, + verbose: bool = True) -> Tuple[str, str]: + """Submit job via cromshell and return the workflow-id and alias + + NOTE: the whole dependency zipping thing is way more difficult than it has + to be and took me hours. it is super fragile. but at least now I think I + can put this benchmark.wdl anywhere I want to. + """ + + # zip up dependencies + if verbose: + print('Zipping dependencies') + dependencies_zip = os.path.join(tmpdir, 'dependencies.zip') + dependencies_dir = tmpdir + for file in dependencies: + shutil.copy(file, dependencies_dir) + subprocess.run(['zip', '-j', dependencies_zip, + ' '.join([os.path.join(dependencies_dir, os.path.basename(f)) + for f in dependencies])]) + + # move WDL to tmpdir + tmp_wdl = os.path.join(tmpdir, os.path.basename(wdl)) + shutil.copy(wdl, tmp_wdl) + + submit_cmd = ['cromshell', 'submit', + tmp_wdl, + inputs, + options, + dependencies_zip] + + # submit job + if verbose: + print(f'Submitting WDL {tmp_wdl}') + current_path = os.getcwd() + os.chdir(tmpdir) + out = subprocess.run(submit_cmd) + os.chdir(current_path) + out.check_returncode() # error if this failed + + # get workflow-id + out = subprocess.run(['cromshell', 'status'], capture_output=True) + d = json.loads(out.stdout) + workflow_id = d.get('id') + + # alias job + if alias is not None: + # solve the issue where an alias cannot be made twice + hash = random.getrandbits(128) + alias = alias + '__runhash_' + str(hash)[:10] + subprocess.run(['cromshell', 'alias', '-1', alias]) + + return workflow_id, alias + + +if __name__ == '__main__': + + # handle input arguments + parser = get_parser() + args = parser.parse_args(sys.argv[1:]) + # args = validate_args(args) + + with tempfile.TemporaryDirectory() as tmpdir: + + # determine substitutions to be made in input json + substitutions = { + 'GIT_HASH': args.git_hash, + 'INPUT_GSURL': args.input_file, + 'SAMPLE_NAME': args.sample, + 'TRUTH_GSURL': args.truth_file, + 'FPR': args.fpr, + } + + # create the updated input json + inputs_json, options_json = update_input_json( + template_file='benchmark_inputs.json', + substitutions=substitutions, + tmpdir=tmpdir, + verbose=not args.quiet, + ) + + # get the path to the cellbender WDL + this_dir = os.path.dirname(os.path.abspath(__file__)) + cellbender_wdl_path = os.path.abspath(os.path.join( + this_dir, '..', '..', '..', '..', 'wdl', + 'cellbender_remove_background.wdl', + )) + + # run cromshell submit + if args.git_hash is not None: + alias = '_'.join(['cellbender', args.sample, args.git_hash]) + else: + alias = '_'.join(['cellbender', args.sample]) + workflow_id, alias = cromshell_submit( + wdl=os.path.join(this_dir, 'benchmark.wdl'), + inputs=inputs_json, + options=options_json, + dependencies=[cellbender_wdl_path], + alias=alias, + tmpdir=tmpdir, + ) + + # show workflow-id alias + if not args.quiet: + print('Sucessfully submitted job:') + if alias is not None: + print(alias) + print(workflow_id) + + sys.exit(0) diff --git a/cellbender/remove_background/tests/benchmarking/run_benchmark_result_tabulation.py b/cellbender/remove_background/tests/benchmarking/run_benchmark_result_tabulation.py new file mode 100644 index 00000000..ffc5e5a8 --- /dev/null +++ b/cellbender/remove_background/tests/benchmarking/run_benchmark_result_tabulation.py @@ -0,0 +1,146 @@ +"""Tabulate outputs from CellBender benchmarking as a samples.tsv for Terra +Example: + $ conda activate cromshell + $ python run_benchmark_result_tabulation.py \ + --workflows 2927346f4c513a217ac8ad076e494dd1adbf70e1 \ + --output "samples.tsv" +""" + +import pandas as pd +import os +import re +import sys +import subprocess +import argparse +from io import StringIO +from typing import Tuple, Dict, Optional, List, Union + + +def get_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + description="Create a Terra-compatible data table TSV from cromshell " + "benchmarking outputs.", + ) + parser.add_argument('-w', '--workflows', + type=str, + required=True, + dest='grep', + help='grep to choose workflows from the cromshell database') + parser.add_argument('-n', '--note', + type=str, + required=True, + dest='note', + help='Annotation describing the git commit') + parser.add_argument('-o', '--output', + type=str, + required=True, + dest='output_file', + help='Output TSV file') + + return parser + + +def find_cromshell_workflow_ids_dates(grep: str) -> Tuple[List[str], List[str]]: + """Find workflows in the cromshell database matching some string""" + + date_col = 0 + workflow_id_col = 2 + + # use cromshell list to get the database, then comb through it + out = subprocess.run(['cromshell', 'list'], capture_output=True) + s = out.stdout.decode() + _RE_COMBINE_WHITESPACE = re.compile(r"(?a: +)") + s = _RE_COMBINE_WHITESPACE.sub(" ", s).strip() + greps = grep.split(' ') # separately match all search elements (space delimited) + selected_rows = [r for r in s.split('\n') if all([g in r for g in greps])] + + for r in selected_rows: + if ('Succeeded' not in r): + print(f'WARNING: Skipping\n{r}\nbecause the run has not completed') + selected_rows = [r for r in selected_rows if ('Succeeded' in r)] + + workflow_ids = [r.split(' ')[workflow_id_col] for r in selected_rows] + dates = [r.split(' ')[date_col] for r in selected_rows] + + return workflow_ids, dates + + +def get_cromshell_output_h5(workflow: str, grep: str = '_out.h5') -> Union[str, List[str]]: + """Use cromshell list-outputs to get the relevant file gsURL""" + + output = grep_from_command(['cromshell', 'list-outputs', workflow], grep=grep) + out = output[:-1].decode().split('\n') + if len(out) > 1: + return out + else: + return out[0] + + +def sample_name_from_h5(h5: str) -> str: + """Get sample name by parsing h5 file name""" + return os.path.basename(h5).replace('_out.h5', '') + + +def grep_from_command(command: List[str], grep: str) -> bytes: + """Pipe a command to grep and give the output""" + ps = subprocess.Popen(command, stdout=subprocess.PIPE) + output = subprocess.check_output(['grep', grep], stdin=ps.stdout) + ps.wait() + return output + + +def metadata_from_workflow_id(workflow: str) -> Tuple[str, str, Optional[str]]: + """Get other metadata for a workflow id: git hash, input file, truth file""" + + # git hash + output = grep_from_command(['cromshell', 'metadata', workflow], + grep='"git_hash":') + git_hash = output[17:-3].decode() + + # input file + output = grep_from_command(['cromshell', 'metadata', workflow], + grep='run_cellbender_benchmark.cb.input_file_unfiltered') + input_file = output[58:-3].decode() + + # truth file + output = grep_from_command(['cromshell', 'metadata', workflow], + grep='run_cellbender_benchmark.cb.truth_file') + if 'null' not in output.decode(): + truth_file = output[47:-3].decode() + else: + truth_file = None + + return git_hash, input_file, truth_file + + +if __name__ == '__main__': + + # handle input arguments + parser = get_parser() + args = parser.parse_args(sys.argv[1:]) + # args = validate_args(args) + + workflow_ids, dates = find_cromshell_workflow_ids_dates(args.grep) + output_h5s = [get_cromshell_output_h5(id) for id in workflow_ids] + samples = [sample_name_from_h5(h5) for h5 in output_h5s] + list_of_tuples = [metadata_from_workflow_id(id) for id in workflow_ids] + if len(list_of_tuples) > 0: + git_hashes, input_h5s, truth_h5s = zip(*list_of_tuples) + + run_ids = [sample + '_' + git for sample, git in zip(samples, git_hashes)] + + df = pd.DataFrame(data={'entity:sample_id': run_ids, + 'git_commit': git_hashes, + 'sample': samples, + 'output_h5': output_h5s, + 'input_h5': input_h5s, + 'truth_h5': truth_h5s, + 'cromwell_workflow_id': workflow_ids, + 'date_time': dates, + 'note': args.note}) + + df.to_csv(args.output_file, sep='\t', index=False) + else: + print('No submissions selected') + + sys.exit(0) diff --git a/cellbender/remove_background/tests/benchmarking/run_usual_benchmarks.sh b/cellbender/remove_background/tests/benchmarking/run_usual_benchmarks.sh new file mode 100755 index 00000000..98c50f7a --- /dev/null +++ b/cellbender/remove_background/tests/benchmarking/run_usual_benchmarks.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +# Example run: +# $ ./run_usual_benchmarks.sh "v0.2.1" + +GIT_HASH=$1 + +# from the paper ========================== + +# 10x Genomics pbmc8k +python run_benchmark.py \ + --git $GIT_HASH \ + --input "gs://broad-dsde-methods-sfleming/cellbender_test/pbmc8k_raw_gene_bc_matrices.h5" \ + --sample "pbmc8k" + +# 10x Genomics hgmm12k +python run_benchmark.py \ + --git $GIT_HASH \ + --input "gs://broad-dsde-methods-sfleming/cellbender_test/hgmm_12k_raw_gene_bc_matrices.h5" \ + --sample "hgmm12k" + +# 10x Genomics pbmc5k CITE-seq +python run_benchmark.py \ + --git $GIT_HASH \ + --input "gs://broad-dsde-methods-sfleming/cellbender_test/5k_pbmc_protein_v3_nextgem_raw_feature_bc_matrix.h5" \ + --sample "pbmc5k" \ + --fpr "0.1" + +# Broad PCL rat6k +python run_benchmark.py \ + --git $GIT_HASH \ + --input "gs://broad-dsde-methods-sfleming/cellbender_test/PCL_rat_A_LA6_raw_feature_bc_matrix.h5" \ + --sample "rat6k" + +# Simulation s1 +python run_benchmark.py \ + --git $GIT_HASH \ + --input "gs://broad-dsde-methods-sfleming/cellbender_test/s1.h5" \ + --truth "gs://broad-dsde-methods-sfleming/cellbender_test/s1_truth.h5" \ + --sample "s1" + +# Simulation s4 +python run_benchmark.py \ + --git $GIT_HASH \ + --input "gs://broad-dsde-methods-sfleming/cellbender_test/s4.h5" \ + --truth "gs://broad-dsde-methods-sfleming/cellbender_test/s4_truth.h5" \ + --sample "s4" \ + --fpr "0.2" + +# Simulation s7, hgmm +python run_benchmark.py \ + --git $GIT_HASH \ + --input "gs://broad-dsde-methods-sfleming/cellbender_test/s7.h5" \ + --truth "gs://broad-dsde-methods-sfleming/cellbender_test/s7_truth.h5" \ + --sample "s7" + +# additional datasets ======================== + +# Broad PCL human PV dataset, hard time calling high-count cells in v0.2.0, wobbly learning curve +python run_benchmark.py \ + --git $GIT_HASH \ + --input "gs://broad-dsde-methods-sfleming/cellbender_test/PCL_human_PV_1817_ls.h5" \ + --sample "pv20k" + +python run_benchmark.py \ + --git $GIT_HASH \ + --input "gs://broad-dsde-methods-sfleming/cellbender_test/PCL_human_PV_1799_BPV.h5" \ + --sample "pv15k" + +# public data from Caroline Porter, high UMI count cells called empty +python run_benchmark.py \ + --git $GIT_HASH \ + --input "gs://broad-dsde-methods-sfleming/cellbender_test/cporter_20230331_N18_Epi_A.h5" \ + --sample "epi2k" diff --git a/cellbender/remove_background/tests/conftest.py b/cellbender/remove_background/tests/conftest.py new file mode 100644 index 00000000..8bafa2da --- /dev/null +++ b/cellbender/remove_background/tests/conftest.py @@ -0,0 +1,202 @@ +"""Test utility functions and session-scoped fixtures.""" + +import pytest +import scipy.sparse as sp +import numpy as np +import torch + +from cellbender.remove_background.data.extras.simulate import \ + generate_sample_dirichlet_dataset +from cellbender.remove_background.data.io import write_matrix_to_cellranger_h5 + +import shutil + + +USE_CUDA = torch.cuda.is_available() + + +def sparse_matrix_equal(mat1: sp.csc_matrix, + mat2: sp.csc_matrix): + """Fast assertion that sparse matrices are equal""" + return (mat1 != mat2).sum() == 0 + + +def tensors_equal(a: torch.Tensor, + b: torch.Tensor): + """Assertion that torch tensors are equal for each element""" + return (a == b).all() + + +def string_ndarray_equality(a: np.ndarray, b: np.ndarray) -> bool: + return (a.astype(str) == b.astype(str)).all() + + +class SavedFileH5: + def __init__(self, name, keys, version, shape, analyzed_shape=None, + local_keys=None, global_keys=None, meta_keys=None, barcodes_analyzed=None): + self.name = name + self.version = version + self.keys = keys + self.shape = shape + self.analyzed_shape = analyzed_shape + self.local_keys = local_keys + self.global_keys = global_keys + self.meta_keys = meta_keys + self.barcodes_analyzed = barcodes_analyzed + + def __repr__(self): + return f'Saved h5 file ({self.shape}) at {self.name} ' \ + f'(CellRanger v{self.version} with keys {self.keys})' + + +@pytest.fixture(scope='session') +def simulated_dataset(): + """Generate a small simulated dataset Dict once and make it visible to all tests""" + d = generate_sample_dirichlet_dataset( + n_droplets=100, + n_genes=1000, + chi_artificial_similarity=0.25, + cells_of_each_type=[10, 10, 10], + cell_mean_umi=[5000, 5000, 5000], + cell_lognormal_sigma=0.01, + empty_mean_umi=200, + empty_lognormal_sigma=0.01, + model_type='full', + dirichlet_alpha=0.05, + epsilon_param=20, + rho_alpha=4, + rho_beta=96, + random_seed=0, + ) + d['genomes'] = np.array(['simulated'] * d['gene_names'].size) + d['gene_ids'] = np.array(['ENSEMBLSIM000' + s for s in d['gene_names']]) + d['feature_types'] = np.array(['Gene Expression'] * (d['gene_names'].size - 50) + + ['Antibody Capture'] * 40 + + ['CRISPR Guide Capture'] * 5 + + ['Custom'] * 5) # a mix of types + d['matrix'] = (d['counts_true'] + d['counts_bkg']).tocsc() + return d + + +@pytest.fixture(scope='session') +def h5_v3_file(tmpdir_factory, simulated_dataset) -> 'SavedFileH5': + """Save an h5 file once and make it visible to all tests.""" + tmp_dir = tmpdir_factory.mktemp('data') + filename = tmp_dir.join('tmp_v3.h5') + cellranger_version = 3 + d = simulated_dataset + write_matrix_to_cellranger_h5( + output_file=filename, + gene_names=d['gene_names'], + gene_ids=d['gene_ids'], + feature_types=d['feature_types'], + genomes=d['genomes'], + barcodes=d['barcodes'], + count_matrix=d['matrix'], + cellranger_version=cellranger_version, + ) + yield SavedFileH5(name=filename, + keys=['gene_names', 'barcodes', 'genomes', 'gene_ids', 'feature_types'], + version=cellranger_version, + shape=d['matrix'].shape) + shutil.rmtree(str(tmp_dir)) + + +@pytest.fixture(scope='session') +def h5_v2_file(tmpdir_factory, simulated_dataset) -> 'SavedFileH5': + """Save an h5 file once and make it visible to all tests.""" + tmp_dir = tmpdir_factory.mktemp('data') + filename = tmp_dir.join('tmp_v2.h5') + cellranger_version = 2 + d = simulated_dataset + write_matrix_to_cellranger_h5( + output_file=filename, + gene_names=d['gene_names'], + gene_ids=d['gene_ids'], + # feature_types=d['feature_types'], + # genomes=d['genomes'], + barcodes=d['barcodes'], + count_matrix=d['matrix'], + cellranger_version=cellranger_version, + ) + yield SavedFileH5(name=filename, + keys=['gene_names', 'barcodes', 'gene_ids'], + version=cellranger_version, + shape=d['matrix'].shape) + shutil.rmtree(str(tmp_dir)) + + +@pytest.fixture(scope='session') +def h5_v2_file_missing_ids(tmpdir_factory, simulated_dataset) -> 'SavedFileH5': + """Save an h5 file once and make it visible to all tests.""" + tmp_dir = tmpdir_factory.mktemp('data') + filename = tmp_dir.join('tmp_v2.h5') + cellranger_version = 2 + d = simulated_dataset + write_matrix_to_cellranger_h5( + output_file=filename, + gene_names=d['gene_names'], + # gene_ids=d['gene_ids'], + # feature_types=d['feature_types'], + # genomes=d['genomes'], + barcodes=d['barcodes'], + count_matrix=d['matrix'], + cellranger_version=cellranger_version, + ) + yield SavedFileH5(name=filename, + keys=['gene_names', 'barcodes'], + version=cellranger_version, + shape=d['matrix'].shape) + shutil.rmtree(str(tmp_dir)) + + +@pytest.fixture(scope='session', params=[2, 3]) +def h5_file(request, h5_v2_file, h5_v3_file): + if request.param == 2: + return h5_v2_file + elif request.param == 3: + return h5_v3_file + else: + raise ValueError(f'Test error: requested v{request.param} h5 file') + + +@pytest.fixture(scope='session') +def h5_v3_file_post_inference(tmpdir_factory, simulated_dataset) -> 'SavedFileH5': + """Save an h5 file once and make it visible to all tests.""" + tmp_dir = tmpdir_factory.mktemp('data') + filename = tmp_dir.join('tmp_v3_inferred.h5') + cellranger_version = 3 + d = simulated_dataset + + barcodes_analyzed = 50 + + write_matrix_to_cellranger_h5( + output_file=filename, + gene_names=d['gene_names'], + gene_ids=d['gene_ids'], + feature_types=d['feature_types'], + genomes=d['genomes'], + barcodes=d['barcodes'], + count_matrix=d['matrix'], + cellranger_version=cellranger_version, + local_latents={'barcode_indices_for_latents': np.arange(0, barcodes_analyzed), + 'gene_expression_encoding': np.random.rand(barcodes_analyzed, 10), + 'cell_probability': np.random.rand(barcodes_analyzed), + 'd': np.random.rand(barcodes_analyzed) + 5.}, + global_latents={'global_var1': np.array([1, 2, 3])}, + metadata={'metadata1': np.array(0.9), + 'metadata2': {'key1': 'val1', 'key2': {'a': 'val2', 'b': 'val3'}}, + 'metadata3': None, + 'metadata4': 0.5, + 'metadata5': 'text'}, + ) + yield SavedFileH5(name=filename, + keys=['gene_names', 'barcodes', 'genomes', 'gene_ids', 'feature_types'], + version=cellranger_version, + shape=d['matrix'].shape, + analyzed_shape=(barcodes_analyzed, d['matrix'].shape[1]), + local_keys=['d', 'cell_probability', 'gene_expression_encoding'], + global_keys=['global_var1'], + meta_keys=['metadata1'], + barcodes_analyzed=barcodes_analyzed) + shutil.rmtree(str(tmp_dir)) diff --git a/cellbender/remove_background/tests/mckp_memory_profiling.py b/cellbender/remove_background/tests/mckp_memory_profiling.py new file mode 100644 index 00000000..fe6e831d --- /dev/null +++ b/cellbender/remove_background/tests/mckp_memory_profiling.py @@ -0,0 +1,146 @@ +"""Script to enable memory usage profiling via memory-profiler""" + +from cellbender.remove_background.estimation import MultipleChoiceKnapsack +from cellbender.remove_background.sparse_utils import csr_set_rows_to_zero +from cellbender.remove_background.checkpoint import load_from_checkpoint +from cellbender.remove_background.posterior import Posterior, \ + compute_mean_target_removal_as_function +from cellbender.remove_background.data.dataset import SingleCellRNACountsDataset +from cellbender.remove_background import consts + +import scipy.sparse as sp +import numpy as np +from memory_profiler import profile + +import argparse +import sys + + +def get_parser() -> argparse.ArgumentParser: + parser_ = argparse.ArgumentParser( + description="Run memory profiling on output count matrix generation. " + "NOTE that you have to decorate " + "MultipleChoiceKnapsack.estimate_noise() with memory_profiler's " + "@profile() decorator manually.", + ) + parser_.add_argument('-f', '--checkpoint-file', + type=str, + required=True, + dest='input_checkpoint_tarball', + help='Saved CellBender checkpoint file ckpt.tar.gz') + parser_.add_argument('-i', '--input', + type=str, + required=True, + dest='input_file', + help='Input data file') + return parser_ + + +def compute_noise_counts(posterior, + fpr: float, + estimator_constructor: 'EstimationMethod', + **kwargs) -> sp.csr_matrix: + """Probably the most important method: computation of the clean output count matrix. + + Args: + estimator_constructor: A noise count estimator class derived from + the EstimationMethod base class, and implementing the + .estimate_noise() method, which creates a point estimate of + noise. Pass in the constructor, not an object. + **kwargs: Keyword arguments for estimator_constructor().estimate_noise() + + Returns: + denoised_counts: Denoised output CSC sparse matrix (CSC for saving) + + """ + + # Only compute using defaults if the cache is empty. + if posterior._noise_count_regularized_posterior_coo is not None: + # Priority is taken by a regularized posterior, since presumably + # the user computed it for a reason. + posterior_coo = posterior._noise_count_regularized_posterior_coo + else: + # Use exact posterior if a regularized version is not computed. + posterior_coo = (posterior._noise_count_posterior_coo + if (posterior._noise_count_posterior_coo is not None) + else posterior.cell_noise_count_posterior_coo()) + + # Instantiate Estimator object. + estimator = estimator_constructor(index_converter=posterior.index_converter) + + # Compute point estimate of noise in cells. + noise_targets = get_noise_targets(posterior=posterior, fpr=fpr) + noise_csr = estimator.estimate_noise( + estimator=estimator, + noise_log_prob_coo=posterior_coo, + noise_offsets=posterior._noise_count_posterior_coo_offsets, + noise_targets_per_gene=noise_targets, + **kwargs, + ) + + return noise_csr + + +def get_noise_targets(posterior, fpr=0.01): + count_matrix = posterior.dataset_obj.data['matrix'] # all barcodes + cell_inds = posterior.dataset_obj.analyzed_barcode_inds[posterior.latents_map['p'] + > consts.CELL_PROB_CUTOFF] + non_cell_row_logic = np.array([i not in cell_inds + for i in range(count_matrix.shape[0])]) + cell_counts = csr_set_rows_to_zero(csr=count_matrix, row_logic=non_cell_row_logic) + + noise_target_fun_per_cell = compute_mean_target_removal_as_function( + noise_count_posterior_coo=posterior._noise_count_posterior_coo, + noise_offsets=posterior._noise_count_posterior_coo_offsets, + index_converter=posterior.index_converter, + raw_count_csr_for_cells=cell_counts, + n_cells=len(cell_inds), + device='cpu', + per_gene=True, + ) + noise_target_fun = lambda x: noise_target_fun_per_cell(x) * len(cell_inds) + noise_targets = noise_target_fun(fpr).detach().cpu().numpy() + return noise_targets + + +if __name__ == "__main__": + + # handle input arguments + parser = get_parser() + args = parser.parse_args(sys.argv[1:]) + + # load checkpoint + ckpt = load_from_checkpoint(tarball_name=args.input_checkpoint_tarball, + filebase=None, + to_load=['model', 'posterior', 'args'], + force_device='cpu') + + # load dataset + dataset_obj = \ + SingleCellRNACountsDataset(input_file=args.input_file, + expected_cell_count=ckpt['args'].expected_cell_count, + total_droplet_barcodes=ckpt['args'].total_droplets, + fraction_empties=ckpt['args'].fraction_empties, + model_name=ckpt['args'].model, + gene_blacklist=ckpt['args'].blacklisted_genes, + exclude_features=ckpt['args'].exclude_features, + low_count_threshold=ckpt['args'].low_count_threshold, + ambient_counts_in_cells_low_limit=ckpt['args'].ambient_counts_in_cells_low_limit, + fpr=ckpt['args'].fpr) + + # load posterior + posterior = Posterior( + dataset_obj=dataset_obj, + vi_model=ckpt['model'], + posterior_batch_size=ckpt['args'].posterior_batch_size, + debug=False, + ) + posterior.load(file=ckpt['posterior_file']) + + # run output count matrix generation + compute_noise_counts(posterior=posterior, + fpr=0.01, + estimator_constructor=MultipleChoiceKnapsack, + approx_gb=0.1) + + sys.exit(0) diff --git a/cellbender/remove_background/tests/miniwdl_check_wdl.sh b/cellbender/remove_background/tests/miniwdl_check_wdl.sh new file mode 100755 index 00000000..2da9ad83 --- /dev/null +++ b/cellbender/remove_background/tests/miniwdl_check_wdl.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +set -euxo pipefail + +# runs from the root directory of the repo + +# find all WDL files +# WDL_FILES=$(find . -type f -name "*.wdl") +WDL_FILES=("./wdl/cellbender_remove_background.wdl") + +for WDL in ${WDL_FILES}; do + miniwdl check ${WDL} +done \ No newline at end of file diff --git a/cellbender/remove_background/tests/test.py b/cellbender/remove_background/tests/test.py deleted file mode 100644 index 5f72ec8e..00000000 --- a/cellbender/remove_background/tests/test.py +++ /dev/null @@ -1,193 +0,0 @@ -import unittest -import os -import warnings - -import cellbender -import cellbender.remove_background.model -from cellbender.remove_background.train import run_inference -from cellbender.remove_background.data.extras.simulate import \ - simulate_dataset_with_ambient_rna -from cellbender.remove_background.data.dataset import \ - SingleCellRNACountsDataset, write_matrix_to_cellranger_h5, \ - get_matrix_from_cellranger_h5, get_matrix_from_anndata -import numpy as np -import anndata -import sys - - -class TestConsole(unittest.TestCase): - - def test_data_simulation_and_write_and_read(self): - """Run basic tests of data simulation and read and write functionality. - - Test the ability to read/write data to/from an HDF5 file using pytables. - This necessitates creating a small simulated dataset, writing it to - a temporary file, reading the file back in, and deleting the - temporary file. - - """ - - try: - - # This is here to suppress the numpy warning triggered by - # scipy.sparse. - warnings.simplefilter("ignore") - - # Generate a simulated dataset with ambient RNA. - n_cells = 100 - csr_barcode_gene_synthetic, _, chi, _ = \ - simulate_dataset_with_ambient_rna(n_cells=n_cells, - n_empty=3 * n_cells, - clusters=1, n_genes=1000, - d_cell=2000, d_empty=100, - ambient_different=False) - - # Generate some names for genes and barcodes. - gene_names = np.array([f'g_{i}' for i in - range(csr_barcode_gene_synthetic.shape[1])]) - barcode_names = \ - np.array([f'bc_{i}' for i in - range(csr_barcode_gene_synthetic.shape[0])]) - - # Save the data to a temporary cellranger h5 file. - temp_file_name = 'testfile.h5' - write_matrix_to_cellranger_h5(cellranger_version=3, - output_file=temp_file_name, - loss=None, - gene_names=gene_names, - barcodes=barcode_names, - inferred_count_matrix= - csr_barcode_gene_synthetic.tocsc(), - ambient_expression=chi[0, :]) - - # Save the data to a temporary AnnData file. - temp_h5ad_name = 'testfile.h5ad' - temp_adata = anndata.AnnData( - X=csr_barcode_gene_synthetic, - ) - temp_adata.var_names = gene_names - temp_adata.obs_names = barcode_names - temp_adata.write_h5ad(temp_h5ad_name) - - # Read the data back in. - reconstructed = get_matrix_from_cellranger_h5(temp_file_name) - new_matrix = reconstructed['matrix'] - - # Check that the data matches. - assert (csr_barcode_gene_synthetic.sum(axis=1) == - new_matrix.sum(axis=1)).all(), \ - "Saved and re-opened data is not accurate." - assert (csr_barcode_gene_synthetic.sum(axis=0) == - new_matrix.sum(axis=0)).all(), \ - "Saved and re-opened data is not accurate." - - # Remove the temporary file. - os.remove(temp_file_name) - - # Check that anndata matches. - reconstructed_h5ad = get_matrix_from_anndata(temp_h5ad_name) - matrix_h5ad = reconstructed_h5ad['matrix'] - assert (csr_barcode_gene_synthetic.sum(axis=1) == - matrix_h5ad.sum(axis=1)).all(), \ - "Saved and re-opened AnnData is not accurate." - assert (csr_barcode_gene_synthetic.sum(axis=0) == - matrix_h5ad.sum(axis=0)).all(), \ - "Saved and re-opened AnnData is not accurate." - - os.remove(temp_h5ad_name) - - return 1 - - except TestConsole.failureException: - - return 0 - - def test_inference(self): - """Run a basic tests doing inference on a synthetic dataset. - - Runs the inference procedure on CPU. - - """ - - try: - - n_cells = 100 - - # Generate a simulated dataset with ambient RNA. - csr_barcode_gene_synthetic, _, _, _ = \ - simulate_dataset_with_ambient_rna(n_cells=n_cells, - n_empty=3 * n_cells, - clusters=1, n_genes=1000, - d_cell=2000, d_empty=100, - ambient_different=False) - - # Fake some parsed command line inputs. - args = ObjectWithAttributes() - args.use_cuda = False - args.z_hidden_dims = [100] - args.d_hidden_dims = [10, 2] - args.p_hidden_dims = [100, 10] - args.z_dim = 10 - args.learning_rate = 0.001 - args.epochs = 10 - args.model = "full" - args.fraction_empties = 0.5 - args.use_jit = True - args.training_fraction = 0.9 - - args.expected_cell_count = n_cells - - # Wrap simulated count matrix in a Dataset object. - dataset_obj = SingleCellRNACountsDataset() - dataset_obj.data = \ - {'matrix': csr_barcode_gene_synthetic, - 'gene_names': - np.array([f'g{n}' for n in - range(csr_barcode_gene_synthetic.shape[1])]), - 'barcodes': - np.array([f'bc{n}' for n in - range(csr_barcode_gene_synthetic.shape[0])])} - dataset_obj.priors['n_cells'] = n_cells - dataset_obj._trim_dataset_for_analysis() - dataset_obj._estimate_priors() - - # Run inference on this simulated dataset. - inferred_model = run_inference(dataset_obj, args) - - # Get encodings from the trained model. - z, d, p = cellbender.remove_background.model.\ - get_encodings(inferred_model, dataset_obj) - - # Make the background-subtracted dataset. - inferred_count_matrix = cellbender.remove_background.model.\ - generate_maximum_a_posteriori_count_matrix(z, d, p, - inferred_model, - dataset_obj) - - # Get the inferred background RNA expression from the model. - ambient_expression = cellbender.remove_background.model.\ - get_ambient_expression_from_pyro_param_store() - - return 1 - - except TestConsole.failureException: - - return 0 - - -class ObjectWithAttributes(object): - """Exists only to populate the args data structure with attributes.""" - pass - - -def main(): - """Run unit tests.""" - - tester = TestConsole() - - passed_tests = 0 - - passed_tests += tester.test_data_simulation_and_write_and_read() - passed_tests += tester.test_inference() - - sys.stdout.write(f'Passed {passed_tests} of 2 tests.\n\n') diff --git a/cellbender/remove_background/tests/test_checkpoint.py b/cellbender/remove_background/tests/test_checkpoint.py new file mode 100644 index 00000000..59ccb9ec --- /dev/null +++ b/cellbender/remove_background/tests/test_checkpoint.py @@ -0,0 +1,626 @@ +"""Tests for checkpointing functions.""" + +import pytest +import random +import numpy as np +import torch +from torch.distributions import constraints +import pyro +import pyro.optim as optim + +import cellbender +from cellbender.remove_background.checkpoint import make_tarball, unpack_tarball, \ + create_workflow_hashcode, save_checkpoint, load_checkpoint, \ + save_random_state, load_random_state +from cellbender.remove_background.vae.encoder import EncodeZ, EncodeNonZLatents, \ + CompositeEncoder +from cellbender.remove_background.vae.decoder import Decoder +from cellbender.remove_background.data.extras.simulate import \ + generate_sample_dirichlet_dataset, get_dataset_dict_as_anndata +from cellbender.remove_background.data.dataprep import prep_sparse_data_for_training +from cellbender.remove_background.model import RemoveBackgroundPyroModel +from cellbender.remove_background.data.dataset import SingleCellRNACountsDataset +from cellbender.remove_background.run import run_inference +from .conftest import USE_CUDA + +import os +import argparse +import shutil +import subprocess +from typing import List + + +class RandomState: + def __init__(self, use_cuda=False): + self.python = random.randint(0, 100000) + self.numpy = np.random.randint(0, 100000, size=1).item() + self.torch = torch.randint(low=0, high=100000, size=[1], device='cpu').item() + self.use_cuda = use_cuda + if self.use_cuda: + self.cuda = torch.randint(low=0, high=100000, size=[1], device='cuda').item() + + def __repr__(self): + if self.use_cuda: + return f'python {self.python}; numpy {self.numpy}; torch {self.torch}; torch_cuda {self.cuda}' + else: + return f'python {self.python}; numpy {self.numpy}; torch {self.torch}' + + +def test_create_workflow_hashcode(): + """Ensure workflow hashcodes are behaving as expected""" + + tmp_args1 = argparse.Namespace(epochs=100, expected_cells=1000, use_cuda=True) + tmp_args2 = argparse.Namespace(epochs=200, expected_cells=1000, use_cuda=True) + tmp_args3 = argparse.Namespace(epochs=100, expected_cells=500, use_cuda=True) + hashcode1 = create_workflow_hashcode(module_path=os.path.dirname(cellbender.__file__), + args=tmp_args1) + hashcode2 = create_workflow_hashcode(module_path=os.path.dirname(cellbender.__file__), + args=tmp_args2) + hashcode3 = create_workflow_hashcode(module_path=os.path.dirname(cellbender.__file__), + args=tmp_args3) + + # make sure it changes for different arguments + assert hashcode1 != hashcode3 + + # but that the "epochs" argument has no effect + assert hashcode1 == hashcode2 + + +def create_random_state_blank_slate(seed, use_cuda=USE_CUDA): + """Establish a base random state + https://pytorch.org/docs/stable/notes/randomness.html + """ + random.seed(seed) + np.random.seed(seed) + torch.manual_seed(seed) + pyro.util.set_rng_seed(seed) + if use_cuda: + torch.cuda.manual_seed_all(seed) + + +def perturb_random_state(n, use_cuda=USE_CUDA): + """Perturb the base random state by drawing random numbers""" + for _ in range(n): + random.randint(0, 10) + np.random.randint(0, 10, 1) + torch.randn((1,), device='cpu') + if use_cuda: + torch.randn((1,), device='cuda') + + +@pytest.fixture(scope='function', params=[0, 1, 1234], ids=lambda x: f'seed{x}') +def random_state_blank_slate(request): + create_random_state_blank_slate(request.param) + return request.param + + +@pytest.fixture(scope='function', params=[0, 1, 10]) +def perturbed_random_state_dict(request, random_state_blank_slate): + perturb_random_state(request.param) + return {'state': RandomState(), + 'seed': random_state_blank_slate, + 'n': request.param} + + +@pytest.fixture(scope='function', params=[0], ids=lambda x: f'setseed{x}') +def random_state_blank_slate0(request): + create_random_state_blank_slate(request.param) + return request.param + + +@pytest.fixture(scope='function', params=[10], ids=lambda x: f'set{x}') +def perturbed_random_state0_dict(request, random_state_blank_slate0): + perturb_random_state(request.param) + return {'state': RandomState(), + 'seed': random_state_blank_slate0, + 'n': request.param} + + +def test_perturbedrandomstate_fixture_meets_expectations(perturbed_random_state0_dict, + perturbed_random_state_dict): + """Test the setup of these randomstate fixtures. + + The state0 fixture is one set of params. + The state fixture is a combinatorial set of params, only one of which matches + the state0 setup. + + We want to make sure that when we have fixtures set up the same way, then + randomness behaves the same (and different when set up differently). + """ + prs = perturbed_random_state_dict['state'] + params = (perturbed_random_state_dict['seed'], perturbed_random_state_dict['n']) + prs0 = perturbed_random_state0_dict['state'] + params0 = (perturbed_random_state0_dict['seed'], perturbed_random_state0_dict['n']) + + if params == params0: + # this is the only case in which we expect the two random states to be equal + assert str(prs0) == str(prs) + else: + assert str(prs0) != str(prs) + + +def test_that_randomstate_plus_perturb_gives_perturbedrandomstate( + perturbed_random_state0_dict): + """Make sure perturbation is working as intended""" + + # recreate and make sure we end up in the same place + # the "recipe" is in perturbed_random_state0_tuple[1] + create_random_state_blank_slate(perturbed_random_state0_dict['seed']) + perturb_random_state(perturbed_random_state0_dict['n']) + this_prs0 = RandomState() + + # check equality + prs0 = perturbed_random_state0_dict['state'] + assert str(prs0) == str(this_prs0) + + +@pytest.mark.parametrize('cuda', + [False, + pytest.param(True, marks=pytest.mark.skipif(not USE_CUDA, + reason='requires CUDA'))], + ids=lambda b: 'cuda' if b else 'cpu') +def test_save_and_load_random_state(tmpdir_factory, perturbed_random_state_dict, cuda): + """Test whether random states are being preserved correctly. + perturbed_random_state_dict is important since it initializes the state.""" + + # save the random states + filebase = tmpdir_factory.mktemp('random_states').join('tmp_checkpoint') + save_random_state(filebase=filebase) + + # see "what would have happened had we continued" + counterfactual = RandomState(use_cuda=cuda) + incorrect = RandomState(use_cuda=cuda) # a second draw + + # load the random states and check random number generators + load_random_state(filebase=filebase) + actual = RandomState(use_cuda=cuda) + + # check equality + assert str(counterfactual) == str(actual) + assert str(incorrect) != str(actual) + + +def new_train_loader(data: torch.Tensor, batch_size: int, shuffle: bool = True): + return torch.utils.data.DataLoader(data, batch_size=batch_size, shuffle=shuffle) + + +class PyroModel(torch.nn.Module): + + def __init__(self, dim=8, hidden_layer=4, z_dim=2): + super(PyroModel, self).__init__() + create_random_state_blank_slate(0) + pyro.clear_param_store() + self.encoder = EncodeZ(input_dim=dim, hidden_dims=[hidden_layer], output_dim=z_dim) + self.decoder = Decoder(input_dim=z_dim, hidden_dims=[hidden_layer], output_dim=dim) + self.z_dim = z_dim + self.use_cuda = torch.cuda.is_available() + self.normal = pyro.distributions.Normal + self.loss = [] + # self.to(device='cuda' if self.use_cuda else 'cpu') # CUDA not tested + + def model(self, x: torch.FloatTensor): + pyro.module("decoder", self.decoder, update_module_params=True) + with pyro.plate('plate', size=x.shape[0]): + z = pyro.sample('z', self.normal(loc=0., scale=1.).expand_by([x.shape[0], self.z_dim]).to_event(1)) + x_rec = self.decoder(z) + pyro.sample('obs', self.normal(loc=x_rec, scale=0.1).to_event(1), obs=x) + + def guide(self, x: torch.FloatTensor): + pyro.module("encoder", self.encoder, update_module_params=True) + with pyro.plate('plate', size=x.shape[0]): + enc = self.encoder(x) + pyro.sample('z', self.normal(loc=enc['loc'], scale=enc['scale']).to_event(1)) + + +def train_pyro(n_epochs: int, + data_loader: torch.utils.data.DataLoader, + svi: pyro.infer.SVI): + """Run training""" + loss_per_epoch = [] + for _ in range(n_epochs): + loss = 0 + norm = 0 + for data in data_loader: + loss += svi.step(data) + norm += data.size(0) + loss_per_epoch.append(loss / norm) + return loss_per_epoch + + +def _check_all_close(tensors1, tensors2) -> bool: + """For two lists of tensors, check that they are all close""" + assert len(tensors1) == len(tensors2), \ + 'Must pass in same number of tensors to check if they are equal' + equal = True + for t1, t2 in zip(tensors1, tensors2): + equal = equal and torch.allclose(t1, t2) + return equal + + +def _get_params(module: torch.nn.Module) -> List[torch.Tensor]: + return [p.data.clone() for p in module.parameters()] + + +@pytest.mark.parametrize('batch_size_n', [32, 128], ids=lambda n: f'batch{n}') +def test_save_and_load_pyro_checkpoint(tmpdir_factory, batch_size_n): + """Check and see if restarting from a checkpoint picks up in the same place + we left off. Use a dataloader. + """ + + filedir = tmpdir_factory.mktemp('ckpt') + filebase = filedir.join('ckpt') + dim = 8 + epochs = 3 + epochs2 = 3 + lr = 1e-2 + + # data and dataloader + dataset = torch.randn((128, dim)) + train_loader = new_train_loader(data=dataset, batch_size=batch_size_n) + + # create an ML model + initial_model = PyroModel(dim=dim) + + # set up the inference process + scheduler = optim.ClippedAdam({'lr': lr, 'clip_norm': 10.}) + svi = pyro.infer.SVI(initial_model.model, initial_model.guide, scheduler, loss=pyro.infer.Trace_ELBO()) + w1 = _get_params(initial_model.encoder) + + print('initial weight matrix =========================') + print('\n'.join([str(t) for t in w1])) + + # train in two parts: part 1 + initial_model.loss.extend(train_pyro(n_epochs=epochs, data_loader=train_loader, svi=svi)) + + print('no_ckpt trained round 1 (saved) ===============') + # print(initial_model.encoder.linears[0].weight.data) + print('\n'.join([str(t) for t in _get_params(initial_model.encoder)])) + + # save + save_successful = save_checkpoint(filebase=str(filebase), + args=argparse.Namespace(), + model_obj=initial_model, # TODO + scheduler=scheduler, + train_loader=train_loader, + tarball_name=str(filebase) + '.tar.gz') + assert save_successful, 'Failed to save checkpoint during test_save_and_load_checkpoint' + + # load from checkpoint + create_random_state_blank_slate(0) + pyro.clear_param_store() + ckpt = load_checkpoint(filebase=str(filebase), + tarball_name=str(filebase) + '.tar.gz', + force_device='cpu') + model_ckpt = ckpt['model'] + scheduler_ckpt = ckpt['optim'] + train_loader = ckpt['train_loader'] + s = ckpt['loaded'] + print('model_ckpt loaded =============================') + print('\n'.join([str(t) for t in _get_params(model_ckpt.encoder)])) + + matches = _check_all_close(_get_params(model_ckpt.encoder), + _get_params(initial_model.encoder)) + print(f'model_ckpt loaded matches data from (saved) trained round 1: {matches}') + + # clean up before most assertions... hokey now due to lack of fixture usage here + shutil.rmtree(str(filedir)) + + # and continue training + assert s is True, 'Checkpoint loading failed during test_save_and_load_checkpoint' + svi_ckpt = pyro.infer.SVI(model_ckpt.model, model_ckpt.guide, scheduler_ckpt, loss=pyro.infer.Trace_ELBO()) + rng_ckpt = RandomState() + guide_trace_ckpt = pyro.poutine.trace(svi_ckpt.guide).get_trace(x=dataset) + model_ckpt.loss.extend(train_pyro(n_epochs=epochs2, data_loader=train_loader, svi=svi_ckpt)) + + print('model_ckpt after round 2 ======================') + print('\n'.join([str(t) for t in _get_params(model_ckpt.encoder)])) + + # one-shot training straight through + model_one_shot = PyroModel(dim=dim) # resets random state + scheduler = optim.ClippedAdam({'lr': lr, 'clip_norm': 10.}) + train_loader = new_train_loader(data=dataset, batch_size=batch_size_n) + svi_one_shot = pyro.infer.SVI(model_one_shot.model, model_one_shot.guide, scheduler, loss=pyro.infer.Trace_ELBO()) + model_one_shot.loss.extend(train_pyro(n_epochs=epochs, data_loader=train_loader, svi=svi_one_shot)) + rng_one_shot = RandomState() + guide_trace_one_shot = pyro.poutine.trace(svi_one_shot.guide).get_trace(x=dataset) + model_one_shot.loss.extend(train_pyro(n_epochs=epochs2, data_loader=train_loader, svi=svi_one_shot)) + + assert str(rng_one_shot) == str(rng_ckpt), \ + 'Random states of the checkpointed and non-checkpointed versions at ' \ + 'the start of training round 2 do not match.' + + print('model_one_shot ================================') + print('\n'.join([str(t) for t in _get_params(model_one_shot.encoder)])) + + print(model_one_shot.loss) + print(model_ckpt.loss) + print([l1 == l2 for l1, l2 in zip(model_one_shot.loss, model_ckpt.loss)]) + + # training should be doing something to the initial weight matrix + assert (w1[0] != _get_params(model_one_shot.encoder)[0]).sum().item() > 0, \ + 'Training is not changing the weight matrix in test_save_and_load_checkpoint' + assert (w1[0] != _get_params(model_ckpt.encoder)[0]).sum().item() > 0, \ + 'Training is not changing the checkpointed weight matrix in test_save_and_load_checkpoint' + + # see if we end up where we should + assert _check_all_close(_get_params(model_one_shot.encoder), + _get_params(model_ckpt.encoder)), \ + 'Checkpointed restart does not agree with one-shot training' + + # check guide traces + print('checking guide trace nodes for agreement:') + for name in guide_trace_one_shot.nodes: + if (name != '_RETURN') and ('value' in guide_trace_one_shot.nodes[name].keys()): + print(name) + disagreement = (guide_trace_one_shot.nodes[name]['value'].data + != guide_trace_ckpt.nodes[name]['value'].data).sum() + print(f'number of values that disagree: {disagreement}') + assert disagreement == 0, \ + 'Guide traces disagree with and without checkpoint restart' + + +@pytest.mark.parametrize('cuda', + [False, + pytest.param(True, marks=pytest.mark.skipif(not USE_CUDA, + reason='requires CUDA'))], + ids=lambda b: 'cuda' if b else 'cpu') +@pytest.mark.parametrize('scheduler', + [False, True], + ids=lambda b: 'OneCycleLR' if b else 'Adam') +def test_save_and_load_cellbender_checkpoint(tmpdir_factory, cuda, scheduler): + """Check and see if restarting from a checkpoint picks up in the same place + we left off. Use our model and dataloader. + """ + + filedir = tmpdir_factory.mktemp('ckpt') + + epochs = 5 + epochs2 = 5 + + # data + n_genes = 2000 + dataset = generate_sample_dirichlet_dataset(n_genes=n_genes, cells_of_each_type=[100], + n_droplets=2000, model_type='ambient', + cell_mean_umi=[5000]) + adata = get_dataset_dict_as_anndata(dataset) + adata_file = os.path.join(filedir, 'sim.h5ad') + adata.write(adata_file) + dataset_obj = \ + SingleCellRNACountsDataset(input_file=adata_file, + expected_cell_count=100, + total_droplet_barcodes=1000, + fraction_empties=0.1, + model_name='ambient', + gene_blacklist=[], + exclude_features=[], + low_count_threshold=15, + fpr=[0.01]) + + # set up the inference process + args = argparse.Namespace() + args.output_file = os.path.join(filedir, 'out.h5') + args.z_dim = 10 + args.z_hidden_dims = [50] + args.model = 'ambient' + args.use_cuda = cuda + args.use_jit = False + args.learning_rate = 1e-3 + args.training_fraction = 0.9 + args.fraction_empties = 0.1 + args.checkpoint_filename = 'test01234_' + args.checkpoint_min = 5 + args.epoch_elbo_fail_fraction = None + args.final_elbo_fail_fraction = None + args.constant_learning_rate = not scheduler + args.debug = False + args.input_checkpoint_tarball = 'none' + + create_random_state_blank_slate(0) + pyro.clear_param_store() + args.epochs = -1 # I am hacking my way around an error induced by saving a checkpoint for 0 epoch runs + initial_model, scheduler, _, _ = run_inference(dataset_obj=dataset_obj, + args=args) + w1 = _get_params(initial_model.encoder['z']) + print('encoder structure ============') + print(initial_model.encoder['z']) + + print('initial weight matrix =========================') + print('\n'.join([str(t) for t in w1])) + + # train in two parts: part 1 + pyro.clear_param_store() + create_random_state_blank_slate(0) + args.epochs = epochs + initial_model, scheduler, train_loader, test_loader = \ + run_inference(dataset_obj=dataset_obj, args=args, + output_checkpoint_tarball='none', + total_epochs_for_testing_only=epochs + epochs2) + + print('no_ckpt trained round 1 (saved) ===============') + print('\n'.join([str(t) for t in _get_params(initial_model.encoder['z'])])) + # print(scheduler.get_state().keys()) + # print(list(scheduler.get_state().values())[0].keys()) + # print(list(list(scheduler.optim_objs.values())[0].optimizer.state_dict().values())[0].values()) + # assert 0 + + # save + hashcode = create_workflow_hashcode(module_path=os.path.dirname(cellbender.__file__), + args=args)[:10] + checkpoint_filename = os.path.basename(args.output_file).split('.')[0] + '_' + hashcode + args.checkpoint_filename = checkpoint_filename + filebase = filedir.join(checkpoint_filename) + save_successful = save_checkpoint(filebase=str(filebase), + args=args, + model_obj=initial_model, # TODO + scheduler=scheduler, + tarball_name=str(filebase) + '.tar.gz', + train_loader=train_loader, + test_loader=test_loader) + assert save_successful, 'Failed to save checkpoint during test_save_and_load_checkpoint' + assert os.path.exists(str(filebase) + '.tar.gz'), 'Checkpoint should exist but does not' + + # load from checkpoint (automatically) and run + pyro.clear_param_store() + create_random_state_blank_slate(0) + args.epochs = -1 + args.input_checkpoint_tarball = str(filebase) + '.tar.gz' + model_ckpt, scheduler, _, _ = run_inference(dataset_obj=dataset_obj, args=args, + output_checkpoint_tarball='none') + + print('model_ckpt loaded =============================') + print('\n'.join([str(t) for t in _get_params(model_ckpt.encoder['z'])])) + + matches = _check_all_close(_get_params(model_ckpt.encoder['z']), + _get_params(initial_model.encoder['z'])) + print(f'model_ckpt loaded matches data from (saved) trained round 1: {matches}') + + # and continue training + create_random_state_blank_slate(0) + pyro.clear_param_store() + args.epochs = epochs + epochs2 + model_ckpt, scheduler, _, _ = run_inference(dataset_obj=dataset_obj, args=args, + output_checkpoint_tarball='none') + + print('model_ckpt after round 2 ======================') + print('\n'.join([str(t) for t in _get_params(model_ckpt.encoder['z'])])) + + # clean up the temp directory to remove checkpoint before running the one-shot + shutil.rmtree(str(filedir)) + + # one-shot training straight through + pyro.clear_param_store() + create_random_state_blank_slate(0) + args.epochs = epochs + epochs2 + args.input_checkpoint_tarball = 'none' + model_one_shot, scheduler, _, _ = run_inference(dataset_obj=dataset_obj, args=args, + output_checkpoint_tarball='none') + + print('model_one_shot ================================') + print('\n'.join([str(t) for t in _get_params(model_one_shot.encoder['z'])])) + + print('loss for model_one_shot:') + print(model_one_shot.loss) + print('loss for model_ckpt:') + print(model_ckpt.loss) + print([l1 == l2 for l1, l2 in zip(model_one_shot.loss, model_ckpt.loss)]) + + # training should be doing something to the initial weight matrix + assert (w1[0] != _get_params(model_one_shot.encoder['z'])[0]).sum().item() > 0, \ + 'Training is not changing the weight matrix in test_save_and_load_checkpoint' + assert (w1[0] != _get_params(model_ckpt.encoder['z'])[0]).sum().item() > 0, \ + 'Training is not changing the checkpointed weight matrix in test_save_and_load_checkpoint' + + # see if we end up where we should + assert _check_all_close(_get_params(model_one_shot.encoder['z']), + _get_params(model_ckpt.encoder['z'])), \ + 'Checkpointed restart does not agree with one-shot training' + + # # check guide traces + # print('checking guide trace nodes for agreement:') + # for name in guide_trace_one_shot.nodes: + # if (name != '_RETURN') and ('value' in guide_trace_one_shot.nodes[name].keys()): + # print(name) + # disagreement = (guide_trace_one_shot.nodes[name]['value'].data + # != guide_trace_ckpt.nodes[name]['value'].data).sum() + # print(f'number of values that disagree: {disagreement}') + # assert disagreement == 0, \ + # 'Guide traces disagree with and without checkpoint restart' + + +@pytest.mark.parametrize( + "Optim, config", + [ + (optim.ClippedAdam, {"lr": 0.01}), + (optim.ExponentialLR, {"optimizer": torch.optim.SGD, + "optim_args": {"lr": 0.01}, + "gamma": 0.9}), + ], +) +def test_optimizer_checkpoint_restart(Optim, config, tmpdir_factory): + """This code has been copied from a version of a pyro test by Fritz Obermeyer""" + + tempdir = tmpdir_factory.mktemp('ckpt') + + def model(): + x_scale = pyro.param("x_scale", torch.tensor(1.0), + constraint=constraints.positive) + z = pyro.sample("z", pyro.distributions.Normal(0, 1)) + return pyro.sample("x", pyro.distributions.Normal(z, x_scale), obs=torch.tensor(0.1)) + + def guide(): + z_loc = pyro.param("z_loc", torch.tensor(0.0)) + z_scale = pyro.param( + "z_scale", torch.tensor(0.5), constraint=constraints.positive + ) + pyro.sample("z", pyro.distributions.Normal(z_loc, z_scale)) + + store = pyro.get_param_store() + + def get_snapshot(optimizer): + s = {k: v.data.clone() for k, v in store.items()} + if type(optimizer) == optim.lr_scheduler.PyroLRScheduler: + lr = list(optimizer.optim_objs.values())[0].get_last_lr()[0] + else: + lr = list(optimizer.optim_objs.values())[0].param_groups[0]['lr'] + s.update({'lr': f'{lr:.4f}'}) + return s + + # Try without a checkpoint. + expected = [] + store.clear() + pyro.set_rng_seed(20210811) + optimizer = Optim(config.copy()) + svi = pyro.infer.SVI(model, guide, optimizer, pyro.infer.Trace_ELBO()) + for _ in range(5 + 10): + svi.step() + expected.append(get_snapshot(optimizer)) + if type(optimizer) == optim.lr_scheduler.PyroLRScheduler: + svi.optim.step() + del svi, optimizer + + # Try with a checkpoint. + actual = [] + store.clear() + pyro.set_rng_seed(20210811) + optimizer = Optim(config.copy()) + svi = pyro.infer.SVI(model, guide, optimizer, pyro.infer.Trace_ELBO()) + for _ in range(5): + svi.step() + actual.append(get_snapshot(optimizer)) + if type(optimizer) == optim.lr_scheduler.PyroLRScheduler: + svi.optim.step() + + # checkpoint + optim_filename = os.path.join(tempdir, "optimizer_state.pt") + param_filename = os.path.join(tempdir, "param_store.pt") + optimizer.save(optim_filename) + store.save(param_filename) + del optimizer, svi + store.clear() + + # load from checkpoint + store.load(param_filename) + optimizer = Optim(config.copy()) + optimizer.load(optim_filename) + svi = pyro.infer.SVI(model, guide, optimizer, pyro.infer.Trace_ELBO()) + for _ in range(10): + svi.step() + actual.append(get_snapshot(optimizer)) + if type(optimizer) == optim.lr_scheduler.PyroLRScheduler: + svi.optim.step() + + # display learning rates and actual/expected values for z_loc + print(repr(optimizer)) + print('epoch\t\tlr\t\tactual\t\t\t\texpected') + print('-' * 100) + for i, (ac, ex) in enumerate(zip(actual, expected)): + print('\t\t'.join([f'{x}' for x in [i, ac['lr'], ac['z_loc'], ex['z_loc']]])) + if i == 4: + print('-' * 100) + + # ensure actual matches expected + for actual_t, expected_t in zip(actual, expected): + actual_t.pop('lr') + expected_t.pop('lr') + for actual_value, expected_value in zip(actual_t.values(), expected_t.values()): + assert torch.allclose(actual_value, expected_value) diff --git a/cellbender/remove_background/tests/test_dataprep.py b/cellbender/remove_background/tests/test_dataprep.py new file mode 100644 index 00000000..8fcb1562 --- /dev/null +++ b/cellbender/remove_background/tests/test_dataprep.py @@ -0,0 +1,101 @@ +"""Test functions in dataprep.py""" + +import pytest +import scipy.sparse as sp +import numpy as np +import torch + +from cellbender.remove_background.data.dataprep import DataLoader +from cellbender.remove_background.sparse_utils import dense_to_sparse_op_torch + +from .conftest import sparse_matrix_equal, simulated_dataset + + +USE_CUDA = torch.cuda.is_available() + + +@pytest.mark.parametrize('cuda', + [False, + pytest.param(True, marks=pytest.mark.skipif(not USE_CUDA, + reason='requires CUDA'))], + ids=lambda b: 'cuda' if b else 'cpu') +def test_dataloader_sorting(simulated_dataset, cuda): + """test dataset.py _overwrite_matrix_with_columns_from_another()""" + + d = simulated_dataset + data_loader = DataLoader( + d['matrix'], + empty_drop_dataset=None, + batch_size=5, + fraction_empties=0., + shuffle=False, + use_cuda=cuda, + ) + sorted_data_loader = DataLoader( + d['matrix'], + empty_drop_dataset=None, + batch_size=5, + fraction_empties=0., + shuffle=False, + sort_by=lambda x: -1 * np.array(x.max(axis=1).todense()).squeeze(), + use_cuda=cuda, + ) + + # try to shuffle and sort at the same time, and expect a failure + with pytest.raises(AssertionError): + sorted_data_loader2 = DataLoader( + d['matrix'], + empty_drop_dataset=None, + batch_size=5, + fraction_empties=0., + shuffle=True, + sort_by=lambda x: -1 * np.array(x.max(axis=1).todense()).squeeze(), + use_cuda=cuda, + ) + + # this is copied from infer.BasePosterior._get_mean() which is not ideal + out = [] + for loader in [data_loader, sorted_data_loader]: + + barcodes = [] + genes = [] + counts = [] + ind = 0 + + for data in loader: + dense_counts = data # just make it the same! + + # Convert to sparse. + bcs_i_chunk, genes_i, counts_i = dense_to_sparse_op_torch(dense_counts) + + # Barcode index in the dataloader. + bcs_i = bcs_i_chunk + ind + + # Obtain the real barcode index after unsorting the dataloader. + bcs_i = loader.unsort_inds(bcs_i) + + # Add sparse matrix values to lists. + barcodes.append(bcs_i) + genes.append(genes_i) + counts.append(counts_i) + + # Increment barcode index counter. + ind += data.shape[0] # Same as data_loader.batch_size + + # Convert the lists to numpy arrays. + counts = np.concatenate(counts).astype(np.uint32) + barcodes = np.concatenate(barcodes).astype(np.uint32) + genes = np.concatenate(genes).astype(np.uint32) # uint16 is too small! + + print('counts') + print(counts) + print('barcodes') + print(barcodes) + print('genes') + print(genes) + + # Put the counts into a sparse csc_matrix. + out.append(sp.csc_matrix((counts, (barcodes, genes)), + shape=d['matrix'].shape)) + + assert sparse_matrix_equal(out[0], out[1]) diff --git a/cellbender/remove_background/tests/test_dataset.py b/cellbender/remove_background/tests/test_dataset.py new file mode 100644 index 00000000..08fdfef2 --- /dev/null +++ b/cellbender/remove_background/tests/test_dataset.py @@ -0,0 +1,40 @@ +"""Test functions in dataset.py""" + +import pytest +import scipy.sparse as sp +import numpy as np + +from .conftest import sparse_matrix_equal + + +@pytest.mark.skip +def test_heuristic_priors(): + pass + + +@pytest.mark.skip +def test_feature_type_exclusion(): + # TODO there seems to be an error + # TODO see https://github.com/broadinstitute/CellBender/issues/121#issuecomment-1443995082 + pass + + +@pytest.mark.skip +def test_barcode_trimming(): + pass + + +@pytest.mark.skip +def test_feature_trimming(): + pass + + +@pytest.mark.skip +def test_restore_eliminated_features_in_cells(): + pass + + +@pytest.mark.skip +def test_remove_zero_count_cells(): + """Functionality yet to be written too""" + pass diff --git a/cellbender/remove_background/tests/test_downstream.py b/cellbender/remove_background/tests/test_downstream.py new file mode 100644 index 00000000..bf578823 --- /dev/null +++ b/cellbender/remove_background/tests/test_downstream.py @@ -0,0 +1,119 @@ +"""Test functions in downstream.py and a few more.""" + +import pytest + +from cellbender.remove_background.downstream import anndata_from_h5, \ + load_anndata_from_input_and_output +from cellbender.remove_background.tests.conftest import SavedFileH5, \ + h5_file, h5_v3_file_post_inference + + +def convert(s): + """The h5 gets saved with different key names than the h5_file class""" + if s == 'gene_names': + return 'gene_name' + elif s == 'barcodes': + return 'barcode' + elif s == 'gene_ids': + return 'gene_id' + elif s == 'genomes': + return 'genome' + elif s == 'feature_types': + return 'feature_type' + return s + + +def test_anndata_from_h5(h5_file: SavedFileH5): + + # load AnnData and check its shape + adata = anndata_from_h5(file=h5_file.name) + assert h5_file.shape == adata.shape, 'Shape of loaded adata is not correct' + + # ensure everything that was supposed to be saved is loaded properly + indices = [adata.obs.index.name, adata.var.index.name] + all_columns = list(adata.obs.columns) + list(adata.var.columns) + indices + for key in h5_file.keys: + key = convert(key) + assert key in all_columns, f'Saved information "{key}" is missing from loaded adata' + + +@pytest.mark.parametrize('analyzed_bcs_only', [True, False]) +def test_anndata_from_inferred_h5(h5_v3_file_post_inference: SavedFileH5, analyzed_bcs_only): + """Make sure the extra stuff we save gets loaded by downstream loader. + TODO: tidy this up + """ + + adata = anndata_from_h5(file=h5_v3_file_post_inference.name, analyzed_barcodes_only=analyzed_bcs_only) + print(adata) + print(adata.obs.head()) + print(adata.var.head()) + + # check the shape of the loaded AnnData + if analyzed_bcs_only: + expected_shape = (h5_v3_file_post_inference.barcodes_analyzed, h5_v3_file_post_inference.shape[1]) + else: + expected_shape = h5_v3_file_post_inference.shape # all barcodes + assert adata.shape == expected_shape, 'Shape of loaded adata is not correct' + + # ensure everything that was supposed to be saved in .obs and .obsm and .var is loaded properly + indices = [adata.obs.index.name, adata.var.index.name] + all_columns = list(adata.obs.columns) + list(adata.obsm.keys()) + list(adata.var.columns) + indices + + relevant_keys = h5_v3_file_post_inference.keys + if analyzed_bcs_only: + relevant_keys = relevant_keys + h5_v3_file_post_inference.local_keys + + for key in relevant_keys: + print(key) + key = convert(key) + assert key in all_columns, f'Saved information "{key}" is missing from loaded adata' + + # ensure other things are also loading + extra_columns = list(adata.uns.keys()) + relevant_keys = h5_v3_file_post_inference.global_keys + h5_v3_file_post_inference.meta_keys + if not analyzed_bcs_only: + relevant_keys = relevant_keys + h5_v3_file_post_inference.local_keys + + for key in relevant_keys: + print(key) + assert key in extra_columns, \ + f'Saved .uns information "{key}" is missing from adata: {adata.uns.keys()}' + + +def test_load_anndata_from_input_and_output(h5_file, h5_v3_file_post_inference): + adata = load_anndata_from_input_and_output(input_file=h5_file.name, + output_file=h5_v3_file_post_inference.name, + gene_expression_encoding_key='gene_expression_encoding', + analyzed_barcodes_only=False) + print(adata) + assert h5_file.shape == adata.shape, \ + 'Shape of loaded adata is not correct when loading all barcodes' + for key in (h5_v3_file_post_inference.local_keys + + h5_v3_file_post_inference.global_keys + + h5_v3_file_post_inference.meta_keys): + assert key in adata.uns.keys(), f'Key {key} missing from adata.uns' + + adata2 = load_anndata_from_input_and_output(input_file=h5_file.name, + output_file=h5_v3_file_post_inference.name, + gene_expression_encoding_key='gene_expression_encoding', + analyzed_barcodes_only=True) + print(adata2) + assert h5_v3_file_post_inference.analyzed_shape == adata2.shape, \ + 'Shape of loaded adata is not correct when loading only analyzed barcodes' + for key in h5_v3_file_post_inference.local_keys: + if key == 'gene_expression_encoding': + assert key in adata2.obsm.keys(), f'Key {key} missing from adata.obsm' + else: + assert key in adata2.obs.keys(), f'Key {key} missing from adata.obs' + for key in h5_v3_file_post_inference.global_keys + h5_v3_file_post_inference.meta_keys: + assert key in adata2.uns.keys(), f'Key {key} missing from adata.uns' + + +@pytest.mark.skip(reason='TODO') +def test_scanpy_loading(): + pass + + +@pytest.mark.skip(reason='TODO') +def test_seurat_loading(): + pass diff --git a/cellbender/remove_background/tests/test_estimation.py b/cellbender/remove_background/tests/test_estimation.py new file mode 100644 index 00000000..528ab675 --- /dev/null +++ b/cellbender/remove_background/tests/test_estimation.py @@ -0,0 +1,358 @@ +"""Test functions in estimation.py""" +import pandas as pd +import pytest +import scipy.sparse as sp +import numpy as np +import torch + +from cellbender.remove_background.estimation import Mean, MAP, \ + SingleSample, ThresholdCDF, MultipleChoiceKnapsack, pandas_grouped_apply +from cellbender.remove_background.posterior import IndexConverter, \ + dense_to_sparse_op_torch, log_prob_sparse_to_dense + +from typing import Dict, Union + + +@pytest.fixture(scope='module') +def log_prob_coo_base() -> Dict[str, Union[sp.coo_matrix, np.ndarray, Dict[int, int]]]: + n = -np.inf + m = np.array( + [[0, n, n, n, n, n, n, n, n, n], # map 0, mean 0 + [n, 0, n, n, n, n, n, n, n, n], # map 1, mean 1 + [n, n, 0, n, n, n, n, n, n, n], # map 2, mean 2 + [-6, -2, np.log(1. - 2 * np.exp(-2) - np.exp(-6)), -2, n, n, n, n, n, n], + [-2.5, -1.5, -0.5, -3, np.log(1. - np.exp([-2.5, -1.5, -0.5, -3]).sum()), + n, n, n, n, n], + [-0.74, -1, -2, -4, np.log(1. - np.exp([-0.74, -1, -2, -4]).sum()), + n, n, n, n, n], + [-1, -0.74, -2, -4, np.log(1. - np.exp([-0.74, -1, -2, -4]).sum()), + n, n, n, n, n], + [-2, -1, -0.74, -4, np.log(1. - np.exp([-0.74, -1, -2, -4]).sum()), + n, n, n, n, n], + ] + ) + # make m sparse, i.e. zero probability entries are absent + rows, cols, vals = dense_to_sparse_op_torch(torch.tensor(m), tensor_for_nonzeros=torch.tensor(m).exp()) + # make it a bit more difficult by having an empty row at the beginning + rows = rows + 1 + shape = list(m.shape) + shape[0] = shape[0] + 1 + offset_dict = dict(zip(range(1, 9), [0] * 7 + [1])) # noise count offsets (last is 1) + + maps = np.argmax(m, axis=1) + maps = maps + np.array([offset_dict[m] for m in offset_dict.keys()]) + cdf_logic = (torch.logcumsumexp(torch.tensor(m), dim=-1) > np.log(0.5)) + cdfs = [np.where(a)[0][0] for a in cdf_logic] + cdfs = cdfs + np.array([offset_dict[m] for m in offset_dict.keys()]) + + return {'coo': sp.coo_matrix((vals, (rows, cols)), shape=shape), + 'offsets': offset_dict, # not all noise counts start at zero + 'maps': np.array([0] + maps.tolist()), + 'cdfs': np.array([0] + cdfs.tolist())} + + +@pytest.fixture(scope='module', params=['exact', 'filtered', 'unsorted']) +def log_prob_coo(request, log_prob_coo_base) \ + -> Dict[str, Union[sp.coo_matrix, np.ndarray, Dict[int, int]]]: + """When used as an input argument, this offers up a series of dicts that + can be used for tests""" + if request.param == 'exact': + return log_prob_coo_base + + elif request.param == 'filtered': + coo = log_prob_coo_base['coo'] + logic = (coo.data >= -6) + new_coo = sp.coo_matrix((coo.data[logic], (coo.row[logic], coo.col[logic])), + shape=coo.shape) + out = {'coo': new_coo} + out.update({k: v for k, v in log_prob_coo_base.items() if (k != 'coo')}) + return out + + elif request.param == 'unsorted': + coo = log_prob_coo_base['coo'] + order = np.random.permutation(np.arange(len(coo.data))) + new_coo = sp.coo_matrix((coo.data[order], (coo.row[order], coo.col[order])), + shape=coo.shape) + out = {'coo': new_coo} + out.update({k: v for k, v in log_prob_coo_base.items() if (k != 'coo')}) + return out + + else: + raise ValueError(f'Test writing error: requested "{request.param}" log_prob_coo') + + +@pytest.fixture(scope='module', params=['exact', 'filtered', 'unsorted']) +def mckp_log_prob_coo(request, log_prob_coo_base) \ + -> Dict[str, Union[sp.coo_matrix, np.ndarray, Dict[int, int]]]: + """When used as an input argument, this offers up a series of dicts that + can be used for tests. + + NOTE: separate for MCKP because we cannot include an empty 'm' because it + throws everything off (which gene is what, etc.) + """ + def _fix(v): + if type(v) == dict: + return {(k - 1): val for k, val in v.items()} + elif type(v) == sp.coo_matrix: + return _eliminate_row_zero(v) + else: + return v + + def _eliminate_row_zero(coo_: sp.coo_matrix) -> sp.coo_matrix: + row = coo_.row - 1 + shape = list(coo_.shape) + shape[0] = shape[0] - 1 + return sp.coo_matrix((coo_.data, (row, coo_.col)), shape=shape) + + if request.param == 'exact': + out = log_prob_coo_base + + elif request.param == 'filtered': + coo = log_prob_coo_base['coo'] + logic = (coo.data >= -6) + new_coo = sp.coo_matrix((coo.data[logic], (coo.row[logic], coo.col[logic])), + shape=coo.shape) + out = {'coo': new_coo} + out.update({k: v for k, v in log_prob_coo_base.items() if (k != 'coo')}) + + elif request.param == 'unsorted': + coo = log_prob_coo_base['coo'] + order = np.random.permutation(np.arange(len(coo.data))) + new_coo = sp.coo_matrix((coo.data[order], (coo.row[order], coo.col[order])), + shape=coo.shape) + out = {'coo': new_coo} + out.update({k: v for k, v in log_prob_coo_base.items() if (k != 'coo')}) + + else: + raise ValueError(f'Test writing error: requested "{request.param}" log_prob_coo') + + return {k: _fix(v) for k, v in out.items()} + + +def test_single_sample(log_prob_coo): + """Test the single sample estimator""" + + # the input + print(log_prob_coo) + print('input log probs') + dense = log_prob_sparse_to_dense(log_prob_coo['coo']) + print(dense) + + # with this shape converter, we get one row, where each value is one m + converter = IndexConverter(total_n_cells=1, + total_n_genes=log_prob_coo['coo'].shape[0]) + + # set up and estimate + estimator = SingleSample(index_converter=converter) + noise_csr = estimator.estimate_noise(noise_log_prob_coo=log_prob_coo['coo'], + noise_offsets=log_prob_coo['offsets']) + + # output + print('dense noise count estimate, per m') + out_per_m = np.array(noise_csr.todense()).squeeze() + print(out_per_m) + + # test + for i in log_prob_coo['offsets'].keys(): + print(f'testing "m" value {i}') + allowed_vals = np.arange(dense.shape[1])[dense[i, :] > -np.inf] + log_prob_coo['offsets'][i] + print('allowed values') + print(allowed_vals) + print('sample') + print(out_per_m[i]) + assert out_per_m[i] in allowed_vals, \ + f'sample {out_per_m[i]} is not allowed for {dense[i, :]}' + + +def test_mean(log_prob_coo): + """Test the mean estimator""" + + def _add_offsets_to_truth(truth: np.ndarray, offset_dict: Dict[int, int]): + return truth + np.array([offset_dict.get(m, 0) for m in range(len(truth))]) + + offset_dict = log_prob_coo['offsets'] + + # the input + print(log_prob_coo) + print('input log probs') + dense = log_prob_sparse_to_dense(log_prob_coo['coo']) + print(dense) + + # with this shape converter, we get one row, where each value is one m + converter = IndexConverter(total_n_cells=1, + total_n_genes=log_prob_coo['coo'].shape[0]) + + # set up and estimate + estimator = Mean(index_converter=converter) + noise_csr = estimator.estimate_noise(noise_log_prob_coo=log_prob_coo['coo'], + noise_offsets=offset_dict) + + # output + print('dense noise count estimate, per m') + out_per_m = np.array(noise_csr.todense()).squeeze() + print(out_per_m) + + # truth + brute_force = np.matmul(np.arange(dense.shape[1]), np.exp(dense).transpose()) + brute_force = _add_offsets_to_truth(truth=brute_force, offset_dict=offset_dict) + print('truth') + print(brute_force) + + # test + np.testing.assert_allclose(out_per_m, brute_force) + + +def test_map(log_prob_coo): + """Test the MAP estimator""" + + offset_dict = log_prob_coo['offsets'] + + # the input + print(log_prob_coo) + print('input log probs') + print(log_prob_sparse_to_dense(log_prob_coo['coo'])) + + # with this shape converter, we get one row, where each value is one m + converter = IndexConverter(total_n_cells=1, + total_n_genes=log_prob_coo['coo'].shape[0]) + + # set up and estimate + estimator = MAP(index_converter=converter) + noise_csr = estimator.estimate_noise(noise_log_prob_coo=log_prob_coo['coo'], + noise_offsets=offset_dict) + + # output + print('dense noise count estimate, per m') + out_per_m = np.array(noise_csr.todense()).squeeze() + print(out_per_m) + print('truth') + print(log_prob_coo['maps']) + + # test + np.testing.assert_array_equal(out_per_m, log_prob_coo['maps']) + + +def test_cdf(log_prob_coo): + """Test the estimator based on CDF thresholding""" + + offset_dict = log_prob_coo['offsets'] + + # the input + print(log_prob_coo) + print('input log probs') + print(log_prob_sparse_to_dense(log_prob_coo['coo'])) + + # with this shape converter, we get one row, where each value is one m + converter = IndexConverter(total_n_cells=1, + total_n_genes=log_prob_coo['coo'].shape[0]) + + # set up and estimate + estimator = ThresholdCDF(index_converter=converter) + noise_csr = estimator.estimate_noise(noise_log_prob_coo=log_prob_coo['coo'], + noise_offsets=offset_dict, + q=0.5) + + # output + print('dense noise count estimate, per m') + out_per_m = np.array(noise_csr.todense()).squeeze() + print(out_per_m) + print('truth') + print(log_prob_coo['cdfs']) + + # test + np.testing.assert_array_equal(out_per_m, log_prob_coo['cdfs']) + + +@pytest.mark.parametrize('n_chunks, parallel_compute', + ([1, False], + [2, False], + [2, True]), ids=['1chunk', '2chunks_1cpu', '2chunks_parallel']) +@pytest.mark.parametrize('n_cells, target, truth, truth_mat', + ([1, np.zeros(8), np.array([0, 1, 2, 0, 0, 0, 0, 1]), None], + [1, np.ones(8), np.array([0, 1, 2, 1, 1, 1, 1, 1]), None], + [1, np.ones(8) * 2, np.array([0, 1, 2, 2, 2, 2, 2, 2]), None], + [4, np.zeros(2), np.array([2, 2]), None], + [4, np.ones(2) * 4, np.array([4, 4]), np.array([[0, 1], [2, 2], [2, 0], [0, 1]])], + [4, np.ones(2) * 9, np.array([9, 9]), np.array([[0, 1], [2, 3], [4, 2], [3, 3]])]), + ids=['1_cell_target_0', + '1_cell_target_1', + '1_cell_target_2', + '4_cell_target_0', + '4_cell_target_4', + '4_cell_target_9']) +def test_mckp(mckp_log_prob_coo, n_cells, target, truth, truth_mat, n_chunks, parallel_compute): + """Test the multiple choice knapsack problem estimator""" + + offset_dict = mckp_log_prob_coo['offsets'] + + # the input + print('input log probs ===============================================') + print(log_prob_sparse_to_dense(mckp_log_prob_coo['coo'])) + + # set up and estimate# with this shape converter, we have 1 cell with 8 genes + converter = IndexConverter(total_n_cells=n_cells, + total_n_genes=mckp_log_prob_coo['coo'].shape[0] // n_cells) + estimator = MultipleChoiceKnapsack(index_converter=converter) + noise_csr = estimator.estimate_noise( + noise_log_prob_coo=mckp_log_prob_coo['coo'], + noise_offsets=offset_dict, + noise_targets_per_gene=target, + verbose=True, + n_chunks=n_chunks, + use_multiple_processes=parallel_compute, + ) + + assert noise_csr.shape == (converter.total_n_cells, converter.total_n_genes) + + # output + print('dense noise count estimate') + out_mat = np.array(noise_csr.todense()) + print(out_mat) + print('noise counts per gene') + out = out_mat.sum(axis=0) + print(out) + print('truth') + print(truth) + + # test + if truth_mat is not None: + np.testing.assert_array_equal(out_mat, truth_mat) + np.testing.assert_array_equal(out, truth) + + +def _firstval(df): + return df['log_prob'].iat[0] + + +def _meanval(df): + return df['log_prob'].mean() + + +@pytest.mark.parametrize('fun', (_firstval, _meanval), ids=['first_value', 'mean']) +def test_parallel_pandas_grouped_apply(fun): + """Test that the parallel apply gives the same thing as non-parallel""" + + df = pd.DataFrame(data={'m': [0, 0, 0, 1, 1, 1, 2, 2, 2], + 'c': [0, 1, 2] * 3, + 'log_prob': [1, 2, 3, 4, 5, 6, 7, 8, 9]}) + print('input data') + print(df) + + reg = pandas_grouped_apply( + coo=sp.coo_matrix((df['log_prob'], (df['m'], df['c'])), shape=[3, 3]), + fun=fun, + parallel=False, + ) + print('normal application of groupby apply') + print(reg) + + parallel = pandas_grouped_apply( + coo=sp.coo_matrix((df['log_prob'], (df['m'], df['c'])), shape=[3, 3]), + fun=fun, + parallel=True, + ) + print('parallel application of groupby apply') + print(parallel) + + np.testing.assert_array_equal(reg['m'], parallel['m']) + np.testing.assert_array_equal(reg['result'], parallel['result']) diff --git a/cellbender/remove_background/tests/test_infer.py b/cellbender/remove_background/tests/test_infer.py new file mode 100644 index 00000000..06feb679 --- /dev/null +++ b/cellbender/remove_background/tests/test_infer.py @@ -0,0 +1,301 @@ +# """Test functions in infer.py""" +# +# import pytest +# import scipy.sparse as sp +# import numpy as np +# import torch +# +# from cellbender.remove_background.data.dataprep import DataLoader +# from cellbender.remove_background.infer import BasePosterior, Posterior, \ +# binary_search, dense_to_sparse_op_torch, dense_to_sparse_op_numpy +# +# from .conftest import sparse_matrix_equal, simulated_dataset, tensors_equal +# +# +# USE_CUDA = torch.cuda.is_available() +# +# +# @pytest.mark.parametrize('cuda', +# [False, +# pytest.param(True, marks=pytest.mark.skipif(not USE_CUDA, +# reason='requires CUDA'))], +# ids=lambda b: 'cuda' if b else 'cpu') +# def test_dense_to_sparse_op_numpy(simulated_dataset, cuda): +# """test infer.py BasePosterior.dense_to_sparse_op_numpy()""" +# +# d = simulated_dataset +# data_loader = DataLoader( +# d['matrix'], +# empty_drop_dataset=None, +# batch_size=5, +# fraction_empties=0., +# shuffle=False, +# use_cuda=cuda, +# ) +# +# barcodes = [] +# genes = [] +# counts = [] +# ind = 0 +# +# for data in data_loader: +# dense_counts = data # just make it the same! +# +# # Convert to sparse. +# bcs_i_chunk, genes_i, counts_i = \ +# dense_to_sparse_op_numpy(dense_counts.detach().cpu().numpy()) +# +# # Barcode index in the dataloader. +# bcs_i = bcs_i_chunk + ind +# +# # Obtain the real barcode index after unsorting the dataloader. +# bcs_i = data_loader.unsort_inds(bcs_i) +# +# # Add sparse matrix values to lists. +# barcodes.append(bcs_i) +# genes.append(genes_i) +# counts.append(counts_i) +# +# # Increment barcode index counter. +# ind += data.shape[0] # Same as data_loader.batch_size +# +# # Convert the lists to numpy arrays. +# counts = np.array(np.concatenate(tuple(counts)), dtype=np.uint32) +# barcodes = np.array(np.concatenate(tuple(barcodes)), dtype=np.uint32) +# genes = np.array(np.concatenate(tuple(genes)), dtype=np.uint32) # uint16 is too small! +# +# # Put the counts into a sparse csc_matrix. +# out = sp.csc_matrix((counts, (barcodes, genes)), +# shape=d['matrix'].shape) +# +# assert sparse_matrix_equal(out, d['matrix']) +# +# +# @pytest.mark.parametrize('cuda', +# [False, +# pytest.param(True, marks=pytest.mark.skipif(not USE_CUDA, +# reason='requires CUDA'))], +# ids=lambda b: 'cuda' if b else 'cpu') +# def test_dense_to_sparse_op_torch(simulated_dataset, cuda): +# """test infer.py BasePosterior.dense_to_sparse_op_torch()""" +# +# d = simulated_dataset +# data_loader = DataLoader( +# d['matrix'], +# empty_drop_dataset=None, +# batch_size=5, +# fraction_empties=0., +# shuffle=False, +# use_cuda=cuda, +# ) +# +# barcodes = [] +# genes = [] +# counts = [] +# ind = 0 +# +# for data in data_loader: +# dense_counts = data # just make it the same! +# +# # Convert to sparse. +# bcs_i_chunk, genes_i, counts_i = \ +# dense_to_sparse_op_torch(dense_counts) +# +# # Barcode index in the dataloader. +# bcs_i = bcs_i_chunk + ind +# +# # Obtain the real barcode index after unsorting the dataloader. +# bcs_i = data_loader.unsort_inds(bcs_i) +# +# # Add sparse matrix values to lists. +# barcodes.append(bcs_i) +# genes.append(genes_i) +# counts.append(counts_i) +# +# # Increment barcode index counter. +# ind += data.shape[0] # Same as data_loader.batch_size +# +# # Convert the lists to numpy arrays. +# counts = np.concatenate(counts).astype(np.uint32) +# barcodes = np.concatenate(barcodes).astype(np.uint32) +# genes = np.concatenate(genes).astype(np.uint32) # uint16 is too small! +# +# # Put the counts into a sparse csc_matrix. +# out = sp.csc_matrix((counts, (barcodes, genes)), +# shape=d['matrix'].shape) +# +# assert sparse_matrix_equal(out, d['matrix']) +# +# +# def test_binary_search(): +# """Test the general binary search function.""" +# +# tol = 0.001 +# +# def fun1(x): +# return x - 1. +# +# out = binary_search(evaluate_outcome_given_value=fun1, +# target_outcome=torch.tensor([0.]), +# init_range=torch.tensor([[0., 10.]]), +# target_tolerance=tol) +# print('Single value binary search') +# print('Target value = [1.]') +# print(f'Output = {out}') +# assert ((out - torch.tensor([1.])).abs() <= tol).all(), \ +# 'Single input binary search failed' +# +# def fun2(x): +# x = x.clone() +# x[0] = x[0] - 1. +# x[1] = x[1] - 2. +# return x +# +# out = binary_search(evaluate_outcome_given_value=fun2, +# target_outcome=torch.tensor([0., 0.]), +# init_range=torch.tensor([[-10., 5.], [0., 10.]]), +# target_tolerance=tol) +# print('Two-value binary search') +# print('Target value = [1., 2.]') +# print(f'Output = {out}') +# assert ((out - torch.tensor([1., 2.])).abs() <= tol).all(), \ +# 'Two-argument input binary search failed' +# +# @pytest.mark.parametrize('cuda', +# [False, +# pytest.param(True, marks=pytest.mark.skipif(not USE_CUDA, +# reason='requires CUDA'))], +# ids=lambda b: 'cuda' if b else 'cpu') +# @pytest.mark.parametrize('fun', +# [Posterior._mckp_noise_given_log_prob_tensor, +# Posterior._mckp_noise_given_log_prob_tensor_fast], +# ids=['inchworm', 'sort']) +# def test_mckp_noise_given_log_prob_tensor(cuda, fun): +# """Test the bespoke inchworm algorithm for solving a discrete +# convex constrained optimization problem""" +# +# device = 'cuda' if cuda else 'cpu' +# +# poisson_noise_means = torch.tensor([[1.9160, 0.5520], +# [2.7160, 0.0840], +# [3.9080, 2.5280]]).to(device) +# log_p_ngc = (torch.distributions.Poisson(rate=poisson_noise_means.unsqueeze(-1)) +# .log_prob(torch.arange(10).to(device))) +# +# debug = True +# +# print('\nA couple normal test cases') +# out = fun( +# log_prob_noise_counts_NGC=log_p_ngc, +# offset_noise_counts_NG=torch.zeros_like(poisson_noise_means), +# data_NG=torch.ones_like(poisson_noise_means) * 10., +# target_G=torch.tensor([1., 3.]).to(device), +# debug=debug, +# ) +# assert tensors_equal(out[0], torch.tensor([[0., 0.], [0., 0.], [1., 3.]]).to(device)) +# assert tensors_equal(out[1], torch.tensor([0., 0.]).to(device)) +# +# out = fun( +# log_prob_noise_counts_NGC=log_p_ngc, +# offset_noise_counts_NG=torch.zeros_like(poisson_noise_means), +# data_NG=torch.ones_like(poisson_noise_means) * 10., +# target_G=torch.tensor([6., 6.]).to(device), +# debug=debug, +# ) +# assert tensors_equal(out[0], torch.tensor([[1., 1.], [2., 0.], [3., 5.]]).to(device)) +# assert tensors_equal(out[1], torch.tensor([0., 0.]).to(device)) +# +# print('\nEdge case of zero removal') +# out = fun( +# log_prob_noise_counts_NGC=log_p_ngc, +# offset_noise_counts_NG=torch.zeros_like(poisson_noise_means), +# data_NG=torch.ones_like(poisson_noise_means) * 10., +# target_G=torch.tensor([0., 0.]).to(device), +# debug=debug, +# ) +# assert tensors_equal(out[0], torch.tensor([[0., 0.], [0., 0.], [0., 0.]]).to(device)) +# assert tensors_equal(out[1], torch.tensor([0., 0.]).to(device)) +# +# print('\nEdge case of massive target') +# out = fun( +# log_prob_noise_counts_NGC=log_p_ngc, +# offset_noise_counts_NG=torch.zeros_like(poisson_noise_means), +# data_NG=torch.ones_like(poisson_noise_means) * 10., +# target_G=torch.tensor([100., 0.]).to(device), +# debug=debug, +# ) +# assert tensors_equal(out[0], torch.tensor([[9., 0.], [9., 0.], [9., 0.]]).to(device)) +# assert tensors_equal(out[1], torch.tensor([73., 0.]).to(device)) +# +# print('\nNonzero offset noise counts') +# out = fun( +# log_prob_noise_counts_NGC=log_p_ngc, +# offset_noise_counts_NG=torch.ones_like(poisson_noise_means), +# data_NG=torch.ones_like(poisson_noise_means) * 10., +# target_G=torch.tensor([3., 3.]).to(device), +# debug=debug, +# ) +# assert tensors_equal(out[0], torch.tensor([[1., 1.], [1., 1.], [1., 1.]]).to(device)) +# assert tensors_equal(out[1], torch.tensor([0., 0.]).to(device)) +# +# print('\nNonzero offset noise counts with zero target') +# out = fun( +# log_prob_noise_counts_NGC=log_p_ngc, +# offset_noise_counts_NG=torch.tensor([[1., 0.], [0., 0.], [0., 0.]]).to(device), +# data_NG=torch.ones_like(poisson_noise_means) * 10., +# target_G=torch.tensor([0., 0.]).to(device), +# debug=debug, +# ) +# assert tensors_equal(out[0], torch.tensor([[1., 0.], [0., 0.], [0., 0.]]).to(device)) +# assert tensors_equal(out[1], torch.tensor([-1., 0.]).to(device)) +# +# print('\nNonzero offset noise counts') +# out = fun( +# log_prob_noise_counts_NGC=log_p_ngc, +# offset_noise_counts_NG=torch.ones_like(poisson_noise_means), +# data_NG=torch.ones_like(poisson_noise_means) * 10., +# target_G=torch.tensor([6., 6.]).to(device), +# debug=debug, +# ) +# assert tensors_equal(out[0], torch.tensor([[1., 1.], [2., 1.], [3., 4.]]).to(device)) +# assert tensors_equal(out[1], torch.tensor([0., 0.]).to(device)) +# +# # # This cannot happen for a properly constructed log prob tensor: +# # print('Argmax > data') +# # out = fun( +# # log_prob_noise_counts_NGC=log_p_ngc, +# # offset_noise_counts_NG=torch.ones_like(poisson_noise_means), +# # data_NG=torch.ones_like(poisson_noise_means) * 1., +# # target_G=torch.tensor([6., 6.]).to(device), +# # debug=debug, +# # ) +# # assert tensors_equal(out[0], torch.tensor([[1., 1.], [1., 1.], [1., 1.]]).to(device)) +# # assert tensors_equal(out[1], torch.tensor([4., 4.]).to(device)) +# +# print('\nExtra genes that have no moves') +# poisson_noise_means = torch.tensor([[1.9160, 0.5520, 0.1, 0.1], +# [2.7160, 0.0840, 0.2, 0.3], +# [3.9080, 2.5280, 0.3, 0.2]]).to(device) +# data_NG = torch.tensor([[2, 0, 0, 0], +# [0, 0, 1, 0], +# [0, 0, 0, 0]]).float().to(device) +# log_p_ngc = (torch.distributions.Poisson(rate=poisson_noise_means.unsqueeze(-1)) +# .log_prob(torch.arange(10).to(device))) +# log_p_ngc = torch.where(torch.arange(10).to(device).unsqueeze(0).unsqueeze(0) > data_NG.unsqueeze(-1), +# torch.ones_like(log_p_ngc) * -np.inf, +# log_p_ngc) +# target_G = torch.tensor([2., 2., 2., 2.]).to(device) +# print('data') +# print(data_NG) +# print('log_prob') +# print(log_p_ngc) +# out = fun( +# log_prob_noise_counts_NGC=log_p_ngc, +# offset_noise_counts_NG=torch.zeros_like(poisson_noise_means), +# data_NG=data_NG, +# target_G=target_G, +# debug=debug, +# ) +# assert tensors_equal(out[0], data_NG) +# assert tensors_equal(out[1], target_G - data_NG.sum(dim=0)) +# diff --git a/cellbender/remove_background/tests/test_integration.py b/cellbender/remove_background/tests/test_integration.py new file mode 100644 index 00000000..624c59df --- /dev/null +++ b/cellbender/remove_background/tests/test_integration.py @@ -0,0 +1,52 @@ +"""Full run through on small simulated data""" + +from cellbender.remove_background.cli import CLI +from cellbender.base_cli import get_populated_argparser +from cellbender.remove_background.downstream import anndata_from_h5 +from cellbender.remove_background import consts +import numpy as np +import os +import pytest + +from .conftest import USE_CUDA + + +@pytest.mark.parametrize('cuda', + [False, + pytest.param(True, marks=pytest.mark.skipif(not USE_CUDA, + reason='requires CUDA'))], + ids=lambda b: 'cuda' if b else 'cpu') +def test_full_run(tmpdir_factory, h5_v3_file, cuda): + """Do a full run of the command line tool using a small simulated dataset""" + + tmp_dir = tmpdir_factory.mktemp('data') + filename = tmp_dir.join('out.h5') + + os.chdir(tmp_dir) # so checkpoint file goes to temp dir and gets removed + + # handle input arguments using the argparser + input_args = ['cellbender', 'remove-background', + '--input', str(h5_v3_file.name), + '--output', str(filename), + '--epochs', '5'] + if cuda: + input_args.append('--cuda') + args = get_populated_argparser().parse_args(input_args[1:]) + args = CLI.validate_args(args=args) + + # do a full run through + posterior = CLI.run(args=args) + + # do some checks + + # ensure the cell probabilities in the posterior object match the output file + p_for_analyzed_barcodes = posterior.latents_map['p'] + adata = anndata_from_h5(str(filename), analyzed_barcodes_only=True) + file_p_for_analyzed_barcodes = adata.obs['cell_probability'].values + np.testing.assert_array_equal(p_for_analyzed_barcodes, file_p_for_analyzed_barcodes) + + # ensure the cell barcodes are the same both ways + cell_barcodes = np.genfromtxt(str(filename)[:-3] + '_cell_barcodes.csv', dtype=str, delimiter='\n') + adata_cell_barcodes = adata.obs_names[adata.obs['cell_probability'] > consts.CELL_PROB_CUTOFF] + assert set(cell_barcodes) == set(adata_cell_barcodes), \ + 'Cell barcodes in h5 are different from those in CSV file' diff --git a/cellbender/remove_background/tests/test_io.py b/cellbender/remove_background/tests/test_io.py new file mode 100644 index 00000000..06d23ce1 --- /dev/null +++ b/cellbender/remove_background/tests/test_io.py @@ -0,0 +1,223 @@ +"""Test input reading and output writing functionality.""" + +import pytest +import numpy as np +from scipy.io import mmwrite +import scipy.sparse as sp + +from cellbender.remove_background.data.io import \ + load_data, get_matrix_from_cellranger_mtx, get_matrix_from_dropseq_dge, \ + get_matrix_from_bd_rhapsody, get_matrix_from_anndata, \ + detect_cellranger_version_h5, detect_cellranger_version_mtx, unravel_dict + +from cellbender.remove_background.tests.conftest import \ + sparse_matrix_equal, string_ndarray_equality, h5_v2_file, \ + h5_v2_file_missing_ids, h5_v3_file, h5_file + +from typing import List, Dict, Optional +import gzip +import shutil + + +def assert_loaded_matches_saved(d: Dict[str, np.ndarray], + loaded: Dict[str, np.ndarray], + keys: List[str], + cellranger_version: Optional[int] = None): + """Check if a loaded file's data matches the data that was saved. + + Args: + d: Dict of the data that was saved + loaded: Dict of the data that was loaded from file + keys: List of keys to the dicts that will be checked for equality + cellranger_version: In [2, 3] + """ + if 'cellranger_version' in loaded.keys(): + assert cellranger_version == loaded['cellranger_version'] + assert sparse_matrix_equal(loaded['matrix'], d['matrix']) + for key in keys: + if d[key] is None: + continue + assert loaded[key] is not None, \ + f'Loaded h5 key "{key}" was None, but data was saved: {d[key][:5]} ...' + assert string_ndarray_equality(d[key], loaded[key]), \ + f'Loaded h5 key "{key}" did not match saved data' + + +@pytest.mark.parametrize('filetype', ['h5_v2_file', 'h5_v2_file_missing_ids', 'h5_v3_file']) +def test_simulate_save_load_h5(simulated_dataset, + filetype, + h5_v2_file, + h5_v2_file_missing_ids, + h5_v3_file): + + # get information from fixture, since you cannot pass fixtures to parametrize + if filetype == 'h5_v2_file': + saved_h5 = h5_v2_file + elif filetype == 'h5_v2_file_missing_ids': + saved_h5 = h5_v2_file_missing_ids + elif filetype == 'h5_v3_file': + saved_h5 = h5_v3_file + + # load data from file, using auto-loading, as it would be run + loaded = load_data(input_file=saved_h5.name) + + # assert equality + assert_loaded_matches_saved( + d=simulated_dataset, + loaded=loaded, + keys=saved_h5.keys, + cellranger_version=saved_h5.version, + ) + + +def test_detect_cellranger_version_h5(h5_file): + v = detect_cellranger_version_h5(filename=h5_file.name) + true_version = h5_file.version + assert v == true_version + + +def gzip_file(file): + """gzip a file""" + with open(file, 'rb') as f_in, gzip.open(file + '.gz', 'wb') as f_out: + f_out.writelines(f_in) + + +def save_mtx(tmpdir_factory, simulated_dataset, version: int) -> str: + """Save data files in MTX format and return the directory path""" + dirname = tmpdir_factory.mktemp(f'mtx_v{version}') + + # barcodes and sparse matrix... seems the MTX matrix is transposed + mmwrite(dirname.join('matrix.mtx'), simulated_dataset['matrix'].transpose()) + np.savetxt(dirname.join('barcodes.tsv'), simulated_dataset['barcodes'], fmt='%s') + + # features and gzipping if v3 + features = np.concatenate((np.expand_dims(simulated_dataset['gene_ids'], axis=1), + np.expand_dims(simulated_dataset['gene_names'], axis=1), + np.expand_dims(simulated_dataset['feature_types'], axis=1)), axis=1) + + if version == 3: + np.savetxt(dirname.join('features.tsv'), features, fmt='%s', delimiter='\t') + gzip_file(dirname.join('matrix.mtx')) + gzip_file(dirname.join('barcodes.tsv')) + gzip_file(dirname.join('features.tsv')) + elif version == 2: + np.savetxt(dirname.join('genes.tsv'), features[:, :2], fmt='%s', delimiter='\t') + else: + raise ValueError(f'Test problem: version is {version}, but [2, 3] allowed') + + return dirname + + +@pytest.fixture(scope='session', params=[2, 3]) +def mtx_directory(request, tmpdir_factory, simulated_dataset): + dirname = save_mtx(tmpdir_factory=tmpdir_factory, + simulated_dataset=simulated_dataset, + version=request.param) + yield dirname + shutil.rmtree(str(dirname)) + + +def test_detect_cellranger_version_mtx(mtx_directory): + v = detect_cellranger_version_mtx(filedir=mtx_directory) + true_version = 2 if ('_v2' in str(mtx_directory)) else 3 + assert v == true_version + + +def test_load_mtx(simulated_dataset, mtx_directory): + + # use the correct loader function + loaded = get_matrix_from_cellranger_mtx(filedir=mtx_directory) + version = 3 if ('_v3' in str(mtx_directory)) else 2 + assert_loaded_matches_saved(d=simulated_dataset, + loaded=loaded, + keys=(['gene_ids', 'gene_names', 'barcodes'] + + (['feature_types'] if (version == 3) else [])), + cellranger_version=version) + + # use auto-loading, as it would be run + loaded = load_data(mtx_directory) + assert_loaded_matches_saved(d=simulated_dataset, + loaded=loaded, + keys=(['gene_ids', 'gene_names', 'barcodes'] + + (['feature_types'] if (version == 3) else [])), + cellranger_version=version) + + +def save_dge(tmpdir_factory, simulated_dataset, do_gzip) -> str: + """Save data files in DGE format and return the file path""" + sep = '\t' + name = 'dge.txt' + if do_gzip: + name = name + '.gz' + tmp_dir = tmpdir_factory.mktemp('dge') + filename = tmp_dir.join(name) + load_fcn = gzip.open if do_gzip else open + + def row_generator(mat: sp.csc_matrix) -> List[str]: + for i in range(mat.shape[1]): + yield np.array(mat[:, i].todense()).squeeze().astype(int).astype(str).tolist() + + with load_fcn(filename, 'wb') as f: + f.write(b'# some kind of header!\n') + f.write(sep.join(['GENE'] + simulated_dataset['barcodes'].astype(str).tolist()).encode() + b'\n') + for g, vals in zip(simulated_dataset['gene_names'], row_generator(simulated_dataset['matrix'])): + f.write(sep.join([g] + vals).encode() + b'\n') + + return filename, tmp_dir + + +@pytest.fixture(scope='session', params=[True, False], ids=lambda x: 'gzipped' if x else 'not') +def dge_file(request, tmpdir_factory, simulated_dataset): + filename, tmp_dir = save_dge(tmpdir_factory=tmpdir_factory, + simulated_dataset=simulated_dataset, + do_gzip=request.param) + yield filename + shutil.rmtree(str(tmp_dir)) + + +def test_load_dge(simulated_dataset, dge_file): + + # use the correct loader function + loaded = get_matrix_from_dropseq_dge(str(dge_file)) + assert_loaded_matches_saved(d=simulated_dataset, + loaded=loaded, + keys=['gene_names', 'barcodes']) + + # use auto-loading, as it would be run + loaded = load_data(str(dge_file)) + assert_loaded_matches_saved(d=simulated_dataset, + loaded=loaded, + keys=['gene_names', 'barcodes']) + + +@pytest.mark.skip +def test_load_bd(): + pass + + +@pytest.mark.skip +def test_load_anndata(): + pass + + +@pytest.mark.skip +def test_load_loom(): + pass + + +@pytest.mark.skip +def test_write_matrix_to_cellranger_h5(): + pass + + +@pytest.mark.skip +def test_write_denoised_count_matrix(): + # from run.py, but should probably be refactored to io.py + pass + + +def test_unravel_dict(): + key, value = 'pref', {'a': 1, 'b': {'c': 2, 'd': {'e': 3, 'f': 4}}} + answer = {'pref_a': 1, 'pref_b_c': 2, 'pref_b_d_e': 3, 'pref_b_d_f': 4} + d = unravel_dict(key, value) + assert d == answer, 'unravel_dict failed to produce correct output' diff --git a/cellbender/remove_background/tests/test_monitor.py b/cellbender/remove_background/tests/test_monitor.py new file mode 100644 index 00000000..68735074 --- /dev/null +++ b/cellbender/remove_background/tests/test_monitor.py @@ -0,0 +1,21 @@ +"""Tests for monitoring function.""" + +import pytest +import torch + +from cellbender.monitor import get_hardware_usage + +USE_CUDA = torch.cuda.is_available() + + +@pytest.mark.parametrize('cuda', + [False, + pytest.param(True, marks=pytest.mark.skipif(not USE_CUDA, + reason='requires CUDA'))], + ids=lambda b: 'cuda' if b else 'cpu') +def test_get_hardware_usage(cuda): + """Check and see if restarting from a checkpoint picks up in the same place + we left off. Use our model and dataloader. + """ + + print(get_hardware_usage(use_cuda=cuda)) diff --git a/cellbender/remove_background/tests/test_posterior.py b/cellbender/remove_background/tests/test_posterior.py new file mode 100644 index 00000000..e5382b3b --- /dev/null +++ b/cellbender/remove_background/tests/test_posterior.py @@ -0,0 +1,428 @@ +"""Test functions in posterior.py""" + +import pytest +import scipy.sparse as sp +import numpy as np +import torch + +from cellbender.remove_background.data.dataprep import DataLoader +from cellbender.remove_background.posterior import Posterior, torch_binary_search, \ + PRmu, PRq, IndexConverter, compute_mean_target_removal_as_function +from cellbender.remove_background.sparse_utils import dense_to_sparse_op_torch, \ + log_prob_sparse_to_dense, todense_fill +from cellbender.remove_background.estimation import Mean + +import warnings +from typing import Dict, Union + +from .conftest import sparse_matrix_equal, simulated_dataset, tensors_equal + + +USE_CUDA = torch.cuda.is_available() + + +# NOTE: issues caught +# - have a test that actually creates a posterior +# - using uint32 for barcode index in a COO caused integer overflow + + +@pytest.fixture(scope='module') +def log_prob_coo_base() -> Dict[str, Union[sp.coo_matrix, np.ndarray, Dict[int, int]]]: + n = -np.inf + m = np.array( + [[0, n, n, n, n, n, n, n], # map 0, mean 0 + [n, 0, n, n, n, n, n, n], # map 1, mean 1 + [-0.3, -1.5, np.log(1. - np.exp(np.array([-0.3, -1.5])).sum())] + [n] * 5, + [-3, -1.21, -0.7, -2, -4, np.log(1. - np.exp(np.array([-3, -1.21, -0.7, -2, -4])).sum())] + [n] * 2, + ] + ) + # make m sparse, i.e. zero probability entries are absent + rows, cols, vals = dense_to_sparse_op_torch(torch.tensor(m), tensor_for_nonzeros=torch.tensor(m).exp()) + # make it a bit more difficult by having an empty row at the beginning + rows = rows + 1 + shape = list(m.shape) + shape[0] = shape[0] + 1 + offset_dict = dict(zip(range(1, len(m) + 1), [0] * len(m) + [1])) # noise count offsets (last is 1) + return {'coo': sp.coo_matrix((vals, (rows, cols)), shape=shape), + 'offsets': offset_dict} + + +@pytest.fixture(scope='module', params=['sorted', 'unsorted']) +def log_prob_coo(request, log_prob_coo_base) \ + -> Dict[str, Union[sp.coo_matrix, np.ndarray, Dict[int, int]]]: + """When used as an input argument, this offers up a series of dicts that + can be used for tests""" + if request.param == 'sorted': + return log_prob_coo_base + + elif request.param == 'unsorted': + coo = log_prob_coo_base['coo'] + order = np.random.permutation(np.arange(len(coo.data))) + new_coo = sp.coo_matrix((coo.data[order], (coo.row[order], coo.col[order])), + shape=coo.shape) + out = {'coo': new_coo} + out.update({k: v for k, v in log_prob_coo_base.items() if (k != 'coo')}) + return out + + else: + raise ValueError(f'Test writing error: requested "{request.param}" log_prob_coo') + + +@pytest.mark.parametrize('alpha', [0, 1, 2], ids=lambda a: f'alpha{a}') +@pytest.mark.parametrize('n_chunks', [1, 2], ids=lambda n: f'{n}chunks') +@pytest.mark.parametrize('cuda', + [False, + pytest.param(True, marks=pytest.mark.skipif(not USE_CUDA, + reason='requires CUDA'))], + ids=lambda b: 'cuda' if b else 'cpu') +def test_PRq(log_prob_coo, alpha, n_chunks, cuda): + + target_tolerance = 0.001 + + print('input log_prob matrix, densified') + dense_input_log_prob = torch.tensor(log_prob_sparse_to_dense(log_prob_coo['coo'])).float() + print(dense_input_log_prob) + print('probability sums per row') + print(torch.logsumexp(dense_input_log_prob, dim=-1).exp()) + print('(row 0 is a missing row)') + + print('input mean noise counts per row') + counts = torch.arange(dense_input_log_prob.shape[-1]).float().unsqueeze(dim=0) + input_means = (dense_input_log_prob.exp() * counts).sum(dim=-1) + print(input_means) + + print('input std per row') + input_std = (dense_input_log_prob.exp() + * (counts - input_means.unsqueeze(dim=-1)).pow(2)).sum(dim=-1).sqrt() + print(input_std) + + print('\ntruth: expected means after regularization') + truth_means_after_regularization = input_means + alpha * input_std + print(truth_means_after_regularization) + print('and the log') + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="divide by zero encountered in log") + print(np.log(truth_means_after_regularization)) + + print('testing compute_log_target_dict()') + target_dict = PRq._compute_log_target_dict(noise_count_posterior_coo=log_prob_coo['coo'], + alpha=alpha) + print(target_dict) + for m in target_dict.keys(): + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", message="divide by zero encountered in log") + np.testing.assert_almost_equal(target_dict[m], + np.log(truth_means_after_regularization[m])) + + print('targets are correct\n\n') + + print('means after regularization') + regularized_coo = PRq.regularize( + noise_count_posterior_coo=log_prob_coo['coo'], + noise_offsets=log_prob_coo['offsets'], + alpha=alpha, + device='cuda' if cuda else 'cpu', + target_tolerance=target_tolerance, + n_chunks=n_chunks, + ) + print('regularized posterior:') + dense_regularized_log_prob = torch.tensor(log_prob_sparse_to_dense(regularized_coo)).float() + print(dense_regularized_log_prob) + means_after_regularization = (dense_regularized_log_prob.exp() * counts).sum(dim=-1) + print('means after regularization:') + print(means_after_regularization) + + torch.testing.assert_close( + actual=truth_means_after_regularization, + expected=means_after_regularization, + rtol=target_tolerance, + atol=target_tolerance, + ) + + +@pytest.mark.parametrize('fpr', [0., 0.1, 1], ids=lambda a: f'fpr{a}') +@pytest.mark.parametrize('n_chunks', [1, 2], ids=lambda n: f'{n}chunks') +# @pytest.mark.parametrize('per_gene', [False, True], ids=lambda n: 'per_gene' if n else 'overall') +@pytest.mark.parametrize('per_gene', [False], ids=lambda n: 'per_gene' if n else 'overall') +@pytest.mark.parametrize('cuda', + [False, + pytest.param(True, marks=pytest.mark.skipif(not USE_CUDA, + reason='requires CUDA'))], + ids=lambda b: 'cuda' if b else 'cpu') +def test_PRmu(log_prob_coo, fpr, per_gene, n_chunks, cuda): + + target_tolerance = 0.5 + + index_converter = IndexConverter(total_n_cells=log_prob_coo['coo'].shape[0], total_n_genes=1) + print(index_converter) + + print('raw count matrix') + count_matrix = sp.csr_matrix(np.expand_dims(np.array([0, 0, 1, 2, 5]), axis=-1)) # reflecting filled in log_prob values + print(count_matrix) + + print('input log_prob matrix, densified') + dense_input_log_prob = torch.tensor(log_prob_sparse_to_dense(log_prob_coo['coo'])).float() + print(dense_input_log_prob) + print('probability sums per row') + print(torch.logsumexp(dense_input_log_prob, dim=-1).exp()) + print('(row 0 is a missing row)') + + estimator = Mean(index_converter=index_converter) + mean_noise_csr = estimator.estimate_noise( + noise_log_prob_coo=log_prob_coo['coo'], + noise_offsets=log_prob_coo['offsets'], + device='cuda' if cuda else 'cpu', + ) + print(f'Mean estimator removes {mean_noise_csr.sum()} counts total') + + print('testing compute_target_removal()') + n_cells = 4 # hard coded from the log_prob_coo + target_fun = compute_mean_target_removal_as_function( + noise_count_posterior_coo=log_prob_coo['coo'], + noise_offsets=log_prob_coo['offsets'], + raw_count_csr_for_cells=count_matrix, + n_cells=n_cells, + index_converter=index_converter, + device='cuda' if cuda else 'cpu', + per_gene=per_gene, + ) + targets = target_fun(fpr) + print(f'aiming to remove {targets} overall counts per cell') + print(f'so about {targets * n_cells} counts total') + + print('means after regularization') + regularized_coo = PRmu.regularize( + noise_count_posterior_coo=log_prob_coo['coo'], + noise_offsets=log_prob_coo['offsets'], + index_converter=index_converter, + raw_count_matrix=count_matrix, + fpr=fpr, + per_gene=per_gene, + device='cuda' if cuda else 'cpu', + target_tolerance=target_tolerance, + n_chunks=n_chunks, + ) + print('regularized posterior:') + dense_regularized_log_prob = torch.tensor(log_prob_sparse_to_dense(regularized_coo)).float() + print(dense_regularized_log_prob) + + print('MAP noise:') + map_noise = torch.argmax(dense_regularized_log_prob, dim=-1) + print(map_noise) + + if fpr == 0.: + torch.testing.assert_close( + actual=map_noise.sum().float(), + expected=torch.tensor(mean_noise_csr.sum()).float(), + rtol=1, + atol=1, + ) + elif fpr == 1.: + torch.testing.assert_close( + actual=map_noise.sum().float(), + expected=torch.tensor(count_matrix.sum()).float(), + rtol=1, + atol=1, + ) + else: + assert torch.tensor(mean_noise_csr.sum()).float() - 1 <= map_noise.sum().float(), \ + 'Noise estimate is less than Mean estimator' + assert torch.tensor(count_matrix.sum()).float() >= map_noise.sum().float(), \ + 'Noise estimate is greater than sum of counts... this should never happen' + + # TODO: this test is very weak... it's just hard to test it exactly... + # TODO: passing should mean the code will run, but not that it's quantitatively accurate + + +@pytest.mark.skip +def test_create_posterior(): + pass + + +def test_index_converter(): + index_converter = IndexConverter(total_n_cells=10, total_n_genes=5) + print(index_converter) + + # check basic conversion + n = np.array([0, 1, 2, 3]) + g = n.copy() + m = index_converter.get_m_indices(cell_inds=n, gene_inds=g) + print(f'm inds are {m}') + truth = 5 * n + g + print(f'expected {truth}') + np.testing.assert_equal(m, truth) + + # back and forth + n_star, g_star = index_converter.get_ng_indices(m_inds=m) + np.testing.assert_equal(n, n_star) + np.testing.assert_equal(g, g_star) + + # check on input validity checking + with pytest.raises(ValueError): + index_converter.get_m_indices(cell_inds=np.array([-1]), gene_inds=g) + with pytest.raises(ValueError): + index_converter.get_m_indices(cell_inds=np.array([10]), gene_inds=g) + with pytest.raises(ValueError): + index_converter.get_m_indices(cell_inds=n, gene_inds=np.array([-1])) + with pytest.raises(ValueError): + index_converter.get_m_indices(cell_inds=n, gene_inds=np.array([5])) + with pytest.raises(ValueError): + index_converter.get_ng_indices(m_inds=np.array([-1])) + with pytest.raises(ValueError): + index_converter.get_ng_indices(m_inds=np.array([10 * 5])) + + +@pytest.mark.skip +def test_estimation_array_to_csr(): + Posterior._estimation_array_to_csr() + pass + + +def test_torch_binary_search(): + """Test the general binary search function.""" + + tol = 0.001 + + def fun1(x): + return x - 1. + + out = torch_binary_search( + evaluate_outcome_given_value=fun1, + target_outcome=torch.tensor([0.]), + init_range=torch.tensor([[0., 10.]]), + target_tolerance=tol, + ) + print('Single value binary search') + print('Target value = [1.]') + print(f'Output = {out}') + assert ((out - torch.tensor([1.])).abs() <= tol).all(), \ + 'Single input binary search failed' + + def fun2(x): + x = x.clone() + x[0] = x[0] - 1. + x[1] = x[1] - 2. + return x + + out = torch_binary_search( + evaluate_outcome_given_value=fun2, + target_outcome=torch.tensor([0., 0.]), + init_range=torch.tensor([[-10., 5.], [0., 10.]]), + target_tolerance=tol, + ) + print('Two-value binary search') + print('Target value = [1., 2.]') + print(f'Output = {out}') + assert ((out - torch.tensor([1., 2.])).abs() <= tol).all(), \ + 'Two-argument input binary search failed' + + +@pytest.mark.parametrize('fpr', [0., 0.1, 0.5, 0.75, 1], ids=lambda a: f'fpr{a}') +@pytest.mark.parametrize('per_gene', [False], ids=lambda n: 'per_gene' if n else 'overall') +@pytest.mark.parametrize('cuda', + [False, + pytest.param(True, marks=pytest.mark.skipif(not USE_CUDA, + reason='requires CUDA'))], + ids=lambda b: 'cuda' if b else 'cpu') +def test_compute_mean_target_removal_as_function(log_prob_coo, fpr, per_gene, cuda): + """The target removal computation, very important for the MCKP output""" + + noise_count_posterior_coo = log_prob_coo['coo'] + noise_offsets = log_prob_coo['offsets'] + device = 'cuda' if cuda else 'cpu' + + print('log prob posterior coo') + print(noise_count_posterior_coo) + + index_converter = IndexConverter(total_n_cells=log_prob_coo['coo'].shape[0], + total_n_genes=1) + print(index_converter) + + print('raw count matrix') + count_matrix = sp.csr_matrix( + np.expand_dims(np.array([0, 0, 1, 2, 5]), axis=-1) + ) # reflecting filled in log_prob values + print(count_matrix) + + n_cells = log_prob_coo['coo'].shape[0] # hard coded from the log_prob_coo + + target_fun = compute_mean_target_removal_as_function( + noise_count_posterior_coo=noise_count_posterior_coo, + noise_offsets=noise_offsets, + index_converter=index_converter, + raw_count_csr_for_cells=count_matrix, + n_cells=n_cells, + device=device, + per_gene=per_gene, + ) + + target = (target_fun(fpr) * n_cells).item() + print(f'\nwith fpr={fpr:.2f}, target is: {target:.1g}') + + assert target >= 1, 'There is one noise count guaranteed from this test posterior' + if fpr == 1: + torch.testing.assert_close(target, float(count_matrix.sum())) + + # assert False + # TODO: this has not been tested out + + +@pytest.mark.parametrize('blank_noise_offsets', [False, True], ids=['', 'no_noise_offsets']) +def test_save_and_load(tmpdir_factory, blank_noise_offsets): + """Test that a round trip through save and load gives the same thing""" + + tmp_dir = tmpdir_factory.mktemp('posterior') + filename = tmp_dir.join('posterior.h5') + + m = 1000 + n = 20 + + posterior = Posterior(dataset_obj=None, vi_model=None) # blank + + posterior_coo = sp.random(m, n, density=0.1, format='coo', dtype=float) + posterior_coo2 = sp.random(m, n, density=0.08, format='coo', dtype=float) + if blank_noise_offsets: + noise_offsets = {} + else: + noise_offsets = dict(zip(np.random.randint(low=0, high=(m - 1), size=10), + np.random.randint(low=1, high=5, size=10))) + kwargs = {'a': 'b', 'c': 1} + kwargs2 = {'a': 'method', 'c': 1} + + # jam in fake values + posterior._noise_count_posterior_coo = posterior_coo + posterior._noise_count_posterior_coo_offsets = noise_offsets + posterior._noise_count_posterior_kwargs = kwargs + posterior._noise_count_regularized_posterior_coo = posterior_coo2 + posterior._noise_count_regularized_posterior_kwargs = kwargs2 + posterior._latents = {'p': np.random.randn(100), 'd': np.random.randn(100)} + posterior.index_converter = IndexConverter(total_n_cells=1000, total_n_genes=1000) + + # save + posterior.save(file=str(filename)) + + # load + posterior2 = Posterior(dataset_obj=None, vi_model=None) # blank + posterior2.load(file=str(filename)) + + # check + for attr in ['_noise_count_posterior_coo', '_noise_count_posterior_coo_offsets', + '_noise_count_posterior_kwargs', '_noise_count_regularized_posterior_coo', + '_noise_count_regularized_posterior_kwargs', '_latents']: + val1 = getattr(posterior, attr) + val2 = getattr(posterior2, attr) + print(f'{attr} ===================') + print('saved:') + print(val1) + print('loaded') + print(val2) + err_msg = f'Posterior attribute {attr} not preserved after saving and loading' + if type(val1) == sp.coo_matrix: + assert sparse_matrix_equal(val1, val2), err_msg + elif type(val1) == np.ndarray: + np.testing.assert_equal(val1, val2) + elif (type(val1) == dict) and (val1 != {}) and (type(list(val1.values())[0]) == np.ndarray): + for k in val1.keys(): + np.testing.assert_equal(val1[k], val2[k]) + else: + assert val1 == val2, err_msg diff --git a/cellbender/remove_background/tests/test_sparse_utils.py b/cellbender/remove_background/tests/test_sparse_utils.py new file mode 100644 index 00000000..01230da8 --- /dev/null +++ b/cellbender/remove_background/tests/test_sparse_utils.py @@ -0,0 +1,203 @@ +import pytest +import scipy.sparse as sp +import numpy as np +import torch + +from cellbender.remove_background.sparse_utils import todense_fill, \ + csr_set_rows_to_zero, dense_to_sparse_op_torch, log_prob_sparse_to_dense, \ + overwrite_matrix_with_columns_from_another +from cellbender.remove_background.data.dataprep import DataLoader +from .conftest import sparse_matrix_equal + + +USE_CUDA = torch.cuda.is_available() + + +@pytest.mark.parametrize('val', [0, 1, np.nan, np.inf, -np.inf]) +def test_todense_fill(val): + """Test densification of scipy sparse COO matrix with arbitrary fill value""" + + mat = np.array( + [[0, 0, 0, 0], + [1, 0, 0, 0], + [0, 1, 2, 0], + [1, 2, 3, 4]], + dtype=float, + ) + coo = sp.coo_matrix(mat) + + print('original') + print(mat) + print('sparse version') + print(coo) + + print(f'densified using {val}') + dense = todense_fill(coo=coo, fill_value=val) + print(dense) + brute_force = mat.copy() + brute_force[brute_force == 0] = val + np.testing.assert_array_equal(brute_force, dense) + + +@pytest.mark.parametrize('cuda', + [False, + pytest.param(True, marks=pytest.mark.skipif(not USE_CUDA, + reason='requires CUDA'))], + ids=lambda b: 'cuda' if b else 'cpu') +def test_dense_to_sparse_op_torch(simulated_dataset, cuda): + """test infer.py BasePosterior.dense_to_sparse_op_torch()""" + + d = simulated_dataset + data_loader = DataLoader( + d['matrix'], + empty_drop_dataset=None, + batch_size=5, + fraction_empties=0., + shuffle=False, + use_cuda=cuda, + ) + + barcodes = [] + genes = [] + counts = [] + ind = 0 + + for data in data_loader: + dense_counts = data # just make it the same! + + # Convert to sparse. + bcs_i_chunk, genes_i, counts_i = \ + dense_to_sparse_op_torch(dense_counts) + + # Barcode index in the dataloader. + bcs_i = bcs_i_chunk + ind + + # Obtain the real barcode index after unsorting the dataloader. + bcs_i = data_loader.unsort_inds(bcs_i) + + # Add sparse matrix values to lists. + barcodes.append(bcs_i) + genes.append(genes_i) + counts.append(counts_i) + + # Increment barcode index counter. + ind += data.shape[0] # Same as data_loader.batch_size + + # Convert the lists to numpy arrays. + counts = np.concatenate(counts).astype(np.uint32) + barcodes = np.concatenate(barcodes).astype(np.uint32) + genes = np.concatenate(genes).astype(np.uint32) # uint16 is too small! + + # Put the counts into a sparse csc_matrix. + out = sp.csc_matrix((counts, (barcodes, genes)), + shape=d['matrix'].shape) + + assert sparse_matrix_equal(out, d['matrix']) + + +def test_log_prob_sparse_to_dense(): + """Test densification of log prob sparse posteriors filling with -np.inf""" + + data = np.array([0, -1, -2, 0, -4, -2, 0]) + row = np.array([0, 0, 2, 2, 3, 3, 4]) + col = np.array([0, 1, 0, 1, 0, 1, 0]) + coo = sp.coo_matrix((data, (row, col)), shape=[5, 2]) + print(coo) + print('scipy .todense()') + print(coo.todense()) + print('log prob densification') + mat = log_prob_sparse_to_dense(coo=coo) + print(mat) + print('nan densification') + mat_nan = todense_fill(coo=coo, fill_value=np.nan) + print(mat_nan) + print('8 densification') + mat_8 = todense_fill(coo=coo, fill_value=8.) + print(mat_8) + + truth = lambda x: np.array( + [[ 0., -1.], + [ x, x ], + [-2., 0.], + [-4., -2.], + [ 0., x ]], + ) + print('truth with -np.inf') + print(truth(-np.inf)) + + np.testing.assert_array_equal(mat, truth(-np.inf)) + np.testing.assert_array_equal(mat_nan, truth(np.nan)) + np.testing.assert_array_equal(mat_8, truth(8.)) + + +@pytest.mark.parametrize('mat1, mat2, col_inds', + [(sp.csc_matrix([[1, 2], [3, 4]]), + sp.csc_matrix([[0, 0], [0, 0]]), + [0]), + (sp.csc_matrix([[1, 2], [3, 4], [5, 6]]), + sp.csc_matrix([[0, 0], [0, 0], [0, 0]]), + [1]), + (sp.csc_matrix(np.random.poisson(lam=2., size=(10, 10))), + sp.csc_matrix(np.random.poisson(lam=2., size=(10, 10))), + [0, 1, 2, 3])]) +def test_overwrite_matrix_with_columns_from_another(mat1: sp.csc_matrix, + mat2: sp.csc_matrix, + col_inds: np.ndarray): + """test overwrite_matrix_with_columns_from_another()""" + + out = overwrite_matrix_with_columns_from_another(mat1=mat1, mat2=mat2, column_inds=col_inds) + excluded_col_inds = [i for i in range(mat1.shape[1]) if i not in col_inds] + + print('col_inds') + print(col_inds) + print('mat1') + print(mat1.todense()) + print('mat2') + print(mat2.todense()) + print('out') + print(out.todense()) + + print('assertion') + print(out[:, excluded_col_inds].todense()) + print(mat2[:, excluded_col_inds].todense()) + + print('assertion') + print(out[:, col_inds].todense()) + print(mat1[:, col_inds].todense()) + + # excluded columns should be replaced with new values + assert sparse_matrix_equal(out[:, excluded_col_inds], mat2[:, excluded_col_inds]) + + # included columns should be left alone + assert sparse_matrix_equal(out[:, col_inds], mat1[:, col_inds]) + + +@pytest.mark.parametrize('mat, row_inds', + [(sp.csc_matrix([[1, 2], [3, 4]]), + [0]), + (sp.csc_matrix([[1, 2], [3, 4], [5, 6]]), + [1]), + (sp.csc_matrix(np.random.poisson(lam=2., size=(10, 10))), + [0, 1, 2, 3])]) +def test_csr_set_rows_to_zero(mat: sp.csr_matrix, row_inds: np.ndarray): + """test csr_set_rows_to_zero()""" + + out = csr_set_rows_to_zero(csr=mat, row_inds=row_inds) + other_row_inds = [i for i in range(mat.shape[0]) if i not in row_inds] + + print('row_inds') + print(row_inds) + print('mat') + print(mat.todense()) + print('out') + print(out.todense()) + + print('assertion') + print(out[other_row_inds, :].todense()) + print(mat[other_row_inds, :].todense()) + + # other rows should be left alone + assert sparse_matrix_equal(out[other_row_inds, :], mat[other_row_inds, :]) + + # specified rows should be all zero + assert out[row_inds, :].sum() == 0 diff --git a/cellbender/remove_background/tests/test_train.py b/cellbender/remove_background/tests/test_train.py new file mode 100644 index 00000000..66bf7290 --- /dev/null +++ b/cellbender/remove_background/tests/test_train.py @@ -0,0 +1,135 @@ +"""Test functionality in train.py""" + +import torch +import pyro.distributions as dist +import pyro.infer.trace_elbo +import pytest +import scipy.sparse as sp +from pyro.infer.svi import SVI +import unittest.mock + +from cellbender.remove_background.run import get_optimizer +from cellbender.remove_background.data.dataprep import prep_sparse_data_for_training \ + as prep_data_for_training +from cellbender.remove_background.train import train_epoch, evaluate_epoch +from .conftest import USE_CUDA + + +@pytest.mark.parametrize('cuda', + [False, + pytest.param(True, marks=pytest.mark.skipif(not USE_CUDA, + reason='requires CUDA'))], + ids=lambda b: 'cuda' if b else 'cpu') +@pytest.mark.parametrize('dropped_minibatch', [False, True], ids=['', 'dropped_minibatch']) +def test_one_cycle_scheduler(dropped_minibatch, cuda): + + # if there is a minibatch so small that it's below consts.SMALLEST_ALLOWED_BATCH + # then the minibatch gets skipped. make sure this works with the scheduler. + + pyro.clear_param_store() + device = 'cuda' if cuda else 'cpu' + + n_cells = 3580 + n_empties = 50000 + n_genes = 100 + learning_rate = 1e-4 + batch_size = 512 + if dropped_minibatch: + n_cells += 2 + epochs = 50 + + count_matrix = sp.random(n_cells, n_genes, density=0.01, format='csr') + empty_matrix = sp.random(n_empties, n_genes, density=0.0001, format='csr') + + # Set up dataloaders. + train_loader, _ = \ + prep_data_for_training(dataset=count_matrix, + empty_drop_dataset=empty_matrix, + batch_size=batch_size, + training_fraction=1., + fraction_empties=0.3, + shuffle=True, + use_cuda=cuda) + + print(f'epochs = {epochs}') + print(f'len(train_loader), i.e. number of minibatches = {len(train_loader)}') + print(f'train_loader.batch_size = {train_loader.batch_size}') + print(f'train_loader.cell_batch_size = {train_loader.cell_batch_size}') + + # Set up optimizer. + scheduler = get_optimizer( + n_batches=len(train_loader), + batch_size=train_loader.batch_size, + epochs=epochs, + learning_rate=learning_rate, + constant_learning_rate=False, + total_epochs_for_testing_only=None, + ) + + # Set up SVI dummy. + def _model(x): + y_mean = pyro.param("y_mean", torch.zeros(1).to(device)) + pyro.sample("y_obs", dist.Normal(loc=y_mean, scale=1), obs=x.sum()) + + def _guide(x): + pass + + svi = SVI(model=_model, + guide=_guide, + optim=scheduler, + loss=pyro.infer.trace_elbo.Trace_ELBO()) + + # Looking for a RuntimeError raised by the scheduler trying to step too much + lr = [] + for _ in range(epochs): + train_epoch(svi=svi, train_loader=train_loader) + lr.append(list(svi.optim.optim_objs.values())[0].get_last_lr()[0]) + + print('learning rates at each epoch:') + print('\n'.join([f'[{i + 1:03d}] {rate:.2e}' for i, rate in enumerate(lr)])) + + # Ensure learning rates are numerically correct + # scheduler args include 'max_lr': learning_rate * 10 + max_lr = 10 * learning_rate + initial_lr = max_lr / 25 + final_lr = initial_lr / 1e4 + # https://pytorch.org/docs/stable/generated/torch.optim.lr_scheduler.OneCycleLR.html + assert lr[len(lr) // 2] > lr[0], 'Cosine LR schedule should have middle > start' + assert lr[len(lr) // 2] > lr[-1], 'Cosine LR schedule should have middle > end' + torch.testing.assert_close(lr[0], initial_lr + (max_lr - initial_lr) / epochs, rtol=1, atol=1e-7), \ + 'Starting learning rate for scheduler seems off' + torch.testing.assert_close(lr[-1], final_lr, rtol=1, atol=1e-7), \ + 'Final learning rate for scheduler seems off' + torch.testing.assert_close(max(lr), max_lr, rtol=1, atol=1e-7), \ + 'Max learning rate in scheduler seems off' + + # And one more step ought to raise the error + with pytest.raises(ValueError, + match=r"Tried to step .* times. The specified number " + r"of total steps is .*"): + svi.optim.step() + + +@pytest.mark.skip +def test_epoch_elbo_fail_restart(): + """Trigger failure and ensure a new attempt is made""" + pass + + +@pytest.mark.skip +def test_final_elbo_fail_restart(): + """Trigger failure and ensure a new attempt is made""" + pass + + +@pytest.mark.skip +def test_restart_matches_scratch(): + """Ensure that an auto-restart gives same ELBO as a start-from-scratch""" + # https://stackoverflow.com/questions/50964786/mock-exception-raised-in-function-using-pytest + pass + + +@pytest.mark.skip +def test_num_training_attempts(): + """Make sure the number of training attempts matches input arg""" + pass diff --git a/cellbender/remove_background/train.py b/cellbender/remove_background/train.py index 0f47f18d..8d778082 100644 --- a/cellbender/remove_background/train.py +++ b/cellbender/remove_background/train.py @@ -1,35 +1,40 @@ """Helper functions for training.""" import pyro -import pyro.distributions as dist -from pyro.infer import SVI, JitTraceEnum_ELBO, JitTrace_ELBO, \ - TraceEnum_ELBO, Trace_ELBO -from pyro.optim import ClippedAdam from pyro.util import ignore_jit_warnings +from pyro.infer import SVI +import torch from cellbender.remove_background.model import RemoveBackgroundPyroModel -from cellbender.remove_background.vae.decoder import Decoder -from cellbender.remove_background.vae.encoder \ - import EncodeZ, CompositeEncoder, EncodeNonZLatents -from cellbender.remove_background.data.dataset import SingleCellRNACountsDataset -from cellbender.remove_background.data.dataprep import \ - prep_sparse_data_for_training as prep_data_for_training from cellbender.remove_background.data.dataprep import DataLoader -from cellbender.remove_background.exceptions import NanException +from cellbender.remove_background.exceptions import NanException, ElboException import cellbender.remove_background.consts as consts +from cellbender.remove_background.checkpoint import save_checkpoint +from cellbender.monitor import get_hardware_usage import numpy as np -import torch +import argparse from typing import Tuple, List, Optional import logging import time from datetime import datetime +import sys + + +logger = logging.getLogger('cellbender') + + +def is_scheduler(optim): + """Currently is_scheduler is on a pyro dev branch""" + if hasattr(optim, 'is_scheduler'): + return optim.is_scheduler() + else: + return type(optim) == pyro.optim.lr_scheduler.PyroLRScheduler def train_epoch(svi: SVI, - train_loader: DataLoader, - epoch: Optional[int] = None) -> float: + train_loader: DataLoader) -> float: """Train a single epoch. Args: @@ -53,12 +58,22 @@ def train_epoch(svi: SVI, # Perform gradient descent step and accumulate loss. epoch_loss += svi.step(x_cell_batch) - svi.optim.step(epoch=epoch) # for LR scheduling normalizer_train += x_cell_batch.size(0) + if is_scheduler(svi.optim): + svi.optim.step() # for LR scheduling + # Return epoch loss. total_epoch_loss_train = epoch_loss / normalizer_train + if is_scheduler(svi.optim): + try: + logger.debug(f'Learning rate scheduler: LR = ' + f'{list(svi.optim.optim_objs.values())[0].get_last_lr()[0]:.2e}') + except IndexError: + logger.debug('No values being optimized') + pass + return total_epoch_loss_train @@ -98,232 +113,185 @@ def evaluate_epoch(svi: pyro.infer.SVI, @ignore_jit_warnings() def run_training(model: RemoveBackgroundPyroModel, + args: argparse.Namespace, svi: pyro.infer.SVI, train_loader: DataLoader, test_loader: DataLoader, epochs: int, + output_filename: str, test_freq: int = 10, final_elbo_fail_fraction: float = None, - epoch_elbo_fail_fraction: float = None) -> Tuple[List[float], - List[float], bool]: + epoch_elbo_fail_fraction: float = None, + ckpt_tarball_name: str = consts.CHECKPOINT_FILE_NAME, + checkpoint_freq: int = 10) -> Tuple[List[float], List[float]]: """Run an entire course of training, evaluating on a tests set periodically. Args: model: The model, here in order to store train and tests loss. + args: Parsed arguments, which get saved to checkpoints. svi: The pyro object used for stochastic variational inference. train_loader: Dataloader for training set. test_loader: Dataloader for tests set. epochs: Number of epochs to run training. + output_filename: User-specified output file, used to construct + checkpoint filenames. test_freq: Test set loss is calculated every test_freq epochs of training. - final_elbo_fail_fraction: fail if final test ELBO >= best ELBO * (1+this value) - epoch_elbo_fail_fraction: fail if current test ELBO >= previous ELBO * (1+this value) + final_elbo_fail_fraction: Fail if final test ELBO >= + best ELBO * (1 + this value) + epoch_elbo_fail_fraction: Fail if current test ELBO >= + previous ELBO * (1 + this value) + ckpt_tarball_name: Name of saved tarball for checkpoint. + checkpoint_freq: Checkpoint after this many minutes Returns: - Tuple( - list of training ELBO for each epoch, - list of test ELBO for each epoch for which testing is done, - boolean: False indicates training failed - ) - """ + total_epoch_loss_train: The loss for this epoch of training, which + is -ELBO, normalized by the number of items in the training set. - logging.info("Running inference...") + """ # Initialize train and tests ELBO with empty lists. train_elbo = [] test_elbo = [] - succeeded = True + lr = [] + epoch_checkpoint_freq = 1000 # a large number... it will be recalculated + # Run training loop. Use try to allow for keyboard interrupt. try: - for epoch in range(1, epochs + 1): + + start_epoch = (1 if (model is None) or (len(model.loss['train']['epoch']) == 0) + else model.loss['train']['epoch'][-1] + 1) + + for epoch in range(start_epoch, epochs + 1): + + # In debug mode, log hardware load every epoch. + if args.debug: + # Don't spend time pinging usage stats if we will not use the log. + # TODO: use multiprocessing to sample these stats DURING training... + logger.debug('\n' + get_hardware_usage(use_cuda=model.use_cuda)) # Display duration of an epoch (use 2 to avoid initializations). - if epoch == 2: + if epoch == start_epoch + 1: t = time.time() + model.train() total_epoch_loss_train = train_epoch(svi, train_loader) train_elbo.append(-total_epoch_loss_train) - model.loss['train']['epoch'].append(epoch) - model.loss['train']['elbo'].append(-total_epoch_loss_train) - - if epoch == 2: - logging.info("[epoch %03d] average training loss: %.4f (%.1f seconds per epoch)" - % (epoch, total_epoch_loss_train, time.time() - t)) + try: + last_learning_rate = list(svi.optim.optim_objs.values())[0].get_last_lr()[0] + except AttributeError: + # not a scheduler + last_learning_rate = args.learning_rate + lr.append(last_learning_rate) + + if model is not None: + model.loss['train']['epoch'].append(epoch) + model.loss['train']['elbo'].append(-total_epoch_loss_train) + model.loss['learning_rate']['epoch'].append(epoch) + model.loss['learning_rate']['value'].append(last_learning_rate) + + if epoch == start_epoch + 1: + time_per_epoch = time.time() - t + logger.info("[epoch %03d] average training loss: %.4f (%.1f seconds per epoch)" + % (epoch, total_epoch_loss_train, time_per_epoch)) + epoch_checkpoint_freq = int(np.ceil(60 * checkpoint_freq / time_per_epoch)) + if (epoch_checkpoint_freq > 0) and (epoch_checkpoint_freq < epochs): + logger.info(f"Will checkpoint every {epoch_checkpoint_freq} epochs") + elif epoch_checkpoint_freq >= epochs: + logger.info(f"Will not checkpoint due to projected run " + f"completion in under {checkpoint_freq} min") else: - logging.info("[epoch %03d] average training loss: %.4f" - % (epoch, total_epoch_loss_train)) + logger.info("[epoch %03d] average training loss: %.4f" + % (epoch, total_epoch_loss_train)) # If there is no test data (training_fraction == 1.), skip test. - if len(test_loader) == 0: - continue - - # Every test_freq epochs, evaluate tests loss. - if epoch % test_freq == 0: - total_epoch_loss_test = evaluate_epoch(svi, test_loader) - test_elbo.append(-total_epoch_loss_test) - model.loss['test']['epoch'].append(epoch) - model.loss['test']['elbo'].append(-total_epoch_loss_test) - logging.info("[epoch %03d] average test loss: %.4f" - % (epoch, total_epoch_loss_test)) - if epoch_elbo_fail_fraction is not None and len(test_elbo) > 1 and \ - test_elbo[-1] < test_elbo[-2] and \ - (test_elbo[-2] - test_elbo[-1])/(test_elbo[-2] - train_elbo[0]) > epoch_elbo_fail_fraction: - logging.info( - "Training failed because this test loss (%.4f) exceeds previous test loss(%.4f) by >= %.2f%%, " - "relative to initial train loss %.4f" , - test_elbo[-1], test_elbo[-2], 100*epoch_elbo_fail_fraction, train_elbo[0]) - succeeded = False - break - - logging.info("Inference procedure complete.") - - if succeeded and final_elbo_fail_fraction is not None and len(test_elbo) > 1: + if (test_loader is not None) and (len(test_loader) > 0): + + # Every test_freq epochs, evaluate tests loss. + if epoch % test_freq == 0: + model.eval() + total_epoch_loss_test = evaluate_epoch(svi, test_loader) + test_elbo.append(-total_epoch_loss_test) + model.loss['test']['epoch'].append(epoch) + model.loss['test']['elbo'].append(-total_epoch_loss_test) + logger.info("[epoch %03d] average test loss: %.4f" + % (epoch, total_epoch_loss_test)) + + # Check whether test ELBO has spiked beyond specified conditions. + if (epoch_elbo_fail_fraction is not None) and (len(test_elbo) > 2): + current_diff = max(0., test_elbo[-2] - test_elbo[-1]) + overall_diff = np.abs(test_elbo[-2] - test_elbo[0]) + fractional_spike = current_diff / overall_diff + if fractional_spike > epoch_elbo_fail_fraction: + raise ElboException( + f'Training failed because test loss moved {current_diff:.2f} ' + f'in the wrong direction, and that is {fractional_spike:.2f} ' + f'of the total test ELBO change, > ' + f'specified epoch_elbo_fail_fraction {epoch_elbo_fail_fraction:.2f}' + ) + + # Checkpoint throughout and after final epoch. + if ((ckpt_tarball_name != 'none') + and (((checkpoint_freq > 0) and (epoch % epoch_checkpoint_freq == 0)) + or (epoch == epochs))): # checkpoint at final epoch + save_checkpoint(filebase=output_filename, + tarball_name=ckpt_tarball_name, + args=args, + model_obj=model, + scheduler=svi.optim, + train_loader=train_loader, + test_loader=test_loader) + + # Check on the final test ELBO to see if it meets criteria. + if final_elbo_fail_fraction is not None: best_test_elbo = max(test_elbo) - if test_elbo[-1] < best_test_elbo and \ - (best_test_elbo - test_elbo[-1])/(best_test_elbo - train_elbo[0]) > final_elbo_fail_fraction: - logging.info( - "Training failed because final test loss (%.4f) exceeds " - "best test loss(%.4f) by >= %.2f%%, relative to initial train loss %.4f", - test_elbo[-1], best_test_elbo, 100*final_elbo_fail_fraction, train_elbo[0]) - succeeded = False + if test_elbo[-1] < best_test_elbo: + final_best_diff = best_test_elbo - test_elbo[-1] + initial_best_diff = best_test_elbo - test_elbo[0] + if (final_best_diff / initial_best_diff) > final_elbo_fail_fraction: + raise ElboException( + f'Training failed because final test loss {test_elbo[-1]:.2f} ' + f'is not sufficiently close to best test loss {best_test_elbo:.2f}, ' + f'compared to the initial test loss {test_elbo[0]:.2f}. ' + f'Fractional difference is {final_best_diff / initial_best_diff:.2f}, ' + f'which is > specified final_elbo_fail_fraction {final_elbo_fail_fraction:.2f}' + ) # Exception allows program to continue after ending inference prematurely. except KeyboardInterrupt: - - logging.info("Inference procedure stopped by keyboard interrupt.") + logger.info("Inference procedure stopped by keyboard interrupt... " + "will save a checkpoint.") + save_checkpoint(filebase=output_filename, + tarball_name=ckpt_tarball_name, + args=args, + model_obj=model, + scheduler=svi.optim, + train_loader=train_loader, + test_loader=test_loader) + + except ElboException as e: + logger.info(e.message) + raise e # re-raise the exception to pass it back to caller function # Exception allows program to produce output when terminated by a NaN. except NanException as nan: - print(nan.message) - logging.info(f"Inference procedure terminated early due to a NaN value in: {nan.param}\n\n" - f"The suggested fix is to reduce the learning rate.\n\n") - succeeded = False - - if succeeded: - logging.info("Training succeeded") - logging.info(datetime.now().strftime('%Y-%m-%d %H:%M:%S')) + logger.info(f"Inference procedure terminated early due to a NaN value in: {nan.param}\n\n" + f"The suggested fix is to reduce the learning rate by a factor of two.\n\n") + sys.exit(1) - return train_elbo, test_elbo, succeeded + logger.info(datetime.now().strftime('%Y-%m-%d %H:%M:%S')) + # Check final ELBO meets conditions. + if (final_elbo_fail_fraction is not None) and (len(test_elbo) > 1): + best_test_elbo = max(test_elbo) + if -test_elbo[-1] >= -best_test_elbo * (1 + final_elbo_fail_fraction): + raise ElboException(f'Training failed because final test loss ({-test_elbo[-1]:.4f}) ' + f'exceeds best test loss ({-best_test_elbo:.4f}) by >= ' + f'{100 * final_elbo_fail_fraction:.1f}%') -def run_inference(dataset_obj: SingleCellRNACountsDataset, - args) -> RemoveBackgroundPyroModel: - """Run a full inference procedure, training a latent variable model. - - Args: - dataset_obj: Input data in the form of a SingleCellRNACountsDataset - object. - args: Input command line parsed arguments. + # Free up all the GPU memory we can once training is complete. + torch.cuda.empty_cache() - Returns: - model: cellbender.model.RemoveBackgroundPyroModel that has had - inference run. - - """ - - # Get the trimmed count matrix (transformed if called for). - count_matrix = dataset_obj.get_count_matrix() - - # Configure pyro options (skip validations to improve speed). - pyro.enable_validation(False) - pyro.distributions.enable_validation(False) - - # Load the dataset into DataLoaders. - frac = args.training_fraction # Fraction of barcodes to use for training - batch_size = int(min(300, frac * dataset_obj.analyzed_barcode_inds.size / 2)) - - for attempt in range(args.num_training_tries): - # set seed for every attempt for reproducibility - pyro.set_rng_seed(0) - pyro.clear_param_store() - - # Set up the variational autoencoder: - - # Encoder. - encoder_z = EncodeZ(input_dim=count_matrix.shape[1], - hidden_dims=args.z_hidden_dims, - output_dim=args.z_dim, - input_transform='normalize') - - encoder_other = EncodeNonZLatents(n_genes=count_matrix.shape[1], - z_dim=args.z_dim, - hidden_dims=consts.ENC_HIDDEN_DIMS, - log_count_crossover=dataset_obj.priors['log_counts_crossover'], - prior_log_cell_counts=np.log1p(dataset_obj.priors['cell_counts']), - input_transform='normalize') - - encoder = CompositeEncoder({'z': encoder_z, - 'other': encoder_other}) - - # Decoder. - decoder = Decoder(input_dim=args.z_dim, - hidden_dims=args.z_hidden_dims[::-1], - output_dim=count_matrix.shape[1]) - - # Set up the pyro model for variational inference. - model = RemoveBackgroundPyroModel(model_type=args.model, - encoder=encoder, - decoder=decoder, - dataset_obj=dataset_obj, - use_cuda=args.use_cuda) - - train_loader, test_loader = \ - prep_data_for_training(dataset=count_matrix, - empty_drop_dataset= - dataset_obj.get_count_matrix_empties(), - random_state=dataset_obj.random, - batch_size=batch_size, - training_fraction=frac, - fraction_empties=args.fraction_empties, - shuffle=True, - use_cuda=args.use_cuda) - - # Set up the optimizer. - optimizer = pyro.optim.clipped_adam.ClippedAdam - optimizer_args = {'lr': args.learning_rate, 'clip_norm': 10.} - - # Set up a learning rate scheduler. - minibatches_per_epoch = int(np.ceil(len(train_loader) / train_loader.batch_size).item()) - scheduler_args = {'optimizer': optimizer, - 'max_lr': args.learning_rate * 10, - 'steps_per_epoch': minibatches_per_epoch, - 'epochs': args.epochs, - 'optim_args': optimizer_args} - scheduler = pyro.optim.OneCycleLR(scheduler_args) - - # Determine the loss function. - if args.use_jit: - - # Call guide() once as a warm-up. - model.guide(torch.zeros([10, dataset_obj.analyzed_gene_inds.size]).to(model.device)) - - if args.model == "simple": - loss_function = JitTrace_ELBO() - else: - loss_function = JitTraceEnum_ELBO(max_plate_nesting=1, - strict_enumeration_warning=False) - else: - - if args.model == "simple": - loss_function = Trace_ELBO() - else: - loss_function = TraceEnum_ELBO(max_plate_nesting=1) - - # Set up the inference process. - svi = SVI(model.model, model.guide, scheduler, - loss=loss_function) - - # Run training. - train_elbo, test_elbo, succeeded = run_training(model, svi, train_loader, test_loader, - epochs=args.epochs, test_freq=5, - final_elbo_fail_fraction=args.final_elbo_fail_fraction, - epoch_elbo_fail_fraction=args.epoch_elbo_fail_fraction) - if succeeded or attempt+1 >= args.num_training_tries: - break - else: - args.learning_rate = args.learning_rate * args.learning_rate_retry_mult - logging.info("Learning failed. Retrying with learning-rate %.8f" % args.learning_rate) - - return model + return train_elbo, test_elbo diff --git a/cellbender/remove_background/vae/base.py b/cellbender/remove_background/vae/base.py new file mode 100644 index 00000000..2e8b93c8 --- /dev/null +++ b/cellbender/remove_background/vae/base.py @@ -0,0 +1,164 @@ +"""Base neural network architectures, for convenience""" + +import torch +from typing import Optional, List + + +class Exp(torch.nn.Module): + """Exponential activation function as a torch module""" + + def __init__(self, eps: float = 1e-5): + """Exponential activation function with numerical stabilization, useful + for outputs that must be > 0 + + NOTE: output = torch.exp(input) + eps + + Parameters + ---------- + eps: Numerical stability additive constant. + """ + super().__init__() + self.eps = eps + + def forward(self, x): + return torch.exp(x) + self.eps + + def __repr__(self): + return f"torch.exp() + {self.eps}" + + +class FullyConnectedLayer(torch.nn.Module): + """Neural network unit made of a fully connected linear layer, but + customizable including shapes, activations, batch norm, layer norm, and + dropout. + + Parameters + ---------- + input_dim: Number of features for input + output_dim: Number of features for output + activation: Activation function to be applied to each hidden layer + (default :py:class:`torch.nn.ReLU`) + use_batch_norm: True to apply batch normalization using + :py:class:`torch.nn.BatchNorm1d` with ``momentum=0.01``, ``eps=0.001`` + (default False) + use_layer_norm: True to apply layer normalization (after optional batch + normalization) using :py:class:`torch.nn.LayerNorm` with + ``elementwise_affine=False`` (default False) + dropout_rate: Dropout rate to use in :py:class:`torch.nn.Dropout` before + linear layer + + """ + + def __init__( + self, + input_dim: int, + output_dim: int, + activation: torch.nn.Module = torch.nn.ReLU, + use_batch_norm: bool = False, + use_layer_norm: bool = False, + dropout_rate: Optional[float] = None, + ): + super().__init__() + self.input_dim = input_dim + self.output_dim = output_dim + + # set up layers as a list of Linear modules with appropriate extras + modules = [] + if dropout_rate is not None: + modules.append(torch.nn.Dropout(p=dropout_rate)) + modules.append(torch.nn.Linear(in_features=input_dim, out_features=output_dim)) + if use_batch_norm: + modules.append( + torch.nn.BatchNorm1d(num_features=output_dim, momentum=0.01, eps=0.001) + ) + if use_layer_norm: + modules.append( + torch.nn.LayerNorm( + normalized_shape=output_dim, elementwise_affine=False + ) + ) + if activation is not None: + modules.append(activation) + + # concatenate Linear layers using Sequential + self.layer = torch.nn.Sequential(*modules) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + return self.layer(x) + + +class FullyConnectedNetwork(torch.nn.Module): + """Neural network made of fully connected linear layers, + :py:class:`FullyConnectedLayer`. Architecture is customizable including + shapes, activations, batch norm, layer norm, and dropout. + + Parameters + ---------- + input_dim: Number of features for input + hidden_dims: List of hidden layer sizes, can be empty list [] + output_dim: Number of features for output + hidden_activation: Activation function to be applied to each hidden layer + (default :py:class:`torch.nn.ReLU`) + output_activation: Activation function to be applied to output (default None) + use_batch_norm: True to apply batch normalization using + :py:class:`torch.nn.BatchNorm1d` with ``momentum=0.01``, ``eps=0.001`` + (default False) + use_layer_norm: True to apply layer normalization (after optional batch + normalization) using :py:class:`torch.nn.LayerNorm` with + ``elementwise_affine=False`` (default False) + norm_output: True to apply normalization to output layer before output + activation (default False) + dropout_rate: Dropout rate to use in :py:class:`torch.nn.Dropout` for each + hidden layer (applied before each layer) + dropout_input: True to apply dropout before first layer (default False) + """ + + def __init__( + self, + input_dim: int, + hidden_dims: List[int], + output_dim: int, + hidden_activation: torch.nn.Module = torch.nn.ReLU(), + output_activation: Optional[torch.nn.Module] = None, + use_batch_norm: bool = False, + use_layer_norm: bool = False, + norm_output: bool = False, + dropout_rate: Optional[float] = None, + dropout_input: bool = False, + ): + super().__init__() + + if use_layer_norm and use_batch_norm: + raise UserWarning( + "You are trying to use both batch norm and layer " + "norm. That's probably too much norm." + ) + + # set up layers as a list of Linear modules with appropriate extras + dim_ins_and_outs = zip([input_dim] + hidden_dims, hidden_dims + [output_dim]) + n_layers = 1 + len(hidden_dims) + layers = [ + FullyConnectedLayer( + input_dim=i, + output_dim=j, + activation=hidden_activation + if (layer < n_layers - 1) + else output_activation, + use_batch_norm=use_batch_norm + if ((layer < n_layers - 1) or norm_output) + else False, + use_layer_norm=use_layer_norm + if ((layer < n_layers - 1) or norm_output) + else False, + dropout_rate=None + if ((layer == 0) and not dropout_input) + else dropout_rate, + ) + for layer, (i, j) in enumerate(dim_ins_and_outs) + ] + + # concatenate Linear layers using Sequential + self.network = torch.nn.Sequential(*layers) + + def forward(self, x: torch.Tensor) -> torch.Tensor: + return self.network(x) diff --git a/cellbender/remove_background/vae/decoder.py b/cellbender/remove_background/vae/decoder.py index 56b0a58a..8d56eef2 100644 --- a/cellbender/remove_background/vae/decoder.py +++ b/cellbender/remove_background/vae/decoder.py @@ -1,9 +1,8 @@ import torch -import torch.nn as nn -from typing import List +from cellbender.remove_background.vae.base import FullyConnectedNetwork -class Decoder(nn.Module): +class Decoder(FullyConnectedNetwork): """Decoder module transforms latent representation into gene expression. The number of input units is the dimension of the latent space and the @@ -20,6 +19,8 @@ class Decoder(nn.Module): expression will be embedded. hidden_dims: Size of each of the hidden layers. output_dim: Number of genes. The size of the output of this decoder. + use_layernorm: True to use LayerNorm after each hidden layer is + computed, before the activation log_output: Whether or not the output is in log space. Attributes: @@ -36,37 +37,10 @@ class Decoder(nn.Module): """ - def __init__(self, - input_dim: int, - hidden_dims: List[int], - output_dim: int, - log_output: bool = False): - super(Decoder, self).__init__() + def __init__(self, input_dim: int, **kwargs): + super().__init__(input_dim=input_dim, **kwargs) self.input_dim = input_dim - self.log_output = log_output - - # Set up the linear transformations used in fully-connected layers. - self.linears = nn.ModuleList([nn.Linear(input_dim, hidden_dims[0])]) - for i in range(1, len(hidden_dims)): # Second hidden layer onward - self.linears.append(nn.Linear(hidden_dims[i-1], hidden_dims[i])) - self.outlinear = nn.Linear(hidden_dims[-1], output_dim) - - # Set up the non-linear activations. - self.softplus = nn.Softplus() - if log_output: - self.softmax = nn.LogSoftmax(dim=-1) - else: - self.softmax = nn.Softmax(dim=-1) + self.softmax = torch.nn.Softmax(dim=-1) def forward(self, z: torch.Tensor) -> torch.Tensor: - # Define the forward computation to go from latent z to gene expression. - - # Compute the hidden layers. - hidden = self.softplus(self.linears[0](z)) - for i in range(1, len(self.linears)): # Second hidden layer onward - hidden = self.softplus(self.linears[i](hidden)) - - # Compute the output, which is on a simplex. - gene_exp = self.softmax(self.outlinear(hidden)) - - return gene_exp + return self.softmax(self.network(z)) diff --git a/cellbender/remove_background/vae/encoder.py b/cellbender/remove_background/vae/encoder.py index 6862cdf2..909ada9b 100644 --- a/cellbender/remove_background/vae/encoder.py +++ b/cellbender/remove_background/vae/encoder.py @@ -1,5 +1,9 @@ import torch import torch.nn as nn +import pyro +import numpy as np +from cellbender.remove_background.vae.base import FullyConnectedNetwork +from cellbender.remove_background import consts from typing import Dict, List, Optional @@ -23,6 +27,9 @@ def __init__(self, module_dict): super(CompositeEncoder, self).__init__(module_dict) self.module_dict = module_dict + def __call__(self, **kwargs): + return self.forward(**kwargs) + def forward(self, **kwargs) \ -> Dict[str, torch.Tensor]: @@ -47,7 +54,7 @@ def forward(self, **kwargs) \ return out -class EncodeZ(nn.Module): +class EncodeZ(FullyConnectedNetwork): """Encoder module transforms gene expression into latent representation. The number of input units is the total number of genes and the number of @@ -85,35 +92,34 @@ class EncodeZ(nn.Module): """ - def __init__(self, input_dim: int, hidden_dims: List[int], output_dim: int, - input_transform: str = None): - super(EncodeZ, self).__init__() + def __init__(self, + input_dim: int, + hidden_dims: List[int], + output_dim: int, + input_transform: str = None, + **kwargs): + assert len(hidden_dims) > 0, 'EncodeZ needs to have at least one hidden layer' + super(EncodeZ, self).__init__(input_dim=input_dim, + hidden_dims=hidden_dims[:-1], + output_dim=hidden_dims[-1], + hidden_activation=nn.Softplus(), + output_activation=nn.Softplus(), + norm_output=True, + **kwargs) + self.transform = input_transform self.input_dim = input_dim self.output_dim = output_dim - self.transform = input_transform - - # Set up the linear transformations used in fully-connected layers. - self.linears = nn.ModuleList([nn.Linear(input_dim, hidden_dims[0])]) - for i in range(1, len(hidden_dims)): # Second hidden layer onward - self.linears.append(nn.Linear(hidden_dims[i-1], hidden_dims[i])) self.loc_out = nn.Linear(hidden_dims[-1], output_dim) self.sig_out = nn.Linear(hidden_dims[-1], output_dim) - # Set up the non-linear activations. - self.softplus = nn.Softplus() - - def forward(self, x: torch.Tensor, **kwargs) -> Dict[str, torch.Tensor]: - # Define the forward computation to go from gene expression to latent - # representation. + def forward(self, x: torch.Tensor, **kwargs) -> torch.Tensor: # Transform input. x = x.reshape(-1, self.input_dim) - x = transform_input(x, self.transform) + x_ = transform_input(x, self.transform) - # Compute the hidden layers. - hidden = self.softplus(self.linears[0](x)) - for i in range(1, len(self.linears)): # Second hidden layer onward - hidden = self.softplus(self.linears[i](hidden)) + # Obtain last hidden layer. + hidden = self.network(x_) # Compute the outputs: loc is any real number, scale must be positive. loc = self.loc_out(hidden) @@ -122,6 +128,10 @@ def forward(self, x: torch.Tensor, **kwargs) -> Dict[str, torch.Tensor]: return {'loc': loc.squeeze(), 'scale': scale.squeeze()} +def _poisson_log_prob(lam, value): + return (lam.log() * value) - lam - (value + 1).lgamma() + + class EncodeNonZLatents(nn.Module): """Encoder module that transforms data into all latents except z. @@ -175,66 +185,59 @@ class EncodeNonZLatents(nn.Module): def __init__(self, n_genes: int, z_dim: int, - hidden_dims: List[int], log_count_crossover: float, # prior on log counts of smallest cell - prior_log_cell_counts: int, # prior on counts per cell + prior_log_cell_counts: float, # prior on counts per cell + empty_log_count_threshold: float, + prior_logit_cell_prob: float, input_transform: Optional[str] = None): super(EncodeNonZLatents, self).__init__() self.n_genes = n_genes self.z_dim = z_dim self.transform = input_transform - self.output_dim = 3 + self.output_dim = 1 # Values related to logit cell probability - self.INITIAL_WEIGHT_FOR_LOG_COUNTS = 2. - self.P_OUTPUT_SCALE = 1. + self.INITIAL_WEIGHT_FOR_LOG_COUNTS = 1. + self.P_OUTPUT_SCALE = 5. self.log_count_crossover = log_count_crossover + self.empty_log_count_threshold = empty_log_count_threshold self.prior_log_cell_counts = prior_log_cell_counts + self.prior_logit_cell_prob = prior_logit_cell_prob # Values related to epsilon - self.EPS_OUTPUT_SCALE = 0.05 # slows down learning for epsilon - self.EPS_OUTPUT_MEAN = 1. - - # Set up the linear transformations used in fully-connected layers. - - self.linears = nn.ModuleList([nn.Linear(3 + self.n_genes, - hidden_dims[0])]) - for i in range(1, len(hidden_dims)): # Second hidden layer onward - self.linears.append(nn.Linear(hidden_dims[i-1], hidden_dims[i])) - self.output = nn.Linear(hidden_dims[-1], self.output_dim) - - # Adjust initialization conditions to start with a reasonable output. - self._weight_init() + self.EPS_OUTPUT_SCALE = 0.2 # slows down learning for epsilon + self.EPS_OUTPUT_MEAN = 0.6931 # log(e - 1) # softplus(0.6931) = 1. + + # Set up network for inference of p + additional_features_p = 4 + self.layer1 = nn.Linear(additional_features_p + self.n_genes, 512) + self.batchnorm1 = nn.BatchNorm1d(num_features=512) + self.layer2 = nn.Linear(additional_features_p + 512, 512) + self.batchnorm2 = nn.BatchNorm1d(num_features=512) + self.layer3 = nn.Linear(additional_features_p + 512, 1) + + # Set up network for inference of epsilon + additional_features_eps = 4 + self.eps_network = nn.Sequential( + nn.Linear(additional_features_eps + self.n_genes, 512), + nn.BatchNorm1d(num_features=512), + nn.Softplus(), + nn.Linear(512, 512), + nn.BatchNorm1d(num_features=512), + nn.Softplus(), + nn.Linear(512, 1), + ) # Set up the non-linear activations. - self.nonlin = nn.Softplus() self.softplus = nn.Softplus() + self.dropout50 = nn.Dropout1d(p=0.5) # Set up the initial biases. self.offset = None # Set up the initial scaling for values of x. self.x_scaling = None - - # Set up initial values for overlap normalization. - self.overlap_mean = None - self.overlap_std = None - - def _weight_init(self): - """Initialize neural network weights""" - - # Initialize p to be a sigmoid function of UMI counts. - for linear in self.linears: - with torch.no_grad(): - linear.weight[0][0] = 1. - with torch.no_grad(): - self.output.weight[0][0] = self.INITIAL_WEIGHT_FOR_LOG_COUNTS - # Prevent a negative weight from starting something inverted. - self.output.weight[1][0] = torch.abs(self.output.weight[1][0]) - self.output.weight[2][0] = torch.abs(self.output.weight[2][0]) - - def _poisson_log_prob(self, lam, value): - return (lam.log() * value) - lam - (value + 1).lgamma() + self.batchnorm0 = nn.BatchNorm1d(num_features=self.n_genes) def forward(self, x: torch.Tensor, @@ -256,44 +259,55 @@ def forward(self, # Calculate the log of the number of nonzero genes. log_nnz = (x > 0).sum(dim=-1, keepdim=True).float().log1p() - # Calculate a similarity between expression and ambient. + # Calculate probability that log counts are consistent with d_empty. if chi_ambient is not None: - overlap = self._poisson_log_prob(lam=counts * chi_ambient.detach().unsqueeze(0), - value=x).sum(dim=-1, keepdim=True) - if self.overlap_mean is None: - self.overlap_mean = (overlap.max() + overlap.min()) / 2 - self.overlap_std = overlap.max() - overlap.min() - overlap = (overlap - self.overlap_mean) / self.overlap_std * 5 + # Gaussian log probability + overlap = -0.5 * ( + torch.clamp(log_sum - pyro.param("d_empty_loc").detach(), min=0.) + / 0.1 + ).pow(2) else: overlap = torch.zeros_like(counts) + # Calculate a dot product between expression and ambient, for epsilon. + if chi_ambient is not None: + x_ambient = pyro.param("d_empty_loc").exp().detach() * chi_ambient.detach().unsqueeze(0) + x_ambient_norm = x_ambient / torch.linalg.vector_norm(x_ambient, ord=2, dim=-1, keepdim=True) + eps_overlap = (x_ambient_norm * x).sum(dim=-1, keepdim=True) + else: + eps_overlap = torch.zeros_like(counts) + # Apply transformation to data. x = transform_input(x, self.transform) - # Calculate a scale factor (first time through) to control the input variance. - if self.x_scaling is None: - n_std_est = 10 - num = int(self.n_genes * 0.4) - std_estimates = torch.zeros([n_std_est]) - for i in range(n_std_est): - idx = torch.randperm(x.nelement()) - std_estimates[i] = x.view(-1)[idx][:num].std().item() - robust_std = std_estimates.median().item() - self.x_scaling = (1. / robust_std) / 100. # Get values on a level field - # Form a new input by concatenation. # Compute the hidden layers and the output. - x_in = torch.cat((log_sum, - log_nnz, - overlap, - x * self.x_scaling), - dim=-1) - - hidden = self.nonlin(self.linears[0](x_in)) - for i in range(1, len(self.linears)): # Second hidden layer onward - hidden = self.nonlin(self.linears[i](hidden)) - - out = self.output(hidden).squeeze(-1) + x_in = self.dropout50(self.batchnorm0(x)) + p_extra_features = torch.cat( + (log_sum, + log_nnz, + overlap, + torch.linalg.vector_norm(z.detach(), ord=2, dim=-1, keepdim=True)), + dim=-1, + ) + eps_extra_features = torch.cat( + (log_sum, + log_nnz, + eps_overlap, + torch.linalg.vector_norm(z.detach(), ord=2, dim=-1, keepdim=True)), + dim=-1, + ) + + def add_extra_features(y, features): + return torch.cat((features, y), dim=-1) + + # Do the forward pass for p + x_ = self.softplus(self.batchnorm1(self.layer1(add_extra_features(x_in, p_extra_features)))) + x_ = self.softplus(self.batchnorm2(self.layer2(add_extra_features(x_, p_extra_features)))) + p_out = self.layer3(add_extra_features(x_, p_extra_features)).squeeze() + + # Do the forward pass for epsilon + eps_out = self.eps_network(add_extra_features(x_in, eps_extra_features)).squeeze() if self.offset is None: @@ -301,39 +315,53 @@ def forward(self, # Heuristic for initialization of logit_cell_probability. cells = (log_sum > self.log_count_crossover).squeeze() - if (cells.sum() > 0) and ((~cells).sum() > 0): - cell_median = out[cells, 0].median().item() - empty_median = out[~cells, 0].median().item() - self.offset['logit_p'] = empty_median + (cell_median - empty_median) * 9. / 10 - else: - self.offset['logit_p'] = 0. - - # Heuristic for initialization of d. - self.offset['d'] = out[cells, 1].median().item() + assert cells.sum() > 4, "Fewer than 4 cells passed to encoder minibatch" + self.offset['logit_p'] = p_out.mean().item() # Heuristic for initialization of epsilon. - self.offset['epsilon'] = out[cells, 2].mean().item() + self.offset['epsilon'] = eps_out[cells].mean().item() + + p_y_logit = ( + (p_out - self.offset['logit_p']) + + ((log_sum.squeeze() - self.log_count_crossover).abs().pow(0.5) + * torch.sign(log_sum.squeeze() - self.log_count_crossover) + * 10.) + ) + + # Enforce high cell prob for known cells + beta = 50. # like a temperature for the sigmoid's sharpness + alpha = (beta * (log_sum - self.prior_log_cell_counts)).sigmoid().squeeze() + p_y_logit = (1. - alpha) * p_y_logit + alpha * consts.REG_LOGIT_MEAN - p_y_logit = ((out[:, 0] - self.offset['logit_p']) - * self.P_OUTPUT_SCALE).squeeze() - epsilon = self.softplus((out[:, 2] - self.offset['epsilon']).squeeze() - * self.EPS_OUTPUT_SCALE + self.EPS_OUTPUT_MEAN) + # Enforce low cell prob for known empties + alpha_empty = (beta * (log_sum - self.empty_log_count_threshold)).sigmoid().squeeze() + p_y_logit = alpha_empty * p_y_logit + (1. - alpha_empty) * (-1 * consts.REG_LOGIT_MEAN) + + # Constrain epsilon in (0.5, 2.5) with eps_out 0 mapping to epsilon 1 + # 1.0986122886681098 = log(3) + epsilon = 2. * (eps_out * self.EPS_OUTPUT_SCALE - 1.0986122886681098).sigmoid() + 0.5 + + d_empty = pyro.param("d_empty_loc").exp().detach() + + d_loc = self.softplus( + (self.softplus(counts.squeeze() / (epsilon + 1e-2) - d_empty) + 1e-10).log() + - self.log_count_crossover + ) + self.log_count_crossover + # d_loc = (d_loc + d_loc_est) / 2 return {'p_y': p_y_logit, - 'd_loc': self.softplus(out[:, 1] - self.offset['d'] - + self.softplus(log_sum.squeeze() - - self.log_count_crossover) - + self.log_count_crossover).squeeze(), + 'd_loc': d_loc, 'epsilon': epsilon} -def transform_input(x: torch.Tensor, transform: str) -> torch.Tensor: +def transform_input(x: torch.Tensor, transform: str, eps: float = 1e-5) -> torch.Tensor: """Transform input to encoder. Args: x: Input torch.Tensor transform: Specifies which transformation to perform. Must be one of - ['log', 'normalize']. + ['log', 'normalize', 'normalize_log', 'log_normalize']. + eps: Preclude nan values in case of an input x with zero counts for a cell Returns: Transformed input as a torch.Tensor of the same type and shape as x. @@ -348,7 +376,17 @@ def transform_input(x: torch.Tensor, transform: str) -> torch.Tensor: return x elif transform == 'normalize': - x = x / x.sum(dim=-1, keepdim=True) + x = x / (x.sum(dim=-1, keepdim=True) + eps) + return x + + elif transform == 'normalize_log': + x = x.log1p() + x = x / (x.sum(dim=-1, keepdim=True) + eps) + return x + + elif transform == 'log_normalize': + x = x / (x.sum(dim=-1, keepdim=True) + eps) + x = x.log1p() return x else: diff --git a/docker/Dockerfile b/docker/Dockerfile index 9b35e0f2..1a37bc40 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,40 +1,35 @@ # Start from nvidia-docker image with drivers pre-installed to use a GPU -FROM nvcr.io/nvidia/cuda:9.2-base-ubuntu16.04 +FROM nvcr.io/nvidia/cuda:11.7.1-base-ubuntu18.04 -LABEL maintainer="Stephen Fleming <sfleming@broadinstitute.org>" +# Copy the local cellbender repo +ADD . /software/cellbender -# Install curl and sudo and git and miniconda and pytorch, cudatoolkit, pytables, and cellbender -RUN apt-get update && apt-get install -y --no-install-recommends \ - curl \ - ca-certificates \ - sudo \ - && sudo apt-get install -y --no-install-recommends \ - git \ - bzip2 \ +LABEL maintainer="Stephen Fleming <sfleming@broadinstitute.org>" +ENV DOCKER=true \ + CONDA_AUTO_UPDATE_CONDA=false \ + CONDA_DIR="/opt/conda" \ + GCLOUD_DIR="/opt/gcloud" \ + GOOGLE_CLOUD_CLI_VERSION="397.0.0" \ + GIT_SHA=$GIT_SHA +ENV PATH="$CONDA_DIR/bin:$GCLOUD_DIR/google-cloud-sdk/bin:$PATH" + +RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates sudo \ + && apt-get clean \ && sudo rm -rf /var/lib/apt/lists/* \ - && curl -so ~/miniconda.sh https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh \ - && chmod +x ~/miniconda.sh \ - && ~/miniconda.sh -b -p /home/user/miniconda \ - && rm ~/miniconda.sh - -ENV PATH=/home/user/miniconda/bin:$PATH -ENV CONDA_AUTO_UPDATE_CONDA=false - -RUN conda install -y "pytorch>=1.9.0" torchvision cudatoolkit -c pytorch \ - && conda install -y -c anaconda pytables \ - && conda clean -ya - -ENV DOCKER='true' - -RUN git clone https://github.com/broadinstitute/CellBender.git cellbender \ - && yes | pip install -e cellbender \ +# get miniconda + && curl -so $HOME/miniconda.sh https://repo.anaconda.com/miniconda/Miniconda3-py37_23.1.0-1-Linux-x86_64.sh \ + && chmod +x $HOME/miniconda.sh \ + && $HOME/miniconda.sh -b -p $CONDA_DIR \ + && rm $HOME/miniconda.sh \ +# get gsutil + && mkdir -p $GCLOUD_DIR \ + && curl -so $HOME/google-cloud-cli.tar.gz https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-${GOOGLE_CLOUD_CLI_VERSION}-linux-x86_64.tar.gz \ + && tar -xzf $HOME/google-cloud-cli.tar.gz -C $GCLOUD_DIR \ + && .$GCLOUD_DIR/google-cloud-sdk/install.sh --usage-reporting false \ + && rm $HOME/google-cloud-cli.tar.gz \ +# get compiled crcmod for gsutil + && conda install -y -c conda-forge crcmod \ +# install cellbender and its dependencies + && yes | pip install -e /software/cellbender/ \ + && conda clean -yaf \ && sudo rm -rf ~/.cache/pip - -# google cloud SDK and gsutil -RUN curl -sSL https://sdk.cloud.google.com | bash -RUN conda install -y -c conda-forge google-api-python-client oauth2client google-auth \ - google-cloud-sdk google-auth-oauthlib \ - && conda clean -ya - -# Add cellbender command to PATH -ENV PATH="~/miniconda/bin:${PATH}" diff --git a/docker/DockerfileGit b/docker/DockerfileGit new file mode 100644 index 00000000..05bbde40 --- /dev/null +++ b/docker/DockerfileGit @@ -0,0 +1,35 @@ +# Start from nvidia-docker image with drivers pre-installed to use a GPU +FROM nvcr.io/nvidia/cuda:11.7.1-base-ubuntu18.04 + +# Specify a certain commit of CellBender via branch, tag, or sha +ARG GIT_SHA + +LABEL maintainer="Stephen Fleming <sfleming@broadinstitute.org>" +ENV DOCKER=true \ + CONDA_AUTO_UPDATE_CONDA=false \ + CONDA_DIR="/opt/conda" \ + GCLOUD_DIR="/opt/gcloud" \ + GOOGLE_CLOUD_CLI_VERSION="397.0.0" \ + GIT_SHA=$GIT_SHA +ENV PATH="$CONDA_DIR/bin:$GCLOUD_DIR/google-cloud-sdk/bin:$PATH" + +RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates sudo git \ + && apt-get clean \ + && sudo rm -rf /var/lib/apt/lists/* \ +# get miniconda + && curl -so $HOME/miniconda.sh https://repo.anaconda.com/miniconda/Miniconda3-py37_23.1.0-1-Linux-x86_64.sh \ + && chmod +x $HOME/miniconda.sh \ + && $HOME/miniconda.sh -b -p $CONDA_DIR \ + && rm $HOME/miniconda.sh \ +# get gsutil + && mkdir -p $GCLOUD_DIR \ + && curl -so $HOME/google-cloud-cli.tar.gz https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-${GOOGLE_CLOUD_CLI_VERSION}-linux-x86_64.tar.gz \ + && tar -xzf $HOME/google-cloud-cli.tar.gz -C $GCLOUD_DIR \ + && .$GCLOUD_DIR/google-cloud-sdk/install.sh --usage-reporting false \ + && rm $HOME/google-cloud-cli.tar.gz \ +# get compiled crcmod for gsutil + && conda install -y -c conda-forge crcmod \ +# install cellbender and its dependencies + && yes | pip install --no-cache-dir -U git+https://github.com/broadinstitute/CellBender.git@$GIT_SHA \ + && conda clean -yaf \ + && sudo rm -rf ~/.cache/pip diff --git a/docs/source/_static/remove_background/PCL_rat_A_LA6_learning_curve.png b/docs/source/_static/remove_background/PCL_rat_A_LA6_learning_curve.png new file mode 100644 index 0000000000000000000000000000000000000000..4f66e009c04c33fce8ccc0860f64019e9f7f515c GIT binary patch literal 23433 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 E0Am;H3IG5A literal 0 HcmV?d00001 diff --git a/docs/source/_static/remove_background/bad_learning_curves.png b/docs/source/_static/remove_background/bad_learning_curves.png new file mode 100644 index 0000000000000000000000000000000000000000..356a8d1c6b45f2017c885017be80d8f424a60c7a GIT binary patch literal 214054 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%0Dha1!zxq*N zHRM2VTQEQChOn{F$NICJ_7+x^31^6{GvG_pLd^X4S3ktaL99Y^(cHD2nH#@27lFIK zdxv-HWcTZNRhM6HZ$TpQClJ|3SAQ1sjkQD)&A(1uf?8bPd%%g#WB@1_x274E#E(Yd zL2rHBv2=27i^58ew?2@v?9NmL=$X+`)ZY>6E?x#u?2epV7f75-?W$7{ea*jgw^ikV z13#lFF#A4#b&j0B>w91Y;<os}d|utPA8&?v^jmmStiypsw=&wlMTDY=(`i)_(wKh5 zh51GO%^-|%Ra3!3N<deXuNbpZNjRq3RkDoN;=}9tU2&|7jW1n<`J<5xVRCxNLzLL; zV^=(8qNaUBkD%_fEm+v?YWk~{ci`so(+6SkJ#wrAohfU=C*ZS9Hl=&ca@eJl?<&&? zJ@0JAghK;O{{_3y=F=anM^H#Pq^1*e@(37cd~nzb(?$|v<k0KvCq#=#a+0ND{@!39 zK@>Cf+pARXf9kT(tWjn|^#gXG2P@)LTvy;ga68Gc9aCyv@_ho|!qf-S0;|Q4EKuPi zcr2?d!p;xGiDrM4I7LApF8VgpaPH@MgXjF_yBG`^<RRR{soBd&_MP1T7G28pHyzSR zqSqd0Vr$fMrvO7J;8~%Tdm{g(#4F>!jA%bf)5#efzd5g}n@2?|y5RBHdWamfQN{>m z$mZk~>}xWH%<sNPF3*}ECh}YK`c6SH%#6Fy=fJop84?mws}*Wzch$@W`b%VDRO~)B zxsq~f`xz}YH8Ca(cW*Cut=f{%U}$6><Lnim{k3p+M&v4N%z~g=Pqs|p7F#NiIdvpX zGrqNA<hpJ4sRm$;D^H@*bHo|!Et>97vqv>!Tin<iyLk`s`Ivt~?1E6^2rqu{?XZ~7 zw2f2$0hXW|*zJ{Snk26hFiqYtxTK=zgR62YLodbM>i0|Ks0v;0mb#G&_vueE?-Pj3 zT$s_55$BE%jMyo<8P=jLnBNH&jA~}VrW6D(Q+(IvX-UxFRI6`o4lEmBO`w1uRM%u6 z)Jkl3wMLcd6*=*YK0P0etn~}Kkr4#2Tr^e7cfyFJ<rbr5$Ao<9sqN)GIsM5Z#BqD` zcE7KuPe}n|d($p(Mb}MM9c|RZ=Lud-J2_~z={aLQG9>Fj%l$9!Ul5>>N@?6W!t-@A z1~3=kwU`9*O@X^`LaEEpS{+qL9TjO>N$Jfo^u@)p)z`HZTZUrm^#i1{BAQW_=d8b! zHrp+>FZpbV0=y6d^z;<mI{L{1C<XJp{*sl+F`<#-MOz4U@%u@Rqye&YA>VCP(CgTy z9N}m$MZ@|t+W&#kAQyB}S0oe`R#qtmDYL2bC7coHkFHCEdPAnecU>*5;Yr567+=v6 zQGfq$!^4BCAc1}j!<1=pnHz4xR+op0y87`upV>spGmo82R>MI~ew+Q8u$~?RNTsQl zR#jVTZlHzBS}IRLQ3G6Z3{sJ(?1N66Vyj=b&dpYmQU@u15ntyN9=j^+kV(7LEOcAd znwg5Yu1>MFu@YMpP`y8)%e5#hSsg}LKLiQj`$`QFq#`|BW$tqWty3*|_X7N|C%J2$ zP)r2??!8YMDM7I19R~_ukN=QYgQY`10+f)F(iUu4_dMTtmGeoc$xU}h@(25sYHL`| z?-;=3CR<kqq=}1wX9E#gs|k0~#=$+Yx1$)tOpC*SGQGv8DdW@mF`Rkaw7I1BSM#~D za<n7kJ6|Fvv8y+ORO{PMR!%-L#U-ocQd0yG5ZnP#t_O9j0esevmiOQ`1h-8ZnrPD6 z0w6q7<`oZW;eR;3GB*S<?8=!>Z9{={decX~p6X<MUzhJfyq~-i_#Iz6*%6_L7&F+O zz)9=}JIJ)a!&_ldVWj&8{={Df3x>}X)&iCa>6VCL3Tw3?MdIBjeURgR)Y7Zka}#Z! ze+8hebrRW!Gix>)lJdWAh{}5lKi#7J>pNhkNkGjz$)@k!)E|BzpJ|5;N9xAaUc)Hy zK_E1->0Du`?`^cf(7}r#3#<91W~p5E_5EXWm2h-)*Q0@Un?HlkBk-hfI9f_dj{n_P zUx;*}On&d9#b&L^=SfNUB+6sQ?X%Bu9Idgb5$bJ^yN%fdL@SHeZiFxC$7^$$)yKnt z_96~kDw-u+wTqbD32g<8_wD^r5I6=vdJ|GBqL|JPOK*U^2E6ZkkP=&KD6AOb2r~ai z^5-mXyrKIdk^dJ_qFPKCi}8kmOVEOR06XX`<qL>4<CU85Sr=ivhZ>aBlJ1n?C`sQ` zpr`wl^~$-6>dAx-V~kqU&u9XoGs)*O6xpI%eDI$K$bp6v379ubHma=$L5?^JqWEnP zP5y#DRqNF3tiMZ0JRY%|uAVL@X2T8E2Ryz^yz9L2a-%IN?sB4%PS>fJCYQNZ!0DE8 zMVlZ`7QqgKq%4!`uGAQ*xk=&OF3}{ouH4khste<E&Q(L;K!Sl^0q7e|QDbyZb4>5F z+Lh=z7e7sZ%bg(NFG?(*I3*s=l`kPyTh?n#vNcP123R1{jKczaMp+LB7|Dlu<R{-H z9k2I2=*B8zj563-J$6{mMPWu|2XgJI(0tDLFk^7u4{G!X%I(CLJHIawvA-<!ak3uQ zcJT8=f<6M!De<6c6nq;<C?q?XBeYqmb<dlc9^ZSvV?0%!JDXSiuHP9#mG7AZ^gZE? z!DEktgva6v&;h+jgUomH^X@L!!=E7j0=z0F=$)^&=U7|4PH(j5X<O#@W-ol_D>L9D z`s;0NMiLI-*k34C*1eLpi&5l#^QU|1tltbOJCXkz^FXVbi#gc^65A{)^J>r6e{;=K zr*E7;iZc<lR(2V3erL#HD@#L3JAW59;g(h(H!5&CJM3od>>0Vn9Br-Qhe|pIF$Dw{ z-Mk5WQWlOjpt-~?)5b+a_Z{^}p2r-%Os?&x$k?ZBO0`irdff>BXVN$3IPF{6;uOAW zN9gtslKi|Mc`FpG9<ESY;{w(?Zs$C*wAT2)4kJu4H2&K;+A$eDMtnbP@ZkF4oqj7g z)EdlSOXFZZk&v>`SYrXkZUZ={*b%MUj9O9+oYM!YI!k}Dr4$n^b~F1mqPQz`Koz+| zH?S*=BwNJMxMyj4W2}Ts9^4`S`{eFj=*b)eBlO$i4?FW�`evtVr{IhQm`L+50&2 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	(N%jMdSvM5)yI}46DOL=$LU- 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 F{{^2d5Lf^J literal 0 HcmV?d00001 diff --git a/docs/source/_static/remove_background/simulated_s6_learning_curve.png b/docs/source/_static/remove_background/simulated_s6_learning_curve.png new file mode 100644 index 0000000000000000000000000000000000000000..017868cac6df9e8d1cd8dbb80e71597224e1b9fe GIT binary patch literal 30054 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 literal 0 HcmV?d00001 diff --git a/docs/source/_static/theme_overrides.css b/docs/source/_static/theme_overrides.css deleted file mode 100644 index cc6ce10d..00000000 --- a/docs/source/_static/theme_overrides.css +++ /dev/null @@ -1,15 +0,0 @@ -# https://rackerlabs.github.io/docs-rackspace/tools/rtd-tables.html - -/* override table width restrictions */ -@media screen and (min-width: 767px) { - - .wy-table-responsive table td { - /* !important prevents the common CSS stylesheets from overriding - this as on RTD they are loaded after this stylesheet */ - white-space: normal !important; - } - - .wy-table-responsive { - overflow: visible !important; - } -} \ No newline at end of file diff --git a/docs/source/changelog/index.rst b/docs/source/changelog/index.rst new file mode 100644 index 00000000..534b1dd3 --- /dev/null +++ b/docs/source/changelog/index.rst @@ -0,0 +1,85 @@ +.. _changelog: + +Changelog +========= + +CellBender has been publicly available since 2019, and there have been some +significant changes over the years. Major changes and updates are denoted by +a change in the (first or) second digit of the version number. For example, +major changes were made between version 0.1.0 and 0.2.0. Small changes, +edge case bug fixes, speedups, and small new features might bump up the last +digit of the version number. For example, the difference between 0.2.1 and 0.2.0 +represents this kind of small change. + +Version 0.1.0 +------------- + +This was the initial release. The output count matrix was constructed via +imputation, so that there were no explicit guarantees that CellBender would +only subtract counts and never add. + +This version has been deprecated, and we do not recommend using it any longer. + +- Imputes the "denoised" count matrix using a variational autoencoder + +Version 0.2.0 +------------- + +A significant overhaul of the model and the output generation procedure were +undertaken to explicitly guarantee that CellBender only subtracts counts and +never adds. The output is not constructed by imputation or smoothing, and +CellBender intentionally tries to modify the raw data as little as possible in +order to achieve denoising. A nominal false positive rate is approximately +controlled at the level of the entire dataset, to prevent removal of too much +signal. + +- Uses a variational autoencoder as a prior + +- Computes the "denoised" count matrix using a MAP estimate and posterior regularization + + - CellBender never adds counts + +Version 0.3.0 +------------- + +Further significant changes were made to the way the output count matrix gets +computed. We compute a budget of noise counts for each gene individually, and +partition those noise counts in a way that optimizes the posterior probability +of our model. This involves solving an auxiliary optimization problem. + +The input arguments ``--expected-cells`` and ``--total-droplets-included``, which +have always been required for the tool to work reliably, are now much more +optional. Extensive testing has shown that these arguments can be left out the +vast majority of the time, making things easier on users. + +A great amount of effort has been put into refinements which reduce the failure +rate on difficult samples. + +Output data loading functions in python have been distributed with the CellBender +codebase in order to facilitate downstream data loading and use in +`scanpy <https://scanpy.readthedocs.io/>`_. + +In addition, the code produces checkpoints at timed intervals, and these +checkpoints can be used to deterministically pick up where the code left off. +This is extremely advantageous in cloud compute settings, and was built with +`Terra <https://app.terra.bio>`_ in mind. The checkpointing functionality, +together with the re-written WDL workflow, allow the workflow to be run +seamlessly on preemptible GPU instances, which are a fraction of the cost of +non-preemptible machines. We also hope these checkpoints make it easier to run +a workflow using Google Colab on a GPU for free. + +- Produces checkpoint files, and the WDL can run seamlessly on preemptible GPUs + +- Computes the "denoised" count matrix by solving an auxiliary optimization problem + + - We demonstrate that this approach is superior to v0.2.0 in the publication + +- Several tweaks to the inference procedure lead to speedups and better performance + on benchmarks + +- The tool produces an output report in HTML format with plots, analysis, + commentary, warnings, and recommendations + +- A ``metrics.csv`` output file is produced for those interested in running + hundreds of samples in automated pipelines. This file can be parsed to look for + indications that a sample may need to be re-run. diff --git a/docs/source/citation/index.rst b/docs/source/citation/index.rst index d55e2e3e..65b8beb1 100644 --- a/docs/source/citation/index.rst +++ b/docs/source/citation/index.rst @@ -3,10 +3,13 @@ Citation ======== -If you use CellBender in your research (and we hope you will!), please consider citing our papers: +If you use CellBender in your research (and we hope you will!), please consider +citing our paper: -`remove-background <https://www.biorxiv.org/content/10.1101/791699v1>`_: +Stephen J Fleming, Mark D Chaffin, Alessandro Arduini, Amer-Denis Akkad, Eric Banks, +John C Marioni, Anthony A Philippakis, Patrick T Ellinor, and Mehrtash Babadi. +Unsupervised removal of systematic background noise from droplet-based single-cell +experiments using CellBender. *Nature Methods* (in press), 2023. -Stephen J Fleming, John C Marioni, and Mehrtash Babadi. CellBender remove-background: a deep -generative model for unsupervised removal of background noise from scRNA-seq datasets. -bioRxiv 791699; doi: https://doi.org/10.1101/791699 +Preprint `available at bioRxiv <https://www.biorxiv.org/content/10.1101/791699v2>`_. +https://doi.org/10.1101/791699 diff --git a/docs/source/conf.py b/docs/source/conf.py index f41e45d4..64a32149 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -12,6 +12,9 @@ # import os import sys +from cellbender.base_cli import get_version + + dir_, _ = os.path.split(__file__) root_dir = os.path.abspath(os.path.join(dir_, '..', '..')) sys.path.insert(0, root_dir) @@ -23,8 +26,8 @@ author = 'Stephen Fleming, Mehrtash Babadi' # The full version, including alpha/beta/rc tags -version = '' -release = '' +version = get_version() +release = get_version() # -- General configuration --------------------------------------------------- diff --git a/docs/source/contributing/index.rst b/docs/source/contributing/index.rst index 2986dbd4..7d89ef94 100644 --- a/docs/source/contributing/index.rst +++ b/docs/source/contributing/index.rst @@ -3,10 +3,12 @@ Contributing ============ -We aspire to make CellBender an easy-to-use, robust, and accurate software package for the bioinformatics community. -While we test and improve CellBender together with our research collaborators, your feedback is -invaluable to us and allow us to steer CellBender in the direction that you find most useful in your research. If you +We aspire to make CellBender an easy-to-use, robust, and accurate software package +for the bioinformatics community. While we test and improve CellBender together +with our research collaborators, your feedback is invaluable to us and allows us +to steer CellBender in the direction that you find most useful in your research. If you have an interesting idea or suggestion, please do not hesitate to reach out to us. -If you encounter a bug, please file a detailed github `issue <https://github.com/broadinstitute/CellBender/issues>`_ +If you encounter a bug, please file a detailed github +`issue <https://github.com/broadinstitute/CellBender/issues>`_ and we will get back to you as soon as possible. diff --git a/docs/source/getting_started/index.rst b/docs/source/getting_started/index.rst deleted file mode 100644 index a9bf9b9e..00000000 --- a/docs/source/getting_started/index.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. _getting started: - -Getting Started -=============== - -This section contains quick start tutorials for different CellBender modules. - -.. toctree:: - :maxdepth: 1 - - remove_background/index \ No newline at end of file diff --git a/docs/source/getting_started/remove_background/index.rst b/docs/source/getting_started/remove_background/index.rst deleted file mode 100644 index 90de53f4..00000000 --- a/docs/source/getting_started/remove_background/index.rst +++ /dev/null @@ -1,138 +0,0 @@ -.. _remove background tutorial: - -remove-background -================= - -In this tutorial, we will run ``remove-background`` on a small dataset derived from the 10x Genomics -``pbmc4k`` scRNA-seq dataset (v2 Chemistry, CellRanger 2.1.0). - -As a first step, we download the full dataset and generate a smaller `trimmed` copy by selecting 500 barcodes -with high UMI count (likely non-empty) and an additional 50,000 barcodes with small UMI count (likely empty). Note -that the trimming step is performed in order to allow us go through this tutorial in a matter of minutes on a -typical CPU. Processing the full untrimmed dataset requires a CUDA-enabled GPU (e.g. NVIDIA Testla K80) -and takes about 30 minutes to finish. - -We have created a python script to download and trim the dataset. Navigate to ``examples/remove_background/`` -under your CellBender installation root directory and run the following command in the console: - -.. code-block:: console - - $ python generate_tiny_10x_pbmc.py - -After successful completion of the script, you should have a new directory named ``tiny_raw_gene_bc_matrices`` -containing ``GRCh38/matrix.mtx``, ``GRCh38/genes.tsv``, and ``GRCh38/barcodes.tsv``. - -Run remove-background ---------------------- - -We proceed to run ``remove-background`` on the trimmed dataset using the following command: - -.. code-block:: console - - $ cellbender remove-background \ - --input ./tiny_raw_gene_bc_matrices/GRCh38 \ - --output ./tiny_10x_pbmc.h5 \ - --expected-cells 500 \ - --total-droplets-included 5000 - -Again, here we leave out the ``--cuda`` flag solely for the purposes of being able to run this -command on a CPU. But a GPU is highly recommended for real datasets. - -The computation will finish within a minute or two (after ~ 150 epochs). The tool outputs the following files: - -* ``tiny_10x_pbmc.h5``: An HDF5 file containing a detailed output of the inference procedure, including the - normalized abundance of ambient transcripts, contamination fraction of each droplet, a low-dimensional - embedding of the background-corrected gene expression, and the background-corrected counts matrix (in CSC sparse - format). Please refer to the full documentation for a detailed description of these and other fields. - -* ``tiny_10x_pbmc_filtered.h5``: Same as above, though, only including droplets with a posterior cell probability - exceeding 0.5. - -* ``tiny_10x_pbmc_cell_barcodes.csv``: The list of barcodes with a posterior cell probability exceeding 0.5. - -* ``tiny_10x_pbmc.pdf``: A PDF summary of the results showing (1) the evolution of the loss function during training, - (2) a ranked-ordered total UMI plot along with posterior cell probabilities, and (3) a two-dimensional PCA - scatter plot of the latent embedding of the expressions in cell-containing droplets. Notice the rapid drop in - the cell probability after UMI rank ~ 500. - -Finally, try running the tool with ``--expected-cells 100`` and ``--expected-cells 1000``. You should find that -the output remains virtually the same. - -Use output count matrix in downstream analyses ----------------------------------------------- - -The count matrix that ``remove-background`` generates can be easily loaded and used for downstream analyses in -`scanpy <https://scanpy.readthedocs.io/>`_ and `Seurat <https://satijalab.org/seurat/>`_. - -To load the filtered count matrix (containing only cells) into scanpy: - -.. code-block:: python - - # import scanpy - import scanpy as sc - - # load the data - adata = sc.read_10x_h5('tiny_10x_pbmc_filtered.h5', genome='background_removed') - -To load the filtered count matrix (containing only cells) into Seurat: - -.. code-block:: rd - - # load Seurat (version 3) library - library(Seurat) - - # load data from the filtered h5 file - data.file <- 'tiny_10x_pbmc_filtered.h5' - data.data <- Read10X_h5(filename = data.file, use.names = TRUE) - - # create Seurat object - obj <- CreateSeuratObject(counts = data.data) - -Use latent gene expression in downstream analyses -------------------------------------------------- - -To load the latent representation of gene expression `z` computed by ``remove-background`` using a python script: - -.. code-block:: python - - import tables - import numpy as np - - z = [] - with tables.open_file('tiny_10x_pbmc_filtered.h5') as f: - print(f) # display the structure of the h5 file - z = f.root.background_removed.latent_gene_encoding.read() # read latents - -At this point, the variable ``z`` contains the latent encoding of gene expression, where rows are cells and -columns are dimensions of the latent variable. This data can be saved in CSV format with the following command: - -.. code-block:: python - - np.savetxt('tiny_10x_pbmc_latent_gene_expression.csv', z, delimiter=',') - -This latent representation of gene expression can be loaded into a Seurat object ``obj`` by doing the following: - -.. code-block:: rd - - # load the latent representation from cellbender - latent <- read.csv('tiny_10x_pbmc_latent_gene_expression.csv', header = FALSE) - latent <- t(data.matrix(latent)) - rownames(x = latent) <- paste0("CB", 1:20) - colnames(x = latent) <- colnames(data.data) - - # store latent as a new dimensionality reduction called 'cellbender' - obj[["cellbender"]] <- CreateDimReducObject(embeddings = t(latent), - key = "CB_", - assay = DefaultAssay(obj)) - -Or the variable ``z`` (from above) can be used directly in a scanpy ``anndata`` object. The code snippet below -demonstrates loading the latent ``z`` and using it to do Louvain clustering: - -.. code-block:: python - - # load the latent representation into a new slot called 'X_cellbender' - adata.obsm['X_cellbender'] = z - - # perform louvain clustering using the cellbender latents and cosine distance - sc.pp.neighbors(adata, use_rep='X_cellbender', metric='cosine') - sc.pp.louvain(adata) diff --git a/docs/source/help_and_reference/index.rst b/docs/source/help_and_reference/index.rst deleted file mode 100644 index 1f52c737..00000000 --- a/docs/source/help_and_reference/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -.. _help and reference: - -Help & Reference -================ - -.. toctree:: - :maxdepth: 1 - - remove_background/index - license/index diff --git a/docs/source/help_and_reference/remove_background/index.rst b/docs/source/help_and_reference/remove_background/index.rst deleted file mode 100644 index 6c0b585f..00000000 --- a/docs/source/help_and_reference/remove_background/index.rst +++ /dev/null @@ -1,81 +0,0 @@ -.. _remove background reference: - -remove-background -================= - -Command Line Options --------------------- - -.. argparse:: - :module: cellbender.base_cli - :func: get_populated_argparser - :prog: cellbender - :path: remove-background - -WDL Workflow Options --------------------- - -A `WDL <https://github.com/openwdl/wdl>`_ script is available as `cellbender_remove_background.wdl -<https://github.com/broadinstitute/CellBender/tree/master/wdl/cellbender_remove_background.wdl>`_, -and it can be used to run ``cellbender remove-background`` from -`Terra <https://app.terra.bio>`_ or from your own -`Cromwell <https://cromwell.readthedocs.io/en/stable/>`_ instance. The WDL is designed to -make use of Tesla K80 GPUs on Google Cloud architecture. - -In addition to the above command line options, the workflow has its own set of -input options, which are described in detail -`here <https://github.com/broadinstitute/CellBender/tree/master/wdl>`_. - -.. _remove background reference troubleshooting: - -Troubleshooting ---------------- - -* The learning curve in the output PDF has large downward spikes, or looks super wobbly. - - * This could indicate instabilities during training that should be addressed. The solution - is typically to reduce the ``--learning-rate`` by a factor of two. - -* The following warning is emitted in the log file: "Warning: few empty droplets identified. - Low UMI cutoff may be too high. Check the UMI decay curve, and decrease the - ``--low-count-threshold`` parameter if necessary." - - * This warning indicates that no "surely empty" droplets were identified in the analysis. - This means that the "empty droplet plateau" could not be identified. The most likely - explanation is that the level of background RNA is extremely low, and that the value - of ``--low-count-threshold`` exceeds this level. This would result in the empty - droplet plateau being excluded from the analysis, which is not advisable. This can be - corrected by decreasing ``--low-count-threshold`` from its default of 15 to a value like 5. - - -* There are too many cells called. - - * Are there? ``remove-background`` equates "cell probability" with "the probability that - a given droplet is not empty." These non-empty droplets might not all contain healthy - cells with high counts. Nevertheless, the posterior probability that they are not empty - is greater than 0.5. The recommended procedure - would be to filter cells based on other criteria downstream. Certainly filter for percent - mitochondrial reads. Potentially filter for number of genes expressed as well, if - this does not lead to complete loss of a low-expressing cell type. - * Experiment with increasing ``--total-droplets-included``. - * Experiment with increasing or decreasing ``--empty-drop-training-fraction``. - * As a last resort, try decreasing ``--expected-cells`` by quite a bit. - - -* There are too few cells called. - - * Try estimating ``--expected-cells`` from the UMI curve rather than a priori, and - increase the number if necessary. - * Experiment with increasing or decreasing ``--total-droplets-included``. - - -* The PCA plot of latent gene expression shows no clusters or structure. - - * Has training converged? Training should proceed for at least 150 epochs. Check to - make sure that the ELBO has nearly reached a plateau, indicating that training is - complete. Try increasing ``--epochs`` to 300 and see if the plot changes. - * This is not necessarily a bad thing, although it indicates that cells in the experiment - had a continuum of expression, or that there was only one cell type. If this is - known to be false, some sort of QC failure with the experiment would be suspected. - Perform a downstream clustering analysis with and without ``cellbender remove-background`` - and compare the two. diff --git a/docs/source/index.rst b/docs/source/index.rst index ce71b411..5e23cc4e 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -4,11 +4,23 @@ Welcome to CellBender's documentation! .. image:: /_static/design/logo_250_185.png :height: 185 px -*CellBender* is a software package for eliminating technical artifacts from high-throughput single-cell RNA sequencing (scRNA-seq) data. +*CellBender* is a software package for eliminating technical artifacts from high-throughput +single-cell RNA sequencing (scRNA-seq) data. For a brief survey of the package and its current capabilities, you can read -the :ref:`Introduction <introduction>`. For more comprehensive instructions -and quick-start tutorials, see the :ref:`Getting Started <getting started>` section. +the :ref:`Introduction <introduction>`. + +For an explanation of when and how and why to use CellBender in your analysis +pipeline, along with example code, how to choose parameter settings, and +tips on quality control, read the :ref:`Usage <usage>` section. + +For a step-by-step tutorial on a simplified example dataset, see the +:ref:`Quick start tutorial <quick start tutorial>` section. + +For details on input arguments and the output file format, +see the :ref:`Reference <reference>` section. + +For troubleshooting and an FAQ, see the :ref:`Troubleshooting <troubleshooting>` section. .. toctree:: :maxdepth: 1 @@ -16,7 +28,10 @@ and quick-start tutorials, see the :ref:`Getting Started <getting started>` sect introduction/index installation/index usage/index - getting_started/index - help_and_reference/index + tutorial/index + reference/index + troubleshooting/index contributing/index citation/index + reference/license/index + changelog/index diff --git a/docs/source/installation/index.rst b/docs/source/installation/index.rst index 86beb63a..4defef3a 100644 --- a/docs/source/installation/index.rst +++ b/docs/source/installation/index.rst @@ -3,36 +3,80 @@ Installation ============ -Manual Installation -------------------- +Via pip +------- -The recommended installation is as follows. Create a conda environment and activate it: +Python packages can be conveniently installed from the Python Package Index (PyPI) +using `pip install <https://pip.pypa.io/en/stable/cli/pip_install/>`_. +CellBender is `available on PyPI <https://pypi.org/project/cellbender/>`_ +and can be installed via .. code-block:: console - $ conda create -n CellBender python=3.7 - $ conda activate CellBender + $ pip install cellbender + +If your machine has a GPU with appropriate drivers installed, it should be +automatically detected, and the appropriate version of PyTorch with CUDA support +should automatically be downloaded as a CellBender dependency. + +We recommend installing CellBender in its own +`conda environment <https://docs.conda.io/projects/conda/en/latest/user-guide/concepts/environments.html>`_. +This allows for easier installation and prevents conflicts with any other python +packages you may have installed. + +.. code-block:: console + + $ conda create -n cellbender python=3.7 + $ conda activate cellbender + (cellbender) $ pip install cellbender + + +Installation from source +------------------------ + +Create a conda environment and activate it: + +.. code-block:: console + + $ conda create -n cellbender python=3.7 + $ conda activate cellbender Install the `pytables <https://www.pytables.org>`_ module: .. code-block:: console - (CellBender) $ conda install -c anaconda pytables + (cellbender) $ conda install -c anaconda pytables -Install `pytorch <https://pytorch.org>`_ (shown below for CPU; if you have a CUDA-ready GPU, please skip -this part and follow `these instructions <https://pytorch.org/get-started/locally/>`_ instead): +Install `pytorch <https://pytorch.org>`_ via +`these instructions <https://pytorch.org/get-started/locally/>`_: .. code-block:: console - (CellBender) $ conda install pytorch torchvision -c pytorch + (cellbender) $ pip install torch + +and ensure that your installation is appropriate for your hardware (i.e. that +the relevant CUDA drivers get installed and that ``torch.cuda.is_available()`` +returns ``True`` if you have a GPU available. -Clone this repository and install CellBender: +Clone this repository and install CellBender (in editable ``-e`` mode): .. code-block:: console - (CellBender) $ git clone https://github.com/broadinstitute/CellBender.git - (CellBender) $ pip install -e CellBender + (cellbender) $ git clone https://github.com/broadinstitute/CellBender.git + (cellbender) $ pip install -e CellBender + +Install a specific commit directly from GitHub +---------------------------------------------- + +This can be achieved via + +.. code-block:: console + + (cellbender) $ pip install --no-cache-dir -U git+https://github.com/broadinstitute/CellBender.git@<SHA> + +where ``<SHA>`` must be replaced by any reference to a particular git commit, +such as a tag, a branch name, or a commit sha. Docker Image ------------ @@ -43,12 +87,16 @@ A GPU-enabled docker image is available from the Google Container Registry (GCR) Older versions are available at the same location, for example as -``us.gcr.io/broad-dsde-methods/cellbender:0.1.0`` +``us.gcr.io/broad-dsde-methods/cellbender:0.2.0`` Terra Workflow -------------- -For `Terra <https://app.terra.bio>`_ users, the following workflow is publicly available: +For `Terra <https://app.terra.bio>`_ users (or any other users of WDL workflows), +the following WDL workflow is publicly available: * `cellbender/remove-background <https://portal.firecloud.org/#methods/cellbender/remove-background/>`_ + +Some documentation for the WDL is available at the above link, and some is visible +`on github <https://github.com/broadinstitute/CellBender/tree/master/wdl>`_. diff --git a/docs/source/introduction/index.rst b/docs/source/introduction/index.rst index aef82c46..7bcf04a9 100644 --- a/docs/source/introduction/index.rst +++ b/docs/source/introduction/index.rst @@ -1,29 +1,30 @@ .. _introduction: What is CellBender? -===================== +=================== -CellBender is a software package for eliminating technical artifacts from high-throughput single-cell RNA sequencing -(scRNA-seq) data. +CellBender is a software package for eliminating technical artifacts from high-throughput single-cell omics data, +including scRNA-seq, snRNA-seq, and CITE-seq. Scope and Purpose ----------------- -Despite the recent progress in improving, optimizing and standardizing scRNA-seq protocols, the complexity of -scRNA-seq experiments leaves room for systematic biases and background noise in the raw observations. These nuisances +Despite the recent progress in improving, optimizing and standardizing droplet-based single-cell omics protocols +like scRNA-seq, the complexity of these experiments leaves room for systematic biases and background noise in +the raw observations. These nuisances can be traced back to undesirable enzymatic processes that produce spurious library fragments, contamination by exogeneous or endogenous ambient transcripts, impurity of barcode beads, and barcode swapping during amplification and/or sequencing. The main purpose of CellBender is to take raw gene-by-cell count matrices and molecule-level information produced -by 3rd party pipelines (e.g. CellRanger, Alevin), to model and remove systematic biases and background noise, and -to produce improved estimates of gene expression. +by 3rd party pipelines (e.g. CellRanger, Alevin, DropSeq, etc.), to model and remove systematic biases and +background noise, and to produce improved estimates of gene expression. As such, CellBender relies on an external tool for primary processing of the raw data obtained from the sequencer (e.g. BCL or FASTQ files). These basic processing steps lie outside of the scope of CellBender and include (pseudo-)alignment and annotation of reads, barcode error correction, and generation of raw gene-by-cell count matrices. Upcoming modules of CellBender will further utilize molecule-level information (e.g. observed reads -per molecule, transcript equivalent classes, etc.). +per molecule, transcript equivalence classes, etc.). Modules ------- @@ -31,6 +32,5 @@ Modules The current version of CellBender contains the following modules. More modules will be added in the future: * ``remove-background``: This module removes counts due to ambient RNA molecules and random barcode swapping from - (raw) UMI-based scRNA-seq gene-by-cell count matrices. At the moment, only the count matrices produced by the - CellRanger `count` pipeline is supported. Support for additional tools and protocols will be added in the future. + (raw) UMI-based scRNA-seq gene-by-cell count matrices. Several file formats for count matrices are supported. A quick-start tutorial can be found :ref:`here <remove background tutorial>`. diff --git a/docs/source/reference/index.rst b/docs/source/reference/index.rst new file mode 100644 index 00000000..ead0ce72 --- /dev/null +++ b/docs/source/reference/index.rst @@ -0,0 +1,188 @@ +.. _reference: + +Reference +========= + +.. _remove background reference: + +remove-background +----------------- + +Command Line Options +~~~~~~~~~~~~~~~~~~~~ + +.. argparse:: + :module: cellbender.base_cli + :func: get_populated_argparser + :prog: cellbender + :path: remove-background + +WDL Workflow Options +~~~~~~~~~~~~~~~~~~~~ + +A `WDL <https://github.com/openwdl/wdl>`_ script is available as `cellbender_remove_background.wdl +<https://github.com/broadinstitute/CellBender/tree/master/wdl/cellbender_remove_background.wdl>`_, +and it can be used to run ``cellbender remove-background`` from +`Terra <https://app.terra.bio>`_ or from your own +`Cromwell <https://cromwell.readthedocs.io/en/stable/>`_ instance. The WDL is designed to +make use of an Nvidia Tesla T4 GPU on Google Cloud architecture. + +As of v0.3.0, the WDL uses preemptible instances that are a fraction of the cost, +and uses automatic restarting from checkpoints so that work is not lost. + +In addition to the above command line options, the workflow has its own set of +input options, which are described in detail +`here <https://github.com/broadinstitute/CellBender/tree/master/wdl>`_. + +.. _h5-file-format: + +Output h5 file format +~~~~~~~~~~~~~~~~~~~~~ + +An h5 output file (this one is from the :ref:`tutorial <remove background tutorial>`) +can be examined in detail using PyTables in python: + +.. code-block:: python + + # import PyTables + import tables + + # open the file and take a look at its contents + with tables.open_file('tiny_output.h5', 'r') as f: + print(f) + +.. code-block:: console + + /home/jupyter/tiny_output.h5 (File) 'CellBender remove-background output' + Last modif.: 'Wed May 4 19:46:16 2022' + Object Tree: + / (RootGroup) 'CellBender remove-background output' + /droplet_latents (Group) 'Latent variables per droplet' + /droplet_latents/background_fraction (CArray(1000,), shuffle, zlib(1)) '' + /droplet_latents/barcode_indices_for_latents (CArray(1000,), shuffle, zlib(1)) '' + /droplet_latents/cell_probability (CArray(1000,), shuffle, zlib(1)) '' + /droplet_latents/cell_size (CArray(1000,), shuffle, zlib(1)) '' + /droplet_latents/droplet_efficiency (CArray(1000,), shuffle, zlib(1)) '' + /droplet_latents/gene_expression_encoding (CArray(1000, 100), shuffle, zlib(1)) '' + /global_latents (Group) 'Global latent variables' + /global_latents/ambient_expression (Array(100,)) '' + /global_latents/cell_size_lognormal_std (Array()) '' + /global_latents/empty_droplet_size_lognormal_loc (Array()) '' + /global_latents/empty_droplet_size_lognormal_scale (Array()) '' + /global_latents/posterior_regularization_lambda (Array()) '' + /global_latents/swapping_fraction_dist_params (Array(2,)) '' + /global_latents/target_false_positive_rate (Array()) '' + /matrix (Group) 'Counts after background correction' + /matrix/barcodes (CArray(50500,), zlib(1)) '' + /matrix/data (CArray(44477,), shuffle, zlib(1)) '' + /matrix/indices (CArray(44477,), shuffle, zlib(1)) '' + /matrix/indptr (CArray(50501,), shuffle, zlib(1)) '' + /matrix/shape (CArray(2,), shuffle, zlib(1)) '' + /metadata (Group) 'Metadata' + /metadata/barcodes_analyzed (Array(1000,)) '' + /metadata/barcodes_analyzed_inds (Array(1000,)) '' + /metadata/features_analyzed_inds (Array(100,)) '' + /metadata/fraction_data_used_for_testing (Array()) '' + /metadata/test_elbo (Array(30,)) '' + /metadata/test_epoch (Array(30,)) '' + /metadata/train_elbo (Array(150,)) '' + /metadata/train_epoch (Array(150,)) '' + /matrix/features (Group) 'Genes and other features measured' + /matrix/features/feature_type (CArray(100,), shuffle, zlib(1)) '' + /matrix/features/genome (CArray(100,), shuffle, zlib(1)) '' + /matrix/features/id (CArray(100,), shuffle, zlib(1)) '' + /matrix/features/name (CArray(100,), shuffle, zlib(1)) '' + +Any of these bits of data can be accessed directly with PyTables, or by using +python functions from ``cellbender.remove_background.downstream`` such as +``anndata_from_h5()`` that load the metadata as well as the count matrix into +`AnnData format <https://anndata.readthedocs.io/en/latest/>`_ +(compatible with analysis in `scanpy <https://scanpy.readthedocs.io/en/stable/>`_). + +The names of variables in the h5 file are meant to explain their contents. +All data in the ``/matrix`` group is formatted as `CellRanger v3 h5 data +<https://support.10xgenomics.com/single-cell-gene-expression/software/pipelines/latest/advanced/h5_matrices>`_. + +The other root groups in the h5 file ``[droplet_latents, global_latents, metadata]`` +contain detailed information inferred by CellBender as part of its latent +variable model of the data generative process (details in our paper). +The ``/droplet_latents`` are variables that have a value inferred for each +droplet, such as ``cell_probability`` and ``cell_size``. The ``/global_latents`` are +variables that have a fixed value for the whole experiment, such as +``ambient_expression``, which is the inferred profile of ambient RNA in the +sample (normalized so it sums to one). Finally, ``/metadata`` includes other things +such as the learning curve (``train_elbo`` and ``train_epoch``) and which +features were analyzed during the run (``features_analyzed_inds``, as +integer indices that index ``/matrix/features``). + + +.. _loading-outputs: + +Loading and using outputs +~~~~~~~~~~~~~~~~~~~~~~~~~ + +As mentioned in the :ref:`tutorial <downstream-example>`, output h5 files can +be opened natively by ``scanpy`` +(`scanpy.read_10x_h5() <https://scanpy.readthedocs.io/en/stable/generated/scanpy.read_10x_h5.html>`_) +and (with some effort) by ``Seurat`` (see :ref:`here <open-in-seurat>`), though +there is extra ``cellbender``-specific information in the output files that +``scanpy`` and ``Seurat`` will not load automatically. + +Additional loading functionality is distrubuted as part of the ``cellbender`` +package and is described below. + +Suggested use cases: + +- Load just the CellBender output: ``anndata_from_h5()`` +- Load the raw input together with the CellBender output (this is great for + downstream analysis, because it allows you to plot the effect of ``cellbender``, + and you can always look back at the raw data): ``load_anndata_from_input_and_output()`` +- Power users who want to run ``cellbender`` at multiple FPR values and make + comparisons: ``load_anndata_from_input_and_outputs()`` + +Example: + +.. code-block:: python + + from cellbender.remove_background.downstream import load_anndata_from_input_and_output + + adata = load_anndata_from_input_and_output( + input_file='my_raw_10x_file.h5', + output_file='my_cellbender_output_file.h5', + input_layer_key='raw', # this will be the raw data layer + ) + adata + +.. code-block:: console + + AnnData object with n_obs × n_vars = 6983 × 37468 + obs: 'background_fraction', 'cell_probability', 'cell_size', 'droplet_efficiency', + 'n_raw', 'n_cellbender' + var: 'ambient_expression', 'feature_type', 'genome', 'gene_id', 'cellbender_analyzed', + 'n_raw', 'n_cellbender' + uns: 'cell_size_lognormal_std', 'empty_droplet_size_lognormal_loc', + 'empty_droplet_size_lognormal_scale', 'swapping_fraction_dist_params', + 'target_false_positive_rate', 'features_analyzed_inds', + 'fraction_data_used_for_testing', 'test_elbo', 'test_epoch', + 'train_elbo', 'train_epoch' + obsm: 'cellbender_embedding' + layers: 'raw', 'cellbender' + +.. automodule:: cellbender.remove_background.downstream + :members: + +The posterior +~~~~~~~~~~~~~ + +There is an additional output file called ``posterior.h5`` which contains the +full posterior. The structure of this data is a sparse matrix whose shape is +[count matrix entries, number of potential noise counts]. Typically the number +of potential noise counts in any entry of the count matrix is truncated at 50. +The values are log probabilities of the specified number of noise counts in the +given count matrix entry. + +The information contained in the posterior can be used to +quantitatively answer questions such as "What is the probability that the +number of viral gene counts in this cell is nonzero?" For help with these kinds +of computations, please open a +`github issue <https://github.com/broadinstitute/CellBender/issues>`_. diff --git a/docs/source/help_and_reference/license/index.rst b/docs/source/reference/license/index.rst similarity index 100% rename from docs/source/help_and_reference/license/index.rst rename to docs/source/reference/license/index.rst diff --git a/docs/source/troubleshooting/index.rst b/docs/source/troubleshooting/index.rst new file mode 100644 index 00000000..893f7bb8 --- /dev/null +++ b/docs/source/troubleshooting/index.rst @@ -0,0 +1,426 @@ +.. _troubleshooting: + +Troubleshooting +=============== + +.. _remove background troubleshooting: + +remove-background +----------------- + +Feel free to check the +`issues on github <https://github.com/broadinstitute/CellBender/issues?q=is%3Aissue>`_, +where there are several answered questions +you can search through. If you don't see an answer there or below, please consider +opening a new issue on github to ask your question. + +FAQ +~~~ + +* :ref:`What are the "best practices" for running the tool? <a1>` + +* :ref:`What are the "best practices" for incorporating CellBender into my analysis pipeline? <a2>` + +* :ref:`How do I load and use the output? <a22>` + +* :ref:`What are the details of the output h5 file format? <a23>` + +* :ref:`Do I really need a GPU to run this? <a3>` + +* :ref:`How do I determine the right "--fpr"? <a4>` + +* :ref:`How do I determine the right "--expected-cells"? <a5>` + +* :ref:`How do I determine the right "--total-droplets-included"? <a6>` + +* :ref:`Does CellBender work with CITE-seq data? Or other non-"Gene Expression" features? <a7>` + +* :ref:`Could I run CellBender using only "Gene Expression" features and ignore other features? <a8>` + +* :ref:`Could I run CellBender using only "Antibody Capture" features and not Gene Expression? <a24>` + +* :ref:`Where can I find the ambient RNA profile inferred by CellBender? <a9>` + +* :ref:`The code completed, but how do I know if it "worked"? / How do I know when I need to re-run with different parameters? <a10>` + +* :ref:`It seems like CellBender called too many cells <a11>` + +* :ref:`It seems like CellBender called too few cells <a12>` + +* :ref:`The PCA plot of latent gene expression shows no clusters or structure <a25>` + +* :ref:`The learning curve looks weird. / What is the learning curve supposed to look like? <a13>` + +* :ref:`What is the "metrics.csv" output for, and how do I interpret the metrics? <a14>` + +* :ref:`My HTML report summary (at the bottom) said there were some warnings. What should I do about that? <a15>` + +* :ref:`The tool failed to produce an HTML report <a16>` + +* :ref:`I ran the WDL in Terra and the job "Failed" with PAPI error code 9 <a17>` + +* :ref:`How much does it cost, per sample, to run the WDL in Terra? <a18>` + +* :ref:`I am getting a GPU-out-of-memory error (process "Killed") <a19>` + +* :ref:`I got a "nan" error and the tool crashed <a20>` + +* :ref:`There was an error! <a21>` + + +Answers / Troubleshooting Tips +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. _a1: + +* What are the "best practices" for running the tool? + + * See the :ref:`recommended best practices <best-practices>` + +.. _a2: + +* What are the "best practices" for incorporating CellBender into my analysis pipeline? + + * See the :ref:`proposed pipeline <proposed-pipeline>` + +.. _a22: + +* How do I load and use the output? + + * The data can easily be loaded as an ``AnnData`` object in python, to be used in + ``scanpy``, or it can also be loaded by Seurat, see the + :ref:`example here <downstream-example>` + * We recommend loading the input and output data (together) using the function + ``cellbender.remove_background.downstream.load_anndata_from_input_and_output()`` + from the CellBender package, since that will create an ``AnnData`` with + separate layers for the raw data and the CellBender output data. This is + quite handy for downstream work. There are several simple data-loading + functions in ``cellbender.remove_background.downstream`` that might be + useful. + + .. code-block:: python + + from cellbender.remove_background.downstream import load_anndata_from_input_and_output + + adata = load_anndata_from_input_and_output(input_file='tiny_raw_feature_bc_matrix.h5ad', + output_file='tiny_output.h5') + adata + + .. code-block:: console + + AnnData object with n_obs × n_vars = 1000 × 100 + obs: 'background_fraction', 'cell_probability', 'cell_size', 'droplet_efficiency', 'n_cellranger', 'n_cellbender' + var: 'ambient_expression', 'features_analyzed_inds', 'feature_type', 'genome', 'gene_id', 'n_cellranger', 'n_cellbender' + uns: 'cell_size_lognormal_std', 'empty_droplet_size_lognormal_loc', 'empty_droplet_size_lognormal_scale', 'posterior_regularization_lambda', 'swapping_fraction_dist_params', 'target_false_positive_rate', 'fraction_data_used_for_testing', 'test_elbo', 'test_epoch', 'train_elbo', 'train_epoch' + obsm: 'cellbender_embedding' + layers: 'cellranger', 'cellbender' + +.. _a23: + +* What are the details of the output h5 file format? + + * :ref:`See here <h5-file-format>` + +.. _a3: + +* Do I really need a GPU to run this? + + * It's not absolutely necessary, but the code takes a long time to run on a full + dataset on a CPU. + * While running on a GPU might seem like an insurmountable obstacle for those without + a GPU handy, consider trying out our + `workflow on Terra <https://portal.firecloud.org/#methods/cellbender/remove-background/>`_, + which runs on a GPU on Google Cloud at the click of a button. + * Others have successfully run on Google Colab notebooks for free. Since CellBender + produces checkpoint files during training (``ckpt.tar.gz``), you can even pick up + where you left off if you get preempted. You just need to put the ``ckpt.tar.gz`` + file in the directory where the CellBender command is being invoked (or + specify the file using the argument ``--checkpoint``), and CellBender will + automatically pick up where it left off when the same command is re-run. + * If you really want to use a CPU only, then consider things that will speed up the + run, like using fewer ``--total-droplets-included``, and increasing the threshold + ``--projected-ambient-count-threshold`` so that fewer features are analyzed, + and maybe decreasing ``--empty-drop-training-fraction``, so that each minibatch + has fewer empty droplets. + +.. _a4: + +* How do I determine the right ``--fpr``? + + * See the :ref:`recommended best practices <best-practices>` + +.. _a5: + +* How do I determine the right ``--expected-cells``? + + * See the :ref:`recommended best practices <best-practices>` + +.. _a6: + +* How do I determine the right ``--total-droplets-included``? + + * See the :ref:`recommended best practices <best-practices>` + +.. _a7: + +* Does CellBender work with CITE-seq data? Or other non-``Gene Expression`` features? + + * Absolutely, `as shown here <https://github.com/broadinstitute/CellBender/issues/114>`_ + and `in our paper <https://www.biorxiv.org/content/10.1101/791699v2>`_. + The results for ``Antibody Capture`` data look even better than + for gene expression, due to the higher ambient background for that modality. + * ATAC data is a bit more tricky. CellBender will run, though it takes a long + time with 200k+ Peak features. You can use the argument + ``--projected-ambient-count-threshold 2`` to tell CellBender to ignore all + features which are not estimated to have at least two noise counts in cells. + This can greatly speed things up. Feel free to experiment with that value. + Anecdotally it seems that ATAC data is less noisy than gene expression data + to begin with, so some users opt to have CellBender ignore the ATAC features + using the input argument ``--exclude-feature-types Peaks``. There is nothing + wrong with doing this. + +.. _a8: + +* Could I run CellBender using only ``Gene Expression`` features and ignore other features? + + * If you want to, you can (though it works great with ``Antibody Capture`` data): + just use the ``--exclude-feature-types`` input parameter. + +.. _a24: + +* Could I run CellBender using only ``Antibody Capture`` features and not ``Gene Expression``? + + * No, it is not a good idea to exclude ``Gene Expression`` features for the following + reason: the ``Gene Expression`` features form the basis of a good prior on "cell type", + which the method heavily relies on to denoise. Other features, without ``Gene Expression``, + are probably too sparse to cluster similar cells together and form a good prior for + "which cells are similar to which others". + +.. _a9: + +* Where can I find the ambient RNA profile inferred by CellBender? + + * This is present in the output h5 file as the field called + ``/global_latents/ambient_expression`` (:ref:`see here <h5-file-format>`). + If you use the dataloader from ``cellbender.remove_background.downstream`` + (:ref:`see here <a22>`), then the ambient expression profile will be loaded + into the AnnData object as ``adata.var['ambient_expression']`` + * (Though it is referred to here as "ambient RNA", all features are included, + not just Gene Expression.) + +.. _a10: + +* The code completed, but how do I know if it "worked"? / How do I know when I + need to re-run with different parameters? + + * The vast majority of runs using a nice dataset will work just fine. If your + dataset might not be so "nice", then we recommend taking a look at the output + ``_report.html``, which will have a few diagnostics and will issue warnings + and recommendations as appropirate. + * In general, if the learning curve (ELBO versus epoch) has huge spikes, or if + if does not converge near the end but rather dips back down, then you may + need to consider re-running with a lower ``--learning-rate``. The solution + is typically to reduce the ``--learning-rate`` by a factor of two. + * In certain cases, it may be obvious that CellBender has failed to call cells + accurately. In these cases, it may be necessary to do a bit of experimentation + with ``--expected-cells`` and ``--total-droplets-included`` to try to guide + CellBender toward a more reasonable solution. It has been our observation + that such cases are relatively rare. Try looking at the UMI curve and picking + a value for ``--expected-cells`` where you know that all the droplets + preceding that number are surely cells. + +.. _a11: + +* It seems like CellBender called too many cells + + * Did it? ``remove-background`` equates "cell probability" with "the probability that + a given droplet is not empty." These non-empty droplets might not all contain healthy + cells with high counts. Nevertheless, the posterior probability that they are not empty + is greater than 0.5. The recommended procedure + would be to filter cells based on other criteria downstream. Certainly filter for percent + mitochondrial reads. Potentially filter for number of genes expressed as well, if + this does not lead to complete loss of a low-expressing cell type. + * Experiment with increasing ``--total-droplets-included``. + * Experiment with increasing or decreasing ``--empty-drop-training-fraction``. + * As a last resort, try decreasing ``--expected-cells`` by quite a bit. + +.. _a12: + +* It seems like CellBender called too few cells + + * If CellBender seems to have missed cells, or if you get a "No cells found!" + error, then try increasing ``--expected-cells``, and also ensure that your value + for ``--total-droplets-included`` is large enough that all droplets after + this value on the UMI curve are "surely empty". + +.. _a25: + +* The PCA plot of latent gene expression shows no clusters or structure + + * Has training converged? Training should proceed for at least 150 epochs. Check to + make sure that the ELBO has nearly reached a plateau, indicating that training is + complete. Try increasing ``--epochs`` to 300 and see if the plot changes. + * This is not necessarily a bad thing, although it indicates that cells in the experiment + had a continuum of expression, or that there was only one cell type. If this is + known to be false, some sort of QC failure with the experiment would be suspected. + Perform a downstream clustering analysis with and without ``cellbender remove-background`` + and compare the two. + +.. _a13: + +* The learning curve looks weird. / What is the learning curve supposed to + look like? + + * The "learning curve", a.k.a. the plot of ELBO (evidence lower bound) verus + training epoch, is a record of the progress of inferring all the latent + variables in the CellBender model, based on data. This learning happens via + gradient descent. Typically, the ELBO changes gradually, increasing and + approaching some rather stable value by the end of training. Ideally, the + ELBO increases monotonically. + + * If the learning curve either starts decreasing, or has a large downward bump + or a downward spike or spikes, then something may have gone a bit "off the + rails" during training. We would be concerned that, for example, the inference + procedure got thrown off into some local minimum that is sub-optimal. If you + see a learning curve that looks strange, then try to re-run with half the + ``--learning-rate`` and see if it results in a more "canonical" learning curve. + If it does, use that output. + + * Examples: 2 fine learning curves (panels on right are zoomed-in y-axis) + + * .. image:: /_static/remove_background/PCL_rat_A_LA6_learning_curve.png + :width: 600 px + + + * .. image:: /_static/remove_background/simulated_s6_learning_curve.png + :width: 600 px + + * Examples: 2 bad learning curves + + * .. image:: /_static/remove_background/bad_learning_curves.png + :width: 700 px + +.. _a14: + +* What is the ``metrics.csv`` output for, and how do I interpret the metrics? + + * This is a bit of a niche output, and most people can ignore it if they want + to. The idea here is to enable automated analysis pipelines to make decisions + about whether to re-run CellBender with different parameters. Several of the + output metrics contained here are also contained in the HTML report (though + not all). But, importantly, this CSV file is easy to parse programmatically, + so that a pipeline can make automatic decisions. All metrics are scalar + quantities, and the intent was to name them so they are self-explanatory. + The contents are: + + 1. ``total_raw_counts``: Sum of all input count matrix entries + 2. ``total_output_counts``: Sum of all output count matrix entries + 3. ``total_counts_removed``: 1 minus 2 + 4. ``fraction_counts_removed``: 3 divided by 1 + 5. ``total_raw_counts_in_cells``: Same as 1, but calculated only in CellBender- + determined non-empty droplets + 6. ``total_counts_removed_from_cells``: 5 minus 2 (since only cells have + nonzero counts in the output) + 7. ``fraction_counts_removed_from_cells``: 6 divided by 5 + 8. ``average_counts_removed_per_cell``: 6 divided by the number of CellBender- + determined non-empty droplets + 9. ``target_fpr``: The input ``--fpr`` value + 10. ``expected_cells``: The input ``--expected-cells`` value, blank if not + provided. + 11. ``found_cells``: The number of CellBender- + determined non-empty droplets + 12. ``output_average_counts_per_cell``: 2 divided by 11 + 13. ``ratio_of_found_cells_to_expected_cells``: 11 divided by 10 + 14. ``found_empties``: The number of empty droplets, as determined by + CellBender. This number plus 11 equals the input + ``--total-droplets-included`` (or the value used by default) + 15. ``fraction_of_analyzed_droplets_that_are_nonempty``: 11 divided by the + input ``--total-droplets-included`` + 16. ``convergence_indicator``: The mean absolute difference between successive + values of the train ELBO for the last 3 epochs, divided by the standard + deviation of the train ELBO over the last 20 epochs. A smaller number + indicates better convergence. It's typical to see values of 0.25 or 0.35. + Large values might indicate a failure to converge. (Not many people have + yet used this in practice, so we might learn more about recommendations + in future.) + 17. ``overall_change_in_train_elbo``: The change in ELBO from first to last + epoch. + + * The most useful values for automated decision-making are probably 13, 15, + and 16. + +.. _a15: + +* My HTML report summary (at the bottom) said there were some warnings. What + should I do about that? + + * If the warning comes with a recommendation to re-run with different settings, + then that is worth a try. + * Some warnings do not need further action, and simply reflect peculiarities + of the specific dataset. + +.. _a16: + +* The tool failed to produce an HTML report + + * Please report the error as a github issue. The report-making process, since + it makes use of Jupyter notebooks, is a bit of a fragile process. These + reports are new in v0.3.0, and there has been less testing. + +.. _a17: + +* I ran the WDL in Terra and the job ``Failed`` with PAPI error code 9 + + * Typically this is a so-called "transient" error, meaning that it was a random + occurrance, and the job may succeed if run again without any changes. + However, it is worth checking the log and checking "Job Manager" to see if + there was a more specific error message. + +.. _a18: + +* How much does it cost, per sample, to run the WDL in Terra? + + * It depends on the size of the dataset, but $0.30 is pretty typical, as of + the pricing used by Google Cloud in July 2022. + +.. _a19: + +* I am getting a GPU-out-of-memory error (process ``Killed``) + + * Please report the issue on github, but there are a few things you can try + to reduce memory usage. Typically memory usage is highest during posterior + sampling. Try setting ``--posterior-batch-size`` to 64, instead of its + default value of 128. (Make sure to restart from the checkpoint file to + avoid re-running inference. This will happen automatically if you re-run + in the same folder as the ``ckpt.tar.gz`` file.) + * If you can, try running on an Nvidia Tesla T4 GPU, which has more RAM than + some other options. + * Currently, CellBender only makes use of 1 GPU, so extra GPUs will not help. + +.. _a20: + +* I got a ``nan`` error and the tool crashed + + * This is real bad. Definitely report this issue on github. You may be asked + to re-run the tool using the ``--debug`` flag, to get more error messages + for reporting. + +.. _a21: + +* There was an error! + + * Please report the issue on github. You may be asked + to re-run the tool using the ``--debug`` flag, to get more error messages + for reporting. + + * The following warning is emitted in the log file: "Warning: few empty droplets identified. + Low UMI cutoff may be too high. Check the UMI decay curve, and decrease the + ``--low-count-threshold`` parameter if necessary." + + * This warning indicates that no "surely empty" droplets were identified in the analysis. + This means that the "empty droplet plateau" could not be identified. The most likely + explanation is that the level of background RNA is extremely low, and that the value + of ``--low-count-threshold`` exceeds this level. This would result in the empty + droplet plateau being excluded from the analysis, which is not advisable. This can be + corrected by decreasing ``--low-count-threshold`` from its default of 15 to a value like 5. + diff --git a/docs/source/tutorial/index.rst b/docs/source/tutorial/index.rst new file mode 100644 index 00000000..c26316e1 --- /dev/null +++ b/docs/source/tutorial/index.rst @@ -0,0 +1,224 @@ +.. _quick start tutorial: + +Quick-start tutorial +==================== + +This section contains quick start tutorials for different CellBender modules. + +.. _remove background tutorial: + +remove-background +----------------- + +In this tutorial, we will run ``remove-background`` on a small dataset derived from the 10x Genomics +``heart10k`` snRNA-seq `dataset +<https://www.10xgenomics.com/resources/datasets/10-k-heart-cells-from-an-e-18-mouse-v-3-chemistry-3-standard-3-0-0>`_ +(v3 Chemistry, CellRanger 3.0.2). + +As a first step, we download the full dataset and generate a smaller `trimmed` copy by selecting 500 barcodes +with high UMI count (likely non-empty) and an additional 50,000 barcodes with small UMI count (likely empty). +We also trim to keep only the top 100 most highly-expressed genes. Note +that the trimming step is performed in order to allow us go through this tutorial in a minute on a +typical CPU. Processing the full untrimmed dataset requires a CUDA-enabled GPU (e.g. NVIDIA Testla T4) +and takes about 30 minutes to finish. + +(Please note that trimming is NOT part of the recommended workflow, and is only for +the purposes of a quick demo run. When you run ``remove-background`` on real data, +do not do any preprocessing or feature selection or barcode selection first.) + +We have created a python script to download and trim the dataset. Navigate to ``examples/remove_background/`` +under your CellBender installation root directory and run the following command in the console: + +.. code-block:: console + + $ python generate_tiny_10x_dataset.py + +After successful completion of the script, you should have a new file named +``tiny_raw_feature_bc_matrix.h5ad``. + +Run remove-background +~~~~~~~~~~~~~~~~~~~~~ + +We proceed to run ``remove-background`` on the trimmed dataset using the following command: + +.. code-block:: console + + (cellbender) $ cellbender remove-background \ + --input tiny_raw_feature_bc_matrix.h5ad \ + --output tiny_output.h5 \ + --expected-cells 500 \ + --total-droplets-included 2000 + +Again, here we leave out the ``--cuda`` flag solely for the purposes of being able to run this +command on a CPU. But a GPU is highly recommended for real datasets. + +The computation will finish within a minute or two (after 150 epochs). The tool outputs the following files: + +* ``tiny_output.h5``: An HDF5 file containing a detailed output of the inference procedure, including the + normalized abundance of ambient transcripts, contamination fraction of each droplet, a low-dimensional + embedding of the background-corrected gene expression, and the background-corrected counts matrix (in CSC sparse + format). Please refer to the full documentation for a detailed description of these and other fields. + +* ``tiny_output_filtered.h5``: Same as above, though, only including droplets with a posterior cell probability + exceeding 0.5. + +* ``tiny_output_cell_barcodes.csv``: The list of barcodes with a posterior cell probability exceeding 0.5. + +* ``tiny_output.pdf``: A PDF summary of the results showing (1) the evolution of the loss function during training, + (2) a ranked-ordered total UMI plot along with posterior cell probabilities, and (3) a two-dimensional PCA + scatter plot of the latent embedding of the expressions in cell-containing droplets. Notice the rapid drop in + the cell probability after UMI rank ~ 500. + +* ``tiny_output_umi_counts.pdf``: A PDF showing the UMI counts per droplet as a histogram, annotated + with what CellBender thinks is empty versus cells. This describes CellBender's prior. This is mainly + a diagnostic if something seems to be going wrong with CellBender's automatic prior determination. + +* ``tiny_output.log``: Log file. + +* ``tiny_output_metrics.csv``: Output metrics, most of which have very descriptive names. This file is not + used by most users, but the idea is that it can be incorporated into automated pipelines which could re-run + CellBender automatically (with different parameters) if something goes wrong. + +* ``tiny_output_report.html``: An HTML report which points out a few things about the run and + highlights differences between the output and the input. Issues warnings if there are any + aspects of the run that look anomalous, and makes suggestions. + +Finally, try running the tool with ``--expected-cells 100`` and ``--expected-cells 1000``. You should find that +the output remains virtually the same. + +.. _downstream-example: + +Use output count matrix in downstream analyses +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The count matrix that ``remove-background`` generates can be easily loaded and used for downstream analyses in +`scanpy <https://scanpy.readthedocs.io/>`_ and `Seurat <https://satijalab.org/seurat/>`_. + +You can load the filtered count matrix (containing only cells) into scanpy: + +.. code-block:: python + + # import scanpy + import scanpy as sc + + # load the data + adata = sc.read_10x_h5('tiny_output_filtered.h5') + +This will yield ``adata`` like this + +.. code-block:: console + + AnnData object with n_obs × n_vars = 531 × 100 + var: 'gene_ids', 'feature_types', 'genome' + +The CellBender output counts are in ``adata.X``. + +However, this does not include any of the CellBender metadata when loading +the file. To include the metadata, but still load an ``AnnData`` object +that ``scanpy`` can operate on, try some of the functions from +``cellbender.remove_background.downstream`` (see :ref:`here <loading-outputs>`) + +.. code-block:: python + + # import function + from cellbender.remove_background.downstream import anndata_from_h5 + + # load the data + adata = anndata_from_h5('tiny_output.h5') + +This yields an ``adata`` with all the cell barcodes which were analyzed by +CellBender (all the ``--total-droplets-included``), along with all the +metadata and latent variables inferred by CellBender: + +.. code-block:: console + + AnnData object with n_obs × n_vars = 1000 × 100 + obs: 'background_fraction', 'cell_probability', 'cell_size', 'droplet_efficiency' + var: 'ambient_expression', 'features_analyzed_inds', 'feature_type', 'genome', 'gene_id' + uns: 'cell_size_lognormal_std', 'empty_droplet_size_lognormal_loc', 'empty_droplet_size_lognormal_scale', 'posterior_regularization_lambda', 'swapping_fraction_dist_params', 'target_false_positive_rate', 'fraction_data_used_for_testing', 'test_elbo', 'test_epoch', 'train_elbo', 'train_epoch' + obsm: 'gene_expression_encoding' + +(If you want to load both the +raw data and the CellBender data into one AnnData object, which is very useful, +try the ``load_anndata_from_input_and_output()`` function in +``cellbender.remove_background.downstream``, see :ref:`here <loading-outputs>`) + +You can access the latent gene expression embedding learned by CellBender in +``adata.obsm['gene_expression_encoding']``, the inferred ambient RNA profile +is in ``adata.var['ambient_expression']``, and the inferred cell probabilties are +in ``adata.obs['cell_probability']``. + +You can limit this ``adata`` to CellBender cell calls very easily: + +.. code-block:: python + + adata[adata.obs['cell_probability'] > 0.5] + +.. code-block:: console + + View of AnnData object with n_obs × n_vars = 531 × 100 + obs: 'background_fraction', 'cell_probability', 'cell_size', 'droplet_efficiency' + var: 'ambient_expression', 'features_analyzed_inds', 'feature_type', 'genome', 'gene_id' + uns: 'cell_size_lognormal_std', 'empty_droplet_size_lognormal_loc', 'empty_droplet_size_lognormal_scale', 'posterior_regularization_lambda', 'swapping_fraction_dist_params', 'target_false_positive_rate', 'fraction_data_used_for_testing', 'test_elbo', 'test_epoch', 'train_elbo', 'train_epoch' + obsm: 'gene_expression_encoding' + +How to use the latent gene expression downstream +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +After loading data using the ``anndata_from_h5()`` function as shown above, +we can compute nearest neighbors +in scanpy, using the CellBender latent representation of cells, and make a UMAP and do clustering: + +.. code-block:: python + + # compute a UMAP and do clustering using the cellbender latent gene expression embedding + sc.pp.neighbors(adata, use_rep='gene_expression_encoding', metric='euclidean', method='umap') + sc.pp.umap(adata) + sc.pp.leiden(adata) + +.. _open-in-seurat: + +Seurat +~~~~~~ + +Seurat 4.0.2 uses a dataloader ``Read10X_h5()`` which is not currently compatible with +the CellBender output file format. Hopefully Seurat will update its dataloader to +ignore extra information in the future, but in the interim, we can use a `super +handy utility from PyTables +<https://www.pytables.org/usersguide/utilities.html#ptrepack>`_ to strip the +extra CellBender information out of the output file so that Seurat can load it. + +From a python environment in which PyTables is installed, do the following at +the command line: + +.. code-block:: console + + $ ptrepack --complevel 5 tiny_output_filtered.h5:/matrix tiny_output_filtered_seurat.h5:/matrix + +(The flag ``--complevel 5`` ensures that the file size does not increase.) + +The file ``tiny_output_filtered_seurat.h5`` is now formatted *exactly* like +a CellRanger v3 h5 file, so Seurat can load it: + +.. code-block:: Rd + + # load data from the filtered h5 file + data.file <- 'tiny_output_filtered_seurat.h5' + data.data <- Read10X_h5(filename = data.file, use.names = TRUE) + + # create Seurat object + obj <- CreateSeuratObject(counts = data.data) + obj + +.. code-block:: console + + An object of class Seurat + 100 features across 531 samples within 1 assay + Active assay: RNA (100 features, 0 variable features) + +Of course, this will not load any metadata from CellBender, so if that is desired, +it would have to be accessed and added to the object another way. + +Another option for loading data into Seurat would be third party packages like +`scCustomize from Samuel Marsh +<https://github.com/broadinstitute/CellBender/issues/145#issuecomment-1217360305>`_. diff --git a/docs/source/usage/index.rst b/docs/source/usage/index.rst index 295ad11c..bb0d5e95 100644 --- a/docs/source/usage/index.rst +++ b/docs/source/usage/index.rst @@ -9,8 +9,8 @@ remove-background Use case ~~~~~~~~ -``remove-background`` is used to remove ambient / background RNA from a count matrix produced by -`10x Genomics' CellRanger pipeline +``remove-background`` is used to remove ambient / background RNA from a count matrix, +such as one produced by the `10x Genomics' CellRanger pipeline <https://support.10xgenomics.com/single-cell-gene-expression/software/pipelines/latest/what-is-cell-ranger>`_. The output of ``cellranger count`` produces a raw .h5 file that is used as the input for ``remove-background``. @@ -21,6 +21,8 @@ analysis using Seurat, scanpy, your own custom analysis, etc. The output of ``remove-background`` includes a new .h5 count matrix, with background RNA removed, that can directly be used in downstream analysis in Seurat or scanpy as if it were the raw dataset. +.. _proposed-pipeline: + Proposed pipeline ~~~~~~~~~~~~~~~~~ @@ -28,6 +30,9 @@ Proposed pipeline #. Run ``cellbender remove-background`` #. Perform per-cell quality control checks, and filter out dead / dying cells, as appropriate for your experiment +#. Perform all subsequent analyses using the CellBender count matrix. (It is useful + to also load the raw data: keep it as a layer in an ``anndata`` object, for + example, see :ref:`here <loading-outputs>`) A few caveats and hints: @@ -61,7 +66,7 @@ Run ``remove-background`` on the dataset using the following command .. code-block:: console - (CellBender) $ cellbender remove-background \ + (cellbender) $ cellbender remove-background \ --input raw_feature_bc_matrix.h5 \ --output output.h5 \ --cuda \ @@ -85,15 +90,22 @@ This command will produce five output files: output for convenient use in certain downstream applications. * ``output.pdf``: PDF file that provides a standard graphical summary of the inference procedure. * ``output.log``: Log file produced by the ``cellbender remove-background`` run. +* ``output_metrics.csv``: Metrics describing the run, potentially to be used to flag + problematic runs when using CellBender as part of a large-scale automated pipeline. +* ``output_report.html``: HTML report including plots and commentary, along with any + warnings or suggestions for improved parameter settings. +* ``ckpt.tar.gz``: Checkpoint file which contains the trained model and the full posterior. Quality control checks ~~~~~~~~~~~~~~~~~~~~~~ * Check the log file for any warnings. -* Check lines 8 - 11 in the log file. Ensure that the automatically-determined priors +* Check lines 11 -18 in the log file. Ensure that the automatically-determined priors for cell counts and empty droplet counts match your expectation from the UMI curve. Ensure that the numbers of "probable cells", "additional barcodes", and "empty droplets" are all nonzero and look reasonable. +* Look at the HTML report and note any warnings it gives. The report will give advice + for re-running the tool if appropriate. * Examine the PDF output. * Look at the upper plot to check whether @@ -108,7 +120,7 @@ Quality control checks * Check the middle plot to see which droplets have been called as cells. A converged inference procedure should result in the vast majority of cell probabilities being very close to either zero or one. If the cell calls look problematic, check - the :ref:`help documentation <remove background reference troubleshooting>`. + the :ref:`help documentation <remove background troubleshooting>`. Keep in mind that ``remove-background`` will output a high cell probability for any droplet that is unlikely to be drawn from the ambient background. This can result in a large number @@ -125,16 +137,19 @@ Quality control checks difficulties in calling which droplets contain cells.) * Create some validation plots of various analyses with and without - ``cellbender remove-background``. One convenient way to do this is in ``scanpy`` - and storing the raw count matrix and the background-removed count matrix as - separate `"layers" <https://anndata.readthedocs.io/en/latest/anndata.AnnData.layers.html>`_. + ``cellbender remove-background``. One convenient way to do this is in ``scanpy``, + storing the raw count matrix and the background-removed count matrix as + separate `"layers" <https://anndata.readthedocs.io/en/latest/generated/anndata.AnnData.layers.html>`_. - * UMAPs with and without (on the same set of cell barcodes) - * Marker gene dotplots and violin plots (you should see less background) + * UMAPs with and without CellBender (on the same set of cell barcodes) + * Marker gene dotplots and violin plots before and after CellBender + (you should see less background noise) * Directly subtract the output count matrix from the input count matrix and take a close look at what was removed. +.. _best-practices: + Recommended best practices ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -142,6 +157,11 @@ The default settings are good for getting started with a clean and simple datase the publicly available `PBMC dataset from 10x Genomics <https://support.10xgenomics.com/single-cell-gene-expression/datasets/2.1.0/pbmc8k>`_. +As of v0.3.0, users will typically not need to set values for ``--expected-cells`` +or ``--total-droplets-included``, as CellBender will choose reasonable values +based on your dataset. If something goes wrong with these defaults, then you can +try to input these arguments manually. + Considerations for setting parameters: * ``--epochs``: 150 is typically a good choice. Look for a reasonably-converged ELBO value @@ -163,8 +183,13 @@ Considerations for setting parameters: * ``--cuda``: Include this flag. The code is meant to be run on a GPU. * ``--learning-rate``: The default value of 1e-4 is typically fine, but this value can be adjusted if problems arise during quality-control checks of the learning curve (as above). -* ``--fpr``: A value of 0.01 is generally quite good, but you can generate a few output - count matrices and compare them by choosing a few values: 0.01 0.05 0.1 +* ``--fpr``: A value of 0.01 is the default, and represents a fairly conservative + setting, which is appropriate for most analyses. + In order to examine a single dataset at a time and remove more noise (at the + expense of some signal), choose larger values such as 0.05 or 0.1. Bear in mind + that the value 1 represents removal of (nearly) every count in the dataset, signal and + noise. You can generate multiple output count matrices in the same run by + choosing several values: 0.0 0.01 0.05 0.1 .. image:: /_static/remove_background/UMI_curve_defs.png :width: 250 px diff --git a/examples/remove_background/.gitignore b/examples/remove_background/.gitignore index f631f062..ad6bf5ad 100644 --- a/examples/remove_background/.gitignore +++ b/examples/remove_background/.gitignore @@ -1 +1,7 @@ -tiny_raw_gene_bc_matrices +*.h5 +*.h5ad +ckpt.tar.gz +*.log +*.csv +*.pdf +*.html \ No newline at end of file diff --git a/examples/remove_background/generate_tiny_10x_dataset.py b/examples/remove_background/generate_tiny_10x_dataset.py new file mode 100755 index 00000000..fdbc9554 --- /dev/null +++ b/examples/remove_background/generate_tiny_10x_dataset.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +import sys +import os +import numpy as np +from cellbender.remove_background.downstream import load_anndata_from_input + +dataset_name = "heart10k (CellRanger 3.0.0, v3 Chemistry)" +dataset_url = "https://cf.10xgenomics.com/samples/cell-exp/3.0.0/heart_10k_v3/heart_10k_v3_raw_feature_bc_matrix.h5" +dataset_local_filename = "heart10k_raw_feature_bc_matrix.h5" +expected_cells = 7000 +start_of_empties = 10000 +num_cell_barcodes_to_keep = 500 +num_empty_barcodes_to_keep = 50_000 +low_count_threshold = 30 +num_genes_to_keep = 100 +random_seed = 1984 +rng = np.random.RandomState(random_seed) + + +if not os.path.exists(dataset_local_filename): + + print(f"Downloading {dataset_name}...") + try: + os.system(f'wget -O {dataset_local_filename} {dataset_url}') + + except Exception: + print(f"10x Genomics website is preventing an automatic download. Please visit " + f"https://www.10xgenomics.com/resources/datasets/10-k-heart-cells-from-an-e-18-mouse-v-3-chemistry-3-standard-3-0-0 " + f"in a browser and manually download 'Gene / cell matrix HDF5 (raw)' into " + f"this folder and re-run this script.") + sys.exit() + +print("Loading the dataset...") +adata = load_anndata_from_input(dataset_local_filename) +num_raw_genes = adata.shape[1] +print(f"Raw dataset size {adata.shape}") + +print(f"Trimming {dataset_name}...") + +# select 'num_genes_to_keep' highly expressed genes +total_gene_expression = np.array(adata.X.sum(axis=0)).squeeze() +genes_to_keep_indices = np.argsort(total_gene_expression)[::-1][:num_genes_to_keep] + +# slice dataset on genes +adata = adata[:, genes_to_keep_indices].copy() + +# find cells and empties +umi_per_barcode = np.array(adata.X.sum(axis=1)).squeeze() +umi_sorted_barcode_indices = np.argsort(umi_per_barcode)[::-1] +cell_indices = umi_sorted_barcode_indices[:expected_cells] +last_barcode = (umi_per_barcode > low_count_threshold).sum() +empty_indices = umi_sorted_barcode_indices[start_of_empties:last_barcode] + +# putative list of barcodes to keep +cell_barcodes_to_keep_indices = np.asarray(cell_indices)[ + rng.permutation(len(cell_indices))[:num_cell_barcodes_to_keep]].tolist() +empty_barcodes_to_keep_indices = np.asarray(empty_indices)[ + rng.permutation(len(empty_indices))[:num_empty_barcodes_to_keep]].tolist() +barcodes_to_keep_indices = cell_barcodes_to_keep_indices + empty_barcodes_to_keep_indices + +# slice dataset on barcodes +adata = adata[barcodes_to_keep_indices].copy() + +# compensate for lost counts (due to the reduced number of genes) +adata.X = adata.X * int((num_raw_genes / num_genes_to_keep) ** 0.25) + +print(f"Number of genes in the trimmed dataset: {len(genes_to_keep_indices)}") +print(f"Number of barcodes in the trimmed dataset: {len(barcodes_to_keep_indices)}") +print(f"Expected number of cells in the trimmed dataset: {num_cell_barcodes_to_keep}") + +print(adata) + +# save +output_file = 'tiny_raw_feature_bc_matrix.h5ad' +print(f"Saving the trimmed dataset as {output_file} ...") +adata.write(output_file) + +print("Done!") diff --git a/examples/remove_background/generate_tiny_10x_pbmc.py b/examples/remove_background/generate_tiny_10x_pbmc.py deleted file mode 100755 index fff6fdb2..00000000 --- a/examples/remove_background/generate_tiny_10x_pbmc.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env python - -import urllib.request -import sys -import tarfile -import os -import numpy as np -from scipy.io import mmread, mmwrite -import pandas as pd -import operator -import shutil - -dataset_name = "pbmc4k (CellRanger 2.1.0, v2 Chemistry)" -dataset_url = "http://cf.10xgenomics.com/samples/cell-exp/2.1.0/pbmc4k/pbmc4k_raw_gene_bc_matrices.tar.gz" -dataset_local_filename = "pbmc4k_raw_gene_bc_matrices.tar.gz" -expected_cells = 4000 -num_cell_barcodes_to_keep = 500 -num_empty_barcodes_to_keep = 50_000 -num_genes_to_keep = 100 -random_seed = 1984 -rng = np.random.RandomState(random_seed) - -print(f"Downloading {dataset_name}...") -try: - urllib.request.urlretrieve(dataset_url, dataset_local_filename) -except IOError: - print(f"Could not retrieve {dataset_name} -- cannot continue!") - sys.exit() - -print(f"Extracting {dataset_name}...") -tar = tarfile.open(dataset_local_filename, "r:gz") -tar.extractall() -tar.close() - -extracted_dataset_local_path = os.path.join(os.curdir, "raw_gene_bc_matrices") -matrix_mtx_path = os.path.join(extracted_dataset_local_path, "GRCh38", "matrix.mtx") -genes_tsv_path = os.path.join(extracted_dataset_local_path, "GRCh38", "genes.tsv") -barcodes_tsv_path = os.path.join(extracted_dataset_local_path, "GRCh38", "barcodes.tsv") - -print("Loading the gene expression matrix...") -matrix_mtx = mmread(matrix_mtx_path) -num_raw_genes = matrix_mtx.shape[0] -num_raw_barcodes = matrix_mtx.shape[1] - -print("Loading genes and barcodes...") -genes_df = pd.read_csv(genes_tsv_path, delimiter="\t", header=None) -barcodes_df = pd.read_csv(barcodes_tsv_path, delimiter="\t", header=None) - -print(f"Trimming {dataset_name}...") -# (naive) indices of expected cells -umi_per_barcode = np.asarray(np.sum(matrix_mtx, 0)).flatten() -total_gene_expression = np.asarray(np.sum(matrix_mtx, 1)).flatten() -umi_sorted_barcode_indices = list( - map(operator.itemgetter(0), - sorted(enumerate(umi_per_barcode), key=operator.itemgetter(1), reverse=True))) -cell_indices = umi_sorted_barcode_indices[:expected_cells] -empty_indices = umi_sorted_barcode_indices[expected_cells:] - -# (naive) filter counts to non-empty droplets -cell_counts_csr = matrix_mtx.tocsc()[:, cell_indices].tocsr() - -# select 'num_genes_to_keep' highly expressed genes -genes_to_keep_indices = sorted(range(num_raw_genes), - key=lambda x: total_gene_expression[x], reverse=True)[:num_genes_to_keep] - -# putative list of barcodes to keep -cell_barcodes_to_keep_indices = np.asarray(cell_indices)[ - rng.permutation(len(cell_indices))[:num_cell_barcodes_to_keep]].tolist() -empty_barcodes_to_keep_indices = np.asarray(empty_indices)[ - rng.permutation(len(empty_indices))[:num_empty_barcodes_to_keep]].tolist() -barcodes_to_keep_indices = cell_barcodes_to_keep_indices + empty_barcodes_to_keep_indices - -# remove barcodes with zero expression on kept genes -trimmed_counts_matrix = matrix_mtx.tocsr()[genes_to_keep_indices, :].tocsc()[:, barcodes_to_keep_indices] -umi_per_putatively_kept_barcodes = np.asarray(np.sum(trimmed_counts_matrix, 0)).flatten() -barcodes_to_keep_indices = np.asarray(barcodes_to_keep_indices)[umi_per_putatively_kept_barcodes > 0] -barcodes_to_keep_indices = barcodes_to_keep_indices.tolist() - -# slice the raw dataset -tiny_matrix_mtx = matrix_mtx.tocsr()[genes_to_keep_indices, :].tocsc()[:, barcodes_to_keep_indices].tocoo() -tiny_genes_df = genes_df.loc[genes_to_keep_indices] -tiny_barcodes_df = barcodes_df.loc[barcodes_to_keep_indices] - -# compensate for lost counts (due to the reduced number of genes) -tiny_matrix_mtx = tiny_matrix_mtx * int((num_raw_genes / num_genes_to_keep) ** 0.25) - -print(f"Number of genes in the trimmed dataset: {len(genes_to_keep_indices)}") -print(f"Number of barcodes in the trimmed dataset: {len(barcodes_to_keep_indices)}") -print(f"Expected number of cells in the trimmed dataset: {num_cell_barcodes_to_keep}") - -# save -print("Saving the trimmed dataset...") -output_path = os.path.join(os.curdir, 'tiny_raw_gene_bc_matrices', 'GRCh38') -os.makedirs(output_path, exist_ok=True) -mmwrite(os.path.join(output_path, "matrix.mtx"), tiny_matrix_mtx) -tiny_genes_df.to_csv(os.path.join(output_path, "genes.tsv"), sep='\t', header=None, index=False) -tiny_barcodes_df.to_csv(os.path.join(output_path, "barcodes.tsv"), sep='\t', header=None, index=False) - -print("Cleaning up...") -shutil.rmtree(extracted_dataset_local_path, ignore_errors=True) -os.remove(dataset_local_filename) - -print("Done!") diff --git a/readthedocs.yml b/readthedocs.yml index 91ace26f..6e320be3 100644 --- a/readthedocs.yml +++ b/readthedocs.yml @@ -3,6 +3,6 @@ version: 2 python: version: 3.7 install: - - requirements: REQUIREMENTS-RTD.txt + - requirements: requirements-rtd.txt - method: pip path: . diff --git a/REQUIREMENTS-RTD.txt b/requirements-rtd.txt similarity index 100% rename from REQUIREMENTS-RTD.txt rename to requirements-rtd.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..3585b6a4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,15 @@ +numpy +scipy +tables +pandas +pyro-ppl>=1.8.4 +torch +matplotlib +anndata>=0.7 +loompy +ipython +jupyter +jupyter_contrib_nbextensions +notebook<7.0.0 +nbconvert<7.0.0 +psutil diff --git a/setup.py b/setup.py index 9078221c..106fa57c 100644 --- a/setup.py +++ b/setup.py @@ -2,35 +2,58 @@ import os import setuptools +import codecs +from typing import List -def readme(): +def read(rel_path): + here = os.path.abspath(os.path.dirname(__file__)) + with codecs.open(os.path.join(here, rel_path), 'r') as fp: + return fp.read() + + +def get_version() -> str: + for line in read('cellbender/__init__.py').splitlines(): + if line.startswith('__version__'): + delim = '"' if '"' in line else "'" + return line.split(delim)[1] + else: + raise RuntimeError("Unable to find version string.") + + +def readme() -> str: with open('README.rst') as f: return f.read() -def get_requirements_filename(): +def _readlines(filename, filebase=''): + with open(os.path.join(filebase, filename)) as f: + lines = f.readlines() + return lines + + +def get_requirements() -> List[str]: + requirements = _readlines('requirements.txt') if 'READTHEDOCS' in os.environ: - return "REQUIREMENTS-RTD.txt" - elif 'DOCKER' in os.environ: - return "REQUIREMENTS-DOCKER.txt" - else: - return "REQUIREMENTS.txt" + requirements.extend(get_rtd_requirements()) + return requirements -install_requires = [ - line.rstrip() for line in open(os.path.join(os.path.dirname(__file__), get_requirements_filename())) -] +def get_rtd_requirements() -> List[str]: + requirements = _readlines('requirements-rtd.txt') + return requirements + setuptools.setup( name='cellbender', - version='0.2.2', + version=get_version(), description='A software package for eliminating technical artifacts from ' 'high-throughput single-cell RNA sequencing (scRNA-seq) data', long_description=readme(), + long_description_content_type='text/x-rst', classifiers=[ - 'Development Status :: 3 - Alpha', - 'Intended Audience :: Science/Research' + 'Development Status :: 4 - Beta', + 'Intended Audience :: Science/Research', 'License :: OSI Approved :: BSD License', 'Programming Language :: Python :: 3.7', 'Topic :: Scientific/Engineering :: Bio-Informatics', @@ -40,10 +63,15 @@ def get_requirements_filename(): author='Stephen Fleming, Mehrtash Babadi', license='BSD (3-Clause)', packages=setuptools.find_packages(), - install_requires=install_requires, + install_requires=get_requirements(), + extras_require={ + "dev": ["pytest", "scikit-learn"], + "docs": get_rtd_requirements(), + }, entry_points={ 'console_scripts': ['cellbender=cellbender.base_cli:main'], }, include_package_data=True, + package_data={'': ['*.ipynb']}, # include the report template zip_safe=False ) diff --git a/wdl/README.rst b/wdl/README.rst index 22325678..b82743ca 100644 --- a/wdl/README.rst +++ b/wdl/README.rst @@ -8,7 +8,7 @@ enable CellBender commands to be run on cloud computing architecture. ``remove-background`` --------------------- -The workflow that runs ``cellbender remove-background`` on a (Tesla K80) GPU on a +The workflow that runs ``cellbender remove-background`` on a (Tesla T4) GPU on a Google Cloud virtual machine is located at ``wdl/cellbender_remove_background.wdl``. Method inputs: @@ -20,9 +20,8 @@ refer to the `documentation Required: -* ``input_10x_h5_file_or_mtx_directory``: Path to raw count matrix output by 10x - ``cellranger count`` as either a .h5 file or as the directory that contains - ``matrix.mtx(.gz)``. In the `Terra <https://app.terra.bio>`_ +* ``input_file_unfiltered``: Path to raw count matrix such as an .h5 file from + ``cellranger count``, or as a .h5ad or a DGE-format .csv. In the `Terra <https://app.terra.bio>`_ data model, this could be ``this.h5_file``, where "h5_file" is the column of the data model that contains the path to the raw count matrix h5. Alternatively, this could be a Google bucket path as a String (e.g. @@ -45,40 +44,31 @@ Optional and recommended: be called as either cell or empty droplet by the inference procedure. Any droplets not included in the ``total_droplets_included`` largest UMI-count droplets will be treated as surely empty. +* ``output_bucket_base_directory``: Google bucket path (gsURL) to a directory where + you want outputs to be copied. Within that directory, a new folder will appear + called `sample_name`, and all outputs will go there. Note that your data will + then be in two locations in the Cloud: here and wherever Cromwell has its + execution directory (if using Terra, this is in your workspace's Google bucket). Optional: * ``learning_rate``: The learning rate used during inference, as a Float (e.g. ``1e-4``). * ``epochs``: Number of epochs to train during inference, as an Int (e.g. 150). -* ``model``: One of {"full", "ambient", "swapping", "simple"}. This specifies how - the count data should be modeled. "full" specifies an ambient RNA plus chimera - formation model, while "ambient" specifies a model with only ambient RNA, and - "swapping" specifies a model with only chimera formation. "simple" should not - be used in this context. * ``low_count_threshold``: An Int that specifies a number of unique UMIs per droplet (e.g. 15). Droplets with total unique UMI count below ``low_count_threshold`` will be entirely excluded from the analysis. They are assumed not even to be empty droplets, but some barcode error artifacts that are not useful for inference. -* ``blacklist_genes``: A whitespace-delimited String of integers - (e.g. "523 10021 10022 33693 33694") that specifies genes that should be completely - excluded from analysis. Counts of these genes are set to zero in the output count matrix. - Genes are specified by the integer that indexes them in the count matrix. - -Optional but discouraged: - -[There should not be any need to change these parameters from their default values.] - -* ``z_dim``: Dimension of the latent gene expression space, as an Int. Use a smaller - value (e.g. 20) for slightly more imputation, and a larger value (e.g. 200) for - less imputation. -* ``z_layers``: Architecture of the neural network autoencoder for the latent representation - of gene expression. ``z_layers`` specifies the size of each hidden layer. - Input as a whitespace-delimited String of integers, (e.g. "1000"). - Only use one hidden layer. [Two hidden layers could be specified with "500 100" for - example, but only one hidden layer should be used.] -* ``empty_drop_training_fraction``: Specifies what fraction of the data in each - minibatch should come from surely empty droplets, as a Float (e.g. 0.3). +* ``projected_ambient_count_threshold``: The larger this number, the fewer genes + (features) are analyzed, and the faster the tool will run. Default is 0.1. The + value represents the expected number of ambient counts (summed over all cells) + that we would estimate based on naive assumptions. Features with fewer expected + counts than this threshold will be ignored, and the output for those features will + be identical to the input. + +Other input parameters are explained `in the documentation +<https://cellbender.readthedocs.io/en/latest/help_and_reference/remove_background/index.html>`_, +but are only useful in rare cases. Optional runtime specifications: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -87,8 +77,9 @@ Software: * ``docker_image``: Name of the docker image which will be used to run the ``cellbender remove-background`` command, as a String that references an image - either on the Google Container Registry (e.g. "us.gcr.io/broad-dsde-methods/cellbender:latest") - or Dockerhub (e.g. "dockerhub_username/image_name"). Images should be 3GB or smaller. + with CellBender installed (e.g. "us.gcr.io/broad-dsde-methods/cellbender:0.3.0"). + Note that this WDL may not be compatible with other versions of CellBender due + to changes in input arguments. Hardware: @@ -100,23 +91,40 @@ Hardware: * ``hardware_disk_size_GB``: Specify the size of the disk attached to the VM, as an Int in units of GB. * ``hardware_preemptible_tries``: Specify the number of preemptible runs to attempt, - as an Int. Preemptible runs are 1/3 to 1/4 the cost. If the run gets pre-empted + as an Int. Preemptible runs are 1/3 to 1/4 the cost. If the run gets preempted ``hardware_preemptible_tries`` times, a final non-preemptible run is carried out. + Work is not lost during preemption because the workflow uses + `checkpointing <https://cromwell.readthedocs.io/en/stable/optimizations/CheckpointFiles/>`_ + to pick up (near) where it left off. Outputs: ~~~~~~~~ -``cellbender remove-background`` outputs five files, and each of these output files is +``cellbender remove-background`` outputs several files, and each of these files is included as an output of the workflow. -If multiple FPR values are specified, then separate ``h5`` and - -* ``h5_array``: Array of output count matrix files, with background RNA removed. -* ``output_directory``: Same as the workflow input parameter, useful for populating - a column of the Terra data model. -* ``csv``: CSV file containing all the droplet barcodes which were determined to have +If multiple FPR values are specified, then separate ``.h5`` and ``report.html`` +``metrics.csv`` files will be produced, one for each FPR. + +* ``h5_array``: Array of output count matrix files (one for each FPR), with + background RNA removed. +* ``html_report_array``: Array of HTML output reports (one for each FPR) +* ``metrics_csv_array``: Array of CSV files that include output metrics (one for + each FPR) +* ``output_directory``: If the input `output_base_directory` was blank, this + will be black too. Same as the workflow input parameter, but with the + `sample_name` subdirectory added: useful for populating + a column of the Terra data model. All outputs are copied here. +* ``cell_barcodes_csv``: CSV file containing all the droplet barcodes which were determined to have a > 50% posterior probability of containing cells. Barcodes are written in plain text. This information is also contained in each of the above outputs, but is included as a separate output for convenient use in certain downstream applications. -* ``pdf``: PDF file that provides a standard graphical summary of the inference procedure. +* ``summary_pdf``: PDF file that provides a quick graphical summary of the run. * ``log``: Log file produced by the ``cellbender remove-background`` run. + + +Cost: +~~~~~ + +The cost to run a single sample in v0.3.0 on a preemptible Nvidia Tesla T4 GPU +on Google Cloud hovers somewhere in the ballpark of diff --git a/wdl/cellbender_remove_background.wdl b/wdl/cellbender_remove_background.wdl index 014bd882..4efb8faf 100644 --- a/wdl/cellbender_remove_background.wdl +++ b/wdl/cellbender_remove_background.wdl @@ -1,4 +1,6 @@ -## Copyright Broad Institute, 2020 +version 1.0 + +## Copyright Broad Institute, 2022 ## ## LICENSING : ## This script is released under the WDL source code license (BSD-3) @@ -6,93 +8,234 @@ task run_cellbender_remove_background_gpu { - # File-related inputs - String sample_name - File input_10x_h5_file_or_mtx_directory - - # Outputs - String output_directory # Google bucket path - - # Docker image for cellbender remove-background version - String? docker_image = "us.gcr.io/broad-dsde-methods/cellbender:0.2.0" - - # Method configuration inputs - Int? expected_cells - Int? total_droplets_included - String? model - Int? low_count_threshold - String? fpr # in quotes: floats separated by whitespace: the output false positive rate(s) - Int? epochs - Int? z_dim - String? z_layers # in quotes: integers separated by whitespace - Float? empty_drop_training_fraction - String? blacklist_genes # in quotes: integers separated by whitespace - Float? learning_rate - Boolean? exclude_antibody_capture = false - - # Hardware-related inputs - String? hardware_zones = "us-east1-d us-east1-c us-central1-a us-central1-c us-west1-b" - Int? hardware_disk_size_GB = 50 - Int? hardware_boot_disk_size_GB = 20 - Int? hardware_preemptible_tries = 0 - Int? hardware_cpu_count = 4 - Int? hardware_memory_GB = 15 - String? hardware_gpu_type = "nvidia-tesla-t4" - - command { - cellbender remove-background \ - --input "${input_10x_h5_file_or_mtx_directory}" \ - --output "${sample_name}_out.h5" \ - --cuda \ - ${"--expected-cells " + expected_cells} \ - ${"--total-droplets-included " + total_droplets_included} \ - ${"--fpr " + fpr} \ - ${"--model " + model} \ - ${"--low-count-threshold " + low_count_threshold} \ - ${"--epochs " + epochs} \ - ${"--z-dim " + z_dim} \ - ${"--z-layers " + z_layers} \ - ${"--empty-drop-training-fraction " + empty_drop_training_fraction} \ - ${"--blacklist-genes " + blacklist_genes} \ - ${"--learning-rate " + learning_rate} \ - ${true="--exclude-antibody-capture" false=" " exclude_antibody_capture} - - gsutil -m cp ${sample_name}_out* ${output_directory}/${sample_name}/ - } - - output { - File log = "${sample_name}_out.log" - File pdf = "${sample_name}_out.pdf" - File csv = "${sample_name}_out_cell_barcodes.csv" - Array[File] h5_array = glob("${sample_name}_out*.h5") # v2 creates a number of outputs depending on "fpr" - String output_dir = "${output_directory}/${sample_name}" - } - - runtime { - docker: "${docker_image}" - bootDiskSizeGb: hardware_boot_disk_size_GB - disks: "local-disk ${hardware_disk_size_GB} HDD" - memory: "${hardware_memory_GB}G" - cpu: hardware_cpu_count - zones: "${hardware_zones}" - gpuCount: 1 - gpuType: "${hardware_gpu_type}" - preemptible: hardware_preemptible_tries - maxRetries: 0 - } + input { + + # File-related inputs + String sample_name + File input_file_unfiltered # all barcodes, raw data + File? barcodes_file # for MTX and NPZ formats, the bacode information is in a separate file + File? genes_file # for MTX and NPZ formats, the gene information is in a separate file + File? checkpoint_file # start from a saved checkpoint + File? truth_file # only for developers using simulated data + + # Outputs + String? output_bucket_base_directory # Google bucket path + + # Docker image with CellBender + String? docker_image = "us.gcr.io/broad-dsde-methods/cellbender:0.3.0" + + # Used by developers for testing non-dockerized versions of CellBender + String? dev_git_hash__ # leave blank to run CellBender normally + + # Method configuration inputs + Int? expected_cells + Int? total_droplets_included + Float? force_cell_umi_prior + Float? force_empty_umi_prior + String? model + Int? low_count_threshold + String? fpr # in quotes: floats separated by whitespace: the output false positive rate(s) + Int? epochs + Int? z_dim + String? z_layers # in quotes: integers separated by whitespace + Float? empty_drop_training_fraction + Float? learning_rate + String? exclude_feature_types # in quotes: strings separated by whitespace + String? ignore_features # in quotes: integers separated by whitespace + Float? projected_ambient_count_threshold + Float? checkpoint_mins + Float? final_elbo_fail_fraction + Float? epoch_elbo_fail_fraction + Int? num_training_tries + Float? learning_rate_retry_mult + Int? posterior_batch_size + Boolean? estimator_multiple_cpu + Boolean? constant_learning_rate + Boolean? debug + + # Hardware-related inputs + String? hardware_zones = "us-east1-d us-east1-c us-central1-a us-central1-c us-west1-b" + Int? hardware_disk_size_GB = 50 + Int? hardware_boot_disk_size_GB = 20 + Int? hardware_preemptible_tries = 2 + Int? hardware_cpu_count = 4 + Int? hardware_memory_GB = 32 + String? hardware_gpu_type = "nvidia-tesla-t4" + String? nvidia_driver_version = "470.82.01" # need >=465.19.01 for CUDA 11.3 + + } + + # For development only: install a non dockerized version of CellBender + Boolean install_from_git = (if defined(dev_git_hash__) then true else false) + + # Compute the output bucket directory for this sample: output_bucket_base_directory/sample_name/ + String output_bucket_directory = (if defined(output_bucket_base_directory) + then sub(select_first([output_bucket_base_directory]), "/+$", "") + "/${sample_name}/" + else "") + + command { + + set -e # fail the workflow if there is an error + + # install a specific commit of cellbender from github if called for (-- developers only) + if [[ ~{install_from_git} == true ]]; then + echo "Uninstalling pre-installed cellbender" + yes | pip uninstall cellbender + echo "Installing cellbender from github" + # this more succinct version is broken in some older versions of cellbender + echo "pip install --no-cache-dir -U git+https://github.com/broadinstitute/CellBender.git@~{dev_git_hash__}" + # yes | pip install --no-cache-dir -U git+https://github.com/broadinstitute/CellBender.git@~{dev_git_hash__} + # this should always work + git clone -q https://github.com/broadinstitute/CellBender.git /cromwell_root/CellBender + cd /cromwell_root/CellBender + git checkout -q ~{dev_git_hash__} + yes | pip install --no-cache-dir -U -e /cromwell_root/CellBender + pip list + cd /cromwell_root + fi + + # put the barcodes_file in the right place, if it is provided + if [[ ! -z "~{barcodes_file}" ]]; then + dir=$(dirname ~{input_file_unfiltered}) + if [[ "~{input_file_unfiltered}" == *.npz ]]; then + name="row_index.npy" + elif [[ "~{barcodes_file}" == *.gz ]]; then + name="barcodes.tsv.gz" + else + name="barcodes.tsv" + fi + echo "Moving barcodes file to "$dir"/"$name + echo "mv ~{barcodes_file} "$dir"/"$name + [ -f $dir/$name ] || mv ~{barcodes_file} $dir/$name + fi + + # put the genes_file in the right place, if it is provided + if [[ ! -z "~{genes_file}" ]]; then + dir=$(dirname ~{input_file_unfiltered}) + if [[ "~{input_file_unfiltered}" == *.npz ]]; then + name="col_index.npy" + elif [[ "~{genes_file}" == *.gz ]]; then + name="features.tsv.gz" + else + name="genes.tsv" + fi + echo "Moving genes file to "$dir"/"$name + echo "mv ~{genes_file} "$dir"/"$name + [ -f $dir/$name ] || mv ~{genes_file} $dir/$name + fi + + cellbender remove-background \ + --input "~{input_file_unfiltered}" \ + --output "~{sample_name}_out.h5" \ + --cuda \ + ~{"--checkpoint " + checkpoint_file} \ + ~{"--expected-cells " + expected_cells} \ + ~{"--total-droplets-included " + total_droplets_included} \ + ~{"--fpr " + fpr} \ + ~{"--model " + model} \ + ~{"--low-count-threshold " + low_count_threshold} \ + ~{"--epochs " + epochs} \ + ~{"--force-cell-umi-prior " + force_cell_umi_prior} \ + ~{"--force-empty-umi-prior " + force_empty_umi_prior} \ + ~{"--z-dim " + z_dim} \ + ~{"--z-layers " + z_layers} \ + ~{"--empty-drop-training-fraction " + empty_drop_training_fraction} \ + ~{"--exclude-feature-types " + exclude_feature_types} \ + ~{"--ignore-features " + ignore_features} \ + ~{"--projected-ambient-count-threshold " + projected_ambient_count_threshold} \ + ~{"--learning-rate " + learning_rate} \ + ~{"--checkpoint-mins " + checkpoint_mins} \ + ~{"--final-elbo-fail-fraction " + final_elbo_fail_fraction} \ + ~{"--epoch-elbo-fail-fraction " + epoch_elbo_fail_fraction} \ + ~{"--num-training-tries " + num_training_tries} \ + ~{"--learning-rate-retry-mult " + learning_rate_retry_mult} \ + ~{"--posterior-batch-size " + posterior_batch_size} \ + ~{true="--estimator-multiple-cpu " false=" " estimator_multiple_cpu} \ + ~{true="--constant-learning-rate " false=" " constant_learning_rate} \ + ~{true="--debug " false=" " debug} \ + ~{"--truth " + truth_file} + + # copy outputs to google bucket if output_bucket_base_directory is supplied + if [[ ! -z "~{output_bucket_directory}" ]]; then + echo "Copying output data to ~{output_bucket_directory} using gsutil cp" + gsutil -m cp ~{sample_name}_out* ~{output_bucket_directory} + fi + + } + + output { + File log = "${sample_name}_out.log" + File pdf = "${sample_name}_out.pdf" + File cell_csv = "${sample_name}_out_cell_barcodes.csv" + Array[File] metrics_array = glob("${sample_name}_out*_metrics.csv") # a number of outputs depending on "fpr" + Array[File] report_array = glob("${sample_name}_out*_report.html") # a number of outputs depending on "fpr" + Array[File] h5_array = glob("${sample_name}_out*.h5") # a number of outputs depending on "fpr" + String output_dir = "${output_bucket_directory}" + File ckpt_file = "ckpt.tar.gz" + } + + runtime { + docker: "${docker_image}" + bootDiskSizeGb: hardware_boot_disk_size_GB + disks: "local-disk ${hardware_disk_size_GB} HDD" + memory: "${hardware_memory_GB}G" + cpu: hardware_cpu_count + zones: "${hardware_zones}" + gpuCount: 1 + gpuType: "${hardware_gpu_type}" + nvidiaDriverVersion: "${nvidia_driver_version}" + preemptible: hardware_preemptible_tries + checkpointFile: "ckpt.tar.gz" + maxRetries: 0 # can be used in case of a PAPI error code 2 failure to install GPU drivers + } + meta { + author: "Stephen Fleming" + email: "sfleming@broadinstitute.org" + description: "WDL that runs CellBender remove-background on a GPU on Google Cloud hardware. See the [CellBender GitHub repo](https://github.com/broadinstitute/CellBender) and [read the documentation](https://cellbender.readthedocs.io/en/v0.3.0/reference/index.html#command-line-options) for more information." + } + + parameter_meta { + sample_name : + {help: "Name which will be prepended to output files and which will be used to construct the output google bucket file path, if output_bucket_base_directory is supplied, as output_bucket_base_directory/sample_name/"} + input_file_unfiltered : + {help: "Input file. This must be raw data that includes all barcodes. See http://cellbender.readthedocs.io for more information on file formats, but importantly, this must be one file, and cannot be a pointer to a directory that contains MTX and TSV files."} + barcodes_file : + {help: "Supply this only if your input_file_unfiltered is a sparse NPZ matrix from Optimus lacking metadata."} + genes_file : + {help: "Supply this only if your input_file_unfiltered is a sparse NPZ matrix from Optimus lacking metadata."} + output_bucket_base_directory : + {help: "Optional google bucket gsURL. If provided, the workflow will create a subfolder called sample_name in this directory and copy outputs there. (Note that the output data would then exist in two places.) Helpful for organization."} + docker_image : + {help: "CellBender docker image. Not all CellBender docker image tags will be compatible with this WDL.", + suggestions: ["us.gcr.io/broad-dsde-methods/cellbender:0.3.0"]} + checkpoint_file : + {help: "Optional gsURL for a checkpoint file created using a previous run ('ckpt.tar.gz') on the same dataset (using the same CellBender docker image). This can be used to create a new output with a different --fpr without re-doing the training run."} + truth_file : + {help: "Optional file only used by CellBender developers or those trying to benchmark CellBender remove-background on simulated data. Normally, this input would not be supplied."} + hardware_preemptible_tries : + {help: "If nonzero, CellBender will be run on a preemptible instance, at a lower cost. If preempted, your run will not start from scratch, but will start from a checkpoint that is saved by CellBender and recovered by Cromwell. For example, if hardware_preemptible_tries is 2, your run will attempt twice using preemptible instances, and if the job is preempted both times before completing, it will finish on a non-preemptible machine. The cost savings is significant. The potential drawback is that preemption wastes time."} + checkpoint_mins : + {help: "Time in minutes between creation of checkpoint files. Bear in mind that Cromwell copies checkpoints to a bucket every ten minutes."} + hardware_gpu_type : + {help: "Specify the type of GPU that should be used. Ensure that the selected hardware_zones have the GPU available.", + suggestions: ["nvidia-tesla-t4", "nvidia-tesla-k80"]} + } } workflow cellbender_remove_background { - call run_cellbender_remove_background_gpu + call run_cellbender_remove_background_gpu - output { - File log = run_cellbender_remove_background_gpu.log - File pdf = run_cellbender_remove_background_gpu.pdf - File csv = run_cellbender_remove_background_gpu.csv - Array[File] h5_array = run_cellbender_remove_background_gpu.h5_array - String output_directory = run_cellbender_remove_background_gpu.output_dir - } + output { + File log = run_cellbender_remove_background_gpu.log + File summary_pdf = run_cellbender_remove_background_gpu.pdf + File cell_barcodes_csv = run_cellbender_remove_background_gpu.cell_csv + Array[File] metrics_csv_array = run_cellbender_remove_background_gpu.metrics_array + Array[File] html_report_array = run_cellbender_remove_background_gpu.report_array + Array[File] h5_array = run_cellbender_remove_background_gpu.h5_array + String output_directory = run_cellbender_remove_background_gpu.output_dir + File checkpoint_file = run_cellbender_remove_background_gpu.ckpt_file + } } From 02dd763fdb3b740a100cf3251cca3525ed9d134a Mon Sep 17 00:00:00 2001 From: Stephen Fleming <sjf11@case.edu> Date: Mon, 7 Aug 2023 17:29:31 -0400 Subject: [PATCH 02/19] Add Nature Methods citation and update docs --- README.rst | 2 +- .../_static/remove_background/v0.2.2_hgmm.png | Bin 0 -> 203431 bytes .../_static/remove_background/v0.3.0_hgmm.png | Bin 0 -> 187301 bytes .../remove_background/v0.3.0_rc_hgmm.png | Bin 0 -> 212594 bytes docs/source/changelog/index.rst | 54 ++++++++++++++++++ docs/source/citation/index.rst | 5 +- docs/source/contributing/index.rst | 6 ++ docs/source/introduction/index.rst | 4 +- docs/source/troubleshooting/index.rst | 8 +-- docs/source/usage/index.rst | 35 ++++++++---- 10 files changed, 92 insertions(+), 22 deletions(-) create mode 100644 docs/source/_static/remove_background/v0.2.2_hgmm.png create mode 100644 docs/source/_static/remove_background/v0.3.0_hgmm.png create mode 100644 docs/source/_static/remove_background/v0.3.0_rc_hgmm.png diff --git a/README.rst b/README.rst index ea39e2ca..d5895c76 100644 --- a/README.rst +++ b/README.rst @@ -149,6 +149,6 @@ Stephen J Fleming, Mark D Chaffin, Alessandro Arduini, Amer-Denis Akkad, Eric Banks, John C Marioni, Anthony A Phillipakis, Patrick T Ellinor, and Mehrtash Babadi. Unsupervised removal of systematic background noise from droplet-based single-cell experiments using CellBender. -`Nature Methods` (in press), 2023. +`Nature Methods`, 2023. https://doi.org/10.1038/s41592-023-01943-7 See also `our preprint on bioRxiv <https://doi.org/10.1101/791699>`_. diff --git a/docs/source/_static/remove_background/v0.2.2_hgmm.png b/docs/source/_static/remove_background/v0.2.2_hgmm.png new file mode 100644 index 0000000000000000000000000000000000000000..62a76adfca631a9ce43daa3c5d76b25f304c3e9e GIT binary patch literal 203431 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 SSEBnC@X=D&RjW|34*froKx=OR literal 0 HcmV?d00001 diff --git a/docs/source/_static/remove_background/v0.3.0_hgmm.png b/docs/source/_static/remove_background/v0.3.0_hgmm.png new file mode 100644 index 0000000000000000000000000000000000000000..d5c8f404e597a2766b818eabcc4a53343520921a GIT binary patch literal 187301 zcmce;cQl+`7dJdfZYfGckA7zeqKyy{ZA6raE{tBHjW9}dgCTcBv>>7mL3Bp%34=R& z7rhg`8w>_x_^#x6o_D=}ee3({J8NNG{hWRF+55MDdmmxin$M}oS;#>k5Y-D6#g`z^ z^#~B?TJz28z?rXf3&FsjTW?g1+(95Fn%_THx_R(&Akg2S7mD(FK3}$HZ(%uL$dmoG z7tM{=<?on^d|iA;{sU!wi%i0}P`<EwH2nMiTq^@*zR)Y!XH}i#m2}o}u)YahZFv48 z9oM$|GzN-ff06z5&tH@8pB|jcg~-tHxZ4HV&8;*x;nu{`33G(hm0q-%nBA(Q1N<t` zn?LRC!lU4&+y6Tf!SV_IpG$YG=ozp4?+WEZa$q?BZ6EFiD~acCUWJ(zW5jL<@5w69 zT<KfzzsdvYcj2y%=TSj`enMfXOXE{UiV`5ux`6{cSYCIO8BELZx7~@sFv&eAv`DN{ zyv5@^%(J+o!yI0dLH+KLNT~Ez$uC+YEm#Z5En!~HuJtNg)c7d4qP@3-<JhNJ@yoo5 zgMh}TG0;~OrtYO8JfgF_<@n++5Qs9WB3MaDEcix`Zl7bDjok6Yq6=!mPHegmc&)aK z&}g_cq>7D@SQzm^nunLXdi4AXx9`0MO+|f=Gm*uu)D_5QFv5R!>$)W;PnLWWV{r2J z#ag%&gqJ8=obPbc#ABD<Xbp1P=f!lUd|k+=@pTu^5{tBpRc?NZ;CG8KTl_%ka)#U3 z3*&1%l4%)dK^XIu@j&v`E1;+I{DOi9!VkvIdWvWucf))45<T6|FO}e4n>Nsy@{^nB z9c$v>D%Y}xzftrZTSLsdY@`E0raNoaBgU4#+qNSGo*a}U+w*2awdVXI1+1rHv8OkJ zlc!R?fe~3}d`G$_zJDb^OJJ_L(??LI5c|f{tefPXJFn2z8?~+x8q)FitU@Q^Fi&b6 z0{O@s-S63S+i`D8-y={+P{jGSDBpHP+vU$iF!WkD!EaFc`GY`jFJSQA%zSZqpHND( zelzxzX73Ep1K)3^B7c!mpA*MlM}*%Sw4ZTO@xLt__^@Hj!ZbK>dEv_5&A^+IV@r;f zeU0T=iThj^uaKX#Hs@d5*qXzvpzc1&P*Ppb&1|jq_*$a0aDp^=zO>Jj%|H=;CRLoj z*=#6329|Ttq%6KJx|<$>{S?YnHTzJ7aOZ#pmEE#6ZVcfwULkunNP1MYDA^qC`eaUk zVr*DH`S0Q@u@;4dCUWGs<=7}<M}(bjh!X_r!@M+%LznM62WARCg4^{;yx7w=v&eI0 zBInc0sm~R{1}h!9ZA{o8$mJke2>}!@^>w(5a5n=78#Mg=5+w)g*7VHX3CEUql*E5V zw3jm{A!3;3ijGA>to<`D^?ZxceoLI1bXAUH0V`R(?HRshG)_4r`yQ*D{`%Khb@T8{ zSeLVCgTQ$HS3iAud5K^p(53_N!r(DZs&{dg$Ghdf{iNd8HKfNG$ZEyyqs>L;zb<9e zHAXE8%gp#__%8-T#0NA++C&a721^a9<*Tmcc6iTSv#sjWba1V%qYi4PP|Qs%Du;@U zXBq~-Yrqx`Nm=5it1>Zz3Y#o}G%ey7YO0ApeOf;}Td@~*7Zh(AD?JE&Ab9oXx5v0Z z27F0N5n_DGQi>-VutUiPb+$B+rkdo9Ads$mj?`kwJ*acDI_F(K*bn0@_u7rzQ=Jdk zF|||ZWJmzrjs@D?=4*f6Ph0!#dnH5H+~x8ZsHfTHcf(}zGw;nnh$_6}rJpmGzIe+y z{aLXdnW}T1NuHIj0+OO`ZBT>We$ePKF~jC6hxH{i>JWYH?w_Fsiaa;OTl081ZBVlN z&bYCW2O|d;PIm3hl|Ndlgl(ZO+Cu_4OR0?c*(8bL0*vXb=VbPq6rHVDgG8U0WTv#& z{~j@ymu6jA<{cS(K@lh;yf~|9+h(SGmwP8i>4%F`UQE@u?^ELj8!Kg{h54hJQ=<DQ zi}mz8IHX$R$$gq*o;WAZq?|(HC%4(KAy4O%X-$)I&ll&WQ7FROIJ|mt9i#30yhHK2 z4;VAo5lw-?eF4Az6*Ie+tEn6m(<&)sN+_Rs$1{HiQlr7jglaHW-ikEc`XbfOEwLZh zO{g?yuMg-EIQlA(p?shX8#Cc8wq?(ISC(s@ctbYOw2V4(g<Z6HipkZ0z!6hRO*Y-# z(BbWda^}|>aUnEm;-8BjloXqDRiw%5j!hb0jJ1dh>|C%!l9?=>mUdSnbF7C(ymS+s zNTvt}3&8M@i}idtx8ym0Xf9&$Eu)lxv|H|Fij=f`Fbp&5IqUhh*Wq{>m`mVHuSuIJ z;~A5lzQLhsqLrkd*UNcfc$eb&*g^0@=+1c2#93)~XbL*acCB?$MiN(4;i@gl!PBZF zdY*QDvBS$rdB(O~%@I{dy7Kk#KqxoHNOG&(&_}HU=`q9KE7wt5DY|n>+Y?PZcgJK$ zkZ+l3TThnkD99U^z5e%rcB5jjioxXa-Mho1f03!K&_`}U;l;IM;&ts%t%<yvq418r z_lTE2YQ|P`!s4pR%ffu@50a{UG#oemH#bqGjsZN6T{ZwYH+>#HW9h&a<Lk4CM%2+} z7R&KgTY@MOrmTO4XrG77ch0V!a0@1cWo{jOU5hSmL%azSAw1fZYIy!AHK8bI%Y7J` z8Bl-e`B@Hw_I6rf(K)1?YA^4-=`wakQOd;JQ8ZMY*Z<Jos=ndLc=Ch+&!3jN{h-!X zCwO&eDNV;D4i?mcc&22nS#)qQ-*%Z!=NIOx-MwgHB9g!9Xfbe|^Ys&`vufv)UY${@ zxl(`r(xXaIeS}+l>6!zzmfjZR`@G4L0*uM$L%!D&T4J@x<0oe-MPBD@)IHsN&i;QN z@%al3t-?lw!X1R$u78X^Mg-$JuBYdAjG+^*FAAw;o|w`_^o)G#x!Lp01)-sAps8eE zKKSVK%~&56qxf}Sr`(RdBE#Zx(Ppfe!g*rRK0VbKXRrkMaQMelleING+kB$b!g@E< zhskp3!o`C!>q+#nWmI0ewV3{}&y=bmlXQ)d&}-3wybmQxspeT~0wxO3+^i~E2gkxq z7S4{>Uiv%A^OvsCTg_L#lAyG~Le<w1d1o7q4|cw2&0=v3x%G9(Aj65wa;Hp@-jYcT zJJvOCx<6|oZ8e^De?nj4nND&~_j8ZrknSNH<HDg-Go7s>`2kK|LPjK3At9~JOo4FI zUQ}qb0a_c!yIDxI;63Gn6{mPRo&T9FuZzcCf^D@;{4^i<c9@RGh8F%iV}nw4$db`H z0}x32nY>VRK76A0<Gfw#YFE+Gj>PFm^2-O)$v@rx)^D*zP~oeL?aPf-5@3ivF%E;3 z;yguv!R<$EVWe<}4x3TF$QoAL+?PuanA_i>&<uqcH6px?nNuZ|V$DrZmo!oP2Q^wq z`+Pp3$EnKt9b>WM#?F>=`}r(+5AedFoCAg@YU2svZ7vJPswI%{r6W&=MNb5$m20B+ zESf`2x?oK`*1qs>>~K%J8pU{KRLP+Du$Cp_OYV@W<7I`z+kw49Qz;Dtr+q!Hw6oPl zdqA*e4Y>GkAtT+aRWY}dWtvj3=|_7LM}nns?pRiY#$D-gys@%JT!@2oaa#by1knf? zHs1E}h?CRYRwzV<1ccRJ$I(RQ<kXF?)f_02d@i>h1?oM<O$~`>?lD*GoI7ow6!jSg zS_K}Y#i!IA#|5OlcBpTV8prGk(EVw;U49-vsQgial`I;Svazf<tG_E*F%^)7&yY6V zW*QCK`X8N}%C??5NouXn(II^^Z?cOZklS`0qA!)0`zDpp`-Zu1P+=t$qV<%a40q|_ zWy5vmYS>nOsgmzzwbgOT-PqoK)D@#oWA4MRiu^i`blPQW9OFwu^qF$nzS!EG(2oX0 z4*i;{Gkfe|%}GnmsWh9~%ja`z%y5dIdA0dQF;A(IhG~|-u3c*LP}H!hz6>|{EsO{6 z<m-Em!yVZR2&>^WUC6GV65*3EGKhb6Q_s*YcFo%w&`ZvGXBP?U??dCI<Xfg@U@ZGe z#*`)kR)^fiSB<G$JgK2BUSmJIx69J_{82)}rfK?gFWu2TsnqKt-*K)w81bG#HmD}G zsraQf=X83}mQw6^8vg*DMg!e?*LQte3v|+-#=q?D=G;4M%{*09P-byh0YO@eJ2P@O zM$75ZLr0iKe2okx6b9v=9GL$!?xH*{n!qYif3Zb`#{2R`in_9YkW2P<+OFTQwXn(& znzv#x(!L+rx>%t~QC&f;PuDKOhkyBi_als`KTvnwW2z$i2o)+jlfd8FgZVybGsR!- zIQgtKw^WJUEDN!17Z2THRTC&@Vi2&NZ$n5LsE&K~lgPJrQ;50M-cV0sW1=_p2Dgj0 zJ!Kv37GnF{`5<8IMn_5Ebe~blVDk?{r)?}#10bflxH10fihgOA>#~6}mNQ;@Hz!-Z zA(lA?pBZEPQO*KdBc%knEs;RId$_41gks9+wCMP59I30`{E^#EfscAJcJ*l4RG_|8 z{XcCq7yB?G6N<=c^yb<RAlf12x(Y~Hew?$GX)t(#WLiWtoyhcM9}BMvR%;Eclm2b` zeFt&T?ALsvk=D!EH}u7&4n9&l12QZY4&1n;&L9+CYhYbLj)POlaw@mfQEm<)%bw~0 zS6V_T_ShZC&e*UR86GE{oLib17%=1iPH4BY>HD>nwzL)1p>>WGTy~Xhc*eQlI!u~S zCNfij>wgl*w05Sk@AU~kI?Qfbn$w(FLzr{L1E`YGCyg;xu$PnNA}sZc;vSJD4$8rY z6NbjOHb#jP>Flf!$C+B1_GtlGo|jhA!5ve?$^og{(;syQwFnyaIRDLK6a>#P^mOjm zKaJ-CALR|QWAOFCM5EGZv)bB}obDq5gJA0sdk)O&hM}j8HHU_p<y8sdIKaQ<^dLj3 zcD#gsYo|(!eZkPt_Z1nP`PoY_`)V|1)hq?8tfGHjg%m`gr3m9iZyq6cVpyy-CCX>b zQxQ&)TsJ}gY74*&<6>U0g;A}4(}zW?Ab)5-IjOaSwv*(!gj((dTf^F}JdCvryPjsM zx8D{Z$|fL1`P>avsQRAQcs!gIuT1^L9@3Us@>gY){g@YC)Xp|a&Hw56>o0}O(3|e) zt09^4nkkxGc?s%V)uQ=Ok?jv3LzX+=|B$k#X3a6z_NG;)UK{Olmw4>s%Et|@SziDb zs1db&W?#_cq}W_B*R?PF*nHzmF)8^Qqqu9NaPhK&bJgtQp>Fc|M6$sMn)y5o#2SM= zOya1o$$rtUBsVLe7R;-J#uo?>8d~dyq73qoL9oWCH+|6Z_JbE1sq-511HPWyzSXn0 zFs4naMFI}Yk7n`DkPGXNsN-|G{JO4f@f#Ux*IfPibu~IC3{jRBgZ0n!S#b6zH9WCM z#{QA>=F#^)86CN~%f-#rX#N#5lW)p4eZ#BergvcZg@*g~&5gBhc49<3vV(VyH%$dn zE<m8CWVYlHqGDY4t`%Ttd)OR{&6cRED$iFN?j0{e9MJS6jzB|=!qmzm!smK%g(0yl zo#MEm>JG7Ho#P)e0&JdR2030R^IZEawQ}062gU}edoFuZWy2(&#K@isNV!8EO(0+T z5+t{$BrkSK-4bndkL!y%SK2@6JIp6OZ1JdH5h<hccX@BRF0Gw^)4BmORVpO@qGq&Y z-C`+Oncq0#P0VYm5Fcax&M58^S(4ek?;=y|b7pqOPlamDkPdPphFo|vg%q8}rR;BM zTg*zB$fVaH=VRX?JOKeKrKLTK+#bES+7vr>g*|;<Xm-FCwO!XR`^dB81>MQM5i^2W zugWELH6wg%y0wA3l;P>7@0nn+I9e{@L&=Xynbc+G7mitluH%QYnZZ?hXJ<3Pf8<+( ziIw9|@!mNW&!p%O4bQ?5#>Yx!8Pa%@8&^F^riCZl04cz~o?q4}bU@j`28$ej6=^=z zx7S!S?6~()-+Y`*M<bhGd~n#jQH$`=Wj682V36s~8}7Kd(qw8XG~@$f<XsQKNbkP7 zPAq974eeOf?jF*?qgo1cp!7aie4XmzuH1b<XUy<jYBp|UvedNvMmO`q3}#{|dk2;O zS-9tYVOSMRIsRQoZi$kHSyo|wMY>Z?JVQW~*{rtOr)T!m<pGY|G)yS>`H!V}Ol!Jy zgoe!dlulM3%U?8eQ(Q$jeq3_xu6S)2zCMy@q!n#OT{Ar*YOjCx&{(g6;=3kZ+bFp% zQ7<yFQEF9aIXWi;vG;)%lBH`B@3rr5zrr!7XN>VdIZJDe7!aB$Vfg2^<Fno3VBP>@ z=>%~+m08pAa+@dX^v>Y-u@PBj5QsaQk+IFefj+8j5gp_i(2~a7^Q{d*YIRv;m7z=C zmbxdv1~YGbOcJ4^em<o}!YqWAmO4-sR+v4sZP*JFh37bY^1aJx$dkjkF}BAP{D9G0 zCrR_Lx$SlL&fHf%q2ni!9zzbi)fBgJEy!GnTCI}Wp&s|ZyGa}NdF9RE+IGaJzM{K! zPB?|x-J3kw5!Z+Ht$QB(3vHgTm?^|B4f_~}ReuXDZHnSkw>Mjli)UmadCbRgq-$x+ z5W;uwv9C~p7m`lYJ_n~Y>J!yIs|v}n$TYDwq#vD3c%tehH`A!8L#z3cVHJLPQF!h9 zW782^imP>igA$}N4<bSJ&)9Z#X2iXs^S?JXV|9bK+!4r3Xv1YrpNV*&UUgaiAVRSp zT8(Zh)@A16=W{%oqMO(M@zCD-cR28yG5dPoNGJjWRm`&;TO<jMqiA$%d0vVJ#f%U5 zO0?)8Q4Ad?fG;j`Tz%sEYW=Y7-?2n}xK~k#m;;96tWB7OH?xby{WIOM>ONhek-n`= z{5L+V7~Q;GH9v-H)4X7~#9_#z@O$7aD&JRqh~pv|io?e>tUhMW<tZ72*~*GYWT+b( zZLIC^rw3}bxiW&0OG0t+V>{Y_)my6bg^K&k3rsl!>#^8>+ETDXJgvXIWu5^?P4bo7 z>aZSP^{O0c47g7oj`2YL$DL@H@?zNXm{C5xDZQL(iTK;qHPg+fL#?vUSTxm4;<3<L zH18%6@w)F^X9+n@J{~H%gspZJ6lmZIV;|rlpNc4vwQU)1_u~Ay;$9q6VtEDhucEH# zVzvWMW;v5E`v)!oF_z%c-5|r+6F%QhMWX9Y=#SdyL@Sus2lj@$DuoN%%<bz}xLtk` zM5i6Fj8-owq)fHw=Zb@sbjF?M#5L%GAHs+uC19h@(F6=p`+Ie$TxZ|mjp391ZTJ*_ zeKCM(%!Vx`P`1mt46sP^ku(;8k3w}9*$0RTDde7#-+eL&wbZCh-OlLg$Ox)*ouG-o zPUk~4C9Y#&$-smgJvH-?+d3-WI`-mSUp`xbco=llr4@?xznGQL8}v<4LBJNFQoKBf z3q#)|$d1yCI5Ik)r6jZJk$lMbn&#mW$))i2!E;+eVI)Ga^q?9x>_2z$2(=Rv9&E4S z?9FN>HJ;4>`Ub!UD+MdT96(N;`A(BB4CG*9?~Txdn)Q?z6ScCikIp7|csPTxN>H#; z*RD9@sjJZ)*7~f&1MwEH2G$gx*pliY&(yH}U5Y%qN!|FD>t|RjM2azZEe_Ma?^$YJ z!0>#wYU~&~A~~LQW6|cGg2b@?B+HhDMMQQB!h-?UGG}P4Ga7tR#!?qxybxTzAn#RY zf!ho<7U?S}choW72qESk?)f{o&0*(L)-^>m;vQp4Y9sN|23<rWIgWbgJ`-L+6XXTF z7!v4!E?Mh#tbN9T8S+K+b5?&A)U_<?(w8J9$(2+V=aQrRXuLJ%xUv_j;&Rr{W|Y(N zT}m?mEYiJd=I0r?u7B|uwmqpSCG?XIKq9#&dj=EE$u$Gj$^-@wNG5-&IrEEpV3i}U z&>alD@rrmG?vY>)=d!BTxb~X-R{<2^Of7`0+;iE}0tS~x;u8v(O={xx^Ez@zu9cQr z%N)aanMd+%o7DrKB=16ED~9^skEuvneq5{y+ui=WmChc~ftkHg)j+M|qgs8u$COiv zviKbAp^;OZX<I1sUK}apu*hPjG|FTZnau!EG5$sNV*g4?){<FX+4J+X+8;NPOQ-7i z1e}hBQM$gKP;vkH9yM>L^lLB^6A8}%36$K{X!%wi_T>uGSpc-?$oBcm{xHqj=@(m> zx%lef^BfOrWF54R(_l(p*VV+co~qp}mJm9mnwtaGkP}$l=pb4=Kg|k9j=xmp7#Hnm z=(A?dNf9MukCcHVG#o!dsq>rS!yg5dRLA^=6CcqUNzLQn3g}Ml$uhcguLE{(IPSzr zfAYwt$j`TG_cQ+av<doPy0^~KUX)FIyf&c6l3yHWY(e-KH_v$HLP36f#GlT1a$YG# z8R(29)--d9xi9j2o_-kabi8!(ls_*zwyt<AFvBpU@1eeWB1J*qf;3v;KN4jq@W(mu zq`Z!1k^26#l&O#}d&LlU$Mb*OQ3@L}1T5scBYX<Mr4FzMi0!p*%$j<h{r#F~x?P<M z;$~)*>7B-Pj&F^N0mYirr2%y=#x4VSxqm{lDP+()kz)0T5NGy!9-JNO&30YgENw^C z2$Dnk`c`3fP~6c-zk(-M@%`pc%<1JPWdYKw8Y|J$q0@}f_OWaB9fZ)_;g|AHUX~6x zt%RMOT#W1d3DUZjj2{b6_s+NXU+#a#D-qKeJ0i{eFl@28wJDWRWBt|q8_{8ZTEW?) z4BMDmw@>eQw#2Z3ORl9tZdMh_UuvHiuJuiHRF2)Bw1(;xKTKeDc1gqL+8BPWHf5oB zZiNaKw{$p+ksGeRrf%XrLht|2xQ)6q0$y}|J4{kM7xTVJU84@0T&^)99MPl3Rp_4% z&+)APMWl_C6rpX?3elL)vSm^(4p$YVtNx`{{9@ZOeX05{-SIpOHTLgA7XN*mJ26f( zJ4T7aE@ymx8EW(5<4T!mp<miWqhj&*&qCRNr|99s<V?IyV)>?Q0LydPpR#X@CaE?( zXHU^V)MvTMJxde<Q1JHHhrMhw3*GELNI54JUocH*m^oSJcKPJ_g(M|auiVoU0Jzh$ z2~WRzWKSH`z}2SX_kh)te(QY=nJ=g@Kc9)yHM!TiXdOQ=?b3lQI4?is!~NY5{+nWm zQ674ky5$~$%xtW`6#pW}AG@}(DW17<?i2?}jXmi9+j#9+V2$+Xl8=Hin*?$vOdz?m zeCPPb_p#xU>sLTYMY%cK25~eg3+P%O_bukMhmmqKUy|_uqB89sXHt%aw?3iQ@&4;x zWtjn(3wG3IHF#}Y1uR%di|;=y>(v_#vLcRnJTcy=ty|A|=5s3>Q|QlWP`C+B_x=zl z!K=Sl+h5P~TK0UwwlJ^qXZ&#Q$18&oixmad?wL(bP1eyf;^ixFC2Cl?&(`4rG(fnh zi{Jl+;X;Q)4O6$^!I7fbWZ%J?^rV`yyjZ@ahQIm0hI6pNJcC@U%`yeDjLNU5GOf@n z=9Dybq4;R)9`C>DJ!U$I@JF#)ts$!*To=u91shfIb_j3EfVpBkOK4Z(1E==|u?P?Q z@)EBxnCbK4Dq2?UfV!reFCr`NbYSZGmjd)t6YCaC_wYQvl6Oit2ZP@D*Na)L4IO@Q z4gn~)$-~o;QKEU5C#;`U5%N;cQ%O*mTeWbop~}ZVw`IzOP#FOAa&nY#LJy5Y0$<$a z%mQOS3e0>!M`rua+H>%$4cj}#<Pl$=XT!p_TGTnIR}^7p^FIyc0BfEgyvDv+k~fIY z$?#LmUaA^dIQkwbqhn#Fz}m|h-&e01T|!g5?9$?o@x`nW^gD*?Po&mb`A3Bgw%jF3 zWM3X9J*uANNJqear)l!}^X%Qms^$=vaho+AVjKwfF>jc$*t+5PGuv7^C$3UrA#*wW z$Y{9RXPA)NqGOA)O%Cf=jjU7X-l-87<Cc*uj`F@oLt$5ulFh#W5qHr~lvL`ejZ=o_ zX2%>g7H@>@>2HFCto;%g2iU*pDs==Z1KbSrh7iKoY=lgH?zfR5-;b-6E5t8iBdcI# z=U?JPc<PTG@2h*34l)o*W1Y|VbK>*kqc5R(t!EVV+n783`-T$IM#IKhDahIK!#-5y z^qOugp@E$6RTX(nYrtTIZN7Up_IQg_G#_m?Jl$uQdw5jXdYYaLmr`$vFR>KLsh(se zHbU!ecO2X(SYSImcQtXHK78o3<-Y-NBsRvIhi5Y$Y5D0T85(QR-OFYvQYGR8rDF%R zk{cuppMN>2tHJw`>rMeuT?)nfbJ)GOyHWJvp9V`AajBW!GnTVAyJc!tJ{?s|D|EXR z5na?{oIdWKZ0_X;TP2Vp9K0jO{a@^e=5D;vqqJK=x+m9ltZ8sWh<8op8%;YuJg3gC zJ;7?U+xC?WsBDq{Na-EeXF;-$zQWW|huPY-IZQh386$(mm#lh<Rr+xY==dj>?gOLz zTP_Zq-Kvx6RB3bWgq*&r_{yjg<oA0<#F`xuSc9^`%9_u@(F0!poMF|eqwH6+@vD&U zjm%*l-kziKy+nX1Hj_$E#^OdNnud_q&`CV^cg&6To8|_tFHBU&8>k8zY@WrBQW^Zi zv-tH;yr{S;!3|}YsIH6Lf3kkMgjv9d1=4NV<NXW#qWQ|xRPA4|e1l5F^KRB6UJsvU zWnvMkNp)_Kowu?c#Wx+5wb$>Je9?4oHr$wstt`p39@_WvLzciMf3w8q4wf`;XFl5J zlQD68IR+<#KtbU|AVvaOsQNvgw+C2@<&E+m@>f82pUe#WIscSRDB|sBEb|5I!foek zZe0-&5~O@f|C2p`%Wcef<^D-Tb^L{u6AfexcwOj!U#FsAN%O&cJ^VRLGR4H?f3*Mx zL{KW-384@L>JxdrR?xy>2jpa1NR)rRG$J0Ebj>EW=}AfshE<V!q+;&Zpy)8d;)X!4 z<NNiipu-2dc7JaC%GfS=m7~Z>cG@DhZ;#2rfLPUUQ8Wmn27N7cmAm%m9#3sUAWr^I z6KTC$dGmh<uR?YH?<@bGivs@lJV@bVGx&c8Z|^Bv0u>McY5(5ID*ONcGa5_3{*3r- zO~EE54LY_QO$DzB4FbCKlhpyPDEp^xuj4WOj4|=d(}s5N=Wl)s#y7}${Xg9Xe*Z3d z_&*2#@8e6d(HpfI{>S!M69x$r!b=VPb%w_5=3(adHuP?fF{&j*a%NyIb1|1W7z=|@ z0llNB6Y&hr=39SW|Mo&G()udsu84GaXAH+OLej^imotTEN+WrH|LDv-7>FBwx1gW| zpgUE9V|8mE8EZZALQTP7yNJ$0#pPFGem6T9|8tkpYootF|8l>AuZ49Y+0_1XQZIh8 zLIsvrxakOEHy9no_{NWio8!_AP6-rxp4T5zt2+nGU6#D&Rp<#b6bR?i4Tuh?Z@rw? zfvpv867-JXoYpJ60Zx<mYfO`H+%QrNW-c2Os55F&u-VkU)^l?>3w9)gIg^BuiZOEq z7*>?5B{p}sS-kWW`x<Y@yO*Qr3)DA`xhzcW*%PT!-O+YqXUyg>?8p>GD!|NTVhE?z zCm|T$C=8U>Zt@olb7ll<7+czT3?l_&0t{j4hGjcWQ3gM-b~fyUD$jyVz39R_b`rkl zW?wN{{e~ARoZh@?w=W+))HK-qW`a3WhnX!9QT3dcWqs)dn@q4HB_$#t!?(LPad*#= zud3JlvIut&Fwc9qzX9<iO8`g@(@z^i1{M{tMhsGnGDCw;pTV8tLq8@>UXP-CE2?({ zqB+eBWlKvUJ%Fa>W1d6I>tyKf_!}su#U<hH&>*8jvFb33SMXXMiF%vKlS<U&BkH3K zGVnpacD@yyDUp&Wt+ad%EGm9{bQ_wWnPgrA+%@0N%08(l@i2dLckZQ)SNFhz@%f|l zxm*ly(qwSh3g<m=I$aDGZO?~?fyZ}Zw6z~;!7eov=bYgB5=F2Ahjoq}vGVc|a4AC! zfNkWGCwW;XqQW}^-;>l&krwH<j~<mhHz860<92&?FQzG0rLb3gI8XaiRcEi}ePf+? zOrx@5b5)a;Uq~qv#4KO}I~bFGCj<1>vRcD3X1vJ4OiZ}Br&qh@!ceR}nV#(Hzh35s zcgVv7xWE>SF)2#RgWv;In#sOElgELMyVMO|*K5IUF$3OTqkAe+n0y6kVw%(@m-{c6 z+ucvoLQRFi8QKr%KfZ5{vu^n1H=z9{2Qwg2nR(;AM0jVtqD@xl`>V<6VJdv|z8^xd zBBq*3%YV@z)1vR`PJXss%J{V*ZT^Yow2{ewmSq~JJyGG8`IFytfOE4)Zm8)jf~lAE zQqhYx##(WCqjAQ*vGLSQwQ6AwZv^@JeQs%w8hoHmgDeQy$jVsFN0X##W?*2q@TMm| ziGj8HiqKTU%V?{>CRu%L`lwS062YY5r(<B?!d_AW;kOSUdp5uW7R|Gf3BH<zhI<L_ zhle-ge?k<OuhJN;SqG#&<-Q8~F#9-IDFgNiQ_^J*)8odzF+;zMU<Z9p+qrC#P>0u4 zlWFGP=L0ADQk5DY1+uD6FZw97p9#bpeAr#?-A-=xa;A+j2<=Sl-JY}g8@tk#6#7K~ zJnbhCx5mU)?2XLmu}GPOg&mQqYgf^tfVlCikx?W3f(Ie-`Cs|y^WW=h&A+&HdE4AD zP+>7|rTksyow3B^NgQp@g*9K?elz-K^LioNOQ&y7pT;wVY0+Qa!!$vVmD=_A0Yq@- z2gL`?@G%5D<LQPY?z#xS;8_kjHMMf5_RNlNLb|{AWpoIJV>Flql(jvr$sg5bsC;%M z79Dw~l&`1bY^J-u?mFnzdQN0PIS<#%$K24$-b45j$QKuh@pT(q7IO4mXzJTO^ttlM zu?uUlQC;6!s+*$Ln`dAB0~o~lOfNJ=Uwe7$W`fT>ojn;C%2eKThQs*IeTr~@)Fmro z!%b!ONvhmq3CulYVklcGaPM^ec<)6|Z@^ttt<9v*YuKUaCBc~n>00r%Gm-Qy^a}@Z z(_-^O?T3MsNt2}x+qv~lI1PHs^7ch;ELFY(pQHb`OFvhA`54Er2$!nL6kv*9PqN`O z0eA{xPZEL0guX8iVf0=2$q$h+X2KZ@KRP-_R*2eUOrC&mQ~q?vZQ>R78o$gpE{>yr znMmS;cenZvn$m~l4WaCaU|QqGb1AzyJT_h}VZb-hhv<1HEnj~nq<33_Ara-ajbng& zIrU>R0E;#!wY8D)RdDdg#6(leq!c}yi?LveNqjF-u-VeLU6*VbY7jb6KtTlj(pz{D z-acq8B7!`Kaj4~mwEvgMJmk4@y5DJgiFoC;LPtZG0yW*`a)Tt>FImtz^zg5HV9pmC z4}i)(kFNL4nc95W7%q4XSl}j{QPimevk99!G99ACN&B$hpndv*wRijAOXsBV(*~c7 z1FY-M#U|NDkP4Xi#~r+0lk?81S*p@;IEggzF38LE2To_9UziNP62?&n)v=!RQ7a!< z>AP!uobTWxLVSL?IY~xlt8tQrCdt^z?l+geQQu-@3@$HrK73Yht#_nh?o(6HT9G4U z^!Ot5)Y{#`$nC<;57DScX0{1{C(58(I4<nUPgTx(QH}Klo9j!w5{RyfeIxddhz2Sc zm6=80L_KJH!bO^RQl8N~odWYrBfJG>u1>JnHfEWDUP;fhu2!m>#osM={I9D&rK5#) z#nfO51XIYm8z0_yHPpL_@q5Fve?hPq=1kG0?a+#5vP5y>Snz~IAZwc6NS{ue82bxT zm&#;5Yn}y*@e#=A)KcvYG%6}v|0QKvlJ9s<RzEhYvTmUb8#o@*UHHet==ESWCPRFx zR%zLfsyb6jMG<P~HfN3Me)by#-GxUC%{@<=Ox7+KrTAFUn;R0_p3@*^oSy&MV2l>$ zCUw*LFH(Bw`BOzNN;7|=Pw_q6W%>P{_P|Fj9^9o?_W<pbpGs1iz8U-sBPC7AQh+H` zK!7>VT~M0xG0P(-SKj_g!y4X%oLOJaS-3Uc8m|H#ZaGnqJKlHcrl${+D_icOs+T)g z$!s@e7;G8u6Hkn84opYS>R4TvSOtzF_X;tN=P%Giy?@*lmmB69l*&p&vF3^wx{4** zqg$|}76803G28)E=_?8yEDNu}e0|2h#3+t~nCIiKaMB&ol<!uk>5eX0lPOvD4gq#& zA1b_aRg9uI{9-h4yhxvj@%;y5u48#N^-2k-4Q+@&r4{zzVj>U0YQN55qU`Hl_Y$T8 zke09W#l*~byYY$Xvh^+5ITLCpPL}ld1<lpPDMf12;Y<#mh!itRlP|l)fz5Z#=l4S9 zIxoNn34js}l(MEFv$zr!H~0|YeF5;UQ$Qm=^o;^VrmxZsR?gd{LqGJfvY+On+3n!C z$CVHdk%V=kbzr(Boaw%uNM&G{Cjq72?#uB299<~FKGJt`74+(74xqRCir|WbWJwS$ zP?s?GeE_^;e{p(G%r6X0ibk7R!UG>y60Pt%gIRkyM!5Nvs2_1${FIZLFmHi}f!OJ~ zq8o?uGRG#tH%!E&dwQde-!-rKL}bmM%JAlI;)#Ff1HEj)<bPG6U5e*{Iq%cvVRW1I zL<S@=zOfkdEKIugsDeuIsZ7*u0(y6EcfG>@-zGUd7_UrV(qxQMd=>5RKW+B_>kxB` z`JRhL+;{`q+XW9@K5e54N14i>uYhIqMgwV{-qxRWj=x5RPn`%Zi(3pfT#)zihM|-q zVduifgu(;3X@#S|gVlUfOwtO^rN0d)J5i&&Nuaj<VPzzov0Xq4wLi3C`7yVa=&Ol% zoCNgw?q8U*xSzr9>ve{(`7ew%Fj=uG6{eVm2I(4u5a)fp>iM+5v%Xv9d!~+XZ+P%P zZ{v!Y4Q|eU;Wq=|oYD-2nHgq^53<nQx~7@7nGX8U;;j(z5tzryy1#CkHTE&Z*c}@= zDlW0hLJ`+tvfZWjB%8>P6@M7YvF#0t_m~i(ccfz^*3X&Z7al4zeMyqPEA!-Gk2eYb zFI4Kdw(VlBK9&KP?@6}l4l^l=-@w>6U%e+=umiaQppcEFE~MU(HVsni(8Y1;g(5Tu zgPLw`q-JBJXeOxswf6E-rsx$E2o%bI^aF;aearAu<(alfRU(=l0SBxo-?1p&zsm%& z`4)GWXETK_jC6zMv=;g?7(sF`$Lz+Q>%dxq7S`%Gi~J)Jg`-PKGeApQn6occWO|-A zV5njYRQAjn@Ji{5%lPsY$ji}NW<bT*e8=_A@vZYQkk*Uc2x}L31~FXjtVzpYG<9f| zVz#?rGqL%h{-`}Oewzc~d7N5>1V;5!;-LM0_f}>}C%~vuD|nAS!1oibX5u0`8=<J7 zKnm+ujS1YJADG+Yx@qyx@izL$Kuoj~+9Z>bS{V$>cpGXBqO6Y3hzF!7|9iFXU2;CV zS5d3tj|qMMESy4VnF>X(lQG&Ep~&qa<eGyC=;!2C*lAkpFdls`Z!kZ*RMsBsgPmC- zzSaJefk`~OnBfOo3TE=21v&BU`50N9eh0g~_l}`iB?8Y5j(^Vr9Qf;7RoqTrjpTMS z7+0)`+Y^B>MRS}`gfMJWE39+&VmetwINl)Cr(A1G_ClCooL3*-nWeOxbKz}x++s%V zhtN9`LvCrFk~H96_+L8@K%k`e@VJQ_Y?`*z13_{moGzwEG=LiEWP<fL<pmIi%qQ=c zqn~iHbNJSKT9R`=j(ICdRzxp_FcNl7jv$a!`WQxK%_kHgboo^4HojxkTqMxZ*+&>~ zVE5BYc>oJ28Zb5Q_w8huTdwA*ZnIAx0nOZi0?9H$1iQDWy<qJGWVJ6y9Srv>#RRA; zYBI)zyie>6YpCz%%rqa;^84*lKP?1?$h8JPiyyxazcu?QRTz9Zsuiq+SAM>W2B1w9 zPu;(q&>*|hxYfoJZ}>5<OXMN4sS)?(VSvuM!_s!qzVG?Bre>4R(5mPtl3&9mKEy}< zm#$S)@Uv_ITGtALqF;P{lK1-S?q1Yjv9B7s=37qHfBT;G8^bV9ebw4dYVFYtvS6hx zsfmz~vo(z_PQ9b9v^C1$7jhAe)Jv~0o52_U`!+ANbIq*fW?)tq`Bx{Lg+4rxVS;k4 z5EV%HsknK}&j-4>j)eRU+1<CtURRQ2N=Qegw)oXPHl453*<L-m@`ESJAfA{uwZwEN z08!x(tWO-%qjOC~r~p{4Z(AR>Q`npdSn2UTVBO|7(Fewa5Ccj_y~0BMTYJZHJ%<4Z z%Gkat`Qt_($<O6hbraM1j4-(As066`o}`ZbAzmrxL+~g)9Lv(8i}}eg-(dbPzFPa* zP;UUbwh(^o4nuwJu(V+F6RTH-DMaMfMyT9X+i(R}C|IT8&RnTFNZ-M<#|tqRzrGJz zTtDZg&lfVUJCB_-0hYwmL_xjLpGT;v6NM!*2K`F@?+G-Kl2xc~tWI#D-%_yBuJ?sx zMm@rjArMzppjf47-S2hQ$RCR~Tbw2Ls!I#WLvb3j$?iVTg8n+-v=i66c8Bo3g*w*4 z?3m7Y@e1l`-}XP+KDEz`%m#ynQBjeB85no+WFv@ZWdN%P2e6Pqpu@MA{$uAT{QKQy z&B(|Ync)tD{=y=ug;XU542$u7b{?>tXl1dGX7kBcsQxMk_<%udI@c`@b5S3P74o2S zf-C5}T8=Nzd{%+z6RaId#muc+%aA=!GIFL6fuTYO{(JNA<IVP~b4nRy>-!<H@y+0` z+z`P!Xd#I4DWMhNP}K84FgXW<uom}(GkKW&hjY*#{YXou`XW_dkCec~$ew{IeN?GM zBv@|u%QjHdmF5aEd75}pJ(nETC~wXrsd+Hn^_+d2q4pFoO(i~-I(#>clPasx^mqP4 zi$N>$^Q%>Fao&<OjOe7NIgP`7*q8C9jR`^xO1BX9M|}#j?0n^iv|ijn3r9z8cxZ>6 zW+8=fZchN-%~v<`rby+_5kH+En$P2jB7cPT)&~(QE^cL|K{q>}V#JqpV#nE`+|c&( zN4cw$=EKUPur_l+aQ)f*{N^Ld*a<DG`r~cd`cuKn^A|sWZ4X~9br%cq>iY4NQ!1Kt zR{!1Y@|1f^_Q!P^$#O*|Th|CF<~+WxUPj+U;ygo4z0xuV&FMd(*ydjSY{3J@%Ne$I zF$aFO*q_1WW>SFH@0wDAp-O=GA$|8wOmz!~D*(Tz<Cc$QDm^iFV--dF|J*WIwpoS0 zdGsHF^au)yR*JAM$fnUZL_etsV^n$pKQ<EcOGEF#;q^(AmA%{U%#}_0iX7}bV)frQ z%G4R>9JWN~Q)iWI1ntH(@dN28Xez&%E1;iFbmS2>J$?Q$1UkP=CN`mi2UXlseDr)u zsH-VPC(fmD1?4PI&{+!*O;hWPN)&FAVSK-1oL|CpN5@@5ld~|>1)C{)M*s^Gi<v9L zG#QL)VK!-EZRPwlU|KInFORGI^L|q`fc?e6U_|M|px>}Ok?6^#9w@fGKlm3+R*o^R zD=g6f^tN#U$HIe^6RD)j67jvKJxC0dG8+@`?hSB(k0(!hW|uv~h4sD3#c-sXK7|e3 ziD5czve=4#bqyq9nrpk`lt0P^F6?goFhKF@z%M!UOOLDbEQO*CI&|ijnZ?XjP;;ZP zqIm(v8vYpCwe*#BjvpLN7h@6Lc^TFj0CtNDW#a-vbVn!QHOPbK3f_RVA(C_6OuqVk zHQ3p`M7`)Js;kTz^tLOjml(v4<NBEf;AQVLxyOWet=GMxNDa}L0G^eT2Jrr6B24^H zUF^A{7k$j$W!ps&-34{<bFDDA1>jopB#VH_wSWU=Hv1$t)L&aMVB1VPO$f|;M<<ek zj2<Ua>7L2pr<N!Y(HYX>o`NyAf;Xkf)X&hl(8pLLO^zjQ0P#m@*GVn-fQ9C?^^MYt zdOh(Gj@!jcjlAFibT4s=YYjbls_=ac1bU<b^Ja+QQd)k)slZGB$$zT%!liQ&=|_V^ z_T!|P&N(Fb!6}N%8s_%vKIx0Q<em|~L+gt2-z;ZNj+ep>kp1ry6TNfx@JnlW)6v+K z*GXuUthqL~Nh3x7QFDa$&p_J!IcBl?NB=oTof|=#&${lIcs2!SOf*A`3w9w}@?HRr z^Y{dKDd{=PTYL29%Ip#Npb6|&$K>|jxi+1ix(sun2a~`!j6LZOeORdhXIwn^4nBBD z^IcW(0t^nkZA~B6`HV(#q!+4;1(cQ**lu?1DUAB2wO{@wQSWH2e4nqRfW;Svs==h? zVVZPC>-9W?<kqnkFlx5d!%v}W5wN4Ny8Z1fR>ZwDZ~Q>Ll;QJ%<<|1w(c~CrAv|YI z?lDaV=Ik|&gX_fKLfPsTa)0Kh=Tb8Nei3GPExNBkQPInH(=r5tuuQBkp>V~D%R-DE zH`;ZLvgKgb-aDJ?9a+GRz5yz+u?uWjq18LOHzza&_{y<~xK-2A)+0R_YSZT965z*b z(P;hDgE4#fym)1xXk}2JBe45yxHruao`;^q)zx|f?0%T@`cK^j+mz7rYOUudpgj4z zd{yP|C}325YthH$D$U=dLqa=up*+3DG`C2Cfj@fBN^0scA6WD$Sd7Obl$M)Y4ew=a zy_H3&e*u=Pj2O{}Zkm;wsspcw6LuD49B1#S^o}{Uav405T=aRyrk46df3%4yrinJ@ zd01y<1GtUYyWPywJmq8-zIMj|hq*JbrfmHTfX3egfmo|CtW>IwzQd%H8NfXpGA<s= z@%Qx!)LoF(=spw<-~)$KZVG@vu`_G3oDZP4f6=<^A4Ghdy=~1ebW}2B4hGBJ`v>4A z<N>nZH@7R%390AVno^ZF+6(Q>+oKh(nm|UPN!WpxZBb#D3c93JhmtMIKxTXB*T6?# z*C`ZY18Hud+yezi93(1lU5nRr>+-oh)<G^(c#}H8T{aEk3{HcIW1n0=XeI#=;Q*Io z{kLUMnJuCN9~j<QEWUJt1|Jw-O4HwMGEs!;ajBCs`+TBGShWsZQ^}W%U>1w}($4UC zwr>;a<B?CIEX3f2o0u<E=X9LUg+JDM78`uHX)TDA`xwY*%z~agO5Fy0N-P@FI8*<e zg0L7J-l?*F&A8?~p>8ch+8Rbh*j_^ha{<HsM_IySJ!iS6=13@brOZ%%5KePiJ`SQF z<Fz=#wOVwVWn#3}EA`6fEI0z5Dw?krXYvEVal_GA1Nh*jnDkt)rbH!K#$;3Id10xT z3{~pdtO#YSjf~tgMfljqwe>a}Z*r)e3v#dPXIn4;!!v6s*In(oqOuPCU(P;xT!{o? z3hLlD3p3Q#N(}~zjX-5UVRd4|I9%rW#_5Xfq7kg6+S^pIgf7PW_G|y#4P~~DVRvWa z$CcD6lU8E&GriA#%yRZ^gK3a;p^kg{uK+Ebo<D^IQZ|$-kty9jAHfYr^Ew0dTVH{+ zO#^*{BWocsv-lk=$##;f*Aea`=?J$=o}_31txz{&v<1$w0jdn}V{<WpC<Lf!3q!y* z?uZ*41zgIsSb%wI@sK%ko(b#E4HH6fAMM2IOI9(NJ_!Iw4CFqw9`(^5eE<b*&xdx# zgK5pVsh53}oLXIteM@2!6vkh}j|=zSnJa4U>oco4d??L36HHSeI1nQ`Q+kVbs|#@+ z0#PeJd>SkIJtun~hj#+}ixP@G1He*qF>{!8x`0c;EiLGLBbx#UB(lyY_-vrnyhdp2 zmy!u{2J1h}aIXaP?58jDy~6n2xXdZ*ftRCs>bY?ln2?hmoF9ex+rYn%35Z9917!4V z?r%au&&y(cj&TM)Oy-vVo@XgU{9_qKihI(pI*^*Zf+zXDd53Wxmw$6ZKWLwgT(X5C zF&1|8`SpRm+YjP-y>8gj3<6(Es_geXWrUOgkaIHAn~R|TF)RQ6nNzC}5L0{5Gg=Ob zRdS*yEe?){d&kc1(!|(lR`^K%kSi6fl&*w}R=S)<wEcRUVB)8t%-edru?QHUf@)fU zR=g+;GRS*@fjs=;)5H0n?XLR1yWB!4lj#j_t&RI0zUB$yS(2nYJAc<&6>@p3c-g2= zNWNC0$JUdeAKt_tx+G(Xt?c!@26}r#(VEC^{7@?DKvmg*CK3dYAV5}7W<7agK6Zy} z-}1sJw`^f3Zbe%tEePjHI{+|4&#lqtgB0Nb9S?n;TDyKxf~9kTrG2OdO}d38x*pLE zz-#i*_HMK>E@y%e{Ji;dwzWE8>+hn^{+WrMnr8>LOixMpZ)YsQJkv#`GckeetcB}a zYytn7u&W&OoV^!gFBl<%3cY8vcyn|G8>Y=<Z8ce_s9_cMSa*{jhSL_R>V0wgcn) z9@A(J^H%l0q~zq{KhYAK9#P4^p=E8)jK;LOo=>H!_k<K~0%@O)R>H8}(GHk)=rH67 zkYimwdw+R%H;<EoFo;FNJafIhIc7L}<N(5pQjk32tq__N65d&9?Yf@|^n`f2#(sab z0eVab*yjW|^uQ!cfLyZT^6AB}Tu0-jzxxl4C;KPKB2fKjaG64f^|a0JbE$1t0d!=` zQuol@l*?5ROidju4|a>i1Sr4^3N{CnxU;u9LOTr<mt`YA_?JCm80gf$ALTL-w)8x_ zlML*Zg$dAr$rWHM7-A4g%kxS$)o8O`09yWSvR-GZ2;C@-Fu!X|!faB&JVQ>N0ds=O z!>pb8yz@gcd00};Awtc6i_;C!15#K<foZ910t?V)&@L~O!KFI80`J1^L{t6!faxEI z0^Yv87w2RvWmDoc^WL6!26QAs2M!)+thXZ;?zFq>x}Gc00GchsxwI5FD+tag!^gsp zC$G22geHgE*%Z=t5LR0EwUoHARlar6q(inqSBAP0;>2Q3&wSrQ0B^?uxgPm62&GU+ zBR4q3nxYW_IHAgO+3+*(#L&(zMF<egQ=Zk8y#|ow2H=uDe4MgSv~imIHSp97b4E)e z*~K(3^FoZMV_;%iH&Q2I`~5~Q;L6~0>!F&ae?8cT>4_vV55T<|L%(Qc=Q{95DX2w> zO;c??MR2E80+d+`#}9_3CjmQ}xho=RlO`!tECB!3(YvcNnx(kx$SLiC(OQjpD66kR zpT?RP(K-F$+q4xRx~{|QvQFY?VD%+YO^hhtEkitcJD`II{^V+61IO(+zkY}=*j%!n zrTWVbZ8Z3FDTt5$+wLN@w9=xP(0MT3*Ux-uK|2(T+-Y0)qUwWuoGs!3Z&V*<4FVZk z!82%k{b7<hvw8ok1(2OKVF@M|4rw<&zK~bc5AP&zXCMPSlSZjAWAK#J8j>n?DOL{S z;Nu#Y!9=eF*;mk*8di{xMK=@@<=bs4fyCl2RJd!m5y9kJs~0<%dhxPiJ=mtqeH$lg z&9)%#-EMxd`|=K?)m^sL)%(uC4lr-iZ5KRIS3s}PXfsyMrkAjm`dIsnBN|s~5QwMH zoPn`njv`!Gta9{06Xc+g5Lg9J8b7I<e&?vcE|DJLn2X-ti#+0wcAIkG>zcsK1(+&w z+y?_lgdhwA+2??vimj&j$0D?|5nQ1ahD?t$ygj-k>5~~+#FfVSoXz{j{!Amk>-o=# z`Bp$t%;0cBL?@|L`fOH~6&JhZ@=a1aj^I4QS6eb)c65m%Oq%3srcRu8ULoSRq@9~) z-{Y=;Vl7I^BW@E0F4Zo+V(NY7i8VkkE7u~UiarZj=lFNmQ%b8V&Vj-7j2VouSzX1( z)eR9!H@Ti(9zTs8Z9cz`p)xhCScs-z$mTxV`|>j3zyGhEu{C+obpW_m1+cN2(4Dv_ z@Y;4Il<x-nH#r(gkiu)#XfH|3JwKCfmw|8wE3=rBo#_kYn+VGm?p#bp=|-uq{2-^& z^0#|@e6%<#$dd^Q8{L9UckAM4XCO{&xV8Iloe1OJ5@1fWildZdylql``;}JLj?lH^ z_;BmVp}Mm>m$6TN|6d6ZsCXULlet5e?m7UZWa?X8Bu>|M>6oq^oJM?uM0ASzw^#NF z7XRxu^surAb|mV8mf!(jCX`3#wOw4qp_#idSVbA!?yP-)ge_UCyT$|8FY#$%OSgY3 z!kvyE`19YN`Ko|9qaI}G-To(`VIQ{{J_abDNWL%3uxgID5$MtFQhAQw1SZv+Cm@16 zab4hUeEz1Uc?9u$<4h?d#0(0xDZhLDb%Tmx|DkJBBg>`Ef1|uw;)G>B=Rk(|zb^pp ztLA|qIE}SjJZgAI%ys7O;&;?{S3&A_yfr{ef>`hmEn?d0{*j%(EbSq$izBN8f0UrF zi&1lLiInJ)TuW;>N*ta?)os^omC&tHZUM$R571N~4}44)!-Uy9hS%uSVDCt3E2b?m z7rW#N65d>@a~4yp&<rJo`fL6_WW9A*)8G3)K1IL;M~ajV1w=wx8f3IIqq`-QZd6nT z2#Dn9k{A-wIRsQ{bmyc-Gs(fI?-PA}-oHP7=eoEqE*+=OeIEDYew=&Is2#Il7KlP0 zU_Tsh&jS%6waxRNsBmxR>I?s`?jxcJvedv+<Zwqi(AM7K3z9aXgB)tD02VQYrc?BA zK-|$A3A$bd>R*1imsJGoMlMs|CzD%bhIvZO`$oKdO7`BdGzIV}>$aIyer!jjr%Q1_ zYRLQ<RKk4JRQjmrMe1F|m7u0fJ<5hb(nGHpnr&~|7y=Xj@I0k_lIQkB(oL`FpoYPP zTM}#F<L*5PRvI8N#|J%Ni*xVEq{*&lpKFfb!xin1wk?<yI!~5@2A`jADi3b_R`H!k zIL=n(Gp&v<8#b$zd#2|RT#EEnIfEE9G=zGEHN~k;iY(U%*c~3_GqJU^VXqO}@AhmA z1(xGxhONZ`*vks`rQB|eY<x-+{OBw$6|*q^ieYe9DGa03J%P+!wiag_;(sAx68nlF zz*cdH4+M(juV_{+;olSkz_G;;K=Nr2ouol_o`8=WGay+{R+h7>odYhxB<>whY=@eV z^G^0Jb{~mHE1evSQgjCxLkVBX3V3Y~9x{JAy9L<^0AGVeJ?lnc{Ph$cqd7%%?{M%{ z{F(RGf$`w?<i&+KY1%XP_D+DX-J7Q_y2|1TW0C!>c<mqV%Wm^N>w;E5u);&?AA4mu z659&lZ%~1maX`#=F6Y#)%Pqz~iZ~4!tG)GJ$!y&P{$`f9!clxvxE0-cM-;R4$)#x3 zCxL4n5Z0(98!z8;d=#bBckPG!@x_h=%9Dvbq>ZM}BR2$+2?AjY@6c{KuFH6z+-2*f z&;<!4Je9}We6)LaY3NsXwScYHgBJkM`&(XnNId5J%*C^f`@_B3g+5+8ko_ma`VfZP zdITwwvqr)LTG5g^mB&cJ!4sMiZ$|&;D>Cn)Km{ZdR8jvp!aJ6w6fp=%wVn45bLLcL zRl0`w>IZ?L-eLbQZOdzm13eT@O0eQ__m2?7DJvRxj`}owQHP0oL)O2}tbFT#)&X4{ z3~#9&He!*8CxW{)*ewLQo!$~ooL##mJX_gwK6W-oV$f_cHrUNvb}m`Ia4_{M^^!S- zV^f(Tta-N8p$8rH!lLQ#$joaumi_$$e>S0drI_XYWNO~O&5l(U`*NV$7jTY<$4VW4 zCGV0U-RgTq@>=ODJy(Qj{~yAz<H^5y@!;@l*Vt$598T^A7_q&yQGNlyy$N=`QS{|M z&6vO(4cNC9&S3n?WZ<OcB^3y8On`pa&#ov|c@_VwWoB0!?E4PRP>K{wnV69?(j75@ zF3OoA_T8eW{Z_+6q7#g~rdfoqXbZc3mJph)+drT38aELtvh8igO9Us#mN;2iUjs=u zXBP_mt?-Vm88`+&B(l&&POz^^SgrobZfI*ZPpn_RN>=8|7Goamhu=|Y2i%OxK)=8L zLA3Jz+i<cQ3jnUeor%LtN{|g-<P;7iPq-mDrWzha@Kl9)V2B}67aA_0nA^X1Sq2Qg zlpBD7`VCipLU!cAzG+C)`w(GxhY6GLaaac!Qr-l2BI61NY--RX;E#(bNvu>)odq0^ za!GDROC_jkd)o^D!<uR6IX9}Vk!q&{v3?u95uvkx<otCEjT-soHz0=eOJkl2^=7$k z;XgB}E4At+PF`W5YBdA(+ad#O?!|@MBnbHaV}MCE%|nKUbsR$%-$Qn+Gv>2hmd_^8 zL9G_DrPHU0%}z5rWHqK!e(dv8M4;ztGxi31ku;+(D#HP&3=~zqitcCY5SWBCG>R%l zHoz(SUZnuxE5bxQ7w|1Q^XQ4Wm65<4041dL#yiQ*OR~+A$M^l6Z%r(bGIOnaPv;DL z+VbqnSh}Vc6u5rAy?F`5n(snIlcqHJ@6SNV-%h=zoK5=TC>&GkePcJiZMV!-xlCDj zPkf!&Z-`z0=t>THB2s0lZ*BX(Oh#N!AB<kU3VL1Nr6c*baZu8pj;9zbFbx?b4=dFj z5!3OEMWQ57I3z(C7FdNuz19JmV-0cf0En}T(m&Std-*c34MX|Ya=NuzPXW&EI(Q-z zd7LsKAH@wEKx+V1ups>s;qRgx&xfU-Z?PGT`kEw0bp@GB|Np0))VdK4Oc|hFYY*$7 zJ(W;me^4(AEx8?&Z{rjg21nDxtU}xxd2V>{?AD%3x*ZrWb4r{8C-cE_s{g_0xq2{u zwS20iL3fe~WbU@^YoTdB&jl&{yJhDf6kC#F5gm_gz0{mgdLOnAp^JX}$F{Dr64N^S zSwX39H}jt(_%>gu`|e!2C9fR2zLxL2pJFkK2iO(>oL+2+hs|fJebzu^2e00hMg+?2 zD_l#5>^v&H>RSVU$Gv<ugx=B{>3NYQT;W=@76~aYg)=Bvfa{&xH)~=;$flbQbeZ?z zr#1wpr5h0da5YoE5n(?sQ6?|@Fpm8XsifZr<FkeC4-#rXFnIG?C^Ktw{RW$A<sg7D zMk0N0Wc}fuhuI!{`RrJ$1F$F5KxPvViJ|)S2;i__UIB;Y{C3P(1aM2$DMC@r0LGI7 z7~TemGvXrfbfJy9AwfjT=f=Di)G^l%sdP8Jdv-zY=1<}3yW8M*F4pt=Yrk)#$Aj02 zffO+(?j)p4ZPr71J#IbBE~#bh{~yi_-4HbK8V@?Yw)>uY^I11LNIG~`$ztHb^Sm7s z+c?_WJ&*YI^>0k8IYUawyJ~DwB&Icc76|EiC+Z7(XbaKHa$d9tA{n(hIfagJ<6L+9 zB%bcwVXeXV)}#hZKB~e${a7`uMC%87?e%<Bvr)^@uI#<bO3>U83Xk!`m$m=hfaWhZ zvG<#s=9xAYGw`oAF1VR>m<71Xi)0G${6DJ;t4`T0TSNnB9T?khL)?8#{yY=Ie1@?5 zzt1WOdkjy~IoZ;X{0=g|?E-5GUK=)z7x{Z?`@fk*0JQneN%>=~5fiz^(niRJDA}bC zom&lCC(?RuO2X4Vv8nD`6GqK}$3|)ir}!!F)&L7M1SEaF3bW8GsH)(p^15glBpuzP z4o$xg;fHy4Uif@cfKiElA!7*03y>G2yq#Yun>V}zLU!+iQh|W6Ejmj><HtA@^yDdk zETP3|m-3M0k<@#tQ<X1v%M|`fW6h-z6Jt7_P^cs~#5Eb1*Ir=uGiYN*zDbBG!qjPE zyy1#Ith(T9<ZY!w6;%xW7oM))NbtDc3IFh<2y&4xE3Yp-Y-xZ#2eNY`<Dluhq(S7b ztorpE8{3TAF*RWwtfl(L*THo7>qRZbt};~AR5Q%!kv$vT44yz`bbH9M6&8qF%K7Od zn1r~aJZwe=CL5aXdhp!P{`#5O%nc4LPRbazBafj<6ED`NzY{^!gYKn{0ra;IP4C4C z1}Z>J&21k)od=A5`3kTWw$(B)%)Dx&Y;h{C$U&3Rb-OiN#J2j?Aj6wW*0#YEF;CvN zHXh5GRsF5(`P=0gW_ZT{(yt88@CX7>5wa(zN-J8yUl6C|<ZprObNvOTkp_Fxl&-KD z6{zGL$NAH6C?!sD_=i7}D!{T|tV{}eLm6E6SrPCc+OqB5%K@#!_KzWM31j1(6v;k3 zPbySGm%jgP?{%jFOt`92+tyYhu<rso==Je~1-6;Qk$3Bfr`w4nH)oH9y7t#yS5r>M zz3~z@lL9;K7k~L0mCFD~E&5#v*ho>;M$)bVK#E6v7^UjnVbvU@g?V=_tdPM*x>4oL z{O&LKd14P}wJxlkU3iC;oOM0!nUCG882H!gR=nP2MwoEV7GOvB)7l5U5lwiH{>Fo^ z>Q4&&CsM!32b(c~&MsTA<35!?1~_yT=wcgElpBKMt!O}Ql_Qos+oBT+*SsJ*fZhHE z7gxCONBzS)$mJHDZL1Tk%6|UmS=Q~H06ScJ>)eLnKd2*E&kRUr{j~He0d?W{RyWi- z9Dd>j=ry8MIQg}q&-6UATrqtY@{;Maen=<!>;c5$I^ydwe$s-cZtY>l+6(a+pJNi= zwVGdkcmKL<-_5l~LVayI+T&MPT@=8+6>x@pBoNypAv>17Ml4q(@qKRm{Tz6UItJh& zj*+6awhL`cN;2&1qDPh54m`oVb#{8D*#8{P;7#YtptbdXhA5Z~!i={aQvhg?M-|Tx z4_(c$BfvE-ITKlyJx&FiaBffYzpGt?2^3biNK**XKp;POvzTos$jTI?5{SV^jqnp= zsLS@{+;;z>oaXJWQj0U5qBXFsmlUtmlh*CikMMvFG>Vqk5GGp_lK6qph4cfoPk!Sp z*Dr!~d-kqoiy6&;r`g46ZoB^M@q=^xmrdeZ7fpd~#%P4>cbbaqivm<Lq6t8^FKnf5 zZ~;n4KYk-h6m3j?SO-qRk8FR5_a1s<-Bw8KZ|Lb91^>DoKEmcEehJi;r)NdOxP>Ug z=@@TKL3Zwd5ffUqe{28#(zgn?DGxq+%-;ZU#mRorg9T;**VBFtekt*@E$e%YEZ+pU zc)&Odq(@1;R^ecl*Ix&Ith!X~&%E*TRUhN?yuziD-30%<4&OxFxNX@b(8GP;tb@)Q ztLNRu9waD`7p%$3Su<mHDpgbNNdBF^CuL;Y*NbUs0GT0rLk~%i10xvMQ6*Hc)5K~> z7kYMTPZYKfa#i(&Zn*QD9~ttCmCX}?nBe&XNFN?AM&I;hG!eSUV(X<EHd497i<*@> zcyhC9reYgK`ioBa!n1YW-K+|(l^Jy%_iRli-Dr;9s6F*6T)#>zcf3{pNZ5z;x$#4g zxinyv?2*A(J)R`?<ls;tqR?kK5H~-8p;K>O)7uyGV{SgPeyO=}o(#H+(SB9O@6bs8 zsAvFCUP%~1XJZZtJc47?AE<nyX`d47g>^)q%nY|ccDTVJN4dgLjSG#@A9+^A_eN6p ze#PVjjE67-diRraPyb_8pd)M<Udn}nX-8-L+Rgum?lER!B%qaWzyW{Xa=$HYS(7?3 z0&9kOmZUMu2R2x84|bm97Q?9kfoh<T4BN?BqZ^pTa$30=*56BJl-5ou+|m%30c0_3 z5XUBSyW(aQf=N6;Dr`e`<j#eudYh)v+{$Rm>-A?xIm^X|zZLq7wlTI|j$MA-SFMy` z;~sY$*ODmaQr2*yL3D=V7XhxKRw35nNc>DqPsw}kh2#WdJGT_z2>@_s4N%VxANs)3 z0G5fC>oyjk3;g6aYG$sn4kk?ink@Ao<E;$Qsw4D2RBKW`-XQ0nfJ6<VB~2<Po@4-u zGouL|2VyHAwiHK{GFqI5)LrxHZIU{`({;XuU`Cq(k?~bgHR$Xk$PKO0T}803@%v30 zvJW}Pxi7!k0V!48`2&9X@weIi?~U#0;;^%k^h=}r^wnqOI7$ER;X-ZgF>u||sPnpm zx0O>CY4uSO(i3oxR9Aqm|Ae@Gq`mY0;G12%J~mA<n4Od0K-+rtVp>70BK*gZNR-UQ zWl0ODakWqH^QZLxkb$+CbGw3L$Pe|!T-n8X2g<ZYp5zV9p^m+&s7eCA--rODhWW`8 zLNoh_i5OM+93&F{6~I^@whnrn?zMA-zx(!Kr{PnPb}uRD4owpv4==!LHvl2cBIJjZ z^K5HYX{N?kJn;PndIz6?++&%4ELChI@+<^5c%3;%SjQefx>?z4eb5JMWSiF@6xg&a zYJ+w;>*MjALiEPl`|1L0Kh99&=q+^e02=iL>FsYbhnU?oNqIKro|XBh9zb^I3hTT; ziaTb&?!_RSHAXZ*RJZQjNoMKO98vdWt`+wGwO(lPQnr+kc{bC4-ms+ro{<B^{`=7x z>OMEs)uyie+Lf7iel1!tPh1t=%gyq!?cMSMh;*sfq$g$L7|dhdbLPgPy0%G9POTAl zIcq@0F$(=l4;2?X-$FJqmyZeEms-7s@0b;Haq)0%O_JN*+Wb6q1>~WA!OULHc?G-W zY;``-e7&bpy*tU|beG6hw~)vDW`+^&sG@^__43Ee;NxBl`FSD#_H8o%k&)stH}3dX z!CDq%hYai+0~h}>Mqj@zWtZ~0;H&{ZxkJw{)}TJrxnLD+W?*@?5_YytygQPI1eAF_ zl1#h2w!g;5A5~*q8k|u#|5}K`qQ4zd$GlFN0Q3d2uJfn4sRqIKAz7u9Jl?!McQpD4 zvtoB|9lAzIs*{a7x_<sk3OrXU#pO3?jd+K3&;gHBbe{-jO$E^=`=(O;0<<5|h>2pl z-TlF!Z_XGE2!r?GauCpqY$V&^OVSqD?2@?~OfPAowQ;{_&67@Q)4NXs-=!YRd$^>I zcdj?XMxvHlc=8a_*#=6Qi>PDa&JR);)c*OZ{|5JzYD#i5SQ~*ylP(0eWt?+Lo&Gdo z{J;?MAe9G1knKxRNt%!YUX>svm(MG_nKd+xO&Gr8-hc51KNh0$Z@KIL@fVe<C55W6 z1o#>6h{ursDTROd!=D~T8xQ4k<Re+f%d)cHQfoXKti$*&78{Ha(~R3ZI>(6kS2rPi z`5U@6roC}25J61~qgYLThtC}uazBy<Z2qnefM@u?F$S<D_^R{(J)ux}PG1Q+3mvXW zl9L>xQ{?t@$)t-PH*xe$sjOhV{wW_9xG~H;Bx)D9*E4+=!ojPrLvOR_9v0?VSZMd+ z0FN>D30mIt)=m>;e@qI}FwsFw8bZp`;iGzQN~8sIm46oAyl15OWy2{g>mM-$(qOQ4 zDdrD{COS4~LcP>e#W$Cd3a&=9K)@62X#X%pF0tHjk_hqVOv{D?l9*OEAr=V#zBr5; z0%=J|(4$k>+H#3(@VHr}fPXyl=AG3ZR?IcdKenRzydK>h@aN!oxZF2~!|h5YUu{Ff z+*2YQa1xxj>my=)wNsE<R_2W}n=mK2VE!jnm7fzYds+UQlgH52bpehFtRMB&@}0~= zAXg{6z@1v6!vMPYg}K3SVAiLYqdO|_!gBIorIGR78;*72F#Vhn9rDjafdnUibPnC* z)dX{xJWzpBY?PJCdgu<!^IZv#Ya`5B=BZGBvY_DHDbE(;CP+5Ld70Zq(i2nL5cJo_ z!(#Ua*qDv&Pk-d7Yvz#bcMmI7se(W+Z(fPWM1S0UKG19+&vMhHWcF$Jzusyv@>bLf z@o9KV3}|J3K){qLNBsWe`lUmmJmDRBLen-@Wy=|S+;*v?1;{fYAi&nX-i}0#k7`ZQ zFLQ{#SPqhTG;LzSp+liY9Il~72FfJ7Y_$Wt)W4-lKNw=D1bqxIu;LA!V`F6J>-|%D zS&TnPWb#93kA5~+>BsJ))#ID=2R{?$pO20VhVPFK;9q^Iyf|?5&&mouSYd_G;t7am zOYBoyZgX1;?6Je~x4#!85DLn6+>_C0Ng&3OzC(l};w&-6uDK!dI6wl})toknSM9Df z77h%amOm}4(vRKWud<x^wLoX23{bG3vinye98e1I6-r2b3Vd>o{~w6~s_oE_(CcRa z*V${$hQ;QK6utiBcis~EtMNXBaoD*vx3CG$E(cqKWD7faJhfW~4Hr|gsjnLtE?j(= z*Zn5gr11D$4tAo?_B>g1=D{aVB7Sm?5-xtJqGdrtR!A_+l;@)NZ$gq?*}#PpS8?~U zM-$|g{u|M-<$b>~d=m3pU=zn*8<LSATc31J-`-#8_`?O=3nAMwcFd6#PKVEjvEO6m zu$17J>O#|$PCaoSODcd%!B>Lo$&KU|7m$Zwd4&%dtl6P^+QJaSR`gg>jTKf8zTyn& zx}QA|kI@DW?qrX~6uGo28-zBJQ|sZ1!!dAm{4G!B3YiVBqxX1y13ES&tg1gUPrQZ~ zlyBEi4&X!^uq+TiR#uMrO4DN)ngOX&N4Ko2^(MOl>X9!YsbNb7$$n(Z<DV=}W{J({ zNu-R?wC$ti-?f7Z$lF;JE_cK2V}nZGDwufe5<@;aMV|s~zMjATzelxI6C#l7oVF#I zErc_D59>pN3jD{GhbgzZsA8HuM|-@X!|&jCZ)*mg9%#hoeZ^6Rt=NLYYKE5c-|Dic z_+TpH@TzhYns2xh`$VO!(=FmeECz>bIA)!Jfw4c1%i?cCM<PVDB41iysp7+OT(2$Z z>zUb}y+z=8-C6lFEU?b#6IOoV8a(RXRDh%lz1Dxf@0#W%vG`~psJCL?Z+PSJivpas zlP_G(nh5O43V|hXDdBrg^7ve5btaxd%D;#P{NQj`hU$DTkOKGI%O--xeF^atgRd|` z)~Fcin2d<)f#-%A>-Q=;uJ9L8#@cbzrvsbk)pMO6`A{kwzRA!%IDK&7pl|{rN6tEd zi$L~YUzW<_;3T(W?hYS4;xDQT5r-?rtGW-gWFOJ!GUVaN#|dQ-@avh4c`gq3IKWk7 zV=r~g9ZKO&r5~dWp%my6$8pQF^)UM;uCWW!fO`3lIT&cZv;n>%3R%lrn_0{3dI~=3 z$enS9E`F6Cfp^>$^K75l@Z|uHJZks*P$<H%Z{?{~H=RpXntWJJ3HB|D5#U%*gmM?+ zfbsk-@$>GUx1RM$P!+n$uL+-8K$5K{!M3_K>wata&E$z3{z#$UMHinuSnLN{H&cU} zfi=sv9|pP>&f<EYxvYvhU#9PdDV8wS$03Qt9Dej)4h%rEm2tv=$=R$|jY7^mhD1D1 z@cn=oS;^e?3x*-;M<8yRlcM}Z3xh?RQ!vlK9G13bj=m__ZLRXY)8iiY5CZDV`pLbE zC@oMjk(4pkwz|y=!2|AlNy>Ue#&QoZ8~aoHuXR07=e+|ufX`^mh-^3r@tZkQe6k3< zT&)m|{$>pU&pd-(^1J+lxOyuV-e^18zSH|y0E%h0q+#cCS$=4%`zEt!zvD|jS6s6; zrDOG@1+VT{V&X3=6?2_@%-Mk<&6&SE*XH~Gp=BK+NO>v(R#?MZ-<X=bU=Z(@!T|~8 z+GvRsU0{!f>;C2k;Nk1F-uo>OTix9Q^k`LZALRfgRKO&1*aG`Zr5oPCj1GAA(0S!v zL{ErZ^>?)M{)5C-(eJR-n!O-)Z{FPsh}-=fWhe>k=jmVU0<ef-(8Yq1%UT>@I)`=H z@90}_`_Nu}f+BRb%#v;d(;lV>Gg~z`t-82azZ*t%afT1lJ>z)l)&S?MbgPpJTVa)` z(FF2$Y>n}OJK0O3ffqlB*f7N}83L@?TL&fXH%GN?7InNd3<}&lmpY&Q8z^9+#ljSO z-sh4G1ie_ggvdfB_Xl^Ye}4nC@_Of`PT7hJBRiqw<{QZ1qu(6*!@W^~MeGYJ5XS?R z_<{yKDW-69&5<lDJ%>A89bd2Gf0w>_tG?@J2VfWf`;LIYAb={U!G4D;Lik-F+1>CJ zjw=AA3d(F`pyuT3C9cf**!>OVUHvN9sW8@bOzrXLi~934WqUmr^w;t-))Y>RAtu@m zd-e3N7Cx;rEtDkk?cJtunL_h__K+bG0Xu@@&mz0wO{G~LgG7$PiLdIK;RV8A&r0oP z5C~cMV<G<txUx~u#SiM&God05gj6PrO)fR!#R79pWV%0l!N=~Z5q$n;Kbz6^=z3?R zWgw7R;&{AJ3g!1MrtWqii^L-~pvxD<IQ;Qy((n+Tt*bWmTVNnPo)nbXHAO+6U*amM z05#cuaY_H7m5S4}C4^9?pnn{acjGCCex;sW?#)WCOST82k47BgdUTJyN}q}Ewbto= zebB!6P2t*Rmnt-<bS119euWmF-Ye?h6pi|CXADDpp^I8k>qK{y$U#+u3FEa-AjxZ% zPXxTYyvPcE{FapVeE9zT=QOiVnA)<kKUl7BufP(mlkIo$KQ&vjA3{Auz@B#4$587k z>h4Av=$WW~WiACl-xPp5a?lc8PFKHYiLffK93QlC--E|!4GnW%$A9Dp2=uik5>B{1 z;0au!{%oRrjl=6#fM2!Wd|BVGqHye*BLWRyHL_gbX7lpH^o&&bzRdBn3v875jL`qH zdYMXH@u{$I-$Sm`M*M1A#eI>wx(w&ANPi?SEme!(%?FmDdz|1S@PLyo6E`H-$e{zx zk-5VPjvQf=a`@ct%F*1d+uh#+;dxB+N5D6A>vvG1+yiivlT${9?=0)%|3FN^Pf3<+ z6qJgFlA4!al<%Z^kW3CRN1P^pN_#sXP}R>S?%v)=qLaW1qLap<KZQj4?Z4-Yf3MD^ zr<rN!^E_O7zR-BmdJHdM*I!(OTd_mz;47MGcMHmOg!p#J(I=mjDiY8qRN#lV2Nr(G zh1q|E>ub;VXsWGk3YA+P=PgaCCG?jd5ntJQb!uWsc={ZM0m}8FyykdOjUvhZXo;0W zGgubpta$>);?~FEG36+V0nUK0APst_ut;s{G*MBJZ;2Vvb|jJ>ugkU1y@s3b@4G6U zr?~0c#$3M>*n{?juLRCSYZ7dq(|&yNqU5de5tNDx62UlZ<M<P-X-B<Lp562!<!QSY z{lAt$406yNgs%X&c<{?+>HX|L^hpG_CY#@PXLZP0acO*6I{6V3xU(&k6jb#td1^Kc zaf`cz`>>fjli?<bY&t<Wmoj{~xlkw6nuac{gAFS18XhDp()rE9C?ETjB4+KAmUHTD zWGS`tvA%wZD15l;(@3#oSO35BD1B?62y7w)4S8&ZhXPmd%yX#SeifKaqU^v^B5_wg zkgG+hxs;>kBSlQr;pNNHT$ayYo1gJ)gFs#1I}7cjct%z3bi^R!<RRrsX&$`pk0E!V z&@?!^2Hu$me98`KV3_ISJB)|V-p?*VOsGKlxVXB|r(x`hQWAN5>_zjvRI>3|$4bpr zUB8zMn!EP@GD(27c?*3I1E+Yr`!u|R!d91BC0)<mEvd)bDYrxrtuw|9eQ+&<ADBL! zxV8|WZ3=bhHY`VYi4F1!9gqsYOQA^xZqh?{rStoW8$pq(RK`#>a7=w+rXH%ILY8v) zzlnFCVg!X-V%y>NcfeHx$BECN4Ph%haX<hH1TsSMwPfGL3Pb86;HEa%O-T8$2R`YD zI<P!H7d+4~@&b>jOIOm3%gW5`Z;|-VK$r2@>MqT>uw-+ZaGyJZJHIW<drI3&N*V$c zmep`Db6VPx3mW9W$0Z;wXbuqH&&7vBI=FkbXA=Q*U^<(#$#+WH&Cy}u8Z8iSh#?yN z58$yDY*-qn!hgXP%T2sGf`(J&c<9HXL@ul{P%`T+vF5OCS?}{3;G?bpy`&>Q2%&dT zv}*>s_mrQUI>zeoPnM8o$Op=(^jhoa=(MK>^X@snBHwn*j1Xh!fQ|pl0=OB;2FQmv ziB*zDPOSHCfFti^KeL@xgf7S}dW(5=N5JK2cGK;y;Sff-A!^YpO4%g?!rDmG%a8CA z^WCO0DKwA(<ZlstPiUGoBVTE356Ia2KIjVXI9c-&3!KR&M_toM$+bz%&rhe<TVo2| z>m;QyJO90jFSOZ}KkNmTl9vqO^a0_&eiU{<IpFzI;MkZnT&L_O0!{!ADBGeQ#O5Qz zqHgMG-<Dg8?V*EuNaq)3uw*kjTvmpxJ%9jDt5N#dSWb!<leIjGh$nUfUjWRaspa5S zSaWi6f*k#K&R<VrIhvYZK|Y&XV65OBq420RK999(ljgAqgu-unVC6M@CqKORw8U<$ zF@?@}F~l1P$VZP)NCD8-6^$9Dd@7kqq|CqH{VPVYBI)QO{A;;q{+`nPsh5ElaIkn( z5B6mDWvocz$&S05<0QAPe#R|z!>aKAFpKVL;J<TMF!yX<FudpI29}W!R1ODtb91Z| zoL$C_ekR=aJ#Y)=w?4}fiO@Yf{pJ#h!x#zsvoWf;iTLltwY0Y@7zZ})PSxO&7->c& z76=w?eS0f|+zm+F;)k9o@q`k6rc5R?{yijrpucCQTR`de1XM~zM=*Y?Hhb0G62c@& zN3~*RUNj=cp>O?sz?6ZJE=bdXn7@cKTW=)nVh>_~iOwi7)0=o28m72ZC|T5%A(FeC zdGbX)JU+(hiO)j8?GgMw&-F8XD?<9jUhg*y!_0pi#=Yx<?Z4qi-^{VL&|xjJoWrTZ zdU&ci_9xVX1?<_*`)=~b*i=P9TxwnFw6U_1g!|mcchO6W*fl>TF+n@9G>n&3G;cLg zo7H6Ji+F5uHpO-01@A2nlRpc1RH=ki$w2&=NyhfZ5DzOEUH{_>WYFuW1utLJ+5FJ0 zkp=lk`sI82I=f$u>(If3xNC15+FhEL5*Cwhb0YI`>P9}L4Qe>u96ztSW>jE7*8xac z{4i>#{yJ8NP86ag>^c9D&m+0Tyi8Q3W9Ay=zi1^$2mFiKZJEm>zqE7V6cAsI;FAJ~ z9jHAS3l2p>lNY){BhP|@E=e4<9<u(Dj){$>+-DSD3`pdj;aeZRhSn~92(Z@^-%goJ zJ&SZ{Y+ijeJ}km_y>G5oRg=K0o4<CwFZrV21puyg2Jn`1O|z`g<jGCm&oN`)F3`~5 zlIhhsw6u7_wc!~YSUULt_-|cI!@}`pkVX?!N~C0>QeBGsF6STf#qqdT>f-Ukc{Z`) zDq=A&_ug5|+YQ|fkXqQy%*}m}-`e^tMb+x^QU#lk7b#iVrU=Kw2PPQd%0IKz1W6H5 zKJf{_Lsh0elM%hmKW2p`Tg$r~MNE7ZkWyR}=_(tBq{*MHWH*P1Olp!62lU(z*ZfuJ zlz=lMr<$^FlF6&Fw?etl8^pUB`)>ZSoboQ~tsN<!)1@Cv&BaqA!5#63Qp^sV3N|#G zEC8^yFI$a3f8~q%utxdKlO};bp;XLqPNG0O2D(@N%JB$sC`AESH;!=%`sG~y+L=FZ zKst(1cYlwve3g)wyEIIeK{?<L^$_H576Z=a2(W(u9N`Sj#d2z$(*`)rDc&3y<2n0< zzXHni)30#JS$;=8>yj->&oG_)XSM;y+jo~s_jt6&U6044-YEVn|Nd06r|J4=@r|dc zpMF;bpPSZLDMSPLS0B3BuM55BdS-~Na-dG$++2v4v_-QNw%iIqlQQ+s#|IzYWEL%} z@)JLc#7AL*@hd~IZ0c9h9UXfUbyf`utt~{oh-Lmd&lE4>%}MVL)XB~pwylQa68F4y zpVb~bJ>4<~pWotHLvm5dsw1xPe7n;w-S4Y?#_o;lD|O4J_P^(`b1`u~!(5LZ4LrO* z_i64=maH*P0k@#bVCB7B8+#X^dj?#|!V=!NnVdfT<fsQOW^Wxsg}6iu+sVZ#Vt3XK zx5Fq|gYG7IarbzS^=>j<3ndc~w(rj@b3K1Umz7oA`%db_9N98~h+<6>2q3JUU#@U> z3-sC;$0CwG{Z92exLJc6f7Gm!SYnV>Y?uec`aWAed1_YPQ*B|9cHlCFoy=27G*&T? z*S6~=(>Xr-QES&X8+;xTmJulQ@CpBJqxy6S;}+=xUaV*{^j&qQD<;dzYo`9qa(cjg z=aA<~Ah!q}vxE1-j}+;VvNDQc)02FDaBZ(>CgxltO;b-(%d_P&R2;JH*_8!WLBMsC zbGIu?R@)!HVf!kIeW=fFAiU~$jc~lkV|?gn{_NRXeELko^gPg>zptN?{gl_yDd9kD zce<kQfv;b!iBA0H8d$i>0A-$Dv+DS3!G&tH%BV#u*fp|hnA8z~|9dH9G*x!ke7Qvl zTip!8IlMzV!-=c1EcI1fw6CvdfpKiu3R}}p7yus$PtSmp5moU}i2EH}es!R4_K+Rq z1OYsX)a1sqWx#FOJ|@Z}p^PC<sv`%_K%weCp>pD1@T2-8*2(Y_OTQ~gb<E)X;V~ZU z#Qe&W3f>hDMX3C|7%9lyKSK>MY(Lh^C^rxau9-m$3VyXxGZ3<5s`c4zyLQVoz`@CC zVVCLj*bd{<zM^Bs+<d~KKrtO`hWc?ncH|DL(>kZ)w-YctT;G{75&b~Z&_l@<-EfnE zuPo3qpfL-dDPwR-Vw~<b;>ofT&8XsG@)VaSnsR20W2|vh*fmm!oOHSS{LWMJ?{zhj z$@*oEV_v1M%_p4FO<rRmR=pl8{USpir;JlI4S&Rig`=f>&S$bw-kU>g4JwH)tBL!} zaqDxdnn?)6YNK5rcQo;C&~{H(m)6)i(M0F!?^FCoN$tUHrEW!c6rtX6^4IBUjS=QC zNd`{%cX-_6(xxo)V@%3r$)lA(*w%>DwspC}ArX0M<4ITd6!Sz)-xqtSV{&E2fPK#+ zQt~Z)68~|^>wU+uLy8#Oc3j044n?rk@@>A_+1bfGc9RiMo{%%}oz#DPqh}f$unE^B z4y7ck=P`Q1W<E2C88KJMD4wc0;z|?t&N$kkKbu_J-P4X1yjnoX-b8Y<V`aiynlLhk zNpgL1XK}AEmYZI<7=N@=@knm{&UtIat)S#)fuP}AdKnedDZ#}@R*^VT*T!jS2|BOc zg37EmS8<8y9@xR=)WUXmjoDGDX<g&lx1r7tJZ!<q=JnHzK&0HEKl5=Px2ZsB)GMZ9 zJ2T(iccrD6_n_ROBFFb64I;pfqytOjtrJi^=sslNeF*vK*$W7v#p6<%rw5(<=F@a| zDg@%GouPvI0tdvgAe|_{tF&<V9Tyv`o!K&R`}g9HE%u2U8Wvjm>=Q@CN0B#f+;E+x zpr;*R`5IWKuyRSd>Ln>SP!URwuwFrah7Q43lx~Rqfp;$02u;c?fF=YFyFj4v^kiig zuc2QzLe~B8Yq6#=kqn}4(@XobzXbUtgV%Geg#llG;W^m3+MHpf5Y=Q~dp>t;bXx5b zlh~C?cWmtuF`|;N#p`UfwtJ0vY=3(@zL4LJ?H$HnA$--pFVY`74v!J8oM_xu$4^N0 zk^8J{8EHr2Ohn4O^Xdyf-nA+#2tM!blbiOo3;%hG+GNZ#n=Rdcb@9|2<6dvokU&GE z-+*WKV%+VJ<$}GO|J`y07F6}ae4x*)Z$}TIm+?I9m5<Y5AZ=b!m{eTS&Qw=?T5oRN zA9W1+rq-K+ABR4)yIx&0-ZTDdd2_N;x%v6q_zKil{N#;326uN)a0ET)Pd$FrABPE! zO7pF3*s&{v(9@pE{eyyU?V%VSXCvw)ASqdT-_8hqV`+W1>xUO9d8)}v&(qJGTNzmt zQn&H@<#*sm*!H7KeUji2W8z%XfK^1E@Ga*0oZR&#T$2z=Cc<lT$5!>6HAougLL0x~ z_Zt=3=u)>mDa4<zdYu9PBes3A+9AO)0EZHD;TApEKF0gq36b;0yjp${zpa~YWfdm- z76@G>Ax6SRJS1E{uRi$9K_Mg$MLVX<d{rMGrnPc@=zWo1EVF9@U_j(q0)Jb+yyoTU zzK=9&=NXym-c5?7%<-U+CZ?hZ*OtfnmM#vv%hZX~G5H?(G6UW({S3?3(`yWRualLa z!|xOBNF-GiqjbM1K*Jk874VVk6}<io->4dp(Im19fv-G3*@8gTi2w@eZXw#H)e319 z_59jDeYYssXf6%dnN<5>emjVvJ_)A4&U1_^J@Hbo@OsLr3D5fI_IQizhpO&G{~nXd zLGQ(V*&)snop?_F^;77sbj&N0(vQKrE0JxX?@CUb5zQ~k3dF^yO_thfOu4?@G;8R$ ztus?S7Y&leFfrmc!gecd`4@gQd$o##hLLhFXE*V)8RAO|<ZsD-;JhVoH)GUoekRpu zf4I34?>iPk&Zd5f36)VGV|%(eOOLxdT4;jc`~JM?XqGJ$O(dthOjhic9z^(=`^{=g z`=Q;7iEx`UYzsuC8$lnq4(Df6OMgixER-F_5n1zc0*7Kz*6;1<i3FBa2w2vV#DMc* z6h>fY6up|EzHizX@ZM}nmpqLd7nB&9!xu3eHm-+mOo9JG2B#39P7O#RPDlzD=S~tz zuO;_O{Im(Mc(0KwB)0kHArUQXxdu71E+yQF!_6eGceY=8_w4U)D@RMkjYFC<@9F3M z@slXM1{yYpWOwa4aXFLASywYgwO(T6d{ziN6c$rdQ)*f<^f~o=LrpmKIB){;^Kp`s zllvZY=0{PFm6)2GzfDTYR};tk=#=?My0-AV`AHn{)~Kp0n#n!*+oiYbB}{R7Si{LW zs}$H9dL#RRN*U7{)G7bL=EMSQa!seMnk_qrldP;h;QMcPz|(L7Dzg4Y^o`^egPR(0 z#PGsGdvsl#u)e^{{@;yLF7?&p<u6%EnS*RMns+G&)0;+#+c@bw7vMV7oLa8Vv-J}V zx#k1#DV(_DBMs}}uLd^+aWOSjEh0v4`epDli8_Lcjf%lUb<wH+l~Hr7AK{8FZvhpc z_yoO#&yv{LF-w_cxL>8ZG@efI{&E($w7hh@xI}v(1BkvioXEh1=Z+tEcPSxSC7*$a zmbrnUA3?6F<?>0ubq==zt-f^F5VAkh@q^73;jc#XxNr0yZUKm5L5GTSvhk?Tav8xW zV6T|$f9>Izj&H>$-7I3IFa;BiL2s4n&1qb<72YL!cvweP*DJx@VlH?rpf5M?PPOZC z`%!?dkiTCo?NoC~lYfR@3$F^U%6?R!J=qKEJk%puQ*KW^S^wjnb`FW>jkhVnJQ@!# zt7k|WSblxL!XF`g+SIoDJ4@DOm2S1SuC7ik;Y^2FGN7X=cYhD(?HlHP_lV#_8<?o2 zr8afK&mAcnBB$XjM={X-t9RK>m)(jIn42yO0ICoy1_wIBnoa`5BN%^@fT$Oi7Z9(o zXaiUTY9V3#X+8jBc(tx)CRk!`L+X>^!*Glzgu-=!CF}Cwz}jR&a`H3P;5WFtpx2v+ zK4#*}=!web%k`cC-HcDV6xAQsSI<^EA8YYMA$@J08CG*>*!($g#%v{<X-JdUEvrll zI*iv2AK6V$&n!uw1f@KOWTfaxpQr5jHX-=)M=+=AUmag;sz1!|beYYS`S#}9hlhKZ z?(T~Ii#gieb?a^_m6ZHKdPO2I0!7qIN4J_7bdO_!{j6-=pE<DK{^)JpB?r^&!O_G7 zuikmTk8kOT6KioKA?})2)=rL|rv&`6d1DTaYqy3Flz3_Y7AlMiNOSbMD_=fGgtwyQ z=g33ycINMrf0;J#yl&ef=Af%ImxiC9H&meNt4&%mnM+vz4s_O<1O(~0Gsy|LP76*s zVWf!>utkNzX>Jd!qo<##R^5YKJM6s#(lOSUiKqxxOI0q>C}S5EuCYf!g3m>DVZMKE z{^=WAj*at`oa*drU;n(TEL<~R;q@`8uF(Vq?~1Fl*)z#fS?<~Y=7rcbn0QF?WZHNp zTtZK1(_3j1Jw>B?Z(wv{Vq$H<K;P%Z5aw)rLlFCBAj={Bp<@jKu(mtAZthhMq1SKx z6k_(EyQhD}h82>pa}RNL+8$Rr$ea}buqEL5C)6f^X2G6sE-TQ2K%Bg1Z#43&*|mwx z+0@j&o(0kc7r+SQLZAXFJ&J*dJsf5z2up8mD>z8di*?(O$FCieIt?h<rk60gXcI;6 z`!Sni_n{vB;pSCHW4yTyqW}<w$@7gR@#QjlPjiRoq<w3Ab>f?|Vj)7j+D)^QkDfSy zV}9RT%HH}WmEiRkG3WiVG5Li3t&~}gTwk@O`b$U1>D1Vv=F@<Ce0fJ7A5juH4kb!T zHNS>f{d#w&nMd}6St75)Fk|P8sCTE+Y~`!;=o-7M(BtMe%+&U7US4Zkf7J9o$(B6h z-&LVD2?ZigDYKxbY5+r%P`mkmQ6<WMTwYm5(SCAtScm)#BTbo<Q3q*3aL-_Ar0$5b z&UZM1Euw>les4>X;0l6or+b3dKi|{ky$yUv3;Tz=e`X8qN<R{9AD`+(M5YKGMxmBI zR4hrDmXwsp$(&T!X&2Z3O7}dNe(z<<^w4f}JcUCFzq?TyP9jsV;}elkGCflbtFR=p zTU~vjYd1PfHRZkKg=ug$(tLrM+VcO6-r#9|YJW2wp(3K~wpzE=s`=<fsm4!*?~wn+ zeW|JQN;RF>Z6$u)%zgyni#lVxa$Ke4zmMX2E2s0EB&VvaFXqKfkVg1@J!4O=S#Jyt zaYRCIhBn)B@mO?yU47j8xw>mcu*&%61m&`U;nd7Ac?0q&e0X6rO>EgPxwL@K8B;Yj zGoH~hX6l`nE3K({?v2}dX&=h?yJLWb7W=aPJe^dXnwDMbY=TLTB`P}StsH-`Q@+Et z_q}W(!lL3A;6=w}rPs=|L#Hy~R~yFWZPjzrvdXG74>bUr1QZShiKh5KtdW&%Fl4Rp zGA|{os)=2IiOoIUUFHjdn=o0B$o0pU2sA!Ml;f)6dmbVTh+}K|<l<?KDy<9qdRR)- zE4*@+E8NCMe%>Pq;UC$?^IR`GL3w=hp5L~Xec4w3v)823e0v_WuwdFmupW10yVd*Q z#+%Z&Z(A*M=<RyX60a>RFYC=Ws?rO&?v7V^7Ny*3FyOMbNo#(2a{2UBIW^H?U{LN- ze3d#k_j%y2_r%0P#da&7%wynjh3P!}-b0k)2luo4po{d!`($4a#n%wS4nkB^=24h( zH}6+m^#-54&H@A{FN`o?ZyfsWaF%;~(})jtA2bm2@0p#-4v`bOwgd052#5!PHoAw} zRMUgE;&b80IHwY!O0P|3nNbn|F-k0ovhK_!>;|3qnrUPPziDoErJ*LKE<c<hmvVYK z7g7^#Xt?FkWw0DZDdk`u5VRXvlM4(sFd%^YO3>h7FHH)H>h|y8EED7DUQ7O*VNZ<k ztZ!3TBrsMVA0N}&mD9ecv~-Djua4?r9M_ar!}-qUSLGCiA4A>8t#*lSd53+q;;9@~ zq#QuL71nHePp<(1TNiCcf=LK))u;s)Wn_f?1_H3surF#`+I@Kqarh51_W{c2#vO$v zLyr4a$%58QXpv%E)AqwlpaRKOTm#F)fQ^MtWLrkS9_qY}H(C(m|GPltmDnc$O3oE- zmy(!CSWAcAYA&w7tzT#Pr~f8kN3%Jj!<bRpxXoy`5gyLQ+U%JDtNdHuv)<}OKMoJG zb0gpAnZ%3CPqygV@x{ZYbc?yK2nd~54dmDUZ18f5oyqjw&2~aObPwJ}{5ks4616xi zu<YN)d`%NK_N&x8f`*GH4(orMrWXP$>u>Ctl&bNY4O%W3RZ>!lr?Go6kiGQ2&!;VK zUTOh|!_w9BX~)X(?J7g=B9T5|O%Kmi|62kGc+g<Ozc5ENGZ5x@ja)PK%j>2!3!JKJ zobg{tZ>S#I#&@=n0&fKblj_aK^;KCcENDvy@vjDA<_v6cbRjAadv}4&0_*!hj*;3} zThj&B*Ly9HcRTj`YAoB8gXWzsbZ=U{&FD2Ci$Hd&WMG#~dz5~u=VLwNINycEMI9=z z!$76QY=mp0ztc%=`!MFV-&xqo?>hJ3s|-(HzDzESHai>m(YDphWw7X)O3z;FyZiPU zv#O}h;IuIH$QLVnwa~2@cR-jSC_JPJE%x(h=4@+g%VDSgVl^eSTzXgh-q6HEm}Pc` z_;#x{Z_C;~0FoVr?0U&P8$34=bIZ#a!HbG-kIR4FIH9DZNNw}O_qq&K2ab~S=j$03 zRv|OBk4Hr$NN;u!)}y7w$u?&<`7&MmqS{=UJoDss6GQ;twKDKn%2Wk=HgBY_uh`c_ z7~QTh3qo1gcpP`hgm7P>#{@4d{R$;xeCaxZ^h{_mzpY2B7Z!AwzPMA;FnJ}SQk4MR z<R~%>F@bkH0w`bDXKu68<;w>#p97=V_XlBP_<gpJtoqYkVnEYl*@u!X*_?dmQC``= z#KbhO*Bm4RR9)eJuo24(P)cgv_CuFxCx8%t42mr~AHKqB8<qOx#hU9sGIA3-Y?7Fn zVx1KnxbNTKG=m3(DOHf{GeC;AhI#~Khd#=XThy!YVu8us^;89-p#hIjav;#CraM_6 z;cQC5-)r-8wLgAVG%QSEnvCs1ZHZ}hheXi1B%3-9kHcWDfkmus&rTb2n40S-<Ux0P z_rl4ab@^Okl0#GW=0Ee=(djEw75)Um{yGr_8RO1mjce&tv{~OxQO}(#HP@X@#!F<| zPu3NtQ@7UF|3_+;W<~b@pB6wl_4pSJD*ep!<m6~~Z8K_WHPHM#s8p~!;V@lEl`CAM zY4@z14OXTo5wsOn5UYCk3U*_fTF-8|moXh+=MMC1+`ibQR6F0GCl-EGdz7b1_r~*N z=+{Tz2TSkuObb1~tmtUCw)E{D1nq5y%GmX#??y&Ut)lFE)#WZ#&~O>jRNlPR;~#WV z^oUW+>#2Kpk8pa?S98q^2d^1zR2#gI5j;9m!PaZlwibWMEKo?~2^(8zTfNug0>v`8 z+>dZu7!kjeI@Gm5>l0)i<}7L&!s~9?P+}3eaCVko&3rvYNm(^-v{^!De(m7a+1tBg zg_T-BvQcxp%?8geGv_~8!xYP^j3xnJ8LOwiv4tJwuCy6C1w1aAV2=VVw_oUNO%|8& zO`M%cLO(OTkl-{uGqX-QI{WimIqc=ND_w_U7zu*UVn}}R3v!JKH@DrJ$K(vxdU`u2 zin(v%uR2EmW|h9xhDPr73&ENcNQ2SE)G?2rn^|EsBtl~x&XE8>iO6Y1I|yKPAb$Oa zpHX^KbinHiL=|&sbt$%%H5&{049DeL&52%<o*3V)xecP~+wkr!1Ms>!tY-Mif?OyA zDgJ`J&z#hJ192phD&Zzcd9EwquqR>HE^+4ZdE3{|Hg7lU-IW?MY=D{fYGa+GotE}t zSV3sAki$4TzB;8uBGeTSHtPt1JFT#eaQjPOM4}5!CRdEpWA##O`(vl^C3P6J{^?<A zub&pJMkw`A5G%MTJ49J{r5uP7gFrUA&Tr+=(;;w|(VQ3aNa;k-#<Tb&ZG>z>LAghu zka!poASN350GJ+`QWwT@o;BQSQv~@;pyL`pPxHWG)7URz4W3in5dJR91;B}dKopYd zQj$wk;jKFRbdbrC%Q6tl7ohiI;2ub}IQVFYW@dCu0<!NJ-NSLn0?7wF@&mW$I`4i0 zH!}ke$QAAIBz_AVGvF&YV50g0uXY3y0l8lk(&Y(QLLSOZ$X#vV=$8OBXt;x^jV#sr z%yg!W<*`p{z`!KfEMx@jjMtc{6(`2UEmm&hF%nS>V$SxH9cO|U&z?93WU^ocT_DlX zG#TlukElMaF&UlAj;^KZ0+F7uf)GZ+MVPeeoooq&-(AL+W(ZFoW}h6{a7Ck7KgHx- zUF1c;WA|X^6OHqf4co(qg<*A%=Kg^7hRij)5CZviHxdc1hr8sMG_e}rJSM5RWS>2_ zwnp2B_xFp9?C>~mxydBbEvXUC+Ovn3@-FF-IoG(1DEHlOEA7^=`!m*r#W71E)}{+& z%#*f{x~ftRZUP~+p~@bj7~USc=ZHJw<uLn}SqXp3w6wH87m8Z{ySbzty|giuHsev> zrX5)VME}lPl(LBV<H;m#w&!M)1Nz_=xHj<5ukU`Jm^f;M&iAVI(yDSup5)O_x)@gc zY75}Gu=T)C<0!Y;)_&XA(0bsX&fySYGWt~8No={~=@6{UzRk6$u{X~~^yt{nMCY0P z$fT!aUf-CjKF*4XlduqtiI{w6GAhRS1_Fq$uH4#Z?K1R}Qo;Do%L3hez2l}+W?xKp z7RRb!LVhn>U!ok#4n);@l#}~9uI}CiRQ#SX8D`SgwvT5bXPjq{z9lclZd|`!dqIMS zl-3fQ+N08Xg}>@Gublp{QgT@zE!|F&Sm^!^fcP}#$bd4Nj%?~zX=0UKyxddydS=w( z$c*^-pGBiif0%qv`y<{e1-lq8I}!pG^7c{CXtO&%n^?GKxq_C}^!97<Hm8HzUoL|R zB$Dd5z%#1Qz_0>p@W{Z}6SCU_&maV4D0in})tjB0UtyQ`C9r3}aeeLPu2`lBC7EL> zLM7EPfr(ccpHNZhC$Cd(Wc@h$`0;B}H=u3K<VfOMNU0AcXY$ZBsdE`Fej)Sbj5eO* z%x&$X&k(3T*e{j&f|A0|1Y!!O<Rk6<7hk>|%8z9eII$dLyY`D!mK&EchsCmrh=`ml z13gc?5^;7STwy;vgHJy_S~oZ|8atgUeyc|!tLbguL%2oD7fryghM0pv(p=xs9P9#e zr@l|7jI3_w=b$9I(NYweaq#gS+Hoa_gBp~pyLQ@!AXymq_o3#`XA-yAqZJ{Og|7R% z{Cx}eE>;buqf~n<*m>7y53!u`G2)slGC|Y*vc&PQdl<Ich>Yqq-#fb3Kp4YYZ@+^Z z>83fRr8!HiE$Qk70<5_!4}RXc!>9bzuk}w~Mlg+yKxAaVo{w~zw1_8x3Mb|BV`SWR z2pb$Cx1S=|gBvN<PI%u#1d_hhibh_UHWStOVOtXr$RBvB3z__ySP>uTH#5dp5h1v4 zjU{t14(SarjKDnrc6A)>TR9D;SXFtQGy$J1&I@*3UnsEaowV(iOC#~2ulMHI<FBXr zxF!>Io70>1*hw^xU0_Wq#>V0ci8Vzu8@-NiE!X*m8|DPxEX>S|$#%*OA)QZKIAC-W zbjCDzpJzK|M>dxph{p$vP8<@DRp$wrj+6DCv#)1O`tTc4nf4{wM5G4|bW>lAYVz3i zJ%0YqT2)h9D!vX_l93K$h(lJ0-~?1a^OR0wfgJh+HUlpx4w6u*xp6;RL}>bF#(onL zyY2QO5-|}CM+tTY5SYxK0)t@ZQRp%7hyf5uVNBX)SV33`u~TY?{ug(gcB~j6cec}e zk9wv_*P;#0by-^!V5XD=_NDYI`Dt;E2D`rQ@V7$GegJfXTE2Rkhe?%Nou00|s5fp} zF!8!OkAdN>=(E+tx}YiVjqC8Kx|zpb>ojAs*Fu%WSDyy$#HqAb->22}I_`*hl!3zA zhM>^^O}=0A=KoRk9nf%fUD!lK5M&|<f;S@}M2QF!bs`xpdKkSV(Fvk=l86{RB6>>@ zy|>XP(W8dJXrmit^ft^W|MkA#|F89*wXiH}+<VVGXP;;9{XBaQ$a2En&UVonmEky# z+J(c0*pbt&6epP`zu(eZNB+Jts}qGofyeGiPA%y&^4#@Kb*rNmet<Slj9ql*8LVkP zgG-EM&>igZ*DqHdW|DEMr<aRy5X>RH*4_)K9GAm5?}CzgdW}N!q(CyAy{54JZh-3` zY}eVlwl#MZ?4yxTq<sn$Ltx*AQ~qmIY|4~!;iw;LC&`x)0)N6n!xEpughQ3m7krGH zRu+6EKy<vB0kC1!$gm;zFX#VcM$22MI6yB#j<28}4%n@lx7W25`yge$=dUsLB@G1| zAzMvM+vDFt&s6kEuvnyC0`0hbM&F6h!}&9*kw&`V5_^5e-ddI$!uWA+?#I~%CDGA( zKN<>EwEF7)m<2H2I{1r~-`L&V6{6vB-~20?JM-m7694u6y@ARgzyNBTyvA7WEi+p( zM>a3?XFmNa;~62jhwB-DNX5D2toZHcN<f*_u8%c3Og5&JqWCXPo16ytRt8b(u`!H3 zt_rp0Z^c=nQd#)B6q#Z{3IDd%lOfq)BLI?bgUP23;Tt29Le_r8qyBgd8_N@BjV=U= zOmk)5u3PE;lo@3l)P^nE{@^KFRcku0D!7`NK!MMDI!FWdi9oOw?vh|tPcz77@(U^+ zx;}}z2Yghg#^Xny%Z%@GV91CS8jU_0ftcCaO$2iVobV`NL#p1w%Pf8mVWSmgz3QC? zgbV=lMhP%1zQ(8P&d=sfH<6eqeQO-YW&@t=WX}=Y@!|dVCf!!Q+V?(tiN{Y>>UHb@ zw%l$yYeuhBz)tklukUVtK;a3y;B-kTYdPBwU~a5qbF<?hT9-<>)RPR<zUE$dBmXyX zgA?Y)1fond7S`IhvO@C@aHnKTxGv)BnN>!PQC>^h(3Jo%4Vw2^!CkBvY`-ud!<{sK zR9mc@rwBP<jOhTo1R<s}wU^*z$|IW@UA+zke=d^5Pw8AH)iCJ|K5dcm<g9V0dp)HO z{33llEe6sv1u`~IiMbHkk_@vc)2)f>rnWzfq{B_$JF}H`eUdY3DdPIqE+1@Sp{KJS zypVl?TiZ{(kCe2?)+&047j%D3sbRElU15Z;{aY@Jo~*lIlKbIbe^`~=c@2a^voO8T z#hszh1ME^8@AvQORHWy7-r1|iIQWp`vSjg#_V6wrS~WQTfs57Va~SHn7DaWcp(!k0 z;yZo>5F#tUP)P&>*s$~Yr=(Ku%m?ntBz*O$7l3!3F8Mwt{xR>t4Lo40ee`-hBvQc? zT6LfCz6^JkO~q#F`uZCx2#2&^ujTPc9r-<X;%<P9C_BW_IPn5LdGGmTKu1f2Xp~Gw z3%BH#mVnbG<!}fcEoNHfru-|g=TM$n5^%%jsyM4AnlBzMaAH&uNIg9bEgg24Uj!U2 zJrkK(LSym_>z?Grxmhe>*Pq$2-z0flrwcpd%P&Wq<m1VmhQ=S-d0!6a-{j&Dps68z zzIdYob%)(&to#i&<0sy-_VL1dFURHiUkx{!Os;F^YIwIfPOMxU;>Fq|U5T9V47DCN zn&_yj7l%uN+beizUD>q1=+}VbKb}kT!Q@o)ghE$kHtDi+d4uPtKEY{D7c7$o12g7G zAt!9zUhpG;eWtn4H?l{8?e9f}bpev)hoXhvVVi%0UM)}Tk;yB5F8ob<>(|Adc`W5U za`Qi+9{D<SNnW8I3r=&v4w!P7<2rh8|LN^Xln73epSjUpUeerqLMggsj#IUgZS9>* zJXW)Ebj*;sAFGKy@?u({1^(68__*t;P`-6>!xC;uZ^ApXTj-Ij?zsF~z+#uw*OAkh zR%&%fL}POw6(h6|IZuE#>7JI4<6D(8FnG`QUxyD^&emisj@(&)7Nb130(<_jQplSK zH3&!nnI~zqI1pEJ-<amcj9EPm?9~I7VK`9biqgl^T4Zmbcm1s`VFbVCKcbG($xA@8 zTb1<m${Z9ki8jpkTxce0aCyC%SBPg@kA!kBDR3k5nmLHs>c0S@=>M<b_!(rRP>|CM z1-a{H#V1M_!mQ#N#YwMl^svXqR2#S_nHO3F&ANbe)OQoO^df)5N&&lLujU?e{(5Gb zGYQM-yEvzvB3?{L6D6^uKFRnRceH<kh?s4zCYVA8Gv$>I3*>2=R15=WdWgn1k5(r= zzqdct1d4O$9DbEz>eKsl!wrD!!HD%YxM+k;YP0(8hkEhv6%mO0@ralEKQvKUTtlw6 zS(nYulmwmd&)a*~h`*a)Zpd`h_+ziQ9^lt5Oo3_|!eYM1?t)J;cU>$1W@h%%@~j^; zsCvNh_a_P1Np>6nEsAN)H=Nu3#q8Uf#^Sn^V&UpkyxyLOd`hZx!B_865I}dTdXCg$ z5wm)@cVB8lrF>s`83M~z;8tUa*@(mbtGUvS?vQrA1FY%_dD#-7{{02L%6aJNTio1( z5{~$B0N=j`Ad=S7oC5S_dc95ig#QIq;;R^y^Q(+aJMRUA^ID;3WbcU6-|c7Pb#kYI zNOH1&v%S9t2lltT+-bp?R0t)y%cr_C=@9CheCT}_@%COl(4eCjGd$AlFS&qtUEL~X zgyg&5`1e&)Cql_2Tq}@pKJ03-#huAJJjQ0_F<gCtqC#ABtOi9)E){FACWzJ`^~N7F z-8NK*?S<NWkd+PTuKx-+Ws?Wb#U$Oc5dx3AjUv@we#qJ(!ZhOYjRe7bIrvvrVlkGb z6>mKO8JQEXe*)nz+0$N>s=Krzlqf?v1$)GSt9<v_+1u&92(ER@JcJ3Fjap9BIL15x z8}(H5mOY@#P7z*MUx$e>%%l`KwhOX2&!q9K=?>Kc`}^pW^hO2W8a^QF4#Rd2IRS2m z1nlm|B$h%bwPZ@}6C=cmJLq_1RBE6Xx%NA)pGPhq#&mONfMO)WF!pyzWax^XRkIN+ z;1_0)pMh~u9niqNx+;n)ypeDqJ#MCl-308_SO^dpw;yi&ZRhyfit{cQl~6+_YW4&D zNnY5=6}$`RqkE)E|6cb$4>S0lhd?y8_3~fORyaRejRoxuDyfC$sj(uBa<d@^D~SLf zmK)U0I4Gv12dsm<ah+d3qfi=26tci1RL3ClK4j4*))l8aN$4cR>e1)@iU1Pzoj(RK z|1>|Y)6IH8Ks^FTbnQT(F_>p#n1orA%ad{Q6}#>pi}>c<yfmQzJFBYdxroBwWMukL zGH^})qE?n2w<2Y@)mqGLJDpx>t7bD8jv14f<TNBlZ*G8Ojhi&VuQGOjhJ7p1ZVBIu zr)TE7(9-0%JIh;qi6pg4{xltt(&dc~l5aC*y<kXRjFC&Co};G%H)GQFx14rmfSG=j zziVSktPcSIMM>PvL?<)YuDkdk*x!HAQATmsoOor){92dg0??GGDI#zItNVv97u#J= ztp6Y<QHnZJ^)pCFk#zN#<tEI)zg_?F!n-hx{^;G0C-l_J`C7MoPpV~q><o&%hTDFT zVCIST`-G@Zz8u!f=Xg_z$vJ4V<3gS@cdN+K3jXqEi8}jMiT3!0<s*<x9vTDxzGA~9 z`}q|&-}v&2H1ERZQYh=SsIUtTF)*GO7d20p4OwXBa$iGF>YygMYHr?tbPpWdE3Keb ztq4=w-xa502GpXagWA>)S+^qLYV_esN&EmhGLvB$e(Em>>toM;@k{7#<^V?$D-)oX z(1BKYd&`lLaWmbQ^w`bz{SlHe(%Hs`za7P;L!)SVCqQ50mUm<TXO2_+E&RUFz08o? zXp=(s5ju!|`Fk24lTt3vYP~W<5>)Hn>4C8Zzorh(JMp{E8lb9rNosQ1W*M$kH}Pxv z_x3f7@{d28gxXXF5uo~1#kf$VC^6bRk6vkwc1gGGb}JtBbdP(W;<9$){>h(n?#%nK z_R`s+nL0_(IIP(Jw04B7PqL9b;Ob~0;uwKD6S6MC!bJ9-kLf<K7^|ks75lp(T(FDs zm9~16WGXn5M^-$_N1{Z7IjkX{z{M0Z2YxwXzllT>MzblCYi#wNHMp4LJcp@SKxr>s z`GC6nzHk4hGX0+XDBcFi|I}QuW9=>=^r1HQH5yQUYx~}rulhmQ&+dK26rD%|1(@CR z3IWh*nRXe)jifyBHuPoRQgrrV90aU&Zoix1&yPTVBL@IQ@OREt=fW1z7tT@a=j&<W z#Y0KhgGp<IlG<(WF1JUW{3ZFD>0<fl9EW5;O=6sQEDrWj5H3{ru|Ah_AG}u+rc};q z)SIf`a>%Z;5uJ5tyTYZ!TascjACRFW_58JcmL2H_-~a>TACsl5q^2v*@gLYU+4Q5X z-7zOoh;M2zg9I_1%fkMpCERiOhSZ{FS%qm|n#Dz4!kCjD1A0C9tWBdGCnJ-y5uobq zVIJLM0v+(T=ETA*l$@Qy5HzOpqLuYmMxLo{{3vL9xaXd@0MLHyviL=`Lg_EJ8zn_* zkFe6J8;WLjx~X#q8f_(9^a6v9y^{Ie-jqwBEUxAr66WmkX4jb@;LKsWJg{*8zeRnb z5+}nh55tJK%77%6zAx-H^?THXCINCcU0d3Rl_7SemG1l}q!}IHw%FW7Cry)Z_lKq* zd!PJ21J<;ks>T1yRk=)wp~6A?^G3bVpn`)`3gTb2`6^)ZBPD6=ELdxR>uGX7DY|At zXC<BFTK$FvtIC<+b3-4V7i(>``Q4F!R$o)o<ZJW4vq(lJloP}Py%ECzI&JACr<a6f ztbTn<7iv?VzMQMyTU4^DirE-(K^IIY_VhZ0=A{HAmr#hbd#j+PLj}LdgJR^sEta)$ zVr5K)L5>ihFj26_ZL;rSVc7CX|27BDPvX>c8}oQPrr1GWKNq2xVN>HeAQz6QF!R|v zRp^~E!K&w`3Lb8KE$<78F&92YK>!ABp^rwfii}yEM;2x!q~*Dx`^w)s^;cL&j(X3n zTgPo^H3FAv<I4GT@#JAGboWSGt>Iv0{O9X%W|K|7?YS=i#^-nb=P8h@Z2dG~Jp#vX zP2_5XeD^u17q^)%>VZQdZ1!*=jBIyvbK;JW@PnCJ;k9JK1&o8dT7hpE*3i(=($jBF zxc+)izcAy4)LI+gXJggNzmX&_7SYYTJA@oc%n8ia%WA!DE7{EpWi;UbZz?s5u~{l} zA&i5ZR)A_<1#asHlF(z7%6Vk0L;V;`3`ID?Eq4-+BdKF^`op8H4M1wpmS~*@7DS#X z$U!$rYt#ZP@r#Zp#h3@o+U_m~8-3*Z2sCmpbF+Tk<R>627zhmw>l&f(9l1%(TR6LO zne09ipr!i&MN^Cfj&?}2m}~;TD6aRMtf_y%B7E)WO~<-_5Rp)Z51#gfCcQjA=FJR( zn?(TJz1sHEQ_sI&@1ckTB-`K9LLARstpXstv+d62DM0Mh<Z8Dc<TU(!HIS|FKR$>i zl{ROVwxf81t{iT7{S$!le%fW*KF2-%Ai!kyw4Egu?=QA6c|_jS5Lch!)Vycflwjsp z61r*+r1&<CMvLuh-NswqA4B`F=sY>>$6e0wg04A0H^cc924GiO&<I*CehBOe1`9sO z54ZfO&a=iC6ZXwf(9!_C>oBr<*P=q!8?MXRD2<n@g=&%mXGT$SX4SuE215AX-SxDu zr8kGgN5@L}3+F!ukCiGC>jKsC?Qb%jmACa$9UMlo)Jf(Kxd7RtW%Eq%%YFNF$uF<h zzpd1L!h9RnpfY{VYPak4gJ}aEk7@FeNTCV`Z1kv-neT)x+k0(JpC^9V^f!ysAKDgV zy#QSz8|&lcYDPDjou66PbZi2hWi@mE5fw$-;z#>9RT6|8j!uzgzEQqlez%Eb(L*=< zkZdQXzdq7O{yQ>SV=iT@(br;|Nzdx?2$0|fVxfT!XK2^6ljF$cv)xz{S_3*=uk~&_ z={eOr#isY{Z*z>Pj6joItAh9BoAX2c+IO#84FEP}fa6qF@mhe0s|KNrejGPhdr%|w zHR$7-RrS_ikzBbT1@GzU>EQf)zJ4jsw|fZayRNM?h#8&V;vC5kMeLBGQjEG4ulq7^ zVSzvjJV&P<(Q`;z`uh4ZW#{Cu#S5Fw%LGn0cCcfLT?6-b6pb{_PxhK*r_;r9*5g}C zPSzxmW{g^9d&nYv<Mm-dBLte;w@3mc>cFVy?n!M|A<Ld#Ww-Ue%ux8&e-?ZAaiC5N z{#tvS+Jk%_YJ8pFi}@~pyv43pF4KmmzJ9;en@sR<qmnD!9Y`x&75hb~m94o08;(K5 z=N*S-a<{6;SozRftFT#EFaNDcBW;w^l8HqT376s){7fCsdKS!-9yc9Lmzxx((x=s1 z1)gtUIBHI+$G7_!W~kipyN1r^D0o-N#-wpg+ve1Cw$@+y-^4?QXD$?YDxf9pQtoI^ zg22nA?KP)~dRM(t$8*Y{XU~%ts~u+ed`BaMB~L5e!}lOiKQpB77(QWtuNY$5v{)VA z$G&{9K59^m?>%b`Nev|0<(&I+HL**(w3Xc`?VNcy-@%yW*m(BrX})*t=VNTWTbBnR zzm*+Q<V4&fRLUq~#V3|)*h`DQU0dv){c@p&f6$M2GciGL<+Aa`8ng$={nQe3bi&A$ zoyQH;ME_aP?{u&0)%;BVpV6_qEXJY^A7cRJhwgECrAYTzWj5_x3W`o6X1zFUdIqBy zsaCwuLaOAeX6nf=GD$hGko}q~LA|yp_$d&{X)<And<%N%HTzdCHw(y>u8$0yJuiJB z%5am_eQRj7g%X!eam6C(N?3$s4c#9HfWo^CFwJt?va^03R+ech^#!>JZJ@lv)-Dh8 zO`O%JrASw}?u}tbevUnX5gcU%;ypJ;fA$2UtQDgtw!9=h0!&TQVati(5a*{*GcfpG zP5_({bz@NKLXF}ZifE6$W3^eTJsD>nXA+M5sQI}hS^M6SPL8InPN<~4X!QTitX{7~ z>Avdu*<0Gzq+i(T34t?9P>pt3?vzG8CYHDB8XCklheU=s8-Tz;Z38CHegke;_$5B! z@~eok9&Ji3V^PsZz00KXB<4HCVc3AC`ZJanEj2U_+I~<h_Ql3B1lrGVw6nam*5Pp6 zV?_B&pc-Jq|Iq$potDDP*!Yr7EYE(YNs^qL#dM%-VaMe%0Od<Cgxrz)^dM!vpZ?W% zF0_=!)@t&A-`T!@DiPaR3IDKQR~4PRpU3Wg<J;D{F(Vap<gMN2ox&I01|kVSg6v{E z6{%2tu~KK~{3Sv!QZNd41xU~A?F$4ra#$}1nsZW8QjV&Ew1v_)?>U^K@I9Q4oJ(ug zx*kF^?3|pL-Mt2ARB!LzJ=0;22R!&LfK1*_Lrc5i(Rll}mfmrsfjo3L`)N$*%zmq0 z(lOf}B+1~X7z0`ZE<Vx_wPN870F!^w!KS9Bra5l=zb#8fHu>kFfwuFWP}1&jG<pZX zLQf4EPX~GFB0glAQczi`U9hyzf<h<vc6X6sN`o86m}yx@V@t7aY~Eu)y#Hb_3DQ|? zV`Q6X5Eq>Crb0#|wo|V6q|zH`74YrY9&n3JWq~3dLUGE<u<#^rR*=Kc0DL<y+}Rn- z#tr@hUwxua?g|vs{&#vJfAtmxE*H#o`@$@|ZApOl%&5f<?q-bP6I)OkYgdL-o0RI) z-JUk=R$#-EVn^OW$;s^Q^77`=g5p}<ym_!ZBw7d?&o4!#n?7Drx!_~y0$t@MCwmsY za^|K<>1B0yj3)zrrL&~|@K{()oN}ZKt3mIfw2Ifj6qv)!2d44OE3!H1r7LSYqKg5( zeoLR?|J|FKh)yJFm_kxfzfPmTc;b4*Cm>P!UtNIn;YYoVfIr)b{0(+L&8-Z``pL8r z=`hb<4y<R*YZ}6(w64@?(2OP6{>;=fg-MT1XV3i|DG%_t#Onc0mIJSqzxD%$G&lLA zJRK@|da6f(l$}yvQQ%KWYI7VfPy|VtzA$p7>m2|QqAhSvp(}D=wmikZd8g8uLCP7S zT|d@p0~0GR(q6=_KLfeu)?ZD!C+8H%-S?)hMM+u$*^s=OkhRFvQ52@QToYMZNEHv( zw=fU@VM}IK3n|{-Tg{pYF9x4dk>!mfi`mATPo1}ADH<C-c1W}ikPb+K@ctd_yf1u? zl8A6|sSq?RIx}B@rlW*SKEBeTzJ1VR7UycD0;AYpNqa|iumA>s{Vw|9ZFTbjtZG^p zU&s%LatnYcE<Fz50Fvdk=zPyxNJjK8ZOrxe<T^TmhG)NWU8H`+l$_GwRSHF^zn;Qq zlDx%0Si2ju?^RA;z_wQOO0BGfL4T@-za)|H_H=g5nSxK^frK}v)N?=;AZGvR?w*IE zinlrcZdHWixR2e(w`9?>#}B&(Ip`d3eVY-un?1YzJE&hJUSJ=3xG$<4$u`{dh0^^Z zIzGsoY51fj0iFRU1c=#dSHQ{7VGN?KMqnT9jKn4Va+-Gn|4DdtjhcOe2)i@7N9Wbv zL4+7?MdN`qNr&y79grt<<|K+k%KBi%*?^b_g5-SueA(>gH^atVhK#xAR5e15QsnNJ z+DlC}2PHpWt0S(TdSc_}mlrHCS^^HOEs`79n!b_bnubHpiNR*~JzCa%;ilt&ER307 z{g0nD8&V#<PS|o+98=Ke^d>^T(M!P%Md!}eSMOr#e@D_vx~(K)E3Gpk29Yz)_0Ln7 z#e1fp0gpz!C-zwnbc^)Y1LwOy$kcTK`nSXPg~8IqBW{N2*f)h6y(f<9zfR1SFL#_( zj)>k{O}ta)oOM!Gf*pviJ;Qw?ZPp&ED)($o`TufISr;EjYpC(v7%T6?Kb;a90MftV z3OAzy7n&AIn;vc^789w-#9kt%^JOfj>Y9kM+21^>;}LBldr;VL9KtX3ei&l<0nST0 zcgs_s{i5m;iN;YMa(+nSR814Hd^0;CW{(e?Jj6`l)KV7j=4RImm{ku4c6<wUCz(k+ zb{)wKo{l=Xud`GL%5qdW-fu$U^IhC9(+`WViQDD86Q4g@oz{704SeIv7>35Y8++GY z-TFvR*dSs(^Uaf@90Vd;q_Tkaq*z_qG;^N5w<zG9RYG&EzBZnD{l6`)^Sn^l*V^+- z0}5{NO!P2dX1kRUrDyYLtV3{8#x&q`3816(HY|p;CJo<=>)WVzB6(mWDp5PWJNb%1 zia^AWI4?TDn@klMmNn|kBi1f|dQ1OkFS=Pf$8YG>c&24T3KgWQ)G<SSsz2>>ZJN|6 z&L2AIwEOK`?8I*^f`Y=wv)T@(9uUBpp``RMRY_@E7dn*VPt-cyDMk72?{raV=vA3L zz&P&vY|r@`agHOmGGBfM@VDc_JUC@(iRDQo9SZeqQj2kZnzY?|XD{%me_;P$U&eN= z@*oB9AOiMSPBNNEWYGl^6J#gFckkXwyKc84e_d0v%(*yENlWgxX^E-I!^=HPlTOb| zIf|}+^l9&glQ-zdU5CYhzh4^44(9yl)2DBLiq6NKHEz$}O`?wNy?Z>p%xd*0ccXIP zOR5BZy}G2|j}QqF@92P?3L?ZeQYb}E`=ME_gH<08c1`yu$(yICy~kv!_AeQTZGSQH zL3P3`eio>EI@KT|$o>wTJ!z=%yagJ0dnZJ6(EcFTbSo=~%lX3t+Wj`}Xvfo~gr&im z{&c3}jdcS><5=kF)Se4Z<JstEW}u_?m7))$Sq#!&n%|CpO{ARZ4Ku9sa)wRJ;|=R` z<YBOtyunhZaa5og$CdCGEMHy?7MgcrIK<t$uw;%`{!Y;o#CwB3)RSE@y&3+ZGg%%s zl5zYqC1cA(H-CFu@~me-8Afh-Nq#!#Tln;K(>ahNiQXbu`m|S6koSZT>BH(v==$;l z$)&2Q+9kd8O`8Gvc2E+^BR;z7Ch2@1|7zuPBzsGsY0cf;?YYJ=;pQWOIdp%g^^7m+ z3-%tyyH5?d>5JPrf9oD73=uXvT%TsDc{lfQrEU)=PF&j?0GoLQSnNI!mPOU^6TR(; zB}|rTPDA(ehrf^H4K5&!omYR&4?gle+@vE}bY~xJ;Q}!$4Nl9SX1q@0I5-1$lOpxZ zJd|^Cm$0N(Eqw&G!DGar%I5X(E)(i*(?LgVVjx3PT|3dekh`PtiJg%=VXKbC)b^p{ zzDi%sTO#*j$sB>>$-%HT;kKtSW~!|0A+~BYdV6P~L%hMf3uP!kbe0=7TIh5Ly;{1k zXENIpf6gW`U#>VAa6HZ%<4-dC=GiZ?ye_?*>dG*p@q)j1tO4TIkE}Gu1&|!f8DS0L z!dqjYXxW;%PbF#5wdK8+zc{Ki?7ccA9?;%k#4mA4mkl`A{$f2`XXKWSng@e-U!jU+ zhQ~VlZEZ3bM%&c=-Pe!uUOx|MG@9SIkHpZyEL{F9>A1fO&BzVw!jm~xV|;rDM9Bmy zpak;S`mVgJ&InT8OAiF%{?)r9PP4wc#kE~wg3G)-X_FDcxh0&B1d2ymoUA()M<bub z#tXU%H?9o%BXg&!8XPUWG$XF4sUqC_kLG*Cgrj}4=Jd=0l54#;wqg$09}7q?MO2EO zd-okQoIAfjw(?9qzy4UvhVrid<F_kcLdd6_O7%)0<9B-1J`^OwW$KGP%mHTB+SV&w z@eU2Ifx=Uzx*f^3&fOeZ@a}Y;)_~ZpgLUmts}BjCYGZ!B-E_Vx2DQJ8kGTB)wBx{& zn?@nopG#+I`C8BspgGV)k!>rA(rlvIQTN>hAC|#$WlC_XZ~!W0H91-g_wYpK9(p~H z<mp&#ZuItV*@?yl$Zkxw&iG5^o_=<>e{RZl`o_ifcjnjA!2)l_&Ob8s9J1g1y=Efv z%{){zG#FS(Lwk{%4a?1Gg303Bb!kvRlHhK0!<Nl!Q?rM!UX9XnXN=FvHu<OE031s> znX5`%Nep#D#SJfHr%N!g{&DNvZZH&1JXNz$Qo5SXelRp4#4&j@cfcN-X)71a7(K9o z3H<e&72Pbm8Lp8F+muQi_c?=9>Nb=v>}zZEN}LWeV(L)VFAqiZfdb@XZ&3^B3+A~8 z6$4E4y;Ksh9`2f~Y7zX_^-{6@)5B4<eWPKU=3JYqf?2O^^Z8ICe}Tf#ErFc%PX6%2 zmM`oj{STveaYmJX$HJCskPnH`Grrd5wrIG!tu0#BZnGlCx02pzk`)el##Q^kA;H@# z*>OlaAuf}MGB+Ey;IwpTojlEtx+HdY@eS#1vu1iu0hg$zPH|#vquE9l$ewwGp0zGX zX$FZL4r$fecyu<bU*~<y^HW2D;S6;zvpY5=#q4HT-Mj52s-CMiPt`g-1owp3{dI%; zsg3UPvQV-XkY=(f&zyJfVDSEvLo!$TyKgX>=oxuR*LW@V<@6af7L@7?>7jFY>ZjSH zSNNklw-;kI_=PlOf%1C?e%Oxm2#O!HR)N}XAwC%&5;)x$Zq|uznLV8SnmG`h6gV=W z#x%hT&U{oml+FPZ=JQ5t)zI(l9P*4wtWQ<s+X3aX?5T58-Xh7w#~ugZa<010ZLy-y z3ncF(5`qwjJRVw|zRc0XPix$8Y^R2Pb!)PG^<P`sEg{!j%%KnCpHSuMrj(B@Q^(L( zO9dmQkfrY5LD#w1-P?S568Gm8`NYaR5qbOqW@oO0!f`21syki~J<G9re_t)KJ3_KQ z{-W2^-v4k78SPBMaMXMB32#MJJ*6&XG)!%|ga7-3#*&<l?$n;+$DJQcFQ|9W^TF-h zRs9kRZqek8**?zw{n&=((;7G1wiXH3H@mbnYNV#=4k8_Uc#v#v>QrU#KXZJ!`@PAB ztKanZh$JqSb~ni!Ce-umG0-NuSG7$)4oyIHnsAh`!zp-|foyAxYvc;lF12d-8wIeE z0{WC3NY%s5_rT!HU(`ThvG08<4MCmF#Mi)1PHw*(mS`1)I9dAjd;QDt9&S`wUESkQ z=DdhMf9}=G`R0Q|c6mr?l^vD`d2;U~CR#<8S#gWK%4X9!Tg~8h)U&sSsFK>VWswcT z<3{?01T)=4$xNHc693nex@s!Lt|LEM%j<abzs0$01{hQeRrq3}ObO>DCQ{+3@G5&u zbMMkbwe1$rf%gE989ne|hry;bM`q*~Uy=zYLGO{_Lc3m&;mZB@6P@K-cSGnnhPt96 zB>Jz!pOI}l!4G=qu9ik|a4pA=Iv5z*b%)(RN3)8%A@WIR?5O@DR0c9JMh&o?DPQ7~ zTOtHuFqqEk4>Zih6~X_+daocp>Sfh_$^<?CDU!e1&F&2QuwdKvg|~cgX#i;4Qhcu` zuo(aDW|v5(XWx$HH)U^nE6dNxl9HR1ON+PZkNr>U>tlH|RFh8+^yIl;OL9!U4uo?Q zecf=zEREH8Yq@j#vyCjc@pnY9n;2U!M~L<x9%s(jGfrzvG&-AWb*4OiPq*gFX$y}} zZS}73U*M9TVO$e))Uo^CWiwT)?EKKqh<NzU?4x`V)gepZ(_}G+msXmE1}^A%AgP@# zO2+{@2KtZifzf2r4)f2*>c>N<Z^TWd9;fZoyg%25qn4l-U}1^O6qyw_k@GX>rUoNO zTido=!e6*N(RQJ|^)r1Pzo6LC<A6tqj~b2v<U>ebp^ZeK7*>RTU|RF2Mo|c28<nwk z7vk`~Yg<yf9;TCjiAlg`fH|sBAGWDGLWA8=g2g=$5GYz7c2Ol`9Dec!fw*+Xe5N^b zuZO5i*M05Lk=-t7iziXhHararbUc8TqP#I9ddA5H@CN@E1fevQl*7}^r9z+dse^a6 zXceME-)BS!r*HPLHJ5q>B=(K@!v1I=wgR1E>AFW_G2RW2;Zi%hZ+p@soERP|&;4<e z>+ESTP05zj7x?YA&?unA+}KSHCT(e%2c$0=t$nVpuHnnkQDGkOb!jVk^Q#gP<7eT| zZh-2_KV<j<71+oi$xz{(?DXSGt7Sv;v%5)Et_6myNiTgSm*EA56}5*C+3!F4kj=Gm z|NerUk<_XMi1m9x#$MtLN*2cZY-hh@6i0HjG@@a^O82%1&3j1+=we++rgXE?WLf0d zUgg&)sX-!HEo@_>pOS`!fz=07&>hYA@OfA0j5O&fY7OgbZ|6ObUG6Q)iHtq-Nbt-x zH(V-Q8+s+7gv5HOJ=oiR+?T!WiwhP>QGZhM+|;%Qbuh6)#Ld|zQ>R9H9YKxGoL@jn zgW#JLuJkOJ+&o53Q{2jZ!s_O4E~lHoaN-4n8+!*-EMTx5H!~!#svp3y^s~yOycZh| z4_9~@CL6nDQ+(bp=i3c#d4ZA`eqE05{X!x7DD*cN7zJP6Uk=xS%eO7g`S%RVGJ{-m z`?Yg`(nRsZpNSt8_}?p<L^@k6Z+Be>fwW@A62~%Qc*Z5h1Dd{{mrj1RJn>wApg3je z{{&(t{&qsw8kZ`u1C(~o$T9Ofd2Jkfg)TY5_aLqq?)><K!_RIqUt4aAmdH`Nf%|6C z>29a@!*#x9V?wI5j`$gCeXwpi$M~4A?@f7pY{@L{nZXHYL$%+Rsi&3AZ!9h?B^-PI z>FarrzKI7wQUM5~mSi-Qa<VqIV>N7R#IEEs!*stTBQV?}tV@TC!a<N5c)Cm)>I+`3 zc>TEzEi5^fJp^HqxD~Wi)Y6tRq3a@=?`BS}TA^(nBCja+#w;e^OvltvQk&vWb`3XR zH46hyedM!z9vyDx?`N;MbGKHjbc!FFNY;$I67zE{)BK6bY4HMv-&Wq;bflxD-Bh)V zmf3seld<Q^^|18$WhK=jy|Eli?NV(5UGpK4f-vRoRPXJ7UrNet`s3DoM>H4qT`ST3 zHPSdx9v@^t_53`|r*e7mXerN3xaLW<v4;fT4DimGG@>J;cK8sCpdCHUg2vf59v<pD z`*|)e7eFAmdCBeBdlYAVSW}IIGGElBH7*ZK^DJlji!%4}pTo3<?UtUbu-p?;)SS)4 z(N@BEuOtG&Z}h!nqNc*L?bn9Edf94+slb+Y`Kw)FIF{}e<m}ps#Ixr~)Sup?nWs%0 zg^M;0tj5K@0Eg>@)Xq_VNNda5tBr0ZAQ(UcGR?L7D9)QPCV@Qv-t$P!B+IsPxzp6` z_qf6DsRTN9G5&`RB`dqm<vYQfJp{>x#q|eNX7Pi|Ez=yxA`>I)wo^|Cw7OF{#4kT( z@r?qrnBz!yxhp!S>{QA#j&*;s&Q;Nw5@+>C&A;GzvZiqPla)#b-$9=j9CX!!{=PdN z$>PdZP1@jse42Iln6F|)!?EQ{Mx}Y#6o<=7|JpkXFOE_?UD8vKJtIi#`{gzMb7qF< zK3M>(l+*pY^xuS1m-nLwBp*O!WMnMXioBiSbqC_blT4Hvy2S<@aQ0|Y`Gye=O6XO= z8M7J~P%V}7DpuVO<Qu5>IIWx>{Ct3a26;PSYWHh}Fr&v}k{A&giC&PbCh#4N<Y_I; z$LQcOr4RNlEfXX0YxSl`+sTp^IdO32KS->2sePzby&bEd7F+{Gv9KZP+QtZMuwcpp ztC-F=%`ly~o7Dot<IFi9r`PT)^{f2;AK60X*PjAt{{3+#0382l^v#<$kF>xAWr zl`s{emHMrR5A8daGur!4<|`BV%=*LF-3E_kxq@Of*1WrlS{u(i&OVOS6bqdjRg5>0 z7(Sl>XylW(|Aa(Sg+GV<C=f=U2R#c9FuX-ORb5%-%_3-c3-99(to17gc_QG<tnFC3 zYiUk)QiW@5l?8xjlWM0Y(eMrKSvD{^c6@R0YV~p{z?iJo7?P@7mSolxJ1S#C5q2?o z^>ZP;(*a_~3$=P3s15hCK`}feBv8!Nw1}nBXCLqMAghn0#zu;#FV3ms-f+aEt=>9a z+hgiBA3|x&oR(l>b58~qL{3(7+XqW9EXIFPsolYWn1_5n%B)LW!#6)>oQ?B3qe{ka zZQ9E2oka{l1&PL~0h`_ufC9jZO%hlm)0HGk$MrN}uyAOX7g-QlV*R_Vgo>Hmi5NxH zPOKbo^GxlpKo{e91m*Z*+<NG1lKXU=k9H5QLeta}2<rRrpe()OosKiYDbYH^6IWh1 zT2x{bQ=@wJMxl{anURB|xXCx|02%YRaMY28C1w*hSZ;(|u-gS~`A)Bf2;F*EX0zYd zm?WCnw*of9I0Hvx2$iX~dycn*!mUVO-#4dU_fE>*$qi!v>6@r_J;6^DK9Vk8{z#tS z_U?c*?1VcPy#C~_rT(A|I2RpC;;Khk{uu~8K5nMkvbW7)=R@YiNfLo=TCY8lL?&A; zmd4ok9ZUw9oE^j$)R!y@g>^xD{cjw0ZXMtG2e6A_G)ioe1=Fx>==%T<-gyr1#=2PG z(~^nXq!6`C$S0{L+qIL^LUaCll?_A4gGA(PCp=d6%q-}hN&=6x-$2@*jDRD#EJt3C z0f*r{=Kz?6#T}h{5D3JgGiqZFRiw{Z=hD7gCYNBAgf90dwWg0ImD?-s#|}i;ZJwp0 z^S{Q%a@1S)<a9-!L&_cX^*N*u+t5<UV#+SVhYX7<15IVCQ70eiMRWZ*WN}L|f>Kou z)io-)hu+Oa3)KmV=Yvo3<#wmWE7usBR_k?Xm-`(57QiQ`zWlw8t@PD9T4dnupl@*X z!X02tkb-xFCJG1O$`}*bSAn=`XQ0kY#^@rRFLs`IFtF}2q|9rrsMz_WqLLw4(DX!m z9|=^L+43BG-x%Nz1RD=`$w@NB%NfXPwn;jrraPV~6eI!*%Cv4h*T-{)^wjzKZg#A? z?7Jn)1g~q3AQ0t;LNaNmAQ-4d0!mg}`7H;FJM_82@DH%G;5UQhbwJ_dZ!3D}zLu5I zn5kYIQ3ZP^{dIH&cILddfyQLiozP~cU!zGgLJ>(4zE&Uer9`dIrp6-nH(onCm$R9m znzK|A78uMtHt3{y)mUpw)p~L$e->};Y49i}hmd@M%S?P%X0)C(mt357J`ZXrz3q2A z&1n*SpmWqPy6UBhKao1~pUFuAJX+l3cx6in)?X3tl&fa4paOmDn5cg=v64{pcBT&E zKV`(o)}Jg^J>5dN$LPYatklG#M#Jg9R@avgIp50*5(4}VR@}~E8{dH}>CKB%hFrhf zmDc#tvMYTlQtD5B`1XHd;Bji0Ta)7qf(eB)pWh;o!k9SGW8(vAJJ!odF~Y=~kGa7G zFAD57J8tuU2`OgFJlwr2A`80NKXbkvLR|RY8<5fH9C&gHTp*SESHioj3+mb5dnals zME%vY61@us)99+<?=hYDjMm06Iiwq$*?1NcBxD$pLP~oMq_!di;3hs*lMqP`H2(}2 z-tfY)W->Y4q1qaE<YY3L#++^Ior^i7>Kq-NV=G&w{Y*Rn1M1^HH+1<^H!V#Z&L)Z$ zr1kLS$Xl|dGkT!bqV#*fR4g)FW4<sIBd<WOU)x~6?`To^ArJ_=OQ3P8**kC!`~(L` z0^L0Iy<qjjL|<6VbC_yh=HZd3*S^Wmi?bAA_xMUU@Z)0S)gU}I)NK32oSDf8WL|gP zpK1<z7}LC};#=;-OT(&-UjJaEVpzI8NJSq)5mIr^Ps_$=!t(lcdLX>59rl6s6F&xn zw!UX&X&Fqcj~N>qYdQ1ppV8~{NGM=UhXJ7NVrV(MR+!}3v0>CwtFpzbUkjW~r`a0M z%T>&DD9kx|tCLx3)oWAXi8<_2&{8jjR6O9ltQ?t)d!!GGi~JWQ{(D>s(vtyQ&Z6@Q zvOcf7Hv0GTS<3?Re~Cx)@d<1z&@vimaPo}vNx`N6Cg<PFmV<urk&Pm{-jIc04}k`1 zt1mwUXu_NL-k)MRWu53=v0uzUvU%CRQvrOl3m+#_r~Er1Ykc`B11axn#zlD~=J%B^ zlBSGcZ@LYF^F3p(&R!$y95+;)+0j<jX}AY*(ERqIANzm7&df1^1BmQ8b4Q<A#PeoO z0KG8&Hwu^(qFD(;Wj~%rQN5FW-*tl|z_d<L{Ogf5g;!fE>CL1^GXwrc%E!%inyMg# z-50<iS{l9m=mU5ZaH=(K34k*~m7bH87}2%R&^8HoDO4LNIP%QO^EE3tQ(vWBC<Smh zFm_7;k30hSA_u=wz}+R!v)4u^y&upfn=Wb*5*B>2r1H1h?@k8oYyjK@pX&j<8#<BA zjnD(9hMi<xE2rl41MEchC;iSW4cTeG<J}DWXXcxq9@}Ci180Brh&pQ2*?PWJ)!C7s z7Pjt<^e3EB(_KVxeP;SiUel#O9(ZjxQz1<~M=Ysc;8|TGy;|D-grai-lWKtgbl!y# z38nj*+Gm9P)4;vazY#=rIIv$eRZyMMBIRl0pzvpYjyHXB=O~EqmhgB+Egy;W!B-C+ z>{y>+ex~D+jyGBo8F){HZCAg_i?B{2F`<zve-nuZG?MO;Ld*Mssc{l3^8r*h7~ja4 z_Vx?kZ!_ZZ(+M0cvONem^S1pay8O;2cC>i6Uph<As#^`R;fSuVl~X$p1Z@|VgNLsD zYA35Fe<*iVbXYPwwOv(q*0nG%bl)?djMKdd-(^Low%ZQ`a}MpAtDB}_E^lu5#{Ii& z_=5|Q4d)uRm))r`JcosAIR3RAq{Ela_Q!9c=nNw%ww)z<QfPIl$cywwrn;Sk06Xj% z931S08_xy!CF|(=5))+&jcDVFS8}_J-ZO0)Nk=I6K`r+*g6yt-<#LAKI>I=ZM6mpX zI%&y^w@!D){fO^llX&6Lj&o>eDM76gJ!bk+SvSrCbVq;x?PG^1I1o<>;#d7$7iPnK ze6QU)Zru*yvOhdw<c{hsPfT|_qcZ`nwb)RKiXZbLBJG9iXV;6qrWjScabN7?gVdOm z+YExTq98y+1wv<?D?VU*^ysrjgr6mvPS2zs#dEHBRUdF_-jFw5o0Sy)_*_xI@b{hR zMd*buW1qso%&{af$Ojs^nq)9d`N=#h>-vqCgS{Mp-Gaf$E89)2^Qvg|?~Q*S27TZ| zejm94PwR}P0B{eQR#+w>^%i>w12nC^*><6W(g=-iHDf2dh`q>MBp)oXh;W;6qMu0e z<ovxHMl_Lpg71D%f<+g|hc`B{l3I8g_Y|^(dHrt^x&k@v&-#zb18X4<mfw{admLDH z3Zz3(_piFE&jgHPO!rE$8<REtSR_>RZAXzUwNpeu{_pAplPPh>iPY+*fmQFW87hz6 z1knYP51I5P4LGwvY+pk(e&`;rI8V+t;Q+rTWY+u`S6C{mv0b$;TsW#|EV42m1@K!K zA^{L??^tiS#m7tNwM$P;McM4kCqkxgqixX1V(yOhhZW)njMl!_#7AzDQ!|GuaftF? z`}IdLhB5IH4DLxW<`Dgp`|)ssKG%o>PjM=%pbm3vX8&Z2qE5AJs&sqd#?L7)j(PK} zro>ppNt-()fqx(u!5@jv--HzI<cMXmDZz~>|CnNJGFYf;foa#F=u49o^uevyp)zLh z0_;T+cXDTrmu~|>`SdhQi7~6}&IW{Sa}p`MSktgME_xWeTvJPUdOmH<wVqZ^IEtS3 zE}V|#=A4-*QhvF!lF6&sJlw`~zy1*S&EF}SofJYkm?!rikhrCXbX=*_kV!w<@^y5o zKG`3s1(bIGaREBzQJ;f@iPb@<bfUb>UTSLUdg@{OzF4u*V<B}`&qJus;%tVVW#jg~ zwh{d@?sTKUb&Vt6LG^pr<s_bSr|t=%&YC_~H7P=`c10<Q*c}lr)Rfn{%M}>mw*n;o z4rK^bC?r(>!pCwTQ!g*=6U1v!tdRes4u9V0HQbver}I3C_?)NM*dUr1vm<>1gEfor z9;w6KZ!WS7zn%fX>4A83=LxjZU5;kF52j<FbHG8;Z&&95g9D{5GHPcuH&6Kh94Fzm z4QIuL(BUz`9gw%PUT68dHStq!UTK=CUT>n;8ylsM&wz-FC(SaBr7Lj8r#P?1A1z+Y zAsl_XZXEsVqa(JS87^|}usVcLHd7@$X<4>eAFpg!k#g<<08>3x*wjemHO$w8FxgWd zk5pCzOH(Lmm^KAVAuq)9@NkxbyC#WCPssGPh=2dbv1H=hH66D4$G&>g!axKPpAnz@ zmGisDunqXlXO~oqppU^GHxvFe*nD(&ph~|uXx`zU3dAU-?uM>hbuJ&QHSbbe^636u z^j7s~_PGbA7TNyFC|}^8T{xPSHch#Kz?sJdhdhEje%xmMLmga@*z(L8aeNNfUwLfi zn0v4?8hYM|u%iaqGJNNK??HBBLo9-htoh}L`^oL=AT4*-Ir)Umz2QZ54k;E4SM5s6 z2a=j*JKB$$I#gaRv3RluRy$1!7#z@Q5O?AW6S>CeH`4s|_pJo9IzDN`M<(!hV{M_( zM&PduET&c~HnZlm!a^B4z84rKONfZA>@lNBJnpN?1Sv-v*1Ws60yv|#dug7BtL^zf z!)lWouCKQ$?JW4~pHhZ@-Pr5Ab`xH3eyLUk9(}YOrev*cfA!Z-AUH{_p`zwp3Ml+R z9CVBZQCEcnzdx&G*}JawlMR30ZC~2$e#62<q|xNvdmYwoFh$FdPgjL)7&$0&wV%^l zF2lC42?kK8@cEalzW~s%U)Rn|)_@T&d9~&A5iGtTPOi>E3nZH=q+n+P7Q?@$j|_z1 z*!ey`U`vv!9MIwzw0dV}CsTB~6S}6U(_7Px?tbHnFYd?lkg&>tV$;f;68r%*wm!iy zJWsx|BdVr&@(JXmT*P8yV#Hk~r8M&jL%rWtU}y77=mY%sedu{_l)o_RH}6q{Wh>Ju z<iMG@V2b1mBOqD=Wr^f}L@o?k-R#2=*0FGN;m<%Av8r!6jd8BMQAe(T7?gVtegFZn zQp`G&EmOR@z(aX#YlFq;{(C)obi(g$Mm%t19-S$#{BEj*czo?u!RyTAmQ^>qbl}N5 zSKT%#A5NVFE)3o)7>6xdrchHZ4eQB{d{ew019XJVMM=rSdX;kSkX^a7GT&OwNH^;a zG^VF<(Q?Q8H0D3NyI5Kp9TOAtbK2|vp>P&@Rp5->`yZgL&P<vD9h;Bp`4zqT!Zshu zBMJ~JtMBO<vOuFW@V1Xb3ss7Oj6`OgaxP&!gmIy7Vf8azN=AU`R#3vV#<yGW1XHi? z7GaGXQl3Y*kN))Z6_(E+Dco;}Fg_(c+8qATy&RSo&n5`$@XT3EmQn7KN_=Vk#Ht&8 zw<nH3b-lG!VUY#b-&IPkx(dvLf(M^g9}igL(k&|rAzX5N{>(Ph`wa5+>a8RJ4hV%( zMVg2ztO9-@7w8^^NOh<vBg@<J3Fndl+y?r)Z4FQZaNJ(5Ll>Q%^|kuEnGeyj$C=Xv zs2>aR)mh`110ECN|7hpbYtO6D3AIj`@v$~RcPO`W=hM*8gt4KUtOusbv&?2@`#jco zM+?i{RVjcVIpr^uYCRORnp4n2F&xDW)cP;paTR$_E-qYNZU8qrt}RLT;2Nm1CG3*F zE$2;f%3I6n#-==)9G#f{Y2nA3=W#ubha1AUohW}G965jEI&((~4uROV{?%pN#aU-@ zT(C^u=CUt7s3jWgP^q7V06q|7Pd;T$A)gV&DcT?L&@eGRc^4Tj2V_UizvNq9<Z`9R zu3dUpiYU?@Aw<_y!WQkw7}u-WTu*1i0qavtUN*V$Sp%5x?}N<_q}Gy}lg2mRRjhLh z`3^}`48iN;^<q<vj+o}w*92RUL9O=XDTxr*7m;@zRAz3NP6t5pGBguCdJcU1T2C5x zku%&p8pQhnYZx=gvB$*l%J2`Q`_WM#qh4J%|Ls6OOe!#~og0(Q+|qYsOSThh`cyc8 zklN+N7lnLR_`rN*(^t0Z5XMCX4=#<*fOjKgB=$S&iIe|CkU}OGp{frv<j9cWO34My z3(*_igPgAOzMN!xsP9RFL$;rLWPTJ}W7hgB;V_3?61R0Ig~X&L-gI-|1=HO1eJvGB z^#OtC;w6l4Z9((bW-FLgRn$ZR?O6b?Qs8<_u=u?+gR{IKc{0w*nMt*^GxY+Wv2aUZ z%U!a1dcMaXZa3cY+U_iZgY<F%D02B)<C*dPjAL!Gthv?tCbl8GB#wd2YaE0`Ae9_f zY(@*<b3owiS%SdXol$hNz=^FqHp$Fy)7j7<YHRAw)=_`-`gFa$=kU-y=*am=>>qdJ z78}QCf%igY%EOW-T!)M{H0cJRGY9&N(`)hEQ2lte>7e=;ee=tS57;HANd+fC)<-VD z9HR_&sYL9HqkDXHo>jhJ4i~UCex9T-#;E41H+0R2y=xsW>~SZS)9NFj|GKfJh+90! zAS<ciPP-<mdKSt*A^Wc*2(+8Bvzio}>^$r%AL#2&8Zi2EDA{uJO4vp02XU=53xai< z<V5Sl?rxNjHtpx!)@BTw{o1=TubHMbcn$#ZL`td`>d=ke%F5ooi(ppn!0{Pkcx_yw z&V}IbStC>^HBEf=;*FJVO{acmGljt&=;{9RLCMJ)`>nSVwQ@T)*aue*rT$i8>LhU0 z%5cwf1aGWN^-P!KH^$wm2McV>%%f9_6d$_h9%ItUeixH1{5+hC?7lxyJ23jv@Qs4h z`0MGwqxu`5RddJn>ih>+^4Bnqv0IEF#wR{wS7N7c#yG*nvf3o4i=WEmy1`{I=*w_1 zN=Y=V?Q&ahU=jOUGW?^9EUM>GeFp5zYN$JD@R_B^>S`mayADSZ6lO3kVTzO%m!!F4 ziu(w-eZXFMR5yeqvVC_RAv@F~V%|2Cq)8hCCy0sklaqdqN-H%red)jeEV45)ALWk6 zA?!<=Uwcl9JM7Y1SbbK{kf@%<mo|R81p@sL1`xcqzW&P0;X2XYaZF|vi&WDU%KkYu zwu$@Ux%p&cQM=-HaPTgX-JIRg1S!;V*`2vRiDN0>D4qQ{V=-4j`tNR4r7y>m{7$|Q zRiDPA+OZb8z!T8U?gQ>vJwYSgeWcGUlin6}=^o~=uey4tG-}4nbjFmUZza!~%QtW5 zWDD0u$L2RO&Dh}4BkT7BVsXmF4o(m-xJf!qb-E#5WX9sM?0{USKP3qbU;Q9(q_xX$ z{j}7lU~OR&8jjEq3!9R*HH*3ry6@t!3<8OK_)bgKmU7a;IW$vE_V;(^M*MBo14x0L zx`p24_Yn^ux%;h0eBhDRQvmuc<-|!P?*z#8Uk<yVl;9O|{sYnWjv@cXDBx*WalEoM z7jo>6?ADI93Wod%<x_J`Umy)*ucv-hL2&QZ-gZ}S#-i(`ngT{R<R!0KYSkezrNoJV z?M)i2M4j<>NKdi<Ei!Oj4mY2f8Y88qbK0|+jFF0pe7OSrmR--ivv)26_FT30HamIP z&vfi-4;H4UAG(fK`TV2|zsA@#UKU_7PjZUV*nfOlZ}fScH1Pa9!F2cZ0{fDzh{!@G z6&2ftSBDTST2z`jr=WCkYlLdSAA%zlQ14s+eT`8*ESvj1<3?VlUeDO5wz$59F*le{ zXt#4D4wq@5Nw!~;Z@N1B29%#wP+jlEqU9c&1Sj6lzSKFhwteH@FwJWGSc-TbVS%}z z{%2$JjhJ|=fRtm4@(kkP^Av?<;r9(*jfjGbsgq0DP6XM2M*roKM}db5F6b*fOt+wd zBe0jJS8(+reswP9m*h*9KEivfB5%9qs2hpCo?mP$&GnC|Jz4(wf5`e0cqqRw?q{r( ztwBVgMj?^xvQ~yHA<G~;p|WS+4U#F_PepbT;<1x`8*OBl#=d3EPD1wgj{5!o|Mz|G z=hHgo-uv8p&bjA&zvtYC=<w0neia!Qc!$ZYHJ4xMm;IeSYSr84x49PDQ{ygkemD5( zipZY*c1d<HrI0+Un4_*!Q&CO1=_BQ_+YEfX_5+=7eXC}Mw$~^9_tthR#{x_-9<v?E z=GMDS?#mND+`r~fQW|^TRcu)AXy&!w1_?D&or%|6HZnTjHfbcTVJ5z2$|<ajROhRs zU0-rl*v0f!srDtMyiN9Z>Qe9%l8Fe1FMZ@!yy39ejM8JRZifw)l{f**`Z$HWNCnec z%c+cRGo|gj`s{^{n=)pr0XH>xemMd|*lJJ=D7ZIN%<ZabQnq;iQ2d|l$G`l19<?PU zhK-6`T4-T=suN*pZN(hLSM9ud?qk!zzT$C)b30By84EpNUPX?oio`d`INpMur`%>6 zovmsrcLNC004^u81~CxVAilE@+R2?S{~F7L6h86Al77zORh0ooP7>50<V-RTY>ei@ zo$IG{<!aTnYV7;pv3=mEe5<l+_N|AryByP__4bvWw%58|*)v~egA!kiJfzLZiHfuz zEB{oDTa~00VB$oHdu@}OFNoPaOig@sUnqKG0XRPnQ3|Qq@70T_95yV-<tpoBUx#n= zhT!%-P&~VRqqt6b3f=gD?Ah(E=@q(_P#(Y|A(7D@I)v~acWv&A1tt(sLM^_IOwkiH zuhAL#UL1HwF{|X`jQkt7(vAgWMsh%A5miVGTJf1uj)x}k+uPdbK&lYBY0&RyR!NI@ zMPE~_plJwBi4JOtH(!Lk(b4Ki!E66;_j8PCVP^7BFongNH_sGTJX_l|j$j6pDn>ks zVGU19R^Vk7a&A<?yQKnYjRG6;8O3hZJwhGoXRKe<XA|z<6*=qtD3{w`P6+6l3k{Eb z{GbNDf2z?eI-u&=o!ErKt_UB&{1zUQhff?57}{Scd>lSsMvATCgd^&-TjD6jU;os# zd~)ZNV0?)9Q&>p}ceVY@ks@8ZL&)FEYF&dUV*77ahVuKLFvG##rb!vT;{Dw!PCjBR zH+Fs((E=1UsJSF^{~rb>O`G7G$sxGT!`#sTYftJE@+}3S&tE1!ja-;ry~+?hMy>!L z7kbEu;%~6^w3`AlMZ{&mltF1Z(@%?g*6ZT>>LmT_F20-QhB%?5<7svL&mS)P587+k z$lbxLgr)ukV+m$rt1daXI7XMg0b9nIUDu!yTbGClRcIx5-ZADI!^E^tN)eB!=0Dd? zvqbH6Ra=Si<`y_^#NAa5!tttJ4^{xtrIQ@Oj0e(axYk~@K!vE~LA^mpr^DpzGgM3k zeyd#hhABe}C5JXTSlEGbH7>OmV-t8yYMy6cZ0Qe5i8?`c=2*2Hl<3e-st%SskiH09 zwl-`=s-U)LxB%sm6!qADQ<I0d5fT*mI;h}ObSP$H3A>>`AcXjK*$U^aEa)Jo7pkfK z>4-tvob|kwB2JofgvS9_LIkdkPnJLGmw3IZk=X*s;{IwKw{;G)Umw1$L3;I5q}g^M zZt)I*1v6w*Xjj&lP9|XOFumz*3k@0lmm)cRSdj9!Q{o@6N}3{*@x4?wXa}C}v}(_T z<@&q%!fr2#*Z5wg2y1K3p0vkjOWUjR>Dgz`I~eXZll?sV`t^B24w0Vx(+FDG>&^4b z;ErBi7jYGJ0Y`t0=ZRw10a@&ChO?;z0ju|*rb15(6=PN0HhRhyB8B$es2I%EOhW}^ zUBh7)HC%k^r1jnLXHXVjNyUmvpPXWn46bSX+x?AYLh<BeRCx#>N8+VB(4vOE2d_Cd zS3+Lh+J4ti-{BbU?R^2f6`)0fNt1>dydLr1Zf#rBw10VHx?)ThSHN$2yf8HQROuaT z?PKs3m$b}eH$ZEq{Liw+LoI~#e8Nm~$C?-U-@$&p0xaxeg?O*-OOX9TmM12P)I8<f zua-mdK9c)qa!<~L`>5ux0Ny*?$b#2AuVt^yCdl!GmSoTKA_Woo3=lQ>s?nuV+3`*9 zbeO&Ui`ltw@~dAQJlyqNb&4ofvME}d+sQU#8Uobl=Q%Gto~1b&R)>GJ6}-4?YDT?E z=^5X?R*pP5<<Em1!t;}_kG&`nP*`rKX-v#T1#e%E`;Pew@jRt2)ILdOkAij2(%xcQ z4`}{u@azd61<0jQ?0F{;{jB{=!M2Bv-;27<lhBJRD}u<oIdIPiGh;Lo+8N-WBk>gT z^a$bcOfFw_C>$(bfBzI05k3(O=pW#qnQcWfFNKxltZ0y(bXYldz<8Z0>Wb!)C5b{r zI#uiN)>K>qK~$#Nt;Mv&mr$twmg~Ot^v92%(Sl3J=%}_swzs7`!h?k~hm0hr`4T9{ zPeXO+DLYKE;V22pnHKA^^t4MlKwJrZ+n};<c+|O}diXk;>y?orhSJB=5ytV6cd=o; zWJvKSi0kYa<#oNjJjek<s5=;a#fukl{ku{A8L+r_jTkb=(NVXK4POjh(ILorO5?Jb zw!1a;`-RudbYF1MFl;?}@}wwRGWylepH%OK=&V0UouFz@OX4t61$e<PF|6U@>O8og zSP`@T?p?gX6g`OU_H0ad4MngwGV_Gt@P{ekMH^usDR4V4<C@TmPjcpO#T0R10w4b1 zImi0xq8SL3T1Va~YtAk;6SHH$;>{~!grVV!C@H%oOBefTMojy3<ArpC2`bF&bR@~G zwsJNfR`J_#h4=;Z>8mK-;GUfGp(QTqTg$C^D?Cn?Ig%9v5{l8p6rv4Eq!%6D4YEMo zW{RGMWD#a5!i#yyh+%76sER~kC2=}<J1uu!59KV0O(dGfOOWtO+b}iFEpNB_$y)$; zy-LT>?D81YsMKrfTz(u9a{iiN&Ytl`dMweT6N!?mUrl^|kenmOw@PQDb<O~|?BVS5 z>D(vG5+^>hN&FL^6yugH3YlbF;7#nA`zC$s^}VQ`IT4o5Cy9ru1s6#~OOCl)YLZrH zijORQV9+}yrhPa&)AAr3cKCV!yfS8=9lv#8V0sl9{baMB#XKa0dhqBd1$==h27`=0 zF-{BV5wm>Dl%pJyV+HQk&(D*DP9A_?Xm(#z;n@;WgDm2l-t3YfsF-qKmWMqW=-d7y zyO7AGdz<Oz1X!~AM50nANUr|V(#MNh%hTDSD3JuQ8H+8j)>`h%gAA1Cf;gabp=m@j zK!9E}b#nxsy{m)9m?Dwdq_fhH4B{Q-KW5yHMc3A?b74-rT4qC$^`9j|5+sgz6tVTE zUtr{<f&r&6es&nz3|Wx!8iC3KaXe<Ak}9n|L8N&Kc}`LiLC5sHvy?YfO;B9sSc3et z*}pS`mC+Y^vz%%=ni7}`c3KeUQC!zWnjNH)IaI*Z;q0_yfB+>}s=r0$Cb>q$-@QGn zM3i*KV<;_3{B4MPw>0*V6+?76WFjt37{U^${jtD&XQ%&R(E_v`Tdpv#G`HU8rjKbn ziU^{Nk2Hlb$$`}A8BOI>KT=T}%EJ)kF$4>wS8L*colWgM$n}wr+!?$}Ousa77T<Yg z^rzfQ?m7P+C0o(JwrJH}If45Gi4D-u0e1Z~I|XXR=$hwA0M)l7iHlV)&K(UgrKdL- z6VJF^r?c@Ea$BL1&3fk&5!3=XRlyGV8SVs6ln@e+fv#v0I&FLc0Ft_-bBZ(UU~Y5p z)cD#4Su+Dg7|CPNFdQ!kWkA;h!AHF|PU`zaOuT?7o*C7u1>e{5-8+FN6Eo2!gts^v zv|m7x+NJTBmAwUv5Of1W7G}gPdGYWEyBfRM0pjn8j0!kbvGDsMzHVSJ%<EfLl2jTT zg6Ya)RYTJw!byuruGbBYa)7|I2BT2a-18+;ocsFG$l$jadv+`p^zOK&M((^d`y9Lu za^kX<doDl=fbsPB1Q<`I-dH~{&d-dm!3rtr?w%z7e)Yx#E!3*U>WB2gU|y}`_mt7k z5lLiep+hd|$+br)R(%R|Kt6sO`XZJ*$^={<PkD^ES8>7{E|fK6w-FQyB|QhQw-f-M z;C>OHrCso|XayZ`rH?#BvuF|m4o5HCQ@}-Cn|8lx=gN5VW+WHYC8D@S2jt94B9#%V zV%ScFDGQ7-l6r&>rRn}nTPiWgK@PhCG3DB9bC2Kp4o=ig(yOf+yT}vc7a@7omlv<@ zzJkU*{{lqX@w--a)M<iP7ah@x6Xmyn9R4Dq2k(^>UTUR*6P7<Xt3mIYQn_8mFb1SK z(nLP7eX_aW+d4=d;{udU=J1oh(WsZwQ?Nrk5BhBxtzBDPpk?vE)5z_!c<NpMsz$N^ z(>EuP4ANc@J~Pv(<`J&h66%EKTU6#%HHJoJ#Y&o)3rU=4Mg(sZ#zRa999b7L{t;vW z-Sz~9AfJFckjwip_4b&_v2jUg660oKWgnVd@^~&<+<v8<W^FfCr9ikL4cqi0o9WoM z=Jcw~sd08l;CE5dHDy*B{1;74glO-~hNv|$R}s$K|GW8w)CE@ZMVGj`1E-u<K3NB~ zisw-t2v64Q$@FiWhT|XVk(|B&V$gZj7$-*Bp|lQqhU=xB)^dldRu@rUoA~d%yg!%+ zo7S{Dr{bh($IXRzfv^-P0aX6m2k%jGrxLnEbv=TMYTk!%3syR_Ggu$L0lIWEq_NX) zTx@L>Z^>7~a`Af{UG*2`NYSE3ZZwrwLp7nCc?W35T>Twzy$%|J1933r3*C-zCf+b* zjoJ3>qmw5c;`K^Cf3A=1HmexaIRw3Y7)**~x$!G^ze*PC0I65>xxR1TLusYK_x1*2 z0iEtOqnYj}OW-L<arKc&M}ymyV32*lJ@nFNw)(#CqaKp$lpN&?b0?~g!=mI)(J=cj zdvUOrHs$lId|CoC=TYe@ATLcY|144TFfLK#^6Ls2RcaxWXHI+fgqLd)jM-;I-5wv3 zj_XRTxNy0pzz(@Pv9Hw8k|Yw{9sgMMbjQqGI>RRkyk$&O<>njs{_bmKQZ+?>=!1f# z=hKH-Pr4aU&fM5Jcqg2LD1$ooIu&M`wSLyoXaAaeNgJ4zu@MDT40K=RQu=9jxA6pK z<epZ|(`F7aE8`5~gGSiix$260qWKe;o!1_ry`_xaBvB&i8p*25rM4F7y_=a=QR+9U zbFofd2QlC_&tBZsp6ndWIQPp|FCjr;d2Z?Xyk3S53lbwv;Me~~%&>5h0*i3e_HrtW z`*<C1m1WO^x1-ZwuWTkL7m<glJNeXgg>461y)?1t>`%v(V{`LikKOpv70iCy*ihym zXG7XJ&M%_19j&fkV7k>{*`EIRn8KSM?^Tv2S0&we-S*LpXMrL91#AvK$ld?hsl~O$ z6dmWRi#&mUT-bS4K6;5wYz%W#o2XjEMv@s*HzU~Iw4_nmnEvb=18mn+ogYxgJmlQ& zVs~vFNuCMF<j4oTPi?bwy@lzfjz4d$sa8Qxg}|rpeuH1Wf6VoEd3*CafAOUsCR2?x zXORz&r3Knw*EfG15DJjNqei${&{{|7JG^mw_v|Tf4RQa{hP%KFxU+(|{g^=b7}FBj zYUEHS*Z8`IPenM3)}A3q5>P_3W5WSZ9xrvfURhObZH6qEw^JE-pk=pmKQtC(rHRhW z9zPcIk5;0`!df4vEN=oOF`Ea61MsOb#+?P50u2t>anG=R{u>+CQ@GZe&z}?}@9J%u zHd?<=_8sZUvGUK-r@aDJLUGJD_6B6MeP&+nBL@d|-M#87{T_k5jj!cLecSd`)oWRH zU#PSf>7Reit0c8iXnSc_Sh#qiuVp}d{V)U<B%etc_Ek&UA5du9uXcS<6Dq1((QrM! z^X5i6Yzmwy7e30z3XffiE|cdUW_0qFKGfrIVF?CRhoD*3k0qp^)qqZ)NGk|s7tHCt zA~K+kwiLkvk{cf-Q$c@S2&;;oGQseRgB!Uw+V{lb%7l(ZrTfUu_y{&Ez{PJ53U%PY zYPdpKRHN>(gpuF0+o#=W>acfP?YmJA&S$I^9;$Cl1k0AIpb2P9IN#4H#obX0|2w$m zvA>R}s<AD|pHVmT6yHt$cM+=wCC^;<5GYtoaCO`w`Ed~ilGbBWz1M^xKg37U-~Gc$ zIdG^-;y^F<p#NJ%MPs@~(CUK(mA!(R_4jpga_{Y{(z4)o>9WpniD%*AO3Q<penl%J zm>`<O^2veORDP4SVF$hQa^D(?JFVjryB_W*O{A{K2~uvPQ|(tr7!SPmbQ>^@=f5Q* zLvL>=y0IW;gyQ6^O^n9z8qZb5^Md8Q$C2xad)hqq{{8!ZlHzpc-}qZf?<O71e|Vqn zI^7u_twe{8;U9zTMv3HIXRmWWrh{`9v#CFtOnis3s)ai!iVV<SP1vLkaOR|_=XRsw zJxjg?j9!kE-;r)~?p`mxHoCbDnj$2C&G@NxJ?PJNfgNkSj(##!T|3je#|#ejJ{62W zxp-B94q*vSD1e1AZg`M3XF%dPO7U=KU^*&6`JuRX8>qh*gZj-EnCooM*i8JJ3m^@S z>N-@(knHVMt1z!Ib@6o>$5?HG86VGH?$APqN!!?`56)mj9ddAp3VlK;SQg{>7@})x zjb_H&4>%MalPexQFQ8aBp7i58`(R0Feo-siy9<D38OVaS`ZX1;A9vdyNS*+PUd>W< zyHZvdNKLsk@O<$@c&&29+-%#g8Q9wq6!WB<+rLoB98I)9yFU7npkMepF~onk4tbPu z>y7?yp*@s6jz6{M^cOsd<`5~*)t{M!{mVNe_WVx%(%|xRn+DH5Px`=uBN`sOi771U zA&d=e3UArUGQV_NFT^F$rUk0qsJPI)1(NQvKZEM1><T}V*YHB!-RqdXgzcp$zsrRW ziE06wPME|}!IPcJ)`IQi={64?pkgP$%`kpbdT&2i*kWpeY#u>RVg+|eH@9EeoFoH> z8T{xy$vgRx#gi)>zDCQGQmi?K7s~*!6xWl}+|qGvo`St)+m_ABk9@6fQ>Zl3|4$~4 z&ckxj2Xx~i9OB~%0hDxV@$5pE4i>4Sp5k&yMMwM)NEY)2MV8Xww?wbC>{eQkLc#gb zIoT@}?Xu!)E<VkasIOhLG~yr^?eYc}Z@LASld%7LpIam6uRS;1GrX|tG#7X_z&`3| zr-BBhp(Y5Z)BW7};h(IRQL~Ul-{>)^PE#pvRPquo^EPH=@zWkZ&@rAn1j51MlwMP0 z6e}n#s<}8C>FhId6!EHKC|~{d0<Sor9oK!KNQd3_qQEL_&dP3n9#0>*1ybvx<%m^y zxLSs6v*-mAe^WqoO|WIV_oNbmi=D>rq0!7oOAOMGeu7x`_98j{KFawG>~CNI?jimg z%yNh#ud(BuYdS=rLa*Wu0B%{t3I=jv_D7<OPt%&+Vd;6(62IJGbc=_~DRHSncJup{ zGx#FlAdKymQ-bcN%C3_eZ<0KqNK1}tt(qA#JZ_I#i2$%hhl~`TWXsAY>8C9&)8jXA zQ4#PRIs4(5$mrJAy1PaF-FCSd{SOX7MHI2^$zy=;|3YhA(xrvgtOOUA*3K>F`NCZM z+W>`>x)T*+on!2lw)T~Z&MIhh&6$Pa2kY^3Bp_~3B%5ryiBU`A!JuU!CkCuALWJDR z=Bj=1!+8@uf?QBq6>&ecz<yqaM8rL!aY`@YSSb+&bh`b4fs0T%Y?Gjz0<bHnX6ex* z5DXWkX1BzTtNGfwhKQYsVVUdMyH(16<WRs&4#ji5#&3+PV>AWsE|%uhxRi2uEc59Z zNI4d~81Gz}9RLW`xG^+tCs$4mRFM+M^2e~dby@Hj>F?3h1tNTMc<dYI;Nd24y580q z&9F!{2$nq`#7sVIMk6(MPwNlu5_c3dCCoa8Fr4Pijb#%%r!)BBc7r@-H`gYRL#i;? z&*b~0bHTP$?+&Rlc(_wc+0hEt5*wTlYeFIh{gL`r{VhzXN(T?B*j;IZf0Oo%@ZN4a zUZlpGAsXSXUtK+N{9h{<KoMbrM85Fe|2N9rwI;<1s7bnG+;naRRF%8no2EBk=@TKr z=KBbiyOvM1qW~379d+=YNkSwrO@@oR2zUEbwDP9lSeBG<Pcl?5)S5GYp50~)*DMN+ zlCMf&$q6}2=$M?eqLTn=XXn`7KB!gxbBe>H49Bzxz=6ZTCYi9`5~mvGzK&K}vy<@x zZtKytzCAC02Rh(C5Kw`vcP*XA4pL$hoS)+2-v6Tk{h%86+;w^@wlw?!u1?}mAA8!Y zkoAKLJFByyiM*Cuy+o>M6~Fgs7N<341IR#P!vwJbAh;wd*S)<Vj4}i~6ECk>BZ?Wb z&vHEgsa*c)v{W^L%YfAE8Jwl3U}$$noy18HdQrmPtqy$ld|#tiECmMw(0!7t3+<Fe zpTZ+aR-eEQa8liGL#cVhX*x4D?5$jj#J?&xCH#VXO5cU;209W$AWY|9M@u3kT1Ow$ z{9{Z6fKQ!THH!|TIp%jVdnv407+PNM0c5=N=ViCRbh`sHVdr^wq~M3Xv9+enmNg;l zXQ)GyFwEP}uGtk<a0WB{G51OpW5ndbtAVNhAK5~0{{Sc3jZI=S0X*2K+qx$)Bc_8k z0KXsKiB2|MvIU|CYO@l|G*9xxhuWkLHKR-;iULtCC1MPCRE_@&n-vL25aPlqmBZ=< zdB)7qR0yN{icC54wda;R(s{WZ%!lK$c|JBNuAe(P83-h(l5b_N;6b*4`ieIHfWoVN z)sfC@r3#j(vD^q(iq%kDTh-i*A+x*G_m9Tq5#1pB=%I}xTBd1uh+;hL%Y}5f=Qj&6 z8ReNp(GP)LJG1-8v7LxTF>dSn0yKID`e9C`N~=XE9N`+{Mnxs=sEWn?%EI~P!Ymhi z*Br>58Q<p4S2-*w70u0-BP#p)_KCC+XmFr<QOy+l*?ISuHC{S_S)95Vl8Wg1cW=Vm z+yVm+{nj@S7p+}7Ei4?=>$EW9ySYS=RYyut-!kX_qg{E^VPMd&eXqeY71Z|0@6<3s zlD{iQo^!r2Au(GPt5(9$=~~_*sw-$ValP#BO+7w{H?SdkN(2f<4BObA?|Wpc5t*-H z>2Pu%joD|)12aq?yv##Pvu4NkAkN-f*m+6q`!Zws&4Zv2oGY1AIveJf4NJRs3q@GC zEqcm->xC3XW{9pv<m7c(?01w<?MIP5V{Hvwb25~bJ1^YWo2pYIk^C%gF-d6ansDx4 z&;@O^CPKmu-XGR)OZK8o9{n78SN!6(_49Uk{+JU3hzzoy90zyzqjv_=o(a71{Fo|V zyT52rQ%wVVX9JdU-UC&_jJ@_<l>)><4eJ$7(EXU=j*d+)?US1q2|^$P9h`mAi+@Dj zL5E-@*WW689z0qLBYpPhsptjB*NRj@tAo^`CpiA{)|#%s;P2p}1%{Tm!kapxH!z=i zNb%A&9jc4J&IHw({tZ+B!<O`r<4b*>DLSDtb~>8a-~5$xoMCOpW7_j=Nti<s($F|3 z)JJmq;Vq-kXG%VhJYtyS-1{s?;WBK}jlq?s!C60(wwh7kPFcdGwCs<6_h$>$pomb^ zXiIZD-&TO#n@Y0BA;lm6uvRppeb!g2DDhOXixZiUVq)H4-f<!!MleoOx7M;ZM!5*N zgL>c~xnQMRZ5i+aG<*rgRV2cI4~BrkGiB_L_RHS)5_GH%oyHyGIl=g;Nl{N(FR6TW z*?IQv(1O|pZZ3?n&yjRw4<6s-<3Z~LFSYYaJ$m^E!WWG>g77c<zN`TGhVh^hSh7#{ zaN-1Gi~>e4tob73FA~Uwj8BJMf>&`L`)7RxX50$DaTqEutx+KdbU%AP4=^pJPgeis z!zBY-C8;Ykz6LjX`!D1_I(9s#cEynP{`vHEI!~FyYZ||9>MK3qmqHzA$27%eR|^HG zB1EPT;6#FBgUSlP{gWh)1<$6;xlj$qfV-9~6VJ=CdP%mCKKd%i8P&LBj6#(nlIX@w z*<)!a-0aVssC%FaD6eX(wpkC@yPTshNBwP2@y_gYO|CNs4*tqs*zyk&$##l?hu4f5 z#E6*7Yvsk)r0s~hHUhBqmu9IRFFnU(uoljDtYYI1UeGWl>wa0v&Hhk6GD>{|=j7uj zQRzOZ1P}7X4HAhh&=|>f`ngt@g@{VNNn9&C?Q+7UwR#^Xo&ouyX3?)a`nG##OB&Oi zh|AQmq89N7b4Q^hPk@xIG3WlS^M`y^G<6CWvXaUY6Xh8YNr-WY#Picq><lQFH~#yr zgM^(w)eLX6D(d}auhg#o<SCrpx={6yl-)Gl;M|?Y^h~IOq^s)V?z;U6rk(;r#PD3g zDzPM1<SXQZiq+gu+iWR>+8hlX{e#^f`RoIF?e?GP>lnTxS<MdhJC*ol%9ms3hTVy3 z=Iy!j>9Cf5dREEty?6G6ZwvXml5$7_JE*7Mr^DtX3SUR3>y+^{6v7Tn(R2tSO0zhe z9pWkt{wb6~(bYx~#zi)VOduaOf|@)99S`YS|D1G4&FL3f<#z^mQzY#9r*|=K{822# z1JDEX>xVGQ%O7%K!Fmj5$&ig(K#w5B!O)s^$mGQB($<ZO*!$2shUf>F_RV)#z=nzK zJdna(Y%Hbv^AKp!UT0{waw+Nf$@XILtVm+Azm!AC>$7A<CK#7(L88tkpw2a-Fe4XH zdPC9;QYyEHcu`qO87$`CN<OA@84qQGD)3m%J9h{e)K6jTUrubv8^5%H#t_VgIl%UU zmY#5dU-Y6dh;veQuRLwOzd20}^5&1Y(=tsEvBcwBGK8}D>7yedEj#;Ezw(rB5saIz zy{ezJqM{$o_+Lg#?;MH~`c*2IP!pX(^K&0ekJ#X1oeeE^Ak!##iG+!dHwvCXcxJ-o z+$b*oVOs}Bg{nG-bEp@pSKh$EGPU9ubS%jaT6}E^!VHO3f~-I4{7X8;l>C*=KdWPM zj9C2aP$A%=v(bL;+MRBQB1VY+|DlP#39*7(LbeP4Wk{zkBbA}6RM&a1TRIz`e(Ih_ z9a1>)V|}67Sl!Y%U_7#`j~%}wWlFMY@ihIp=o8qVeB2dcfb1Zr)7YHSUsPbn&c1~i zY$oderB8(Q1{cp6FGZw|ULD)5K}djrPI??nk*In!#!T4LP;PMMp^n=Nw&PQU8-8@- zJ^}fEA{XEjDLB@AJq1^fCemcj8zAo@0PO3BsQn~Qd{V+)u=Ms7o!|F<{f!SbA-7Vu zkbu?V<8u9p>NRWQK+ZJX0MFWe*5{_1kQ}knlh_!qM=WLa_}RS|+Z}#PNgNEW0o3nj zQl~i7Kd7(CsYe@wLhS@>E|W<YR1b6f-fFKGd01UBr>@%CTM}&aGBb^br$+BlO}dF; zPj9Y?-klT2o*mRVy!?vF=HcZ@55k_?O}}}Ahrf&8xW`pBLFD0Pyw_o;&yLg!;T}HW zhq1~tyIv_?9oK~KcU-&1{W590WA^|@fvX<j8iM6YLsy8_LggAMJ#c!?Kn0Hi^!G97 z(J!V)rOV(WRtV$pO8CWaS%W`De1WKFnYD=R%`jXN`M8yyxd;co6!r5g_7)<Kw20$+ zMlK-4UG_ab9z8u8ErQM`xypj~QOLNCIa9MMsE~0IA5y?O$A4e}R<hen{7&ZAPO_F- zLWHSntj~p;cV~zP5wX?b>nnHsp*N5(Gyd>G(HFzvoz3l!oVCZmXCnPHmVhAp(?q(K zDV*4_#Skd5xPmRrw(;A0^i&CnJ)|6OFutQhGp=rOgZLba6c_lk2wr>bf3+b!(As_$ zZHd6jRd;YRk@=y~>|{mscoSyoWC-7TW~R4vbK45`#xh5PU8AT8ua`Z@Y}K6tS9s$r z*DHvAG_h$#zz3fqa)xJu&QU!sAX$}%8YrCTumY4p>AK8}Bb{NyP(}VmYN!HKPn$-8 zpXktaGN&g!%K0PC>Ll#Vj1?X}t?2an&fW)U>Tx#Mo3fA*EHlk1Qc-KoS_8eW`=_?@ z*}xAITe^QHT!^TAFjsO)Osrc3Tn@olc`ut}wKu(FJ2c#ixFjO|nJWKTotN}R=iVjg z5yPvm3IXq4|9dtZ^~Ly!m;wHu#uHHtt^)bfqB&8sq@LWMFj57Ya&vLe!E{b;gD<By zhMWKW5oD$e(u)I|31wY;bmimwbXPeK;^@BxiB*(G{lDWvaZs+RdeCMhy1YJ~M^q(| zY^S!rAEQ(ZQ9=m(31&!?^fw9QvwV3uNk8%0?w+L>HnrLf1v!)me1~ng0*J1}gQA7b zmUJXaD3iH&EqlJaUe@eyH>^KfhAYv!g1;VN{2)sCjJQ-ojJW<k7f?)mGPL6cyLqH| zi-TuJ($<%1-YvS^&7y3^mRb@5s@;#;M$q~&m+tNjO+B3rdt?<gzJc!neY6}rFI;<) zIODhtk28{UQ?CON=cNp9O_=;kq)8eHkKCtU3yeCv7J^~<<ZF(>m?Bm)c6}$bYl*~{ zNdLwyw+>yXbK|F&XrSA_%UrEJVKT;2VWMhQe-eLC*=I_z>Hyter3O~4+pKTayc_If z!#m0V?Z02(As0oQrZ^|H+!ge_>m%*^^nVf~XBCJS@H7@Q40Zi|2xR8-6CQl`CL$lo zn;pEQjr0&JM1hZJPEr3`0m_qH_x&@w<dx;Kc_dvwX5<)rZ=kafm2G8T#_(exQ6Ff? z>7#N}@HI`z8n)|XcqxSo1~)R`c8ICEIIM#)`j*0!F0zUPZwomizLET<_;+X41^*oc zrxgRsa-;MRr{~x;VeblD9=VeMmTLGz1qFT@u8wAY1)hpR>dC*6_{(0M4Z7t0J$UCi z?ku@ky)CAK4!;huV+cyssZzvAvHoXLNVgl9{8J+uUPS!vLAJ$zWc;BjT6V>MQxQ}5 zqTx7L_?MAFo`k>NHBZF;X?zrv)M`osdQ;K+pXDIbr0&}vFj4!VeySq7)!A)(_V)k} zyJK-i68tE!soal&tP#!M9d8(TA@QFpIXv%Ir!s>7H~pV(WXR3Lusy#G|IuC6A(&?E zDuamZ=YJI`v-A{n6Y5}yezBcMB-7?_|J5IUj2|gp6cR%05l!wG1#w7mJ9+WP18EV^ z0To^h+LipRT#-F*HRt~)KZ(b0t^O%`iVqT~Iq_y2N;wrh3rU{<A^1LoGEU~f_&M;T zC?VsIjq5;f$+9>{S`9I72G56f>7Y~+v)SSDk@<t6-OJe2ocY-LZDmQ<0$dyURcgEg z<dJK$cUlq5?_sdHrnmlk*;?>-(2OViw0FEe|770+@2W70d!!q5A00X|ds+2Wz61w; z%;%mV$^v63M^V(3Y-)<Y(nCyxz9wjJmW<RDcar&{9AdUn&M9!g^4onN;F*l&|5~7Q zSMET{iC6|NY6UiOGd9fFMT<*Vg=J}j%FWZ*GYDS}EJufaNT)#T6~jljIZ|8u_~S^N z@`mnT!fufsBlUcb(FSsw$)@{1A{(gJAg>0oQ?8!C#yHrda@wm~bE1BlKvcsPRM^Wp z8{hG~rVL1`$a<?>0h7vc`LLE5fjKj&1`;O&`kK+#@a!kK99S;W2S(sOph`ZLp=v*4 zt`kQ&^+dt%TvyMQ1@tQ8y4=`r*;)bpOI5J@fJ^+5l4cj;nsb)@FJV64`0l68>Nz*9 zC!|;Z6ZT{JTApoJ?_rOLG1sJIifIq%WpC6&U&uKWdv(Q7kQLuKl1{F`49{z?E#%C* zp)3l=$i{hXsaP61@+<f&wqm%8clW=XT>$?Ga9z78(6e*$15rk9QHOcQ<AyE9p3Oz% zKWhdR2J<2Q^=p2f?S`nI=9?3LGRhBn4Y$<lq-jsAB!0!W=$Y)#OoUJskgmokSgi;2 zcWdyWJ~@;tV}`!&C$U9-qGHy^Nj2I}yp9Y)rNX0pC{xHO1DBKz7m}Hp>WDQIHZiU@ z<+H-}<Uq5kKMIC<o0<$W`3!dU8Ko-8nIfx7UTk^vhI*XB-s=w|YB|tzCC3r*i$@dS zIbH_Y@GXohOWAQ#h^<DEiEV0#%M>SW?7S~_NW4sGHU?ykG%`k^&e1gO?TRV1s9c^Z zFzB<B@*H#yc|2?GfeqM(6`B1!4{7l#U&b0u{s^cDv{*m)YB?pxl(_Z`-B=09qMnH3 zXR!?(-6MH@oG9n#R3QgxaQlH6`r`r3PLSaqG5`a}cedh^>{mJS5wLe4Y?2ELaD47{ zbnjW1bnuk!?d<cj?VzSyC7{Lg;NFJa8i%#_vXZBc6avlWyrrg>JD-XvOAoz2H-nd6 zNyKUO{KjiyxSSqK4ZHe^FKm2cgc?YSRM9Dn(Et$~v&$2KnDv|U;HZuE0<e5qXD)|n z{R0f%_=T;d%1q<4-#vyoglFEMe!5`@WC7`A4hE7L>VM8B8ZU>gy%)oscT?N^w4dL* z2=xEQDm7JY&G|rn(dvhq9LXNG0^1DGTSQT(Nrx*xAOE{6+Jxz+4oYZAs%q{6!wrf^ ziJ7=jDH~Ru_urj<Ifa=9lxfiJk40}r9gg~a-!?9=ZPGR+nCM8Yj1_{L{)Mg7=X%{1 z?1bFMqaNc<Gi7FljcCT?&Ifix-od0YMDs%KZ!BfrX}I&Br59|;@0r{DV`{a&E#l2( zV%z+BzFJ*YVUB6n$as&abwo+pZ3oi4<0>j<5^rCzu4C6Ev<JGo_$hEkD?L~ra$I3S zHOTtM^c5gvX`c}$7qm(XB?HTLV#pQjYwOXZQRbR9KPjDuQ}Epb<53(=>)c#Orv0~x z&f|(i3yos63*v|A*+j+~99dJ%r1)0B@)U_8cwEnXQ8v3*<uLei{;dgyI}>mI>smt) zud)AVV^CiRZil3aPetwEdgLy>MD;in-HkX$)W{oX*()fo#u)o9MdUU;wzKA~gcB#Q z0N@}MyGPQL*p{|^tiF$;X4a2EGxdb-^eL{QHzeZuvsS>ToHxxQc3Ck+zdiZjmYMAD zrRwhvU7rmVrZ9T3HvEh;mHtD~XiA60bUK0I@|(~T6>!Tlvitg~fk3tmiX)x+8p>jf zUA@ZxG@9{VUQNJa5$ZlvKXCRe<;D0L>yu+rnH9^4xNP|vM7WDUe}MJ~&A3pvn#Z~; zz!^3Ko+#veY4B3cNOintCMy9=f%iGv?~!ANbjrjP2VR7Shc6B^btcE*tAP-IL!2SI zM*lQpDd+nbJvv8#{4n`Md8vwZ*WT|fchP=7$5C<3d6x4i?doeVn&@qbnM~5wk((9x zm@ASj>@L(2qMAS+*2_(N5s%e&p8|sf{*IZfw+z_xLStYm^eF5X=M95&-7GnlYd2Q< zyzl9OQ6J95y-@!+R9Kf%j;U@+_0;;%V0!m%5=rPybh6W-`jXP?Vq_3M;luGfj#|fO z^%bcUHE+MUM)<fY((5<9-Sf@VE+qY3<g+FR?NugjbUO9)QI6{a(fi6u+{&`$Y-a|r zm6Vr7=bVF%%nwh#D5d{z^!u4{$#&zsTXPDMUJu4w6O;2f9~Ejhv7eCk3B<V$I_sfF z=RPx*#_koa`u=ArSK19<;=9QW%YUhAm?Bv&qnZXk)XSWred{>%C(VNOWaEu>RR#&{ zxL;4;mEJeMx{UD*9LL<s*oj_Ba?;qdk2i-xjPnj?#EtXer>+J-Lefn>f`sesI<H$7 zoLn1I8ukf271Vgvt<%gl4{ne1|1mFh){bWKU&4cfDz~%}?&^pgQefJDOyA-Ph^qe8 zjt>*ZHTz8JF-0#RjD9esp8YM)m0HH3_L?bUYPI^Lrm30!%Y?nr+81Ccgh|%H03IyZ z$>Dn*y5=|JmST^VrMdL76YBwIpf-K2;~?RaH}EEm%hQ$6qtvpHG`oac=2~Hmn??3K zCv*i-M1P$fdkbwDjFaX^b%r&oL#og_lHcnMCI()Y3lYFkJe-8WbG~@*jFOmTZLDJm zPa-3Qx;p!GHuW@2F=dF#t;&1HtgMAx{^Zd5m&q2DQa!J7Gyr1q{M9p_^SXj=x0x?n zd#roEgk_J7-#}htz`sR+*wU5xq&?}XD&&zpZ*9T~7B8?-V_W-9+FM75pnczV$KBkw z0!@D+jr72G*>(q`?BT%{{;gEEUdDj~&K84t?&n$tVggN!Tqa<y%dTTob=(SI|KJ-y zoxAZC`Y)^ZQtF?AH(ijf*7@%#OZ-i4q<LrAbYpI17l8C&)EmL}Kfqb5?-M*kYDh!- zLs${L95wa^HW_Gi>HV;Ufw*h@>!T2!UpBVN64NI4F$iB>OzzHF(>uYigYlWvHeSBd zeNq2*Rv^BdI4sk{<}Sy0n(|@{&}U+!pn0NDS9lVCD%q|qEv!${x$aDZ(r|?Op7?Yg z_m%~wu23%EdgR?d@)4Q?%s}44jnnv9t)==S)BE76x&BM=&htWttGWTJO<(cjQFJb= zw}|rxE-Y+wLo*(?_hjo&WG&NFL_GJHwj#<+%!B1fJRfBz{RN*!#g9x~Cesszmm)|O zTfdJZyCv_xAJZU45`SCwxlfJO+1z;ozyHYXl=9Ke9*u=!%{a}Zsli9;l;pG6!J5q< z_-`%%FW>n8{d4_KBA;i$K2ZM$gRdb%!tvMsCe#o|q0!xYnR>J^#NVV*&$&^vI3@q_ zDr%oqYVfgf9$$LK(`J3>-thlDz3y|?=KsKhq0%d4fPiZVYu<+rGGI(?c@BVMFlBEk zIZ>POqdd?C<ep>WiAx4H`@BCV);s-QCH(KhunvD@+mCkeX2)_sp89BT-|1VN(syvM zeZ;UHFZ4J(rt7vL!gIoI(gKnr1M&Vniq5;|((6CBpyr=iK?mcbTb8=!jS?vee-;MB zYM1Yrm$2X)prm7I$M8AJkFH@U5qmnAT(6wnP+T~LQyDJL;~vg1MlT;jkz?a>pAu;r zI0b)hdkBp#%xu#*p`JbekZo|G<Zw;rtlz|OhOwP3TWJ;`6Ed!C%G?u6eI{eC;TK=m z&ZfAw<m?{qgLeWjN-(14(bb2bF8if=o^$hl<s_4UkyDASs)r;t-a$Wz0-{5B9`p{y z9)5VA36#cgPup?@ID4ra5}WkM?dQ3xC1y?UU+*uQ2WqlmM|#yeWbFJ`h_30w2*a@g zwFjC5dpKPG*zi^jTr2}inkyw;K+S`Y^GDHDqH0R|&K;cR`+!RS_G<Z19i(Dzv2?jY zuSkBILYaZuB}jZ7)6MMpGt!tkRW$pfnCtn=Muu;*>7fr0qicyU)iaP)GS7Yr>P3JO zoXb#Tku5+FS@LE>aNZpM4SbQ&-2L@!5vo&u{@HME%JMDLPd&(#e3b*rs(!{vb*|uK z^jk<e4c1t<+hnz+d%!>C4Ec`oce>Ax)_*i7+<0S*wKT=^l3jgYmMF#VbaJCW@?o5z zzuU=F2Gl(1e*!%~1v7|uM6_3Ix1yfsz-Q2wNNg_TOO3w^g5k4E>`e$W{clw03$10b ztxkRB5%6H8Lg&Qz0?QSigdguY55I>he;BFM4skGGtV}s%Z<~Drp5g;aB>@-iCS#+f zD{=Pwe^i8Z3T;_J#RMa!NF~00zEU#W96~**U>TX~P+T0gS$Xwd`Wd+<UPH09t+YPN zq0?xGdl)FP#AW$rO%bd(ELwESHT)QoWx6+c-k?+M(J7@B=<3(}a_iL;Ce%C?byzlc z3&giJ22P#-5%>&}{8@jpaWY6uR#O;jz|2nG^eVhk<<+<l$%1s}STKl>)KK)!XKbmH zCgU6(YTN@So;8Mt_z6^pHbjzpZ&hsuy1~^I9#OGJ@%=Z3R%oxWZskkf`=CeCVSj8F z8Xf#1lL}>VZ^CHVA6t~m*Wz)C-?569IakGt^!ha{$u6xR)*dRa7JOtkoOEm3wkua? z<g;~Ux$|o9`2g-KKYGU1jl(1zd*OeKa`8r6!$ZOI)F(9?%=FR9E_Iqq=7*EVt*otA zFZ^pwXl@3=>Gw!)rGEeXZd(-FhtScN62auV@OR`1Wk&SXtmMp#qMUQ7!g_1iY&@jg z`R9XPci(27iPxi?9RT|L@xS;Ok6Kk)^I2#$?#zNUJ@y{td;0n%Z0JZFy4=5v{3OaE zM)CaNzCX|RP{waQI&R$9<O2%QK0X#Eu?XjdhR?0?=rw)%n`lOEdQH30n%2ax-%A_J z6Ag#DN*k>H_|MsL+4B?-GeVzi+@$Yd(G}!CuQFnX&{HJ<cGSP9^^rF$=yixs<PFVd z$Bh_l6)GCbXpQ2Rfi}<*VLTo)(+`NG?bZ8_X4b>%a`?47%R)HyD;`OSy>#5lD*wyI z<TRDNDaFs4WA-JmoRDuLxk5WAH(G51;otCOVB>Id2N7E)CSPA}`9M?%Uq*c59Ju51 z#~nNQTWH2R&rNXyUYVY6tO~`;tmdoosBh@%at#g|fZ_gN@S5|--@RD>3@$QbLzPhD zU7#yutH{2D<r4t7m*zoj!8QtXL+P5&jd-{lPh649URY+$w&BO>4F}_XoFu9miI5PP zoZN~xU(RSm&YRC(t>0WW#TUXKW<GdGbzWSGYOjRI=m5XNCX6Z~&uU;{d5sNO-1S2d zT5*k90U54{Jtq7lJlNbi1gaxaj1%MT@WiKeL|o3K-oj;bQit(8L<uqBPjA)dT^&;C zK6ww({Y!At>#omJa<tdA0r`phf6!qS=C!~eavG4Mfva66c|!-CCLb4q?nA#Rv2<(9 z8CwHoC!;MO7eqfzd5E*ua;b6R7@e5_*5Hh4%jXz_TBpE|QRhDiX5z9h|Bt$jzxp?$ z4M%Yq`Ng?WBbthR5Nd<2vRtQy&UATX;BHsYE<-Rvr%He!6mgr(i75c#or>%4*Bm2r zdRL<;JfePcnN_E1q4*RYkQ8nU_N}S9gqhc_?6~X|LB8~qBLA`grxhQe+#<8Ho&O%& z-Qy@!Jk08zy58oNdMfg`PM*G7H0Iqq15Vnl2QGnHSFjY2D3kyVx3-S?$gYpAbC0>r zvTd>qlS4uyqW#CsYNWQ19)5YEEjoH5R(<^MJiiD11QG*i>GK#ruk0jXC=H2A3s+NO zWfr5J-LbZ&&_HceE1`>HCMjsVd&{tsr;hdwnaRb>*odLBC%bbDq<Oa&XnlI0<||${ z?c8_J_Wtz-Y#@N*9KIi3R@+uLTOhUa8-)!sn(j)54oK3pF#LQaK6W)%Hp!Q@n3(`- z6bWSD#GC=Zha<Q*OapDz(BIAjXz`^pAJ5LW7k!g-yL#V)KSVWkcGjc>cAvx4XVR;w zsWo?YHUWvE4*%n0XoW{8kd3eFmZif?xBFdsy*obFKAc;AfGK;@_fF%t{XSFnJm~@L z@J5MwIA77w1pDE!T8I4k8PeY+R0uf|GjZ(UDdba*uxGgDrspRCm7=R@d82zOkHpcY zmGsN|Tt6Dh-(k<8-Ne$Wvi8I$ACLk(&%>!5ZB7x<Hqc%g=!mAnx%@oNHy+FM+1!Zc zH_Vkh?z^t>n;(B*LAVKS>mw<!IyYGOs(SXL@f+&H>TH`0a0WM=!qXXtT{qkkMmdWG z17GF@z=l+=f%)@3D-UG_I!VXa&@z|)w*E)E_UxjgdhUh6qDQ&nWj0rHdA=%rOf<Os z7w1%w2~0arFD=1*`*HAjQqs_RZWKB6gw#_Nvv6`q=&B0cGcwW(rP+4=b?_+Jcuj#7 z-~)w2ho6Fg=99)Uj%QlG*(`rH_JV}9rfH<(l-@O(&gRXTw^1yerg7@}(|3xVXP5C$ zm8DF^{e^vV+Jl~$g$XgUZ!dMAYJK+|=&{z&hjD|>i#}|5^valkb0{k4EMnZ4>1K}2 z<UbPf=x+=9!2b=74M9)Wcuc&|FbbVaF&@W28}1uXrqd##HI~;eCsB}6J>FA6)fD#E zx^e&Z6F&02(!b5V$33_+#jE?C`WZ!dh}$lrZH*4^DF2G5#vk<@aQn;rnbgmKrsnaX z(h<z2EK?Q!rO()@Z1P%o>MeLGBiEY54ZgM#<osi_?X~3#_4sK-nNG3^mN720RGk0T z`=q>F*RJ0vus4=T0A12&AfHF1>OoTxWjgV+`6(1h=~Rz<Nm8_Ve_?pi-nJf**78|+ zf_zcxN}eG%Y8Nu%L78e1I5wR^KRL9aw3FxMq>waxK#m_42pCpgOn+n6?6}{Hfu;(D zF9~y;`kp1rHrCwH+Wg+Uu72e8`+DD*iiFau%|WP@S}SYs8_{F2S5BY3>my0=SHMU+ zF{%2wC54F7wiWZquADZAB4u<6`RY3=faQEEA<5Yy`^@e=f?*orK?x)FNbtOJd8Ia2 z^#ULNb`LBdPmXxx%7<kb?kS}05Wb1t53&D2G@`ob$g)uK$nRGV*-z)~rOh}QRu1fn zt&9-fY&B8J`#V`RYWPByLt}kT_{6Qg;<O(v6W2T^^Q=s|EGMEq+3Hoir6*9%)9rd* ziruF%1e$q9%;D4LcBwR^g1SRNMMv}V@6D~P>w{mdtnN3F-D0{zKH#2UID~(s_2;<U ziK03yOErFIbjMPBqy|w-VirXenK1IfVKdUb@vGmJwtkXvbCZ%$D}qABX!)MM#{m^& zM1zOJ>UmHu-{D5!K*$f0S2MY4+xsz}z8mvZIQXy)M9>yi$c>LVx)ckedfBf}YD}E7 z$|v-S>REUymIE^t$@^e&a<?JRhkC)LMbPIXwUOj*&<|TCywR_3%*EAZCtRErCrbpm zEjF9uD=jz4l`<SG2jkW%XDi7)^KJOm&-%Truv^*vRO5(`IzwmX*?84);3jIQ^T3J0 z#B<9zoagKlRj$;)OWT~aTWTCKh*P^;6Y>H^VfprDqo?HqWVS+0Hd;b7{2Qg}AH{Eb z?ksYA{~+Lhxw_-Sy8lP`^@o$scn0}?M^lT4i{G2fvhR+-U{==QFd-o!<cW|vH$I7y zxf%YLxNG->N`!^Gm?G1BwaEu>p0~VjW&RoYqIUMLE8++sftvuYt{B?)s5$q(_V~CI zyd#CYMuq3Ua^2wgxPq+)<v1g=nMjqu>miyA9+RxmX*i4>9DI#hP^!m`k@)2`V`PrI zd9qAzrC8vp<<ikF5Z|4h6WB}3_=98PnXjGwaoLVnK_Hhi|KXrQ5k2)hZ}_bLS6QXI zN<SwQJX{B#bU11<cOR3j-f=J7x$pC7vR`ofHskCm@4^t2xd2X3Y@}wvYjJSRBag+) z_vSsyyBAwhE9!8&3%ZjnpKXkU7D$wycy{)QoL$|#7jT|%HoGahYO?sX6|>4us$#2^ zE53H^&MR>Tj(x(FPD4GO84hfU)|U4IGH4v%Eq-D?T=U!W9i?w;NgQVz>TkPwn~yyL zxIUu`VrBN4omN)IN=i#lo+xvxj8Kv|n_R*B#_2+Md9N6Fcc=GC$dID0ZkG7xXth!a zF(Q)-+?9asbJ$5E=odN0@9R>Z!_S{1ds>+NV4QECU*PX6eb1LKF{|uF>g9IoTXnsG zTA-w*&*y@uess7*ojY?MX2MG_Uu`5;7SFaJbY0^|e`5xuSmre<oa70&pnJ#fCRSX2 zHai~WmRr~B$TUu7T2t#u%bsnxL@rwMzFj$j&2nj+k4H$X&SB-sif7PJMN#vn{dz$1 zmi$Vb{cgG4N>!0(IWwb|xo&p%P;C2<k3)9Odx6ddq$=#5o{@I!?%lhU>%)%UU1H8S zInPCt3aR(pF*kLU?CP2-i&=OUf_|aWl%DP!#msm&v6?fhJnF8c_L&dO99y`1f4nv1 z2EQK0vg6UIo4r35r}66fAp>OM4M@rrM1IAtHi!pijVQ;tAk*oq%zjOn(=uGBL}RPI zT|^SC8Jb&)pO#DoQ-HF24eQcwy4*nfMIFXz56*W!vZeJfO|Ba=DBZA3Y%C6tWH_tZ zOcH;w>6Ll=Kx^Hj!1;tTwSAxO&v+Gz`k3;Nbg;NHrbsMV3xq36JVwe`4vbYa_)+=o zO*T`L9Y2tgza!9AlGdE1SM4SDuH;_4;HH@bP@2{Fw+#_q0s$Wq**i8gnu??LibL%3 zN;VRCi>wT{0vy$ot`17A^k#K@<|`=<Gcev&3Gm?(;7%l>OvIg+Lq^j>w<>vG2UK5e z7MJZZaWG!R4eLwhJ5VPZVe%(M7YyNQ6AXZ4LY5QmCgK$!|M}{}Jn|wA{1xVtBge;` zF?DT0sPFA!$cxw*g_p5G7-1%!{@)UQ8v*UV{qFWZzb&eIf2Cs9o|?lpGqz1^e`(;f zLT^w(>DJw5i{14tTY~ICweH<1J!Fif<z#gAhDqE#f&yJ_E$b_0w$KF)zV*+@`Q=JG zwg#IoS><P+K7KP)krQ%<t`g=t^WoT)wvw%>o2#B9-nA7E#6~4-<G1`>{ETd64t>>H z*jVy!mZaJ%Z!A9^oOW|(_whES<fL+MsnGF`L2r7@Gzv(#IrhY|jaD-;4#X*JZ*QBB zYdZOCCSjP@R`iYz$#j30jG=B>@zID|=$}S+ULH3Kg~bf|$6=#9-no3>WPYn&3(p&z zmNhA<pMIZ0t!HQXx(mD?Dt*_kuOK4Cqddj9BHhr@u-*?~5f4l~)qYW=07&?97!N;r zuC-ltL-7J{;)m}mxgx@yiG$8U6H$bK2DOTE0#}_{fKTF(O|@?-Ifw4~U*8^%$z*6f zSQ_Q;XMVWupEanI*hkUfcxcU@Z5mwF8RKQH;!9BT#k{cZ8~k{e@LbK_%VopCaaZ@Q zWzRyS>B)SXpHc6F&J8(IeWMCL&~2c_wC}zdqJCo7xNdbLI-vH;yViw8>CdLGUVkp! zD_)qXNLs&{df}jhnnIx`>!qUnd0VMj$Ikx*YWpC_q-Z@2u7uaGwhO6LWWP6ZBhRGT zPQm1=9rzywBnX;jpWXlIydfjQlLsRM?k`t~$?-UMf-Kfpvpc}8<N+vN>>kV_cXc%v z^Za|oxrJrU^)H-?J_Ny-0+r9PlWv3#z61Szrw>`$rK+^YrK@ctW;lqiGrD)&fxEw; zeGoU`o;Wn<v`J;USzm1-_X0yYZL@iPh2upu14DZMX3Lh{MwI<Id~6En4ko!o5g zZ}JtdTs|T30t5DZdM)ve=<Si(#5aM_`?uZmQhg_?X-Ro~Zhv82P8RS<<&fQY$C_Qb zAoNXty7Nhd;acxbyGiRcxnIiYB9-RRdn^3So$EKxAF>X3DmL1H)DvQx7axKa-S}rW z`_-8RjQ+`odt)6kq;PBhho`p;i|YNphY<u(M5G&(kOt`vY3c5i5*WG$h7#$N?(Xhx zkS^&SV(9LU=kWRdp8vezy13@W-1pgM*IIk+5M0KD(BIc!e6pzhne<(~mEj>VQ8u=d zXl^NK&*|Z9TF%vt3G!&`Z@8duSIOMz-MQ6FJC4hT?5g9m_$Y!P?zyXB0hW62Zkz5c z_1PN`R5*;%&T1NTchW+dNzwi_Z(7Txbo>EEGuY3wq2co|h%b0y4&Ku$r`=A;+Wk58 zTVLV!F{Rv4Z2&9f<e@9!dO?sLLS8y<OAprRy=rZ=pkkqb{ZX@vh%LV;iuEZ$)Ya_K z=JJ?e2HSQU-R$gbLL2XHTPXV_!t1vLu1R<!0N3kggw>NCy=dkMPnrzTWJ}>8O4W_e z{M$<ztcKC(O+B8`|DK6a*h7T8>*+=`5}5-84X>N2ONeu1jY#lm(FuP6U4YNj*ufW% zq{YqebwmY9u8Y<vuToxSnhAAOr9%RVNPik$6EG2=kN@i!B$JZH`K0r>aj8ccEE{dL zL;zx_FUxBga$=Bdr~-%MV$HL)!ROXxLQ%L@eLkQlt~*VsjU4b*;Fhjk&FG%KieTtd zC%DCCo~)JtpLfpwKF5?2|BSirC%|#pck7zx$$Cc7jpD<YV7K?V?{3kk{XH*PyI%^T zQfHi1o-Fokd)@m!{^m~$MWbj=PY##Yf5yMLyF3lex|O%Lmh-ulsi~En=fPMUjMQi5 zt{k4)TsV%UEI|2Xv^D>FobYK`SXo=XQYCs*|MYtN1tk2{8OXn+vVR-Ke5L+B+wsCd z(nVe+;3ReA^!`%sULLr_NS2O`eqXm!zXTS?!D{W?k8=~v`A6G1@yPd4(H<x{%nRLZ zayiRBEZy)3S{L*cbY=O<i^*6vE_GSYM*Nli%_e|1E+WWQ-|@pz2Qj4fH>B@eUl<9i znduhctg5=zyRUq&a<^eUl30y^fp=f4rO_<Ap18ee_iUXT8adZedcRUF7+4W94!SGL zDg?KA(lOEr;Or;67^*?ROeOfS%0vz&eW58wtt%_}q~W(?u6<>O$1V4;M|!)`J&>o8 zsQ_)4Y~XhJeeOebR(a?sLy&bn1^HsJWR(!32Kz>UQQhbPI%`v_nq-BrWkI#`RA%6M zU}3ICySX;o#&>a-&zOs2{|i*8M4TVSSC+`3U*J~WoS48l!=BCW<uaTw-ze<#^4ygb z9l<DNh{>YNjR;@eV0bT+{g^%AR^`7)9uO6^yLn5To6A4K&MbKKYo<4+E30%Gl5I71 z#m?#2Sf-lKw@MoTa(jg8CNNtIUpQHkn{`H8jpZpzgax^_BjOU*7DDVN=>mmX;Q&TP zk_VF7;SzFtcz2$>jVrsBDlC8nhgufABZ&TMHP+>cLTh@1G+R}Az9~Ii2j79nhG=e0 zHoZuH+v<K~#^Paj)3ViwF-m62at;NQ7eO#<2;qQOd-iDS`TcQq8IQbyJR<36Inq0` ztHS=it^NU@n}HHywg$vSu3|7xIH@aE#XdI^RuXd_TN4w?NlEYkTK+-H{g~!ZC*=`4 zq^-HmuG50zxrNwzv8nU#5iY1COMyC+Cc5{Mnp#T5AXMf5jLppRGRTq{*W_DNp!<r4 za|2w523+>iK1bX5NRgXhx%!~iYXjeAPctotBu7DD4?O>iyYAgUjkv8usXmY9L5&m& zQ^-mF;vCuFmUXk)wB--jbiEY{5~dm=Hc0upv^AE?en~Wi|59{yb@I)2Y0!ypq8<t- z@0a8>-a}(|TWwJ6nEvc@H=<N9F0Fn9cidW(Q-u~SIU(#!`iI_PdFBoquLA03fGG}( zY7=wfy7pmbEvT9~piG1JO>uI)p-DH+@vY!&dyruBKlAQ4o*}nD`u8+wnRN`2KczR` z@AN84D_#s8(z;p=b6NfnC|<vx&XkN)?DODY0i%DkgI=Gm`uClVPuII>Ghmg7zf+UQ z4T-D!GfVOz>Q`@GoWNsYa&mI(<L0Ju{xtW0Xd9Un;_2r|dC|WB8?-fW34S#dE*$PF zMn}8qrJY{K6s#zC)rV{)&ry&`GzRagET<+0KR()&V!oH1{A-((%kg`$g(e-wLAsOP z*HsGLd1|+qHPw|(-J8>pg+8gXZI^@MV1IRvWlilv)oDJb1(()BKk{nnFA^*2Dg5-N zi#V@ujZo*gtE9ddm2R`>3K>t<2??408a5H@bNv>ndauDgHZ8BS9VTI{>@`f<9t$Pj z)_Zfmu4J|3TH(=F=fE$Q?p{+*d=AZ;zkx3G+(<uak6+etPOUE5(DyBE4`#uL5fS^M z&wkSrnwj^CkajNYg^gQemX=-WN*wTMCe&;lY?{yeFjCPC5y~SIbdKsm+*(rCx<fEE zP=1=5oA~|jO$Aa)&YvY*#D~+h1?P)N?8SSSMQ#B_(5?*X+MvMNcMq)|zCTFG3oW)u zy+5KO0!3DhF*dd5C&Ni}zwRg=R80Sf@KIdjZRf_LcIUDqd)NCXer6+t(h?oQ^SidZ zg%9yoEhOoJr24g3;>hZPuKZiA52!X4ol^eB;`*eVAjjdmW5%Q)-8EAtiYf<VhGY7# zjcYez(8{oZ{veX#TdmzUCs%&$;r?b<gIjyc4Zu+T{M16*ZRrKQ(A~}C><?XO5TVdY ze+n5>LZc-VgK4$txFs1~FlX|l<RJma?ld#PPZbwu?5eAn%p47oA%%97*zYj2*SE;; zAvo6&C0NFidLxW#YJgv)>*~0C-&u9BukMhy(o?zTb0_Kl?&y+4kfQ3-3riM%&$0Hm zP;Rgn+U#Y(rzt9mAVNpnBM%u>tJN)-t5_hlBG9>H(1fd4U)n#p=hi>Z8}Ouf`kNP@ zeV)8`4crkrdA?&K2u6u`SQt@Ck)+C!+igNvzCD+ss5c!kk}P?!Vq5UDqzmEFvc)x7 zOS(DZ6p_4z`S);-SYO7+Mr&SAb_G00lEqiMjh{Mtjzm}DT6TKlp*uKj>bD<F1s*CB zI9!X1IsP7y=U9OY*GqSJIIjNKXnbm5(f2Z<5zhQ5aDGwW>OGVPNxtqYakwp!Zmpma zxTwr9>^>rH*ekR=kzD3s`l|KZrZ0v-UhJLZweFQ?Rja`AFqoC5b`Mtl{<cMr#}MR5 zTFSsMSJCM6|Mwj|{)UNMkdmDR0ZFzF6`4L(q=RTqPBTA}PaY0>;wQ3mG2d?Oi^v;W zNtkt<RSC^C*G4z0`q#K!s5(2fJRCYI@>90lcg)BTIGr6RC*Rb>f+dxmya=lJCYppP zCn*PMne4su`b9o&reZg>MsyG=E;KCa;csz>Y1mIRTk&lir$%eVC9ve_P`CZNA8~yj z2=S|R#w)h}Y#Mz<WtV-UfNd=*er|2!sbYw(#a36lnAEy&6t}XZ9?pDwxVWNFjU7SC zr7>VUX*yeUBY$amqH;^uuotG?;t&%cb2C3Ehz9B`Nx>+w;n!GG0lXd8_br&sGnZ+) zdW$;)NBvA6-*&mzbicA<l6okiGf|0wSBo{jUXe~ntt{_XK61kSBs#@}RNVXXS*z~x z?q0+B1o_pJLNm9qLrX4il=KI9wR(~V!hWsIQmgqOhct~HRes_~<<R^w&0wc#!c&D? z%!F1OB*sLKZ)_Ab<SQ#+xNa1GN@61Cocj7%eE?QxVPRFMwP{z^oPwpdhg`?SyuXIe zY*_*wK&!`!>Cc|G!hFe*#jxfR-=F=jQ|%TVILFC=3#aju)C4^89nSKNqM^v^kp2i& zr|foV6fz$eeq+Wi0-PND$!9`L303tIvP(uzwV0;8@?qd1&jpBcC{&|fSgzzPXBSze zhOzry8PF_A1W1aC;B^DQbu1jP5J2~{rslw<?Y^jkHlZos9nEp~C4c+_iR-)v=jx+> z60sig4^UHmAxB}wPI_!{*10x8(^FJ$UJ`KteL9<+nxm_R4w#LD=?aBE*Dsq_r;Ohg zuDRQ{1s&!8=K{z=ySEtV7qDlmj)b&9(@I=Ky#+!I?2SL+wU$<Jt%@qfqY2Q(BaO-E z=y=`2lMZd(UlZd%M$v-Z(H-?rF-WmKS3GqY2^`5jR`j=QZ`!z7op?Gt)VFfjsx2F< ze&cxh^Z5I+O}%ZhEi<hBOi$Zo+@^wjO7EAW=eW#+Gt{MGH8Huu`kA(c>KHGSp1w=h z2Krn7!0pu{9Z6qO<eTEC5?Lr}ahz+cyjr1SgQ|qunz0d$W=IQkPS2~NoqVWXC9AOT zEq7z1UaY+SyuSLe-*+dq#tmUgyYu;Zpycks{m%s{>NmXVFhf|ZO)kf{=KA2RO5~xT z+G>-kh4+~Z^VKlYi6WfYyae9NIJEWITrU^8E!_APP7bL8uR|0UqY&jLN%XJQQj66J zI+DQ(95k=!s^xlQzs!e%EUWClwpmeZ6L^!63}bNkAeA<wkFyO66&>`np1m?}hP$ob ztQVmPRa6fmmynaXc~q9DDd%M=uNZP7x3j8UkKcza{5!NL>jc%PGxE1R>NA%wp4sI} zfWHOTW+umSLX$bY7$b;{><@p*G7t5IrTr?}y0SCon6Zw)XDXZzbDhdS2U5+Wvuz%o zbN`W(BF`?n(({)_OXmnG{<<GMKECFh`|0sXe{a0)bkg&7Z5i)JaD<;Ekk3sgFF>q@ zbB|L`5Sc(V8K&Pat(mZ@tVT$fyHSGa|5jFpJt*|u7=4<*d%8V%ODICal{c|wT`pKt z<JXeWFHDFM%u-$T@q^!;@z|4wBy`G8^r?mTH?g#y+zMjP{|cU6aZ&n%#)-$dkt;jz zVnE5~%3=AO3ht%~QHo4y4?e4S>HHM*X`SjOWU5(5TX28loE^^0vC__xZgQhcgxlLp zY~!=)rNF^iaWv8z&8Mtaz04uhCPbPOBpt7}@4Ip*M}y|~6v@p<di9#hd<%jI9rBwu zW$)|y=p#lMc5NHkiMo<Yr*D*(lc6oHvvbNnX83cB<(4Af^={M#2xT@n8+vM(O}1M- zO5_VFJFlA6(dLAbuxV@0S0Fm1({(p8xzpUG)J9ZS^pS@27de)k^*wm*XG1T9bQ;)n zs%)X?`QT~ED?JC;em&&4*1O+_puMV3YwXqt$Ev*WtSjYv;v2eV(EA*^kZsXEp<r$% z^h>Q}$}Z^2c!E?RJpiHteVFlodF24l_nEVplxTBv)Aii>y)*s)u5YSXz_fnM`Zs6M z-V)GQ@qFuzhHyg)2hm-uq7&QjfIF%%4AxcHSox&Ib^6I$8!jckXl0Xf&nX@0gbo+W zPlqznqZ|Ai#jj||;R;py-qx(h19w(6td)Yy3q6t*9}8Vk{#2P;3cuD0bzJ1_=(Qgz zd*v?~Rb|v(+z1)4eEFd#9Z!2}<vxcad#RHyqda{uDyAH<m&~yJ?XN>(M!}{w{^82o zp>TdeSV-UBlH_Rg`}CWmxVbAk_R`94stQ)xy7}eHyx03T7fGZU91}RKdWtN2x;x5* zcxD4d$!R=?&0J0siqI<kTL;5adOoH0w(imu$b{3JVm0nc%Dv{psb3G&0d1<h(+NUn zx6u%kN)k!BH+S{O;X?d~<*Ch0D7f1ba<o&Io6<_6KhB016HXfDQF~cXSa^7z&5-&P zCzkhGlrH2;Y`C9sATE~ER}QNG%S!$PYV1cj=n_`nt6t(18&ulayfoQyOfAK7{vv+h zsI?1xusLaa+hN^%{HkI>KwM$kLN5dg@ShMgHiSPF<5kgS9xqC8A2n^jRm^aZFJE#` z@aHvd(+gE)*hB?te7cFxbPoR?6dc2Bb`ZLg30SPKtTae+f=J3bG_Gs-%Fh2RXFpC8 zb*+~%zL?PRM;zyj3fOAPz1m+k#C2KUI;<vu{^_C3e-7>Ly1pk2Hz!yjr<J9z_v@aF zBCd$yA!u$NQ4A_jb6uoR!UKR#C>k6GP;{&9D@k3Df}`^|8=rPNA|?Jjc%^vObxc=- zkJmKSQtk2eb?S3#Ld6!-K1sKP`U(lLbU#UYu|~*CXLT`R_KC5~DrH5@`UPc4mz3si z&ocisj~movxof)5R$r5uWsjDWoP2-y^ZeYtg_g{c*K87ql>Yy-SWyp{2jkBQl7pdT zk`^=sP$(g1TbSQBbp$<m_xrD_X@C`5@3&O~0H#cG7(k}z2PSMvbap*BwPA#WAv*y7 zNxu~!5Dujt8UhL9m8*3cN+ifVI~yQN8B9y!aHS%z9*sR*KMWl|%m?Qqo!$aIp`#*D zsTVVO;aTwKc|3`OS~~GU4SMvik;5U%+kvpLNepC*g_`q@o?+^giA{SsHS6KCiibJo zKLjGO#Edp&i|8Js=@Ea!4DrIX>x`BgY%Cpbr;|8&`H#x9h8}Hh$Bg1iv6t3-#p~ss z*`VCJuZM|P2T-(tba2%56a{KIGkOTL5Wq#ArRsjhFgAWL6z#-f6Nzc#lwYa-gBiAb zpM%pIrV>P%<YMO^y>k;gJOEyWhA-XURftx`t6?~$xX9HGKR_FTBqGh-@Ug&MIv2NB zhMqVel2S~!EE<{6vbe}eP<;FSb#D?6(PlDT%Z!7>XbOR{?8Y0NlCS?)<Fey6qqbVr z_t+6$ijWq|%x@N{93h_gy)enF4w8XCM$nFog6p6_52G6u%QpB`30*`nE->l=LIMKW z4=Y#NS1nmZ?aoHBnkIA2$4%$q@&Iit%h+z1ObWj<IDXY#e{SXD;*ZishQ`6H{9^s! z(Q@mu9sA{b=jYO)&1F=`k2v*1O~PtEzWRdhP2CYl_So$?`d@z$-X!NfdYb}h=$;T= z6T*V4f^AoW5sybHrL|xxq8MdV>OZh}2<M95x!yw*=T%ggVojC3ZjJqbyX_gGo&wt! z@;B<C+`uMQO}&02qxZK!E1Jro9jn<eZ21~!r+fhJ(S~q4!USuDW7O+$%~g<qjbW4C zw(?{DLJK>G(?c_{PChRVmTtQfA|qq_K(e@7=3}KQOKokPzL8+de<=KaBN_mJ&OB?C zGvSB6V<3|}eq>0Ztja{aKF9fJ+O!zyfj9F`{c?JF^fDvRD^+E>?DW!FCwq6fH9e4; z1ZZ%Zgfb9e^Tz<U6i8Z}&z+*9!A5HYc5G8PYu0g*@~<UdB&lC2`&9hN)Yb7QFky4J zp&c!2sI#Sa#D>3u)pR+`?%T}h7VUur2rW^ItTdJ6I&R@GwJok-6)d`3$^4t~_CEeZ z80M^_<S64v^f@`r>#sT9tuqHu!6-&SPTVzZ&qK~_{yITiUS%Z+xWSV}R?LQv7KPGF z2HPOI3>=_Tm~NZ~gi=oFE^<LUj19M~Zk57Rw{EPU@6H@}`I=UFmMep^`Up9H=!lnb z>P|J08aYUR*w3#U%w$-kZ8b_@E@k`DQf1CX^v(23``F9y6wu97CWF4g!PG@o%q&Vp z{b;ox3P>-V`d&BFUw4ihUkhdI(S819YZFaqW-;9HtN{$+okVj1)>M>m^DYs}VK_IJ z!0=&+QPKhp(|++eotHLy|Jt8&Y13Xz7esx&e&p3hkGp~6*ua-r@rd_u`&e3utvp%% z<uAQH-z8BB|5eS-*=_dd&P7AO_FpwN?C)EhkIm-8%zzJ`yIm|?311GUNc*m>VEm-? zjN|FCUJG8IIyN}(Y41L2^3b!5dD|HrY=$00^pHFtoPrPgBC0*&v9)Uh`4)*N?lPi{ zfr&g1u^{*W&irRk_;HU0<p;fYC5H`hZN_iyZJ=+Lz>!<C*s8JLc#Spu_ee4XK%_<g zsx#b{ZdL)^Mkz8uyff`FP1~HvKu!|?19<s3&OLN`loIz-iETj0>}vy47|FU3Vnt@$ zy6?{Gi}pAibv#5p`rvuI{_Tc{Z5Z=DPgFl0Wb2&7XpFg%Wx;t8NYEI`KeqiBNxBfU zNh0R=?mYIR7l!!R$3(aFE#_x7o5*1T8WH++MF|;!f00bQR-S|dh9>=Gg9Wz7a83Hu z+7Bd#xneYGU5Hs&eq*zzK4ThS%QUZeF<B>`p&tNp2>p)FI>v6<)V)aJVb)7uP#k+V zKU@o^{@#B#({`+Wb2+Xbswr51Z(*Txv3J>EemM3~smC`;QIEIzE7rc2Wks!9J?@jn z5D(!>e;(nr3K;ew)^rQ<Yy2vyXr~UeEYI)C&*-)n0&U?RbU7BiO&k1q!ZtOx5(6;4 zQlC`bEVdn<6hWGdjIeYCodifyPGxP9b`r#J9$t?maiap=bd2*RM3E;vG0zSY<^Q=p z9#DQ0s;CZcQ#o7%N{8U978<hapnewsx1Cw+P=-FMO!rcOp@(y2^Dbh>a#6ohpTCVn za=6!pxqY1*LqWe3tjo-fsoWKU_{rL~G4Z*4a@NV%+v5LzxEWJY2(GzYT~WYf<tbY_ znXWlFws!@61Kn3gi~kMBjzJ$d0CVH9G~OE8F&s*<_BAlmFSosufE{{lj&FuJY4h+O zWsA#oZ>KfmqfM3ecC#~yYY$Fa-WbeH4y4mFsg<1x6N8<Of{WAIamJ=>!Zq{7$n|n3 z4kez^Jlh{_z!gsnDG96u<+W-(C1%ITr~f2Q?xW*Bt=E~~*PZltk)i}VI6HX?sp4CA zZHo1Y^--|kFwQr1vsP6CAcwX4qw|t}{Q_j9=#MAov8fGFPUh&-Xbmk%SOKRE42g0O zKC9b`UtN90doSq`xwf{Rik?`IV1&Wy&-+v1>@s-9|6Q+?RHUWZjN-HVeH`=+!VnJi z2v(%oAq*bQMk8ZmA?Z+QT0HGez{E;RuKsgQDf)ZwS+Na5I8USOcXM;1x`#TdB4m1t z@nZ`TJXeu}tAdoGQ!5&pF#yY;ex_@RpHa3py`{xdJK)?SlZ}pJbzo!%tP?+~@*T3O z%#<2&53}NB%^%u~vpu*6QXn;i$81B@fT4Tsy~P#S7Tt$~V9o1Bgz`RmLFHSFy!V#n z0NZeI|Ds{`XmK4;Z0q)}w6brhXN5Y1V;NgEQ<|l!wWAL{6^z3ZM#}Lnu}rE5EjW06 zVQE@?;p2Fqy5`0)WO_7A?}n9;bruC^aMI|{kE{38Bvr5Oyl~g14lsl$39#^sg`0q8 zPXNd-^4Ne<k&*+n6daaZm+9`Xf>cF3-)M=ZrM=MiW@vPvH#`;63af-^wHN;A*M9?C zC;^euBQz+G8olUFM71{gK-lsMZdD4dzUeD<nuqvLQjHdrj%hf6{A*W#1Pl-+1iI^s z;s6YgAFr8&j+Im`?@uW$4PfvB_X@CLI8P*lpvQJe(Qu4N<{9CCvV9@_)aV14k#ukm zs2y*XegV_pSvi$e)UttqkW1OS2Q;e9&;dgH!+(1t*O{f6b9-r9w)Uku^)+?vUS0+J z6+dmXW#flxN2ZyF2=|PNJ+`(+{}$E7G7p*R8@Q8sd3soa`f-AaH3Xb4mJ&7xZYxz~ zzfF(a^Lmu>&b+^^!+#E=ix5DQ5Ij5mnSrT7HjkI8?ISqdihthXC+S)H=lFT%kycC7 zQDqc4MaL}%a1#btV^E02?m>bX1J~WH>uh#i;Va5pKLFv9WBWSj2mTeQN(w-ZBC)Di z^EW~WoxNYG;v8lyM$5Ct21a^ff?z-$YW8iye*`<h=`Y1a2|Fv0+>fsjzP|<pt_BpQ zzu?}@!Ct{Vlar}gIkI_2>rxIOS}$dV%h*M@G|z%6Hsf8<-QtS`$jJZ^SR}aZ1qmX6 z;!h%QA9sQ?YdR|6nYdS$?Gd<Mk1+52!tW%4&-V?y!>0?G@D7}N)`?sE!>*PPRU~Ma zx#7aKg4-(vqEw8dn7u2~Tl^iW=G&}O&p0u+dG<>|ci7(5@&J!zGMLJ#p{3c}=7QVn zX$d{Qx8#29^f*XUz-FPaz{-3@U)NG3zmHh(Nl`s`<KL32;q931rGqrj`{31OSGq3| zL?J^!C7E8WX79y&xd?^y8WWXtRPC<pFScLASY=b07`v^F?H@Odprj7l4s^ltp}r%y z&t=_l_BeQ9^h8^-UUpAmPzV!!njg+iXHm8g0G#xawigx`5m}y^!VsMP3it3c)CTy5 zwDyoTzmyc=pd~UCUwenD$XMe0l{7?g9MDSvh3eaBe+)#l26`c-X|LkFF_lY^BCU1W zkT38FZ&s6MDqa(FX0CLi{Nq%)G*R_PFaGFO_d9j2UT5W1N86miv}k?<$8S%C3pQ_g zCfa2E<=H+dQ4zH6tcw%n`{Cs$v$Zy-KT&#?KS?F1fs2I(PxXOnnWJ=i#8?*=D{7rM zz!B%-=VgrX+TE3~-h&T4B-#`u#EfIqNd!PLFX%QLn&3o7;L=O~ym#3C!_gB`dz03{ z?BfG1V>-U5&A7%H5pVU+S_`+aSNo-2iFpAaprO_8&`9<@QP*ly_wBB4IoE4lmV;M_ z?@bOGH?Fyi*2ndn{y`;+)$e{PH~i}dy`6Sb6~ehQ25#JlCTwi@yiQ%~D^F%+z(K1- zcyi$V=rhSoO6w9znvc~!5++I@=ppZgCMnzeF7%5Wo<qL_&d2|klU}JBY@E}EE;TZ) zRFRuLkQx1oL)3mr7!ZsVmUw}YLPWxAaaAk#6f>1e-Xb?S9YS6dD(m_POz^8a|3Krw zOCi-qUT=A=d=EhJqGI&E?d;oCrb<{bOOb=BSVY5Vus~*!Jfm)%Pi&=V44Ws}><}=? zt+>(VXNb_P!BkRdjdl;r3qISiKp?=lbTBY3y~hn8I{k!kh!s$S{n8B=fY7l}25ono z4{iavmk)nqi`(>7^<_6_<mA~w2ezISLvf)A$7|rBSCrh9q^s@ZUTVYkx(#LBo4pE< zj?J-lU1HLczk0{>l#>d7rb+f>2sz%)%|11Sp%@=RL3iQI4&J&E&fu%<2m#{BfUr)9 z@F)4X6EO)vPj&*fx-JVy0lGTYSZ8kZScm1bWu^Od$W4E;U`Hf3C0<(MZ<@p&F8d8* zrkq4}>#FOD$r{&VIhkRC@Hz#CJhO<7v*`Bl^XFStri^Ns7R#ZMjKkqN$ZgCH<>c`4 z+7N6ipjYlmJlWgAxu*BI?zj``HmbE>YFYO8BoqYjhSk2+me-Ml$udy)kBJ#6v+nH^ zqQ4{7+MLF-?%b-Q#gd8xGCxDzP?Kq8%I=WXA~N2zmK0EpA33rgd^>B@FZ@X<#Xl?e zFJos}Q#HU1Dsdva6hdxH{(WEJWdJ-oi#O)vCJ++}1bb>L?=j^)R}`&CDYR7Un=I5J z;BOe-yH}}(0A6Wf(_H6>u3CCNi((z{A6DW9>~DczwM+%sS+a2QkwK}SIsUBfrk2<n zoOU4s>luzl>nZ_$I4_+0a8q=lg+y*KO)jNEDP{`k!5-Tc!rhHYaroQ8kx;84b^vcx zz^(_mv{@ZuOFlgWnCW|$+dNub+`5GEV!O<=;pvVJ4EMZ+Ep!)De@S}}veaK8#RW3F zE1Tns;T7Fh48(hu(?(2z-CEz~f}4g9eQ0+^%NFjI8}KsJ3I3!<Zle%u5le<M3e2&V zXXgz>tv{M#!&K=FqmT$cnRbCEB;!DXz5dGaL+$1UL@Ez@0;Ks1Uqvbd-F^G=s9ht= zIHQpQ%%~6EpcS=J<I)`@ZNErF5hguHiQ!Yu`Z`02O>3r<!onb8I_fk;5tp$R9M#f$ zW*)N!m(hD+pp+Tb5S>rNPvCcWw?|0O>Vbo^fwr*slHf?`*(~!m-ha_{F~o(Tpf*AP zMG+~qqi2Wpu21(BB}@Dt)@Y+*00P-1*5bd*vYYb1q@zF2q;(aH(@zADR>c8;zG9)( z8e#B3ShVcmWCR!wAv>{yb2%}kswMupNb2BDs7?DL?s)mO{zH6#366OB`8Mg&M@Zqb z(yi$5Sy54~hWauI{InlIt3_(~!)zt4s}ZtOjwU&@LHN4F^L?b`oF(k4w;5>ndi7sV zs|t4B(v^SvE)MxRRbp7OfUnJ8*JzOs@c8{?W=rm9wglAu$M_xr6!fS*>u`NNq8}au zC9))nX1+3jo`QCzbrPiz!yFb@^ze>G5Omr{RTXCgtx2A-$C(KoVb}$D8g@qL^QRga zCRRIjRx3fv5X%mxBVdFlH}wXR@4?Ua%6X-x-{a3rHiQb@Rqz;)ai+#Dw3w@Xa{>Q} zo4VUZ9hcAe@MtSNuz(N{Mwk^)N4+41i*Jm3_Z<`6(xal|vj54us7+lpzF==w#fj0| zrrB!Y8S4luQt|X&1DMrVM%LUrneKF@4G6zs4qK0}1~?{hA*=yC^j;PdCd7=KzKhk8 zUTsb6b<N_|6wXAMg@~B84*=T!J#*Gxj(prA3yed1c-P_4;L+<2YF?csE~~D1FiUt^ zRsD$?(2}u^dmgtMG-(~KxqS-I@22Iga!@1E-J&^36n`171H2@onGjOCzFyv{YfZ72 zq9x%gMSoiL$CnFysPx<tc;;qGIlHc{`f-@?KGf&nSj=+Qd1JVc>xYH86j8JwPGsuh z3m?%CrpCreN>pB4SV%)a0R&9Ng$hW%e$)LI%g-+MRf6Evwzql?J|s)LL4l~qZ9Xpv z3me`|tjJNPZD61qc6XK@us^0~53$ItwCL#;=!?w)K+seEAxFk)_bF4+p3@PbgDIGb zlb!VS33t0b4Qk5G*Ds!plv8-sE%~KiOmFLXNseq?e>~0YI6OU^lw>71$>X^?4xd3x zQ^Hegr}f??QsK|d;%QHBsN(}iO|fG=X*6pO8;dRP@bQ9f@auo7WH=91#nU~Vnr#_O zkr#AA5Z}as{Q6UAL1sy_t^Sz8e5(O!yKw=phaN)?_kUawt83XCo*wuX`>oSiVi;O2 z(i0`cxK^;Y9S(&<phGKoSlHs8PI6{mgjxp1MhNWnHO@C~Uez#=g>`4snU!9w;&7#@ z@h7SfT}6QVJQ39F(zI}ttO95|2)dnUOU+)NKzIABTPUDFNCYla%Sa>Uhv?s;NI83n zOJQ7z>(q`137E9}D~<Wyc(IMd)$TKd>pR(_+j6w|=tQzA7(spy6RufAsHOm;joa{9 zE^N!GL1(^&>Mli4KT4aZ`Y0`K&YEP*M&Iv+n)f+;nu(OvUTb*Y^AEQFdadrhUArZU znW_K|1-r!@N>uoW`Ll2ygP?Nz0E#Z?5i?!?08tXgdfsA@1<+o5R30@XYgVVVKfE>0 zi%45Vl<v)IPj+#bm=+#5S)5h%O|~^TB`PNy3|}n&TJ@DiRr5rtEq9`Lw9?${S0sOX z>5o;f4=BG&f(zUo5QVL*0$QvO&wzP`mr>5Fzb|3KakZ@wTARHuGu*1Y#1pU8r}KaJ z(gag)R37VjLSJ@UJgev7<x%yJ6D@+9lbsNqty_!jpjE50bH){1t^^jQ@1%B3+1np+ zJrtX$UnGFICD+NcW9QJGI5|~-z6(9oSJTMkvBALQxk_@=PnKhyp8i*)_pTBtJ^-nx z_2U~ocKJNc(SHa|#ivJE<fqqnsHthq27jhX-W03$8gCfb<V+XCR|ySh{4{<wTxMI1 z+xu7jK?AwEwiM@u+8wpG4BfY#{?^X-EWV`Bx`<-`V3FCjUSF=geq|=ma0F(emU2GG zellfPEOAQq`|63pSxok>Dq}}T1an~lsjR9X$CxWASv%`+iw9O;aQ}R;{MJ!N)0OG& zx$IlD$@e;A?cXK?Rm%>OLIIzB;g*L#3uUmj`_2yZ^or!g<ErUlEXa1jz8rrMS~#p} z%y~=qc}aTmdxAYe=I2zMPp^{l-ZV{;P-s^fOIL|oQWyF^&eS_Oo6jn$7D^RGNliTW z6*-L-@;L3KWM}E-KV5ndLOt_&U*wy}(nUts)oW&y6XpIqFYHe3vX1mckdWA_(ZFi| zo6fUxDxs(4cj1Ce)el2G78704sc=POwJbN=UsWK~wM{|}_>(XA;zEVUYH54h-7`Kr z9i+J&Ks*NRV`smNw7W}8jttx%xO+J14mR-?6Q0yr)hD<n#vzJ$V~T&@ua{qb{HEM_ z-q<Vv@*)2`8DG2fr{u!*v92uUP%n%jG?L<5<ZC)5#EXlFM?cLKwLQMay-D+89|~V{ zwAox#W3>r6YxbpC?cF(v{ck?lZ#8nr`cSp#wOt)6T?}-umEVyx^JopveK*+*F>)Aq zkPYA&pKhGx`vRjIXtM5^I_Vdku>y`c9=H8ew4=?P^8R{(=2izlkec?t=>7Ndj;nPK zW=+68u&_1_LsMP0Y=)~yO0&(fx@nk>^wUzLAJI29_tll+%wP`Y@%g6ZRL9lln4=z9 zE-j>9UXPlSTC#ac)05DD#=ToXJHCnX6zh0N#NBC4!~+*x20k$cRTB~<yeB>BoK_1P zjgvuKdn$O(XGIY|yo{>fs$Cr~MC<5lEnkM|N<$`0mYLd*$P0=~^f>-RayZ4ONM-+^ zb7oi0443}z=<pIgWP~+yCfcqw&?4HQk+uPW+WJFrvNWMjc#=mBCKdE1Xv>czZ5;lo zsI?jkhS2~)p#P_%T=y-JTu`%|QQYN!jDb1|HJn(I>*T%tp#$A^R{aN?26M4N509;f zp|>kw)=E(_liRwx-{$f4s@Bp_vu&G#mE@|Uh=aBsm6MAe)2LWJjCIK!a>zI<OJHmI zvu4W?Z+nP`{*5N<)}K&z3gx$~Ah5lO`(M6%ZVkgc2T22+Ar5#N!+_x-%ZEMAr;qh~ zp2h=!Hk*i(tlYOqKEXw2jx1q|+dta>KNo;F-j{l!Xhc7fT=}iZjPfVEzfa*DQ!46) z?)C)Rkh_sKRGrqi_rVj9eIP_7J`&co|C}%q`{;6GjB@j=9J}Vsf5hO0D7=@0cA4x- zo)ns<<XR1tH2;t)97?o)Ul=z_R3fL@*Um?n{9ThIO`3rkGSo>b+q}ft29^bFzafXU zS;^9ymwr(dR3fIZ>x!MXO!$YQ->*Mwr}D|5m!Js6cf>93wGaje>R)oObSb7@VeYp8 zUm2F82o=@=l{ob*g+&_n9xldbJn>VoyKV#zdIW4@vzTjTIiPJweK<kv=tgRHZm^)t zgW=29cL76jHGnJ;S(Z~h?~qfcmV<Omz603mTEs>3|2;K-vD`l54AVv%_vI(!Sj`#f z39a_t{rX3=<PG=OmO5LDc$8;*hmo|H&G<u4#lf@9)6SY9-OIz5*K-WK=hWn-IX9S< zp@er{TN+}JNoK-_-jf??sC+rW>OQ?>CXzqaa`fC&YQj5mBTCGBO+Vj;8n<MT7fU_m zEG7FHu))}V_bHh*!fr|7#7mN5$-h~O%EZP4ZHXVL@nq&*xQyt(Un<HUV-xNC?0Fhh ztIK#f4`@k0c6i%1Z^<&>meDM37Dz5?aAK5R<*L}SGv)F<{6-(QI5Atyl|VYE$fX*3 z6j3}H#<lXsD0Q;T>ub?Rufy7}<^26lHO(IDX>*`)sw2-vhsSs+QOEO2%ViK&<!-A^ zs5kG7Ihc-|Aw$E;<hhl{xq9O#PchrN-P<f%%vxv=X&?+wN~qTI5x;}5S<l~pyZZ~@ zLYeRYEqSESj{%26u)s5TR)RI0o8o$)>DmM@S^~b{bl!Y2m@#>?4z{wT6>e2Sa7(1l z!=VvLOZ+yFXEB+XG$e8NVi@%OwV2vhJSimcOk2Ej2M6#ID1sYl-UZ*~yTH&LUG@ez zr{_hlDK@2ez6^CHLAxwPI`_~0XZOYrAAp+LQrxmNC%)yi<nEC?Rk~A9V3nbUid$Yv z#m`0?>Ee{z&0fwdCk(WlC&;0`URONvjThdJc!Xb{KE$!F3iXh%+CV>Un&5dZnw>Uo zlXN%RG@<;C&i--`X%}cr`^xXN0EU{Rfin7s>}@K+-&9DWYghcb;A2jKKnbdJW>pau zlE_8I5dmCif(V^q-+pAqUb4;OP1Uy`VpbZ$W?9au1>|4j_I<HIf*Rbj4)eZWG1}OU zO0+|k$L66k%Ynlq*+o_Faouo=mOx^WR^O>I|CEMSy~6vCIjs0$$s%iyXvU>H)xJ;^ zh(ffq<w-jq;EvDqwh7>FdrsQTOUrX1hmM_p=;?ByuMHw*?xG)x(Z{7KQFV9iAmI$0 zA0oBKt4$G_sB@EIlsJcE;rniQ(DL;6^r{}WV)!qZjtffUH3e$2$xUv<?)B50HEGR9 z#U)N%qQ`PVA>_ZtnU+sYS!-dK16-o0qg<jGYI7Y_Snt+MAU15B<N82UnzWG1!!Rw$ z(M>|Nv37k3OdPB->DzC_B4(Py6HRskWy>tZIZVvR0zQ|>Pb3$!O0s~Pm9R6mSY(F~ zPwx)=$(zN-%S5-3h3DUNS_#KXtkvp`Ik$EAKsD6roHSSkJbA@&>SG^u8cL7HXI^iw zS0|pwSI@7&DzvV#N)c&19;N|af-MG;2dYx7Iy6q=G?xr;>4+!I4?{06#r9(E_CB2T z`IQB!ceUo#Nnh%1dHGtTWJFCp_<Wit&a=Z!%hq#GX)y7GN!?ee*>oySHJ4sL5l^$K zrQICO-&Er3_G5zR7H>t3l8HT|&x|c`);Ke3?54lMR?#P~o*^oIFF^qwR=-14_9vhG z(3~INX#?usbeZner7X@i5T>_Xdf+7zv!Cxu)?D1;w)x=pGOj8-dbT|NBdl(#Th7xJ zoOI?yxz(AU9{17U3uj8ZH{)ZzA<`PUT8(vbS?}t3isF_kbS5MsiB&-c`cV*d@~y4x z22YQLnmm;6Av~q%-afBKI}N-`w}H4sP0ByoRQ~Fu$0TiEkN4786OhF%_*wJbzg|J{ zf(FjT3`~4$_q-@a#CwJUWH3(-kbEU6&zloxIL<-X#J_IKA&d5vN1SJS(HesHAyN?! zMXQ{~<u6}9gGr!yu`iR*=ISA?_CT}VE1l)m@?ex+#=ml(UyP^^7#vcYi3TA+bT<Xu zJ+892y~`A?;48HEKfJ<xj%+#rE&;GKK{tFR3xPj6);2%cRKKy5{gE-zoQh>=1IE## z{)jKMmOAp0YBrbAwhP+S&Bipk5V;x6Z0i%X1?z*im}GJlRyNDm=lvI}>p(*$$;pbx zJ0Cqy=L2v?l|e}Q1w7t)XA|ZkxX85Uw{_LoJt`jov*pcgT{<GpdrYxncWKKPoc9b@ zeVLSw2{`60ekxMhL(tmab(Fu>=Oq?&<61;}p#ugVQhTd&mw#T_MSV4gCbTeqaM4!n zLFFx|E;SHOMhbVL1@|UJPVub`|J%^C^P;H0K($b-9jVY6ttZ%1PQ7~hV3mut`R<AZ z??>d)pdp74t6FiGgQk8}raNS2GpT9{XTQ1bP)75Ju-VinYs<h7cxkx)P5CDeIRg`s z)-30Va~7GkM153?mQvbH<GaJDf)oZ?-|w4CMW2pInn}6|i<*XA-5f5z9ndf8v6u-h zzz`9>y>3x+SdK@sJ$j(jY2Y#-iGN4-*6#tvG{EvwTrq}|^79?&a8AQ>#ci6?%*ycr z+iq+0VwCJppQP>0-y0xx@WXkESw0qPS-$<v^Xj3l9^yisdvr$YAKu@O2z6<MLDBl! zcM;{!P!`hvX)&prNQ=f`(}hS)9z$Yz%VS^d)yzC^9OWwQ<xC=3V|0*~Zz}dDh`|xG z_AqdpDnc|dN5yfP)Y)FsRh97y2u3<JT0t;<CW28GWR5{?pD$}$PDFcQcHNk7e?0A$ zMP!y$H5q*S^O~EkRCv(oo+Ui8CO>*F+p+xfHNX4p_a*hek8?W|Dv2S(Yfs_VYhdHy z*J8gg3i>1ABz;P@ba`znT{>zqlG74(F_7n-9h@I18};GysxSx~UdC`aUPG2Cj?|_2 zbuC_Esi*+wfb9$*N9wL)X;t(qMhOF+rt~sKX)orX4$u36@aj8UDfCO*F{;REi{r_x zR>au`hT`Yb<VJWUsqfxrxT84Bueb<emD11KlV<Lg&5!OSa;N%UwcvUWdm(msf!le& znBI$rMOEQ5cMAlhMGqEh0?i+j(==i6`d+cWdb|sCOrF~nsXq=j@o})4_>g^`gpL<; zHCR?E{VeUmB;1%&kkYIES5EmY2BhE18g(mkxcOj2H7?8^`I-TvfC7*#YWoyPojBw0 z%iv=Wc*$3AS~b>`AfzYyyly(hO7IPn&K}67w=r!fAw8KDTM{G&EVrv+&uMhFe{(dv zyD;FgtfH9p-%XV9w%$58OTNYLmb4_k-U8kZ*W4*1XapGr^&Zm6vm|BYjN5=gj}%Q$ zxQM6<^81i?(sx0vblo_`ReW*buUTBc&w(ui&5b#v*KbQNp8+iaKGaooo2N<zr|GzT zOq{6@Vxno5WuoK8HR}hh>u#E%vdqLOQXf7}duB>{VgD1+uGD(ZM^3wftj15B;i&e; z?}-wj@sz`wG}@Guv0@;mc*5HjTzLxH%4>@%VF@a!@+5iqw6f9G0&4xA%v723^qC{~ zO7NcxzecV0lfE9%5XZpEEq+-xnk8GRFe@i9VpHaQ?b@vwxA0QBMeZL$AC%!d1O4`& z8qOO~J$%mYf57Rxu670pfFE|&&hzEc743OFFKng0{>=yseCKDV7!>72Ete{AUWVBh zzJ#_q4VSbDQN^EyTGoEbE#lv=yw=+PY_rOLyUvO8-nuoj+-+Sw>byH>7<L?(@6SlD z`Bdpq|0O=Th(L*?-Mp_Y<?35ks`R)WA3vuKuoPCgxmmbMRS8x-37i$-wuK7zFg!9s z9vMjWn{4r@H0G}nbAh*%|2G!YH@H{IwEiHI$aedFE3xhJmqU_ig<m5sD&|h*n+yji zH9G_UIlHy9QS7BBRYbw<KkLyFhP3o)w~(s2%lMGdhtBpX01hvBWf1$%%w5*CWt|Tf zaMqR6?11Ct_uHn`g=p3Y6$<DorB&+RLWe`mbgc^({QZUSvV#f|osZ_KjR|*qF`{m- zY*P#AX+<ll)eeu0n^C9P#pbU}4Yfz#zEw2nLy)47s;i<_{zu*yX+BH_?xTDawZt@L zh5~40WR+(Ao0Zerw{b)803JsyMedX*6JAtjNkGjEvyI^LAlYQxhYr2QDWns&=Oob@ zwK^S*4OH7Zi*l*+GK{%gR0*1C3Xi|7j~{wqxz{~TmCGvQK{msBEaekKp#D1xo4MyI zzm<@Nq41!28ceLWiFyRYT~B#i8}AZ<-@W*JGcG79eK_ia$g6EwlHu5?O%s{1<1Q~q z7Kz+tV(8mt2;}Du&uy(E$bP~J$q`w{XR%T9`;Wv{1trwdgclo1+!SL*``j<)l?#59 z60Iqmv%8>pf5(tJWtn65-WwM#B{o>2^fE(bgf_QMnvkc|X$mEx=9(Pk@G-fAmYj^X zp;SZDk=1*ai(iPwYXbK{;J#$;V%VS8uN?WXx86uSdT8<Y;<=mW*wQ-Kr#on%WM40_ zq0X3_^8HyWHY_NHG{%@nT2eS7{c(#F3pAWnTSt-^ma_YDl%QcTSp|x$^YIw|<~d%2 zyj(R8R>DMWWcQZSV4afx#1^%%_1ZDetw_qx!gG4>kMF<TYRM+qgJJuCtj|W5ew$=d zPqENhgn7(HZG|$FNBcN_NmRvF+ol4a)^`#rsAW(1URB+yAzBNwNJjGm;@OZa-ERO% zW;sWQ7{+KLh1|sFXIIk<k)Ic?Mf=hmm$hPhRN}MNGHf3th+(+*yMMtLym+tAKB;6V zlB`W4_#@A<)&`SRnWj^_?z~P<#lU=SUEM<P6F~!u@A-0T9vSU&+x*~Xq?Zs5d}{n; zU1LRmL)FO*%cpfxImIJiODc)oF#;=X57eYQv}rC8bEnd2a>J=}_3~pD@?+jXM2INy z0G@0nAeBCtJmV(mR{Ud4dR60V!zoLjjkud~T%VDVEB|x7^^*zT-Eq6s)=Cv@rey!_ zdE|<zeu{$(*^jFx5n8#uI$?E_*KaqRCBtwqlPp+MIjz)F*ILw@@&+RCj(J8ov(aj? zBE0k8Q@EPWL2EFWFYfBpfZ8`N6}7?MiP|+?MfA4s|H=Eo-g|q&RVa(IpY&2%Tw7aV ze0cTeTh&m?<Ry!Z47oW!3)2WcTz`3JK&;a8S+Wrv5P+Zm<R=8Gg&3k+eGl-d1+%o_ zeN;uFJ?BAvLwNmVdw;07x@^B3>x@Z$R4zFKc}w3b?5T1shQmqe@oZ;<_2&n*gxyEI z3bM?xc>QbiDOEMI_ueeE71}oY*bDudQ5^?uPDIs`UFnVt^9PS6nIE;T*vN1~66+jH ziE}eB-?I8gD!m#W8^QJv1cuX(3c6SS)z(Dx88NG<tLD7c#>U1r|9_`j05SuXyl?h8 z2)QbLvr%%iA<ke!#SmPQ!*klOtD$45R=aTHM=iKB%E4D~Oz@u$Jq6mQ#~9GDd;M?K z<Y_K#e{oz!!CM7zRP5QZulkCu8EERgIj=oBrr2&SM>EsC9^Df8iR{aq6qr;<-^}Lz z%TG?%x_HGrjq_tfLLt32;Ego(wc#U`N^&&E{)y{Zw!*U(UhuqBWBeFZ{Tc!oNZ%D4 z*Vet?>H<v(pU-dg1_y_5eLj~rNy4W*9*&q2R{nIHpVcl+MO|d|7sJqrjrWU&q3`<2 z@%|@kIj*MMVX1y{7aREV{13B#&7^>+B?AJEL<@89sF7hR-~z19eX<$hO7*ZO1j^wH z=Zod4V8SVzi@t&H49Oo~Kg3HLkp5gFE&Bo&25m&{ff1Io?@5BlOk5e$^mBVVo9Z^) zjc)5o_WgxFr$820)+>*W*UCoYlT6e-oWk%!b{wL|5()+TcV5!Tyj~%Ef6Q}J?%4_v zpUBIyoB?Bgk>txCzsWv#{;`_>qRdI{GdodQYr@HRtuK32%6AQN0TjzMQO4=ZF;gRe zdc)JvsixxaWyz{y(e<a=-@rm>bjJ@KTdk)7c`b|Ba4XTLK`jP9n;)$4grafrz9UXB zmR`b*F`{F4iN6cM(6bpWFR|wpTz`BMt9B%ZU(^S2u4ViO(A1HC^wt>aCNSkC4_>X^ z&an=t&*78}?N6tXw#THj^Kd3QEsyWgv|R4D2LaKrCcTuk6t)!nDaht&57jF$VninK z3iQO4Uspw-N*jobVM;r6I~SZOLlad*R@jE#X@DHYyC3~oTC(>siWKcufb+|5vhz9N zK$VgV>W|1-nV!7sL9c1)1{F0G{WC3LH06hV%)ruD0GJ4Nn_WPEaf6ZRO0*kc(o;0# z<N(hN)uJ>X&`$1F|3&d!CIhbD__U-)*leF>Kt>xAhJ}L)-i$vU*D`x{7C_0JB8P+4 z;_$X;nwPe}7qYe&SRtWh8iJxQNGQ^Kem)$<?am;Po!`^>!BMV0ui1#ls2Wi9+)Quu zj=1P&@1#Swsa8DDa`<Qna(h>cJ+08Tmws17&{BI9XH3VfnHMG@+$^GNW!^{k4hjBC zMy1hnj_dDFc<-?JsH+%Ga+a5Wg{$Ec&~RHT84Cm(*nXz2Iy?bwM%QFS50aVZ{@*d< zZb-b<!TPJGfT0GyXF_(v^j<kx2$i~FJ@VMTMaZ3cp3)KwVPn{zuv?fzN5}pvjuN8P z`kdgI{rW249sLoAQEwyqKB<ZKwB0P)=v`K$n~mO>m)O4S&zq+%F40tW-s-Yu9XhVt z_-AOJ+?Vc8nzOq3G1>#;d;Qx2grjp~-kG*shhWje(&llGQ+va)26s6p0mxmStOaz^ z7eV*X^tp+Nf$z&JMKcKNmJ!N*D&xaTLbI^mw(lnvJX;PdhHOCVc$2b;WaIY6yB_|A zKX-}-u02h9h=(joc=4wpdJE3ahl<v>s-L|JjR~8C6wywou38Da95+d$h60=&w=UgX zh_X0|!Shx7W|oMY%s{H0Ri_Y}C`G-YA78q`@rJN>uA>L(Yn_sWFu~hkP)|g0y;sHR zc1L&wg{sITYc<Wc$b)W>@dw^L%MqUYYxextA}mf35+r5@FVV=@eT*Bm#gh{F$uUt+ zN8n~$tbuZoWxXRM4_bzwKG5SJpc-&`8(w$kN}g4#zGSn3G8Ff#CFVGKgk~%B6(QXj zxB^zW8?!k-r=vF(e`*H34?|nePro&CKV4E+uVrG98*jF>5z`0t%H+BQa-@U#BHtSs zTXf@p{)XOiBCgf;U10-F?_pZJDpmO1Yj~9MLqxGEG-c)Lfqzm*(Un05p5JXZNFwNm znkL%91-)OA7KWqd(Y5mzli0u=>}#$5)V}c0#Mb)iL<%n8)k7mIPGqQ|W4V&WN}Qmj zXw4RfjLA3xn!v?HkdZ{%Rqip}=gky-t@P{+kcA2|I={_KfnpD!@7}Ym9A^~tK(KPD z)9mxoC_85g)zi3q`neLrL5lw@L2C=5lyg!wsmkiNuw4FKWs8iUUY;AO&xRe6L8}q& zjrr+tW!55ZyBUIFUj_={eH*%vlx&-sk2bFH9-s`H>gOJ&ELzKLEyE(?981_<%!H-X zUtdAWqmQsU@WoUvs^RodS82VYwe};@c|3aczCOPJmI2<Z0zW(_X$Q|6P&MRtx*I+Q z%Kij>Z1nM@`LBlKK-w$#xqjMO!V=JM>_e$m*N#>y8n_RT_RaZ`_3_HTZcWSaFX;PL z$gVbmd>*LPtBO>YSIgeB$5)xVav?jO!}0&4>MEnE>bmtIL`mt8l9Wd2MoPN7rMtV4 z?(PzhhC?5^1Ze>Y>2B#fG~CVW`+fJ`HHHiZKOB4SHP?)1KF?g3e3FDb>C0b>P>F5O z9@T8Uv|Te5`u1AAdw)uX)pvgTU7rIev-|Hn9|?K7c^zsWsu82;=;&~#kzXX*Y#<3i zCAB67r{IO+xpfYRB|1V-zpSd_&ecS2x=*OSk)(PazB#T|0P*!8L(6=A&&=*IKw;7W zTE$@S9{UsW@eFx894JffOY!I)!WspD_nMcm*)4G<dT~<Wwt$nFLpu=Do86M(9&cs6 zJbpT#v?apZa^~4Fjp$}DcUfqoJ9eVVdYQ=Kd}ZCaRG*h<(Zb<8mm^P@SZ}%C$&%%| zQaE37XV{spm-)5pqcxI#Hn-h&;q5CuvGH>=uQRj=*CX?R>$HPJ72ITL4M-Kif|V6+ z|9eN_x211++#VAMoCb+|B)TaH>HdKwfVaU|`*e)0lb}Ge^hZI877RgA(>Y#ZAL|MW zn|{+d@-3Om#t#u@6(}E7g%IW}kY?b<$9r$cGs21xbTIU_TehNp%2UszNgDfA!t-4T zxMIf2@R@Yyh92{TfBam-pZasq=PDW{BX_`uA$3RDA}+TV{6?zZW^#IdB1nQVfrxZq zEJnM&&YCwvguSR%VmlBf8S25#&YqT$p#{~6iYfMGO13w5Q-&*}r?+35@GoUZK$qyw z&)Acak&!7<!3DAaZ6V6LjjF6?BLvp`5KtN_A3tdL>CFH7lcZ0|JQ0a^eb@fy8Za&+ z?{oBVE#P()k4df9FmajQWJHNI8b}7z9bBIxdG%2|lar<0I7o$c-$tE^VtbXds#}Ih zQv_1)#&bBav@?%!IF<Vd;C%Hi(zb0Qv6$HnVZdx*m=Tt1AVh&b!6WXp>0>}b2n0$K zPMFvro)l{{J87&@*D*5OXw$_Ui640VJ4nGjT))OGyZZ;co%3E~W5Kdd*@&pB1{1^% zG-P5OX^7drh$mvz{&#Q%2Gty?#%s{EJcADJ%eECXdOLipQo0D*La5jGiL{61=rD6e z;5wG%sL_-4G@&E!5Adpc+WKUjbYUOghP7JSzCVvvoeLx^#T}Y9l@q{`*!sm7OZq|C zue^CHM}D7q$(`R9v#iBtp7PaDVQ^N3y0)54A6>$we$y{2;q1>e#(nJbjg17H#0T#e z1nd2(5EEG9AL@+xffi?}i6zCmwb%-y@=)s+<6kPF#x&G-GzQ8oNVI?VA)m2gj@S9d zWD8ZQl&+L%LaU$ZZLP9hHlD|%0Wklso&=acLPb%8OHZ<RW9Y6qj9PN1hrhuS!GrT@ z0b10iCsyV|lI@KU{e`9N{dBgA?oB?wc4l*UdTB+n$S}VjYn=bV1cHD7VSPb)g9GHi zLX-iQ^|#Q(86zHMA0=kwlV5eR(5VIh?K5Tm5-$r}ZC8gj9IyZ?VrawR_Y=tJ=HsBR zN>XT|P;8L462I|PRZAI*6(M(H08MHc-G5%eGS+SOCFs6zF-d8H^f45a1An5MKBFbL z7G>j%(dDF3A&lhS$v&O_Pr!!lA*UmV-a_rV3~v8$E=HLwRJGs=_h@@Yz^dwjfbF&C zn)Y;#@@`vEIi)$FCxQ8t6%w<cr)oqOa*!tahc2|1-wzn7WW>VAsTT`R7uaKj-@%cg zBRE4x#Otb9bXhpGt21UobYLwzN9y))c2-+|w}ZfME8P|mfdr(C1r@1(W+zltYjFO( z<|@91dBkECZ8dp$<fIZpv7E0$vE;LNkv?Vt-pZ_{f{9m>vS_$^n-6P5$U{c}vvY_~ zbEaLlGmrCJrN_wYkL};c>vF%=rr_gBTyc8X-0+8|9DBSLA!MP^WPD1Ksnsc~g=p3N z=J*ppj%aMHV0^3{v%n(9JV~tx`)zK3Z`4(vLsjeuDw1c<vROkG!;i+f>!7_ZMjmfW z&)@pAGpf&`JSi|{!JAs@^Pii!){a5<F#h5I<-<DAd06a@&tJO$_Ro(R3L~jfvt%W| zZ%MbPg;V9pN~p^ao<N`>!{u8pPDN3Pr)|@G-WzxFkeOkJdMussI+qN+&zwA>VeeM; zc+IquNGpaokyhJ8l@_14Gv@KjcjIz)59F;0o-qU#CciCt7Z;qOVl$;_hn~#OZ~g6? zeg<)+UqJQ6oCPw@O6p7YXInKCDHl^59FEyHA@|8*t`E-1BB^(wO7o*8<z;`Zg?zpY zz<BTPpJP~1@G&eUN<ww9ZXYwOeK{V=;Jse+{grLXeZ&RzG4vcNM@t9$s{lf>Mi?1} z6mEdAB};p$2C_TNY2@eN)Q?MaXJkon?ZDqFvqbk7hMkw8?=kUcmwJ!gEpFF_w?gFo zrpnyIL-ER`E-`m2v8t1lG&`Mz@kWZ#GOQo#6#`sX@4C{FQBlv#yAx>tlbudP%r}0W z(C5Cqc}b<_S=-0={(t^xPC^ytkrw<1p5Wg4DQu?xLUgV_7GirNepTqpY8yXS)aIuO z`jRV!AO__2ylzu@4Gr@_oIMm+_(UXPT-d@cm)%WLjzo%8juP8jHKRU^uMm>vOlg`< z=2W!crP!6E&zXMy9L+1MCCdA_*BnO0*8LsyU&m&W2T4J`5;}$ww-zatNp+KgvO%^` zSjy%lv|PFo+?{8P-~%8APrk0?oXv4hMGCe=a==x6`{4Z{i}(+#5QdCueBa3h*Zi<! zmH8i%H(ksRCsFAuE_n!zY{Ya&Xm*Z6$R|?ayg9Mp+!~lDWByROjMIz7>hx(<wRcyG zJ~=8-iAXMGNTShx^YpfE6OS`vp%e`^N_wujC$(V!dD`1|wq@??;rQzgl=Okn!==D4 z<umWOoJS7ae3m$9iD8rauCId{6A{^t=Yr=m%Ia~1p!k$1JX60zLRxILO$U7(nriv~ z!v(1L57IDn1aMdO0E5<C=(7NuwH?oGLS5XAFk#}phwHBgi7S0^&h%#Nos<*p1yq=4 zMGz9$x12Zq^wg?&!PUi<c&n&SM%$4zF;g6FO3m?jhrU9i%)^`%es}EJCUEB+`uJvh za1`n_UfOVrZ9jZ+;Kc^J1}ymTkU}vcnL>oJ@3i72C>3;7!*4VgsAv-C8d_SkfE4rV zou+aCxd&sZspD0vt2U%@?8~OWKs`g7J;NWmfCTWlO4rZ38Hawse=R-#0<iRoSW^D1 ztGUzeLV;uGYYl6o85-RkkCyNf{0N;+p`_MhxySd-l|WD(Qg2DJa|w!KzBroK9=Xp8 zk$X($BrDB`A0k3DFy4DDw#As3CbcRI)WO~H95(ScG(*CrWBc<n0qr(kGVT-xF^h}2 z5~4;90C^%K#T)9f*3P_9ga1jqf8<<OHkvmj>%yEZ!v1~Q+3oqb220cY%D5@Cu&r$| zNWKV`j-|6;Z}2FvzPQfl@9+YkuJ%n*S^>J1LO8jMq4hODDqs#~-md1sP+Y!de48A_ z35)`Jnr~I$Cp+)0Z_Ot&*<TncJNIN~9UWaF{V^CXbYQhO!Z}V&`E{e<GRvlM8-RXW zeodN9$Hf)awa=-%lC*bTGXx;aFaqi4)W!3zl2W@*(<ilRRf;PLI=xiHB9SA=&l(xo z4mTJlG2J+ZoElsMF2d}YnM&BpPoI+*^3^BImO&85*)k~cXSp-F(iWyzFdg%Ch4eFR zV9Z%kHe~<94Iw8V%2u*0p80fS3cghL*b6I}s;Lc=`jkv3e-r_HdPbLMTJ0shczq3c z=JyFm-*h^7QgKcBd(=mgIM5bs8FfFdtC2KQ`p4%=kfe5r2M}Py_D>*)rKk`}t~vva zEUfo0vXSz1Wl_0){f;4Qna6mAAe-5O%%3V79M`#C^0a3!)y2-jV^Ee(>7TH1a@>d- zy~)j_$w`Dl+0U#sTlFQYPw!uwAzwU1-8iAd?I&Z|!1ow#q%C~>MC-CrI%&q^-V$cs zZqrgNL3{bBaH>bDw3Fe>Ql59k+WU|C`;T%%XU*}28{e@b;6<MkOn`XvLuT^DCzQnL zuR(7oJ~7R_|Dm=b5k_GUMRh)bBo}~FigK11_etx!2?b0dym&3MZnjsAk2VC+V^qH_ zO4Qq-jZt%qlut6wI52xa2YX!OCs3$^hC5dP)NHUOrT~eK*zZNM;6KBz@{`vf^cdqs zR~*1?ol5h4*<7xayCWSqU1M-f`@k`Fv4^E1&%dk&BrLWtCnU$82*VtgW6B2XMhM@` zE2j{azhS9t)k^(@a60fq*&JCl9YDw^Gc=fF^4GO2E~CJFJhO9_eQ*iC!~)XK@$O`+ z*DH6BHc#f{b0`cH?4I6^y6E>!T~r_jI6}}*XjqTpR4|*t7YDw_D>Dg;J4e!R+wD8A zf8HB$I-oooM1H_OkGt*4>%R}`t3Fu@d>RfRJuOlPp_plehMA94KPQVrAH^KifvjtH zvF0V}m+HA%8N#v#oI}XG+d((~f}QwteQPqu4s_Ysf#=k=xr_>8W|@u)VyZ<=59wap z+&I%@<|a{i>pv7xc(`HggP65x+K-4?%V=ScS}8RM@tPS;GC}-8IXlNJl)_39Z?#;` zQ`_&;(CQ}nd0UO#WFGCg?f@2}!vJz*<sC^iqp<CHk>hv4(MfU9{b&P><S0M<ThG4_ zN!S`PE{fe6h-1n_kUn~+YFLB+`0eV(g#L@MHP9vD2{-e*Cu2=EnSqvNR2X35=(p^p zdoN7fG>*5tbJ1aFCHC;<U@<G=c>hl->wGAtYSN6DeP5M6ED+RVaNcqfkPk-;9&`w` z?%EKfcKd2Vtlhl%`e$wQ(le&;yh@XlvOxt)i*eIDg??=S)ngN{h*+;D-4}d`El-94 z=7eJ9x6u}66gXvGwJGp*I9ER=@1k(RaarXwzt`u(9B3<ts`2sMM5Rl8PJE3R!P9Z# zL~VY%JHUIYe{{W7F_z+A^3B0*zJGJy4Ke<Rkbv!O>vdwuwe@8bJY~a3hRTeDIk|xp z6At^MjRXmWK^$uE!K^TgoPw%}SnWfmb!SlvOS2CF?*N!#=y%s|1ETp(ym9x%whli( zswuu1C+?dJXqqt{<I&;}m3H#qcM=t)cPzgu5IW|Cqhj1X!0r+{KE*(cbdLxx!LF_i zQ(LF;H)~(0oV}0{l3RDTW;yh(nXQ^o#~k7NU_S~kmT%{2{oBjDhY~?-zaN}4I1LD3 zdgEJBZ?u=4t9w*X0r(&T#V+H`{>b%5%y|i#$+?_2qLNlk&I@SpfrB#=??@uobma9} zXlm~)uI3QLPE^qbTQJoM%ccGkVsJc4uL^t%V#Kg7iW<Eph3tNkH>2%b)r;0wUQaq` zg-?P=PIIm_N?OX^`b@r|ccpA?%D5p<aQGs?d4uu>&cyV#CY^R_OHubCVH?i0f&zdr z%Jy%l=T|pbGr_MC;(j!k)g_BH41Jm&E?gh5m48={Xedg9{fPlr%<k(AN*d9EL^l~? z8bc`q5&$<du2qQg<t%cv#r2cY4LTh-%syCKEC-jBMHnjtu_cSxswTB{94NQ!{Ws8u zqed>5CMDRlj(Tz4^w!)9--<17oKby8m#4)@h6M)Vae^=79ztbkagY&^&wD}vq6Tcw zQyZ7Q=yRdK`DAanEYql}vUO>gr|^nj@P<Iyz}ajc)f>y^b2{u>Kkb$qbE28zqEr>4 zW}(;K3xPAPwoe_n)>Ys>NPI6Hn}zhdyyzg-(y>E*p#PfKP)m#ce!+?Uo2luJLT5WQ zfp1|sQSDj^pL$u&LG$jO`P`7*zqcaiC)Xy6FasA&+Uea+UeOi$zU>r&9%VLWf4w&% z#J~VUQ1Nhq0+gvvs`jS{?e7%uaN2ZBV=k|FISWC1j&}<XcI0(DU>a)DWSHeqzO@T< z!qOr}=`~z^dK~9$a%SAIrsqz-?ICp+iq&@5tX-%hkC%`_=5kNwKO;~$O0@4oP&w1l z^eZ&(1b8+jG_T+F<dqGbQLUv4($w~w^()ry2=`G8<09PA*FK}iG{0G9s<`!A1D??s z!Vsl0B7fqh`3JjJozKVTwjYk6xS%RUDaqgCez5Lux?Y<o9KR&-F1foN?{T^x#v0d} z3riN`=dOJB^r0hd%VA`wY=Q+dUE(Mfc#T$|L)@U1X=Z|9gZ6D>Ms_P2o*oCsq@=7u zLx~n!+Wd#%X>Wra-RA&2P0sANAo_-pYPrulF$gj;a%A{Od9K>*bVI`mtzd+m*1Mmc zwKg8n_V#31mdka>taTVNdS9g)a)$eRm+5!sS4_(S7OVS1^nIb%#`*;|%SXD=X_;Te zDOqCUYb4nYE2QuC#@%7@T9_%`M3NC98TgsecfTlOdA7EBQO9Oq-J^M&e~?eE`f1D) z_#`D_&@#&EyMk~uP@_-i-HP*#(jLb#bP_rWfKzSu>$CBGm#_s+ppL#hpaohKeQj{Q zY(nCP<^T0mK!&-IDLIa_z7vzQ<<_H4ghgMbht-HyyHkKO@OH??o7b8Q$kA?JBFN%I zt8CUcuoa>z3&Xsi;>7vrwZH^4pvch&?!S!zh15{QnK6B1%OU&hZ;jZdX=<68WWG~( zhB?g9rRA7go9z^dgCCcF2y_VAQmmy@ZL`P)3Ghnq3<c3#8%)7SwZ>o3Tp)$@i<ucY zy|c6MrW8&kV6dE;M)ST-8=Jqmv+o*FaKJX-b0itZoU4@dI0X8?;TB-8HiynF>Y0nP za%F<yRWzW3mo7D&aY!)QO?GT*4!%K_C8sL`tk?o9n0)9^I3;%scU8NuWO36-zaoDW z`?ItDP+=TuXXarE5p_vR7SoOnB56?7E=qAEXTg(gh)bLfw5?8*FqawoSp+X(JKWeY z90)LCGl`HTVd+YjYiy2<TPHZ=x@j7dGl^Rzv?e5TRg{$jOG`^l0?CK1IY->3QaXKf zT2j0mzY<kdY>>{Bn#g~f<0PyfWchpd6JzpWM$$|r054{0H7TIE;}kf6As5+CU)=5r z_}!0J0yEnkq9{c@G5ncUt{UXe4~0d0`&eA*2*AmaMhHMD{A>DG5C|Ldm#LPz<_Kpu zZlVnlX{uv4*%op{4)20dHzuO2EzfK`CjNKAs)3j%Rz8+5-}9{WhFg)&(`4?dP~M5) z^SZ{vtGFJJBl;F7(UR6K)hY}GDcgRg%p0>dCh>t2L0)jt!|FIqF<v4@g&^OtlFAay zNR9>qFM<DjFZlDSmtekMXD#e(WB!<+N-5fcu<CHUU3rI86}_|s>gZLL2A;Y)OscQn zQy_a0C%toLdIra4Ca2AD8eUAe=pnIZRy$SyBbCAT!hdq^Y#&N3I@*S^Pu)p38qnNV zaxW61_BYf>CB@?5#omixQN8DIAVzgrNLV;iXBrVV8m!*>sP5&+3qTE0%XU}NeGHDe zodVhCv`IDb1rs{}nu7Ie5MN?qS}x|!Ti%Z)2ouU~lS_HWkSx=XU}-Cm0@X0)PR)&e zb~C`jEkus1Mn{<gN!lV3WJ*{)*nk}GK+g%lix4pt7ClWT!W^Q9kU8RX=Az#Xd5O8Z zKp$p3KD_wkkM>F^K&7KtksuVU9m$vx9?{p`sQs>F=2b`FG@$zqAEl^**WTon(Z-B& z1J%Y`$p!AxHiFEw?pY0Tf`-}C&_#4=B9!%Jyq47ZOlis#@0g!7KmZk%*FRg+#6q)S z?O#I>BiF&@SW}^H$fs4tQ7htb`@03ANxX=m_w-(>65FtROB<r1!T)^m?C3^VJq_dS z$P%M|rm52ReJ)cn`}9_4o*znS5^_rzRe}MY<cVy(&<}v&kUIe0J$*^~=-}DHqoqVr z1u!p4yB!*-zC_&VAZiutm6Vl{Q(4Db^e^+{f6WrswLvW^(4y^k2(PW_-yw;VnA0yr z&yLN%oA}7Gn&8tI+Y_V`xlq0F=K0_POYzi0RigYU!9R>f943c`4(E}>x!2jkdEnUy zu<DdO+O_UtbeqiX4tFC*p1GSHp&VhK-+%5VB*dN@B5!QZGU-3AA&Y~T^##!WymF^1 z0*Zm9l&9uelq$@Auv`KXWM@p5O;wU5c}r)oVG=R8XK({6F>#W*DZ$n4`$y0n?|ikL zT^(ZF{hisuFRHQc-p-MoMt?UQ_}PG<hO0Q}uDnElviU3Z=h1+-;-9G$Bc3tEP*|AY z=M40&?L(ybM)l#;y%FwQij(V{pj<4xtShkvqnpR)fqED15+X~<IklD#z7wahUX;i5 zt;{KYni5=FcC==_`HEQA_3WJKuFj{T<Wx-whmv>Pt*Dwa4f%=vXwLQ2{k&ym4Dxqx z{@qXDR5e@oRhz?pthzVvgog&7Dd^X5#l!*eia5IU6ezJzn+MH))_3r9ayXyBenUeL zBaB&)8<8u_??<3K!vA!{#b2XA#NV#2B>aZ3OG06@!F-slFIFFD2T4h{+5A>*`lIkJ zM7-|<8=v8{+)PTPgBkx&H<`2kp1cL8*_C7r1xak?M+qn|I!fl9ar4tq^_*FH>Mw~S zH|_Dk%7%ZW9PeYFRXK{|C-XpKD-1Z{MaYr$(_cX+;h3{HLzCC{#%G8CS}pPGe6Uq8 zERiCxs8Gk(MXWwu0^cZ*d@aVnIFL$n2cQAvkKZIwG=g^uSl+Ra>aviGI~v^&+?^B! z5*Kxsl+|_z$<;Cv^w4AiVuT4bB1vQ(pg+*h1Vu~pSs1S-4iuS@d7)_Kgf;4RmGN;f zL@&KhE8$M$J30_oOi)^%AI*Hr9f%shDhvYdezB7(rKYt#$-$H2Oc|E)-nnHRGy}Y8 z_fRhQ`-<Ku>E3`52Ms1>+4Vx-AkVl4!<Inl&-jzVHU?`tC+lHu?Yu;K57KEBb!w3} z9zJe<ERyODl)pt!Nb1NG(u4H$Ao10Qr<*RYjsk6Jo{u#tl&>Q9G+4O)E#-moZ3N(x zfPW~0uI6@ni_DN5G3ix2=5Gwcdkx(USBdl{yg_;BPgT_flIDgY_=utnGt;YktM*bQ z8!^n3FcDF68?U{Lv+V)go-x5+;u+muOXQ{gCDo0?SrD(#ul8zdxS=kw)JC3@lk;nZ ze}d1EwVj-rlH{sOZaM#<hBQDDn{=1{Uqkaa(f;^<GHpwBveETu)$HquDL?9+NXdZw z80LGTPgsg<@ZC)pF=H7>ujh3Z(fi=Josexd@4?$Cg!%&&lXDTdN=2$!tvQ6%vq;(A zlKb3*XJIlz@izQ;0Gwctlda#9gBX>C>yn&|V{WySytvbBJ_RpE3*OC|_JHcleu$h6 zh<V<t=Vg9w^uOJkc%npRF!I{qpPfW)hn+|vx(G@dOqRp1Z6OUUpE?LQ2>gD>+4OGP zv8N7S3+H_XnK56a+cYIhHV4TL$Ag9t#O7u}G#Ig&3kg0bq2n#Z<5B9y$-yGD{o6TM zr3?W!+B*kVTaRSt?f{g@Hf5vzJF|NQI<{qp0o)M$@7n+Ne&q}c=VN=BtnH6%W&{g< zbv%u0SluE<2=C3i#USfA3h;D6yAGF5O3m*@$4{T$B^V@vWooTw>nFM>h)^nTH-{aF z53E@kai~xN8uh;!CDLvX&H=i{=9!;gdHn|K_v-eWervGS4aa6DjqF}uQY|!EM|R2l zbHe`dpX2ieCP2l^pDf!o)xDesH0RPX#k9?N`*y0*|LE{V41FY6K_Qgk%lX(c#DPdl zxm!}kz?u93b92CFp>gK3n~@L8)M-_!EO`yODSRLqAdeXH(#e;}KZPI7K9&`D^9mk- zeQ>qLOZ_jBwOt9%vRdZfwApvyow}psDd68hIWm#HnL7)Z5K(#kRC2&h?vj3i9@&c_ zZ5|YeoR_MCJ;=kmr>?F_xo~MGc%va~=9BezD}kTWXwN+puX5LSZoS#eA>*Zze5`&W z)|y4E=T0RktPJxs)~XT2?*<xz0%xEVexHA-^hHHeDX2nzS;`(Ieijx^9*U@?+7A{H z0<gg%m6y#n6B(}408s5I#yDxri)=73@tGc5frcL0$d$viEbwm^d(3P7OelWt6IW2) zTKr~hkSxH~EgH#!|Io0N<Mnd_Do0nj3Ms1FAR0WKwyV-~x#NyM%o=Rwn)=<x;rySC z7p3xl#wpq%BZImQJK^_>Y8DMtS>P;({>}JOR4GcXa8dHzP8REKDmVVQ7?riA?}>tO zdwb@ZitO=AF+m)dG1np(Za*oqe@Se<ca68QTObJ%AwvN)VMLjd^9L_rhYsq3RG{pW z*@Sl*4Io?g+Uz==zKH*zY2^9qz(JteV8!dq0#YZx{XF%PSP=^oq@dLo=-G!OX*uca zzu7rXfCClmgm<gdO@%00RAeR#5EOFmzo-<YxTQ-hv;e)$SqONUProc<QDM0DH=j@H zOW8CC5uvfBNRQFB2WAMs;78v1e5%s~URwM-1m;M%v4(l(CjDJDwkVM$#?Gq8FDeDC zT>F3G#ecHA{8aODrt!NF5VMQc1J(LTJ+HO<UG%lI$SC$DU&zs5%OFrWcGl-e<MG|V zl{yQ>FBFX~y}a@2+_56<`j$AhstajcziM5M6xAsX(sFHg;!ph`$eDV6bJD2}VAlTP zMePrPrrL9Kfd|d@aCDmbunjW*?~(2~;-vbL)AKefo6dXRvv8)@{!X7|@So3bOM!>| zw?!T7)vyu+gzmwv5)cdI{jds|5p2<@8tbPx!hB<-oC(!64a`~5?fjxb-IfL$Jn_nm zTyyo@MVaGrv^=AoN~*l+xg$N%op0ql1QV`uu=xsH)<wgr2+fDvKOH>x$NCKk;F@Gu zf=&KwE%h~<%gW&;1A0r&W@j$|@U01A;Wwn_HgiBTZ}m?CYm-L@pjdPy+86~`;aT*? z)+b4}e89b%9M;?`ORbbiwXVOXHc(Y{@nwFd|2dlX4Dv~qtbMc$%(vIX*S*t{`HUUO zWGx+|tu;X=(wjwCG<Ugl8aa_2>U`kA1$6$?aa(x+G0MLy!fY~BOsdphX^*6E$}34p zm#SLYY8~iJFaxwrK*E!yWGPCEqbjAVEad~VrXtJWhe57097Vt(?Pul(zUWcSV}5%| zeNJLTe#dN7`Vb3FPAT-X8?Q8u8xRsH9U65<9}SnIanuGg0@|`4gV3Jq?#C5QWld<} zrA<j4rjn#{?l)A{x_By^15B-VB1EbDwjR2zD=ee&Pke(OI!8o><-paBKzSRMq|~W} zG$XeR+22o6I$p4RF7$yc=#j&kkf$)|0_D!e?$pl;+?ipT4F?i<y&C7VQVb%R)~Y&s z_fUAe1zJX34Fz?een#>~fxplKxxu&>2bpW_i<S}%29GZ%-L&%P>(tM99(JUH#u%8~ z*y{l(v|uZ%KBqO-2p1=ML2INT=)CbWYcgLAK9G+@G0r=##h6g$No(&{QrXNJH@B1_ z!4%f2aSl3Rox-o5ay{oCHk)sZ2Zsk|WlVpP?|3`{$(?(5RO6<gI3}iQQgKy=RORG& z!s+FM5syREbNrw0^6hCgWtfK~Iz42ZL+Bf(FX^Ap7`QI_{&0B-<g4GY0)O)D@ny1- z38>@MYVL8KKD6kna>TYWlNoev1-^7~dkIL);M`HV<YBH~Xcnuux;xvFA9{b#NpDK2 z{k<P=F{N%dyq|2$KyE?XSmnT(66r_zcF%lKcgkoUiSlO{m2+)jCNZn{JLh?ah{X>s zo49Df=twWrajcEsY|wmlSycE0TRgp8WPFl9Z(;E6scs=L4q*0C29j%YV_%FWcVbF- z7;!f540OhzW~h0RJewLv*c0sP9JxO4;N|}Dmd9ZPqccF#2G+hcMPr`VH%?-JN$Zu- ze|#xmEuD5z1$q=_fw^H|B5g`mV%FVw&{YOhQXL1Kv){W@ht8~;U$*zoq)rIP_Z3Zy z;srx}JUXox6Qu(3y-0b(0s3;lSm#Od`Vl<=$LDx8N0#H5^hrMxt~p=_T@yRwd5dCZ zSLQM%97mXEaIKr84ijyF27ohJlH!mG!r-;|S;if&n%)|<5pJ{4I6yhywYK}j)^P$i z>ukh*(@%`_GSKv%!tYmo#`*KSMiqcoyP_9p^{&~sJ*Nk<ALe%0Qdp_~EN?M?u-UBM z6<ZGdV`t*N_y}tS{qmC3vv~S84eNb#teu#veY^xMaqG}~eUwAqH{<9U<|5RSEkk<% z>wzwUB;6ee@C9w}UGoOKr0wa93X-#a-j#nYD9o%^OI#K1js-koD$t=3Q)<W^K$TNt ztyJWw)kSPvjUuDGqsfb}|E5igwa8_Jp{lBu=JdITT^n&TW@}S0bcY$5*(C`}ftc~U zH6@>C<QyO7Q`c%XA@u&KgAn?vzYh-v9=>ESGv`t;H>nKHz8H_1-w{w^d|>eYK;OB3 z%gLPTZt}rZiuQMYl4q#WUTl)m7)@clTWi{J13<k2E_}KTQrfFfvecqwFG}*1qP-+5 zoa(?i(tqhsvAm9_UK?#Vhg&IWI|uj@>2D(VvJCYn34eZA`zFh<K!5%1KOlteU8PP~ zEY@3_MAawM*=$)CMg<YFKx6CG>efPoNG38yzy*VSq*()wADXI+1_dI9A{?C<nvuLV zn9?oD!Lq!(h=G*5HQ!^2zad)CeYxNHrA9sIETERP0nDQzuT4^N^PG{@SCopb*q)c9 zy&S^qbhSJy3%Rd~cRVbE95uv(d;gxlcu0IdL#@HMaYn!I6moYxr)%uK7swaoqj;Vh z(67>mY3uyBfHc$_a9{hgxfRJ@M`jUWbtXxvA2R(_%apfs_p(35E?K)h5`~-7uK>bS zT1~SSg_o&uGh5TFX+p?D5V*V6Dz`2Gz}s{J+5{9p0a+~~j8U2sZ@(cd{}qw%U{(;* zQ^JZvo2pKyoQ*JRz{v?QRc*+J7}3l4fXs@6B^1zJyB`GuqSn{&fq=;hd1>I<$m4 z9mNiGcu9JG?sw$)C?<TkZi{)f3N$9#y*$3pjurc4ez4W{md4+x!}LX=>)}+=QE1Gt zPHTSJUk58%8GUb)+m2o$bDnlrUf%B$i|RFLm{h59onpp%pwA=++#909=8XgBs}}rN z{k7X4o(k?Q<*Xi>85X>nt4xG`5^7vhlnX9)^YAub!wI`};Pbq3+gJjk`!iwM!pG&& z?j>Rr4?Z@S7Ll|2d+#x*;I=n}+|<K%v_3zw*RW}pH%^I4c};cAcpc##W)cG)lO&aV z<$lZJO#Fv{96`5n73e^Rn!4(?%6MW}|M-GnSUY2@3_1rVDZ8p_3ZVo$kjYwDQ^k*+ zK3AjQgr|866&}&5&xyrZdta40T$KnaJL_~?^9TNYVM#)622b2BX;9l15DERf?{^K( zqfdbjWk%cUYsb8kSgn1<m2;@O^3y{(v@7uSL;KY*Gl8t%>PvZFzXN8$)6?=BTXovY zcgruvZUB^dml1GY0y}*7kH?c=#s9+vPzDt0P@r{4`tsL{)v9ErbFF>nPT@r6`dBzF zUx1$zcQxFC2lN>?IotGS9==T9G9&wts9CBo<AwvJ=v)1YPNU=4{D*n8#hUYw{MdNW z-VglzR&-|Tr}(g6-nt&o8<bfYuAygKu^Di%!~)QHl#n8j`@e6RMH@wxs}1kNGG%y6 zASgM%et2xnzCpG%)FH<}(vSLbe#AFP(u<3E*J5$bKYkpM5;ML3eFFM{w_8;y3sQ;y zTuLjmE-|BYj2-vmMygbCJaE$+5yzCxMr#`2PLTRqU2hTm@iyn5`8t@`mz#AyJ1vsl zTY&51QS5&9HJ&HHXWjDnKPJYcS|PL;DNF0Z>@V+5TCtUC<hQPRdY|W9e0Jm)J$<{P zgr-rt10qU@1jKCG5zU!^8myGp;b0)G(OuH2-MY%Ua0(TabA>B!2|gaHUM|np&$)y% zpX7f0kgT)-GvGVOIj*X;Z;mEETn`@RTt3ZD+39%Nl;VuP;EnY`c^%`^!$4B*$N0Ee zsjq*@!TN`wBjP!XY=3@%u#R!jxn-xI-b=b~Lpfo2xOgK?>&2idmijUTJzP{lQPBW4 z(HV#3%r6-k4^O*NQY>1RIW;2BdTcD1@5x)fb57o%k?g>=&}aFm2;l;%JLu6$KbLCF zq~9EJ8ZN1PLuo{|g;{_xKD2nT&U<p7D7ZVL)o9zRe7&B!%zgTB?9<o)?;0G&LId?H zZgU8>)~G*#OajK}n#1M#Lv2at<*y2e94~t5(>(20Bbq5lqT9pm%6YSE?;Cx9N)JHd z(<yiIqtavgaM$uxS^D!3exy~qHoeg^gFF36c(IqD#Z|^fuW*tX`T6u`V{Mk9w*Wuk zbg|pj^p@8Sg-?45BVn}-)h5?_(nLJ&Dmc~wh)w<PV^Q6=)&b<{(`qWILl(J2b81#8 zK_Zylv!G8!@y!=AXP5|c4$;PR!}h{&5%Y{QX#F7IP0Ej&l3Wy3W>?As0y45=8B#Rq zq3Yah_Lmum(JVDp^!*(ZK7*g0%lCEs=bL?10?@cyFOp@1FeY?(vw3`qxMzB3S0RZy zoiUr9hY`_Ef0KyJA0ZD=dEfEEBw*mwt6iIp(66v3P8K<?Rjf~AV#~eBEj=E3D=Z7w z9R7_S=WgzdCn<$V2|_Acgu4zq`4&qqDiDyeAX}>efP<PDqi=)<zZEJns#Bg-9O2L| zl<Usa5YFVVI+_*a$&<a~M%2;y!1^dZm+;N8|H2_K&Y4W9$TCAmd%BRK>K#lhYLu}y zOJ9OM!y7T0tVed}fvxZZ^v%zopMGkHfB9%2Ox{>4r8TCis%rmFtDa8mXf<zT$lwW> zDY2xte`12O2l!*(2W1c`lt1auJPzUJGb<cOp~6uglpVk>RZ4rkAU*nrf_ACW;;q2? zX`c9PT9$!7#l`~|;LFAtgH$JnZ*`-NKBZ&4=SSz8`Jc3~y+y3}_gnRS2ceR7rv_k` zZ6U?!S?vY=z*rQY-)$v7@g^b7r%7OWakFYTKyIE6z76kP2kKnYZe+jD6nWwB{7R@4 z%9?Whs2PiIDV4+O-*9+4Tsf^>YTGxo;*H;!_aRXOLq#i&D=CIuAiuf%YF1R<g6nZ| zo~|DbFAJhc|KWQnhFdzj?t7!P?p7vxS1Rolf^1)$2uAoEUOYR|L4Xn7k-7n)=NR}K za&0gPJF4QYzTbX0Zdh#TZ07KS&>b;vRx;P+`I`AQ9@jjHFu5lw$%EpA<jdN9XB*vP zpO`_NoumC3>&j+N0?jn%Rpy<g=2b3c=VSmhg)b{QQV(eW{vZ}?Q0|)xOF-{i(6S9+ zh(M7%qG3Z}L_FvJqcd8DY(lDeO&Y*@luM09`VFaRhJp#PUjzs_A1no)<1xScYPT@^ zTSa}lek{FD=S*F#cLNbVkg!>s7C3D-hDZM2npF^+XXJnxHuw3VFy0ljGjc!xm<Ilh zKJVwwzx#=ZCambWh@86BA(`W_{b2IpE5cjEu#0BjX3mC06nM(;pT&^r*lo{EV91Lm z2{crNUX4(P&l!lHz=(WL-!s;KvB2EVjBO?E*1uy_a81gu<2$z+02*3sbd0|EQ`hHd zsjT1ispn2Tsp)ggN!0^jL(GPyEEUW`{>pzO$||zDyOIx`1vW;hR>6uzu3nErWyuI) zf67V$lQUPI&Hgk0(Q2us@8vG^P0px+&(-{(&k-;K8vbNYSm&RSLl`zHgd7Zj09!16 z(H9`>n|bgZ<NFKhH|2~My5HNbRBX)?{WNjUAzDlYd6!nVs_DdEude|mIr*3IVd!#G zh`7YfNuy+)svwK$xD>rFW%Zy5U%s$IPbv_zlE5vhGU4v9K%WVKhN&^JzpI-V5BdP} zOa6V-0X5lY4Wi1&qtN6VB949EUsApr6I#-$6A!(QJ?=AA`r}%i++#b*xBoS&hn{Vz zVIisJDC21>ueSli75lz-e3>Tgs)JB^q2ttG#$fmCrikKf<`fNvlnRD~)i9}0cr;*C z55`}2-#1$GMUkuN?CDPGGb=|5&8)lVFz~d_Ffm}mglYG=fPCu%d|Aig%cfe$g0_u` zYJ=r7k$C>3vQp%QBK3!z$J)QMMD}0k@XR87c|P0`F)MMYIkfK>w2lb18)v2+Hwcs4 zhU33)GPMA)UP!SY&zFhYbiB~bI|aNeC1K2D35e5`H7jXeSGBy62#5p-2sp9gn^mqu zVoYn1;5S-`h~bn9RyMXQJ0)><5X`xM_A?A=08CvrYEX9sQD#d13tnmusi8#DwOJTv zUr}I5O1gT)+MFY3jQjxa(%QDHD@YA$NJKC5lM%poqPvFd!RWAQYo#%hJa>mA2I~FJ z-pud4iM-87;!UP*qF1r1OGcoaxIeVMGEs&}+MoT{Jhb&B!cr9P$4BAeGZ`Qk@Rcth z-%zVE<5}@l^06pugl$;--h=}fk|ArNSv8gP-)*8NZ1*<u3U9m;q4LBY<32|P#vKXv zoIlTm_zxjP&(?2bx&FM@{w{|JzTFm$#inwpCZsqv#i(34D7ytbGTk$<D_X0XMNC+N zPI(Z|5$0%pGCu@qIOqdLFe!hag#EIb0Ep61m<Y;CRItk}pKG>(4+lSw$JTx{?W36e zzXu`&WC^q`g#ImTuMgFw+C7_#rE8G<Nnf5!>cw|mMbwv<U&4U|_ietRc6FM~Ez@V+ zkXEb-<RF}caXta`6w4Ww{T*YLmTNdc-~`|HhhT8p!KMA#JYd@^=WdWHJ&7%aV`kGD zn>L+58l$6UW*$fr$Ar#C&?1Joa<b>v<`dyDp{9KvQbVG`Jl&iXO{oWNKc1_JP@ABB zhI7mVTlNm1^f2De={@#U*_Ec6cE6L9&W0O(EE*=`dLZ;|HCBZG$Fr8AE{V6l9%j1X zxCnC_PCgT`{;JtXF?bXSdMvMS0C)j}&$Lcg6M$u%rDhLj<#Cz|A*t=OR+j1w_}-0O zqMJ!7&8v^ia~bJ8^1(<trjy5{T{}}!f}NuQ9h-R9oKXUwqTh(V$k>{?^nEQLi+VrU z5krWr>9_(E)Fq{QB^|ZjmGc%h0hfu9oLe`_)UHUY3Wns!HD*3q6$3L)USr?bKgxqh zC7hn5VZ15EY=9GNr3g&IK(KFA*ZlowiNS(<_E45|T+7X_^4oJYr$tH#M$LA#{c|+D zMNLKDSqXWZ=OGdQq-ACC?yBJGy1cgHwsrJ=#qvhYBhZRL`=DiK6i-Ba!}ea~5NtZk z0<Nl@+by>1iEp$9<a;_RE&EIJGJTT3K%AJsZ1AfB0%Z&Cad*SPnt4~R1|AyRNUA_` zE+fpjUo`kqBUeDj4j@lD1r{q=Ndr?IL{-cIe^26CnP~|_G<=2$O!~08=s(fVENZpu z(eK2~P}+NtDn$l85_H|Qca=<Dv0%Pk+ISc^dmwx&dA38To{&-oPhk9k@1%{08?YgE z?w!@1yFeCwd%z+;v+SQc1G;#gmD2L_mfjJl7wABO24C+2-*xJ5Sr_jC8Mffz$`L?9 zPd&JMR*JE{iy^*2@o!C1@_Tp=w~5Yj=Z|{2&wnKVRh`D{+mX7T<lRL$@TJofE+efn zF83@LIi0_ls|=9?dWygp1TMVhfWt4<>7Vk?OHfjAF4-*<$@3hb!ld~%_}zKvP`3th zom?b{p_YXPmC$%Ia{H^2k3%(51CzhU4TbA+BH@~5-Bb}66B5YIo1#>wmKzB9+u^7c zBKi%txgn4R1zfZ|3$u3a)GxWh@9{;?bEtoQ+Lpyp>A2(J@m-2~Ni~-IIqKPKq}|WR z$!)!MY<G36%%tSIj#Jv3R%&v6{#K7jU7bx=9y3)dKF?q7U8w9p==Wwr{mvB3!X$X% zuP%M&L%*>y9~RL8vjgKm6p@vH@3G~x`V=*NTMl5Kwel0GE$_bWn1d%%XlM!x<S!dx z7Sq>CCk)qufT2$G^K+^SQtaG#PO-#ohYh;Se3w&YjlfLmOTV@9NxYx;gk@J7$1C^6 zV!Q}90T2K7{q4t~3#WrKD`TIWtq#29pHeK+sh_fa*1SoD^WOe5e@mKJeSo-i0EY>g z0{@kvtu0d_o#avMsCXg(K^ftJH+7^mT#oJwH(d(?Ecwfu%&p?CoEh>sMHSj`Z9Pwk z-5&=@FRZ}YoKNFSm;YNfOhF^VaB*%sm4jPc&nh!XKqnmx^16*y?}l4_eYAi`y$^X^ z2;ef9RS6}&FIt<v+Ux?~Hw?*$B3d&^*y<q%b3Qv@QmbG7zcV&IA_&<ayrtr62X&yV zZfNbdF;yZJY8c_R*F(3BH7L(}DQ$kpb>3c`wEP|66)7~1G=SGWvG)^||IDEOt=6A& zPE2lrQW_+>;3H||yg1@JiRH*`hhy&xT@tnpyul5d5!t3+lc|mcdDYA`32H8SpN$vB zwg@j~UEMj_5>2!$A;%tC#&8oF3^9Nbm+vb802?|k!LODm?M;Gw3#TfxD@J@DT9g1G zoK#@`hra^~f_v=XktM8rFlcm+?15_Dg4^DXmS{n1mPE(eXA5uwly7=-m>=1URZ_9= zMn7K^KcamH`7PzV)<&$GuuQom2{Z>wUIwY0%<hp9WIoGpSP>Gkki7&77_(6+$(>4x z#VJ4T0YvqjW%|L>a6lMBkLbBr9U&y)X?r=NRuV$b!P}QouUmi2o4yzHNz5Z{Cnd}r zndSnLIDMN5>KMEl4RN9l&D}*j=GbPO@iHR#@XvkDbZ?*ef%=3k3Vb;<1Crj*+c_ZI zooHNLeGYv}{nH#Tu=s0slv5;T)6TXhB3Z4@TI?*i2^f`z{T(^#erFVQd}tWAgDo}J z(63+kG8niy;BzqpHVfn7fit_%m>Tl&nMn_7#}0CjTAidxe4F1AM-;$)re-sFmeJNX z(-t0`3V)TMB;u)n_);!yNR=k5P+%xxWVby%%4~EGsxzN`@tZ~V^s_(fxGTD8d^?Zd zje~PWL3*=(p~Qwc*DtuR4WaEOFPx%>X@l#E1WCjxQe^j~cw|g#9qWJ7U9^sYmGA|H z$&O)fp4cu=zmV~EbLa@uYdxmwVvSrlwlrU8@f!gKq6AuNrwHDhX={!B(;<0u+G*g% z0%X9*MmVLQTZE8=vH0o%1e`}&oR`{{I4NM$#1D~_yUzXl2^>)<8$fWZ(*pR=9DgqN zz3TX=g~p}pAnB7@u_m5TVblGg0{3f)+#M%V&%fwLej?xJNC7%qjF7y}Lm;bV-s?m- zdGjQ~&8NFljaKOP#{a=(#wc&EOgETIUY&x%VkgqT-f_wr!i3)EP99O(OfaST`(!Np zWdq~zS3tOVP6gfpw!+4V`nUKAU2H)DRW9tHhZ>~fb;BM#A9v_lt}sn*f)G*L5P66L z@YM-`DH$-=PAhp^w|R!jx}Bb?LUUyik7*k~ZDIa|u!=kiqcV6L0CQj9y?GUI7TSY@ z<1{X@X?IghO-_eO2wlK0RAKk`i$AXLA+4r*k!Fam!UxR30XZgiipZ4702;@J>tRPA z1^Jid-A{ofpZ*7m11}aH)c2QPrQ2k>PxxvfWy{R@o(JIfrK%uk+GesY6v+)}h-T~B zG%X4yRanM1=yJFln%B5q=P;vjhSeG2en(bE9yc7956~<%N5b1(0p@_`>i{YEI}d=x z#z=!ns^8;7mf!6~{wDmM^GOYOa`3Ys;W)004Wg$LAdMECO#p6ogSX!Ndi0p${Q6u# z<2CFx$X^^X{f(;Ht{zra6}9WS`~0Uj#$Xfk>lGKwXG!TQ%}Ui<Dw>w7nnY^r+Y9iM zpw|uzsklSKsoAmZR{Z9&jf-YqT+lDC<C9=H2??_A=!X5Dg<r*uk-g<!O#_kn(-u)C z#W7!?A@=&qN(-aLp)aa1%%x;fmb(|Ww?6nDn?u_gTj-V~-CC~3j%V8$>sXz<&PMp| z+K%PzZ!55_Da;HfAQTO(0|eVY5u2lSHOzAIA(#6i-555poZ+M0n28Ldabe>}gm-CQ zkj$YE7O5M~bK`Cy@ROp)m+rGB%9RD0s#N#cpYcNs5U}2K#_ZHsg$?1~32dS}p|J9O zK>enOw+?uT+*en0L_4RTobA{w1ANon!R>y_F$HO<G^Y|1&8u34q$PK7_I#leKNgud z2BH{M2dwv8E%l5b4>b(ZnRpO&J4Ntp?Glb^a-n0u;<B2m9=5BFTP#6_Xk&1(M%*`x z-+P|iLQLnRA7qHEg{Y=|Huyq-?jGi!N9UG<U0$p|dc{T~AK(8epEt?$^;<kf>v@mT zQ-J@bGlS0+^#fC%0GeR``yTws_i8ZLq2Ge<nzhT3Kj`7D<F%mM?Fn1w+Pk!%Yde!I zPX=EnGl@=hlC_|-x1gtZ5|=g{<{>+TGX3y#A!{i2Nre`tx{%3D1-onE8MZS8<smCp zAv+Y#s~<H%;SiHlE09mCnSM~~hLPxond*jdme{tSzi=4!`KVj0)4n2Zqy23UqMGcI z!z3zv-r0hFw=c{v9(=8XmoJuFCx^E#iFxBphHzh>U3Q*n=@Z2CgGe`Q#)T}yne4s= z9jrLIpo+JS=t6o?a<@*U8+PtOW++Eqb~oVICMbfpE~fhmli6)oxMC`}Nf|F+UfAi< z<EdvH&#(TD?>qGI<E2@7i(0#7e`Ee-G1Cu*-|~c*Z6QT_rllR}tMi?mw|Z@5^VTIT zzqrSCh40_%k+L+4aICyyO)B4Y7_N11@I@bIi_W=EE2!K>zA)-$!i0er*3RDl<DVr| zr{9VoZ~cU_Le$Pn!u2>`uqZbA-nFg|wUMt*h6i8J6&ndjRHhigW`<A8JRmE@^eqVK z(wvu3!a6^TDa1e&CnxKN6WfO<!eR}q!wv@$kt_VAmGD(p2JU0|ZwsOw1ISKu+}UE# zb^&y^I9-nHVUKvg9MgnC5Ky1CYpjHSU?$*)5Rgp4acMv(tqogE*MyN28?z>4TD5qD z+R-Q*i<o}6$@W}pw=Mq)ZX)Vh|1$c8?)#P=Xs6XRSt*BI_tnr&J7xG;C8!$xV~5eX z@g;fu{!R;eac0P=0jx>9#wFp_bS**NP##`5g;{3EIM&v^H_qev9fm7j`Aj-!nL4kR zEs8O`f%Q|iq`e117l}j6H;yIHYH=l0_Jw_dr=otg;hRrCLs6Z{%s+bx`X4vDj;K@t z^Lp7(H<We5_>$i}X~%4okeb51T|3a2eE&$Wp~a@qPSUl-RQIXWGrMq4_Mv&%qtXIj ze^2<=jvVZ&x=hcte1$6vm+<ds_c=CK>VTPGcbG2D{46uShGLi|VZ8Mzcb@?izgmx? zA34NY+&?Y{#I|8d8Ws+Z52PgV@YURYTskYXdVIr<c%}8&Q3tnyj5VgciDD$q9f?nk zfr(+6g|!8RZ(fjPt1Dx0wr&e|bYz3ni@LFWkRiYNTw%0JA`Nfm&dpn))3Mtw7+!>$ zDU!FHWq@~>C8j{OPg50-GE?G_fcx>Vmevd-G}q|afe_q=n$f#?hG`gV8wQsc;hVZE z?3#;dFhIp3@t&s1u*ZXLkU*I*QEG|nFKHETJaof0WP98xKE-CieMaMFMOjq^u{FyF z4BFBuDY7hXV@511H&3CmpZaO$oBR=8L|HZ4V?;EIE$xiNQqkyG`b{aoZ3tyW-RS%f z(Td*1tlFCM@}$%ofspGXBJIWTSm|C`#w!;LP)ez9u;uG;`>&;!N-mFVj{UIi?WSwp z?N(*wFEPu6N`3`WVza}%6*9`c)p>0{6}|UZvZo)QV<8VRSHHX=y?o!N4r(hzu1U4P z&otDz@}$DHQ59ANBVkByrIzjsmLu07`?n@5i1yDj)!3D7>{<+pC&d|wHc#vBEeASI zwC5c)SCu_dezElf9hZ#FGIl+r{~%XgDPO<Xans%5PA{1rEWB`Ik6r$x`5JVPe-!Uf zrdL%WaNu{1PQ5?4o!*0R+0S3opPsJb_>Q|p#bekz_=U2PBGke}e61+j4;5UT__ljV zK}~Ku$%F-CN3@w=NKboZpU;(t;UN6Tz1alQ0XThFSN!;YfYX;)qJcG7!{+KtHf{Hj z6b~!eE>&8(@t5cZfg=Pe4l1m5VfMrO=lm55@o$Y>VD1lYNy$z^YZ&N{CNEHWj7f)< z9CE*{L!c2%KVYO7@(`bn(?d=(TEA@if==)}IWW6KTF_OC3`D)w-DBwXlQfv(+;@eE zib%3TFbzk6?J~Hl&j?07)~R<t4Ml^Yp=&`m<Brkx`5o{gbVfxzG?)-@(>0icpXl7A zzbg2kNx<K7$`+=F)by#MaevBD8cq2M7{li`A=;F!<7C(mvJmi`Dq8SCD{<EgsR16T zaJz?I+@KVtcEeXpsoX*NS5;cot3erid%t=RTF|Fr)yrSb7sEBdb<KU)6WwYTU5~K9 zw~2AAR68VVB;?K^Q4-#e-V?A^?brPl#NOgZ5Ar7L3OtG|@tVSo$a#;tVLjuE*`x>m zURw9K^3|m;eAh9^`(27g0g-|$sSC(`)McQqYzg=z<7Q`opH{eBc%6LW8axCZ*rb`u zs@wG_j3G^daT%m#7@jxQ#0^%+^^3a4Ca1^oZn7vYpJ>iO<EtDTGuHlSa4@Q`7Ffmj zHPWopn|sC%k-B#lYpcFs&}nk<5B669$W<P?qsA{EeC9@!DS&7uCd0yY{N0@EMYd@5 zl7!s&<i_P&JJADgy|A}z$=LGWqlOGSst5qbYQ64p$;L7%%}2KDdGs!Xpg|{37(Cau zuAyI%@=hEx;um55K6hwjF_*B!2hNo@VG0G;!4%!&E^>KcC8d?i`Q7!s-k6%fwRKM& z@m?DmjS4}_9LwK?t1#~Ngo%j1%^q%|IUtLbWtk<jz8p%&QHw!(afNjW6`|r{7pDpR zL4;YoEL3&3AE$9B6E_3+ZArE~2|U9B%z#`S@qX@La@8t-3w(Ad4YE<n)AxN_rLm)~ zNWg!`l*)QQ)L#Rx+{g-8wNR`ynjuvGADX^7I<D^fJ5AHrb{gAu<D_w8H@0otX5+>U z8(WRliETIb1n<rBeSd4se=}?Dxd;1vu=hEPnit;p3b$ImV!X}yeapUsuH(>@#p=Lx z+hywSl^G?H5ZJ-~DBrJXga4;JF@&tKTZMOD=v%fQ=8m=;a>9hs47%xzfH>&4F?+ty zID{oTzt|_91(3+#fF+Oh%~`#Pb{wPJWWIWLqt-q>-6huM7&bEhBn3<)A6t$(rsEKt ze6DvVKlQYw(<*j^`W)AtqZNx>iBWqZO-vz?UG>jKBEhw_Z!8rI+3Qlzb=~xsag&T3 zM~=j*()-?j01U$t3=wNUeYx0(Ggd$U2Q4OUj^p21Zxu#A%Tch?_MxcKYbsdU+Clfw z62#K=<s2x7G~VkjG3+2IW%E}xLU447*-_63tMmDc1PaYh@Sv_}=1*BELZNG(j&_XV zhYnygTQ$a)^o=pLcdZ(-+VL$htctFClNox-t@g#?yMmY#AF~Wuzx$Nh4ol~=^re+) z@^QBeuV~)h0YQN2wCk#D+GVDNH>hFMjwCc{Wq<LeU3w@h?9zS6(f5k+NK^^4%6D#M zg6>AA_+-Xp+c!@BK$7QFrSaJ=#5baLiYSPQbk^KjDj`d~!GZJudEBs`3vn%pKTRRa ze`XayEvVsuL*CnJgh)1>elPtsVBiO5r^kAZKazrNrZ`Wb1xbG0y?wH-B6*7QVed}O zpsgMet_lnKh)}kIXVhy4Sg}~iWfYP4oHf!II!Lpj39V!UW$hsO4A%Q^cAr)24=)Z+ zeQg1(Un~43cDQ+G$s>=n1_*n0nS7>6<Cfy!BuCEyBOPo0Ha8dJz7}P+QUFs%r8OaY z+RwavB}Mo48lUbYtYz>Z^p9QJNUazpvzUJJks?Do@lLZkJ&#_a3NyqFiwwc<USHp+ zqYpcHxFt@-Aj20{-^Sl#_MAvOu*ezRai}uYayH7DVi})yEQi;_j-JwG3L~FmJHu!# zG0bQ~eN)?7x{Gr>G*FrT2<C%I-E+KZO^Cip!3D>=RCS~8@L26g0?3bmYS7ZS!-0EJ z_dHn-eEI~X=F#Y}xIOqADlS$ceN+M~Is`nb%sg;Z=}~ZPMa1+YVv=jY@$5AO-qifs zN8Z(yrH_@1VporFOMu`h4q^1)(f{QF<S3l+JP9QxkG86`)|`TEopbm=m!OpIJbFJ} z9giWsdFQDIMi_??jqBAJ-iIw-?{4yZvfJX!J&C5T&10Q#@-A1T%6cO+IBx#FzuNK_ zp}b5SBkt0<vtpjB=;+A+qQ4I@l2D#TSXvQfXMD=TMrLxE;|rCi&CD#E6S%4(DdW)u z8j_baYo1%S8C_Yx_8~&z@`|7JXwcKX@i){@)TQNl((`|rse``apP%fexj?5_%ALfD zeR(>?=URMcc<$LW!kQK0I>2z4d2Hc#Q}MeEIuLeir@6+LSPHB6DFXNQ!hOvud8skg z5-1pCSsFB>#AaqgG7c}=Z?D{=Z9^Rifyux$-bkNuI~3I=-szAcvLiCrY?#`arCfhq zBRXL|5gp(a5U=9m8sKg2uRF_yYB&)KuB)avR>?RFRMz~5Ekw3?TFI<3t5HX&8NxoU zTxI-khwQdrZs>{HvHHHwxKr_=qY|6p!Dhw?FEdfR+?X6T*c@V5<HTi3(&s@OXB#v1 z{xCoqOrGFi&fXty^Hz71+q$*XE%F8Qdn8V{OUOyAIH-bEqTpN331Tws^uWcJP-uS4 zbZ5w{QP=R~2I?HsNiu)?^+M^9H<j2Q8ezvG3Xxl)3?gxOggN)vjGXb<qeG2t)o|_N z!y+c#igyiBH-fU5I-d)t-K|fIH`vd(B*t0?-b2!zuyRC4?wAik56mdzED0UPu>Szd z_~vyQ{Y+Ou4tz@fQv*%%GRBkESP(AQD3qz4^-mWHp;52q(4EKjO%o3oH1j8d*PoCl zw0RoCixUCIE2X_y7|}(PZ2rI~`Kl`_jbtP+b+hiyG4YkreVtjyST9EO<Vf^k?)muv zHr!`l^UV&bZaA}s-UyaYFXBXP@|VeGpe=Ip1j*|uVwqSq8_Ji)H8+3r0f#)9YpWe$ z(bDOsg=n)~FJX2(sL(7j7!kS<=;lQX>prc0v&+X~ej^sD!XL?}{Uf9z|01b|SwB*v zEu`u6kkXK7eBMm=j9$$f`6Ar#8d1@kPw5=E<e6fDck=WR?dLlR$_XB-LCas2$SO(v zexoV;smNE8!6+kUR}92r_qE>WE+9Q5OG;(7OjTg*^f^&@I;3n;<i$P-_BJ)5C5d5j z8kw;|D6-x%U_oKmxeh$~%}A=ymt;yXrCi)<gYI@|x;x(dP;|Ubf<Z4rh7Jb1PJQni zJizwE!<9@RTX1?1QgGya!}wLZ$oSlvMnC=8<<X+Y25z$W4y{VA(F#g@u*s~c{r;8i zsi4Y18-V;<_u$K|C$&ZMC%Fe7hAj5Ff*gt?bbKRuo-yClLAIFr@ABfMpjHmm+K<Kl z6!>k-xz=M^alZC5O_w{8#@A`KXu`=Zer744;Y!QH%X1roIrF_`=!_I8xI?Tc3vU*h zZtyNg{mRy}AL7tC0zku)y*!@riN@;nK^(RQl(>}H9ZgOw$7KkYLm%YOLGjUcS*M*= zy+LN2GWW{zuAJdh#u*N$366{}s98yWIAX+M7AFb6US3fStSH*98vJ@2<A@phHk(si zUS562tlg0jl8U~^@+1smnMYCcCA;_u-(6C!tNb>e-!|Ci+3mwQAJ~T4K<Iq!>*Naf z;xO2Z`aVcMg;euqm_O(ixfvYrxQnF7GN_NG0jrOvtfY<4N>ftfL4YcJYl)4@@*RT- zOXOQ-2`8HDL|)uR^7lLQEr342NnlO+!mI>Q{qc60&3nZacp10s-G#<XlHb>oNuEZv z?&H;qd~Apf+$H=v|Do?O79C|xszBP9H-Icvtg6~JXoKX7nknr7te_EWo48Pei7>rZ zUSsS9%=0(cLO!)Lc`0vm4QU#(8v(tpQnwjL3I<Lt+oXRqSwf$7hVHnHK4M%t!$Hr? zuj4h^OJZSPbc29}*^ldltBmd`51NF&Fiy=TB?hidWZ_}PTG0IMQOC%0%b?xS0(9xd zmG1-#sWeY(7W&JH=x+NJ9uj5EbZs~!IRuXm&bASVWw~hfAc*I-m@Bt(-v1}UWs4>5 zM^}0zsEVnnxn~wQ<ZJfAA@71VqLTTeE*{e|`jpR8A6rC-o{9k2UQ=CO9k*ZHHeB~A znqqtg;qVjvwi=Kmw0L9vs_y&=#ay1Vw5ua2F#&Xd9CQt{>|o~6V}zE>s;ZC!&CGEW z{PWgDG>!}%pru^48$n5RbxxbCt;q6-Dpy{}oSYoRWCu!x$f%R{v$BPTn*#cZ(n@ti zJeQ+&LD)H@`Q`q!P`c&|$e7r>;o^ZFd0K3Fsf=_pjkGAZRrvyGldgPGHeaJlj9&gQ z7StaJv=i-enAFiU+N`x<xo^CcmYGgw`ZE2A!M7mR19l54P#r@wnWjLs<ucD6TZKz& zxOU2yn*#I<=;+X6K1#ac{1U48w*vI#70<73Y8YAiSY}5bAa06ZEgH{JQ&E3V?fVrW zY_TI5qitj$lK&9OI}z<b+En_h{y{fQy7^Gl;s{e$uHRxVG+&n$IN-=2lAaUoxQ;u( zet`DO9^x1x<>R7WBzyB<r5OH-2TDL*d4dbhv8aFv{vWVqi-P|{1AMI1$C_k7kpfuL zlE+>#*e@d7688=GL!~G%o%!qsi1lctDR}f`!ffIwRgOjpoNeZ>EQS93laMTPj?x3V z5>d7l$nAq@-(_gzWM+Zm(YA)>GGh$q_9dad_l8g|0ELLT1Sdy70*Xy%4kLZYSsV*w zPF$j)ISOoVGMq+EDUvo5n4qt<Gh>LLC*3y0oo7Em2I?0`huV<C#3g&|O?P(nANKmI z&lgr3cIqZMqzt?F9&+^y(R+~`5$dRFH?|QY$xmE(2^9QOwQp7uza7W%{N|ITrAC#$ z>sP-bq9FE;p$z|qn`$v)=1$gEc{7YX84R5?Q_vvQD~Tt&QeZQ}IFu~A&<7lq7!q3H z|Ir1p_?7Gb_HWC2{u$Vh2cgf6wDS$bLgPNbfyGBtc4tt8&^zLVXGYzvv=RSK6e|$W zF5wu_p<GCjL7|_e26=<0{keJON6>Br4<>;LO%35Onz~VjQeyZpSKK`@(S|A|$(J@@ zq8E|uLOQ(U;t;h$&WdDA8SwL%5y|Pb1i{hk_l_&6<cVmGL4(7V;$LMFjkUwA0BfS` z*Fpp|R#jR!KwjK^BKy!yv*s!rpwx-OsQ=smdrMhxC_yQNzRLn8ldMw^Icz`vbgSn{ z@yFA?oKmpZp_EBHw~|<2FM?jxf<HIJh~kvNh%GFA;otb6<Vm|cy`s*X05NkMUMqd> z>T9O172$H&2*lzH`j6gm-hszhFBuNR)w?^U)?%;*>`ZC*b}DH4H>+F~DQlQ$pY8fz zI^mCW&d0l#hH>QC?_$ouZY(b8#!4PRXj+3a`V!=4Ri;8Xj6a4a^Jxj>qcWaHE-?(_ zD084AoBEYr-l%U=A#fPQ-or9F-Z;db+arc^3hxVue<n1e`syyOpjM>BkRf&+6~uA~ zGy1a))u7@+B>qVB)D&Mb*%FuN>u0M^4#`=`nLAkmW*IqvoaXLIs;`RNDGTxZC6Y4b zB-(E}{!=YNKrrE1)WP311K{5lLi5jGboU5-G;xfG1GrTc*qppm5+8OP#3gckfKhkU zi`Xc8W>=lRZbMb9%;7A7XT8IMfcchy;ksM{TI|RxKOriwzW>cMfKy?6k~$M0dU;x) z%SJ(`R$3=SD%anlj1yE17No4|C_%V{LLyI9Vp9&)F6zSP#dZA(1!Bnsg|_It_)?>t z2+rl{(Z$bLA{RvDm|bt*^q01w=2bQk@1auCrmLvLsQ8x>YhRQ(R7e5RYHHZuW3V%N z0Nw4HcE#Bzs-cl(JQjHn^b<v*sTQ_yZ?XuXh7Uxw)gjh^rQnZQd)qWo<;a>ZO!g<o zJ&QpxkM5x(%IHYo)M$!qXN%8>`;BZr#6|CwrMYxmXlZlN>$+F>5@f^0^NB%-V+bZB zm0+KObI8z2@*y<a4cm11MbE1?Z@0FnLtXR~{CQhgUw?p>el;A%j+2%vycbuBl)dvi zGGaq)J;RL3;c+I<4E*dv96Pv*DVj$Ro(X7nJpDThRR>01O&@w->O#n<OAJ?kBCzU& zg4!2T1D>(5{3=xCpIH%$T7X@B44B#-HBQ@!JU72^eL)peT`<AXb5L(6bB)Muynct? zzUg8NQCZF-95I!E-b6R!QAHlFOu_YScHgCOiX#S)(RbAJ_RCwh*JkPQv;V5)!76Pe zc(|q>SCS0!G^xX}WkR&pEUPW{eViLZ3Vr792Xt7t+4NP3XuY#WP13`|2H$umn-7|W zAtO<+eVDv0T{V4kta9r7(W9wf^M>W*i+2|F(+v;Te>4|43lgQsX9P72odyoAyi%qc zYtk68LAd=Mpqj}MTXOql6E0fc_<I0Z?I7%_xuOsjxJSbkiC|Cg9OOzn4E5}Hgj(N? z!1ddHZ`pORu|n0Z{MQC5dX)6T((hIYyV85FTqb~mUo0CJR&>A`R8^(!B@obUa_@1{ ze=U_6`o`g?1TV8@mSH`@@iOg7(*E`iE={Ceo~`0lJfE|)aw>#^7m}*xD(UP8X%*^* zIb!lh1FwwtB){WIDy!&qI?ZekrdmOQDS%{;hEQk=TRQtCDa@3xzLLyIlQPQz4#ZIv zw_JE%ZYiKNn|5ng0mOox96hZZ{IAZ+82=ARifou@+K*~oHhoUdZXiV~Wyc~D-XNVz zuK%+XNRjp?Z*<I!<CD6Q0(sk=8RcRJ!e%HSnZ-k&_^CaHV*_!tw9ms&Eb?9?H91`L zNV%*q9il@p<uNL!%uBa`P-K^wQN6lq;<&*#C8tzo_Wn&3nHqfmK@bj)8!_0+VJq+J zfPn5ERiU>tk#8Er8P|WtQb!6$&WKmNCsjRZFUk0)<M@b@ID6cXHY95f`RuCK0xF-t zFD#T3YrxIRzs|{=!%JYYaG!TrIm_0U8A8c(kB!*^rQ@)(%I;to5A_vThl+DmR}FTC z;zUIPzvNEgEX3})91MdAvM{aH7dS(8g`2X0dTk9%ZIyPWl;C0etOCMsB}+Rr+%%tv zvi}yAe_O2^iv6vx%hAd$l{iEmO4csWcE^-D_>J)QH3e_Czng`0yPcEXb<a8X(#sG) zl_<o>b`~HxSr63Cfg$8gsmOAn&?-`BjNxd}D@`-5?{vof0|2rVxf+@eheEes?^f~u z=KQ@a$OyYkLZ>3Dt2EZ}g*0s}ckoWXDIz{7pEkOTtCYPE@#aelX{nr}XS}&51}r$d zp3oNoZX^9N7n0KIm(Kw(U=@1}UL?94UH{1!rO>Nr*YS@K#1VDEzOAAeF=W<*WMlQ{ zT{4{VMIH(FmDFDARAYsvT5CtYwrb6C*@eox**TG?MvQa;x*!syJXl<A*^S&!5e%9! zQd9-Md>F5wGlUU?-o)mw?_~Vg*?s!@xxm8K_tZz{EJqhqsvs_A+%S%3-X1WFCC<F8 zSa5tg?Yv7vW*FWCYHV^peRdCzbKDmo^OEaElr;~pDYAzC7?_}AIS_$%sJ@M<xAH2d zvA`u07%94&cs+uL|5vM7-+Ttv?Tr<HxNymb4{9I|ct;mPN~MEKYe_Vv)W@$$srB*k z6qw7&e!u$j{c*#N_Qa)xea3zJSmc@#F&YTdOkZ?B9AEwJaUeF-nz}Vv6*CuC%agp( z|EHAC7+_(Pe1{Sk2641b7Kd$dwEnOTNxHHoc4I+I_&%M~Iyx*PE$Zm+5KXj19AuM! zk8>N&SiSh@Z?w1Kbg)Y{gsMlN?(v#mXqhZ3iYCGvWi~-0@eV?F5vt0qgV_Iu{Nr<~ zuXYUfF>eosMQ?D+)<R}S{bIZJG(DqAf}TH|X#z;>UczLGD08uCpi;Rnh9W|cX@h_h z1H^#e-?gxpwDLe4|0IaJ%`hudJlwOG#LK<<_^H}ZP3eB8{G4<*Zcl|~zlZ5(u@uD# z8rZV0{L5XYWDN9|mc--$XFWr7E>zo>!3F_Y(C-Ged~K~rQ>|?2fFc~c=nh)=_(r!A zXczJbH~P;DnSsWNb~V~Sl|UkuTITrRq@no8>r(HuzcdY>zZOzglTWqoU+^n1_NNZO zc}!o<nXS4Rs}nLrJ%ffl#i|KuyKXWJ{hckc|4qXg-txJcsbd<OsbykrO4B6y+TILb zA4!O!w1%j+hZK77)F>|eTb}W*-mnj|J$K_xHp!M#(O<xhg01)%sfO7!g<ZJ%&*Z%e zRC{(7Vs?Nt+u^Yul9&c!G_htw%f1;_z|WQpkrBGJpeL!LoL3uXYy~nwMGgwjhYq`Q zmjMor<uSjosI7K|6Cp5nOt5%4!4_KT?Io6&{+9<3)n6&laM?X@dw)Dq=bRh``K30y zx_+1I9X8Bvh;T|&iYQ-y#{ZC-O>wQ${;QElkH5`y+h;U9sdCzcBeajqF_;MPrPNi5 zx{G7pI7TWR7{4wDlfQe3DkT<ADbt;q{}gHh*9~T0N0O<HK>N1&r()`;1>Kwm)ph~G zr~y+agJsI0_1%*3bO8%Hp&LQV`T>r{lD&s#y-)kUu5dSoA*-}kaM7JR^hw|muEltR zPdg-8SN2eg1@!IhA9zO9c5e$^z0J=z1}-paJ+0}N`T6>rlp_R|XeKb+^w2A5G)VLe zCzd5M{JJq$%~Y|S?dmw{w}1G5x%Uh|eJU?0Zh<veYqVPY9d4L$^WMMPT&eWINoVKK zn;UJY@fEw9d6gkIX`>oWT~0WQ!q~Jh!|3M507!;nQTcK0WarM<Z-PVtyY^{Q5-_?C z&mjWbAa+u~4RV|zuT;-z!s=m$^@+MZs%w4}yi1z>a#>4T(&}friZD%}&C4eLty5O- z&DR}lWZB*bDkfSS8LrTRqSBk}d2Zlp)U>pGxtzR{t%WB7uGpi{kOKEE$Ekq+X*3Fb zWbO~npI=x#`*45%wn;D8K0HT=6i68hAHdVT2M1f&uB?Ogs_BA(r0NylE&)vWA2iMg zziL)6pSrwdOF~=yAU_B<+1o2tC@37D@6p2BqCibAFJm7;+1Q`M@+&TMvZ0{2{<Jtk zG?!AKIc6W#5&y?Ek#Cb8-(70C7oAEUu9pqSJGfLL9?w}Hl<Iu}5<r8<Z~1DH1%2Ur z8x``>pO4lfV`gA|GXn8i0HlVDn&VQj<H?iK&W%m*Lrk(D1z(S|A||Kq7HYaAY1`p# zd$BOxWvG8b;qdrA0x;j?KNOg$5AeHJY1POvjMD3t2}siv=3J4CZWavu%!uIz#@{~3 zpJ~Wtjr#I_S>>HRl!(LEp{ct^OSvw!?BAbu=f#B$+k;v*bSbJfG#-W%AKE>dc~ifI zGfW?Klb~ttaA_M)R9&eRY3j{vDEs+KENU6ksivZygJB3gnGcW>zE7SyhpWXmHM(yl zQZM56u*iM8c;FOcK{9S+8pwsPgLJUVdBlv;c&3KX$O@~Q>jZJc7<_n`b2w)Y!!r|r z3P{R(jUP3X9BHC1KL>|H_}SzCVSg@QM@*jB9cQR2QO34qfUIq<_v%jmFlR()W3d(m zIT4Hu#2yfDo$MK;6Xw!nA#1-X&8Xz=uJhwfm6I52Yp4#(2-Yc~Mbm@WhKf};`%RWg z#w3oX;fASuT<Oyvvm-*XKd}VSiJ_0Me^7&^rycox{=&6J(g>qPim;DHn<$W@cUcfb zN>Y%CMCxZrMSGF#9(N|uN$(P|S2%cZyfYOUU_>)B!bG<AnWjS@C<E*v^BtUSigz^k zsI-f6L=`i_W^ztm23h*yKrC$#0;T%zf=f~rRy2n^Sfnt#qNPB%7$%fx#a>=zF2he0 zQo(fHV;mi{=fzh5S0+rX5^RN)7FBw|7H#7UypR}2F9pu$nc!u4WD@Pa-Us&_Ni5sX zOdvOO0~`0mja59r8~Ul%watnvnut+B4=3T*EzDq_bX3-k6{B0K+okay7P}~T{C@h= z9MU%Fsb;VNn*+^P*fz0F;49!0_G#&q!Rw2lVJhMs!vy45{W?)w1$*M>4+n{2)e-=i z4^Aoy?f(YMMTSeL<Sn@>)Wj4RJ2l%P%x^wzae8#JyBnIvc>;Ng@Jzcsv{_tm)>aFq zYRq%LRz8O^mR8DCCntY}#S5DJLz}U8)!7H29r2K%8lY2vkDO%kKf}W$Wz56y#}kO^ z28NRfj(N+)BFkkHtn}22Pmtw+(wZE5(Ba(Zf}MC0p8Nz%56fLAg<qPaWVQvcqpUZB zquPg_o=({+CIzT=OHgnIO&_C{zjx>Hc|ro=u>Yy|9|d5VO+GHXzb&_bpXvYJnk~&H zw>9I(rsEBHHpBM0R$8OrgzG5Qf0+-*@0kw`C(T?%>o$X>YuTnAJZ>+5Kxw(_rSMCd zl<X+*gAPqS>DIvdJ|fY9P~3$_CoDANQI%V_W7sJ9sBDQ$xGF_>!ivo7&b{+1C-B@q zGGsd%Pf`sku?E6>m)2&52+D|?su13g8C9Y%UfZhkY)Cs9y8jwp^ASWgK0N_46xeF& zy@T*RzNoXx_e;}|I?P8&q?rn4e3%<nJA=Atu>!Lh7>ayFM^rw`XY)PH-vy#g*b#G% z3O!-X0*2G{BF~!m<*;hOFj8wF&8{xT40X~;%sCbneu;2E)7@mud7g6Ur_&p=49wo0 zg;OaUqm)r1S3Ah<1dLxKq_8_c3!%OXLx3T9ka`wod2dS$Q&92`BLE|j9}o?FA-o~- zMZowF_Ye=k04p!=Du&4tvfK_S#7rN1Z#QrMKBEqr+_pLFkho#epZY5KJCI;j$)jZ< z3)ZyBK(y2wvGFy6r%@2Fpn@Iu_en)UoX~#hub@^qIL@e6S+BC#2#KOc0jOZe1!k}9 zBt|BVS-m=?M$R0FI;>`@qA2;mPK{{oLV9=<uK{tIXTsC_J0HPOFu(wD`&Js)3#uov zTF>Bv142OFv8WHA1*3fPSds_QGq|`)YNg*N{s?1Kbo5Mzscat;V5Vin82M~TzkUH` z2ODB3k2sI>wW=B>=~QYwHLjdIQ+sdU$u;Tb{aB@PHr?0K0_*U=AfFHHsM4CxhSX^9 za~V;`4{{S?5B2yPauM~1D!JeyDzuOj+<K3L(j8GCxeG#H37HD4UH=av?pqB!gg+>h z2cTwZM`ZvQ13K);d@&NR24)!KX^)VP!*$01b8}u_z+S;^LiZid_G34*QzsX+@ePtX zp^dBxWKpHReu3b33ppUO(%#77Bq7?v&EhP=6f7~=C$ASyRwhT-eN}BW$AhM;B4~AG z%WS%161W;je)eP?|BPyR3ZLIw&yWlj-r<o_i^yf-UFL}KM|S+wOk0Y<>$whdffkx4 z3u>%(gq3K7h~q{w=IkujYPom<@^6GuHlZLeAfC~B3@t1E*LX`a&4~BLV{iy7)pXJt z#W=q`NAJ&10p6Yw1d2{tBe|Ch@D7N{`m5Urp-f|{y%ERDGp$7$gjXKB^#$d;zvCCz z*D3o|DU(ZSR6f5a{;{1WaWnJNO_*?Enx*%*vC7$D*aMB00&!$L_y-Kt;0@Y+o%W{t z7(xbcAnOA#puY_<X?O7KEzE@G7cZvsaQRMQNA0>+R!#tIPENS{6i^O<JQvCXC<xsp z9c=H-=`a3K<*%y_`W^h?nV{zf1adJUh%T)5S`GR;ZNL<VJU`9HiV5InCae@uxPoTg z187c|yn{Gi!n5L5(TrAeoK@+rjX@%Zo_t<y{d(e<)wZsBD)Vp>P@%a+EY9ywV8>nc zJ6NNHi_w!R^A+%$V6ag>Zy>b3*NVGvs{xY6a={QF7VQtKdy6+Oy_LlO&4hA_%0V)D z(D3?m1$yu)$pT08EnL6?1cS=ShsK(uChIIW3ux86cf<G#i-n=ifl`Q{BBGACR%4q! zQ!<te%{U%!l(bL59;~m0eAkNhO8>GEf}vzH9(p5#6f#*eLPb$SWqd%&h?2JrTfy6V z8po>PtAw+EYR_WhN?qPiO{Q2;#YhCuO4_*FQX|5HRrh+P5bju4Aie;rRo>(uVq}SB zirgl1T&eCM+%K!I9ROI4KUu7Sd=Q3cuiSYnv|MJgIWh;97{mW(103@^KkQe@#kfrI z6LUn!6ct<2D4LXjD%}yS*~TLNS#0!(EG`@5&|wVG9+sHtIy1!$O!&kmQ#v+PeU=DX z02tpK_Einz4Zbfll-Y+{LQ2R%{Ptt3psp-nE_~X9$%6a-1~gee?$+IyQ0m@=Ab=G@ zlD@!s?(=N?`!1J(nKUt3m<=HZGmX5tO6kt9)?Z&$x+>f>1IB#lPG7A{@!M6B+(LF; zKMyNe2F6Z~L)+cuYe5-ftyr}={BD=!YOMs5%=dR=#ds(tP1ei)e8Z4pzm_yG2#N}Q zD2Wsmmde$KOb(ZuZWcT5EO>+DGdNZ^EnR+yNzHWnc72#$-@b-^^k{N~3LgH7)pb-{ zE|*9BP8dM~c-Z)7r(}3jZ2MEIze2$FOxXP4bKRMyUWA}?L2nzXu^KU1Hs?$nCsMHA zY_+S+GUGq2ce;a1wP)gdnhH`28WGk>yFKuLF#rO_#kQyOYn2n>3sest#6FUO+WQcT z;~MaM<BO7}DZG^n5UuC@WuFEqBP)yg=@TR%b0jgh++hrYwxy`+#FmzjiJkBV(V3D2 zh48KhBWn51*@~ck=<zEhFq;UGp!b`p&2W8eyp><9Gd^@?xWyT*nO#~6y)>4>m0bD! zf4KntClgP<V-b_xmY3WAIz<9o4c-x<X$FVb&VnKaUV9KQXn_9!NO}7Z9uPeZKnf+0 z3{qpbZd0l>Yl#2nj%SFQH%D4!hmfD*P&7nu-i7B7V^B}B!^udGU0W-$i9I+P20u<< z+u^ZxRf@zf!uM_kM^X5e!$%**uH}eo^|?LU6e>&%g&%WD;05vZams%)jKFSSONuaV zjHwfom|4om1Q4A^%<3$Hw7DoebBU}ybfZq*m#hsbjNHq-8KCeb-N6ab39E#Vkxd;S z?ENdC>~uFe_)JDx`dPS+<!&Ubp1|U;U7S?e%J$`{R#(E4T=Kh_1Zz{%KsL#+%_*vj z_{p8ZQ5ir2xZ(vaO|-o%{<n9L-U}sLPe0sV`~A)Y`XPX6V9V-k3mW1LVH2PU<{vt$ znugSf<oY!eO()!5KPwJgo%{5CE+ElvLycv1GcVp8*o79+^zePWQqnQ-{KpwXEQqh4 zha>p<17)hS%?3|F@SiI0Wd6?E)99EJcu)9^cY_uPVw6h^*o}}Gu;0HX9muPXo#x&G z3mT8&R6sPo`31o|e(9sXKnYc8E^KLU03+s1(mH=AzBzKC_$R{B9&uT(ywM$Sv`R{S zXlm}6T~&qczzr=%t*>|cD)w&%n<LBqfezLS6A_wbOBL#(+ArU4m&5dX<--t6>LP&U zho`EomwX=Cx3e(5DUY=TWhEp0XHvCBytdxqbx>>L3*-?0zXQ0&+lo&Jc5zMifI_)Y zMktM#j0W|cbn~3R)NqNwKBUvYVNUG|3khE^mVqG!4MjQypWO;`|M_9a<Frm{=C@yw zKxJ({g!fq^HL}nH>f`JAd1v%;8=q=Q`c6+Ua+o(PHgK`gFu8x?0gilLl=I}H!tk2- z4kvyC^z6gr$>s3sZ;ldnZ?B?)uG@K?f-4mMQ<jv}^devHb7B6Xp_{nJLyy8=jcQS5 z2UA@T@q(|oS=@F5Ddj4cYtEB!&Z^2k*1_P7nd#|(q$Kpm@7v~izF{LOC7a_QMa5-b ziM^M9sT!<iH#CGUn}L?D_Pi(h+S*aUC_*06Vj1lx$!B*cpMoDB+3J8v8L_>m0O?Rs zVwtX!hIKy_U1B-At}=(xI2WuU53J_XFhYs{vA=pRYj!%Sy~$v|NLWrcV6+_J<y7@M zNODJr^AOEG!{(K`Lu}bpVxY%#=+`{=?%#uzRs6a2kF;ZV5GovO_c{`4Q_2%|WMih2 z-2zzUm_$jphaZ!zXo~gPa=s!aQ%*m)rj=N(i~p(KytFQ<V}V&&J=P@o(Q`Rztc~9K z1xN>Cs5@i>;L{fDi-`UCs^z@3wfzuMH-e(<!g3dpeYGa3fr8b^Nk5@tVwtUG_#pS{ zbWN^ou}}7+a3{y<%P9hr^ph7wN^kx2{0!;Fi9X3!*(itg)9XEOII)islmA6OiP2yb z*545chPFHHR-esRaGmLxx?B#=hl7dS*fHjI1`4)>2M5pu_n7f>AVgNyyljC@FEh?2 zj)pFpN=(aRnob{7H+MQ?KWR8&k_*^K<hJOfO0!EejJd<)m9k}TUI#ez-)brlhA<%8 z?uiJpH^8NNNeL`Stazwvekj(y+P2(C!$?20V&6$b_tr$&EFnOxFW4{2OzcI2EO?44 z@LU?c_j(lt?;)s9==NZE_0kpwz3Mf_C=)HXuyLWI%KY4@YoO_i<kz~HPJ3id<;gMj zm8sROB;Rs*?ihxEb5nh+o+(;`Qyz3!b3Qf8JC|mvH*`PVGtKeKvAOe(;b}^W#N3%3 z*ziS|c%lzC`ZOm$d;8OcX1Szfo;K1Jua9z`Y+iecc_tiQQ&FSAiL<$6KmFJQd4tV- zhs<)?_W9&4W4<`o5{#MYg^SuB?^KkIc8VL`xRo;?H&W`6K0}Xc+^r)R_&m!bn`#Z> zX|#%bKli=21|J6BV`N4c)u%MwDXjXw<(cg9BI>y%o%okRN8xwRQ}DTciZ{rlDAQ_j zI4vBEwhb&<=ZLuqyvt*P3Kd%2U*rHl<sI&j|L(AsOPeL`6!OJWtO}I^gOyDTR(aeA z6|u+W2VEX_CVw-z<uV%j<U*zRjTp~J$0A9w<pu@>3@U{llqr5iJO7J7nCaSTWxip^ zMP37aHD%KDG^~Lp+h2?JZ!Z_S$%@-|EA~TI-09>NpSETMc(#YhpCVYAJa&Yba1pmF zDr=C5+@I@)!r(;3B`hN`-&V(~ss<_=t;KY3n6)wCeLX<uemFBr`%D|2aRe3Dw5317 zP&VEmcK*coA1^N#3$eA^G=G-#{Yd$zRid&lu}CyeCl@$nLTc9EE`x%WiAnN0jZwbD zkm80wDEo(mJ7kNTVCR*JJc#bY^JsmQkYm1m_x0JxHFK6Xb3pPO)z!Ck&IdJOVv8&; zt=2YJgU<;|iYe@f>@3o_WPxQ~2~OBZTndiG7EhQlBrDtkTJ@6!nhD<xU9v5fYk7Co z>qE181FE}As=1lb;J*0zLzFCGpexgi6W@NCt>f}*xDO|Y<ld#J{~_@y_Xbu%;r^Ta zQcm%wqD(bYrz6arZ;!n1;8!jQSlS{Tb(K%|$JRHSEWkh(3~<C?>qW%It%|Ti_@I}6 zZ9}~=uKZhfB>cR!$91w$Bc)|(TJ8RkeK>)g4o!R6UDEC6ZDnPpaqb?rth7r3oQG2= z@8e2kO@3P&H02;i*ZuG%HE&2xA?mCnMFfxMPAoTAx7qR~EM!@%FPd@k`4YuH!UGXb z_{>?lERtg1=lZlktncr9(|p7p<u{U2v9Za6PgoT*t+8>gVIDD<XNh<MK<Z#UgLNg4 zjrZZgyzvOr%QCA;{Uu<jqDh5prbty(Nq)cl<NoxcnC6R(IkDi9S#$5k5~mHpD2p63 z1uD|ev@=E6qA1$TOzX#;KQVII4m+47u$jW<LvbRm?Tem~o2UV0#Jg-{Ro`277Ei82 zUo^>Q!UnRVQ%|Ug^d#Q1O@=$gW!vU=(Tt6Acg7pUXF02es_=e_;p=3*!%Q0hn|^{Y zAH-`vJIZi5xTI&Foqq8wtmyBZ86aaL;S>Ecb9%H~P{YT*2*e=5p&SRud;VmMmQXSR zr=hCy6<Y1qP_hF@h4C*2fyG0t$kg1kUEuTZ<wk4eb0-2Kuf+l<ne7;m<1WP}Jdyte zDU9rW0wa8)gP5p_gsCY>xJrG(1r#MdZ^2cw?HYE|1a{i!n5@`~<jMGS;>0A`Q}0W} zJU@a<I=PVD&yz@O0(rqi&V~A_A?WU=et0jsGsn4n)2_ZC+SYYa05VWh<Sh0f)%kk! z&);NNIzF|8(zY_<#$>_J>P<J&aAda=--x9^(U1NUgHxm>W@V%wD=`Kr(BdTp?jVLe zbkItt`1#IV&B;*BlChc1Fz-8L<<@c<`fKn`4KLy1^m=zRs6KkElVblU--je~3^QIq z02We8y7hFy^fv;oE8kSnCJy@^zi<*PI)^Ok%2GT$D(9oqz61N4{p3Pw+0BRQHRpe> zEuC%Ljrz0a-_3EZh`_{Mmy$N;Y<+R(W!63Bu1LP4`MQc6c_Q(tY4Vv7Nq^ZoZl@ed z(H#c@!DFpKQ~F+T2VD<jR>I&a#YfL-KH}z;YR#ug1H-pMGEIUkR@=W&9T(&55525X zJD{nz*c$(Tl`ZG%;LW+~zjre}H@(7+2YT*X0WT;$pK$bH<EdMHWXu2X+tO_kv~~Z~ zdec~~uj;nQY7!lEdL<5!?)zl=wVj}cG0l_{NrW>TE6vmv@(Xj8+^u(KuI@QHpoU|j zD@a#4hM5qQfvB~a$eLLs7U-EXsRlDG`cjDM6|OC4$85z-$E#@mj5Z>DQwkhCF-B1T z-Ca>glLCqmFUB(kT@H@!ZeyZAHG9)0qPkGnsHG_MAGb*^Rrg|V{YM;#ai+4b9|4l? z$2qx}YEj}zNZiea*OLrE<BmN@B&3bA4G`1Ut*SJp0bDHKf&Hn>r`|-RS+_-HIKmMM z_}C1gOo3Q%G@#rkzLc>G7HKU&i9fB^xbA7t5w3uv28$F&ery!J#b!f21m<EW4l>>d z`E%5o5%I+-)EGO4J%uCFpG?1A6j^qvlf`(RAbH4!F-aWOW=JRt=QEe4N4*JP1o(0{ zF|-;Vfq|xi&`bYo_Rwd;5MA*mmU^cNzC}nLIL;R|^HZNMZcJn}1=9CkVsXTD>7qT# z>ttYDZkLz2M)|*6VoIL7SEQF_`F&`iSPaZR;?#f)2bYri@-BmF%Y@rvRQq6gvNKBb z2r5N<n6(43uHod{l4<9}0Y0D(30hF5rL(hP!}NEf^P*9h2&A#b*I2-23%|e@bs^Q) z&}f$H=Yif@d6F%wLbSFf5~M-?-eif3(sB<Je^nvWLG@sbUf%h)p$=t-)rH+HFz8Ba z_rA>pZy%=sb!Hxp(**B&D2v=zT(|hu3X=Kfo%bjr1B;GngM-Fvbv$pILKek%M?ua5 z1t~&{xzri~SfxP;ow1@nWnhxgzn>Zp>+PawPZKG~qYKy+MC2R)V{w~oODq$=41Wpy zE(#g>&xg!$9J}UF;x=IX1w@beaxnJeEu~GY!xXYeD!vc7|4V-xl3`!Y^)<kUTyJhN zTEMTuj`3`A@LP4(f1E<lC37MP<6Sxxq20AUO5zwL!4KK*JYTZQ00oBkoIr7znQ#r* z8iK;*->*I@zmidd@~1)UUg^`0&&k4?@c+aVZP+8P@7*_g-OW%=jeQ?8OM%120*&JY zp-;H%Wj7H4H0xl7DL-gk(;Z2o$3if+?pHJQN(tN=nXD+-Y0&9*cHbS|yz!<~{dQF^ z>$sKEDz*$}LtI1cyVL@vL`D^<c0{wPh$-J-u1Wt)BK-)mwUjKnevT*_qYTa8>l-E5 zmOr;_6{VP2W@@P+%M!M~onb^mqZ;&N+|~|pkASmGWM(4i9hBdAe<-T$Njx~Yesoz2 z4=dSM$`Ck5{WBzwS=3HF8~zcAX!w1k5O;cBN%vkwQf1QiL?O&2mNZa}4gLa>e*wZJ z5=1-=DP!LLyzX9t*wIRf;WM|Zyxd2jjfAkf5w5Pc7w5}EjQIP?d4dJ|o{-C(>Bjyq zj*e){{NQs1Gk_zNAB=Qw7zl2O3v_J%5_(~Eoa%gfx%XW!lsIhJk|gvS*m}79nclZU zw45U$h7|p-8_20|V)G@rzEA||oE|Ao67X03@U7O%WyGBU10Hj&mu>JWwiAkFE=zC! zB#{ZfpY(X(F-*{^u!}&d`~jatu|;8|ZwF&oW*~%HrgBgm)5jBh?vOZyhZj6w*%VAg zF)1Lobk%8J7vQijIoA^nEM}@A-8JkLwQmOih$toiu{;fI#QtVX2V9>bCMZhqW7BAJ zBXz*YD4sh?02oMFJjizTxHzt?+45K5<vnU*@P0G}-UQ9*2XVrR={&>iycDuGps^(* z0%)EwzU%a_EE*#8WzWmK@mSig3?9dzRrl#Yn7eji6u}#%M<cJ1<xDI<9812%oA~#k zWvRaE1fA!=Dpl?`OpgZR*fJka<Ga8Q9i?+9ot`{Ednb-wwB4G$YB-(4n|SIY<`5zM zJEdS(6_?jtD<yj9kX5WNV&b@s>Iku(NGfeMTi}Xs=J=~DxXp!_sJ+pYpNq?0LGAwM zCw`Z_SX9p|7$aHPY@4C+D5FWm0hVA`I0<7(ET?pKIrOs2lLH7l8Ix0ZAds@MAQdrT zDNuu0Mw5Bwznv9IJv89?`8@7@^|6hwp<b&_H}Ha!BJp)O6b$_(_!0xE^LcdQy#sc~ zdt832-_I}=KYhJdn?OJ@xcmT$--DRX)d;o6(O|ks#tS*Jur8nPy6=HrD@9_&=Y^?M z4P8<LIj`aUA%_}BmJdB`fVkC3nTV0LT6Z)5h%@nm266Rs2IX89WB_nST(kT|(XTT% zw1>+xu|dyhFW6B{O~1!<folRwoc_cTg?|4`qbH#RIT0a1q|@9eqk%%i?srPlI)w;T zXJ$(-*8rnmgOW@Y*Ix{0Y@|O$OU!#BS4~P6f8j}UkNN~l3<!><-ZCs%LbmmY+zU;e zAAu_=KKOqLOF)2n?yROnxbXCa)fV~P<TjFkLPW&>{pn@eS4a+57<x^R3b44v-4)|8 zGrXoyLiCbHkKplXE?`ZfUcc$H$v3S%E`g${Dm&M6{HD`^C^<rG@q8@r@?VD|vPV#m zWBR_<D6(45Gx;`w9*nmKB3V8%ptH)+<!^a-YT*gs*H$|U%5~#$e#nKv4}vQm8oNFk zp2D%PKDUO}>##uEpJ=B!_3k)aw%)q*sC}N;bE@tw@^o0-3g7AipCLFS^VPgXzrBQF zy4!W_VFTz5@-={@hDisT@2<r-F3}mM2{z@#aDxqL0@*y-6>H%)G=#(r!E$|7h(8A) z+R_I+LL4)WRY==2h6`tvaGo_S<Vw6f9`2+7S8ABU{MpCp+u5QXzzdTRx*;Sw2ZDML zEbQ*IRwJJPX3#(Fg6A(-rl8&UJhjGHLxo%b%zw+tzv|Wnp^m2Rtm2?FkCiIE=0_Dq zxHk4L@Sc3xQ^IXawO$A%<lg%UVy$N}ICE~E>C&e-y^72?Ehu@l>-gJ<KZK)NP-25D zAXbH|>{qJA{x!VQ`H<fGJd|1JwRohyDhIK+`@Rd@=zG%(E@IE8lf#s@>2f_H*`4HV zm@+k2M*cr8$OV+hIIu}vKBSJQxsc+Q%H?RzE-nt=f5F$P^Wlx--3n>J@pxS_cQi`b z8J2fBE-(GQlx=S&-=4YJC)FA}m%&Zkwm>}?tJ$!px<1^O$Og3xFfSpncag6JP&|;s z&9h%tRC^lBO_nAF8F#J8O|h-}dYw0RzKmy{8~Fdp8bUi49E*a;e)9tJAM2W~u)Q&j zo|DV`G7CPlJbxjk?o+mhkG-`{W~ypi!{qUZaNPFYFI;v?ygr4Iyrnr#bgy^E^ac0S zgzh;EMP1d%&FfCGi@Z0rm5hXSUpO8xad3(}$I_@kEa*>2d4QHYV%5qza(%i}THFE@ z{J}vp`t0218Kz~#0UmCD5a0>PgyuF3;&clK00$$W4SqtmI<2);0=DxerL%ly4bGlY za9;?Sxey^=SCvQBI5%dS-84KLkK5WdoS2&hpZN+TvU{@Lg7jnZse@DfuM*k~uumIi z)Tu9pPpA_q?-k)v0)#PwzDr#7lZmWiHfB_bhve|yprCDrfYE8fTErx(^JU+ExlnRp zfb9B8@dnV5eimA4<;26E2L?TkLqr6Qd5FC3Pe&gAZcQCu5V3wzI%%!c#tDyeh>~_L zudJXs_>i#!w|;49g~kg#qk5k=#IH&k^~B|#Wnh(8l=aO2S}{3{oUCTTOC&?xOV$TO zj&;8iA_jvx-7aQYroODU3mDv?Sp3*YB7Q)ja2)Op&u?<G%~(v#;}(U-$4X7T@ap(G zcr|KW6PgO7YCxUV4dr^=-u@^YZbZQ8JGc(bVdhXTPS|U-UKn*9HNT#ZYVHe(%}h<D zVXo<cIqzmZQT--Bq{i+J2S;VF;_F_e-OhE|R&q4t2au-HJTH7tt5y5x&k73@Xi~&z zPIC+`$8?^nmqWz#Q!CC>f_<Znyia9CyPm3($8(iWuu2s537X;yzL%jmebu%IEa~Ij zP|b|3j5n`;AJaGMW&N=)uSc)F#P-C=5($M=4b1btZ736wi}a!Xi*CvrVW`()DAZzl za@(i&T#w+Gqb_QBnQRvXh`(&0arcK!R0z|Xb7+Xsgjei<4M4CLp_*&;vt~b@Q1@Bx z#GBK}R%W%df}V{s%qSRO%$UaD+ii)Yz+K!%;82uP9yv;JjHcPGBApq)PO*^j49p>u z$Q6S)MtZ|WgcHG}vOhgcBsKrWVOUn=3<HmF)xT_pAfcd4q5Vo>?zsz3CY92emo^BZ z4u{jW%bBEkO0<ND%E;iB1nL~j(K<;G%Qj@n3QuMZ#Eh^bos2?=)ohG=-=$lbPk^z9 z5=IVfxM~t_kW5Mar)EiXqA%1Ng2x8XX&WG>15$0$JR^5e{`0WUh0P8hXX2R#f>GXR z%>=8pYrinvFI(3{h@uJBy8SDZXu158T^N?be;Dww_OR{5<nQB8cjiIc=Cw3eQ8YN_ zclGx8<YcD)*QZ}`&-D5hxV%;r9Jh0&JL|f2g^GAsrlw^z_5qY{2&EmxxW9g_i0z$q zPp$Jjrl=U=u6f+AxnGP7<>gyTX=t96S|DSh?^Jh{;BSB@-FLzFudnVL931(-f2&3b zL}N4d9o89}z+P9@bm7MfJ<+7Cd)Elu?ItUTYG~kCog6DE>&K}m@Zx#@Yixc#%{fCs zOa)An4oEX|3E8r5$&S?GRsCG?pVxnO{GPwD`#dq3QO6#L^HTjg_ZT@2#y{NG@N zdv+9s@Rr@qef@hPhe&WPJ2XY1^x8c^k}(AQ$Q#1<x=V_6IgIWbzTDOAXKhM(tKJ)( zG>o+WoOKz{LZHYibXM-%w9NVLa=p*sZb_^1bK3K-{4b;FfAWa!Exue`4v}mX2*1e8 zKaSFa_YWdn{`F#-oZj&Y!<c!zS0$U>iupBDOf|%BB!%&rqNkKysj21NLcEGxN8fPc z_qc!X(E<IAW*BSZS2@<@GKBx?Yg`+hLA3ywM$)LYpD@s)=I5nw5N!-2b0nG&hVbfR zjV!!7*I9<-NviT)_7WCF559Ggv{C&KGu23wA3AO;Nf;Ivoyb~VpT?zFo#y1Sw?*Pj zw&6}uxhdQ^#-9%#Eh2fFd}@<GD?K!A4u9%n<dC@>#g5tLVgFHZkna~E24{)sb!HUq zkZhMza6XCO$)862O1~RFj1VbKft=(`uN;ook7zy|y0*T=Nx^t}6iJL9Y*?Q|4sE$A zzOxYd!o#fbrv?w0fkY7d6<$<ea$5eKH}-zWtX<*b#o@Eh+++HFc;O_D;<GOt>v-ID zy5p-f6!pNBE3&MXa}}v*{VpPH1U`o&`OlJeq+wUpix}rk(L3?}55X>B3H@PCU5i`2 zg}icyo$NKyNUd(Kw>64CF$Uc7avb-ye5s!7pVrPr!I8(u)+VpGPVt0*WMffQBjzb# znpdkIPUsZjgI1dBg|Bb0e)3Sz7K2NA0r&$W_ojP$aN$totUG(@1`1`&<sBYpn0$Y< zrli3neut!|o%idc%`uE^1ANTdYj2P7{!~8ChT%kM4mw4K3n0CCk3GH>_shX+7}ao> zzj;%EBgjB3dinxKMh&Qp>-AN(mkQGywvYkIvnY*<(4|>o(2bXHw-l@GaYFedjp-2i z0~O8IS$8F-S_Wp{1|PK?0q^!N(JQ_F<L}sz59mlaL4h;2WCpvTL{i(M`*&PUfVH&N z8orvqqRL^5j-SQ#wK-O5dF_`_H6b_)FbfOQq_$;O?&1<I>YcsMzeF8NzH4XsAr$CQ zrvl<;pK0=*qNt);LMe1C$hIu@vRwa8DlP;NjzjfBk=9IwUnN-{vc4=%cSr~!Nw;PV z=bl$H!-)suc}*hwYHZW@B(Dhf_uXNuMwI(5TZhj(hwU0?=mv)rwx7qpaIgSdF9u<; zBSx%&qKwOF)G9%@83*7nLOw(m#ktf>+njubAYy=K&6Fb(RTfB$5Y3kV!6j&>pSlw# z1U)5ijR=^CZfmv+WeQ~IrlYEwZPKKz-#+aDw_SSb8aZC{!fb_LD8P<Y8X33qSmZTK zx_Q)UB4fBeG+Z;ce5RP5PIBs4EQ}@a&gNf`WjjOTJFltfAiT>R)vPy>S$+~yb9i72 z!}F>4Yzhsc_rvIshH#(3Fo4T(PUp+@8y4h-btPnD%H=M-1AN>`H-n91U&2>)d5{A1 zmu}oH2~r{Uf=SG<>fVj8sU~|7r0@dcjF``BTis--iVwlqE>f?=GzSUnIEtXK3EyKe z|1AX_zfWdy8Bw3GgyHwdqr@$N1PEd+)U@yj(NPKXU}={l*9(t+C*q|=-hjh${}nW2 zvAyN(I0AI5<z??$OXp}8@zivMXu7Btz#10Ch_u)ZV4EQJ9B=!xFLXxRHVN>A6K*@W zTbZgZJh{8fI{L}wj&{tbN#X{nVXb4k^YM!MY2O~w!*{Z-YN$1T0-^7YlOFayI#XYb zPNQ`3yUjj0t708BJd|7FHXnF}vt&*IAvx@gcW*c2R`>FWfah>Cc)N)*O{v)1cd^Nq z9!LOpT6G+?ES12DqOq5k1>Z%Gp@q6R9}E--aB&D(Ev;iW+TC2_u&ZXrPMstp<MY>y z^@bD1Sl4tiRS~(^8H$inDdYrLS9fXieKmr^NDN8W6vyzk*^cBYN0lX;3j~N5KH!$V zkc1+t7aVq#TP{aK?CYe>9T?=SoOgJy0=gMcI3;~NMD$X5yE(1OZ~UN%<Q2vKQ<OtQ zvm}0yf%QlKG^<?LW^S#b>qCw79yd^v**5}IsIw>s%*#fVexEyjD!X;u7Xlj&?Pnlo zPUvX=)D%~;BP>PT3#nGqQl}U!=WIMF)-*woq&Q4qj|{<u*H~Bsk?RSbU6)rkjg7cH zA0Fo@@$gJwpr=*P$%;LC*;stu>8NI;m~pEa`dFiw9^4>poBvpy))cp%qksqPi+oSg zj*8H1m*fu?qzlRAH^7P(M{G!T?()R`6Z8LgdhcjBzwdh-k?6g5MkjjjF$_cW5+q8r zAbKy+jWT+#gJ_Wuy+s$jixRy=?*!4?@A3M4-@iXBmNkp}oaf$i_ugmUb2-SXX(@C? z-DW<dGtld<vrx7_NH5Qlw6=S5*pLqare8CYbAy&1FhLSmH(}(keqJMu2Kl_es3c>F z#zqiJD2OsiqhC-$C5s5NQ9&%=;$TPS>;Jp}bB-q0pB^^#OmGgFi*b^>`q_z9$puK$ zOuR#hg`o$|VP*xVh`d9#st3-B*6Csg;x8klk#-3id1!Rlr6vY8>;Te#WV(a1aJE<k z3xq9+J)M{M&kc7iq<SmeXsHVxAR0gc&R(t{w^W#cC))*+*#EHx5|XS&)1o~FSsK`U zDttRx3qrcpwAMf>MkcTD`28+bH^;&N?U`sUtv=GL%?l)J4fQWewgzvEWJ<-fxkUb* z-6hKr!FXuzKShu5V5^eyV++*EXI82+ADtd93Nj(&3BRoU?jy|}Fwo)ufY}stB&|j# zib{=Xsd(-8mHJ(T3vls8iYy2_ThR=sF;OA9AB%|B0==co-g>!KpeT^*X!i9xHV&Rc zcZxZNU8Xm@Iy@5F_>Ex)!ikj@X%KGaW}{jua%}ovhkf%+U%uv!Zk2IST-)dS3*84v zJ7`(8agaumvrrR80`G3a*tD7!Xsn~XUUWZYaaTzr^6g}Q9f><yz@w;5R3pX+&GK%L zshiyW7uBMX$`_(B&3_80rp$!N`#Zw|W08A%3~3rhav^TSjjsE%)By)oUN_&0EgfhH z^-+HQ#h(S7Gc@xt^riz8B{;Z2TZz|cutC>$)}WokhUL@+_KkWY)&(55<%78&dwZpF zGkKQ-9i6W|Ot%yBKdldPRzzgT!A;YRtHpO@dXlFF4^@!xCfl|5`u@r8ZH8UceWjb{ zoX}-eoh&bw^kV1Or$Wl{EIP?k6zeO2m8Mx|dQ@2&C`nm<v6<IH_Lakd<|spqw0o{P z6EbvY!Unu2q)d;wbLj~p5Re2I`>ofz4d->@>~AF=vGnf>tDcj-Wo0F33`K|qx=E>r zxz;e4h8fD4d_VAWQB7Sv`E0rrR$1xovBbt2PvwF!H_F&VYLsROX_}!*)$7N#RNS0M z@*e%`yJ1{Sqt8S>$FO5(MGCk5$GXH7DK-GBboHRJ|Jr2#ra0Qx0n6M$#DF8)?n#x~ ziZ5|a`eI|8qPLT;LMOrnsMxAc<v)*Lb3N?ds}!a5m_6jF;ep;UUd;#=V&*-T>c)$C zTSiPsva9ua*g3h-M;&V_)!yc+P>>6YShh^<(*8-9m@6W030*v=b51PI6;n_RdBETC zxcxMebK`VMTOErtDYmH6jW#Y^u6h$)P4BH|Lr|KDzt~JO%ycdBoFboV=mw~p2_gZO zWx5jCAgavkX0nd+R7*&}fw&O59{U2ddO!2)7)rKZe_;G;_i`!fN@|{ZC#A<Tf@PD{ z-&qOS0i=k+Tt0rVKnI+y6&$($$*Yo@bcFG#*_TipdPhIb^4@?il)borefXWcWi;V) zEw=n>fQiVdF}+J?s0uTbhY1wYVDKgjSpUw<KFUwrO#&oPbRtu`pZzp1;$m$akFiUO z1sZ_f2NDgxmX^3GY_W7~KT>Ua5Ng`Z;Q#KS$iY*Vca<oC>bPL4-T$QVcl^8wG2csu zr}H{sPfrPjmR~yT-(FpZDLPLy89BM{hO)h6gL)gke5yN{EB*cf2M3Sn?o&uP0Nq9q zzkxSG<#?d{3ojDwg$=MkdSz1dYpE{Dl44r^-C<$O%<mla8h<*XAl(}YgXNH!?7T~r zNE@58$_@>u^MR^OH_LS=ApKi(9Sd7ddN0TQ8SSW@E+$5Gc6?GIta_}##ipGL<tH=B z?2LP}A83=z%u2&ym6*?V|HhX0L;50UzX$YB?bkTo4qyx~P(-;vtK<w7)opG-@fxZA z-c}Vl(IqVO>KX~@e!l_!z{32A8NdKKdE`4L12r#)e8#J8$$&;AlpVj7RhrZ%Yej$t z1c2`1vlr_ka)=T5LPCb7P#U0ba10DCHC9z!h~`um<EB_Jp;~{dTsaeum@YOWQ-A!G z8LM>N5~rJL0}_!FoC!E$oo=8>xTQkLXD0vEt{A|vt9Yn4Qw<JFFRuS(9)7I~Wo_cd zd2=8hFVXLTBX&kaa2`XYp=%sXqtHOyad6}5aY$ZSY3_FHrgbjf5NUZ-r~}A{*1LC^ zn#Qn0nr!Q%*|7O@)$}!rpmvY)Zb?@ONr~Fz?VcxZA%Cj9GQRhlm~7vH*sQ7a0n*57 zv&H0&*>fyR)jrd0{@7-=72-f`HwG5qI05s}-Wawyo8h8nA1zf~(13U(2m^BM&G@9( zDHY=zuC^X%I5};e=2fXN^${F;g8LHi<twaL51>$&NXU`PZtFWFW#M*wfjcM6Fp^Cr zNP}fM!V<8t3h$wvOY8~hxL?(swSKX=zqhT0a@iU_qrDZM0g8C-%09{`Nfpr~y|R-Q z(fPN?2;BEVJp=VGO9kdnfVKau2OD+u%o?Lnei2239zQu)oe2TP#NgVe%qsFCBGePa zQ<+?S*xki3Q2gx_iJt&IxNcdl)Uc^7{N=**`Cs}Ml|6^%)J2BL9jR<ObXa&u6zPL% z*pErSYFvqE+9|Cg2CQl+r^dvuv>t4d;&IgC@9OJdp>F$llf|mNH#k`v8PY~+hlY*f z?&^l)R<FPY9mk6HT`$-d%gSxLc^*D-K6!tLusme}KL{(yQ832MPVL73g+GZnCW};T zy5{3zGKRSxi?d3XmmHZH2B2Hg0>0T1!D!qgFbh!xGqK<H!iri`7|#B5=(J7kSr#M; zycVY_Xr(Uci6@q11{bca0Q56}QtM9{DkTiMV`==k14qB+Ekpn{i|%kM3x0gS>#|$j z`g_v3q3`Re<J9NytDG-3kG2q~e%|@$hvjE~41M}(I>u8iaoA)5(W)_uhMW5hF5@oo z+XeL8u`CUJK8~T?Q#cE;X5$7eh#^!yX;+)oO!crygPU$1a5=4>ontB<wa6be$zxXO zy^&NE_l8C|=jImg^FPKnt0l_~TrXq%9w>!zE)d8s05<cXf}O=W_ZSz6Ly<MfYsJI) zN@wj^;g2%RsoCP*k{|bP6-uir_RD8}@D)@#PrkXfpohN&<}=?JE%UP!ledD9rewR- zScJy@d}fh`d~Cj-LfTrdUqDzjhW7gsNnPsTSktx1>E#qBo`n8Gc>H>dX?6A!mdvLV zAUGU|&dP^FBpuAmOeuTS-5KU}$$tXh9JDkclqy|2tE1-paEm2*wPFoZe`KHehM_|N z4h}#`go}Q{?^y!&yTxB^%&${F7uFK%8Tq+eAA8qW^>L+{f|k@@lJl#$RO%;ZAWA;g z0Y3b%>YSSSfH$T8LG2lH<XmkW=IWm<H6$`5Yn^8~?iq7-z&fPy{PDvYj1N}=x?oKn zD6xG{U)Yob4A68Z9lNhU<K64$FnJb2kKj~hH1X7#5DF6D3QPeW&6XxRTYJUHn-2zW z3^oNDN7y}P_la+~l3n`~LRblb(~9wV>xjI+-``izn_m{G283otPVC|{o?7@9$!BN^ z8#NV5W}?ZWTFAsv8jx%1S2J7^nEfcSv*U{%^o$Ig!eci7^5-g;gPq*Z(u{<I_57kn zgs1vdKd*|(Qy&4?C(HlYD?tL(8JpIVLqJ#^0O!pvP(ZGc?#u(?3(Ch@jTTaoN$$sJ z=wAMe<%wA?t^dXJ?;TcBm1s7&`-f(MB`h#b=9<YYg~<8hJyOznnu$k7i@zXW1Oy3S zF#kGa-tZ@_>y*7=(P$>qb<z2H1~wZ%^j!8k07!u`+8^6wYImRwnPUsE!`O>WgacJF z<bYp^VnJ+ER9w5QM~9rG3G@P%6JEP7l?5N8CpT+sUUO!OIEEaZnJQTFxoryO-$N#g z0Rc+{=y%(HnY<FwIjy;s^V`;E+pV8OXQmQaH-#A}j7g#dAz_|E9F6l|X+%P0w<ih) zoLuW?!E1QTn)cRqM<nV9?;t2t^RU>}Cm$Bfs0oiPv(?8l8tY0QXS8H%jveJ@x1P%< zN`Z_rx@e#OgKgtQveL#-ixFO5qqy%258iy-acBLhYxVj?JUY+*kPwa*H74p^i2>=G z@^8oPqTZ6#h|ip8ll`42we<?PXapbe0t00N11)7Qy}-F~holQd)u?f4_oOsS61?^A zEru`nu!(TRsM;S=t{Q(2e7o!!l=oNQS9zno`_&hev5>vaA}+#2dh!FV6bL0%t+(fw z3zkqEKXz;)kZJa{iYOB?{=~KVaa?~ZT41ar%dw539=HMkw-b<YseE#wvH3ckX83@U z`d5dU=7;L$lHXrYKVD{-FG<I}kgVA<5xmqrzmP(jeEMk%sEWDgKAH?wm(%$h0TW1^ ze*D85U8O}{x9$zN`K{42gL0B&v!pQ+X`8!Q&C^X73?1`B<^HgiprgajEv|(>Cm*j| zbRBc(2>HLL=HR=W&US`r|JiwmMvssEkHBuHRsAxrx&^%sXCEkLf^v>urcu9nSMLzj zvVy71$Be(Y`~BNX9)+bQoJy30q56fX@o|Q(BLf|@p+pz_O~ccy2Mrl51HqpyP37z_ z@d$CQ=I86X*7I_(20iB7PkmZXmD+M%AsOeYZ&By(Lx>{#oj2U5G*={KL_GCn2M@c! z1YJycV(99U7ZE?U>*_qK^}9Dvw5jdyB!e!*`&9E>fdk!NaWA6T;<D1MzwexF;B;XV z96eb|nW;QR!(jP(porHF#Txlykx#7sAgm{UxI0JoHPca*fOV_uh2Tn+f4mRGOiW6O zY##-vW%bTV37s`30R*3reN4Ti@{GZLZk|IfLpL=vyfG@7XJGk5xK|dx4FbXDj>*Ur z{M~VxlAE}ZMvi-D;LiG1i5&33aa&&d=`hQc0(j!~hYvyp!D}3;K1J$@-U46m3w5E? zyzkewd?9IizuL{^q1m2HqK>l}49bf@WplBedo6NQ>E@;aT15kN%k=N&A8V_E&L0n2 zG194ZTOS^Ca*mWnR6Yz?WV}q0Vz46sEC~469NaRp&s(`?_T3v<SU$6H2gs`in;E`3 zK`|wetsq-`)yiS5@k)dExrI=?U#<mz#=wELz|!RQqwg5v<45r&sU-p6OX_&r`{r9o zxpwiW*zbX<Zw<@Gdi%YSo?jLlmXj2`A6o_j>{=cDRL)qmnqWqk)W*hIk&-8~e^p-a z7r$-yzvolSb8{so0Hd=zq|<-qJ%QzHsAHORKmOxk!8dC0+0=e(o6;LD(h7@jVFZP3 zFr7wm8A~$_@DWo`3$BGl$iOeC!s8_Zt^f5L3p*}ZrgD|hZ0Qrd7!BW!go{N^;QO>t zOTqg~G>H2?SFFH!!3iYIOzm2{qEl)HX@7nFFX-&xn@~y&j7z7xiRW^`pVzU8hPH%9 zJ6puyD|q;(>eNu$#N7TNDF`|PYy<s~F4N7p`fM!AEZ|Sww9KCtIKGyO?;pQoy6O3= zL$`PhkL_$v+9sc{S`Pv^>1b9Im575ND1I30&iBYQw<oe@the*}Y(%Rbg8`OI>zk;Z z4y|_`kT*<K*uPVMeyf#CCG>5Xu-1`ulzlmm1-3z@{*NFnE&?-(47)MB8@}fG(2a%r za9_RH=2}6(E@|3N6!i9OT;}P3p=^!S$Sb1}3u>GFj@4A)j`Ee}<M)HSp9*@2KCdl_ z*0~Gq92}_adYrDqbv4VX+?*LZS7k+$!uBpC0$a|!%u}#;_p5u(R2~>9R^rD<nA{H+ z0)9;qn8d*vC1w{twk4TwiH!0e_V>&J?~1|`Hzp*6jp9Lsb8wRFI9G&OO%#gG0O_!A z@LTci?G$Oh=92vTORkD?)X4d$k{WV?@ZQRpt+gQvpoQUUt^G34Nq1X#QzWqa?O&Ov zYBDkiM$F?7;FZ2J>3Fu^zhDQFkI<jsHGiujA55aqO~Z(i$oi%K1f=2B*WEc7^FCk9 zcZ1F2P%2%E?X*Ai6SO<aD-U{;2-nz9?0w}zt1G%GXa1RB$N-g-5bh=5s3tcdF8@lx zc@89>KR#PW5Y&H68Z0%lI47WzU5T52s<hb^tBDNBi@*m%rT;d=OD05f1D2CxiQxEP z%wVZcm!J*Ns<AHV1XgXITf^aWX~tB~enx3UP3{Dz1w9j2oKcxalo}Nh|14sbmM~Z{ zw;L%5%ZTvqM|aAyvu2;nvvI1TDQu+4!w(v?T7+Pzc*K><pZ8JhyP+CHm+`*suIk#u zRUoqv6Sh+XRLg%L-+Ok&ZFXZX;jkANV#d-fZsuS6x5W=K><Rh;%Y}@Da7HB;4Db7Y zHMV22FW>Rc_`22>*rxXjHJg4^K4Br|Q1n}h3UIJcv9xRTg~*{K#~P6-RR%2P_nI~q z$P1n#%&=t?(HWT3-EP$c-f1~TJH35u`6dAo<Nt{vHk#H-fZlwR5^?KL>*Y?6$lkEx ze_P2oDs?P*Efw>Tnrt{Lyuc{C>d-<g(q*8bq7~4woI}MzSl{wJYC4}ZDAH{TF%`<M z5@mN<2n41fr6(%vlip5?Y=09eMgD#+43cX7_L>MBLE_i+=_V{RGizb?efNt26Q-3< zKklFH>>WXViN9+xU;Lq@84%Epp}5VuWGElXLS6)(|FoFjh>l7O{`p?zB}dKv>fb<T zJ2?I}o#HG40^&ck6-WHVcHJK4?Hp^nANk<RoV++3W+OV~%jA(QX<^44m#j_8Plx9m zblt-UhOYh^Pq~vWYbu$zYX?IUCe~~()&!gW@JuG=Q#085G5*1j+z0x9`N^}9CO8)_ zu@YmfLYa>7u7PUAs(C%TATimeOWfR$GfF}&@nnR4VRELG5f9;q_rSftuaE^fwR2GZ z(t3xb^*UQ!P3I13-wLB#H5#?c=<8-k))O#TfEhvY+kz*HvTzr|fr(tK;?~wK-#?+6 zH4bEA3Y`e=(X?@xJrSjqYTxp+5r}CT*$D*3g^@iYYSmlWHkROjAYnZS0VSBjK>Dn| zV~uVTr+H$zuNL(QmDOM%CMQXFd~&~-1+}8|Nd&%@=-oznb5gzKX1H|V{GMCBCxKQx z^{LR_Z=`aXyo3ku$vooCQw8|2(Q5*ANE}&sZ+^LzOg$fi4L>h_uf*~-E|9U;(Nmuj z(E9Qz%Nn_>Ds-`(u{ytii_+)qcP9|Dy=Gmyi0XHK;Ptx34pOY{YVkgcZTtd@pZLtw z4O|@Jf&?;cf8L?9Qa%>h^;_?Vl4{<*boyrR#K!*Z-HVPH<d>Stx;AB>2x$tF#V5&d z%P~6EudNZ&Z;jPu>=y9ZInDPt!7SoyqHxdDTHv_-EA1KruMcAgVHLKwypF;wdb-_% zgD$(B3U&*1E9eUT4AA;kjEI(NQkrO7qEv;hqgGXjYmbGUrLV<ZON**8RN9%soBP|d z@V8;1(XSs-$7@3yu48I;s6jw>VzWE1TW?X>QYEV}7IP3m*&Q{~G(4NpT6f2|N!pPB zpLT{z|6?$$GnG5gxpbUQ9=Cz8H66zVMB9fC21j5kL~GPaj56>O&Y?4GhqjzysTKYZ zUDvJX3@a^P16BqqyH6Ex)$ns$44$Y@ldR*D{N98Yn%);*lbeierCdDDoL||t8nB-; z1x_M;NB%p)RQ6-B!M}JE!r}pjDkVUtC^#PwV9;8`4x?#|&uy4I-Ssk7(AFmVDHa4Q zSTa7j5YCLXMK38Dk;-_;XGL&8W%swy;;t{Y$5iKKKY3JXu_ST#=fhIbXvx0#=y1_s zg;31y@}c)`f75;L)Of83m*il?&j^jx4CUbQm2Te_6=1|zKq%&11~PS*5#LynyeGZf zPi|sFa+$}xClSs0`dbx63bXEXk;hv3$LIrOXWJuG?y(?QYKZ?w7WLk|t#OK%H3VQa zW7K4G^7`*yt3VXo*gw9GAc<`I2;pf=NS&c<OIeFQo-2|(6qivSq2@BF?JEOrXJc=} zEt(R)70#rWwQ5hO2xBk$z*eM|7#Ds2=e><gA#<V5U-@kNh0AnH@tf-81PzyOgOOJo zp)y1baX&%|eM1Fo(j}nsXg`OvHy9qn?Ut)2fB5CBG-2gc^Xt43Wvu6{Hx34mFZLQJ zc!iJzzwhd@UuxvZD;RX8vy4R77)l-Pn_xbxvRI{Fr#@xGtt5(jXMOS77}OMr&W<Zz znfBKOE|by{S(tp4U%~TS#4&O^QK)qK1Ft6}VZ;Q3;rZZ@TEKN>SdXI>*!Krt7#$<9 zAo8uVA<Ey@eU(@mo_RG--*`74*T7@P-#Y3l+auHW<zW4}pss!0Nwv6hJ1E1LTb|s+ zDcj7g{C5esCzN&LSQN=1ZJ>Jvxt~ZU12ub%<oRE|vhxJHOXlaL_ewI1QUgS+L|{xb z^{JCZ>1rvh9EveMrt(A!Gg;p@1_R|KcOhMC@vD4+9@k<hn~?fqd=WZ*&K2X3ee;Fs z+?w~-@98k9TfEqLK1N3g5;?VeFN>CsEP9z}O-oXKUEnQv4F|#Gm*4CC3H7ymm%RXS zGJi*^!Nx;%L!-ih*HfPMvXp~!Sk9`kcg~{_zzG?%7Us(q+bRwHzWt*~nD)!WU85#r zFDkjR8#zw}1DIjNv@*AIV}BnWuj2HZbA0bG5Wc5M1rFOh0VhNHqacDvi%+$@FlqoS z3HMNkImFnvONxEUT7(vRFUlajeD*hyy6$x~s!6(qiDjf8T;J-9j9p?J9-yse=3<gx z_h568nM+EAe78v20wmtK`0X<yutJdJ&gJP+zgE3ALu{_anwGDqL_ixug~Ro7u1T@; z1@?iXc=VyfWp6j@H%4P50_1|RLy=J?=O$~Ko>3`PB^vpG&R--28mRlplo8l5b+G-j zUi@jx4Gde*uaPW)e=8NR@crH0sFc@0SJj$vw;kw#=bteN)@>nh0-~>8uG~^QpMe2} zpU5zmDKZdccdGcf{#?}Yw5GS*ir*7LyHx>;N9p1r#_(M7n@R7^KRv}ix;}KQnNa$_ z3G^ksC*SpO!SwQjS50dlH<jyD`S-lKhcZC?B5=M$N#`0nMS{NQ{DicaU$-oTdziSv z$bt;l;#dp#1x05!+(2$;{Z+V*pAfJB?`95&1*uEoUk*4&QK~L&0{g0dqMt(mImhSd z0_f?%RS#=>;HKhUnv!aMylu{V(9nA}(Hldl=iruEW>CDy^n>m6icDbZEpG4NSgwR? zx`5qki-G9;xP5s~(3dS(_8E9#Bu5M<sJeqMIL}a`y#`u7XH9Jb18`Q`ueVVewQt$o z74t^2*5a@C>#?`X*}hzJ0-<>#1Ca(VGab|7;xxE(B9^$vAO*G4&FhINv2|^VNRo+V zH`PDSsT|8sL*eNCUGiY4GyR&}U5LLkJ~N?Tfu{ZGZ1-`TybvfsR#R+Pt6t7>aLVY- zo3Jv83kGWV`<p3omF&0SQn$DnhZ?*QVHA_R__3cm*%d#1N;9Y^ar-61%R7uw_?ZY3 z(pmdWTf@i*uE7f{Tk!1bE>KEh$y=dK8nzdtymQDI=e6C!rj~TON@uhhP7l+l#BTMI z<1YF6Q<m|cN?8TXg`)f@k2iuvwOnNnd;ie2%Jnh`c9`7oxN$R3m&mtNWt)2~O^$6k zu-3RW?>*zCVT(ExjK0qhp75ii5aGGRBuF0$0-r|RmD2X-v*nC5p;KTHnJyFe`BKsH zXuF69FlP|CARtK6*nd>0K$U7LcZ@oPUFGkF$4mgeg3pi4ww0CghEw0-ChT|Vq01Qh zCX|rdpk}Y;0RefoBt^{uj*OSbWl$$iIEEPN*IOL%fwg!)N0&n842Au}wKBAT{fsG< z@@;HwUTHJg&-WCatH?EoHzu~=EI8HI-9J?*k&5o;7H%FM%!{n&gNlay{?3IftlXhs z2G??(Z73{4WrD8VDMgv>G)jx`qxvEc%cZVZB_?8}ISOstk;c9KlBDV5b_HYOukyIL z^%tw#*eT&E5#mKCN@vmo=kd04)613!=(6Lh^0Ekd+O=1i4hzcY12Wl0Qa`RQ=$tn& z*!?XY-U>t-J3YLmhfym!gb5>EMXT>@;1CXod)|#bVq-x($3y!H8(Dyf<pSpG!@DhR z<&)r9dX}tphV;FX$L2w(VT99$$!dJyVv_oM38F(z7J8D%)<W*P5=GU2J1V!R@Xqr{ z#H{n-Szjc56+$E^(3w_gRt&?t{{6BY5sRt|p8Y}_8X9gLwd=vtX0n0Lq^EAcdwq)y zGGub0_3rC$Qwasl`pWKZi6^=$c@y}ja%aT#U~Q3yYlw3fHpbxCz<C~QH_m5<*om=G zqsduk<f&yU*HN-AzwK(++AT4XW160HHtJVf=QzhGc{>Z^5PfC|jdnt%s#iPJ)MNu- z3%ECW*d)zD3uC+Dc^_bEnwC~f$YR7`|1l}7RX*N@ba7k18Iv#b%&Y&1k%?>h{>YQ@ zps7mz%XOrMwClOh%%8h6o(_|TQ!-p}23UM8`v<G>3ZxdJgFEGKLT~q}v`F44E15Vp z_@z=cG@s2(O$3WYp|j)MT?gNpj<g*27;NCVvw-@ivp<=y$>rY(b-Cbw3nb9OrMBbC zPgtQKI(AF&tNWeuwJgVK?_hVg>pfGV8={EI*pC(@oDv>f#cMl<4M{_{$&KKNsj*5o zlmWp)y9kEu(!=CN6l29YUG00q<6rkwQiI!^ysCXo7mo54RfCY!-q!zu)h@I)u)kS| z?=Li)=_2xHn#$G-m%vx3Jm{f@Z28)3)hDiJv`56>o#sSw3qI<7i2B&}R}LzjaJ~P0 zci8CXwe3#=7epM&k6FxDCe3T7Llq_s9`>&N&P+p(4TY_yGg8}6{xYenUvfj`^OdVH zNZcv!bmr(hmZ(^7$P@2Q243^@sIJ`Rh^^#pg<SQmJpLSK1@b#-&r4Dzlu4fXhWM9= zoBw$MYTC>lzf?@Vr8~0#4ugt})r!niREx~3TbBjMNRP0<;ydXx*#7wOG)CNkgOa1j zyw_Y)ulJK5?F+`ORayv46%le;;So@+X&y7LZNigPsBK@Rj}&q*ky`gR9bE%cR7&-O zk_<yQO*7urJn0DAipDx3L)7W7lLCr16E*GNJ`rYydpgFP6F`_*^Oocz2)1=W$O`kK z$+ztI3#oj`C+G7-D{<*g#4+=W>Lgt^oZBg`T$wV!EuVfL+5v{zxsZ~AQ`a{|L_rup zxLF@5)8KiBn8RV0+a&;3_r-rT?jc|<6a|9YpqSZgw&TAin9=L<@K(cj!Z=DM)adf{ z0Hw!;*!E7%nAmoxyX{OHz6&B3d6s2{e?!#Bbmo2qF6PFxGHg;w@6pTdt}Xfi%<YLU z);*xI^Uqp)QZ6+wJ`XN?1sJoR2Ug5drD(k_du9_>7YU%L6;a`AfUt*I<OllFaZqtv zNBpG+#r=T2KRbf<^Ivu2sG}!rrXJo#*Yu3t^%_(eDpsQCfKKE)OK7AbXTA6KKmJ;r zAa(7)#$fC~7)+X<D;XItNKTMM!XhJ;tkaEiXGsKuUk?yP60SDp%70Z7oIVlDM-9jU z$>hwktb}*1lF`U+GW^4X5uq!SvwZdT{&u%|m_PnAUGAGCWJgBkVVyaerUwKDn75F} zgAZ$<5aY0siG7z}$k|MA=TOR>zF~oxhzUa<J6`iqU;~ZEk{m<dbqu-Op-`c|{Ap(~ zPwNz7Yc-s<cU$_>;QwEz35!mT+U(~nNHX;o4$k<kGoD=+FHD>**U{RwZCm{inJR!X z6BU7-xZQh**M~|uHn0Y#%Aq$kgc2&KDTX(~<qc1<<OaHvGWV2qxHB9PLN3GcLoAd; z_VVNje?1;tl|M1XX_WkRANULIf^c%ivL`^<GT)knPuE}6?p;tz5B!CZC9My{mdU6m zi1bz?M2eAD`{`Nq-jIuozY?|UgtAj*EyhuE#^ztO=<shnI0db}jNIGdwHk+B#a*5< z13(do$jp+{WW&?m6fC%1{^zdl^IyAcd*_(Fld>6<2=(E{Ic|a1;&T1u=*cOo0%=Ac zq=9(>Wg+&frYNgpy79#bbVtISrP{wzrwc4aLgd%^w;*L2O|kty#(*9h64E$?0U(Q) z@|9nm2F>#Z@wfR;P%#LIz&{yeSARgxD%}Qr83mb#0@hbC)E7Ky$qAVdr|H^CdxWxb zss6G(62-~ycs)P#t~2*>Aw-70A1|%=+GTx*ZZd4=ikX)Xw41rl-V0EDF$eUUFWBET zHt?#_(8sEnJ2TPWZ~i2^<>>oVPA4GTd|`gv7UJc<&rS4Dz6q6RDY+EF2@q!Ji+naD z<B(&$8H$y>Kfzn@kbb`#o#E+QZwMLx+FPC~_aQ@Vu0H4JJ0cALNCRX5C2Qn~X)N`P z1$I6sx49QRte+(I-sR?g9?$6)G)IXh7>Eao1Q2SQsyMs27v44pd$#32ueVL!r=IX6 zJjHxhYibmP2Sl&ohnBQ5`+#Y!q48b)y>07JSQc%Y*ZH7%E>hxnHD$-!<5{RW4_ab8 zh(X%WQ21}Nisa9q5g1XF1lV5*&Q`8Yn(Zu%U_?ACu`=z1->uhWimyjAh+PL!QG(Kk zpfDom%>$`lcGM#NXo=B4*K1aU(x#jPTW%Iq9+4riSM|wJ`+G_a<(JHO7yq=Bw7C9# zt9(O^f%tn@DymBRKIuuiZ+%!5tmi(a8+Tr-TN}4WIntseYA+YF>BW-e3llw9Y@<Al zHneqh6HXjKN&A`D1ipJ5VL5reR}b!2-hGo^dWY;k4j0|4?vzg=G?*+KeyDnFlr=DM z0U{WT7{oYYglsqdR;DXT&*=d5ua=3ZcwE5s^cV_0&r$0zx0nq}pVJAe4Br9goN?o+ zIR)O-|5Pu7$0fh4;l%Q%HC>PgNF6fM`RZBz4s+;#wlA<R(Mma}l<Nv$$%OFEo+3uv zXeM57?xZXJyy}FJQn(9^(gIU}I&f|>tKle8?30?LgQ*H4eqHiscRTUP2W2Ci*xGv2 zU*fLvOsAbIG!0+JlL^NA>B>ikv@O7G1|kWtv3D)+W1Ww@^8UfHn=jY9Eu%Evkn)bQ z;<Y;^ev4ldt146@__ATREc8||K)C*BkxC*!Qp^A1I|bj#0Yrr84=yYm@tU#L@_W8I zOT=tVaUF$gu}arFx+~&Tv6_=2?KhNp)(({uFK6n7%~$_*bMuM48Jv0n{vc%_20U=# zuhqr6uU?&)GQ~YYH{OjYsPwLDLi^Jd?WRlfbu5mWzz%Bhuy6lW7Bi5^3hDrosaCB5 zB-VawHnFOR4cfAEQ>4=bwETo>L0WVoaBr^s>Y4%}#so>a!aBc_j)*T<!!eg?h=l32 zGr6uhZR8z;y{FO4KS(MF>CjQ!Zu&kQAv3+SQKwyh-x#>Iu)(kvy-k`a?T(p=OB;J= zdwkG4#V%yf{3VCTwy)fePZQb;xgmkehhad@wnjTwQwyrvGWU0Jsn=U5V|deTCH3MX zq#VB)gh{P>NKUQ<^VnEYLvm`YAEq{r>HDSG8AtPVHqj}#P9+XG=x5v%$xIYj0jBl` z52^dq`D4E`WoNl9C=F&LLg|7yeun?9ud`Ix?#Frw4i#-BcOl+Q=Dkcy1e0FN#lcK3 zHKcL@NMHTd>G);|T6=C(oLA0eLP^y4U>2qaCuid}nj}2d&<I}2AR8u0k%ZVi^F7jN z^n4Wb7a>(nPSwd8ZnO_=5lJi_hSb&S;6`|t!YC^)<71WaJuN@Cu~hXD29LW?QaBt^ zoo$cu=JP4ONYVyxB%Z7uEoKk+k2gvNY~>8gV`9b5q`~e_V{o^uo8va=OU~S2kvGEv zNAws{tg#@1K&{Z!BtNbC){1b39jF?9-p<xSK=)5(STvUMHwaSdTuU>eofP+SUc=>d zYa#&os-(iw<e3w4U=ni6r2qRfb&ShrS3l)xL=zGF?YApkU;tlRU;Qge%Pi>DWCABN zr~<3cLU}wAqRj3+aV_0^%~N*1LX@0=`v(_kd%nW3XiB7ZT5qeN4j?iQUaM>J7Wf2a z3l~z1O=^UjjFecXy$|(9w=p$}duQDlrrzOp<V{K}*oFnp(-9gQWG@O^33EnDU*9lx z#>+UyMR2)VsrSV$p@m_*0@ZqPBX-^kZt-F!KUblWWEjFSVvPvV0*}E9ps;*HQ4Upo ziCiR>)wBBJMG2K(i5H&^PaAk1PAzYnEV0H&HpC*z#nuJVwZz0c>?d*9SvU7ft9hOZ zBMgn5A_1zNN0_4~SmBlX7opU^9fG>gf2}*FFExO3&YyXusWT-u1Ufu-GMIIDNA`@1 zCQ8h;78HwI!$?lasC31a0&<eYcjB6w9rugg*A7j~#O>NRQnI%=fs=kBwl3xkZycuT zrcL?-k}w!7d`~(ni}uBpQsb-zBk0%R5|yUY0JU(OzIPwGW?K0*D)qqok)#iy3GT)T z&7j)r3-+#2eW3kj^{{9l>h=Ri!sC$6BbuyQ4VHS3hRcdGxkY9sDL;Gy9*artW2a!G zA)`|s<+&Qp5c1P+zALX-Zu6g-(cRu?vLqTKNsbMPhzI|XA~TAZ-x~~WB>k-$I!OwK z_V(YMf1>ygSep`fEVT|$5_=da1zzXGuiGIx5e5n)#f2F)_yyyVJyHG0cr((d(VC$* zNC7I9k5Wj+ragsZNCzl?Uo32ou@(7$ty@mq7EVJ|{zifHWuXlf4XuEA*&M7KrDDWd z0Nf6VPQZOPO6NSrM93fgIW*yU*_A&a?R`;mey)Tr!Bd<dGmN0;W+E^q{Jk>09QsUk zgq=ojcgs0aMq#wdF~D_LDP`x!Rh1gc71U3Q%uc#^FjA=xA@FX7Ya!xQayjsXCkn9q z`8^I}G%!?HbSx~D%I1he<Tc*xu~+~Xe`oovU|=!pjVQ1sGZcyr_)}-!ImfnUJfy@9 zY53pwW^L}yrg%KI)85~jS4_NZKX0OPc#Heza|=E0d#Qk$0)=I-clI*6;)LuI4*2|h z1O&3+DkXg(0~R82Tsj+(HKls|RkP897b+QA;RXW5>pyy2iE`edT05UW=bGjzYgCwg zu5PQ|FRR!sG}1kLW;*p-O~ElYs=AsUg(GmT=EI*K%x46cDOmv4TjM6joWCjMt1-<a zFfXhqv!|)zPq1FIW;ks<xEzFIaimz&(ngyNT>uVqbCZ{J+9fyZw`_iCMYWEPKN&wz zNEBnH`=4Lpbzc;9n)G?mOF0}LzF4mW9y}uuc;nXzTjfs>PAj9?<v|%;Nx{tt|Nk$I zCEEkxVWI+NwRM7#L)?lpASGK3Va;8H-R@WT_6$jE-bU$FEIujBGH8F{KlFbwJ*%C* zM2e4->}a7E{f2-uqO*gwHkX{yI;|aSh!!w8IJ3Wt=`iVJ${1$SwVNxV=9H9Rs(j0q z%(qp%Vd#4iVu>D(hL4W=%k8hzurAX%^r67=^%kz{E_BIWQNsD3bvS`~^uE&b%J)Yq zD&-|mpJfdL`Zs#syyRGEtk*Eo;avNRTZ|Vv-|gX@14SW*c+Qeaxv{h{`7Q%@`c&OY z%#AUy0>y-XJ~Y~jq!qT}(6$o1m3Hpb3TWpzA2tm@p)p{?CXb{mOIMBiJ*9fRW;_3d zrTc%-VeYK?Ryc$Cj0DIU11|uon9|2}k63*d!0TXAV>G?d6a<tazDIl}#C#Fc&!?5% zWVbr@({;zG)LTvsHC^Y3HSUU93Q$4%U~^G;Lt8Sr=n!M{W*u<CqpwyPI<GO!8s&VI zYdeASU7r<WfJXkWAY-a9ST#N<!D+BE7-Z*-lKIk7BKN??UKmio-xnDuFN4Ag7=ct9 z#MXeD=cP6B#Ee%7U8ozsl_ptJ?aJFLrJO~?t9V`Ig@>o4+DAfw)mtsg7X?Y=tw!$X zM7=e3Op~aaMq9t|UL!OwCICYTqdTg;j{h)IV04In(N3Q~7?x8MfwX=RuDQzO!}DI$ zpO1~knZ-EJ0Dvbi>PEk|KZwJem=by0C-l$IuAj5gkhQ5@a2ZWSKm{|a+n*&sRoD`X z?6xO?&wmVYCiWf$&9N}eL==>j7K;?rxVc%r$pN^c{8oiFA+f5E=kx7~(5|NQ{WRk` z)2{YsqC_41NCJuIf$(3Dhr3W>{M_3`tMQd%vzenM{U7gx=AHy1;DJ`Y-(dx|B;I`} z(rKLbL6XB8Aw}|vX{GqY_R~4WV=i%J3n<|_6VRz~&0IZCU@SXikwkn}ASihWJWIkl zYvAzc=5L1J>7WoU7BWo^*3=(?y=%Pl0e_rS78B2W+#{a7w9eIKl28PBYDp)=yAt}S zQA0q)e5f=7XdvPx-`hCRX;?h?)mBBtu+x7VNl5%U^x<pYp#X6sJOP%X9@UTbxzAV* zC`4sg<-k?5gq<q^JAp+ukVyT_*M)~l2V^vrm9&0gBF((T`my-^9`w_hr{*?xz+E2L zTYOLCa|SW{A|Q>VLcM!eCwutYNuo*JWl1Wir`r~hWS=H}(g~}l!l_lhjV8o6d6`2{ zL18&h6GIjt^^t%|3y`z-@u++ZD|I*Wv+h|eH=qB@ezj~Ls&;PI+Me@bbv(aVXAp53 z`&f2-PWL%E^VuKb=IgkYhID|ky#;oVg6avScT?o0=2qYPuRV`!_($`v5D?nkNU4FF zgjfOVLRSkpYQ{o+?=c8jeti>v!L**<e=k>y{%nSGGP^nWYzDk;_o+<ynV09RdjXN( zt0%cr%ZIp3zp(B|Q@ItV!?EoB#x_!5z-y=30R5pKiyKS1E2L?-%IxqF$t4dqQPKWe z3o!ITNpC8`bMmEuDC@Ca7m>|p6uzKdp1X7p1$V6~#X($!g4xzf4XtfW@zKvGxI&6h z21c-^y*o(-P{K8=JexU2ju->y+Wq&QBE=Wd9}6^qAj9IdioWK8Y|3(VlxcVzFOWok zzrD&ub}F83;{3@lWdCx<DKh<+g~gj^`ui!77U`my`21BAF<5NB`A!@t2`YzNk{xXd zeP0=mf&c+tG?sn8jK_#SVD`j#E+~li1sWrJwj!fg2qwc6P#VDp6S^+ph!{O3Rh~kz zr)mE@G{Of9+3EE4(@+wNc1*<TMW$EOYYuK*R`M}^Dj>-;(6l~PM0m&1U@C_BnlVx; zv$?_r0}BEZzz8x8F(Hhb&m!gP3_Q^~`H+X)m-6@@+)Zxp%L`AHl6Zfu$gt>XFob2U zw-W)09rXvm6@!2Tu44ON9Af&u>$`Qz)1fC);K}^Me{v4E4&P@9uhv=RW;@f2|CIH; zowq&tD~GpUXVp%c+xAZjb#Ty&`3Vlv^cFKv6x2y$zmh)H;7=??tAP;%m#f}&T~>6B zN#yi4e^mczzg@l_@|OV0>ZmTcyRk};2k07dn@)F=Hi}>EcJBO<UoXlBqeI~G^zEEB zKv5W5UU`T_N99pX3;ve4<tZc>BcAp@I<Ua8llUG>TX1Q5CMn50bPp*z6WSqIyVMOE zcl#QqYxnWdf<<a><4fs$W+2S`9#_e^_+SONq-ZMIAJ>qS59|v}LOHzo1>?0#0=u-X zf8Jx&+pmPwUsxm<_A0R0U!uOm5Nq)I86}q7ot^ysU=0$Z0K-QvN$%_;8EPj|pAx^$ z(*^#>zy-}G5?}@6YYhSpDNUpql=PS0QQ%mC7&630R4ZUJkVq1Zej2yoD=Pv9STvzC zd4zVSt4hDH(ulRoUZHFB%K7BNOx#V=-ggtY%ED1-NK(Ap8pmnpFXkc0Mq{FKjM=p( zA<xG$d;8wbT>+w_=K2OI_mrf*))8R(pbyXix|>_SvpAA3K?fE?Un2w*g*?m3a+*L% z2mm;5J8pJ{t&uE|?*fF8u}`0W4&fwaFQO$kCwXh@=a8By2Vj5*EP3$9GE3`{XmVAx z?1b2paKF;;>B)V|(JJ}CV0by0FEu#s9@VzgGEz0!8hpe2Uo(H~IW8^INOsR3XTz<f zp>VCk5pqX=LA0{$;f6D&WNf56@YsOC;0@?wiL2sBtjIsmJGKv5X#`ECv(uqDpn%c* zai`u=<4_zuBcYd1p}|kY(#ek(?FrQ4_~`gUA*5PlVHjOhAzABIUG#8DEbH;wLh~{N zU+b=arAEFyTLm@z?|b5(fy!(f(0d6F5sGoeZaQa*BF?M+szhxi@Mg@`l@|TvB4j;b z-&)d@H2Z2|^6y=eI?b=QA|F~$LGMpaUQ6Kmofl?S)w}ISzT+!?=;?n&^MADo=9kT< za&)ik-F4Y<7#YMY^B-k|-iQWp`GaE_&6bu<+ky^NSVU0851Ly1DF6}l9%u5)$Xt6s zz<6y25M*{iN-C;x-;MsD%Kb0ycqRvq^%icf!ja~{L?A}W!B6J6dk4DIWC;!-2=O>l z<ke5r=syW>O0oo*a*!nS&&Kk2XoY&emjAL@6Lcq>n9cZG`U!-o0wd4@$JStXIQ9rS ze4<}l(MIw>*`Wx*2Mk=m6y*Ich2j=!9|7w0YdSLH>JPsqkiI7_1|qcqWk#c;cS=tL zC1OEQ9^u3k43y7$03C?q^}agN{H;%Ak3HC)-XgWy$RtG+rq5JD@LN+JB)5Me29ux7 z5NQ6nA)lz>xr-_Fa3S|xLtBbMHwD+n=f<h9u4^hKiu!eEZ}6^wbKhy4`Or9xzOZH0 zoEqfIrjoO^wr*7M!%B9+o}6cU6m!6pQ>UNMZ{4enlDO`AiDn<CTN;_wictJS&xwro z`9@o=K<2dX2JXT@D(oS7!!|K(^lzYYpBAwb0>t2{3cq2#W!&OpiP}*Q<gL3eT6^Ku z+>WU1May67+S-vafmn1WvLz#6p+pVpqLS}Ze`13J;k^I)-#IFA`lh36ye1oaO&K;i zrKgvzF{?z1!qaw7=<jfJu>0kp{_s=u(9X^{8wV#%a!N{(q-PaltIuuq*~HO*&%)S# z`>~jR-!Fb;oN1+f=oDjPixEal=W#U8k^3|liKju^e%Gj_=x7f$N>h6hmte`%L>xc! zr<(v{2o=(Coukdkhfl<SxQUeR5QmM6s}NOk4~zfT*|bR&phoZf*DF7|R=u+`roJ@; zhDQXPE<(3*qYY@b8p{kSDTy@gWBu6v5+ZtfN|u5aGTQ_+aKiU0thC<WRWO3+j=Hh| zm^5P+kQFt&yw8vF|KE<r+$t(v)bn8>OYg6q)W<i^yhi;g0W%k59tX_AlJkRMl+<9* zgW=B@22<Yho!51Q1^Xe1EGyMvY(;5VD`$ao0s`t1J#)0xWsebe*+3_aY_pqq{Xq;L zIK1R;%v}Hvj{fzea#FhnO;MS&H-3;>Dv-{iew;>=wsbMwELj3FRRkWut3%N2I7!w2 z1<?b)fbQ}W^nk`xfAfwWvV9On5uNkT4AGs#qmn}(pz+uI65ow6W?xXCnbgNhFh|@( z_?sD|+q4b>|J*8T2B^Vb4Zm@QG|Q&G+viNX%^T*44?{QdtB>_|odbAfgYdtgbEVdY zo7Q9b1B%0Iroz=6Ckg-MlUf6yyaRT@2H@pSRpF-H=L~%reB)>#PbjEp0EQ`NCDzBi z(AUZgiJX3$6P;OHp!^MLkO|+yU<j4<MXxoCB+3YL%M!2^*LlS}d>_ID)~l{&O!&%8 z@Qn#52(C{|E|3vLpkm0fMtCLf{-7)#&+knfH6V_Q5PG!prUiB$1+VLggb?(v9TAO1 zlJa|VOD=3S-UKd%#uX2BWg`)LUkxg7V8ah?T|_qtXCrvOO)~@*z9)6&|2_ni2cH|l z=A2JPWUWBg)Nt{)<1|OFoA3WiysT?w0t^<2)w?<*zyTNn6dy<f$55`^`<<6bJ(g18 z(%etG1v?kZRJ0yDvvbZ^{a89JXCMmz^_MAZaX-5y{Ix^N%#3m3*P^8jSf*odw^&8M zHmlj)m`jGfl`2>kCAk=?>@+>_W@f%KUxEJ-EUKp*w<gxrJyR4a&%<D9`GlMMNjz7s zg0?$UXvld}TV$<#)as;sUfXG*abJNrx;y3HgO#JoTVojY9P3*A%WbucusF%e<%2AW zOuKr;5X5#4$%^S{KFVfvyRooK*9RP~w)34_{=M#Lk_I!i`yGD~U?Zmlav(LZzv6Y^ zAPpk<Qg)mHk4hUTgEGr{42_wZt=vD#ekG^ylqo=kK;@}u%65{AV=NlUm$<{$cV#8H z;0y4`Ki5NF4KbfEENNx)EN=>kl0!f<X2PN67VbqKi%q6Z_u`L9M{=Ku`QDa4Lw_-( z(#j;3v#&@kjfZ&9Rmsu`PrJKb?=pPF*yvwRy_5jB<;6gt0cnER4FpI*C{_3U>qkwX zwPHmfvodpj+eiKiZeTdkP}c{JfaHz1VP~XefS<`$Ekt@$4*4ME*5tbVA`+~|0&+Mw zGQzCQ;5zB}1D8<?D_8_T;S{+ah`{~b^hxm!C)~L@t6VkgZZSG(=(7HN13Vv<(8cF? z4$GVdN7{gt?&L*ZBuZ+sE#K{WZ|9ul<g<SA0rigivs-5~S5`Io?ZrwOFj(1~hz(Cl zICK-Pk`tfoa3!JTrIVsZJ`<<t>B!@MH)N7thP8Z0sw1w}DXgcfV^$atOgPQW)j$Z~ z7hvV|sNb33EdQTuQpk28@{Ye%YytTXN7*@^%M>lJkWz01!A;)X&AymHSHHX_q}#u4 zisEhow}#)a4r%aOBOn7e@n1*bY~<eMxfg9Y>95v3k&77T4J!{MCG`T7=Qmqjl^qH% zWo|5~P5Am?`AJS*IZ&au#RL>48=2Q#UG6X+jc?(o`4Ajejdw;uHy3p$YlPrxOkik3 zc&s-_Pm8(mA3M+<-7j-<<FM=lQk->J?vQg9Fe|S5yOERQetBi!(@~DOVliWdSfN%x zV$fgcXd$y1WD^m1cO2twZvg`eiFRVyG~d=lUi9A5<0X$ZQ(rJ;B(@}c;HDjDm$w3f z5iba}df;%Kp_K^mi#(g@WH@M|%iJ-4;xq9R#ZP5V_a?LdkPRQ;&w06scxg%XhL|vq zE#W<}GJ!N6M&}_(WK>D~-zc8S>zH1SZfJIMEOmE^`jYi2scs4XzdhNOni~s4{Tgad zPib2OWKD4Xw+q|hnNsUFgc5Ng@PE9V0Kw*I-eA&57d=@C2zl}0-7t{BU_HQH36;5} z7nkKn43e?iuUs@oT+V#zST~}D<q_>_d3kn(nP|5oH#|)_T>@515$DL3u>3gbtCVQ) z1ROtkI72Wo{)rDgMH2uQ&_e&`nZVB(uV82e3fRG8&jB5H<#{q&vLTDt>IEAyO_Yf* z0a`pdBnO}ImeABtjw>7=E)O_(?yvTV<=F_W66k}IBP34eJpc9cu5MS|^I(@wO2oDM zJ7dG~Yk4MYQ*)>=F<^xjhfgW`|Nb#Ms`7+EVRE9sY87AZLfv$R)W8#)UFD6<%f2PR zPVHF)!wp{zbWSEzt;2bME-(HJy<Nx4-|%3+NO9=a*G^{G8Mdc$swwMIba!?R`9PZa zE?P5@0fw}t+ObJmo^$n!4`JsY-o>W4mZ{=@95peizIdWVh-Ok&hCVU0j>l(zwU8!} z``@vfU^Qcbz`g(T0vuho;sOdWcGia~p@XJ(EH~*-5^~{R_8V5i8ON4J+75}Qf~Xx* zF;Y6#=V=oK_ByhTt|yhPi_m>*?Kfv!tVt9=95w*X!Ts;zyr9~Q5HQq)XKUv43eq`r zy%G&R)xgIQ*drjgi~!n?1R3C^d`rjbANxH0WagbFs7XFV+94c#0jiI{ceQsE`N+wd zMftc;&Pus@(MAg_ehnJ*&fl6f$@bT6Z69~8uEbk?zUa=R7u}IQI1aJci8VdrsmP5| zV(ZGLQO7NHE&cQ>xeN!Ua_``UM3Q%^e{Z}aCNnVl`gEu(?v5t!Pkhn=qGmKu;G6H% zcKczd#40M-CYf4_?$ba3IbRaKR_5J3U7Vie#TC&pmFdwu@_V|#Vjx#bf@58&1L=^x z8Y`R!m$jyPg}i72XP$|YyCA$xXJXVgs(=>?IJ&i`o~kLR-ndAgmzO_#*FF<9YtQ1~ zxk9<>V77hZhtv`FdiuLh+4N25iM<rCz6@7!Va}hw&4~s)DSOou6f8Gxo|pNX(06vt zB@?pe8_F+@B=G=xKmp>`A?>JUc8znUh6~t0EzDpuRrCc0R-vHovRj+~a1#lw_dXX( zch&}VqJ~ROm!hHKr|;{EqVtn6l*O1F+>XDFQsulJYedX^K2vjz2hCot$n5eXns+w6 zZvJ?**j;F$qF7elOpHhouaG4M04`M_k5K{R>r*~B#Kh5ue)}+B#rZg2Uml8aR-%{F zM%!TtxCizRti%8q0_k_|hWw)s9B8whHOq#;e~@-iAq}HAaR<t%{NrPK3XZ9Etyx0d z{^P{5239z-uQq7fy6mz$#g8a(fw`itMdf85dy(4oTfA8H{ivtY3M)9yPEPSWPy#R} z7SBrj2Jz`O)#=xg@8qP)YW1d}pWPxnsWb3BnzQiX*pv+L>j;-9bXiBgKic|R!@|IA z<5qDE|H6x-@EEr7G{b*5IiGSS%*qh@tHJVh18zRPj7B_47FK>MFX<k{^XsUsDkvqB zY1}{3Y-q^)g8Tnb_10lge&H4<2m*@Iozfv8-Q7roQUcQ5-AH$*lz^m!#Ly|-AThuI zLxT(rL&yF2opbJeE`P}LAk56S_kL@=>s?!4d-?m!V`D2h|7K0b_61pJ;_2Xok(ilG zxRxu}8@R!++Y$iZfe7wO9|YAa*yGdw5^&>=Kw$vzc2tL)aa1B}n(xn`MgZ)`MSYKW z{oy~-1pp-UAF$lM3)-w)xvN1~Ede>GYN^>i_`)P_d4jkOon7wjZyY@oegh5f8k(fM z)hJO4putC@+ew9qjSh5YseF9yV%2CN|M)|G#%h<YRgG$dGL;4CCSV%K)y44pU4}wV zl>%di3GvuBh61p?cTnCdPtZurZwoQ88?X1J(Si*`n>vp^>Ue*Bzd!Q6wrUe$wfP#K ze__>TWRlI*WKf-j8Ds1F{AbI-T--M(9Hjwz4tFc*vc!_|OeYeg*qce%JJmRn4-mz2 z2w)YA)yVHS?DAi=9YJQS7g|BK@K2<?%cyH~2orhyQqS{Bi6+GWS=4i(xX&#>t}fdi zbFn716|0+o^y9VUs$IhOID`NP%uWCY8m?RkO#~(+JE_FZ#C0Vnsgx}fwFg|^4>!VE zE&QkN7cH0u2ir2`FR}Ti?$vUg3A~MgTPIc|Pba8fX?xBei&D7Ky`uE~+Oc@-yuP~K zyzOqpi&0b}0cP3e2RxeDo1uG<7{K`jKDD$;1AE14hB2hwPg7GdF!H~+aDaD?Tcvq0 zzQhiim-{OqZo5*LdRq*7%1^$dPp8*|_42v}3#-MYa)_Z){TxylB;HC(`t4p)c~5Bt zMy1ByG{dpPk(x5c3|yrO+~e2nvh4R%(-nP{a2SYKI;LlmBcA6(I~b{NbvR8UyR|su zL1Z*bf`~kJTYWN}`CegSoiG~NnZ}^u;n*rBoTGlMr$7R{B~@7e+^i-_yxBbmMgV|h zt6)7!q>8w4w5@zh7p*4|=o<%Z^(Gh7eqFYe+VN*UXl<)^i(la-bQ5F&2t2Nf{Or$x z@9ZN0ksD6r91>GB^|F=5s{shg5OU9`bLt2&UOwvZG0U0cO4tY^o;iBpYJqf1IBo3m zy-^1QP0+BqAjT#=yGj12k&PNVR`hmFTZw!FBf0LlQj|DEFZ)o}UGuaSwMJ=S<LVJ+ zGy76fmNB^%M<DZg>)!yBTJ$2K56=aYN46NVX2g_9o02}QQbyutDk9(@NV3sCVnO_J z-}+wx)7W3gJXR<P2C<$4msvZI_LM<Z%jV3za<ucJJb>3DYA2H`&yhIwPFx$+mF82w zJl!Q%Oy$}W-^HeR?0zjXgS5>Nk?1)#nBCZahM~YO;QZ>L5GJ678oaYmis``jCpi^L z_^&^g!5`)L4m?-u+922KwT4gnoL%;YGC#j7-q8IValbRrQ$`W0TDz)n(+8-nE(ned z*y=9p4L~qtZewGgUbPN1btC|^b%zlgFa=ap7u=6W{tD1lu7YJ5T|a!>ea>Ix^Pcmz z1Z6B{KFR#awPwCW^Unthz<<2XFf$&*0T5<JQA~}B9C<UdC7;$fDaL8g^W$tCl%uI| zPUL&QSZty&-nbGdR2N24^a<IfZxZHCk}xDShyENRxOx{~lWF<~+)->nd~~>MlD^C8 zO~<y}v`mHx(<)R;rF7$tj<3$E%>PyNt2wU<@M7Zn0TXj-nh{?U1?JI)X*dH71fyr1 zAN7drUYsZ*Sca4Brv8SB=F0wJOL=mr(rIAI?m!cm$o7*|f5Oi&dQ1mMat`&7d`y9O zozgBda=9kpFM58%EJ!5Tv2%^V9fIe*|5?!+yz@8eI3M#+)@X}oOF{Ecihl@9sB2qa zmMek0f{8`;wW;g?VT<VhdTA9edo%q`qipem6jSKsn)wOmPDj<PS*4gg4}nUyd1Ke? z-%wYI7CcX}OBos*5%>AGI{cuXE%M}60O(QU8s?zdmu9T^BvJnbURtx!h;Lilc=+K* znltAqUkat3zP|JMq1bmc1La}jzz!D2-KExz&tv8J=}qU@l4JL9*Z;MtQxSxG&_r%N z@Jw)H@JfDV9M0q0?zGD#1++FwvlcP!n|bg}D7Dmrdl#8Yjy3{6rg+u;C8ytT`g4AV zn<$R$c_WKZZSa(?vEQaxek=X52I}P+c97w6`6~c{Z@Z@a*#?#Uh`1K%!$Q6!h^$|x zf@MR$O9#iLLItKQB!}n9u>uz1WEk*9V{lSI8H4>p?trt|e37x8Jv2uA$D3zPjOm@x z2Zs`oD%PE4obT0AazI9U?01Qo$z?7`z&A#s&WJN@qdiJh{~T&%*JMcrc(#}ErKr_K zo`ds(J7y%KX|CV~mM_~DKNM?v2t36Epsb8r{HlnFFl~#jC#41Vwz|23#7#2HwPKI@ z(eR>=p<-W_@1){;`My4HZgO&=JArl86?1Vlf>WHozTE1vZh7i07eb4`Im>)9+Jzs& z$Ah@s)Q&Ill)G%e(hO74gmKVp#(YV*DG=Ob8M#=B+`|RI4t?bDd^R_YxIexU^BjeB z+L6iF^GdI@<v*aXE!UG>d3Jr3{(0QcNgilTJVMA;@NeHPQgD4!$YFp^$U*k}rC0>6 zB85fb1n7X%eP65cehSsaCw{+T<ld9zEiGA2v)`G7<4?*`(e{#egWnQ0fUr&ZTfh!z zCaS)4O1F9e7&ifcHGc;3l>tAdAQJ3v2ZO%0Tj-rAzI-o%?D*(V_h{&*6RvCwK2*_S zJZQy?AlpSls7;zcJmEx0Aly5_0e1Z-0^`2;wjS)5v6$9+OWV%K%s=d*ujnBAi_u@b zKu<q?6#(c2|9n2~lr0ojmDehNb7aaBom@J6J{Z3m=4<Hez;By);@~~>8bg!WU^_p< zdd2R>oo#;;VDytP&}STUtv|yh%NX3D+Z?#N=>@CfN^YcHZK3bta+XM%E_i`B`&nCg zXgZ}`;^s9fc$-s9lxlO>op1SK4oENs`Nsc?bix2R;2%Kedhs>HpNfY#*>v9(FxK~| zx%}fzk6`SPM`h~E+j!DnI$D%2Ilfi(3d_zL&9~%1lmJQA(X=xA`Fw9GaYPhwSychr zsh<!6j2%lp1t$!9vc6)n_kKS8L4Z4xCwRg@B91UQ|I?&g{ypbxi5C5wexh)5w3JqO zhn$Cjsv^QqZg6hASKlU{D|m|3HlC{`DztcR<~04g`Ht@*`xm#3mRde5vzCTN4(t3a zeStw4o>67;Jl8nmf56fExd9X!lnSOt`yE?DH@4q!JPcZRM=L)nNp?I8MDspjP4`7} zeRQS8d&O`)-;|&>-}MxVxBa)6q&vHx$acjMy)TpX0aIY2Mk+pqyWOPx<W4!87Vql; z%`*c^zFh4;4kBD^TOdKhhBHWef#{FB2haq;w61E34g3gHH;I2Yo)Njb{0@#oHM_?X zdry`p{?*QdcI?p`So*Qpb6Ct`m~2&XcyaQ*%kOmukqgN~t1DN)&4~@J-o&Ur?J~G! z&W}NHGQ$&UnxjBXu>xtqzk2kJ!w$gcJhZ&ttR6h67wPJ?4s4;d&Tkj}IMil2(aN#I zXrdzstTIi~!15=GqbDib+z$;z#FUcpnx?9ibWdsv?%U&uVoR!>r}|mhviw(w&|4kW zslS#t526;6?;$nkEt}G`cltxlhWH*UMgO#ba^-=^gYc*Moju_fr!kKO_muSKGBr9X z87oHk;4K{Kl4~94T^ix&zR0u}n>om~q5P}&^tCVn6M!PDZI2}#jl`JW(-(AB3t9() z@DcRxmQL0+q3EI;s+7d_OX6ty%k&Lb@E@HvE+eMJv8idMTRM&hO=K(I%ryx%gUxrd zPOmcBO3wu<A7Gwp>b$QaZUtlCaVfk!>4F@|O35IhoEE0Y%`;GaP-2YEg#<82CWUYU z159?%4ukAd_#kf~z0Nly4-w0WJ4xubQ2!-J3*p?icL87!F|_um3?QfK_|A}{18Wx6 z<29De@5w5-bjZ3{gkZ=u5qAasdJ(HOPZ`L4Gk!Ak<?WibF_@hGs8YY{u>xSq>AYMM zLZFYTCGEC1xuocAd3Ji7DygYD((wf^x?K?-QM++3QI7pEaH-6w0p{X!-L@qu;KLm~ zqKK;E&1gL7*+j;vg6%!kWikQF^rc6V{*uD+k&itUjWMAePLOhL*>jOqTg!J7atV#t z-B;z<JWlhqdqUSaO&C2rl)}XPRca*XEH_%j&%L)Xks=y$^#I!^yrL2`5&F`edA>LJ zoVq-K=dPVci>yf8fHaW<zIs~m9{07Ve~7VG`8y051Gh`~*Zr-1;|G&?79ipZ@;g$~ zU^h;xQm_RjRh(2|#;P@n4LcJ9tSA_68Zc#0W!U6#7)Lc|jdX&02Zu<-pP&7P#b;77 z9kj*`U+RLVbEX@gdqGrLQnh8F(|XYT<6Mns1w6np#LtsFtfSF~1)n`>Onj$-Yinu! zsHvF*I32`iPDYXuQ8d!?3b#Y}V_IL%T@-qDD3k9ct~?w#M&;c;q@P=YlS0b!wM_qX ztgPG|{1%i{lbuR3jsIoKO|^ZmQUDC=A}7C=cP!J3<zw@vTLnGgZR#YexogziQvkU^ zm^^JT!}rE@^ZE>GBC^}JQAqn!k9Q_5(Kzs!M9I>*LxiP)(j)*<t_@TT#e0#%m&EOb z()|&Ai&zmAf!*754$b_*v7=$PLIQ{d)<ez{h`&by;0g$oLvuF+DZBZ1gpXJ8PjR3% zDD>&LctQEu)uk3@6*Cpr*-wJ?V6OFF7y!R8`*dnDcvO-ZRPWVukn>7bqh>Zg{sSH6 z4c%aDC`J(tZQxJ}|F9UX<h0u34_5lX#7L>SW5Unxd@SL^^kUPydADqjQy_B7&paEo ztMtg+;ql&Ee^c#Mwz+SmCNccBzPVpNM!WBMpTuxX@6Ut%Urq15BLLa~K#`zMiDnGG z5#z;drqjyf|FQRux_=BvbL^J&y4?G#GBw5Gx+pd3w!S|1!w1P<)ziQ3L6wSkE#6`! z8ALfekCH)05Y8?<2yWhV8FutHnf~bNSM6*%oZP=r#yofQ+<sZZn|beVX<5r=p0B=* zT%4*?tlCt7PJ3tEAu<V2XM>d{%2Rzn(l>}FdbT|T**Av1G?yY(@S`tqpbt?OhsH;Z zr(neobY$wLoEF8A3*BHD5szaWDMo@mZE@L_9$BV;x&U}JGGH1`#&&efE14Af>+Yj! z#h0P1^Iz40>$s>*qy_T(8QYyja!$?1W!TZky3xIRY3C|LY1z?02~!J9;x?Vr>2|h< z?kMk?d3R>b+`Lzap+vey3j!lvO90d0tOu=8tm7?~fDFJwJqyLU-Qz>H>oVt~?6X&= zE?w9V!@Gw8Nm~ulwO{(a&-)-~AG{4mJhwyOK2&4h1i*spoq?w1Fi%!!I8Cvt{k9qI z$T<4byhB))m*w<xlp^A<spO9ffIhSj>vLy@?czArh*|@%lUGa2wDo}cmO#wUH&p#f zpS;7I;jySVmkz=!N<UAA=GzsRKB27XA=tilT9v-Dj>7UVAa}`$schRjM99MsnBYUW z7d>c=IA0zuMQ9(a?pk_$OmUW7c5X3CsyXsYcy889)`{1O6sOqDV!lYsz9)SBLnO*+ zqto`hgDQgw=I5BSg1UCx_{fK(<FJVdtxnwste2;{0~qk(9-`$YV-leyoX(ry(YfYr zxy5-r{s;h_GI)A&(|@7gh$rw^a+ZSFn|Mh*Cu5_T(2z%zteT$$PhOzF->vdZ#T-3~ zx?#API;_|U`<lI1sWuAU)oU^~oMTbS6@F<ia!7ws;MCBC>z-nR#e!}kF|I^LzBj;C zrGGjgP$TWFE8qd*-9%@<Vf@@`!0$id%-jBj_$Y9^=~NOz(H=1UJ{A&Luq)3&)3xG^ z{=}<tlO!*ZQsq4Z@0`*O<8@>X2euiYBpoyqr#|Go>tcFy2y5^TO&;uc>9*i5=Ym)q z)2?>wu7BB{xTzIp(8Tb#khq!i>TBx?Q0{oe*T9ARVNXM+|2g<%q-X_}{U*Nq-K9y> z%bkN#Jy;H%4cSY3k6>y(lP61P*<zYCk77CBqS~9k$LOH>t7{Kn^2ePnh<%ZCPCrcp z)22#)uznNBk1_r`BOz!ql%0VFV=Xk)Ner!i+gaH-Z7~hJRC|ft_Nj^7G^aw0A+~u? zMD61a(nCREyC)g_^v%2X^BcXGl?h>ezkCDA?EhXupuh8KqJf6VLX!6k=0VOsXCc0E ztLH)HJT)!(b9!tHn{j>A-rbrE>nh6O(-s8>oi+6O9o7!WH@!OrnR&^EFau9ufGiK$ zi6n>wR&i$$T$ph;e~jm;RgJ>1#ZS0|<xkNyHupbkAoN0pyU`^7u>;8J7n|ov5y`X^ zAGDa@1jVz>S8}%g#q+nqRd9SgSZ%wqYnnlIO!kS_?hR*<vWKRFk{DmO>oaI9AOn!d z&=geO>5lOFK_^*UO(e1HR;g7PqwPy^qB*;9qeB6Sl;&UOx+(cX`9cay^et&WtCDR2 zg_EI$-{&Pjx)oRqqOj*|{pAM><91B$^Em$aA<+MK;!ZU!%_aTy!SGr=-)QfH4D|Na z9R_AUJ$@q)FU{l~vx2uf!<YOC&n2gbYB1@8?^Bl9(+bc}lOJ-f*u1LJ?=l1+?k+no z(F9*0A>P|-{STQs{Ry;i^kAji7II8H=-sFY_ozX*bT7l(k?q7H(llIB&ZMf~uGU)m ziHybZs3#hC9?Nj1rE8wrTnPN?eet8%VL#;A2w$VUg6?c1`+OYd9Lwdzd;PJK5S)m{ z1!9iG5J`Q1Te*MZR48#@U@2$UhJxQ*YI~sWM}{BtD}uUzwtT8~f;yXK*fvAE+Iory zs!&Y_Eac`WFjt&sv8yDhO@Cfux1FgRKCidqES97id}FIHZou%`7;K;>Z}7J5r~|0s zUUm;|&F=st|Dz6@-f$s%ZUX1!T$7lQ^KS`28b3s&!mxf$yT0O1HHeM9N30-Y88!vh z-OY(uZl=S_{jX}j##@0X>A^zuV2(CbswgL~5%?6DU)(i*Mha5>Sf@}ti>p}vF;!y| zFVkNs#}RY20HktzTQ`4ejIgQ<B|~6;f8g*OFUsVH1cn8GSl5xOe=?2Q<)ZW^!{MQD zb9d6f*90Kj=e{kFCz@Jn*c|4n>5bms9QWM)#NMA`X%GSAy4X!!kBZ1468CFx?Tsw3 zL!YMQ3fB9<6W3=#2+KK-nI^CnFuqk`A*0;L?5==H<lSnsdma1y2(*ugl_1G720R6d zq6C1wRH|!Z9EKku`bzwdPymk#V{&404N1|5|MuMZXQm4QdC0t;iM|-1YcTto<;faK zguZm$QK~5TqByl(!6R+{(tZ2SE;r<lTOIrT+iu9gt+ltj9zZz>jg9t~OCTy30>*iP zPDT8sTlQ~90Clp8!q_tZ`u<aQ!zLHf3VlOvgQX^z_X{qX@j8(1xllW?=5dg=>0$Jb zDCl=VAaR1NF=)g*RStt{jo-<p)if=UjWo{2F5FLQtlj3t9KT!RKJMaIfwq)x*U?<T zzWw&dYfUnMRKcb=knXc)&jEYh8_kE)8rU7)o{|{b1Ppv^-VeV@^pmz+yp@Ukj`;Pv zJBPwUSK0?RW3Yd67ZPx$el{~j>88%p2aK(psVk13EZ%2)j5I*NDQ(5*E`9x@<)2e9 zYsv(-Pn+WdP&xt6n&{k58Lg6zGf_2A9_`P-M|b1JJpZd`CkMx70!m?RM2!Q=#^Usu zxQ3YvkatwQcj(XYA>pP+nDIAQ&Xe_gFfS=(%+UOs*_P)h_GBP^uFV+_>`fAXgsN<) zfu~}{8Gy7H_l`aUf&XI~*()BU2|bVFfQRIm=#2LrP~X*>j=cWi{cod#4xA=?gVgE% z1aVKklQ;2lyzqC=F$hp#0*zFE)Cu+6YL^4dkp2xYqn0;sK~ongG}wzS(^O}TUXl*} zQB{f#N?|@R8eI*0BJ)Gl^I4h_n2KxRsjq$5qYz$fB%YyHmT)h74H3HfLAMki-A$V+ zCsmfi{VHkb-BMw$m-XB$uM$tvbXCLXjt=F$_{%~zwU9uuBfsUwLx*<Tp6sbPaNM|o z(1%hJ6gC|f48aw{0~`AR!t_AA_o#x-w+H4W{!vS8qmT)M2+*Z(cp)Ic5!_v~T)K&K zHkln>{<z8GsL1Il(zBDr^#5uPAS!Z-hG^_-*}?*AKyrknt6OxrUcw!n@cm|g9t6Xz zwM>~yngaz>;j7XG5w8AcS{3daY<*F`r`Ak#IcWk_H;y|BorE@_d>+W?XsNN$Po%?X zr!xt~%Oz=O%&)+`73=ga*rH(N(39wCrtafGR%y6@pxn&ysaN3n?_;(~-FV37N}iTf z9FRf!BbIw;;#lI8)5i5MKF$&wIG)ZVGt1852gqUU94qZ^-uLgb09V@J;pj-aH8*W$ z+x|g**mKPgnwZ37Q@aPyxKJx?_fnsciT;5}k-34XxFt0tOuwxnN{HLOHT#1-BDa7+ zJ1luZx`(pXasfW8_ryfn(p=NFUgF3A@dRk4I2$z{mAe4pMuP;XFTch>LYKscSj^ji zo*+4zE_9zF7Jh#674r-ExNlcBO2VffKMha?6KL&)sLbr-F$!|R!$*xVXgOn#v|K}k zaZhp`KE!F>?J7T-*7G`&L;;S4<$Tsv6Bxr2_6L}(B5&7f?=hL4-8)*=5MHs48S5=2 z@(D$D3|eQlueZM!QV_s1mm8?fGA%GL>_+~;6enoo2a|K1&U_}J(h>N72Ri0Ii4+K! z<6_@pYd<&U24kyYJ>?wv9xrxCPq%ui%3gim81B{QX!Ag6Y&w+X7mN()h!{6I?@v2F z+1!B|$3TLInIm<#-L3u|i>G)v``p;IV~NIYZ`V&1-A&h^eqdh+Vw;OlNZzOVF~v0% zqsD0VXNKG<+j&0~S1lZ2KUeRZKz8LPvzBtjAGcD1*NDief9`LI7d$V}9`AQZYfC{d z)kuJeuLBzaJeV9UP7kg!<QWUU9|w$yd8K>@#d`prTTKtF(`Yl(h&eg*{u7zBO4PW) zf4Qf8lp43m^s@p+r`dSL+$Ftl*27ZUaJmksC&G2X{OzK%okgQnqlvnoP75&4;}6c6 z`%K$IZvs#LgMx~B{`8q2aHwHg1%HPYqA(YCD35Q&(d^6rO!PZTV}5PAGuiqPfpVE; z?)r4J;Q92XiNbdc;bbtc;Ka?-O*HSf!z+=i5U`Q;e8;7MR{b)XA`bJU?JwZA5W(FT zo!jiItV3IU=(i`q!;t%8Aiuc&dnj~ghoBleMe?7_SWD%P)MQ@&cRlx@*`4a=U8ede z%}7$a2dL+4?F81UzS~DVA#E8(Iq|J>7c4-H4jV@>eDPJ0<j~+iADUD87-iKo4~e|E zC}9Ie$X<pw8%h&pl2&q$0^FxDxfH4P(>#NnAJ$VcRj&)B<OZrlD5%k@9Laqq|J;cz zo1Zgz+vn=;yorhyqD+YTa_8e>vPB0Zki@K=e`99&{~DFh$+U13r7j_V4SVako8J}i zvYSuQ?&yCg5{jYX*zTrL29GPz_*|g*<9R)(W-uSbkp8H}I#q<G$GOFVCMe~wQ~=QV zDxCoa1w0aen`{s)68_`)xJcj9OX`Si)K{g6CW&2HFR!T{a{qr^fTf)$k;r=a&Z{LK zt0|tl34;rlde*Tj#a#moV0{F35^HX?OP!gY+W)CVyDY8ehC#~T=!@mV_&uyx5| zAh=rJ3B2m&+b){Tlti(vaxd6f!XBIj%e>S4A9XE!4aMAl=%`@icg{JvEC9=z#e3ME zl-k_9|EB<s<d9k>_bZX6bb*+&;J|i(S!LmZ#4|g)c?Ee2FaIP}j+)@sWc-0dMy?s1 zi@9|Ds3Th~>~&}nwltFZ7-Rlx&)<|Y^mCgxdE`2u1t^iGB`)4vezk_baFg+wBLCMP z1^PI}GZk_vzdL0R@`6Cgp|5h^+NvxwxM%O(_f||(340m<S-@|*e1wMlUIl+X=BtC< zQx3Wi01fDj&rL{HqblblHv3p_2+Y5Oqq;vEQBIDUt-77=rzv|A<wre>2|XVqI`P_Z zzpbOzktR`+gCd%G7Wszx>@*G47yNI#NrYPD`?foeX_;(#E}y0S;;!2TX?>-sv1uxv z8}R3eb8jO~@9YyyY|L4yrzM_?FoUY`DaFm{5LJmsA9$!QM`;}*l3*<5!6Uv(rA{c9 zMQ*gwK_}+q<ze4qkDyXbPV~_?3awwv_aK;nTc{8R7dO8C?UnK2@Gqwyun)I?*myl1 z<PZ?sjaO}_romz3<Pddj-H`FBHs^`^nJN5#FB|^Er_*by1fT-Tu%#1x6PNn-E>7Oa zP~aH(Q3H+1={e-<+OGW%n~mG>?8O#<&gug!k&$e!IWtbj5mQI{zWcQQ{C_G+KP`bd z40LSb?SCJGaFmn*ti&WBG;s_qPt`+RWA&)lG%?!!Wem*Lb@H7DhlEV~<pT5^`EN9m z(|?S*z*|>IzwIZxw&gP6kSpqa-vJ(C^F7&pM&T>C-5^NrD8}AV^p@eBM8ywF>O+f` z4ayA4`s1A<%&unVJwyHJT6g)q7Kl+`F?Osp<L$`<Ec^^_F3*Ha&MohmKDRNRr51Ev z62<$!TPLG39SM{Kzy*FKsW{l%vQX{EP|=w*4bOhcB2Xt|k0;Rl$U^|y09Q-2<v7Pn zh$r+2rCu_KeoD6fv<&2mv3<*iu*0Z}i=ES1;4Hi*cE*cRqa8ZCv<whYV#JZfi9Q=Q z$elDXu&sB-KKy^@o~l7mKrxH-6(IxL4?AZFy5|N=8S|uKH_>h^8z}t<vM?9DH6+He z0V#JySvg?N7cmEOO$&i*%=ZJ$Zpb_!50W7T^cw&R3`cCPPY5M${-98m#&k(%k~?nn z^FVr6+1Z?y{)$cymcP@IKnjRaRYNH&E6gmsfa8kt->B`R?nOaHP6GSEgY&>dp&#`G zHM@2aOaC)`(S8h&M&m-G#w?oo8L&3+Cq@2GHER1=HHw-}8Yr_6{Rq2J|6)ble~5ke z95tg~M9aL4oxg43C5Fi%v=emOAs``KE;*q$Syg#%x1j<Jb%ZS%M`YQNk?Rd$f+Ue@ z>)T=Vd7v<hrTXYgv6yX^@46g3>GgYA^Y#m?wY!-)GMJ5`9(EIj`xz#RGF8L6ZUDT{ zMiXHo5Oe#<OlP8SP%obx`2DbnTrYTKMqyLe<Q5B{*-NN7TKX<}?{|*O@0Lp1iyZ!F zX+{$?090qPYnZ3TtNN_CqHYB!!wLezJ$PnO33so<QE0cGERRLkis+xjf&%}pg8mt% zz9`0H)W5_cj;<qnR~8f*1nC-bVkdipkI%sT4viTt_(kCv62lKW-MTBrFapLEp+nI4 z6Z~h3OUEjx<8Qj{O}l^pRx-nI3Il6Ln`7Rwl(aMteuxad(x*8t{F@#1PjjpYjr^l< zZ0u=}MC=N#Im1_trAAkU(>;x@uuDPCBkDgdYzjVol_FE(4~wxrT_E>GZri~4kxmw= zrAhKvi8zvrZr#K}_;E})h`^yoepsP@pX+JO$pW}kOE~jPY2kZ2VeMj+)%q&J`oPk{ z_uQbF5gBA6;nRU{Swy;)2y8oj)`&kI-}<ci?bC6;sl>!Aip_&VsCjv?SC2SfEc-b# z{^R!HI|!A^pvKOld_$Nq>KN6>!vQD5R^Q&(rLVA%o&;6<U=}EKL`)|j#AoBt<?^LO zMn>AaK#3VLPNt1&AM3dd2ybuq<E6${e@p#BG@&wEBQsk0qJaZ7tg^{}#?fY-&p#a^ zZNqnJKax<6x<=DNt<37X)H1%vv1Dc)u)lr$6mLes+#14!^Z`+yx{Kut51+MZPw<U^ zi$9@jwD5S(C`{UsaT+}uc;BJ$yNgdP2tL_(=BT7m&mV+j2easm=vQDreM#bStkVB{ z44=1AL8_TOn%Oa6i+P9!=Zw9Bev*$kI^LXf8u@FyPxNBLP6BFX5|y~t=fI0Z9$1xM zG3yPBV*_7vT7IGFBc{AT+qVI*H->p+5807rDA@nDrE92MkEu?V#(c8#OPj{+wg1+a z)%`4Mk?|$?*C)u)iG!U4LZ*8u&(fhQ>G!ZGlvHNnI#Y9maLo1JtKLgXVQ7AW;~;QE zrMk6LS0DV4mDWm$Om(I1SdJZYV<j>Z_z?=Ut|mEW*5CV5F};6F$h85|a^L8R`A4{B zd?M{($gAYNI5aXEj40b@X%v((jVg)~Se6_uy^V7==Qn#<7SXVb$JnBK!g1ZRXCobq zgZ>KV4V#0Lv%8FI*Jt_3ad8V3L6Vo;(s~{!_agU+DcK<<5^odpa&>hwJ`zVoqE#j= zT+oKz&NK5~0uM7~4?8!viP-GerQ!Zf0EsQziAI@14iY*BhKYeydP4wwQ|F*|+i;w= z9ZIHwjEzbdb}pICf4=K1wppzBm>KAl1`dhLfj)u!5w7@1Kbwfi)D+dBq(qi2-Qfo9 zh5Ly((*1ugHI0wm5!UA=v*YGox-qetoE(Z!#OKjR@u%u-+j_4E`n$H)-toD&Fr22M z;#w*^CelZ?PMuWXg6(9~!Z{Xh=hL2^`&8<=)6n;S3`Cr1+24k=>zP<u&<4}8o3%1F zPw>2nVzb_R*CftchrPFx&_O)t<oeZeHp!N%KQ&wy(O7<5Q7Taz;mbR!nV&zB91XZJ zDq;Xj4TJL<A^8$xC*_xB@TQf$`S&lf%)-llqi=X-)n8lKn6r;@^tgl9d4oZdUNwIE zkdB(V@Ox+vwM!<g0thjavY&SgNbRwsBCFL+z7)#MD>IRm%HPZAWZ9%mJk7S7#MKKi zbPmB%Y{Ge)Fz{Yw4b8le`BM=~vveO^A)a&KcBFm?Pp{0RzPnEf*f@)khg=N^2TWr@ zdG!*?@XJvfI5IkqxWW)=sHv%$xer%7^<k!0c_=3%4ZyXB4ohvvkJPI!2>j^cOjRJI z=(;3UMQLg2iP#=$=7d@V`s}OG@gXxB9BhLkz(_#i>VVClH)=6Zt7#2>8c6Wz=;w*F z&C0=wk?nE6rcnm|)Z%Gxa!5Qs=2+usy0lL1<^dhpK>?vo-GVbLRV`NVmA>W4*&E~c zz)NP|3wMB4`ROiMTr>(Tr~8GAbtb7@^#rL4>u@#+)96?YB5TCnpacLHF_u)ek=K)Q zJ|70g`=65kKRaQwlcp}TO}$Q+{%N0W$6+!3(?-x@8ZTZ~T6%l-`G_u^dL7@Oy{+uG zpsxrhIm>%Kmdb-)fp6Fb*w|lcl_2xnw0O$c6|7AaV72VP*}IlMhbgCCNi+UF_}S39 zRV5KQ;K>>@@xpq5Riv&sC1NSGUE0|G_2G84r~muAc4yO2o_KLEsn1$x!BwGaTRKm5 zmc>L~$g9n~zUWVZCPTRoz?`m@fiSlP8NozuoHz6_Xiye9dM7I_4W>=fP`SWkj+0l{ zp3i%JBj8ILJw!&DS2|a;N;w<+7^b@FjXPsGHh_+sSEjD){<uMRaR9-*dUF6n1{Fll z9^Jxf19w&0`Am5Y18#?3J3>kaRHlMuW>&LejXmE6<tGpx=cf!$YGZ$rR0REP%+UJW zE{g9-ak@CXr`AOLH;si%AyU%Lr(Ir?`ELsK&<rKv%x107<GZEXrtX3*+-rtIu`iZ( zku(D8@<ZBK2z=5zmhX^SF!+FoV6{gOG*At4el^@Y-GsDE%hycwWvbfa<4=nco9*BZ zq@>av8fF2MUVV6k9XB=S<BNL{f2^%TP1a*pYynJ;OSLSGku+nL=i><&#;>^lHH>~w zr~ksny$v+dQ7Jb(BQNl?KJWGpfUH^FcQ_+iC<UT(aBz5?mUCE<Oyh+d@A=Qc^swt( zm2|o;Rom~Ev<_nosO8-3Ad)bHhOZMWe!P|xt6rzXjrq9PJvo4x^_->p6YYRiNL7b8 z-<fqhWCv&-#!uK8cs#N?uC2p0YdPUTjVt&#TIwoyUF1=uufdeuhpb=XB|f*1vc7Ct z$iR*8kDM`d9FA^j=UBQF-BcYPG!U&iaa}TQaQ+omg|zEz_uoT3|C5VO8a!fLc|D<; zFX_U?`K$76za~teM3_;4-k!}+8(CXh+soJ6N;4>*PY`5V00&g1j{f{9n#>hz8@R7z zdAiZw`mWUcD;&A2Y+r<bpXx9Nz3ZB6xSY5hNk#hN1x`=yhmcZU!WvdxN7Z4aCVg*M zUE5?n;~TtJ-fG5`vWS-0j5ruueT24z&#PR=Ia1f9o=(X(a>ggCyK0uYEhVcfYL&We zbOC>~Qv!aa!T~tqXISbf^S5}mCufxxvUsXZ479}?*Z-`@gs`J<8HyTOyjbUB4%60; z5dEjN2S`CQHBauKd74ssopv+CR=19C9nodWKJLe%FhTb}<wG;q>!qLU<Qb^{_D30t z@49e-TD<IsecFIfxiX@kai~?pbaZO3*=%sZ!ud&Us*^b~PbPRz*KCFD*&vEJM(U;+ zM}bbzm@9%X!VjS!0)#&CCL}m~T2?neJJqrX2e4}Qp0C&fKyLN1qJjbkH|UEtc;ta& zWPH3gYRD?5%juQC;-XAr6xgI=!B7{mD4kW`_Wa<$j+V9r4-&w6Mn>Opj(EEwfaXpT z-a9jcTYw$sy!(4SQ{Y(N%#4{g;chkt7xZ=fK){FqLO<{w8`5{Nq<_4)9Jp2V6mfS% zd3XZ9Z+c>Uyxz79jo@q0myPuXw96l6*c-rI)hnTQ6ajc~dX3WZhgfe&;qTb`88UpT ztAwtMm(SU)2XXJhcx*yNkx(|kV)Kxd!DTkj1fuee)xbSk`t}d%=t{^aa{%+f(*)Xs zi(%BnTF9Cg=+0T)^^cz0dg+ZaiQEslV^Oco!+(*{jVrM3R(pV!ED|0UfVDoJZ99ks zZu&Z$Amh`K+eMU+lpq{`5+2v!lA!8E5Rs5ytIrN|ZRfmUJ+xFj2sG__ytbMbHnT7% zgiJ1bn6y*dcUcY)Jd$N4FznB@$YCDBGfVT|*ZK$Ofn?u<n?Jp;V#uefeO&dGv$iE* ze;inEEFGcI_!Twlit0Pglpc)1+n9mJ*~s>OU{`11O8KC}nPA>f>}>`LyVO<{`l;`3 z)9>H?GdffEO!l3vn`UE<ycnt|mwyQ3^1H9QSFP+X2Aw7^t!&Z6%VJRV+OB(k<t#e& zXUZHd2Ll%vx$muGM{7%>m}unsekguayPrLMTZLhA3p&@jubD9$i}iZr?8(+!7%=nu zsbo=S<_@>y2TkEGY6%4iC6jh3O^51D(>84Ney))^q7x_dAVP#l2Kr(g`q~FNglzc3 zbMBWzF~~w)TJrWMg?pz?;?Va6HXovws5hUkx3_kUC{l)@HP?6d>=u&)gOmhs_snwR z`)+2EbUI9k2?DQp(gW^9NO;OLe~!K7yXf96tkk$)YP5%FH3Kr`&<)!sYDho7`jf*o zspksU>^kh`u%@fQ+rsCxJA;)P>vG<f9e=TIqs`HIV~eBm(VAx;%qsf39!*}!|JYQ? zA0Adnx)HR;W$7f!iSvk_{^JgQs3?4u@N|c+Dt7am*CBPWmFE}7*JBEn$4ATM<@$P4 zLPzzkrq%p!!!>xA>5+My`cH-l#pqps##*3jjjJLD6ua9Bj_VIi^!O`JTdyjg+}~o5 z<%A}zW>viWDH}@>zj=2>n4T4Q&mUm)z%^g_h;CnFt6^d=*md&S!k@e21io0twa|Xa zet$p1S*g?dhN=e<!=MfAY+3Bg_+YgaUyStu<5(#-T09Vv4=6ybmW@*qJuoiER`)kT zXNv$A1{d(U;MQxhI#4qxJBt*TFIp4yNHAKuOdg2_D@#dE;}tB~E?V`)iQ3y83B7o@ zD2CLWtsJQ}<Egi;eyVzfZ2)Pt_g`IyiLLsIN+QK{L8%LwoA82ekRrV}?c%P7UVOz2 z@)B`!BM)-+!K6`O??Ud*Z8rcs%+|p|ePoWFhN52iH|qL}*fY#@!{j14Oly51_hSrI z%qtT*b4nwY`$q;q@CLKAh;2>759gACzZ%YLGgnK~=(rH%JQ>U0Xp~TG(BN%jqn89P z92_bEy+kC(#Kg3_KUeLe!#nJ+cb$~T5p~Du=>d^<<^?{jRE}qZtaNP_w?_$VzZI4m zelIgH@-ulIpD!4}v6=U$^AK`6fqD#CKAvfT;-N%4w80$iZ>~P~4bZL6W)Y2j??PMD z1-OEJBK+<<?JKU7LLNHkc%ZHVp#c3RVnTMhjpZAD;gh{hy_3Cvy8|{7^=DqN5LI*} znZk_8);I`gGsgF7@RpV6gIOlQh4)61I=|Oe>NwZ^NiQ|4+QkM;v(^`iU1cx*)oRvM z)e0gOaHV_?NY0;}m|}JhLP+&J4|;B5Ug<O(5K41fSG*iI%s$hL0zEz6IfBHeEse(H zzDP!2y2AgGI@&;ZYxH9V2Ss#$qR!mStV-+o(Cc}!UB9`TN9Ae&@BGVRpq!b9`d%40 zd3p{OH-FT59JOiN<!kk}Ixp~q+PnH@U{rxN(IB2r+SR@i&tYNfAhyo$eUQ+_yJ@=9 z<x~ZAlq@{+0tNNUY`pDu1$7gp=(AGbhe%kepA2S^WIgxpaDl8(fbUd>hCyXJSDI}n zoqXw68WkU(s)!r6#!BFxbXEzHoQm}wzsYo+QJ+j%3e-<~d}3m{goRE{B#^`K!MB$H zzDQ^|-3S%Cm2f|AB*!o^x6un<`t?+`#6iHKt8RB^aJ5piDr91o<Zi@nSdvD0dQ!9x z_{^Dfu`H1;`7BE#Zv*|OX@-13t$f#A_Hsi*!=+9@4-2GUZJ)uWmldDeS{7IZ)v>#~ z%zd(k^w-Ac#WL3&PQtT4QBoS&-_3fK{3=;qHo2S3y^3oz_~Pp$`#H%T_ktH(eO$k2 zV`vzVbVz7|I~!Rt-f)PXQSG*O8^+#w`x$aoqVMyIl<K9+ws`#9i78mY^%zfF3w zL8ZN*d#9m6m+{A1|NhCf-|CoF=5J7nZr3(VXJf|-!Oh#yl`wF#gXyVY<|Nh9Y1?tk z)AD`oB_+td4MQ)BZ#7`@=<#?w)4qv(_2xvgN(uVdWG!|)kCQSpYsh!?Ip25Ny=@Td zh(uIUXkz8F*r4<l(P@*`y>iEAXo}n3tU#C;r<P{a6@IxcF^2M>Y0;<2?GO-?Ak_qu z-j3drXY>q6gm`(Si>JA5mvnih{_W8b`N&_2!knHJk-@d2Jci4zdC1iC@Y)dtISI)= z^3yG_&7X`m9Luk>_2#>Jm89fUMpH8)+S}`Pt+db2LH;9L;eTfpa6!Z06B5`vpZ;mT z=^71qO~+C4m+#}}uZOo{zda`%XpNf7;0wPSoo7&l`Ay`LKv!=m!_<3GXuK!BT;KUv z!_uFwLwG4U{P6tR+c|b;5>6j5V@}3W5^P}o3mm@!bP8Fo4!l#Oz}{zCc$}P^4ckH8 zKQu<K4rVa@9b0M_ZsQLjHm=T<QgZP{-qIm|?4b|8k*%%E^^VgOaE+K7Yn(nFi!S*s z{yqM1TQJD+JFv#Yd<p7=l$U*CRttBxL8UG<f1e}hOcoIzX=v2w+p)m4S)b6r$_GD6 zz&L~~9VT7&nI;(j?IS$htUEs4y0)C&9e~Av###B?*&Fk(Z(z_sgmm^tf|eF~rCjcp zc@!>5oGWb}vjc(A!Y;_Dn3S@|q-{%;z2s8i8;|Q!(N)LLQo_gPO_c*^6Y56-zc40T zBNwmxw2VCBgs_;-fhDoP!LgR}5B3_<S`n_DhLN~~@n7LKcOnU);c?UrEoJDRD3X%7 zn5hWXC8#h~Y)2oE^#|qURi#`kNd6$%Zhq15OR95!2>HEx{|dRqchlrErwP|aQcmt` z_7H}`8PlX{3+l0YjP@_WPW*6M6E2+JG6J!JY@G`Zbs|UFGXLoK#Pfqlov68R>>s}O zg2z!A{!ad=_Wkf;`61DGMEc6detq90D2BE`y{eV0G%~XK^{Hb*!ok0(a!oESZ@~Y5 z416%IsZoyBDB<fY%u!F@MItIXR(<v~vqUV^K+}!ZCI2Ptj(8;dbtN}j@}@-o*?}ew z_J!AZ6?nSZ{e6QKjzj&HZA$6dgXbz6T&LW+e-I6)d{0{3_`IvFAt(y%%l-LXjgzyp zL_&4$8dY17hm$>PTCRK#!Dn_Ni03hQU=Evv*KThLPD@LN&*tmxld32B)59Pe_BI^2 z3);*a|7~NAh_7sRlY?oXaG@ZG9krrxa&Un~vnv288}?FlGMN1fUhy6wQ<iS@<#scx zVIHSa$rmz6lPcu)lC;K3Q<qk^AzN2I^5N9b?8e2ZEMVnpwz;&8;30{keEkA<Vb+R0 zHnuXTMLvV!FP@;FM-rNi$cI~w_D07Sody^9^c`oy%PX-<ywl+y(^<r!`o}>{+QVWD zh>zcvzQjt=<%wgNQmgmlTx}+~YyK8CrwqRV^@9CNQknLQTcB!C-lZl|u@VYKmpAGb z-M5y`?-(e)vB}czWPj*uic4oVm)S>b7MB#Yds0cGWv+4g8?3kVBd0$c-4cEN=Rt!3 z<JnnZbM;Gqs9E=OayHUScFOvw^>ujTqAFe{_8IZ3egTyJ+Z+Vl68^7;$IEgUDC1BF zn_CDeX@)4YwL=<Jy_LN0I{qAaP=5u2F;%R0$ybDp-lvC%!9n407P``fB$*#}cU_PM z4yzLXYXM%nl`yVdHfky+kW&uPxwDIF%vExQQ4@jB@+>;U^Zr-IYJ+_ffnUo_BLsWz z7zuOn?aCd&8>}w(J2v}H`#}%;)t~ORv(?*1RQC2w%B;bXmt~)gXiH1*Vr#Yzx9vSC zUDaOr9MkH*3IA)lSn=s=nSM?7+UB7(0B!mr>I#%_8Z`0fBa#zl{Dq+SsFn2DsvQPm zAOG7n56s@(p3E+{ZiM{i?u}S3N{bZr#_4(l)&9P?9fvqOf!To4pncX<2O3!6RTz<g zb{$GA3{+hP1nGBC-3e%Tx|C95GC$<8z7+~q*L_w=#q@A~ul-|4HwwmV3wee|bU82^ zm&SX-IWoGsQ2^kI+7f_G(gy9Oou%_l-WsNzC#LQdsJ)-68QT^S-g^CS?w!vMHwWlz zBfm4Myxi;XMu+oOP$o~HL~R{4e}nOZ;MlDTqM?6)u*3fRt97_kgLuMT5>?5V#@|S8 z+xZvSybo2Zj!<1JwEe~Noj->nt@uB`K^px(_S{3qm)aeT1_$NezHVQ>qot{L$-BRT zzeoF8Z21$ynqt~Y#(&OC^-g1YIW8katA2-_*>&{*@YJ7l$yv>pUj2NPE~ecnx^3GV z84my8HjA`$c9sSutTw83Y2oE-PN!g$S7F<8$0xz=F_cM@{uzeb@oi$;!p7D0d-GqN zBL*LWs63weL9BCL2T+6gbp4)5USS&U_U4&uL!JyzSaWq<BRQ~MNoj94XqbamWpz7S zSmI1mxAhS&rf0zRUqgWEG^yT{M9?L(q9S8#<(N)kgmscg!W@5XH{`kxZ!0yiVzjcs zO?Ufr9#*pfHqy2(AGHYJB*#o>$CN<q43iUdIUxGZZ5yxe$Rz3!xA^!#SK3gm*+kKq zC8qt6uF>4K$1;+%by=;s!!{$h*5&cWlC>^XVWIW1CKwKeh?R<fSb}8~KW`(){OKjN zK1aH{T4Hsj;_Y;53Fw%5Ep*jME~Ln+*`<J6#W223gZloUJ#D+MeA6SrZ-4fcJ(~~c zC2Cq%#NvssoJs$NW9?a+4FBD{(8=jp_dfp1O$+#et{)4NEt8LGoezBfllR@1_tHz; zNxTkqA*KYn#|%m!!SKwQe-BaP95E$MW57|Orsg``THEyL-m@%X5wp`s%|8IetEcyO zS3vi+Klx_?mONC>p(CxL>{m;OZHQS~IFUj00q5U7O9(%{%mt^<_O^o8^&?fJpg)Nb z+cg1hKDm+CMNSUc);6B1s%4}3o#Da56%@x-^L^RZ`#he&>cLwhaQDgzxrpPQ4zNt6 zje6o=p_hj`wflTuqTkD>tQ_950m)oSB+3$z{05PNLKOb0q2#WLK`lbPlhu`j9n>Go zKnTS4d1tNXVd={kTd>OIAaBJRBvg!n9AZjixauee9Hjkzd$**}?h%H`T3p~xUJoEr z@UFBam%$^EXn#Zp6=-IDzP63>Q9C^S55iJ{SWR$30;Y+H$=dq*Hy~!Gw?0{mSk2X$ zpWZ3q%Pnup_FN7Q*A4oJ=?|ivT~5=(4tKU4)~g!4xfUqpDiH?l>7ViB;h&6<SU?)1 z+lu49Y%kU^)%?^g$4irK=hbbP5$c)(0y)bInV9~^`{{T8SuwZU*2NnXZEkxlO8EY= zMCjH3aRKJpc*B$a2iSr4T|Y>n7CpRuDdKMtc!`~?$zF<rj*c$1l_h^)@2y??pz)XU zWa+22qDVls!t@T8s6XY+%}w+6rBDNh#~4u4?Ew|t<$h5DbZ)0g&_nt>@<T+8j0abt zK9JP7Xla?1Z;zVpt$ouISM)m1EmyOP#cc?DLbMmXJ>}4zeP1F>;lH*X3={Jwne4o; z8^6^R^t)F|o1aWZTWY^qy)c1^<-zGxC|LH0-H)fR`x{YF2`}D6#dYZH3-n#9V~Sj7 zHnv~fg<Tsjn%H|U>_sRZRxu1*-Fo(lExBZ{#RCkZXDm!!O#>^1$Y{gN7C^o#oB$yD z*au5q>9Ajp0^wJmYw+zwvCI!NpPNCi_rQ@X6a4x+vf?E+8cxUi?>yBBJIbU5)+tT^ zh!+D-%hHoaw$1Zxe7A?|zw@T^3!wI{4>c6Qn&y9zAaeRH{l1yRa>AhRCg$|odR%as z!wZYI>H*!rH!Wx6SJ*0z)CCz%t7liaPL>1T1&hW`y8dn2olmRBVZnF;xsb+@X(}x( zKLRe41<mH6)#c?;izD*9!@c&$dP46@>KzuHU>WF`oY&?+=JlVCX&Mp9Zbwe!tB)sK zRegotu2YWP2rP!3uNhS2Xqf28rwKPe6vp}E20@P@D4S8W3EJM|<4f*`(UYrzs9d`N zRd7Hza*x(9@1EDtzxszKB)2!*bf|kn4E=Bk|3XQ>)9+P$Zmgt(Lmuz;E`%b)>Uzp} z$#1trS*PtbaOvzfRqw|tXmv+KV%60(Y^mI|d>aVOL(VIWq6ro-%J<IE%E}g_IG;FE z3b!)xwlNSUBgd8qBxv+g79Jabf-MuTc&l^<SntRj<e4dT5H-paVGn6HNb#4*M&7sU zN=wy)rFP<cKTdL0(X*iWyFn-zUFw)L>fdpDRFc#&OI<=t47x=ih$sT%aPac&<sg^+ zGJoL^%)!8s@pDPGs6*1?TX04f;b6DEWB)Je{yfiZ_@4J|R76rvYG`>)XAm^tRy~^q zWVQGj%BB-Mu&!;HLyB#eWKLWoB8CV+^2N%R7sMY<DrVJ*I5s3M_MCC)W4*PqS>OjV zgsx)wRSzmUqyqP%EZ_M^IZA1!3$1(qQ~~u-Tt<FCozBfXE6HZOZ@5j5NPz-uzPZYC zQUliHJZfRTTJI=!Nc3FUO7r9@sEcxqoY|co{P3E`6xT%9!PG8Ah%Bv{&%z5ccziyL zdd9ya%ic&c3s1N0J&q$epN<iaJ$W$Yk?WsqKV)*4V!1LA*n%Iw9n5mi+7rc7i1@7c zBw_xL17CXW_dn3(y(^sFc5@LG?c7@}_OIp4g*5&3*@&FAmb|KtPtZ1-FZqPa`T-07 zllQ+lX#~@ezTN3AM<W))TXJ6eThffei9fxAq}Z%_8!e@IQdh8F9+lLvTM@A%=Vdw{ z{D+f{&te?$8fX1Fv#;LD=xn079WCQO++N5XXGfzRSNyF^SdA!+U?2!=!g64q`k{dP zrqh;aK=k&Vu*kCgyfm^yfZ;h|=e-Suhr?oM#}mG4iq&D~deQ3;nIbun!iTX8=}(_n zW;EyHNZ==*?12VC;dlBzFy)}{B>QQFw2$C4EHbhpj{@!1ApiLw*&r+Ut;=Z{Cez9^ z9ZZQ{oCNwVgwI9FXI)LVIhyRoAEtf(lQ2@c0tcHuP2_s`zW5Z5|Ld{)cTbbGoTwWM zPStlFmQxne#-o985kZ<lb<=~THY1q1ob)!h!W5Nkv7S%%)7&lCgv;Y#nQptwK*&G$ z2eb5CIMFY8;5sMiuT0#(KNo*~crIomE7H}|i==GkUdP49TZ{sbM4INqEgYMalG0Qo zm9ryaH&aF${G%YmAtJktG~mWw#8J#Tz2;sbJH|Ot5gqRpIwAYi4rXjt_kRuP=S&S- zooA5SO&a`;<4E&Z^x^b0_FpqBewBByqri6XTQ5Vc-8$bAJf7_IYdLVw$z##=PE3~7 zLgCB2fV0zI^C~wt%!N26*c5mgCYUXC>F*uAeFr0B+Zb<;sfB;@PSEv3MDn(8`h@%V zumbZJ<3!_xq<BflMQd(!g5fSY;;dC{&qdquABBcr5M;T{i9ZG|{ZU(17Y?(;cWimm zY-fq7S<#O`yDb+lCL}6pXna&AI5`wu*ZD&$33iqbhNTPpnwtuzl8tDxI*%zIbaMq| zyn|#zS{CoSR~U^T>_zL`eo%7`ZK&^j*smD$;ErIm!Cp#dMP?gc<agA~6u#;}g7x25 zTG0QsR*``+?d<GqF>+3AMG#c$eQ0#;3^yY3v3#=a5U3W|xZ>qw$COLR?>Vm#E;R^f zt2S`H>i!!@Ae#Nq!W-zmfp>lLCD%}f8o1}Rl}RVB4zu_E|KaK@!{TU~wHHW$B)B^X z!8N!`!a{I@Ebi_EcMC~y2<{GnEbeZ>-Q9I@cm0OvdEax+_4SWs8HSmj>guYy@2aku zTip{<+DA0#Qyh|^G;zvlY^oP*bjDK2Asf*_swap{uq}5J=)XlhvGymw@Ose>_tyFN zlnp7AF@kfVCd`>>%{8unt3FWpk?XUTkkQ3$sc5_omCA2&(Ab5u6bk{ijh#jBx_wZ! z_Q;hiV(9Y>R~A=))L_X@!Vx3RpEA&P!zBv=4)>@7z-V*yWh?2ew~j^eU<pZYZx}hh zc=GlfhvS6V{rv;hL<#xNse`%IFuL)tPl1>kB^6_g3GC9z#lJTSQAm`A+J`&y2Rrvf zSdI)h=`DHLJ7d<rxM{u~a$7xRo%Fn}C9onJF8A(^ee;V-mDVDynu#1sj!JyJ{+Bpf z%Cy$iw=+%V5Wc|rK!=U|8+Wt)xwmuG0#{K$--;#Uv=0X1(gNsL2C;!C=6{#Yf1ve< zz6oHK>^4LfZtpvBWxvaV8HJs}oAI$D5GzD!P5Oxmp_!3WTT8t^(T!k{gx>ZjMH6X= zL5YZO?^at9_%!r0-%j`$4&0<~U5WT^Ku`KP=<{zV7b3mZ{{%##rHb6u`(tYwn+(C< zCzw37$4(fBP1DfLmWmc&RRZxv#%GO|{&91SUQNi>OXW7A)=Sy?dlcPPDl{_5&}@^* z@+qLlj+}`&o4kAD^BT|bSmp8B<M99L*RzsoHvm-eKP{g~`ir7(NB;%-$wfe0YlJ%( zx0AM?dnbU;STQD{oNS7=KdZn^3FlmHu7~&&aIK+G!RG-48nnztGyQYLMFg%~*`HoH zFV-l^I>{)<WJ<|p;D<s~4vA#c7^Ng1o#fb66eVgbWzZ<IJ@pglnz;2V(w<{P^O5_K zEOh7e?DTl`Gr9gqM%zrI8~YJAU<o?7SAbgqO__>P(jC6l19V?BWcp$S_3fvpPmjKo zlJ6l9!B&1zPT!7X3C_iCb`!ld%Mx?d#MGjd2;s*SK^h9E2|#!J(|{BoXdRH_fv>{H z&P{y49bSNjKiWnCya%FH9>fg)6=CG1h>swGIPvIv(Wo3^;L4t{doqr>%GGZt9f`TM zhAIi%wov}<7hs|OX_KJ@(X@a)TvhJo&fwGbMMi77y(#2nQihP0KzHY%P&q}&g)=A> zE@iy`C47QzUs+&EV!BR^%n}uJ$7a__X%&~tV&>Nska$C6F#K;nDWLSaaIPwlNk&bW z62vKjQqmwLp45G}*d~gy3OGQ1gaHw)*?|akCx7N#bQl)M*3R74KOd83IrYZIgoyr= zt^y3MLhKialc_mO0pb)-DLD_fkWqr=fEbc5C6ma<=?NrE2${jO9>U7^wWS2LE_Cd; zcXx2aUe|}^?u#lP)YaCn{eY!U1E3t5_FoB7m^yS(sNwW9h(aVbhLfz;9kcQ@g}vw* zB;`L|y|R4^+?1F9IbGqOHuSq#%nQraB|lhFB|7oqHi~*Qd)pRN1HdGn|D1aX3{8F4 z=GK<M)eZKxa>*Yqwd&k^Pu$28{9k!n?><V3#*di%Fz%>UvV&o!r-m|LBw6kac3WU$ z`PGJkzuyGB{g;576IxTdfkK%YT3@byY~zW?i755em|M^~RMtX4qe=T1;*0p9mH>lH zt)X<`&-K}i^D5}jdJ;YD(B_K_^}U-tf6`6BYE%@ws^q5{#G<MT2DFm)5f!gW`;ihS z(*Zkxz<d9WpY&jtqpf)c8`=I0Fx?E#;s2E#RDAqDD|7426zFw<kf^GMy&k_n<YLtg z4dspZa*`jdc|o$DK4tFSZNArS=mKW->j;{;tYROGOD&$_RHZ0p;R-uChF5K5-ewqT zNO#OB6LViCm_`PXPI&+1Z*CQ6r(f^B>sUlDo2C0Q=_wMsa<By_oQ?kp;aeH|7VR2) z^ay=v<|R|-Y6mR`I&!-h6=4Gl+4p?AyI(3Fq>3eaB>o0Xux}Gjkw*5i@+8>94>l65 zg1ZR8uAHsm*IqnHUU(NMA4QtKOV_>PF$fk-NkS!L{_;zAr$wNqR~BP+7S#J&dEyGW zEvS&T@;qFml*G5#X-?020IjlMlEj8t{JZP5C{_`(q?vMoP2?T2B$F0kXNF{>a^^tw zn#%U<wuF$(CW=-=JHC@G{U);eL<Bu`ItVMA#LKT^Ikc~BNdT3B;G^J0wx6Th{+nOd z_f%d=4+MquZ-$@Rw~C0rZj8Vgb<l|P_WpD!(lA@j#IASV32#6|6Ujz&3Z5`IY`h^j z^NE-*)HgGuh2NbLo8D_!FK)Zi(|gj1b*73^zGM+`IpY5oZmnt7FW<z2neKC~Q^rO{ zMuv>`Ml=8|b>uG2o4{-N!;5QN*<ov2T^ARZ7eA&%8=Oh)*2B0BH;z}$zOdA)@qP|U zuZq`64?T+aLK002=37PmYWd{ndftYFp(DHz3`CN)%{|W!J{4*{Au*?fe^)Jf>v%YZ zdxchqE{e2h;nGq8TQ4;|g4^e>CBM5o=vq2>T08#}Jy$K(@7<QK?_XSN6D#&Yo~Ve( zufr1?UOP09q_Xk@0i_VCaHTVrw~XKySLdfiaWJaJYkYiFfm*;_@6LBLcO!ZRY*~t1 zbYlrnsV;0SVlj-P8RXj%AGpSKkA=ewz~$aHW$Cmuk7DZPkfFv!0sOAiq=1BZ{OmT{ z>`0_4iJOnz8v2kqee0WEB?n9w7+Y;!{aepT<O9#kKtA+i>#&=eM!(O~@|~{>+>u@G zDyP0-PEAuVT0Fe)=546z@m@=6-W4Q_czD2z%iAA+Jl=}?Dy;qX-SVz`UmvbwS#>Gh zRyT#^GT)Q5IX{l360RS`s>>#22F|_EJ6YXC=TbegKP^I<o-Oa1t&g3Kdc_X2)oL=1 zl2Hf%G^tA}8I@&yPz1Gjcx^RZ14nSNX$_=AYzbyV*^Ey&V(6l2Y)b`F72*a%@_?i- zKW=}(Az4rWR!*QER4ckXEIr7yV<``#fyX%VIe%p`bdCJ(;?w9^myVg&aMSTumw=76 zZ~G}ElpWpcN5a!9KVCfrD4+|3(kU%}0@N!+OB2RCZ8)(V5L}3T_xtznwPkC~udpI+ z!|Ol=SHN9;^=Q$gFVYqlI{r}ac&KQQ2qeACY6-7b%>L-ly80+CP907v_${wn;G6B% z5cn$DeRcgRuYGY)ZLQhu=BB4-pyMR_^YN|&_J^a22v*mg4>E}Yue^nHHtUN^@EHI0 z#R~sjv1lEa7eZC_e}jdERc6tt2-Mjp=f2trL0?MNVa$NwDU6mS@SZt%avr_WnyzO; zTogineDt1s;J3ei`xCVp)wYS9v_#&scWd;p(Gqldv=9Wu(?;rLH60J8nm(v)>>DVq zXXd}uy$z{zB_&hCz<|i`@)T>)+P~al6FOYt(JzxN6n5M(S}l7KofLsRi@!<(FR9X9 zwlJ(|Ke;8u{F5!VqLOM$I5{&Cd$vqWC!~Jz@-<_13+F4Wa5`9(Wu<ET`Ye8>Z#YvK zVdoWg$(wK&ora$>MQEFE5MzJahieFuvRGa9Ux^k<5A}&;#IHZeVPHm5Kb)yM2o)Fp zPT=*hDSEZu)yR^jI;v`Y?Kzb)YUOSZkG=<)=}mqPo<1icZ+w72ra>6d+k<Q~D~BpY zElwUzyBv*AQ<MTX`){tl&dnd6f34AUKIl4dy`3$SkdmXrW9;(_&Z7}9cW8;JL^-d` z#rIaLCunfC>CO}lutL<L|D<<-(QrW<*7V?M`O<Le^LUxdu#cIYHouJPeVc*t{sHkE zE&O<1b2uS+Q$*{pde`+%Q<CE8bRXMJLv-N`rjk2TZ1<~O_1c5S$ZR{!<>cc@Amiig zxMM#;`0MqxVLDlau4=JJJ04T1L8sLB7f3j>hxp3GN;FO34TogGz}gyr{wdX*JWIh9 zq0)+|_~Q81w4a$#`@X3CqLv7(xBYj8-0FAc*@t@ly;e8p@sS|wDf4aSiHFR-@sUo> zU6m~k$1;B(S_dM&gSr05pNBzc*}(bpY%9{gGZ_LHWJOJzBY=P+Soz&pcZ64#;y1A< z%E{^R!5@1Ck4P(NCx+?yOY*-J!t@klel$h{l2%^-vlhZEm(s@z7icq^*`xtEJv*BW z>6P3q3xNT7R9;kEHuFr(pGZB2N7%?2xR@oA2ev$U<@v?unYE=BY<E4#3vT_Nc9#&k z85%nWy3>yTGN2vM^d(<a!HkS#^b=Rn1=mKJO%0iG;|Lv(yf*8rM<XIeFH5FtBQ5#{ znW`UhxtAuY8yXr4;@6_B$lB9VJ<#!|j>dVHXPOZG+wz-lw;GK3ww9A!@W>p1xHkzD z9Z1jYSXMmYzR>Uz9?MjM;XH0*YbQ<=qD(s6=vfEL1r{7n6%P0SgapU*=fR`&4t5QS z3RdB4JNq~w3VUe#)n(cItIN~y%HgAx`mXU;7auv6r;@hC#gMD<vj4<s`&v){>8Og_ zGvWFu_20V8{8$x%qLtg*m#(cW6WmXSnB7l{ZkL)j0-0@{?qy8^TSMsu2a`pb5o{4R zN)2%>T)a@7rjfsb<uQd87Y_KNrDPOI9FuXwsbThJ%cbsZ$hKM|#57z}&Kf0AKthvY zdwPo{)lW21IR666vN4whm0!55{QSf|#mgHbC({pS@~fvA{5BOHs5R&Wft;4!&b5!v zn9L}hQu3qw*ZeviiF0P69H<3Xa#%`_7l;qeEbq#lA!HIXw`aZ(aAxu^%U>FpqGKh+ zcK8Hy5^z0NDwJm8Lks<fQze`Y7LAXJ{G+!SB{pa8+hUu`-G1{1_9lLBvH&RjiL4T| zbBOt#p^14jGC5tfG=BFwpSIW?TIB015^yExxsNj>o;n)GUwLFyF>paT-`bhG0)&1^ z9JjBL&=1GA2Is3p+e`VJ`zO&YeZA&u-oK-p%v^uYc!;!SHyw@@>(U2VpTqNaIEX-@ zCgr_7z30;f6~j5S#zZL-IkeqkZV#IWjhVm`Z|no$HILdI1&B1DJ<15`7;tu8a^^kR zZ!1<G%mow{ej^i-P2wt;Fp(JU0qpIvWxwFvxtQ9bMyz{tFdi;xNd9<URrXW?`PRtj za9TwBj?&BYJdMiQq1B|+;Kqe$x<YTSWMcs%ZVuaN6-^;G=terO<>v^pu_+)Bl+|Is zbnAQFEeGav^n6D5<<@^|StCH(`L+uPD=HAk_>9)Z_qjbftQuZ5P6eH@D}c$Ru(tpJ zk&>o^r}T3Ik1YNrza!l!E9;N`wyJL>wS*laR}{2Hys4p~ZBLKaNG_-?s(Z0(>+2z^ zx`|p_F)o0}<5dgE;*@mK))B^hgk0oS?Q4kL`6`bJ>m1(1e_n*Smi+11$oacD_wmw$ z8qmUDTP&>amNM7V`CY14X4>9S#W}<qTc^cDt&N;K2O{%%B%>NZjfJ*6pp0}VwAYH> zUU3WO1uL2gi$*%WJkzrg-Y`OGe78~9k)g4irmM6yXWhe-d7v~UB4gjTIh?g6(i+QC zYl-jKD0o1of4**b+>tGx@mX~qD5kq9ab(hupYE9<ds%q<V7uV9H<(LC!_AG}EuY@L zb`-ysU6W_Fx65hs9qF)P+QbbrkPUksB~^g*2UUNZ0brJ^s&tv}$x`QH7d*P-3Jd$y zB^DMI58}>_Y0d5`Il9L>jH#*P-L2Xtt5(wc2V_jd-T^|c$BLqK+g@+x0DXNSq6>jw z&*X1(43JNeJfL+7tkAc3JfD=;&CR$`$(;Kehd4W*GOs+k%Inkped=k{<D&-?5Zn$8 zKhQ8YA5T$`^y9*$)u?ynwRky4w%n_eArt!YT$>j`tn_tOow7khp_BjzpuLzol#*Ds z-&NsjU-}|rT&Mt>B<2HBQY3WW+8c1&l_qVShUW@D2R7<oKdWtQRt~>bl`>WKKpTZm zi2ZD^edpjvwKV?zd|7r+J&6+8khpFK`QFsJzY9=Fbz0}|Q0jc?S_9SbY2)dVOtp;b zDz4{cTLZ3r;apploi=P}dmiR2z;P-xQLuikCf$8`(9VA(-=1}Iwz9K&&FSIpj?2sd zyoB5VoicKFICCB8*0L$GJa!+ee{*wl_o8gs<C)6oA*7_G6EPSK{(gPiuJ;uHz7?Q_ z-z@1EiNXE92v;(o&=yti$-w<Nnx9{Ag&V}xFFEL>{_G%zmNN?VEM#6u@eTa`ZwQu` zNqBaC6?)UBV@wOl@HR7Bwb$}Y*+x)Wm0dM)6pI$mG&`L!<FK7Vd2nC!UG{l=mF~?- zULqvi{CC(TcWjKsXUopX$tfQx#uz>0x<h$?$ps_b^A_$ob+u5doIqcHHQ{7w9&P%= zh;YW&8^upqi}v`;I63I(DE5pQxOh{bG6hpRI_ByQ`z>Ds-}H3R?&lc@wE*~i-ThF2 zg8gikv5x+z{OvbhK;y@BsR|5`znCNE1EStr-?yN(-p0KCFY#CBr)&OWC5;~c7#uCv z01IZxC@m^Ucd4ix!6-^&iKrM#$uSMdsKb0TeC_#ZbT7~TrT&)0hL&o1b*H@rG+;5J zu@g-bt~zCmv+JRxTG^7hQgJ-o!dP&A78_6#|9RDs>dz?{TCZul6CNuazqU1RGd<-6 z1Pr+z8oE~v#W-HGXbItyT35)#Mfn@vU0U|bQY7&@-s3S9k8gEHkTaEOxr=|4uK}Vw zy#HDv3g{)cb?n}8)-{`P7|2PEC<?*a>vRSgUWi0W)bOMW!~e&6LNkF401Sr*ENlGk zAk+(*6L5H?4rodu>O8ALw@%{oiAWQiG4t|xfq9VOp&GXN%3+;PWi=Na?}b!>CUs_} zzD8MeKyeu33yOmUq$4lo>)VHjC5LN*qNL9mA6-SQ-Hw`{tm0<tU?2cXRBi5QR6B29 z7irdvZ&7ILC|5o#iH(lJMv5&}U%cdr+j{2A^66dc+{~H+81t+bh3)IBRUsE95C|1g zUO-C5t|RLB_)yrWzwqC6kO2@$oT2TPCpNzE&Ss4G(0A&1GWv0ud1tdbDaL+7?Vq7G zK*5{T%6bzLSV@BMhYTQYvY@*~x9%t6PW6<Mq^S?PNE~~9kIlw=boPde)oA2TPh=0m zKt9BL9EJIWls%o0dUD@;dV0nA{`RN2S3Hh3(^&FCci*ZT-8<O|=PR=(ycpfwYqM3K zzExfdKVBmMOm0Z5`q`cB+yW57eehV`9yz&N@N`%`g)Uo}atAeIL@cX3p(7wJY>t#Y zTVH5!NJvg@Vnxa~qu;|+P+Dp+Omst`cX$^fzj~5|;9I*vcyMYcD=)p8X40~ef>n;G zF#z(%sZ~z_l~aEqA?-F+@DJ3Y@rE7(S!9A2yG@=}O?lWATv+&!w^vY`9pf80Ba~q$ z91!87R3qp5Sk-%Ny!krR<B<vg8u4o00Ak+u($oc~w`?ERP2E>vBDoxl#o0F3m9*cf znyz<;j>GegxHoz29><0fDU2X6-fl=*%`{f^RJV5zuQZfwne|76ruweD^$7@P`lep9 zEC|+o+=$)@l%^#^zSryOp7ZP|^(eS2dbWEMS@vvneX11MbwWQe&xa?cqD#dE^34@v zSZ1H;Ol55X*F5^EfmsK!rL`}hi;iPzgKg4>7j*00LagnP(bmgl{VuTL#jJUMf=V$G zZh4Z=C?)VKEdY|G{o^5R3VMP<>pR`sVHH~gNgr$m3P6a`QOc^2$v3Jcol^K~u!vl* zrS{Ql2@*-ZZxw%7dwTnSBp1M~HfNe)j$koaaDHp6@+=#^`rYgYvSsnS><yS{wnK1V zns`%X86Xn3xVp9mPsNWE^y-Ai`5f6>vw|p_%#*+mt`h;v=GXBKOczHz?~_<uRM;8o zs9Lon>o<#+>!aP>dIJeGAqTc{nJ&{_SL=DX%Mh7$-XN7hB7>>;WxauH^flN~{L1iW za?z*enwUEK2fzy4EHifW#WI}igc8nFS#oP>Yeyy|1nR0j!OxDri3leQF^{I1U+_6O zg%Efh={0hkpvw5b1`Xz0uC4G)xGeojw!Hk_i2^a8rn|P~VRT+zULN~vjArd)+$DEY zJ|J(|>g>9}TRY_8?h>zAPEL+qYpHt2HicLH19e>TKCq3&tFQOyd1D+V=B%M24lBkU zD4Q{4_+jnL{SD}&yB#aWZUnVhkUqjQv+dNbr|>e0QWB--v^@2_I4>4s6lE`NYdWZY zjxI_FP|_19l)18^sTmn>cJ71sKDH!wR~Rpx$cFVEWw}2@F<O}b6WM|kD^nKN#|n7; zZ(oS(#_H!XgUP2-^D|+!niJccPJkgA0E;x$n@u;rcVFhpQPRi$Z!Q2v`tUtGkfmcq zW;#7YI%gz#{`=MIqJYZ-{?$a)rPjbq(a{fuauANhakq0nOrEdT7(%H+sQk`{_Oxo0 z0=FXwu4d=7jn}u7o@@??TC&s=mJ0+3M|JoSg6F>$?-cP2meH3yh|z`4k((c#;Zz># zU*pSt{>x5_k=o$cd8+H(J@T<;PH-#|o94KypgI69`Qc_$*8>xo@>$~#&cd&=yh??F zkQU)DOo9|4Rqv7mQ&Pz=pz88BfOJPWW$E{Ln3VY>qdIE-%4^~bU?onR8wUuT119)K zCn$-+tdi6hWyKjl#0CcQO;9LazaOJyRFBJL0~A^^&)d9hH$mF^07#hW=pdGouHHD{ zGBe<5UTH}bFcjKn8czGZ?>#QN@}U|}8df3UsSP>zHI}d{_6%|b+#t!&XKLS^hJVSU znJZku4YJXqlq+Ziq)#c#5*n*}7N<jfn(@~uQzyxhQ%x0P*l}lL#MSY3KKu-lSp@+b z%*VSW@s=e$fiS}PYXMb9i6V{6(a}*{CkbG(Tgv_a(L!7X1@!$!gcX}6{`z)G$$D9I zoK5&zCCKEwG9<MSy4w%DdTB|-cBdQ1c4A993dd-jB#P{LqYu#RsmmeSSZ*$XB!)4@ zs@aS_XnO1*R@!13kdL5$paj29D{VizigE>!v3icZ8u|*-iQr3LME6pO(0E3<tT^ z&7sCHz{*VGkB>m!LLeb1KiM2EwVnX-AqMth{QO233N0>M%7^Y!N=6kUeJyz0+NUCx z-!euxW?m)H0V<5yYdrH$07Rlb6LoG0TqVC4&W*I9hcbtjFQ}qNaf~ByOu>Dzgi0#h zDj#nSPLQ+V%E7A{#D;-A$&bSn;@D+^6&Z<x-iMa&|G83OL-GgX#gdC5iG$FCGJnEx zV9m+`7aGi=rMYgG0j%Kzz}^@Eh_We?Z?|er>(jx~sK3}>3CSoOg^(>A8AJ?~zmHqi zxN}UY|MV)KateJG(4tBQWhMgS8)rd@^`2p?AEpn0W3<Ne%i5o&mTNTZ+vwc_4fX?L z*kWj#P!S27X&aqIsnteDqy8cotXI<_sUWxO<R*<y5_CiZo{BDkTW~d2l>h{%iZDLH zoBnZ&$V<p_NZ;c*Sn=N1^&yvlq&gZB8G>iK75t0xPo$8q)o-92L$>Dg{%W9Yza}(x zt6XaMok{kc&iq?vb>D}<wFD&~(T6BHD{y6q{8rk5E6Sd=&)ym&ufESeMnXF_91FK1 z^uUjtnMbDl95J`}*+u~yZ_5&gN&Q*m3fV+cnGc6Uj;H*S9QGi-eFgyh!9TCUfL)5u zO_?yXTnoQdOYk}y<cjF4c9rGL7il8r*)m4bYU-Zo39=0dWu_LhE6TSZG@fN6mP}e2 z?~QX|oC@RUvv)&K6$QC&_wUIDmk-waN-BU&qFESK!suaj&(A_{P}*}-S(&e3j?k1= zsaCxpe=fzAS9<p;D(CH)yJQsj%MNZ6@%?$ywCBH_0pnT}3X%N+-b6c>Lz|w6Lp62# z!k~~WI!hqi^rjZH!U;-O`Kpbm&iJIS7~`n<15gnSuBh_*@vMbDtjn?mt`XXPT)el> zLV&ihhNQ@oh7je(DmD;=Z1SnhcZ>_Q?D%V@{h~A%1hIe&zR14!4T3@sp?|_8lv6ih z1w8+|eUi-q*e|?Uq#ZefN9cn2OPK=-QPrgB(@}nH(EqMnn6g#`a)ucn{Y}qBm_#=8 z@8Bxw32f(pC)%3~wQ=`t4+F?F+7Q?=>2PnqW$W7Dnx&npBGD_+HXHgT|41F_&u<Qn zH&)-BtKJ_^`sw~kP7hgV6d)N4?da)3(ErM6u>K?U>!3^9@5&|u0@wHUdf$>aehx}D zj1IOiRZ|^`8V$X4JT(hf<HUS~vYcw4eJC9oycV#abH8)`XynY1<iYg~$dq9=()p`T zg;o3^BkdjXD+xcJW^TnC6k500ZTtyTQ+AdWR}~xs2c?n8ikDFi<CUfY4_aO$tfjb* z!OK4<7EoMk>$8C!*H1?KVocdA8iYjp)>~v7qGGxcmoxeM-Kl<yWpu{qb3K^H?ALEu zSzdl-A8w`G%*?gqLE8||N;b9ZNW#LfLh&uw2$riV7In9w9x~R#p!*mZlNwB#7%=*! zI3z9&b#-s+jj%tr=VFr`*SY{!h2mEV7^C}3$B)k5T%KV|bB;o1SOO?)1{G_g6Eq~y zg74V9k#mA_{jvcy1^ASzuXKvZzMR^R{4K#`lS%A}SAJ1@^J%OiiPD7TJ>NRTrD>W- zf;4htXqp69Zf2$nEedln5VGoy3TbJNG5thZBeJlvjMhC)VQ2W&w6?xp&u7do-;F-z z-iqTC8i8$YTDcd-)tO!7@q&4adZlIGp-1@)V{6UN@Mh=h=rGe9TSq4;;SB)%)7o2{ zihun=!WH`Pc4RW}L%hg~y1P{o6C5J<7uh}{E(BVrwZCu!_TVYLOw$lJ3BXs~t*q^S z`_Q5RB#nzHe`5UW|7m4SQ9V)TdEO9Be{Q))pcbQ})5~I|>%+`uTt;2d#WZ8<I|XpW zP2RVp5w?P!DaAgU3gpYchrTmX5%pmgWRc*s%OQLb!xL>V@6dCMTlJN{*iiR;miTW) zi+J<0eZxBa`x%;3no#2ROE_|%V+>z@5KxLBt9!H?u;$Erv49iN{%f-L78g?+4wKgP zxP-fu?I6P$<0Qh7;Y!bn@HqGKcC{+HlmggAE6`DcdJ4f6-Z7ST>>27B$LojrFg6R0 zUD_~Qk<wP%XbxP7={&{Rxk*%J?=*xQmQ1_J-ygkXu+kQFKJjs{R+~HlYm5#zEUP!^ z<mt8sH9A_g-~7E;Ho`F)PQbj1=UPt1Mz{317)nJ_;=*5yYW(A>-N|W^(t1RADUALU z={<JHrB&Y2o5>c(&1h|UGRPZW%J-08eQn(rzBV5n+`M2(&xclyjPns4E3tFSG(OjW zYjdYtQj~e@)E+YyA0gp&nm<o!q~8UhDf5wu(*uRx=8-|`pw3`bdY-=b!Ld_1-E-Up zQp|TLL<|6ebZdD|HS8wUNT=4kW7$ZBII;RVtuxE$tbJfy_&^UJ0RzM3)A9j&#lOS@ z2J@P6Uxui&8SgZ`wuFsK3MCbkvl-K?k(sNEN`W!Xch@K4gRSc;WRH=JSKt2}YIo0u zLfxRyp)Zgs0Ji|IAHOYt&do;x$v_aMQBi|ju@$iAoIq-Hei42&?-$DZ1osRpKZ-0O zi5G=fXR>og(g|(Y{YsbSE$^RgX>6;m@W#smQB7~^t8zPyvvJ<)E-Yr2{*}QS#c%~h zz-X2(&@ATA{)zQ$mZ~xvrN9J@Q<njb6f9O|8hO@R?i#JG5w7bJvRT+y9~G5`HIdGU zQdH=Gt!)XWFY@rzz~51ym|^;&$%1lWt<;<*2IdScN)y{!#s(Mz4*Xevpz?vbJ03>% z<Yt~4V}M4}&&PdydY-QaiD8u4G3Cw`k;;GTNQBZA;tDuIdf!I~>lnG6Z;#@7y?%CJ zz=m;Hv<)U>x%YdE!SOXG^L1h%1LCcs8Pon19<_Ryx{+Mbh3qmnYmgzH-2g?ny0Xzg z7B{cSGXjS&V@{aCy`9-*j5D9&L*TKhYI38R=wmC8kfSq}9uQY-gFyq&p1~xfLof0S zlh<(|Li}!Kd&{P`{Ih)Q=29f(pX$zJBT-<>6(lujJLzrnu?-Pc@bBA_TB}A9ZoGMl zPrG>Li2dbpN$+GlCK+?|geotXRH*py?pwSo6q7G*h{fl$mbtUC2QP;8YMVLw4p{?g z_B40h`VCPI|HQ1Tm`31)TWT$QRUY!nmkRsF>q++9Z|K7<fk07_T)F&_?0fk45kdOz z28jWTgVDNpTPu#s>l|Usg;k^2r(@2A)$b+6AKwmRrwd+83wAGgZ^8;tbkI*E6+JhF zHTeqdiWbxTK$WIfoAes^0FBWrJvdnOSLvBFe!dgk8SKDDT%CE~SYHuG429}-Q98dn zfNglQ8EZKD%3a4Svc--!;$Ih9)pwQ`*+nsG1GoG<^wM<L`}CsGjVm5lisu8|&rsem zY5#XSLz_}ne#t0zJm)vG1QYg75N*J#S_13=4RvJn?21kt(lb@|+@L@bg`5_=9-(g) z$flyv7x*m&q!%ZoGl~R4+Z7B2mn2Aomb`&F8&~wlSxiWbO~o<gae|p7WZUOeLD<7; zFG3r`$`>-&hE-=f2*jwxMybP90i9JQ@fVX5hd?6NT_bb~(x@hEvN}((ASfyS>?Z_H zz_kFN93iz>9l(qG1HsX;(;1*}ha4weFfu`q)+q2&N-1<ARQNBzpQH0+(o(ejE^Yt; z>d_e^&CHg_{FX^$beFSc?!N(cCZ>ux<BS%VHDtq{aYjK1psVNgIt7{lLLaRE8AT}z z_ch>=4Y&0i+W4B)B$85cItWnHe?>o9HIzd;3)t|19NH&fg`f)br7MRv_C){22d}?| z$avPoohO^|s*=D`&FK9s1P;bv{&l2*DNYqA!c&s+?;Sf@f0pn7Rd~1!bk#^k%*sd@ zCC6UxMgM{FO?1`kQc2!owLZaN^!sefZ}zyyUpa4OWraeaClJp+28CI@TljT^i4afs zf7c0FQ2m(AymM^hBpl<%Nh{~*EE2B1@*eRqIA0b}B-x`Eu~>-FdsaFrw~EL>)<mJP zmWXZZn9X9qIgMHN(Dr-ZUcE3`jy=-?gzSjRs-|4lfh{PyPcmBZ-MTt-a{1nA6ahRX z7|PaBDh`D{e#I?zc&@Q?%I6<%+5^c)_*WrCxyZ^ZNN`#P&}T6rnS{6PNy`Ye&^C(H z9`SN<-84Sq-HBLWyoAh`fO-aOrtbmxiv{ulp#ueh{4Rh#cMuuhIDlA!b#*aa+4}5# zqO(%QuJBu0q|Z4#|Ei1@K>wB`0P06i3aE(`WU?`_0*00da30Da?jWshkUc16av8@P zV1_m(^8w=<f9}WEiPWT}s%pai&$=`VaJK>bfzWRR{@ui_n5Jgd(OLHvF~$yDSZ>eN zR``GtEb%k_;s%N_41?mQ)V@L>K6o>f6<@$feBnlH6$R~XZ-Q5LMi~U~fhX3cLcx1p zR1I&-&nX82gbWWiu+EQ|_+I@?v;z(LyCXq(5LC;na3RKp#mYPq4NB7Z9XxG5D<K0A z-_M^>HZhxU?!!<Wpm0KHH9d7RI-!kXOtz}KkoH0C^^1uT-Ii}?00?kA!1R&sT%IV` z;rS<T?|HTu)8D@1&!R6S6LA1d^Gh2h<A}Wo?gEyAq3GvN2dPL2RAN=#!+z$!ktqU^ zk&z|hQv4-UFmR{{B3H0y?BKJ6e&|mo!o~R^VWq5~W%&kYeUth{5=TPG$lFiBE1{JU z_p|7Vlqal8F!eCi<7nad$xGLV+tJBsl6P@((g`{g87r*W(G>Z8N@ajp((ItZk99ui zV_@JVb=C!^$=D*%^!CKa+%$ue5bvgz{rN%&i;!-cfF`E;#f4SDo6O!ImCKLAgQ({V z_sY`U2DGn3sDG9r$DpwHi&f{4O<x{1IJ^Uc{?i8g2rx-$i)Y{sxn37F73u5}YIro& z2Qpk;cS=hTcUtomES$xDE&fs96|VC3!&dKz2IH`W0l548Q4m3pn{~wDOo@e0yp-?@ zTKU2Q*<zeKER6equPzJpUK{MlgE=S<#(&Xe^->lAxNpX6YahiIv~2J>zTjbS^$&cF z*NQLx)1Q%0;51oq&GzeTI<TXY-T)`q5ff8T0$hTn@Vh^3WX|%d-Sep#X@0;ng*wQ2 zBDTP|6B3sbeY_dJJYW5}jZ_Z&Qq?a?8BfsE+*5fGaDxAQbb^1o@cHMz&8WSs>16qz z@2IGuV*fo10_~uPa6SKK<~+lTMCBi)w-tdo8s$DPaI=+MVtsKj^#cPA1oCBbJ05B< zJ6x#Cbg=PLiCMir8-5zv-7DhvA;o#=`+F_5?r4m`w&heO7Ee=;)grm%e!g&Wo({M! z7~U`qrAQmC&r$~vq_-Bwc3qHPT5`JkD60ydpZ(1DK<CkQxkP@K!~G!yzO;hxlpghb z-dr4P56EV@^?@lZ4y_+mOIq4~s&YFB(qKoHrI1ZKIQgYmB5Y`Rx!3dECN+ht52W&6 zg#rIg&t}<>S0GAVMe+$ugBm8|BgAkpz;B~_J)M`v#>rr<;Vr05+JHGKTlTainS6Q2 zk3_<80Q{}|YfM}qU;d{nHM$Fys3n%OTVktg@hLmPCu<>~Cjve#CQ2u_rm=1m7xE)M zQ%~!=$xedGiin%L!m=u5_eM_**mUHeFp;O$R<v<Mq#By6H=>p$^7Qskts)KHsCRd_ zTc64@blO_&&k#s!5T6x^n=dX_Y^HRwUmPs|iF|SyJS6&l+-GFhK7Wgvt?L4XS9ECR z?fTk9iJp$7`P-AK(=oI#8C^CO;2FRiQOC;y=HuRbZo(3pk`M8UPZT>3Y%tRJlVu4{ zpQ_z-$X3vVu>7>!#o(Pb9brtt6Nh?i5;>REVCluh)m2qhP0Re$Qrd0v#MF`yHw!A4 z)l8{=`%hHOZ0obh4vLrms~-P++r_HQ{8!lqJKhil-v5Aia<34XtGs8Hxn@b@I=D)v zimSkp8suha(%ouYAA4;0VC=*B+>63Ww~OKNswW=}uQPAeZ}u1I)CCsWdH-JDm(PE) z2?TP2V-LAQy<RP3qkv^b?$9{8$nj?WVc-i24BhckO|MNWK;F<Iehb?j-(|D8fC-;R za3QjRGQ79R3AU5DcxX?Ed~h_9ubXiQ*j2STe*cEc7~LT!P&1fYSy=*Cme~|wH^DNu z=QFGFMBBpT^#<U;l?a$cpTW|Yqgmi{==V!XiqVtA%qjvNo3HSO;P^Y^iM6(oIZh32 zxiA^MfoiZL#E-sqWKKrjK~4R?Gxzxkj%U9I%KZc<C5cWTyRu*|N`NbZwz0vLsYH>^ z=%F`KW(Nx@_{z~=1u+GqzQmepXn&AxtpGcUi*r`L%fbyZ6W4+0Gs6EXi+?_^1?0iq zn4<?^M`BD;d2qwWPqLkUU`KhggFWwDc*7}*EQUZcbc(1+;}%P&kDRaa3?O<ASQ>XA z%!730x>ka+CxJi0KG8HFf)EjHxM|`lIQwFuUv}2M|4tSS?XG;`U0tNk1m(BS!+9a@ zqq}@iF4p-v)Q`WM`hDePR}RsSsU>0p_D|r?7^9{@?=muH#TI3n#lf%*2<7-^(*M(2 zkZ;@?X;I;iIXE-3EZongKc<>vRWS?y&l4rYcOn=HMZS-wFkb?$zWj@Y_LJT~IT4GQ z;ln)&CX)m>B4DamEg0ht2{A66i)ZFDSQ9&P<Bkinx5^a`^MSt7881fB!+`G*3$v)` z2d#RyAFC$T=##P{@Pz?WA>dJ<<&koRAU~}oCwcq!y~c6x*qO5*>mJr91^Ao<Q~NVG z{v9>s<{TZx(+p4tG#w9Zboa|M&8WcU3}JZ&dzAlc3D4|nZOp&=abTjYvt%Iqv36sO zX2xQu=ndQhrki4J;0_3UYlH?GwO+5ZCLE5;6=rN_{8d)#Zh*1|&}6N*CfH(*hM&d; zc5oiX?S}2<k7y8t^kpczPu*QpQtT$>rv;fUe}6iB6AC2LA1q=sSu(I$e?9(0F=vql zDJf0!x}3VZeH@uf4kqy(di_6gZgu4mqxRm9tK?9qFMI%Xu)ca~%4G<VGFC$svnSP& z0&`nFrqg6OIXbnO`?1=7pGrfOod~TB@1HCgDX|^^J2moR9>5;(@Ew(cwmbMD)!$=H zpGhwTM=KIss<_1#z!IOeP5WJecA%L8#oQMwQg9_1rZyQtg}&K=Qc-awTj0D3wbHPp zr{>e0?C7_*CYWYKKR<UTB%+&a@h9A%ns_HBvY2jZXKePh4HU4Su?~2Wv$ymQgeP8= zOx|e1nV==OeKrw_OtjVCQcb*B9`K}Qw_Vsh{ev^$31WXzDA|1a;LtO0_2H~0ht)h> zV~Tv>9?6<};dpz7sE9d2s&ydmGn?!znc2OD3fYmyy?w<b(<|$<;`6x%{HpYc32U9d z>=(QyY2y~dkb@RU;hUQ6cDOIdL#(I3SiTU&r1g(?{B>+bF_#(`N0U{iSn(=!Rvn4V zc;qQ0vx+}p>hi}F8IcA9`$WV<j(u1f5kbX^7zq0sAM;+SgcIXK0x$NYomo+#iXNwi zS8$-*+pPD2+do?qjCVDXE~Il{%uNy8^i??z2nYqPh~LXENHjbY%?`ep9e8C{8JM|J zS6-5XE9o$MEutfEwW!{7Imj0_F{=*)ny5Am{8JsG2`gwfn9>dHzSzvIv>cfO74T5y zm4`+Y?mq&VRYLYI0dvLvG{fscQmKvEEDc_^{N_HvJ|DQO#<V=ncW1~%aZ8Qq6_(hL z;y~5%!PgG(d<EE}O<>3On1j?=Oy}?F`PqFsd6AZzaK9&Zs-AIw=&!cWk_Sgn8a>KH zPm~yR6nCn8oNMfCx|B1pvZ8s&p|(9+8=gqMpt4%T^C-@GLKOLUdv}Xy<loq8grVU9 zzOVF?)Ub-_=aBs%iu42auJY2<kCp99BQ~a2LZG)6-L%=;<l1mxPU8XQnFo{fN>!>m zvr1(FB3a*>kT=N`SLix}ZNU^)n}%R06|9|Yb>vl&kk(|lj20Rha->D^7ktNtTqHOm z43!a-KWoOHJj*i{Q<G~Rg+6=LbOsFqz{m`C2!SbuxKy2n4t7%JCF95Xe0$0U8s7mz z>aci3pwI{l9J2g&JMo@PjYe8Z_#j1dink_Uh%3rZ=){nZk^Q@-wgj#S*)F-=P|;D! z-8YBBJ;48RPl-f$<lCx#d6%FbXCP0L#c%wRXhQ>64!BKv=>?a*c0aW<lhA0!By9jf zfcWncoGO>0I;Kgzv3+Zu`^5TWheHOYYpvMFc{>YAF>*8zC@G;efpel0#~gIW5e}4} z=Kp{gT}SjnzT06UA-W6f=vgmUILGvX+KiKM8UcU~)1wBBI%0yKb!df_T(K-X4Gx_2 z1?7oJw73gS{aD|awdnE`;e2dUdyxchqVrMZ1xlFA@+9w-fiev&<$B{jZb<Lx0+>4Y zBi9{YhkErkf`;k>G_Ay)2fq$!(;=u2)uAI!EZ(IQ7U&p3w&4a@f_B$Z8b*1q>V2XP zhv--^Mt?mn6!$^}%uyo3ds{ak;Pc~=p7Y^7HZzcg+~2AhwgRNw!M($jQ|J8_kL0F7 zY4_iXZ-i8<o~RiPhCluD#A*InujLL7WKqq?G(1o-7c+(9sj{@~%sEgZ!)?)vQd3p7 zgSK5QY)d+-+*Fqr`!tpisbx0C_9rZM5(BHJhLJLhC0E}bdC<8JIk;T0Q((n^kC#6< zU^0&)2o=-&^x>?0Z7)4B!eC1};YRktN2nmhvlA7WU3jCDq&_+^kJVv`O~{Vs%*X{6 zW5@nI)d2=A8My#J<&+gTjHc&Cm>w42KVU0u(p-qb%gsq>A2&lE5JLx3x=8Xa`egt3 z%e#3ru)ZhCj`u)Zrfc-#KHlC~K!C40;i~jelh;j#i!;h@)iN;=|7d47A@i|BczTgH zmrg5dGC3voAmQePiO`S42&1jkgu0DpozyAozcKbqQzD2JyQ_8m0}NDEZiE*lPEW;n zltQYBZqX(UNPw-cL}}iGcH7enw%;{-iSvEY1=rJ$u}DtX0f4d_!LXT>fSvhLQg6Tn z(2$amSDe|IRVCfyzDcD~X&X@c3r0Ijc*DzA1C5W22!?a;hTbck;5$rZKDz4z8#;F# zIwrp^LVg(^va#i9)v*_n9gOhC?E~G)eR)jm!zImM8X9@<-e8Uz>{5uqpE~oyh9r7F zso*sw*#*;dF5+Mo<=gNO{p5>w7*|B#jqa<p;$=V6;1dO#AUsu#Ix4&;?7wKl$2`zd z?!sC~4Rnq%g?2G&ga?M(52fk`l}|+x^#K)h3|$?q3IGjrF)^ZIzlz5b{pm0?6;?{! z3Mgy14ob``1?8caB``1S$7qquHT(TTip|3HddRm=(*|LO*|;2mR<h|0?b(KVmyS;N zBJ=#_d({)YhUArQMH5F79>pqBh)%BPfF#XO<1Q@{xqF^st`>#mLSOaE5R;tKj1>J& z7e);Y`c@{LaldG%J((h*Di+FP4q$N6mPjFcy#Z??n4><$EhPXn%$X^&(mC=≪Ug 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 literal 0 HcmV?d00001 diff --git a/docs/source/_static/remove_background/v0.3.0_rc_hgmm.png b/docs/source/_static/remove_background/v0.3.0_rc_hgmm.png new file mode 100644 index 0000000000000000000000000000000000000000..61fb1e7518673bcc57564ce4e14bb08fd9d0d983 GIT binary patch literal 212594 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 literal 0 HcmV?d00001 diff --git a/docs/source/changelog/index.rst b/docs/source/changelog/index.rst index 534b1dd3..378c73b3 100644 --- a/docs/source/changelog/index.rst +++ b/docs/source/changelog/index.rst @@ -83,3 +83,57 @@ a workflow using Google Colab on a GPU for free. - A ``metrics.csv`` output file is produced for those interested in running hundreds of samples in automated pipelines. This file can be parsed to look for indications that a sample may need to be re-run. + +Human-mouse mixture benchmark +----------------------------- + +The `human-mouse mixture dataset from 10x Genomics +<https://www.10xgenomics.com/resources/datasets/12-k-1-1-mixture-of-fresh-frozen-human-hek-293-t-and-mouse-nih-3-t-3-cells-2-standard-2-1-0>`_ +is a great dataset for benchmarking noise removal methods. + +Figure legend: + +a. Log-log plot of counts of human genes versus mouse genes in each cell. + Each cell is a dot. Gray dots are the raw data, same in each figure. Green + dots are the CellBender output at FPR 0.01. Marginal histograms are shown + above and to the right. +b. Quantification of cross-species contamination per cell. Blue boxes show + human genes in mouse cells, and orange boxes show mouse genes in human cells. +c. Quantification of overall count removal per gene. Each dot is a gene, + summed over all cells. X-axis is the raw data. Y-axis is the fraction of + counts remaining after CellBender noise removal. This is not a comparison + with truth, but rather a look to see if high-count or low-count genes + are being treated differently with regard to noise removal. The red line + guides the eye for what would be a constant level of removal. + +This benchmark is not shown for v0.1.0, as it is deprecated. + +v0.2.2 +~~~~~~ + +.. image:: /_static/remove_background/v0.2.2_hgmm.png + :width: 750 px + +Note that the very small dip in panel c for genes with raw counts > 1e5 +indicates some over-removal of highly expressed genes. (Some of the mass of +black dots is dipping below the red line.) + +Nature Methods publication +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The code run in the paper is technically v0.3.0_rc, a "release candidate". +The results are shown in the paper in Figure 5a, and reproduced here in a +comparable format. + +.. image:: /_static/remove_background/v0.3.0_rc_hgmm.png + :width: 750 px + +Note that the seeming performance regression came with +a lot of extra guarantees about the quality of the output. The dip visible +in panel c in v0.2.2 has disappeared. + +v0.3.0 +~~~~~~ + +.. image:: /_static/remove_background/v0.3.0_hgmm.png + :width: 750 px diff --git a/docs/source/citation/index.rst b/docs/source/citation/index.rst index 65b8beb1..f6f1ed3a 100644 --- a/docs/source/citation/index.rst +++ b/docs/source/citation/index.rst @@ -9,7 +9,6 @@ citing our paper: Stephen J Fleming, Mark D Chaffin, Alessandro Arduini, Amer-Denis Akkad, Eric Banks, John C Marioni, Anthony A Philippakis, Patrick T Ellinor, and Mehrtash Babadi. Unsupervised removal of systematic background noise from droplet-based single-cell -experiments using CellBender. *Nature Methods* (in press), 2023. +experiments using CellBender. *Nature Methods*, 2023. https://doi.org/10.1038/s41592-023-01943-7 -Preprint `available at bioRxiv <https://www.biorxiv.org/content/10.1101/791699v2>`_. -https://doi.org/10.1101/791699 +Preprint `available on bioRxiv <https://www.biorxiv.org/content/10.1101/791699v2>`_. diff --git a/docs/source/contributing/index.rst b/docs/source/contributing/index.rst index 7d89ef94..682cf7ff 100644 --- a/docs/source/contributing/index.rst +++ b/docs/source/contributing/index.rst @@ -9,6 +9,12 @@ with our research collaborators, your feedback is invaluable to us and allows us to steer CellBender in the direction that you find most useful in your research. If you have an interesting idea or suggestion, please do not hesitate to reach out to us. +A github issue is often the right place to start a conversation about a new feature +or a bug fix. +From there, once we collectively agree on a sense of how to proceed, the repository +can be forked, changes made (using the ``dev`` branch), and a pull request (PR) +can be created. PRs are to target the ``dev`` branch. + If you encounter a bug, please file a detailed github `issue <https://github.com/broadinstitute/CellBender/issues>`_ and we will get back to you as soon as possible. diff --git a/docs/source/introduction/index.rst b/docs/source/introduction/index.rst index 7bcf04a9..77b5525a 100644 --- a/docs/source/introduction/index.rst +++ b/docs/source/introduction/index.rst @@ -13,11 +13,11 @@ Despite the recent progress in improving, optimizing and standardizing droplet-b like scRNA-seq, the complexity of these experiments leaves room for systematic biases and background noise in the raw observations. These nuisances can be traced back to undesirable enzymatic processes that produce spurious library fragments, contamination by -exogeneous or endogenous ambient transcripts, impurity of barcode beads, and barcode swapping during amplification +exogenous or endogenous ambient transcripts, impurity of barcode beads, and barcode swapping during amplification and/or sequencing. The main purpose of CellBender is to take raw gene-by-cell count matrices and molecule-level information produced -by 3rd party pipelines (e.g. CellRanger, Alevin, DropSeq, etc.), to model and remove systematic biases and +by 3rd party pipelines (e.g. CellRanger, Alevin, DropSeq, StarSolo, etc.), to model and remove systematic biases and background noise, and to produce improved estimates of gene expression. As such, CellBender relies on an external tool for primary processing of the raw data obtained from the diff --git a/docs/source/troubleshooting/index.rst b/docs/source/troubleshooting/index.rst index 893f7bb8..54c13507 100644 --- a/docs/source/troubleshooting/index.rst +++ b/docs/source/troubleshooting/index.rst @@ -177,7 +177,8 @@ Answers / Troubleshooting Tips Anecdotally it seems that ATAC data is less noisy than gene expression data to begin with, so some users opt to have CellBender ignore the ATAC features using the input argument ``--exclude-feature-types Peaks``. There is nothing - wrong with doing this. + wrong with doing this. The CellBender output file will still contain the ATAC + Peak features, but they will be identical to the raw input file. .. _a8: @@ -421,6 +422,5 @@ Answers / Troubleshooting Tips This means that the "empty droplet plateau" could not be identified. The most likely explanation is that the level of background RNA is extremely low, and that the value of ``--low-count-threshold`` exceeds this level. This would result in the empty - droplet plateau being excluded from the analysis, which is not advisable. This can be - corrected by decreasing ``--low-count-threshold`` from its default of 15 to a value like 5. - + droplet plateau being excluded from the analysis, which is not advisable. This could + possibly be corrected by decreasing ``--low-count-threshold`` to a value like 1. diff --git a/docs/source/usage/index.rst b/docs/source/usage/index.rst index bb0d5e95..ddcaebf1 100644 --- a/docs/source/usage/index.rst +++ b/docs/source/usage/index.rst @@ -27,7 +27,12 @@ Proposed pipeline ~~~~~~~~~~~~~~~~~ #. Run ``cellranger count`` or some other quantification tool to obtain a count matrix -#. Run ``cellbender remove-background`` +#. Run ``cellbender remove-background`` using the command + +.. code-block:: console + + cellbender remove-background --cuda --input input_file.h5 --output output_file.h5 + #. Perform per-cell quality control checks, and filter out dead / dying cells, as appropriate for your experiment #. Perform all subsequent analyses using the CellBender count matrix. (It is useful @@ -67,18 +72,16 @@ Run ``remove-background`` on the dataset using the following command .. code-block:: console (cellbender) $ cellbender remove-background \ - --input raw_feature_bc_matrix.h5 \ - --output output.h5 \ --cuda \ - --expected-cells 5000 \ - --total-droplets-included 20000 \ - --fpr 0.01 \ - --epochs 150 + --input raw_feature_bc_matrix.h5 \ + --output output.h5 (The output filename "output.h5" can be replaced with a filename of choice.) -This command will produce five output files: +This command will produce nine output files: +* ``output_report.html``: HTML report including plots and commentary, along with any + warnings or suggestions for improved parameter settings. * ``output.h5``: Full count matrix as an h5 file, with background RNA removed. This file contains all the original droplet barcodes. * ``output_filtered.h5``: Filtered count matrix as an h5 file, with background RNA removed. @@ -92,15 +95,23 @@ This command will produce five output files: * ``output.log``: Log file produced by the ``cellbender remove-background`` run. * ``output_metrics.csv``: Metrics describing the run, potentially to be used to flag problematic runs when using CellBender as part of a large-scale automated pipeline. -* ``output_report.html``: HTML report including plots and commentary, along with any - warnings or suggestions for improved parameter settings. * ``ckpt.tar.gz``: Checkpoint file which contains the trained model and the full posterior. +* ``output_posterior.h5``: The full posterior probability of noise counts. This is + not normally used downstream. + +If you are interested in saving space and you do not need to re-run cellbender, +only the ``output_report.html`` and the ``output.h5`` need to be stored. The +``ckpt.tar.gz`` in particular is a large file which can be deleted to save disk +storage space. (However, if you keep this checkpoint file, it can be used to +create a new output count matrix with a different ``--fpr``, without +needing to re-run the lengthy training process. Simply run the command again +with a different ``--fpr`` and specify ``--checkpoint ckpt.tar.gz``.) Quality control checks ~~~~~~~~~~~~~~~~~~~~~~ -* Check the log file for any warnings. -* Check lines 11 -18 in the log file. Ensure that the automatically-determined priors +* Check the log file for any errors or warnings. +* Check lines 13-21 in the log file. Ensure that the automatically-determined priors for cell counts and empty droplet counts match your expectation from the UMI curve. Ensure that the numbers of "probable cells", "additional barcodes", and "empty droplets" are all nonzero and look reasonable. From e3588886003177df498561107deed9eb86cc4fb9 Mon Sep 17 00:00:00 2001 From: kshakir <github@kshakir.org> Date: Tue, 31 Oct 2023 10:44:51 -0400 Subject: [PATCH 03/19] Add WDL input to set number of retries. (#247) --- .../tests/benchmarking/docker_image_check_cuda_status.wdl | 5 ++++- wdl/cellbender_remove_background.wdl | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/cellbender/remove_background/tests/benchmarking/docker_image_check_cuda_status.wdl b/cellbender/remove_background/tests/benchmarking/docker_image_check_cuda_status.wdl index 8763bfe9..91ae2777 100644 --- a/cellbender/remove_background/tests/benchmarking/docker_image_check_cuda_status.wdl +++ b/cellbender/remove_background/tests/benchmarking/docker_image_check_cuda_status.wdl @@ -12,6 +12,8 @@ task run_check_pytorch_cuda_status { Int? hardware_boot_disk_size_GB = 20 String? hardware_zones = "us-east1-d us-east1-c us-central1-a us-central1-c us-west1-b" String? hardware_gpu_type = "nvidia-tesla-t4" + Int? hardware_premptible_tries = 2 + Int? hardware_max_retries = 0 String? nvidia_driver_version = "470.82.01" # need >=465.19.01 for CUDA 11.3 } command { @@ -28,7 +30,8 @@ task run_check_pytorch_cuda_status { gpuCount: 1 gpuType: "${hardware_gpu_type}" nvidiaDriverVersion: "${nvidia_driver_version}" - maxRetries: 0 + preemptible: hardware_premptible_tries + maxRetries: hardware_max_retries } } diff --git a/wdl/cellbender_remove_background.wdl b/wdl/cellbender_remove_background.wdl index 4efb8faf..6f974639 100644 --- a/wdl/cellbender_remove_background.wdl +++ b/wdl/cellbender_remove_background.wdl @@ -58,6 +58,7 @@ task run_cellbender_remove_background_gpu { Int? hardware_disk_size_GB = 50 Int? hardware_boot_disk_size_GB = 20 Int? hardware_preemptible_tries = 2 + Int? hardware_max_retries = 0 Int? hardware_cpu_count = 4 Int? hardware_memory_GB = 32 String? hardware_gpu_type = "nvidia-tesla-t4" @@ -186,7 +187,7 @@ task run_cellbender_remove_background_gpu { nvidiaDriverVersion: "${nvidia_driver_version}" preemptible: hardware_preemptible_tries checkpointFile: "ckpt.tar.gz" - maxRetries: 0 # can be used in case of a PAPI error code 2 failure to install GPU drivers + maxRetries: hardware_max_retries # can be used in case of a PAPI error code 2 failure to install GPU drivers } meta { author: "Stephen Fleming" @@ -214,6 +215,8 @@ task run_cellbender_remove_background_gpu { {help: "Optional file only used by CellBender developers or those trying to benchmark CellBender remove-background on simulated data. Normally, this input would not be supplied."} hardware_preemptible_tries : {help: "If nonzero, CellBender will be run on a preemptible instance, at a lower cost. If preempted, your run will not start from scratch, but will start from a checkpoint that is saved by CellBender and recovered by Cromwell. For example, if hardware_preemptible_tries is 2, your run will attempt twice using preemptible instances, and if the job is preempted both times before completing, it will finish on a non-preemptible machine. The cost savings is significant. The potential drawback is that preemption wastes time."} + hardware_max_retries : + {help: "If nonzero when CellBender exits without success it will be retried. If one also sets the memory_retry_multiplier workflow option, and the exit happens to be detected as an out of memory error, then the retry will also increase the memory allocated to the next run. The potential benefit is that one can start CellBender with less memory, and memory will be increased only when needed. The potential drawback is that the job will be retried even if the error is not a memory error."} checkpoint_mins : {help: "Time in minutes between creation of checkpoint files. Bear in mind that Cromwell copies checkpoints to a bucket every ten minutes."} hardware_gpu_type : From 7a834a41aa121dce3f32ff428facfa8c7f269985 Mon Sep 17 00:00:00 2001 From: alecw <alecw@users.noreply.github.com> Date: Tue, 31 Oct 2023 10:45:41 -0400 Subject: [PATCH 04/19] Move hash computation so that it is recomputed on retry, and now-invalid checkpoint is not loaded. (#258) If number of tries is exhausted, and ELBO tests are still failing, allow to complete anyway (using checkpoint) so that outputs are produced, but exit(1). --- cellbender/remove_background/cli.py | 11 ----------- cellbender/remove_background/run.py | 25 ++++++++++++++++++++++++- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/cellbender/remove_background/cli.py b/cellbender/remove_background/cli.py index ad49c018..29f7928c 100644 --- a/cellbender/remove_background/cli.py +++ b/cellbender/remove_background/cli.py @@ -207,17 +207,6 @@ def setup_and_logging(args): + ' '.join(['cellbender', 'remove-background'] + sys.argv[2:])) logger.info("CellBender " + get_version()) - # Set up checkpointing by creating a unique workflow hash. - hashcode = create_workflow_hashcode( - module_path=os.path.dirname(cellbender.__file__), - args_to_remove=(['output_file', 'fpr', 'input_checkpoint_tarball', 'debug', - 'posterior_batch_size', 'checkpoint_min', 'truth_file', - 'posterior_regularization', 'cdf_threshold_q', 'prq_alpha', - 'estimator', 'use_multiprocessing_estimation', 'cpu_threads'] - + (['epochs'] if args.constant_learning_rate else [])), - args=args)[:10] - args.checkpoint_filename = hashcode # store this in args - logger.info(f'(Workflow hash {hashcode})') return args, file_handler diff --git a/cellbender/remove_background/run.py b/cellbender/remove_background/run.py index 7b777e4e..42cf5b4e 100644 --- a/cellbender/remove_background/run.py +++ b/cellbender/remove_background/run.py @@ -1,5 +1,6 @@ """Single run of remove-background, given input arguments.""" +import cellbender from cellbender.remove_background.model import RemoveBackgroundPyroModel from cellbender.remove_background.data.dataset import get_dataset_obj, \ SingleCellRNACountsDataset @@ -21,6 +22,7 @@ from cellbender.remove_background.sparse_utils import csr_set_rows_to_zero from cellbender.remove_background.data.io import write_matrix_to_cellranger_h5 from cellbender.remove_background.report import run_notebook_make_html, plot_summary +from cellbender.remove_background.checkpoint import create_workflow_hashcode import pyro from pyro.infer import SVI, JitTraceEnum_ELBO, JitTrace_ELBO, \ @@ -59,6 +61,22 @@ def run_remove_background(args: argparse.Namespace) -> Posterior: """ + # Set up checkpointing by creating a unique workflow hash. + hashcode = create_workflow_hashcode( + module_path=os.path.dirname(cellbender.__file__), + args_to_remove=(['output_file', 'fpr', 'input_checkpoint_tarball', 'debug', + 'posterior_batch_size', 'checkpoint_min', 'truth_file', + 'posterior_regularization', 'cdf_threshold_q', 'prq_alpha', + 'estimator', 'use_multiprocessing_estimation', 'cpu_threads', + # The following settings do not affect the results, and can change when retrying, + # so remove them. + 'epoch_elbo_fail_fraction', 'final_elbo_fail_fraction', + 'num_failed_attempts', 'checkpoint_filename'] + + (['epochs'] if args.constant_learning_rate else [])), + args=args)[:10] + args.checkpoint_filename = hashcode # store this in args + logger.info(f'(Workflow hash {hashcode})') + # Handle initial random state. pyro.util.set_rng_seed(consts.RANDOM_SEED) if torch.cuda.is_available(): @@ -771,7 +789,12 @@ def run_inference(dataset_obj: SingleCellRNACountsDataset, sys.exit(0) else: logger.info(f'No more attempts are specified by --num-training-tries. ' - f'Therefore the workflow will abort here.') + f'Therefore the workflow will run once more without ELBO restrictions.') + args.epoch_elbo_fail_fraction = None + args.final_elbo_fail_fraction = None + run_remove_background(args) # start from scratch + # non-zero exit status in order to draw user's attention to the fact that ELBO tests + # were never satisfied. sys.exit(1) logger.info("Inference procedure complete.") From cf71148b952e8f6ed087e56a413c44c61b3c4768 Mon Sep 17 00:00:00 2001 From: Stephen Fleming <sjfleming@users.noreply.github.com> Date: Tue, 31 Oct 2023 10:46:16 -0400 Subject: [PATCH 05/19] Bug fix for WDL using MTX input (#246) --- wdl/cellbender_remove_background.wdl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/wdl/cellbender_remove_background.wdl b/wdl/cellbender_remove_background.wdl index 6f974639..f7507ec3 100644 --- a/wdl/cellbender_remove_background.wdl +++ b/wdl/cellbender_remove_background.wdl @@ -125,8 +125,15 @@ task run_cellbender_remove_background_gpu { [ -f $dir/$name ] || mv ~{genes_file} $dir/$name fi + # use the directory as the input in the case of an MTX file + if [[ "~{input_file_unfiltered}" == *.mtx* ]]; then + input=$(dirname ~{input_file_unfiltered}) + else + input=~{input_file_unfiltered} + fi + cellbender remove-background \ - --input "~{input_file_unfiltered}" \ + --input $input \ --output "~{sample_name}_out.h5" \ --cuda \ ~{"--checkpoint " + checkpoint_file} \ From 322971d81eb8ae745601515aa15227cc7af6d951 Mon Sep 17 00:00:00 2001 From: Stephen Fleming <sjfleming@users.noreply.github.com> Date: Tue, 31 Oct 2023 10:47:02 -0400 Subject: [PATCH 06/19] Memory-efficient posterior generation (#263) --- cellbender/remove_background/estimation.py | 45 +++----------- cellbender/remove_background/posterior.py | 61 ++++++++++--------- cellbender/remove_background/sparse_utils.py | 6 +- .../remove_background/tests/test_dataprep.py | 6 +- .../tests/test_sparse_utils.py | 6 +- 5 files changed, 50 insertions(+), 74 deletions(-) diff --git a/cellbender/remove_background/estimation.py b/cellbender/remove_background/estimation.py index 24437248..371a7fa0 100644 --- a/cellbender/remove_background/estimation.py +++ b/cellbender/remove_background/estimation.py @@ -463,11 +463,9 @@ def estimate_noise(self, if use_multiple_processes: logger.info('Dividing dataset into chunks of genes') - chunk_logic_list = list( - self._gene_chunk_iterator( - noise_log_prob_coo=noise_log_prob_coo, - n_chunks=n_chunks, - ) + chunk_logic_list = self._gene_chunk_iterator( + noise_log_prob_coo=noise_log_prob_coo, + n_chunks=n_chunks, ) logger.info('Computing the output in asynchronous chunks in parallel...') @@ -538,10 +536,9 @@ def estimate_noise(self, def _gene_chunk_iterator(self, noise_log_prob_coo: sp.coo_matrix, n_chunks: int) \ - -> Generator[np.ndarray, None, None]: - """Yields chunks of the posterior that can be treated as independent, - from the standpoint of MCKP count estimation. That is, they contain all - matrix entries for any genes they include. + -> List[np.ndarray]: + """Return a list of logical (size m) arrays used to select gene chunks + on which to compute the MCKP estimate. These chunks are independent. Args: noise_log_prob_coo: Full noise log prob posterior COO @@ -551,36 +548,14 @@ def _gene_chunk_iterator(self, Logical array which indexes elements of coo posterior for the chunk """ - # TODO this generator is way too slow - - # approximate number of entries in a chunk - # approx_chunk_entries = (noise_log_prob_coo.data.size - 1) // n_chunks - # get gene annotations _, genes = self.index_converter.get_ng_indices(m_inds=noise_log_prob_coo.row) genes_series = pd.Series(genes) - # things we need to keep track of for each chunk - # current_chunk_genes = [] - # entry_logic = np.zeros(noise_log_prob_coo.data.size, dtype=bool) - - # TODO eliminate for loop to speed this up - # take the list of genes from the coo, sort it, and divide it evenly - # somehow break ties for genes overlapping boundaries of divisions - sorted_genes = np.sort(genes) - gene_arrays = np.array_split(sorted_genes, n_chunks) - last_gene_set = {} - for gene_array in gene_arrays: - gene_set = set(gene_array) - gene_set = gene_set.difference(last_gene_set) # only the new stuff - # if there is a second chunk, make sure there is a gene unique to it - if (n_chunks > 1) and (len(gene_set) == len(set(genes))): # all genes in first set - # this mainly exists for tests - gene_set = gene_set - {gene_arrays[-1][-1]} - last_gene_set = gene_set - entry_logic = genes_series.isin(gene_set).values - if sum(entry_logic) > 0: - yield entry_logic + gene_chunk_arrays = np.array_split(np.arange(self.index_converter.total_n_genes), n_chunks) + + gene_logic_arrays = [genes_series.isin(x).values for x in gene_chunk_arrays] + return gene_logic_arrays def _chunk_estimate_noise(self, noise_log_prob_coo: sp.coo_matrix, diff --git a/cellbender/remove_background/posterior.py b/cellbender/remove_background/posterior.py index 37587026..6aaeefa9 100644 --- a/cellbender/remove_background/posterior.py +++ b/cellbender/remove_background/posterior.py @@ -451,7 +451,7 @@ def _get_cell_noise_count_posterior_coo( f'accurate for your dataset.') raise RuntimeError('Zero cells found!') - dataloader_index_to_analyzed_bc_index = np.where(cell_logic)[0] + dataloader_index_to_analyzed_bc_index = torch.where(torch.tensor(cell_logic))[0] cell_data_loader = DataLoader( count_matrix[cell_logic], empty_drop_dataset=None, @@ -468,6 +468,12 @@ def _get_cell_noise_count_posterior_coo( log_probs = [] ind = 0 n_minibatches = len(cell_data_loader) + analyzed_gene_inds = torch.tensor(self.analyzed_gene_inds.copy()) + if analyzed_bcs_only: + barcode_inds = torch.tensor(self.dataset_obj.analyzed_barcode_inds.copy()) + else: + barcode_inds = torch.tensor(self.barcode_inds.copy()) + nonzero_noise_offset_dict = {} logger.info('Computing posterior noise count probabilities in mini-batches.') @@ -505,46 +511,43 @@ def _get_cell_noise_count_posterior_coo( ) # Get the original gene index from gene index in the trimmed dataset. - genes_i = self.analyzed_gene_inds[genes_i_analyzed] + genes_i = analyzed_gene_inds[genes_i_analyzed.cpu()] # Barcode index in the dataloader. - bcs_i = bcs_i_chunk + ind + bcs_i = (bcs_i_chunk + ind).cpu() # Obtain the real barcode index since we only use cells. bcs_i = dataloader_index_to_analyzed_bc_index[bcs_i] # Translate chunk barcode inds to overall inds. - if analyzed_bcs_only: - bcs_i = self.dataset_obj.analyzed_barcode_inds[bcs_i] - else: - bcs_i = self.barcode_inds[bcs_i] + bcs_i = barcode_inds[bcs_i] # Add sparse matrix values to lists. - try: - bcs.extend(bcs_i.tolist()) - genes.extend(genes_i.tolist()) - c.extend(c_i.tolist()) - log_probs.extend(log_prob_i.tolist()) - c_offset.extend(noise_count_offset_NG[bcs_i_chunk, genes_i_analyzed] - .detach().cpu().numpy()) - except TypeError as e: - # edge case of a single value - bcs.append(bcs_i) - genes.append(genes_i) - c.append(c_i) - log_probs.append(log_prob_i) - c_offset.append(noise_count_offset_NG[bcs_i_chunk, genes_i_analyzed] - .detach().cpu().numpy()) + bcs.append(bcs_i.detach()) + genes.append(genes_i.detach()) + c.append(c_i.detach().cpu()) + log_probs.append(log_prob_i.detach().cpu()) + + # Update offset dict with any nonzeros. + nonzero_offset_inds, nonzero_noise_count_offsets = dense_to_sparse_op_torch( + noise_count_offset_NG[bcs_i_chunk, genes_i_analyzed].detach().flatten(), + ) + m_i = self.index_converter.get_m_indices(cell_inds=bcs_i, gene_inds=genes_i) + + nonzero_noise_offset_dict.update( + dict(zip(m_i[nonzero_offset_inds.detach().cpu()].tolist(), + nonzero_noise_count_offsets.detach().cpu().tolist())) + ) + c_offset.append(noise_count_offset_NG[bcs_i_chunk, genes_i_analyzed].detach().cpu()) # Increment barcode index counter. ind += data.shape[0] # Same as data_loader.batch_size - # Convert the lists to numpy arrays. - log_probs = np.array(log_probs, dtype=float) - c = np.array(c, dtype=np.uint32) - barcodes = np.array(bcs, dtype=np.uint64) # uint32 is too small! - genes = np.array(genes, dtype=np.uint64) # use same as above for IndexConverter - noise_count_offsets = np.array(c_offset, dtype=np.uint32) + # Concatenate lists. + log_probs = torch.cat(log_probs) + c = torch.cat(c) + barcodes = torch.cat(bcs) + genes = torch.cat(genes) # Translate (barcode, gene) inds to 'm' format index. m = self.index_converter.get_m_indices(cell_inds=barcodes, gene_inds=genes) @@ -554,8 +557,6 @@ def _get_cell_noise_count_posterior_coo( (log_probs, (m, c)), shape=[np.prod(self.count_matrix_shape), n_counts_max], ) - noise_offset_dict = dict(zip(m, noise_count_offsets)) - nonzero_noise_offset_dict = {k: v for k, v in noise_offset_dict.items() if (v > 0)} self._noise_count_posterior_coo_offsets = nonzero_noise_offset_dict return self._noise_count_posterior_coo diff --git a/cellbender/remove_background/sparse_utils.py b/cellbender/remove_background/sparse_utils.py index 4a0f26fa..ca31329e 100644 --- a/cellbender/remove_background/sparse_utils.py +++ b/cellbender/remove_background/sparse_utils.py @@ -10,7 +10,7 @@ @torch.no_grad() def dense_to_sparse_op_torch(t: torch.Tensor, tensor_for_nonzeros: Optional[torch.Tensor] = None) \ - -> Tuple[np.ndarray, ...]: + -> Tuple[torch.Tensor, ...]: """Converts dense matrix to sparse COO format tuple of numpy arrays (*indices, data) Args: @@ -28,9 +28,9 @@ def dense_to_sparse_op_torch(t: torch.Tensor, tensor_for_nonzeros = t nonzero_inds_tuple = torch.nonzero(tensor_for_nonzeros, as_tuple=True) - nonzero_values = t[nonzero_inds_tuple].flatten() + nonzero_values = t[nonzero_inds_tuple].flatten().clone() - return tuple([ten.cpu().numpy() for ten in (nonzero_inds_tuple + (nonzero_values,))]) + return nonzero_inds_tuple + (nonzero_values,) def log_prob_sparse_to_dense(coo: sp.coo_matrix) -> np.ndarray: diff --git a/cellbender/remove_background/tests/test_dataprep.py b/cellbender/remove_background/tests/test_dataprep.py index 8fcb1562..5d11380c 100644 --- a/cellbender/remove_background/tests/test_dataprep.py +++ b/cellbender/remove_background/tests/test_dataprep.py @@ -75,9 +75,9 @@ def test_dataloader_sorting(simulated_dataset, cuda): bcs_i = loader.unsort_inds(bcs_i) # Add sparse matrix values to lists. - barcodes.append(bcs_i) - genes.append(genes_i) - counts.append(counts_i) + barcodes.append(bcs_i.detach().cpu()) + genes.append(genes_i.detach().cpu()) + counts.append(counts_i.detach().cpu()) # Increment barcode index counter. ind += data.shape[0] # Same as data_loader.batch_size diff --git a/cellbender/remove_background/tests/test_sparse_utils.py b/cellbender/remove_background/tests/test_sparse_utils.py index 01230da8..2f2e13ea 100644 --- a/cellbender/remove_background/tests/test_sparse_utils.py +++ b/cellbender/remove_background/tests/test_sparse_utils.py @@ -76,9 +76,9 @@ def test_dense_to_sparse_op_torch(simulated_dataset, cuda): bcs_i = data_loader.unsort_inds(bcs_i) # Add sparse matrix values to lists. - barcodes.append(bcs_i) - genes.append(genes_i) - counts.append(counts_i) + barcodes.append(bcs_i.detach().cpu()) + genes.append(genes_i.detach().cpu()) + counts.append(counts_i.detach().cpu()) # Increment barcode index counter. ind += data.shape[0] # Same as data_loader.batch_size From 12b47582d0eafc698994d6f24f7289449df44568 Mon Sep 17 00:00:00 2001 From: Stephen Fleming <sjfleming@users.noreply.github.com> Date: Tue, 31 Oct 2023 10:47:36 -0400 Subject: [PATCH 07/19] Fix posterior and estimator integer overflow bugs on Windows (#259) --- .github/workflows/run_pytest.yml | 6 ++-- cellbender/remove_background/checkpoint.py | 2 +- cellbender/remove_background/estimation.py | 10 +++--- cellbender/remove_background/posterior.py | 4 +-- .../remove_background/tests/conftest.py | 24 +++++++++++-- .../tests/test_estimation.py | 23 ++++++++++++ .../remove_background/tests/test_posterior.py | 35 ++++++++++++++----- 7 files changed, 83 insertions(+), 21 deletions(-) diff --git a/.github/workflows/run_pytest.yml b/.github/workflows/run_pytest.yml index 37e652b0..7c8c6620 100644 --- a/.github/workflows/run_pytest.yml +++ b/.github/workflows/run_pytest.yml @@ -1,4 +1,4 @@ -# Run cellbender's tests +# Run cellbender test suite name: 'pytest' @@ -7,11 +7,13 @@ on: pull_request jobs: build: - runs-on: 'ubuntu-latest' strategy: matrix: + os: ['ubuntu-latest', 'windows-latest'] python-version: ['3.7'] + runs-on: ${{ matrix.os }} + steps: - name: 'Checkout repo' uses: actions/checkout@v3 diff --git a/cellbender/remove_background/checkpoint.py b/cellbender/remove_background/checkpoint.py index 5b0903de..206737be 100644 --- a/cellbender/remove_background/checkpoint.py +++ b/cellbender/remove_background/checkpoint.py @@ -297,7 +297,7 @@ def make_tarball(files: List[str], tarball_name: str) -> bool: for file in files: # without arcname, unpacking results in unpredictable file locations! tar.add(file, arcname=os.path.basename(file)) - os.rename(tarball_name + '.tmp', tarball_name) + os.replace(tarball_name + '.tmp', tarball_name) return True diff --git a/cellbender/remove_background/estimation.py b/cellbender/remove_background/estimation.py index 371a7fa0..b4866d2f 100644 --- a/cellbender/remove_background/estimation.py +++ b/cellbender/remove_background/estimation.py @@ -218,7 +218,7 @@ def _estimation_array_to_csr(index_converter, data: np.ndarray, m: np.ndarray, noise_offsets: Optional[Dict[int, int]], - dtype=np.int64) -> sp.csr_matrix: + dtype=np.int) -> sp.csr_matrix: """Say you have point estimates for each count matrix element (data) and you have the 'm'-indices for each value (m). This returns a CSR matrix that has the shape of the count matrix, where duplicate entries have @@ -229,7 +229,7 @@ def _estimation_array_to_csr(index_converter, a flat format, indexed by 'm'. m: Array of the same length as data, where each entry is an m-index. noise_offsets: Noise count offset values keyed by 'm'. - dtype: Data type for sparse matrix. Int32 is too small for 'm' indices. + dtype: Data type for values of sparse matrix Results: noise_csr: Noise point estimate, as a CSR sparse matrix. @@ -238,7 +238,7 @@ def _estimation_array_to_csr(index_converter, row, col = index_converter.get_ng_indices(m_inds=m) if noise_offsets is not None: data = data + np.array([noise_offsets.get(i, 0) for i in m]) - coo = sp.coo_matrix((data.astype(dtype), (row.astype(dtype), col.astype(dtype))), + coo = sp.coo_matrix((data.astype(dtype), (row.astype(np.uint64), col.astype(np.uint8))), shape=index_converter.matrix_shape, dtype=dtype) coo.sum_duplicates() return coo.tocsr() @@ -785,7 +785,7 @@ def apply_function_dense_chunks(noise_log_prob_coo: sp.coo_matrix, """ array_length = len(np.unique(noise_log_prob_coo.row)) - m = np.zeros(array_length) + m = np.zeros(array_length, dtype=np.uint64) out = np.zeros(array_length) a = 0 @@ -804,7 +804,7 @@ def apply_function_dense_chunks(noise_log_prob_coo: sp.coo_matrix, out[a:(a + len_s)] = s.detach().cpu().numpy() a = a + len_s - return {'m': m.astype(int), 'result': out} + return {'m': m, 'result': out} def pandas_grouped_apply(coo: sp.coo_matrix, diff --git a/cellbender/remove_background/posterior.py b/cellbender/remove_background/posterior.py index 6aaeefa9..c4217130 100644 --- a/cellbender/remove_background/posterior.py +++ b/cellbender/remove_background/posterior.py @@ -555,7 +555,7 @@ def _get_cell_noise_count_posterior_coo( # Put the counts into a sparse csr_matrix. self._noise_count_posterior_coo = sp.coo_matrix( (log_probs, (m, c)), - shape=[np.prod(self.count_matrix_shape), n_counts_max], + shape=[np.prod(self.count_matrix_shape, dtype=np.uint64), n_counts_max], ) self._noise_count_posterior_coo_offsets = nonzero_noise_offset_dict return self._noise_count_posterior_coo @@ -1528,7 +1528,7 @@ def get_m_indices(self, cell_inds: np.ndarray, gene_inds: np.ndarray) -> np.ndar if not ((gene_inds >= 0) & (gene_inds < self.total_n_genes)).all(): raise ValueError(f'Requested gene_inds out of range: ' f'{gene_inds[(gene_inds < 0) | (gene_inds >= self.total_n_genes)]}') - return cell_inds * self.total_n_genes + gene_inds + return cell_inds.astype(np.uint64) * self.total_n_genes + gene_inds.astype(np.uint64) def get_ng_indices(self, m_inds: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: """Given a list of 'm' index values, return two arrays: cell index values diff --git a/cellbender/remove_background/tests/conftest.py b/cellbender/remove_background/tests/conftest.py index 8bafa2da..6a430107 100644 --- a/cellbender/remove_background/tests/conftest.py +++ b/cellbender/remove_background/tests/conftest.py @@ -15,12 +15,32 @@ USE_CUDA = torch.cuda.is_available() -def sparse_matrix_equal(mat1: sp.csc_matrix, - mat2: sp.csc_matrix): +def sparse_matrix_equal(mat1, mat2): """Fast assertion that sparse matrices are equal""" + if type(mat1) == sp.coo_matrix: + return coo_equal(mat1, mat2) + elif (type(mat1) == sp.csc_matrix) or (type(mat1) == sp.csr_matrix): + return csc_or_csr_equal(mat1, mat2) + else: + raise ValueError(f"Error with test functions: sparse_matrix_equal() was called with a {type(mat1)}") + + +def csc_or_csr_equal(mat1: sp.csc_matrix, + mat2: sp.csc_matrix): + """Fast assertion that CSC sparse matrices are equal""" return (mat1 != mat2).sum() == 0 +def coo_equal(mat1: sp.csc_matrix, + mat2: sp.csc_matrix): + """Fast assertion that COO sparse matrices are equal""" + return ( + ((mat1.data != mat2.data).sum() == 0) + and ((mat1.row != mat2.row).sum() == 0) + and ((mat1.col != mat2.col).sum() == 0) + ) + + def tensors_equal(a: torch.Tensor, b: torch.Tensor): """Assertion that torch tensors are equal for each element""" diff --git a/cellbender/remove_background/tests/test_estimation.py b/cellbender/remove_background/tests/test_estimation.py index 528ab675..c1cb931e 100644 --- a/cellbender/remove_background/tests/test_estimation.py +++ b/cellbender/remove_background/tests/test_estimation.py @@ -81,6 +81,29 @@ def log_prob_coo(request, log_prob_coo_base) \ raise ValueError(f'Test writing error: requested "{request.param}" log_prob_coo') +def test_mean_massive_m(log_prob_coo): + """Sets up a posterior COO with massive m values that are > max(int32). + Will trigger github issue #252 if a bug exists, no assertion necessary. + """ + + coo = log_prob_coo['coo'] + greater_than_max_int32 = 2200000000 + new_row = coo.row.astype(np.int64) + greater_than_max_int32 + new_shape = (coo.shape[0] + greater_than_max_int32, coo.shape[1]) + new_coo = sp.coo_matrix((coo.data, (new_row, coo.col)), + shape=new_shape) + offset_dict = {k + greater_than_max_int32: v for k, v in log_prob_coo['offsets'].items()} + + # this is just a shim + converter = IndexConverter(total_n_cells=2, + total_n_genes=new_coo.shape[0]) + + # set up and estimate + estimator = Mean(index_converter=converter) + noise_csr = estimator.estimate_noise(noise_log_prob_coo=new_coo, + noise_offsets=offset_dict) + + @pytest.fixture(scope='module', params=['exact', 'filtered', 'unsorted']) def mckp_log_prob_coo(request, log_prob_coo_base) \ -> Dict[str, Union[sp.coo_matrix, np.ndarray, Dict[int, int]]]: diff --git a/cellbender/remove_background/tests/test_posterior.py b/cellbender/remove_background/tests/test_posterior.py index e5382b3b..04b766ed 100644 --- a/cellbender/remove_background/tests/test_posterior.py +++ b/cellbender/remove_background/tests/test_posterior.py @@ -368,23 +368,35 @@ def test_compute_mean_target_removal_as_function(log_prob_coo, fpr, per_gene, cu @pytest.mark.parametrize('blank_noise_offsets', [False, True], ids=['', 'no_noise_offsets']) -def test_save_and_load(tmpdir_factory, blank_noise_offsets): +@pytest.mark.parametrize('m', [1000, 2200000000], ids=['small', 'big']) +def test_save_and_load(tmpdir_factory, blank_noise_offsets, m): """Test that a round trip through save and load gives the same thing""" tmp_dir = tmpdir_factory.mktemp('posterior') filename = tmp_dir.join('posterior.h5') - m = 1000 n = 20 + num_nonzeros = 1000 posterior = Posterior(dataset_obj=None, vi_model=None) # blank - posterior_coo = sp.random(m, n, density=0.1, format='coo', dtype=float) - posterior_coo2 = sp.random(m, n, density=0.08, format='coo', dtype=float) + # old way that cannot handle large m + # posterior_coo = sp.random(m, n, density=0.1, format='coo', dtype=float) + # posterior_coo2 = sp.random(m, n, density=0.08, format='coo', dtype=float) + + m_array = np.random.randint(low=0, high=m, size=num_nonzeros - 1, dtype=np.uint64) + m_array = np.concatenate([m_array, np.array(m - 1, dtype=np.uint64)], axis=None) + n_array = np.random.randint(low=0, high=n, size=num_nonzeros) + val_array = np.random.rand(num_nonzeros) * -10 + val_array2 = np.random.rand(num_nonzeros) * -5 + + posterior_coo = sp.coo_matrix((val_array, (m_array, n_array)), shape=(m, n)) + posterior_coo2 = sp.coo_matrix((val_array2, (m_array, n_array)), shape=(m, n)) + if blank_noise_offsets: noise_offsets = {} else: - noise_offsets = dict(zip(np.random.randint(low=0, high=(m - 1), size=10), + noise_offsets = dict(zip(np.random.randint(low=0, high=(m - 1), size=10, dtype=np.uint64), np.random.randint(low=1, high=5, size=10))) kwargs = {'a': 'b', 'c': 1} kwargs2 = {'a': 'method', 'c': 1} @@ -396,7 +408,7 @@ def test_save_and_load(tmpdir_factory, blank_noise_offsets): posterior._noise_count_regularized_posterior_coo = posterior_coo2 posterior._noise_count_regularized_posterior_kwargs = kwargs2 posterior._latents = {'p': np.random.randn(100), 'd': np.random.randn(100)} - posterior.index_converter = IndexConverter(total_n_cells=1000, total_n_genes=1000) + posterior.index_converter = IndexConverter(total_n_cells=max(1000, m // 1000 + 1), total_n_genes=1000) # save posterior.save(file=str(filename)) @@ -406,9 +418,14 @@ def test_save_and_load(tmpdir_factory, blank_noise_offsets): posterior2.load(file=str(filename)) # check - for attr in ['_noise_count_posterior_coo', '_noise_count_posterior_coo_offsets', - '_noise_count_posterior_kwargs', '_noise_count_regularized_posterior_coo', - '_noise_count_regularized_posterior_kwargs', '_latents']: + for attr in [ + '_noise_count_posterior_coo', + '_noise_count_posterior_coo_offsets', + '_noise_count_posterior_kwargs', + '_noise_count_regularized_posterior_coo', + '_noise_count_regularized_posterior_kwargs', + '_latents' + ]: val1 = getattr(posterior, attr) val2 = getattr(posterior2, attr) print(f'{attr} ===================') From be360063c9f59e5fedcaac86134fb928bd0d4be4 Mon Sep 17 00:00:00 2001 From: Stephen Fleming <sjfleming@users.noreply.github.com> Date: Tue, 31 Oct 2023 10:48:29 -0400 Subject: [PATCH 08/19] Move from setup.py to pyproject.toml (#240) --- MANIFEST.in | 5 ++- build_docker_release.sh | 2 +- cellbender/VERSION.txt | 1 + cellbender/__init__.py | 4 ++- cellbender/base_cli.py | 7 +--- pyproject.toml | 45 ++++++++++++++++++++++++ requirements-dev.txt | 2 ++ setup.py | 77 ----------------------------------------- 8 files changed, 57 insertions(+), 86 deletions(-) create mode 100644 cellbender/VERSION.txt create mode 100644 pyproject.toml create mode 100644 requirements-dev.txt delete mode 100644 setup.py diff --git a/MANIFEST.in b/MANIFEST.in index 66e89a17..679690c5 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,7 @@ include README.rst include LICENSE include requirements.txt -include requirements-rtd.txt \ No newline at end of file +include requirements-rtd.txt +include requirements-dev.txt +include cellbender/VERSION.txt +include cellbender/remove_background/report.ipynb \ No newline at end of file diff --git a/build_docker_release.sh b/build_docker_release.sh index ff0511fc..532bffe0 100755 --- a/build_docker_release.sh +++ b/build_docker_release.sh @@ -1,6 +1,6 @@ #!/bin/bash -tag=$(cat cellbender/__init__.py | sed -e 's?__version__ = ??' | sed "s/^'\(.*\)'$/\1/") +tag=$(cat cellbender/VERSION.txt) release=v${tag} docker build \ diff --git a/cellbender/VERSION.txt b/cellbender/VERSION.txt new file mode 100644 index 00000000..9325c3cc --- /dev/null +++ b/cellbender/VERSION.txt @@ -0,0 +1 @@ +0.3.0 \ No newline at end of file diff --git a/cellbender/__init__.py b/cellbender/__init__.py index 0404d810..9fdd33d6 100644 --- a/cellbender/__init__.py +++ b/cellbender/__init__.py @@ -1 +1,3 @@ -__version__ = '0.3.0' +from .base_cli import get_version + +__version__ = get_version() diff --git a/cellbender/base_cli.py b/cellbender/base_cli.py index bf5a71b3..fca8eb7d 100644 --- a/cellbender/base_cli.py +++ b/cellbender/base_cli.py @@ -23,12 +23,7 @@ def read(rel_path): def get_version() -> str: - for line in read('__init__.py').splitlines(): - if line.startswith('__version__'): - delim = '"' if '"' in line else "'" - return line.split(delim)[1] - else: - raise RuntimeError("Unable to find version string.") + return read('VERSION.txt').splitlines()[0] class AbstractCLI(ABC): diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..6a0d36d2 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,45 @@ +[build-system] +requires = ["setuptools>=61.2"] +build-backend = "setuptools.build_meta" + +[project] +name = "cellbender" +authors = [{name = "Stephen Fleming"}, {name = "Mehrtash Babadi"}] +license = {text = "BSD (3-Clause)"} +description = "A software package for eliminating technical artifacts from high-throughput single-cell RNA sequencing (scRNA-seq) data" +keywords = ["scRNA-seq", "bioinformatics"] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: BSD License", + "Programming Language :: Python :: 3.7", + "Topic :: Scientific/Engineering :: Bio-Informatics", +] +dynamic = ["version", "dependencies", "optional-dependencies"] + +[project.readme] +file = "README.rst" +content-type = "text/x-rst" + +[project.urls] +Homepage = "http://github.com/broadinstitute/CellBender" +Documentation = "http://cellbender.readthedocs.io" + +[project.scripts] +cellbender = "cellbender.base_cli:main" + +[tool.setuptools] +zip-safe = false +include-package-data = true + +[tool.setuptools.packages] +find = {namespaces = false} + +[tool.setuptools.dynamic] +version = {attr = "cellbender.__version__"} +dependencies = {file = ["requirements.txt"]} +optional-dependencies.dev = {file = ["requirements-dev.txt"]} +optional-dependencies.docs = {file = ["requirements-rtd.txt"]} + +[tool.setuptools.package-data] +"*" = ["cellbender.remove_background.report.ipynb", "cellbender.VERSION.txt"] diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 00000000..3257b82a --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,2 @@ +pytest +scikit-learn diff --git a/setup.py b/setup.py deleted file mode 100644 index 106fa57c..00000000 --- a/setup.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python - -import os -import setuptools -import codecs -from typing import List - - -def read(rel_path): - here = os.path.abspath(os.path.dirname(__file__)) - with codecs.open(os.path.join(here, rel_path), 'r') as fp: - return fp.read() - - -def get_version() -> str: - for line in read('cellbender/__init__.py').splitlines(): - if line.startswith('__version__'): - delim = '"' if '"' in line else "'" - return line.split(delim)[1] - else: - raise RuntimeError("Unable to find version string.") - - -def readme() -> str: - with open('README.rst') as f: - return f.read() - - -def _readlines(filename, filebase=''): - with open(os.path.join(filebase, filename)) as f: - lines = f.readlines() - return lines - - -def get_requirements() -> List[str]: - requirements = _readlines('requirements.txt') - if 'READTHEDOCS' in os.environ: - requirements.extend(get_rtd_requirements()) - return requirements - - -def get_rtd_requirements() -> List[str]: - requirements = _readlines('requirements-rtd.txt') - return requirements - - -setuptools.setup( - name='cellbender', - version=get_version(), - description='A software package for eliminating technical artifacts from ' - 'high-throughput single-cell RNA sequencing (scRNA-seq) data', - long_description=readme(), - long_description_content_type='text/x-rst', - classifiers=[ - 'Development Status :: 4 - Beta', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: BSD License', - 'Programming Language :: Python :: 3.7', - 'Topic :: Scientific/Engineering :: Bio-Informatics', - ], - keywords='scRNA-seq bioinformatics', - url='http://github.com/broadinstitute/CellBender', - author='Stephen Fleming, Mehrtash Babadi', - license='BSD (3-Clause)', - packages=setuptools.find_packages(), - install_requires=get_requirements(), - extras_require={ - "dev": ["pytest", "scikit-learn"], - "docs": get_rtd_requirements(), - }, - entry_points={ - 'console_scripts': ['cellbender=cellbender.base_cli:main'], - }, - include_package_data=True, - package_data={'': ['*.ipynb']}, # include the report template - zip_safe=False -) From 084194b4612623976cb5a46cd1b47f4afbe6fdec Mon Sep 17 00:00:00 2001 From: Stephen Fleming <sjfleming@users.noreply.github.com> Date: Tue, 31 Oct 2023 11:55:37 -0400 Subject: [PATCH 09/19] Fix bugs with report generation across platforms (#302) --- cellbender/remove_background/posterior.py | 11 ++++++++-- cellbender/remove_background/report.py | 25 ++++++++++++++--------- cellbender/remove_background/run.py | 1 + 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/cellbender/remove_background/posterior.py b/cellbender/remove_background/posterior.py index c4217130..d99e5338 100644 --- a/cellbender/remove_background/posterior.py +++ b/cellbender/remove_background/posterior.py @@ -1518,7 +1518,9 @@ def __repr__(self): f'\n\ttotal_n_genes: {self.total_n_genes}' f'\n\tmatrix_shape: {self.matrix_shape}') - def get_m_indices(self, cell_inds: np.ndarray, gene_inds: np.ndarray) -> np.ndarray: + def get_m_indices(self, + cell_inds: Union[np.ndarray, torch.Tensor], + gene_inds: Union[np.ndarray, torch.Tensor]) -> Union[np.ndarray, torch.Tensor]: """Given arrays of cell indices and gene indices, suitable for a sparse matrix, convert them to 'm' index values. """ @@ -1528,7 +1530,12 @@ def get_m_indices(self, cell_inds: np.ndarray, gene_inds: np.ndarray) -> np.ndar if not ((gene_inds >= 0) & (gene_inds < self.total_n_genes)).all(): raise ValueError(f'Requested gene_inds out of range: ' f'{gene_inds[(gene_inds < 0) | (gene_inds >= self.total_n_genes)]}') - return cell_inds.astype(np.uint64) * self.total_n_genes + gene_inds.astype(np.uint64) + if type(cell_inds) == np.ndarray: + return cell_inds.astype(np.uint64) * self.total_n_genes + gene_inds.astype(np.uint64) + elif type(cell_inds) == torch.Tensor: + return cell_inds.type(torch.int64) * self.total_n_genes + gene_inds.type(torch.int64) + else: + raise ValueError('IndexConverter.get_m_indices received cell_inds of unkown object type') def get_ng_indices(self, m_inds: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: """Given a list of 'm' index values, return two arrays: cell index values diff --git a/cellbender/remove_background/report.py b/cellbender/remove_background/report.py index f1a34cb9..dfb5f903 100644 --- a/cellbender/remove_background/report.py +++ b/cellbender/remove_background/report.py @@ -16,6 +16,7 @@ import subprocess import datetime import os +import shutil import logging from typing import Dict, Optional @@ -42,26 +43,30 @@ def _run_notebook(file): - subprocess.run(f'cp {file} tmp.report.ipynb', shell=True) + shutil.copy(file, 'tmp.report.ipynb') subprocess.run(run_notebook_str(file='tmp.report.ipynb'), shell=True) - subprocess.run(f'rm tmp.report.ipynb', shell=True) + os.remove('tmp.report.ipynb') return 'tmp.report.nbconvert.ipynb' def _to_html(file, output) -> str: subprocess.run(to_html_str(file=file, output=output), shell=True) - subprocess.run(f'mv {file.replace(".ipynb", ".html")} {output}', shell=True) - subprocess.run(f'rm {file}', shell=True) + os.replace(file.replace(".ipynb", ".html"), output) + os.remove(file) return output def _postprocess_html(file: str, title: str): - with open(file, mode='r') as f: - html = f.read() - html = html.replace('<title>tmp.report.nbconvert</title>', - f'<title>{title}</title>') - with open(file, mode='w') as f: - f.write(html) + try: + with open(file, mode='r', encoding="utf8", errors="surrogateescape") as f: + html = f.read() + html = html.replace('<title>tmp.report.nbconvert</title>', + f'<title>{title}</title>') + with open(file, mode='w', encoding="utf8", errors="surrogateescape") as f: + f.write(html) + except: + logger.warning('Failed to overwrite default HTML report title. ' + 'This is purely aesthetic and does not affect output.') def run_notebook_make_html(file, output) -> str: diff --git a/cellbender/remove_background/run.py b/cellbender/remove_background/run.py index 42cf5b4e..ca2a592e 100644 --- a/cellbender/remove_background/run.py +++ b/cellbender/remove_background/run.py @@ -43,6 +43,7 @@ from typing import Tuple, Optional, Dict, Union import matplotlib +import matplotlib.backends.backend_pdf # issue #287 matplotlib.use('Agg') import matplotlib.pyplot as plt # This needs to be after matplotlib.use('Agg') From 97c1d408eb7bea18efded99777230cc473fce4cf Mon Sep 17 00:00:00 2001 From: Stephen Fleming <sjfleming@users.noreply.github.com> Date: Wed, 10 Apr 2024 22:38:53 -0400 Subject: [PATCH 10/19] Fix major bug in v0.3.1: negative counts (#347) * issue #348 lxml_html_clean dependency * Fix #306: noise count integer overflow * Introduce --force-use-checkpoint for redoing v0.3.1 runs * Add a warning to the README about v0.3.1 --- .github/workflows/miniwdl_check.yml | 7 +++- .github/workflows/run_packaging_check.yml | 4 ++- .github/workflows/run_pytest.yml | 4 ++- .gitignore | 1 + README.rst | 26 ++++++++++++++ cellbender/remove_background/argparser.py | 11 +++++- cellbender/remove_background/checkpoint.py | 36 ++++++++++++------- cellbender/remove_background/estimation.py | 10 ++++-- cellbender/remove_background/posterior.py | 6 ++-- cellbender/remove_background/run.py | 6 +++- .../tests/test_checkpoint.py | 1 + .../tests/test_estimation.py | 36 +++++++++++++++++-- .../tests/test_integration.py | 3 ++ requirements.txt | 1 + 14 files changed, 126 insertions(+), 26 deletions(-) diff --git a/.github/workflows/miniwdl_check.yml b/.github/workflows/miniwdl_check.yml index 8a8de2c8..34d1a4cd 100644 --- a/.github/workflows/miniwdl_check.yml +++ b/.github/workflows/miniwdl_check.yml @@ -1,7 +1,12 @@ name: 'validate WDL' -on: [pull_request] + +on: + pull_request: + branches: [ master, dev ] + env: MINIWDL_VERSION: 1.8.0 + jobs: miniwdl-check: runs-on: ubuntu-latest diff --git a/.github/workflows/run_packaging_check.yml b/.github/workflows/run_packaging_check.yml index 8a9fc1cd..6144cbe0 100644 --- a/.github/workflows/run_packaging_check.yml +++ b/.github/workflows/run_packaging_check.yml @@ -2,7 +2,9 @@ name: 'packaging' -on: pull_request +on: + pull_request: + branches: [ master, dev ] jobs: build: diff --git a/.github/workflows/run_pytest.yml b/.github/workflows/run_pytest.yml index 7c8c6620..b6a02ae4 100644 --- a/.github/workflows/run_pytest.yml +++ b/.github/workflows/run_pytest.yml @@ -2,7 +2,9 @@ name: 'pytest' -on: pull_request +on: + pull_request: + branches: [ master, dev ] jobs: build: diff --git a/.gitignore b/.gitignore index 80b6c0c2..4d5b6868 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ dist/ *.csv *.npz *.tar.gz +data/ \ No newline at end of file diff --git a/README.rst b/README.rst index d5895c76..f32bdefa 100644 --- a/README.rst +++ b/README.rst @@ -36,6 +36,32 @@ The current release contains the following modules. More modules will be added i Please refer to `the documentation <https://cellbender.readthedocs.io/en/latest/>`_ for a quick start tutorial. + WARNING: + + The release tagged v0.3.1 included a bug which caused output count matrices to be incorrect. `The bug + <https://github.com/broadinstitute/CellBender/blame/e2fb5977cb187cb4b12172c9f77ed556bca92cb0/cellbender/remove_background/estimation.py#L241>`_, + introduced in `#303 <https://github.com/broadinstitute/CellBender/pull/303>`_, compromised output denoised count matrices + (due to an integer overflow) and would often show up as negative entries in the output count matrices. The bug also existed on + the master branch until `#347 <https://github.com/broadinstitute/CellBender/pull/347>`_. + + For now, we recommend using either v0.3.0 or the master branch (after #347) until v0.3.2 is released, and then using v0.3.2. + + Outputs generated with v0.3.1 (or the master branch between #303 and #347) can be salvaged by making use of the + checkpoint file, which is not compromised. The following command will re-run the (inexpensive, CPU-only) + estimation of the output count matrix using the saved posterior in the checkpoint file. Note the use of the new + input argument ``--force-use-checkpoint`` which will allow use of a checkpoint file produced by a different CellBender version: + + .. code-block:: console + + (cellbender) $ cellbender remove-background \ + --input my_raw_count_matrix_file.h5 \ + --output my_cellbender_output_file.h5 \ + --checkpoint path/to/ckpt.tar.gz \ + --force-use-checkpoint + + where ``path/to/ckpt.tar.gz`` is the path to the checkpoint file generated by the original run. Ensure that you pair up the right + ``--input`` with the right ``--checkpoint``. + Installation and Usage ---------------------- diff --git a/cellbender/remove_background/argparser.py b/cellbender/remove_background/argparser.py index d53aca3c..aebe6703 100644 --- a/cellbender/remove_background/argparser.py +++ b/cellbender/remove_background/argparser.py @@ -48,10 +48,19 @@ def add_subparser_args(subparsers: argparse) -> argparse: subparser.add_argument("--checkpoint", nargs=None, type=str, dest='input_checkpoint_tarball', required=False, default=consts.CHECKPOINT_FILE_NAME, - help="Checkpoint tarball produced by the same version " + help="Checkpoint tarball produced by v0.3.0+ " "of CellBender remove-background. If present, " "and the workflow hashes match, training will " "restart from this checkpoint.") + subparser.add_argument("--force-use-checkpoint", + dest='force_use_checkpoint', action="store_true", + help="Normally, checkpoints can only be used if the CellBender " + "code and certain input args match exactly. This flag allows you " + "to bypass this requirement. An example use would be to create a new output " + "using a checkpoint from a run of v0.3.1, a redacted version with " + "faulty output count matrices. If you use this flag, " + "ensure that the input file and the checkpoint match, because " + "CellBender will not check.") subparser.add_argument("--expected-cells", nargs=None, type=int, default=None, dest="expected_cell_count", diff --git a/cellbender/remove_background/checkpoint.py b/cellbender/remove_background/checkpoint.py index 206737be..44ed12e5 100644 --- a/cellbender/remove_background/checkpoint.py +++ b/cellbender/remove_background/checkpoint.py @@ -154,7 +154,8 @@ def save_checkpoint(filebase: str, def load_checkpoint(filebase: Optional[str], tarball_name: str = consts.CHECKPOINT_FILE_NAME, - force_device: Optional[str] = None)\ + force_device: Optional[str] = None, + force_use_checkpoint: bool = False)\ -> Dict[str, Union['RemoveBackgroundPyroModel', pyro.optim.PyroOptim, DataLoader, bool]]: """Load checkpoint and prepare a RemoveBackgroundPyroModel and optimizer.""" @@ -163,6 +164,7 @@ def load_checkpoint(filebase: Optional[str], tarball_name=tarball_name, to_load=['model', 'optim', 'param_store', 'dataloader', 'args', 'random_state'], force_device=force_device, + force_use_checkpoint=force_use_checkpoint, ) out.update({'loaded': True}) logger.info(f'Loaded partially-trained checkpoint from {tarball_name}') @@ -172,7 +174,8 @@ def load_checkpoint(filebase: Optional[str], def load_from_checkpoint(filebase: Optional[str], tarball_name: str = consts.CHECKPOINT_FILE_NAME, to_load: List[str] = ['model'], - force_device: Optional[str] = None) -> Dict: + force_device: Optional[str] = None, + force_use_checkpoint: bool = False) -> Dict: """Load specific files from a checkpoint tarball.""" load_kwargs = {} @@ -192,19 +195,24 @@ def load_from_checkpoint(filebase: Optional[str], else: # no tarball loaded, so do not continue trying to load files raise FileNotFoundError - - # See if files have a hash matching input filebase. - if filebase is not None: + + # If posterior is present, do not require run hash to match: will pick up + # after training and run estimation from existing posterior. + # This smoothly allows re-runs (including for problematic v0.3.1) + logger.debug(f'force_use_checkpoint: {force_use_checkpoint}') + if force_use_checkpoint or (filebase is None): + filebase = (glob.glob(os.path.join(tmp_dir, '*_model.torch'))[0] + .replace('_model.torch', '')) + logger.debug(f'Accepting any file hash, so loading {filebase}*') + + else: + # See if files have a hash matching input filebase. basename = os.path.basename(filebase) filebase = os.path.join(tmp_dir, basename) logger.debug(f'Looking for files with base name matching {filebase}*') if not os.path.exists(filebase + '_model.torch'): logger.info('Workflow hash does not match that of checkpoint.') - raise ValueError('Workflow hash does not match that of checkpoint.') - else: - filebase = (glob.glob(os.path.join(tmp_dir, '*_model.torch'))[0] - .replace('_model.torch', '')) - logger.debug(f'Accepting any file hash, so loading {filebase}*') + raise ValueError('Workflow hash does not match that of checkpoint.') out = {} @@ -265,9 +273,10 @@ def load_from_checkpoint(filebase: Optional[str], return out -def attempt_load_checkpoint(filebase: str, +def attempt_load_checkpoint(filebase: Optional[str], tarball_name: str = consts.CHECKPOINT_FILE_NAME, - force_device: Optional[str] = None)\ + force_device: Optional[str] = None, + force_use_checkpoint: bool = False)\ -> Dict[str, Union['RemoveBackgroundPyroModel', pyro.optim.PyroOptim, DataLoader, bool]]: """Load checkpoint and prepare a RemoveBackgroundPyroModel and optimizer, or return the inputs if loading fails.""" @@ -276,7 +285,8 @@ def attempt_load_checkpoint(filebase: str, logger.debug('Attempting to load checkpoint from ' + tarball_name) return load_checkpoint(filebase=filebase, tarball_name=tarball_name, - force_device=force_device) + force_device=force_device, + force_use_checkpoint=force_use_checkpoint) except FileNotFoundError: logger.debug('No tarball found') diff --git a/cellbender/remove_background/estimation.py b/cellbender/remove_background/estimation.py index b4866d2f..777bf03e 100644 --- a/cellbender/remove_background/estimation.py +++ b/cellbender/remove_background/estimation.py @@ -21,6 +21,10 @@ logger = logging.getLogger('cellbender') +N_CELLS_DATATYPE = np.int32 +N_GENES_DATATYPE = np.int32 +COUNT_DATATYPE = np.int32 + class EstimationMethod(ABC): """Base class for estimation of noise counts, given a posterior.""" @@ -52,7 +56,7 @@ def _estimation_array_to_csr(self, data: np.ndarray, m: np.ndarray, noise_offsets: Optional[Dict[int, int]], - dtype=np.int64) -> sp.csr_matrix: + dtype=COUNT_DATATYPE) -> sp.csr_matrix: """Say you have point estimates for each count matrix element (data) and you have the 'm'-indices for each value (m). This returns a CSR matrix that has the shape of the count matrix, where duplicate entries have @@ -218,7 +222,7 @@ def _estimation_array_to_csr(index_converter, data: np.ndarray, m: np.ndarray, noise_offsets: Optional[Dict[int, int]], - dtype=np.int) -> sp.csr_matrix: + dtype=COUNT_DATATYPE) -> sp.csr_matrix: """Say you have point estimates for each count matrix element (data) and you have the 'm'-indices for each value (m). This returns a CSR matrix that has the shape of the count matrix, where duplicate entries have @@ -238,7 +242,7 @@ def _estimation_array_to_csr(index_converter, row, col = index_converter.get_ng_indices(m_inds=m) if noise_offsets is not None: data = data + np.array([noise_offsets.get(i, 0) for i in m]) - coo = sp.coo_matrix((data.astype(dtype), (row.astype(np.uint64), col.astype(np.uint8))), + coo = sp.coo_matrix((data.astype(dtype), (row.astype(N_CELLS_DATATYPE), col.astype(N_GENES_DATATYPE))), shape=index_converter.matrix_shape, dtype=dtype) coo.sum_duplicates() return coo.tocsr() diff --git a/cellbender/remove_background/posterior.py b/cellbender/remove_background/posterior.py index d99e5338..5bdd890c 100644 --- a/cellbender/remove_background/posterior.py +++ b/cellbender/remove_background/posterior.py @@ -107,13 +107,15 @@ def _do_posterior_regularization(posterior: Posterior): try: ckpt_posterior = load_from_checkpoint(tarball_name=args.input_checkpoint_tarball, filebase=args.checkpoint_filename, - to_load=['posterior']) + to_load=['posterior'], + force_use_checkpoint=args.force_use_checkpoint) except ValueError: # input checkpoint tarball was not a match for this workflow # but we still may have saved a new tarball ckpt_posterior = load_from_checkpoint(tarball_name=consts.CHECKPOINT_FILE_NAME, filebase=args.checkpoint_filename, - to_load=['posterior']) + to_load=['posterior'], + force_use_checkpoint=args.force_use_checkpoint) if os.path.exists(ckpt_posterior.get('posterior_file', 'does_not_exist')): # Load posterior if it was saved in the checkpoint. posterior.load(file=ckpt_posterior['posterior_file']) diff --git a/cellbender/remove_background/run.py b/cellbender/remove_background/run.py index ca2a592e..7ac466bd 100644 --- a/cellbender/remove_background/run.py +++ b/cellbender/remove_background/run.py @@ -307,6 +307,9 @@ def compute_output_denoised_counts_reports_metrics(posterior: Posterior, posterior.latents_map['p'], ) + # Failsafe to ensure no negative counts. + assert np.all(denoised_counts.data >= 0), 'Negative count matrix entries in output' + # TODO: correct cell probabilities so that any zero-count droplet becomes "empty" # Save denoised count matrix. @@ -627,7 +630,8 @@ def run_inference(dataset_obj: SingleCellRNACountsDataset, # Attempt to load from a previously-saved checkpoint. ckpt = attempt_load_checkpoint(filebase=checkpoint_filename, tarball_name=args.input_checkpoint_tarball, - force_device='cuda:0' if args.use_cuda else 'cpu') + force_device='cuda:0' if args.use_cuda else 'cpu', + force_use_checkpoint=args.force_use_checkpoint) ckpt_loaded = ckpt['loaded'] # True if a checkpoint was loaded successfully if ckpt_loaded: diff --git a/cellbender/remove_background/tests/test_checkpoint.py b/cellbender/remove_background/tests/test_checkpoint.py index 59ccb9ec..0dbaa22d 100644 --- a/cellbender/remove_background/tests/test_checkpoint.py +++ b/cellbender/remove_background/tests/test_checkpoint.py @@ -414,6 +414,7 @@ def test_save_and_load_cellbender_checkpoint(tmpdir_factory, cuda, scheduler): args.constant_learning_rate = not scheduler args.debug = False args.input_checkpoint_tarball = 'none' + args.force_use_checkpoint = False create_random_state_blank_slate(0) pyro.clear_param_store() diff --git a/cellbender/remove_background/tests/test_estimation.py b/cellbender/remove_background/tests/test_estimation.py index c1cb931e..2cca6418 100644 --- a/cellbender/remove_background/tests/test_estimation.py +++ b/cellbender/remove_background/tests/test_estimation.py @@ -6,9 +6,10 @@ import torch from cellbender.remove_background.estimation import Mean, MAP, \ - SingleSample, ThresholdCDF, MultipleChoiceKnapsack, pandas_grouped_apply + SingleSample, ThresholdCDF, MultipleChoiceKnapsack, pandas_grouped_apply, _estimation_array_to_csr, COUNT_DATATYPE from cellbender.remove_background.posterior import IndexConverter, \ dense_to_sparse_op_torch, log_prob_sparse_to_dense +from cellbender.remove_background.tests.conftest import sparse_matrix_equal from typing import Dict, Union @@ -92,11 +93,15 @@ def test_mean_massive_m(log_prob_coo): new_shape = (coo.shape[0] + greater_than_max_int32, coo.shape[1]) new_coo = sp.coo_matrix((coo.data, (new_row, coo.col)), shape=new_shape) + print(f'original COO shape: {coo.shape}') + print(f'new COO shape: {new_coo.shape}') + print(f'new row minimum value: {new_coo.row.min()}') + print(f'new row maximum value: {new_coo.row.max()}') offset_dict = {k + greater_than_max_int32: v for k, v in log_prob_coo['offsets'].items()} # this is just a shim - converter = IndexConverter(total_n_cells=2, - total_n_genes=new_coo.shape[0]) + converter = IndexConverter(total_n_cells=new_coo.shape[0], + total_n_genes=new_coo.shape[1]) # set up and estimate estimator = Mean(index_converter=converter) @@ -379,3 +384,28 @@ def test_parallel_pandas_grouped_apply(fun): np.testing.assert_array_equal(reg['m'], parallel['m']) np.testing.assert_array_equal(reg['result'], parallel['result']) + + +def test_estimation_array_to_csr(): + + larger_than_uint16 = 2**16 + 1 + + converter = IndexConverter(total_n_cells=larger_than_uint16, + total_n_genes=larger_than_uint16) + m = larger_than_uint16 + np.arange(-10, 10) + data = np.random.rand(len(m)) * -10 + noise_offsets = None + + output_csr = _estimation_array_to_csr(index_converter=converter, data=data, m=m, noise_offsets=noise_offsets, dtype=COUNT_DATATYPE) + + # reimplementation here with totally permissive datatypes + cell_and_gene_dtype = np.float64 + row, col = converter.get_ng_indices(m_inds=m) + if noise_offsets is not None: + data = data + np.array([noise_offsets.get(i, 0) for i in m]) + coo = sp.coo_matrix((data.astype(COUNT_DATATYPE), (row.astype(cell_and_gene_dtype), col.astype(cell_and_gene_dtype))), + shape=converter.matrix_shape, dtype=COUNT_DATATYPE) + coo.sum_duplicates() + truth_csr = coo.tocsr() + + assert sparse_matrix_equal(output_csr, truth_csr) diff --git a/cellbender/remove_background/tests/test_integration.py b/cellbender/remove_background/tests/test_integration.py index 624c59df..078e9f23 100644 --- a/cellbender/remove_background/tests/test_integration.py +++ b/cellbender/remove_background/tests/test_integration.py @@ -50,3 +50,6 @@ def test_full_run(tmpdir_factory, h5_v3_file, cuda): adata_cell_barcodes = adata.obs_names[adata.obs['cell_probability'] > consts.CELL_PROB_CUTOFF] assert set(cell_barcodes) == set(adata_cell_barcodes), \ 'Cell barcodes in h5 are different from those in CSV file' + + # ensure there are no negative count matrix entries in the output + assert np.all(adata.X.data >= 0), 'Negative count matrix entries in output' diff --git a/requirements.txt b/requirements.txt index 3585b6a4..9b68a3c1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,4 +12,5 @@ jupyter jupyter_contrib_nbextensions notebook<7.0.0 nbconvert<7.0.0 +lxml_html_clean psutil From 578c214e1afe9d737c4920c4296c63fcb98d4258 Mon Sep 17 00:00:00 2001 From: Stephen Fleming <sjf11@case.edu> Date: Fri, 19 Apr 2024 20:55:35 +0000 Subject: [PATCH 11/19] Tweak readme appearance --- README.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index f32bdefa..76add55e 100644 --- a/README.rst +++ b/README.rst @@ -1,23 +1,25 @@ CellBender ========== -.. image:: https://img.shields.io/github/license/broadinstitute/CellBender?color=white +|badge1| |badge2| |badge3| |badge4| |badge5| + +.. |badge1| image:: https://img.shields.io/github/license/broadinstitute/CellBender?color=white :target: LICENSE :alt: License -.. image:: https://readthedocs.org/projects/cellbender/badge/?version=latest +.. |badge2| image:: https://readthedocs.org/projects/cellbender/badge/?version=latest :target: https://cellbender.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status -.. image:: https://img.shields.io/pypi/v/CellBender.svg +.. |badge3| image:: https://img.shields.io/pypi/v/CellBender.svg :target: https://pypi.org/project/CellBender :alt: PyPI -.. image:: https://static.pepy.tech/personalized-badge/cellbender?period=total&units=international_system&left_color=grey&right_color=blue&left_text=pypi%20downloads +.. |badge4| image:: https://static.pepy.tech/personalized-badge/cellbender?period=total&units=international_system&left_color=grey&right_color=blue&left_text=pypi%20downloads :target: https://pepy.tech/project/CellBender :alt: Downloads -.. image:: https://img.shields.io/github/stars/broadinstitute/CellBender?color=yellow&logoColor=yellow) +.. |badge5| image:: https://img.shields.io/github/stars/broadinstitute/CellBender?color=yellow&logoColor=yellow) :target: https://github.com/broadinstitute/CellBender/stargazers :alt: Stars From 80514f06aea41795486ee0caea07a41b67498f90 Mon Sep 17 00:00:00 2001 From: Jura Pintar <jpintar@users.noreply.github.com> Date: Mon, 22 Apr 2024 15:43:11 -0400 Subject: [PATCH 12/19] Add newer Cell Ranger feature types (#339) In Cell Ranger 7+, there is a longer list of features one can specify in `cellranger multi`. These are added here to the list of allowed features. --- cellbender/remove_background/cli.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cellbender/remove_background/cli.py b/cellbender/remove_background/cli.py index 29f7928c..fee04796 100644 --- a/cellbender/remove_background/cli.py +++ b/cellbender/remove_background/cli.py @@ -117,14 +117,22 @@ def validate_args(args) -> argparse.Namespace: args.fpr = fpr_list_correct_dtypes # Ensure that "exclude_features" specifies allowed features. - # As of CellRanger 6.0, the possible features are: + # As of CellRanger 7.2, the possible features are: # Gene Expression # Antibody Capture # CRISPR Guide Capture # Custom # Peaks + # Multiplexing Capture + # VDJ + # VDJ-T + # VDJ-T-GD + # VDJ-B + # Antigen Capture allowed_features = ['Gene Expression', 'Antibody Capture', - 'CRISPR Guide Capture', 'Custom', 'Peaks'] + 'CRISPR Guide Capture', 'Custom', 'Peaks', + 'Multiplexing Capture', 'VDJ', 'VDJ-T', + 'VDJ-T-GD', 'VDJ-B', 'Antigen Capture'] for feature in args.exclude_features: if feature not in allowed_features: sys.stdout.write(f"Specified '{feature}' using --exclude-feature-types, " From 72e6a3fa405c917a1e2faba971235eed037ef74f Mon Sep 17 00:00:00 2001 From: alecw <alecw@users.noreply.github.com> Date: Mon, 22 Apr 2024 15:58:20 -0400 Subject: [PATCH 13/19] Fix test_elbo bug when retrying with more memory from checkpoint (#345) Keep test_elbo as part of model, and refer to it there from the retry code --- cellbender/remove_background/train.py | 30 +++++++++++++-------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/cellbender/remove_background/train.py b/cellbender/remove_background/train.py index 8d778082..bf7bed67 100644 --- a/cellbender/remove_background/train.py +++ b/cellbender/remove_background/train.py @@ -152,7 +152,6 @@ def run_training(model: RemoveBackgroundPyroModel, # Initialize train and tests ELBO with empty lists. train_elbo = [] - test_elbo = [] lr = [] epoch_checkpoint_freq = 1000 # a large number... it will be recalculated @@ -212,16 +211,15 @@ def run_training(model: RemoveBackgroundPyroModel, if epoch % test_freq == 0: model.eval() total_epoch_loss_test = evaluate_epoch(svi, test_loader) - test_elbo.append(-total_epoch_loss_test) model.loss['test']['epoch'].append(epoch) model.loss['test']['elbo'].append(-total_epoch_loss_test) logger.info("[epoch %03d] average test loss: %.4f" % (epoch, total_epoch_loss_test)) # Check whether test ELBO has spiked beyond specified conditions. - if (epoch_elbo_fail_fraction is not None) and (len(test_elbo) > 2): - current_diff = max(0., test_elbo[-2] - test_elbo[-1]) - overall_diff = np.abs(test_elbo[-2] - test_elbo[0]) + if (epoch_elbo_fail_fraction is not None) and (len(model.loss['test']['elbo']) > 2): + current_diff = max(0., model.loss['test']['elbo'][-2] - model.loss['test']['elbo'][-1]) + overall_diff = np.abs(model.loss['test']['elbo'][-2] - model.loss['test']['elbo'][0]) fractional_spike = current_diff / overall_diff if fractional_spike > epoch_elbo_fail_fraction: raise ElboException( @@ -245,15 +243,15 @@ def run_training(model: RemoveBackgroundPyroModel, # Check on the final test ELBO to see if it meets criteria. if final_elbo_fail_fraction is not None: - best_test_elbo = max(test_elbo) - if test_elbo[-1] < best_test_elbo: - final_best_diff = best_test_elbo - test_elbo[-1] - initial_best_diff = best_test_elbo - test_elbo[0] + best_test_elbo = max(model.loss['test']['elbo']) + if model.loss['test']['elbo'][-1] < best_test_elbo: + final_best_diff = best_test_elbo - model.loss['test']['elbo'][-1] + initial_best_diff = best_test_elbo - model.loss['test']['elbo'][0] if (final_best_diff / initial_best_diff) > final_elbo_fail_fraction: raise ElboException( - f'Training failed because final test loss {test_elbo[-1]:.2f} ' + f"Training failed because final test loss {model.loss['test']['elbo'][-1]:.2f} " f'is not sufficiently close to best test loss {best_test_elbo:.2f}, ' - f'compared to the initial test loss {test_elbo[0]:.2f}. ' + f"compared to the initial test loss {model.loss['test']['elbo'][0]:.2f}. " f'Fractional difference is {final_best_diff / initial_best_diff:.2f}, ' f'which is > specified final_elbo_fail_fraction {final_elbo_fail_fraction:.2f}' ) @@ -284,14 +282,14 @@ def run_training(model: RemoveBackgroundPyroModel, logger.info(datetime.now().strftime('%Y-%m-%d %H:%M:%S')) # Check final ELBO meets conditions. - if (final_elbo_fail_fraction is not None) and (len(test_elbo) > 1): - best_test_elbo = max(test_elbo) - if -test_elbo[-1] >= -best_test_elbo * (1 + final_elbo_fail_fraction): - raise ElboException(f'Training failed because final test loss ({-test_elbo[-1]:.4f}) ' + if (final_elbo_fail_fraction is not None) and (len(model.loss['test']['elbo']) > 1): + best_test_elbo = max(model.loss['test']['elbo']) + if -model.loss['test']['elbo'][-1] >= -best_test_elbo * (1 + final_elbo_fail_fraction): + raise ElboException(f"Training failed because final test loss ({-model.loss['test']['elbo'][-1]:.4f}) " f'exceeds best test loss ({-best_test_elbo:.4f}) by >= ' f'{100 * final_elbo_fail_fraction:.1f}%') # Free up all the GPU memory we can once training is complete. torch.cuda.empty_cache() - return train_elbo, test_elbo + return train_elbo, model.loss['test']['elbo'] From a71e18362be9dbe45d553c843e786edce2edeb6c Mon Sep 17 00:00:00 2001 From: alecw <alecw@users.noreply.github.com> Date: Tue, 23 Apr 2024 09:53:21 -0400 Subject: [PATCH 14/19] Retry: prevent ZeroDivisionError if initial test ELBO is the best test ELBO (#312) --- cellbender/remove_background/train.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cellbender/remove_background/train.py b/cellbender/remove_background/train.py index bf7bed67..961e06e7 100644 --- a/cellbender/remove_background/train.py +++ b/cellbender/remove_background/train.py @@ -247,7 +247,12 @@ def run_training(model: RemoveBackgroundPyroModel, if model.loss['test']['elbo'][-1] < best_test_elbo: final_best_diff = best_test_elbo - model.loss['test']['elbo'][-1] initial_best_diff = best_test_elbo - model.loss['test']['elbo'][0] - if (final_best_diff / initial_best_diff) > final_elbo_fail_fraction: + if initial_best_diff == 0: + raise ElboException( + f"Training failed because there was no improvement from the initial test loss {model.loss['test']['elbo'][0]:.2f}. " + f"Final test loss was {model.loss['test']['elbo'][-1]}" + ) + elif (final_best_diff / initial_best_diff) > final_elbo_fail_fraction: raise ElboException( f"Training failed because final test loss {model.loss['test']['elbo'][-1]:.2f} " f'is not sufficiently close to best test loss {best_test_elbo:.2f}, ' From 2c3dbe88c660f5e05d979d38c8e99259695b5286 Mon Sep 17 00:00:00 2001 From: aawdeh <aseel.awdeh@gmail.com> Date: Mon, 24 Jun 2024 10:50:31 -0400 Subject: [PATCH 15/19] Azurize CellBender to run on ToA (#367) CPU-only version of WDL --- wdl/cellbender_remove_background_azure.wdl | 250 +++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 wdl/cellbender_remove_background_azure.wdl diff --git a/wdl/cellbender_remove_background_azure.wdl b/wdl/cellbender_remove_background_azure.wdl new file mode 100644 index 00000000..503a4659 --- /dev/null +++ b/wdl/cellbender_remove_background_azure.wdl @@ -0,0 +1,250 @@ +version 1.0 + +## Copyright Broad Institute, 2022 +## +## LICENSING : +## This script is released under the WDL source code license (BSD-3) +## (see LICENSE in https://github.com/openwdl/wdl). + +task run_cellbender_remove_background_gpu { + + input { + + # File-related inputs + String sample_name + File input_file_unfiltered # all barcodes, raw data + File? barcodes_file # for MTX and NPZ formats, the bacode information is in a separate file + File? genes_file # for MTX and NPZ formats, the gene information is in a separate file + File? checkpoint_file # start from a saved checkpoint + File? truth_file # only for developers using simulated data + + # Outputs + String? output_bucket_base_directory # Google bucket path + + # Docker image with CellBender + String? docker_image = "us.gcr.io/broad-dsde-methods/cellbender:0.3.0" + + # Used by developers for testing non-dockerized versions of CellBender + String? dev_git_hash__ # leave blank to run CellBender normally + + # Method configuration inputs + Int? expected_cells + Int? total_droplets_included + Float? force_cell_umi_prior + Float? force_empty_umi_prior + String? model + Int? low_count_threshold + String? fpr # in quotes: floats separated by whitespace: the output false positive rate(s) + Int? epochs + Int? z_dim + String? z_layers # in quotes: integers separated by whitespace + Float? empty_drop_training_fraction + Float? learning_rate + String? exclude_feature_types # in quotes: strings separated by whitespace + String? ignore_features # in quotes: integers separated by whitespace + Float? projected_ambient_count_threshold + Float? checkpoint_mins + Float? final_elbo_fail_fraction + Float? epoch_elbo_fail_fraction + Int? num_training_tries + Float? learning_rate_retry_mult + Int? posterior_batch_size + Boolean? estimator_multiple_cpu + Boolean? constant_learning_rate + Boolean? debug + + # Hardware-related inputs + String? hardware_zones = "us-east1-d us-east1-c us-central1-a us-central1-c us-west1-b" + Int? hardware_disk_size_GB = 50 + Int? hardware_boot_disk_size_GB = 20 + Int? hardware_preemptible_tries = 0 + Int? hardware_max_retries = 0 + Int? hardware_cpu_count = 4 + Int? hardware_memory_GB = 32 + String? hardware_gpu_type = "nvidia-tesla-t4" + String? nvidia_driver_version = "470.82.01" # need >=465.19.01 for CUDA 11.3 + + } + + # For development only: install a non dockerized version of CellBender + Boolean install_from_git = (if defined(dev_git_hash__) then true else false) + + # Compute the output bucket directory for this sample: output_bucket_base_directory/sample_name/ + String output_bucket_directory = (if defined(output_bucket_base_directory) + then sub(select_first([output_bucket_base_directory]), "/+$", "") + "/${sample_name}/" + else "") + + command { + + set -e # fail the workflow if there is an error + set -x + + # install a specific commit of cellbender from github if called for (-- developers only) + if [[ ~{install_from_git} == true ]]; then + echo "Uninstalling pre-installed cellbender" + yes | pip uninstall cellbender + echo "Installing cellbender from github" + # this more succinct version is broken in some older versions of cellbender + echo "pip install --no-cache-dir -U git+https://github.com/broadinstitute/CellBender.git@~{dev_git_hash__}" + # yes | pip install --no-cache-dir -U git+https://github.com/broadinstitute/CellBender.git@~{dev_git_hash__} + # this should always work + git clone -q https://github.com/broadinstitute/CellBender.git /cromwell_root/CellBender + cd /cromwell_root/CellBender + git checkout -q ~{dev_git_hash__} + yes | pip install --no-cache-dir -U -e /cromwell_root/CellBender + pip list + cd /cromwell_root + fi + + # put the barcodes_file in the right place, if it is provided + if [[ ! -z "~{barcodes_file}" ]]; then + dir=$(dirname ~{input_file_unfiltered}) + if [[ "~{input_file_unfiltered}" == *.npz ]]; then + name="row_index.npy" + elif [[ "~{barcodes_file}" == *.gz ]]; then + name="barcodes.tsv.gz" + else + name="barcodes.tsv" + fi + echo "Moving barcodes file to "$dir"/"$name + echo "mv ~{barcodes_file} "$dir"/"$name + [ -f $dir/$name ] || mv ~{barcodes_file} $dir/$name + fi + + # put the genes_file in the right place, if it is provided + if [[ ! -z "~{genes_file}" ]]; then + dir=$(dirname ~{input_file_unfiltered}) + if [[ "~{input_file_unfiltered}" == *.npz ]]; then + name="col_index.npy" + elif [[ "~{genes_file}" == *.gz ]]; then + name="features.tsv.gz" + else + name="genes.tsv" + fi + echo "Moving genes file to "$dir"/"$name + echo "mv ~{genes_file} "$dir"/"$name + [ -f $dir/$name ] || mv ~{genes_file} $dir/$name + fi + + # use the directory as the input in the case of an MTX file + if [[ "~{input_file_unfiltered}" == *.mtx* ]]; then + input=$(dirname ~{input_file_unfiltered}) + else + input=~{input_file_unfiltered} + fi + + cellbender remove-background \ + --input $input \ + --output "~{sample_name}_out.h5" \ + ~{"--checkpoint " + checkpoint_file} \ + ~{"--expected-cells " + expected_cells} \ + ~{"--total-droplets-included " + total_droplets_included} \ + ~{"--fpr " + fpr} \ + ~{"--model " + model} \ + ~{"--low-count-threshold " + low_count_threshold} \ + ~{"--epochs " + epochs} \ + ~{"--force-cell-umi-prior " + force_cell_umi_prior} \ + ~{"--force-empty-umi-prior " + force_empty_umi_prior} \ + ~{"--z-dim " + z_dim} \ + ~{"--z-layers " + z_layers} \ + ~{"--empty-drop-training-fraction " + empty_drop_training_fraction} \ + ~{"--exclude-feature-types " + exclude_feature_types} \ + ~{"--ignore-features " + ignore_features} \ + ~{"--projected-ambient-count-threshold " + projected_ambient_count_threshold} \ + ~{"--learning-rate " + learning_rate} \ + ~{"--checkpoint-mins " + checkpoint_mins} \ + ~{"--final-elbo-fail-fraction " + final_elbo_fail_fraction} \ + ~{"--epoch-elbo-fail-fraction " + epoch_elbo_fail_fraction} \ + ~{"--num-training-tries " + num_training_tries} \ + ~{"--learning-rate-retry-mult " + learning_rate_retry_mult} \ + ~{"--posterior-batch-size " + posterior_batch_size} \ + ~{true="--estimator-multiple-cpu " false=" " estimator_multiple_cpu} \ + ~{true="--constant-learning-rate " false=" " constant_learning_rate} \ + ~{true="--debug " false=" " debug} \ + ~{"--truth " + truth_file} + + # copy outputs to google bucket if output_bucket_base_directory is supplied + echo ~{output_bucket_directory} + # commenting out b/c cant use gsutil in azure + if [[ ! -z "~{output_bucket_directory}" ]]; then + echo "Copying output data to ~{output_bucket_directory} using gsutil cp" + gsutil -m cp ~{sample_name}_out* ~{output_bucket_directory} + fi + + } + + output { + File log = "${sample_name}_out.log" + File pdf = "${sample_name}_out.pdf" + File cell_csv = "${sample_name}_out_cell_barcodes.csv" + Array[File] metrics_array = glob("${sample_name}_out*_metrics.csv") # a number of outputs depending on "fpr" + Array[File] report_array = glob("${sample_name}_out*_report.html") # a number of outputs depending on "fpr" + Array[File] h5_array = glob("${sample_name}_out*.h5") # a number of outputs depending on "fpr" + String output_dir = "${output_bucket_directory}" + File ckpt_file = "ckpt.tar.gz" + } + + runtime { + docker: "${docker_image}" + bootDiskSizeGb: hardware_boot_disk_size_GB + disks: "local-disk ${hardware_disk_size_GB} HDD" + memory: "${hardware_memory_GB}G" + cpu: hardware_cpu_count + zones: "${hardware_zones}" + preemptible: hardware_preemptible_tries + checkpointFile: "ckpt.tar.gz" + maxRetries: hardware_max_retries # can be used in case of a PAPI error code 2 failure to install GPU drivers + } + meta { + author: "Stephen Fleming" + email: "sfleming@broadinstitute.org" + description: "WDL that runs CellBender remove-background on a GPU on Google Cloud hardware. See the [CellBender GitHub repo](https://github.com/broadinstitute/CellBender) and [read the documentation](https://cellbender.readthedocs.io/en/v0.3.0/reference/index.html#command-line-options) for more information." + } + + parameter_meta { + sample_name : + {help: "Name which will be prepended to output files and which will be used to construct the output google bucket file path, if output_bucket_base_directory is supplied, as output_bucket_base_directory/sample_name/"} + input_file_unfiltered : + {help: "Input file. This must be raw data that includes all barcodes. See http://cellbender.readthedocs.io for more information on file formats, but importantly, this must be one file, and cannot be a pointer to a directory that contains MTX and TSV files."} + barcodes_file : + {help: "Supply this only if your input_file_unfiltered is a sparse NPZ matrix from Optimus lacking metadata."} + genes_file : + {help: "Supply this only if your input_file_unfiltered is a sparse NPZ matrix from Optimus lacking metadata."} + output_bucket_base_directory : + {help: "Optional google bucket gsURL. If provided, the workflow will create a subfolder called sample_name in this directory and copy outputs there. (Note that the output data would then exist in two places.) Helpful for organization."} + docker_image : + {help: "CellBender docker image. Not all CellBender docker image tags will be compatible with this WDL.", + suggestions: ["us.gcr.io/broad-dsde-methods/cellbender:0.3.0"]} + checkpoint_file : + {help: "Optional gsURL for a checkpoint file created using a previous run ('ckpt.tar.gz') on the same dataset (using the same CellBender docker image). This can be used to create a new output with a different --fpr without re-doing the training run."} + truth_file : + {help: "Optional file only used by CellBender developers or those trying to benchmark CellBender remove-background on simulated data. Normally, this input would not be supplied."} + hardware_preemptible_tries : + {help: "If nonzero, CellBender will be run on a preemptible instance, at a lower cost. If preempted, your run will not start from scratch, but will start from a checkpoint that is saved by CellBender and recovered by Cromwell. For example, if hardware_preemptible_tries is 2, your run will attempt twice using preemptible instances, and if the job is preempted both times before completing, it will finish on a non-preemptible machine. The cost savings is significant. The potential drawback is that preemption wastes time."} + hardware_max_retries : + {help: "If nonzero when CellBender exits without success it will be retried. If one also sets the memory_retry_multiplier workflow option, and the exit happens to be detected as an out of memory error, then the retry will also increase the memory allocated to the next run. The potential benefit is that one can start CellBender with less memory, and memory will be increased only when needed. The potential drawback is that the job will be retried even if the error is not a memory error."} + checkpoint_mins : + {help: "Time in minutes between creation of checkpoint files. Bear in mind that Cromwell copies checkpoints to a bucket every ten minutes."} + hardware_gpu_type : + {help: "Specify the type of GPU that should be used. Ensure that the selected hardware_zones have the GPU available.", + suggestions: ["nvidia-tesla-t4", "nvidia-tesla-k80"]} + } + +} + +workflow cellbender_remove_background { + + call run_cellbender_remove_background_gpu + + output { + File log = run_cellbender_remove_background_gpu.log + File summary_pdf = run_cellbender_remove_background_gpu.pdf + File cell_barcodes_csv = run_cellbender_remove_background_gpu.cell_csv + Array[File] metrics_csv_array = run_cellbender_remove_background_gpu.metrics_array + Array[File] html_report_array = run_cellbender_remove_background_gpu.report_array + Array[File] h5_array = run_cellbender_remove_background_gpu.h5_array + String output_directory = run_cellbender_remove_background_gpu.output_dir + File checkpoint_file = run_cellbender_remove_background_gpu.ckpt_file + } + +} From 569b7b1bf77e622706bed2d1a6d25eb9d76e402c Mon Sep 17 00:00:00 2001 From: Stephen Fleming <sjfleming@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:57:29 -0400 Subject: [PATCH 16/19] Updates to benchmarking scripts --- .../remove_background/tests/benchmarking/run_benchmark.py | 2 ++ .../tests/benchmarking/run_benchmark_result_tabulation.py | 8 ++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cellbender/remove_background/tests/benchmarking/run_benchmark.py b/cellbender/remove_background/tests/benchmarking/run_benchmark.py index efb8520a..ab31ca3a 100644 --- a/cellbender/remove_background/tests/benchmarking/run_benchmark.py +++ b/cellbender/remove_background/tests/benchmarking/run_benchmark.py @@ -141,7 +141,9 @@ def cromshell_submit(wdl: str, submit_cmd = ['cromshell', 'submit', tmp_wdl, inputs, + '--options-json', options, + '--dependencies-zip', dependencies_zip] # submit job diff --git a/cellbender/remove_background/tests/benchmarking/run_benchmark_result_tabulation.py b/cellbender/remove_background/tests/benchmarking/run_benchmark_result_tabulation.py index ffc5e5a8..e5c997ca 100644 --- a/cellbender/remove_background/tests/benchmarking/run_benchmark_result_tabulation.py +++ b/cellbender/remove_background/tests/benchmarking/run_benchmark_result_tabulation.py @@ -69,7 +69,7 @@ def get_cromshell_output_h5(workflow: str, grep: str = '_out.h5') -> Union[str, """Use cromshell list-outputs to get the relevant file gsURL""" output = grep_from_command(['cromshell', 'list-outputs', workflow], grep=grep) - out = output[:-1].decode().split('\n') + out = output.decode().lstrip('run_cellbender_benchmark.h5_array: ').rstrip('\n').split('\n') if len(out) > 1: return out else: @@ -95,18 +95,18 @@ def metadata_from_workflow_id(workflow: str) -> Tuple[str, str, Optional[str]]: # git hash output = grep_from_command(['cromshell', 'metadata', workflow], grep='"git_hash":') - git_hash = output[17:-3].decode() + git_hash = output.decode().split('"git_hash": ')[-1].lstrip('"').split('"')[0] # input file output = grep_from_command(['cromshell', 'metadata', workflow], grep='run_cellbender_benchmark.cb.input_file_unfiltered') - input_file = output[58:-3].decode() + input_file = 'gs://' + output.decode().split('gs://')[-1].split('"')[0] # truth file output = grep_from_command(['cromshell', 'metadata', workflow], grep='run_cellbender_benchmark.cb.truth_file') if 'null' not in output.decode(): - truth_file = output[47:-3].decode() + truth_file = 'gs://' + output.decode().split('gs://')[-1].split('"')[0] else: truth_file = None From 31130fd9fe5405c891d4c1efa25aeab9860a5d5e Mon Sep 17 00:00:00 2001 From: Stephen Fleming <sjfleming@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:58:19 -0400 Subject: [PATCH 17/19] Update documentation in anticipation of v0.3.2 --- .../_static/remove_background/v0.3.2_hgmm.png | Bin 0 -> 189077 bytes docs/source/changelog/index.rst | 82 ++++++++++++++---- docs/source/reference/index.rst | 3 +- 3 files changed, 66 insertions(+), 19 deletions(-) create mode 100644 docs/source/_static/remove_background/v0.3.2_hgmm.png diff --git a/docs/source/_static/remove_background/v0.3.2_hgmm.png b/docs/source/_static/remove_background/v0.3.2_hgmm.png new file mode 100644 index 0000000000000000000000000000000000000000..a9ca57fb350324f0ccdb8c8ec1d84ac5f7c480fd GIT binary patch literal 189077 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≺|o!>TcRhlty$*81bXSbPQ%zQvC(r6M+!a~n|?m7?kITQMu z@j)kIx-&dcJSdPb`lur`;t3y1#Y@=qFN-m_(?&>v?e+|FFZ0fQJ!;X6rjwPZ?Hdtn z?h2WLvIN-1OKpL70^jZ2muTK?1KF#-+Nw-<qaLYc@l5%x5J_P8Mh3OCc!L{i?`_fz z+6!;ZT6+WO``X4)32b@<5<h{pT~Q;SF?Jgu-SQZ;%>p#@+syQ?<wK$_>|DUO_Z3LY zK;@r4yUH(9MMw&8$HcUlMkBN>)`$~bkfJ-r27UWFT9c7Vg1S!019#^&M5k;bdV2w8 zcXgSay$m*I{96`|;D2feFwD*gyj0D1-7ZDcS59G$cW_n3^;XnsHzph1Mwn=pn$M0x z|734FF1BI+1k>~F%gtU+wz*n^&;9yNzUL0}=!Nd?E>O+Qx@<z9@sGZKR7kV@ZmHC9 zO=gK@qNMF+p3wt}%?(*!gC)RlYSFSi*IgYOSGIF~jM?pyPJDI<&)vm0SKT|L#jgR} z9>S=XS%z%yo6ug@%G+pwyk7u1BS1A=@7>{k5*Hk<U(?`q=Ys+&_ZikmO^Nm`3aWu5 z{+x7)F@>B8{RYpAv!nlebKD<FwBnm;eODyx>F_JOhHa0Rv#_WMWX7`IV$s$oB$9ql z3fOMTlYN%;I>a0$GNs+soFpt*qg4&k(U-Q|&ag*iG_>!QY{A0s#FNa!&U06iI6D;+ z-xx|W;Vji_QclW5?dxwuQik@Fe|%%$dpXDNbWTwVE58|9_Wmu?r$h3}mXA-fgQ-Z^ zfEvCVjN0&16qg4{E;dS(M0&Db-ir1NAhMf8By(J*he_!q{R-jlbgQ-UWa0xT@gT2z zTI(yGj?D{0VL80kzn|7dhrDuMgm{7d8a`qcJF-$wvsu+k?=t=PDCl-<7o+r4+<CD@ z7b@9war}icfpQjlHIge$2$Og$wfyo6lnDgnP(ns3zva-7UHhFu(aRIMqdHaEzY|5I z@miz9q_hG)XR1#Pv02of60@j1l4$`UYI_D$i3@!%&VmCALke;`_BIbKUYHI&%bx0r zII!!0K<uF<+BF3sprTEiQLHwYBJK>l-~aZVD?(~@I+4=5`0vEOc*#A0DB*!-nAPc8 zgZ2@l?hvN0s!f<fT-R3t$YWOIJDtYG0V{`>hM`PXYRw0!g04skVNW72pIrclQqC88 ztIUQOvIShWI5Zol6>ng*M5OXbi+y@D63?n$%a_Qhe>uWPJq1J0KNLOdq4%jW9prWv z5EUoC_wTk9(nT%~ztIq9XA=^>tlk>0^S!8l$%h8jHSuvq=FJMmj9tI+ORx@UvbUzL z?u*O4>BN4<!mZ47!w#3<ciDY^Oi{g1qtFUkdU|@=;I`dt3@r>1aldK;AOIt13QXX7 z+4hdM{^}Cb8Qa;R`ZPPBt?hLOkT{=eKJ7vR6E<0lb!9IvyV}fvg-r+1z76Z+{6B2H z1z42bw>ONzgOUy%0!lYZH>d+hcc;YAAl)SbgOqfKNOyNA-Q6kO-TiHR{^vdCeD8ZZ z*JTYeckI3PTEAGE=A(p+QIU?vWyaQ6?mwI)kO`~VWW1m65r6X<>d}D@(WtWIZi;i< z%{820T6dIA;&$EYRU^xFEwmdT(^1rfVj_Qq9~EjX&)2(MvOtpf++FTM1#8pyfu?Db zxD2c4b-nQ6K?{aV;+sz+?ZF_FPXlJH<pF`a)49FIAQdqG<K_JbKINI7!VI-z{Yv^x z1)2W)!JFS=6i#Lz0p!&YL|EZ|O-jUR-rE%ADKl5=etk;J>QXN9^U(1Zs0PXSB$X5; zg_B_k4d!){P^CP@=O1N3#V=3G3UfU8<sHV{h)+UtcYA)kJ#oFzdy>F;D<H5e6=;Zb zF5U7E+OTMd+if2w&J@$r`EcLBJF9NjaV+X)vD2l_^%GLJ7d!A)sIbT?9_|YOH~h&B z5%v{^VnaM8Y6c5j&zo=Dyk#OSKc&-A`FA{ioko)-{83)v;kYH%_!BVkVm>Wfq3*11 zzy8C1Jyz_qCt?rN7SimP0vYl<-Hr-oq*3*b<a+u3Ik;AEG5`+j+y4y;?Wdrg=Cfau zEIh4tVhL<}4+V5J3RLpX%2Gzp`T$sA($e%evcR+DQh=d-3*Mfv;7rI<D%g4`xqRg1 zd!vcz<b&NWS2ss8D@?|YCIhgnq~Z<O;<3SHPR?LaWug+*-WNR?f`m~;93B&}l9Ro^ zI^4R5x87;1DKqjNPUQ7WhIbF-R{@rW>^b6lXocw*vaIB9a_tY@N^;*h*HIu!MTO{p z2kDBk_n$d})dD|&xbYD4I@r8m)S%<Y6Z3fI{kkKS%q3kS#tZQu)bU_Mgcn)8v2#;p zo_TN*my1v9oSgYO15}5XH)Wfkd^R4<mLu}KZV)-$f}SkP6oyW`+i*1+P7f7G7Kef} z1u@2HB~0`SahOqGg5WQ0)lgzAaob)~$}|u<5JB|GQ>bDRqj^DQ3RFX0ddMV)gz|;o zzSMK;z&GYyd+z$4<qKKPSJOtO){nhF@RDE8$x5b3n{z#PKc91aZ=y}ex;A~f4Lz|F z7ym={gsiz1XiJi5SYhWf+9VKmbEk=`AKRRk6lvM;P5`qQ?JMTLU^Uo~MH)((siH5{ zdKL?$C8M4fuOV$v5fGGfC1@{+OQp6scG}Ja5%Xq2d791Frz_9O6heUw)E=f&JVI{~ zL!HoQRfONoCo)47uaj%N;k4PR-kSApYBcYh^Ijt$Wc2^?e$o+4LJYyZYYsGN@k76~ zzZ}@P-BieGyj@Ee;J-HKmAZCbaL2<Uxb(!LcG#Qct{#g1aA?i0UTHj3DjW!hAG}$7 zZU8i+jE3qWXB)Ds-BC#kv!%|g5c}<UM!F-<P#J*(AzLyY=c7on8Q))>olb#spHyDc zx%6#~Wo&%Ov|13@X#?1l6BdAFJEXx)yO<>OMxoC(9m^HNM5g$!(v^V*YWmTc9{Fg^ z4Pa8{vy&}^ZiWc--=83%AKX>E90xajc%wx|V5;#p^y+k9tJwH(cE8a`A+zDF_0lLH z!aRO|algJdRc&f)({nakYJG(S(7Qh(T{^6Hm+Pc^6+Xrw9?+$MB#=8RK&b;$?yjJe zyUsI??Jk&8;LeT^q7)SJmT<zZ{@Tm0nn|m6G)E}{-k;1Hqu*&Qb8tACv(xq<5ghFN zvYtF`|M9&yAG`7QV`En}O8F1n8V|#|N5SWxDF1*oHSZhS<$t7c!7wQ>?1{cUC&d?V zD*o2Fc%pNhDV6CFTVr*vBNfl~+#v{r8oo$^vb+}x-f*B{X>KUHJYN8!ynyVMxrkY< zo;nezTp9}c`wjf_X|oZ*dms^NYmJr6^xqeV&uCuhikJ$F5oxjmYs|VJqh|R=k5%LA zw9ipnI!}=Pd0nmR1nYcp_P$<-O3H=v*>A)rR%laYu8!Oc$l-2{ktr;n5WftA`foRl zjJz?9wZpQh)M&j>YI|azErB_)so3Z|S*5-4%YqhI1q^6MgefUz*I!+Iy1Q{)aOWfg z@J8d+l^GebLJrRY|KZf(GBrFK+}&^HcsHgczYp4a<DiNedXy1eqmAx$f7&Br&IkNS z-8*lOyQAo<bS8`HSxqp{?>zTWdEVp<WHM=-9W&D_PaYTY$HsCU`QnjCO4i$Nk8iP? z;WBG=54+tAi2@qqwh0M2LiLrMBQRiI`~ifdGsAaKG+ps}v>oEYolL$9p<Oynvz<-I zt7EUMA7_k4brpR1az5`GdY#o8;R}~fkxDw-%<?4WQjHdWf{;3!tNQw%ynlQnfoLE_ z&@%)M)R8?cj5h!tm*;+ozF_<I{?Z7DRurKa{IOhalW)olJ7%4a6``T0`%O+mWb2W) z*XKHA4i*cdq_@sfEDKdA{j*JJ1O5F}X~}c7+{~NXN5P6v=7O`T1yAa<=T=Q~l~P1M z3{JPlFnT}F2SiX4NjTa3c(ZWYwf&_zZFJNK%~3^|N;Bi?j}PrKfQ%&J-jpRmoduHJ z&fXvMUuV?PJX`OX10jMCK=YB2dx%F$4rkdV`g01=^Wb43JcHcF@m=21Dok$2c6Qd+ z^R;ox$uCu#mx;;fkaOVv^fwd(g)b5{wI^6@i=RCDE*AHe7fB9~h3F*QX*Mp@LB>66 zeZcr4;lO&YY@T0Roo+D98$l)QG;_ZDg>_12$d}Dzd}k8iK@n&Gq~1&9#ymdp4dtx{ zfOgG-$MyAoLjSG101L~}yvsRIiZL_pwhi<81nj)!&78%BM-qldj&A=9&5WK;dzHxS zcx>1k(yeI%&iw1MJ%PGpeiuLAoc<)<^-w7aYK-vYd0ka}QWfp-OnMBE>1QOd47BIM zl?%1`H@c`9>l{iP)5yt;`fr+@0fo3Wa9^064iz5#>B=cwiLxs0b9I`5!3D%(Ao)t> z#|fg|kbT7@`>J1-us>HR&+lRIA4?|-^l6VaoomN9QY;BP^M;VB_@I3U86Ofan8C8? zlaYDn;{|m<cnd_@#N2M#daK<)%9$shQ7RFS{1%5wI`&1Ty#3y+TF&m{j*g;@J#<pO zY+XxmMZmW_Qf;k&miDKg()wq6aDz*CiO`Ul$umTDJ$*DkUnVQ<S|{t#4Y@K{|F^(U zM;X%WK@boWoZ`|!##L!Hp}bK9>PjUC&^7PjfVRSJ<PIBX5!c?(M>IDpz8|P<Z|hio ztBUZ<T6Owg=0v;!AR?}A0QO78{{0`_ex!@-tg^7J=l}Xggs0P`loEK1+8?3L&dzdj zat{jSS1X+_%L2az99p-;F5>+C($v{4Kt=wfI>#Ey9cwRs(@XOV;g9%QY|=@Wrt=Se zAlC!OLoyh9arPBcRP0DW#(rlsfU|F$Q3Ev)*Vo^F`!sG5p94AnqMFbg2M(4L-Hyiy zFTNRsOxf>EzLoT4Li_s}?;~Fu{XSt903^AFRRd$>+FfQJ(D<q?edfE+)f2Z7f7JpM zV=t&}do5e8PP^M5{r#!b)Umwr7jmH_b5nhq^-HF$XIoRYebW_9ceRfn%n2{#o4@?W zz2J4kfLr!$BTTdwPQ888Ne(sOxF`6Y3O*+N?|KdXAo~v>8ROxYduFea^FR4qLG89y zHbEYI2UPB04mnFYY%U4!-Gi@b*Rw`Nct#d9_4hOY9Hy!Wg~|=RUFstHnHI32{JY@c z$LywH64E3TZx6GFe)46$#mD`|r;3K~$BLx`NR;PY1uQR;0<heB|GgBUkEf<eyDCL@ z?q@+xrM8|alxcKPc~2>T3<Mzu+$|}OeST6aNPBEj(^!E<3|O4_iAo9nQ8fwGv8H)} zNAtpn1`WKxvXd*fECTC6|7o(@!yJku24gFrO!GtI=X;NmA?)O~+;dKG72j2`t%S~? zLP3InFts8`w0-a?FBTJg6F6>ijRv$m)gAKH8(ca<l6GgRmZkJL5>yJb3qYkMLG<U~ zmyF^fgfa|Nc!&sIkHNXcDHkboJcz2mfyjS8YfI{W66Uj^6MApv-zJ}@%oy_&fCbKa zzYvgs2G@2#5HIpoPuc$nx+SBa`vGs9zQY47_kTW#UHoJ0{chF%&BFbvdO;G&=4_)y zT{jNBpT9pI9^Sp}@>SPJmgDZM*832V=g;@0V+VmGN4G;`&-{NOXf$m{_L14&P~3aT zd)L7{ar3v=|9j6<%?VFVMr8PJ?fjUQM>a=fl6iKICV;3~MaN^+2SebOl=i#B)?bfg zP+tl;W`-z<4_&rw9sA?-zCd`T3gXe<>otu2M#HMGkSBVsHZ=tp@p_kC(~8`&El%UX z0*#5R6pzfxnI~o7t*@Jz^&Q$MLuP-9nsaEpd-ralQ0uk?P_z$6fXn&jNS#cIuIM9g zFK~LPy|PZdmdowI3RxcYmbbOdX=G>8?>q#~C)8Mt_GTOE0Qj{pnV7xf(1UNuF^)v) zRt)sABIfx)l1x+P=^O5A-;D5eGx$B)eh6u%3MKwvOVlc#`a=BR>-gyV?-$tg?g7m% ztUq2D8p69@Er}vW4qSm%3%T%QDX9X_{RU*q+MxgNJQuNIiTPoTLa_hehvv-IvVxC% zrWUf4R@}TT0K@d?nRvLzS(C9^BJCQius*UhWVxZx+wGDsU%nXjXzf!1b3+zgklWj) zKjTF`F`<O);yF?={D5~MI2l!dj+TiI6u%h*LEDEI0!SX;Yc!C6dXaiuEXL?~R!o@- z`}zWBlk0tHpSJ90`poyj_7%DBP%*F--42aU14RL+3I=5}cGoJPg;U&kq=ZKS1+U)` zdjH1r?qCsQR>EKX%_7R7<%d-Z*i)8jIHW2+0dfZDCOG^V28zNO{@=k7`2k>`K>1>{ zbv(eVS#Asz>`k|Kb;mluD$(!{fL9vsJ^TmP!F#_z<F0o+G@AO~r5DPduBXJP6f$r) z3SFPYuYx$_xga21siACrJOxx1`issFPaDA*=msYM$nR;XiANYt#BVyf&I;44aTqIa zj~(TuP5tdX41x?HDhfYUo!#LQh##=NL>xTQ{kI={-#<b4{vqyd9bnM1;mPhyN^W5B z+nT8JhlBhpqtl^>ZvAoxs2_ZY{yKhyOn}t&rWH$OWv-e;<Ybp~0V*PjLBcaiDFud? z2AkQ{#P1JglK5rxr(jV5$v*{ENMLA8GCsm9nn>rpBTykhM++^8LTU39bHt&XNw^V+ zj{ln^`^p~r_p0j8PE~Z0_-sXlPv#tt0ic3Od!TVau2steXMovy{SDw*z3vV`*$2hO zAzprKs6Ee4miuCv+t3*oEWEdCSdhbe&<s|y_mULp;9SyCY;$l?(}*to<?7Doud|=# z!dTbUqYX>?DYqMiSJf5!!}9{a3e(a>!N1#)#%IREK>ycUm>D7Q!rsL35a~i=%K7=R zv!@C#`~IbyAZbo~KjOoQrb^d3>=HuM;uB=>1>e1o^==e^2n!1<DX4@0G;ERVlh)8k zfIr@!!`gG8^Y-tc#0?7wcuu}NuJRIneH*l1!8|~0ZFc$B{I+_wF{F<>l-?CV>7Qd} z{6bDd1Xe+TXs?9sUuHE?SlYpSd#XYy+?Lyegh2QhX6k?&txR-(wY_n;%(??}*oJAU zPXb)ga=xa8ES}So<l$>VJnw@~cmCc}I-fQ@2qe&>m~tnkbpV>4mL^Zk?G3N3I41Fr zaP1f<+Bvkv<w^y?D5_PmufM!XEux){KrN13B;?@egoR^Ion>wCw@;5sz5!r$$0d(; z>{K_3Wx4c+hMP;z?$7=jy|R7d*{yJiv5r~z-rG#x{z8I|{?NZR6+^x&vfQm#u~AS* zr#5O2B7jmjps4R~qaZ|efSV*P-aU1>qN*{o5{a$Asz5K%)4m{>1wfh^|BDL%{!mg- zA;Tx30D0Fl7<571{&%rd46mtiR+Q{*3&g9mT6nG0jkLHg=vM6k=B2@>PilRe@8;rj zWFNj#^qrFzqw%BEZ*R)17$8%VlZjj&lJSgf)JKQMb#ANQ4ul;6_1|Au*!(34RbvY% zPTa503{4*p9B`CmN+pRv19ZYYZtZI(y}*-O55T&h(1n1W6G~<_Lg_g_ERA(_jdfo! zGPc23&-$?uQs;G#qO7k@2tc|>%x^;x`0-$YnT*hq|D<b#dfCE);3eemM+@aA^ScHS zu!{@XU37*4E(80>NmwdCr}06mCb8cC`}Ketv~1U?$`Sx$3Sh|51jHHX2X1U{*VWZn z+ti#temvh4DlyP$KARn8c?^5f%Q&W3l53_GP}nZca20->G3__5IBHOKKmfWhAs~z* z6&7ac^|}Z{h3{(&Q6SG#o`y%nFi%In7aDCzpJ}|kHl_Oj6kWq_G|RB$6~B}6jMmb* zSiZU|BQ(<|2<&0avoO9dVNw@YALIC&Ckl<pDSr1nx#+5Qwq@3=r@7EBTMm3G8P7EY znqsLV=Y0h2?+Sbflq!ba`}+>~_@p2qahe2m1^m5woUB*Oj#s0!Ag0z55aiHt!XOfA za=^xbj<P=Bd9-l|0EQI<Lo*&x@b<U42Fb*V;Tw%5;$KAW^tEzbS`DO!ziQ;=x&R&x zoHOBDeK4?CVTzgl7onu|w$7mbptt2lKwuN<9o@0vO1!(h!W@cboT1>uaXnru0Hp9o zu@b9=)3zfA!&X?yK{4IK=Lq$g&J+^oVaBZ6)&ymML5=o=b)emk&-ILq?5HoHO8E(r z_%k9lr@@)(>f)G1ynF7B&gzFBL_iq(AUg!~!(Pa`u;jU(L0R0P;>8w2LkfEuMoM;@ zR`{`{W!3(y)}KGWIzfK^a9~2~Q625ALjpZhI{JFn4-GOhR##RPBZ(Z1XU1VC_)k9g zl-e!1oqSYU2h01bZ*lQjnzOtQF!eeHxvSm2$9&&zThAMj_P@~xfhO3?xcy`kZ+7<M ztQ#lpP%Wc|M=}?{925lI_Uz;5dUHFA_vltoZf@PIoLm=Bo`Et|Sw&@AQ1=&ePc(44 zHDoI2Bcw2Yl#+;e*|NCu3`0IVqGvd(Hl8p+D-J3DQR?qcnXs6iK1wpJIhbJ3=<pC# zT5BtXNP9t1xPp9>n-~QdNzn`D?Y|d?!)n-#eJ&9L|EMhjs}7dx2qBKb#<Ar}jNQQ3 z(OEdjmn5tGe5m*7(;|TT%y_1F+7|{KvxCtfCTwzLm6hlio||ini+hXKx(kiY$7^GD z4pC9@(HtK276d+cTnsc4v2}I+pR?WpakHMyf~xkrI}CkfXFjr}V-$jyRd+z`G&pWC z^R?rMg@rxg-xW;Du4QKCb{K@=#Gs&oxw-~PDPavnXg{?Klg=GIb?Elq;#<R`$WJX` z*5ukl68cE^ZB~v9dwN~Yag(`$diH3+Lj&;PHNL_f=)|TR{0LqyUUBhB^@%Sb4Z*JG zEgwGx<sx$gM;ZKRc|T*l4DTFn#ytK{{Qb3AjRh%z@6FdJ<m*!NS%E`W_sy?aO(DCR z3+vIH?zV>x#KZC@y-So5g|5zsvrYSZdv_hv73@*?J{%4M=43s22GpCE!$ir8x6BBN zPg&XP#tSr1;Dy>X^$vZ6U12IknlK0fAt4KkrF%xs52i$RMn*=Zk($5HV^l1ZR8S8B z5TmZq-u!ZW1%;8W2&yE0&%48A(QwxULo1y{NmYjNE-Y#~H)rDEzG{tMx7VbCZrPjA zMo1k)(&tO=lE6V64V%IMhN1ws)v|2!F$@Gk2Cx)~w6{aC&sc6wHWfy)251<2Pb1AX zdOqV0{rT-f@Neuv5Xukgl_X=~Bz?tg?se%^wmx74GZaJTwcXP+O!mzA+{eVh!9l^r zwc>32`Jn92pYP_<=#WiQvnJ2;J^u-wy-Dkxi^G8c9RtI3jdJ5p{B|4lHMT(Utx_V{ zO~%6$4==a3&$EQvgcUO+O$u)mue?MUr2|vnCGJ!?GGd@_xj&)l6(^_TeElV*eh3Nw zQO}W1z(;8jSjd0oFG8lVsj-`wv~r}%_m@=6)G|=QEy2Rk$XVygAUe$*jS{`pMjs@) z&!0RVSykTVgX!FCg@WuXSEM7_;NcFKyN=x%JZ3fdp&*Lq7#K~?+f<NX0`^+ED<lMC z<Jg?3uI}#H26wZ*TKn@SPXI}L)=_(Ub#;|X7Yy7B&U|2&C>ubbFo#MnW1%LGg!`Ma z0C9aVx7$}&*4?5m)l1Bx3?f0N-^Rc7LdAPdtcZjv%Z4C$?5np7M`QG#idW|KbedpH z6{Sl!clRaY1hkvzyE7tC;h5Ftt_W(a;}Zicv)?z)RC7{C$46ERHMXnM>?A2oH&qMi zh6cC{G$YDch8=waDSU=3DaKprVj?11vAgxnqhq79bNt;nI`&-vU&qtGZa-sVKdo^+ z_p3VJZz}S@AwE7hT-JN^j|*{?<+a&G@h8dPXG*`@&E$NGPD!`ZGSb_0S^kX)9JXtc z`x;f!TuG`8E*0TvX_K*l^#?N}(0DvwE!@>?EKL|^<>JXz5)Y%z=M9*-`D{UgxA!|Y zH@7;Loer0^-Z-=5WT*kBeK+8oe5rSLcjx%|sAQ7Fp-l`r0_GP7Kz)U)#nLk`u<`pz z*Bro~n>)tPTz>tR7NA4aJi=>Z{W+G7aL0!I22jF>vCM0+>z1iSIghiG%hVp_4H>Sy zJ<B9QASCqD5qMCzxlI<Y4}2hfI`4VE2pYsIKcu@A=0imbUWHo0vBdxCU{l$CiUt!3 zS|(m+NQ{qvuw1AuP)#!jbhI9?rMbAvboz5Fk>HnV<YM9+Ky!(#dD>BH-~7a1`2Ld5 zqrRY^DJ3PM%=U-S!MYzB6BCoL6zS6PLZc^hjfSPRwuuy|2dk~OVcXG+ZtiY4IQWwl zKcZDhgKo7SrBW%0buCO*=apDb<Zck;!ZXt{?^R<+I|3ql#o|Ak;gntez4eOnHyxos z_sK*<Qw^Bm!A~vGj2hF8TGt}o-8yAu`U~|nuIqcCOtC$#))xuBvR%#u>u8|Xe5vy> zp;%q`<0ntBFtGwYs%Xq)n;mi*HWjKauIxxcNk~XKLU_Bn-CPBo&iCfJQC&`2#k4Fe zbOi4+rP%35Kt~IBGuzxW4L9X!PYjf7=@41?oUn+;9G57x;vs1iav!eL;$74kW=InS z5$dYuVvGMV8Sc;+(Cus2DIXoVF;y}A<a50`xf;t$!4z;`UBSg(!6+?NFFu&rsjREA z67};pGd7ltd;61xQ=Un<Y#r8zeOzt@8U|dQ?hykITvh6?-6db3CQ!DirY9ls+@GWG zgZcXTamXnZ7+6&V>lfK6aeGkmc6I9CpIKpv96j>#`-i=5dSh_$gGQAF7D-P}=cxI= zL)c!9l$F&%Y43Zq&aVV6>t-}7E6gc*Wr?3AatNW!swEDLft{_RibeVzxjoR)2G{ei zNKdZLv4{qXJnw(`V+3r>-(E-MPZg+@Ijrw#NktNgLPf@#z7RvYBo1-tZbRaF^8O90 zqdTTQebG@YI)cf`Bv5*`;y}L!aL5iky|`8}xi2%CadmdZl4G^l?NZ2urDr`S<z-~C z%dQY7U(GL?nxE&)Er7)&C%@(!9K^nl&GoygDv)DkVWDIFo|U!UKUW9O*7A3t_tc=B zPS47!a*4WVv$eCgmq?ZrlTc8yyg6F!>0W8c2hKJ!@c|=UjBh75R#vs-<jrHn%oe9h zIErT}7^$!yFcl&b(`=L~&hY5y+)d5DLoKyBH8u4ZkGT}y9ztLXoSi1LIc7lNls5$# z`t#anj#&#C)vfp@W_2t=6`fkt3B3CihtS>i<xYNnH)>>jJRP4C;mad7E@*j9Xq=h} zdtI$z3+v9iM+ofC*?Iqdh1Zd_gY|1NFwQ>xE-WuD6cO2rVG<UBD(ah#we~+8h4m_w z6cmwsw25vL!0*s))E2oCsn~u!%J~Mnzt_u@oYChS(x}D7^Fqv_w{IOS7hJA@P%nbo zYH8^yR9ZAt`H#xK68_Qm=lcu#kg2{z+8==0<f-L>M#f%b)E<#h3THg5QLAff-_ZVe z2o}v&TUQt=t!L-u)YQ3t3|aha1M7`_2NgvprQH=<(Q{{sc!|J<pFO1%091i5d2G@% zAK)C2F)o4ZsnT-J<$k{5G08w{t3g{)6CojCbXCN_^8jdiQ5H3KewaKt+0t5+35vQ% zHisN!d<W!aZU3aFXSxUGZ)%bMcm7peS+E55E%D%@4r#eOi!AZWq@o&pB&4J}VfXkn z;>VBQM;Sf+)wPYt7^E-@t&z>Yr@+PqE>cBNQC`s$8y{cQj)j}Dtu=jSkzBNyoE%8_ z?zlZ0f%eG5!((+fk@>|7$Zhs;WEj}6BRDd$d&bk(ek+}s&xr_+n&Z{p?#zCeAPtvt z#Rq>3f`nN7gxGW=!?l%_zcZ-fg{gy*Ughl$F>mGl&G7&bC+W-WUUdS27O1CRADkS~ z{lNn+-4h^*+gSOALoeVdhWP@={qW)jEMc}bJ)Ahw3JN~(rR8Nxe_vl;IogB_Wynt^ zk!BxinG`sh)6GT6L2B8j7}M??Y!qT#0St5xl9#jTCEw)PquC!JY$1>Sn~$ZExLlpk z1{x2hz7sZLVJTzMto}vDGPr$lGgSu0VIL7ErkuJ+`=$cZ>Q+7IGx9hsVV;w+_2BZc zqoX5knA-k4PMt3@KF`UFf&i!0Jl)jQ+U`vCg%eqLOc;T#rM87y07$|9M`gI2M2jF~ zZGRf|mV?7#Kbha>A2h(z$Arazm(^IUJwXxL!Fg4AsiLB3dTuU|rLRXd-Qp4vX+(AX zt*wRZuM@uuK}EFgnus>hm}LZj$d=b(c5qNuTiM|>SBYP;77~^<5o}{`sn41Sf9&&R zZ~l~)5w@HeEJjNUWdo`j<Q1K_Kom4GWGW7Q9uV;9$B#C3$J^Vg1Kq@e0*1=brwG|| zxw)_odIm{x@sRtA5;`885<Nre4=qtm_arayX*6{!f{sv}MzUl`+3bvU2V1_p*G7*a zI=wmtQH|Ge(?<9HF8AZVh`%Y+)RYin!ahdFL#{a~t)fu}WWK`GqM?M0uUsIw%7y(| zG6_SPqM||uW@g))n`-${5j|QU$<mprDubh*o(8TpDun`d*K-VXQXU$Y`Q>3sY9k}E zaJ`c8q6OI`+JLCUa6%FYgaq<?8RzKoCSDo|A$9!I#m^{CtA#z_L%VJd#z+x(KCohY z-}I&xbQ73wZ!<A7>5FI2WBGZ2?A-k1zcZx6|71uMX#z0V*;(2DGeJ_7jcffoT~ebv zSJyD*1omfK{p)XTi00=R(r6Vj;eHk7Q{ixVd4--a?u5Qt$Nl*&r98fd`u1SbqQcC~ zwA^O0+U0#SU1NNrYZ0NxY9?`S^+k5)8>*VCzDGv#nH&uWFRZPudkUr)un*>L)E9*o zZ74ag?r^D1fzj>2Z@Z@?83f9)rtkN!UoRRuaV4lKN8@_l+_@&CsH<?%XY!$<*4s__ zz-?@~fuol_2`HxuS`7Lu7w+7fZY$M=ni(VE*%xalI<}3Llht8TY&N6DX!aGz80iZ+ zBV<Vap8!$xl8r_{pi#>o-LPh>H;xs6BDtldb#--_e*ZwGW@hSKog|ZaqTn8Cjc$_% ziv{YH*bS!94eo<JNa3!QLutODGC2xML?H&!@@ma&IP6pTwO6tn54UX;2hd*u-$D*g z594?Yks&oTT9T6De@hZEHU?H!A9y5oPXp3>V7|QP_7vcz92>Ikpv9Zuv|5JK+_i|3 z$tx?y3+P`>S9ltmW~;2>+SJsXlRk~&8(2PWOJ-gwb}DIEYU8c65?r&pnHtdr{;@U2 zct)*qC!k0m?mpYgAq*m9bs3EvQfzRw1LyNPXl&<fccJR2N(p2fau^YoEW^VX_l%8l zLy@#2xXjw}o$IbH+9@VRDvKp+{Ye_$d3UN+(oP_2eEsRSwDJFyx819`pM7w<nK|F5 zJn!x6$rBPd9RL_bH|Cn)xUhuSc8B%f;S)8O<(Q%}^cHV!Hik(n(@OWxMs);yG$9+* zZr}WTMWL8-z?(+L@h#KuN?NodDI^5U9FR&d#Y7w{BviJ8PJbza5AuytFO5bt3*iF5 zu#9bu1sQ-qF%}xPDGhvc;Bm*pdCJX*&iGC~4YsT{719u7zG5~q`ScF@=+UE~APom^ zZ*LF<py_!9{GV>V>J>B<UPKr8`-^%!k}2N=69`eWaHZ&ce_p8v_zl1zq}CU2C<Cp3 zug$D5!jy#eQ%_G7dRDd@=!-bt)IqkTXQ0@%$YVcD#53x$Q*AAYv$MsY53-h51gyt9 zOo_boue{@Oa$;g)Y<`Mhk|CiJI(1BN(tI3-?&Zp|xmu1(zLnUluo%hI*`N2uAhkh3 zo@LUG<*_$Cg{f4rE16#zq|IQogxiFh*W)UE5cqpa(9xfw=e{VoU^RsbeW}`?hsYhn zYJqgV&REji+#IUN7T5`T=fX<Oe*q6^x%~{sVo80FWFOTN1X+}~tOI*W2H23k%BmR6 zV)8UlIzWc}F_cPE@}GiK7K;RRV?oATsOj#uNqD|VM~Zt4j{!F?%={;*2W?lhYru<# zQ}F7ZtTP($ZgAzX-+9GM%{k=Y_Q%Ix{M)y*NB*HNAtb0I@&y`ok0Fe9suz4*7tWtQ z16);H+zBlGvM<4XL3TofDn?ICy#$#=m(q2i(B>vV^Aj{Fsgg&+u6m%iv!X}!_wVcI z=nIvpK-5o_CY8Vm%oU2FD(Bs+J$lTLx&u>j^>{z^HqL)>7vn!`13G}B_%f`nQl#Es zH^qV*I0lk<8~baHJuOEpEHWPZZhK%=*VC`Bug{cDpkkyXz9P%#t^|S~g%4WQqW<OO zic;&35oC$pDwIXUM3AR}4bX1hJiuSj^qic-mXEOKX1>t$|CzR7#3V%#yd<P^S!>Dq zijjh8hlNGI0MIvZyh$@rI852NAM{08FXQHxBFu|aE+!`<A|m2en>y+3MOnXBdu`cZ z1>X8R)|sPHtqcaWyZ88mLC#;KqYsI*+wbqJt{6wKJwDn~4ts@8^)LSWkeAJYyez0V z>?H@VJwFOdDbhJL08rTJb5?fVWy`szP?aJrccOFY_pu!r63k>|0i7<LFGSiIc`4hh z26or}N8ZN1s>rjG3dC%nVKc~HU(wU&fnG(*jd^&?+AriVu&}y5%>@Mq(D0GfACW&s z5c<&4TUG+Qy`t^xwmv=vjyUJ-vm_YLH08rRg-uVDz~i&CC6hRk!mN9wD+0thsQuyp zov<k?6*QKMdlN@Kd>;aSOnAJDAPu|?s$#Oa3GQ$PCAVami2|9pn6#l@?-kX5S58yr zB6n&C2wOPq<7G1y*H-?*fgm{pBah3l+aPYgPBM|#k?F1l$!eeIUci~|l^#eDJT#U4 z;;efL6{v5)bAfMIXeI*us>`do%Bo3pOUVqj#9*gt%xn1)qNc98RP`4q7P24*O%v7+ z!7>uw^7YYUOhpNKdsG;m&@RQRrQ^eUhBrRKigCH<`W0o|W$SL2;q@lRnX@<b5ll?Y zy>R2qhK4sns>L%Uw?#ugMc%R-PZ8L^tzBOJ0F_A=h+{WX?(*sgB}KvDA#%tW@BMod zQVZX*Y#lLht#q%_k7P<myl}W2HpC74;r*_HQrZ8eQqQ;L1`%p7nt@XCM&XgEJg_5+ zo2pwf`S+|M%N9S$?CJ);y6EX>K~2Xv5l9?yJa?yB*IuqN@E~LKJWMmldq>^S<apQD zxdg#^W0!sUPy%hN^=VLQEY!Ob;gQNf0aEy+w=a*oD*PY->*1_~EMS~1dnTXZF;(Y4 zOafdDv>fe2LqpqZQn+DBNm?K<anjH|9GDQ4P~3OHm@gWfk28zEGt<-m%qaMoo=rnZ zsWc+?j{o(GgX3cqu&Wz*m6esU46}M%<=9W@9N~M2*#80gIwW+kWktQ`{d}F{ApyZ= zFxZ>Jcqre~(^h}Eus1}B>EE>N>QX}fy<S>E-OSfREU3nR<!%<If>j!r$w1u*j_kf2 zSU>2?q2&Two3?-0)@-6crzrcC&S-bns^xUG_4zzM0~wB?;Wf9d=^G`4?+lzV8mgT! z;d)hfIl<WTUQb%m({a+Vamtkx6_=M6)~#!F%9`ltIq8<$l;l%}CmxQXZ^`ufz~O1T z)<>Ntj2_6qn9s&G>buU*q-A5{Kt)E2Yj%5u#vZri7*DtbUQi0g;H|$QTd07Xp4@$S z${DN>&~meZy%v8AjF)VKzkUfRD|1j#v`%zza)#1t5_fL4KEK=#bblhmsQ5ia6e=}3 zDp%~2`!oAhQCeDfSaMi$oLmcgU2b&J?U;4e&jT)U^5vO#F736a+rljzR?`$$1#_r% z07L*~a+Z-%aEdPPjE94^_WUlGBRUOqsFM}8Mh|I|{gL7SnTlCiS?2(8l{|&9x?K#l z_!HwYF<?LAa@LdqP88;%H04K-1XZ9Q&JJ6x-+o%Z?X6DMl<Ea1WT!JDKupyG7Eab- zR-4kM=-Y79+^N;iT$hOTRCK`vn~aS77Ii=MOCl2aEK4HVOdX(hhiM5(bEp6zC*gBD z`Lp;l?O2{+T*uQwquLlkzNthqUiP=|nyx0mnmO_{I&}RX<lG#4l|X|&<G2qmR39KC zgjqBk4g_n}5x(Wp<o9vpmz8+-^f6g@4q}hNyIU&y>s{ZF0ldgVA7q#Z4I)$~g^x0= za(6l>j~!xBi}#|~ZfdwQ+n8*4Xk5F=GU@g_$sjK!Kj=hoy&o)!3+2wo5uPcXot<n} zL+071#h@m!+Zg<jSxWc(KP24fbC8Vi^A}|q!RDIq4h~!VLHq-p^!cu!SI#B!DgOMa zP(ia^i5U-K_WC!E_U=a3w*a<|`Si*C>Rcbv@C*g3U<wfl38RvP?v?kOA75Kr5mE49 zFhiz$LuW%jv$0acM=@ZdB7kFqgFZq?DQ{tWiqbZmqMWXqhOUQBMdL3lGl&4-9K?U- zmvL|jiR{^{inHDPr4$K63Asy;ZrNx~ueC4`gjT_F7U*>O1%AT2xoN*c<8n8FLw`Z> zii{m6O1VJYx54Q*wR+td#>^p>I)_z%=isUQt@hNX<^m;5b-YUA(&F=BQ;EMyC1BZm z{(R=4M+LYg0RlgHfRsWZO9s!~3^u(z%`T%P83=SJ>V9!uDb`lYs!&|q`?&fuP#~s? zhN?pKMMLjyxDP=+>(SU~t_NxtfLDNoOoy1qt#h)qb+VO$pPrSPIxBPJuYw@k73{Ia z!_Aw*<6i62+4=?K=rzd#jIZdfTuv?)QaqDYeVpGX{aQx>Ai(`~6qz|#IGBbayVqlG zH#rdy4rAktV&bBNp;uQ)P?`A}dkLpv(A2^=q78Jt1H=5y01@YnyZhbEK1tE5T<yZ0 z)ST>1kgvWMVxbm0!sdGjDqf{1sBS{gXk6TH$VbA|RpwLTP;)&-?fPts1djfG>JK`8 z*O%7|4cn~7gTDxSa7-IU%gYa!E!sF3KdZ_fr30$wpi2jEWBPzVN=T4^ZkgUYi`9}| zcs*2l!lXVGZ%F?*FSqA)(mb$9TdUpZ=C~RXVtM~UBwl`G9B1r-*+w7_HhO$>t1vvG z3Pn2GPXJRH(pQ`?wU#w*LO=ivnWB9_K4gmHcNUEE3{C@r?S>=_25x+n8Z^S=PK~WJ z2c|&Q-GABLS$&G*-*S1y?hk+J_NZj5i|;S8<h6Bj2r7-O$sZqv2o_l!l1_N~lKDlQ zMC9IibPZ<^aaf)lALoTp5S7-R7K(oOFb9gv(hhnWI%O>uF!$hO+VyTY1d!7$C2>>J zPoI7y=9>rN_RTmBZVwk|1g`a&(v?u(-z6kRk7wkSgoHRqt;&k5;o`mvC7F^*@i@6S zjPK8QNv7@Rd2`_nmvlW>mXph=^#<$#`^ea9G7OB+I94O%fkZBAvV;i0^K&_u8XM>h z<B`cL$r&2VUUeVtH&t2AQ1L~_gyl>bJUlvtEiy}O0m$m=`tv577tT&j#c(P~eCFD_ zpwC1N11W+NAH&hq=3FLP$mF2}=uobt&(py8x6Uk<fw)m&)#Th04c2faBjxvIcNfdr zx~U^WKOGz##spnH6x*H`+O7{^g$)4j5m-1aU;U+mK;Gr(?jHJ5z+BJ>I2s>XKqd)~ zmVEHnyKeClz@SV628_3Wp;BU=01?jE_`>axa*7{eD{SIQjUGWsQbA$aR!>i|*KD!s z9R|r~6l7IsCYekRrkt_^E~IPxDqimPA<&7g+8hIX%>!^4i&Y@0RMo)PTxe?g^5wm} z&2X8~?<%Xg{+oDWfK6NkV2y+;L`D&fnKxIcc{O=TWy$7&Sg<|g=@k^oR`k8f?h=4v zF<4<<aN%;Np)|cP$Gv$&2mz6!KDeh~N`N9}@bhPz8l6VB#kI9@JF>yll1YZub~-6V zC1I5XBx6}11d0E=Jq`jVXukSRU3?34cLGAolB<(#YQnR<Iad&4hjQW=h~9ujgQweJ zc9OTT5lYb#Jq?m1XOx!)hIb0;i^qsr1Buh6&OO(mq-Hdt+0>IkCu#Y!8(&A>Mt6p6 zLfH%kUoAEl3Ii}cLS7!8Ewj)V6a@GO*_m`BScB&|IwEhj_2b4@^yJI8b&i{HYV1iU zLVftGE^H9@i<7Qdw_jj&1WlsA!ogu4Tc4kAJUK!w1OHg0kQLvBiLezZ$Z3g<yR(vR z`1tW-T)<`J1H{vuqsP)u3u=%)ce2UQ>*6mC_-$f{R5D+N1l~_9YH84#k%o>|O#`E( zDn*N7t$Qr5ue<{EAwGR!mifR;XY+H_%(i}gN;W(=YCN3&Jg}|TNFM=5R`&b-Y7d?? zI`!Mv@1&J+%XU*A#S6H%7i!g|X*YQsolHe!4Zy(z0o3MDtfpmhN|PXn00Y_?cI4Vs zmUHk<(?7pJX^gsticq0uBcA(nS$gsCw-1ub+0N_Ns?y5iIjxPz0NVw`^YQVi^SOWk zXUq&#sjaiqcm)nATkns$-tTx0wPSvzn_9sRk&0vM8f&BUZ{fB(_+w3-^;PD1U;H*Y zf!^&*u2Nex`L*pxW||?{dT)xL(Vg4S_+)G>C>W7LKYZ~?l1_Z~{CPld@NIkqIXUCc zjIr{VoK2vsxA4PYcIMq*UY@bv5Q4h*_JY`DTjTtI{yOYTc7&!(mz%I!FSQy<#IT#D zQ=s;*u5qXES?{IT7U^qCh)E2@3M`+qn<*+0#_TBXkYH0<xy{dVYionfKq%sM)<0xY zuo?<=8XN@=Rs-?&7dqBg*J){J%FU<JbQbPx*ZbL7w&ag6Ra8_KJu@oI#&2po+~ws< zTfSTZA;KccQ_#1HkXvu`TNM4+SUg;Ncx3d%**N<^H8v~zF;mqF4NkjiUkDr(4GmPo z^sjY+(;b+;^gg#<(fxNxQc?;u9>n3vVeg>d#J|N85`rPeW+!iB1ArknQqqC0#dISB z8oJT5q-6yB4p^Dxe4_=ggZXD;8c3H|53sTif?e9!KwDN;K7kaV+!09CO!5~M!5jh& z2Jj{E5lm~qa)*n31kaYrQ^uK`|2@-VR$frB;nI;qK;Ut{cR5#AWw_1Z=vdX5AsCKN zNXP-}-3VQ9>~Y4sUyO|yp;b|_vfB5!cb{)!aPswqxnCV^-q)-gA}<NLe`~Vqx*g7V z<bGZ2tSPU+XwN$u8;egwlmKwt#VWbCZ;3dq1YFM~g?{l{Fctt*aT=ABga}UsyUBH7 zJ`j(2*7HEf{D)L&>B0qI)=p4SziA~$BwW*hmil(RhY{4c+*~_T4I0g=jg5_1)OU%O z?AJ3E?Twefeu;-?<azHUopjQjz)c>TKlMlf;1i1e4zj@INe1{h_(v_NhD@wS7b03x zNf9lV@kzow*;DU6jB2W!A1-$cr1&>_;u*1jmhFoAgR_DIYMtmly;IO!RFglCL%FN7 zdla;Dt1)<#T3NTb%g7hYZKjOKv{0+>U;L3{xE*$o`VNGyh1NFEaDtA5iHVZm;!o<k zMgajmoj?Ki8!m&+Kjpo>i{l?Uf`}u+!uFPyFc0azX~^oDnGq3PXKu9Z0ufXlA%Vqo z{iUJP#TVye21Z8V>!IPhvkssj`5qQsN$_a|^q#`)OQ5HvH8eC7hKkhI)Bq{hyz7B( z??%|8N9V25ue!T?LA>$PzyMHoZ--0@`i|iD@Z>Y9y`;Gyg1tQwu+Loz78WqzRg{;? z%E@uNU-j<RISNuz^_P|%A0E<9c$TCQ>6Gif+ZS-h#1x2fScWRf{sK@=UxJ3Z8Ug-> znW=GScUM+sI-mPl?{1ogrN{j57JnoSb@Yl72(PlL@rJahC`oA5Q4HwuWABc4z6V-Z z9Ht0lzzif~-v}`52oHUw>u9R9nlHWdkbMEMP_3FDEOz?wUF>nTdw95lwx53!D#pa9 zd2U9A(#WP_L~Bt%k~9WCet8vmdI%R7#1BVODM$g2$jNntMH=b;9Om-Sd$EAuzY0eC z`rZIBVXF2f7{)<~v%jApnev2PrS3GDKI#@06*amHrxZlJ4v)kpxcqkhQztS}voI(z zvHamR3p^t|2|-ygG2pLX(uRStKzQI7`SPsH2&K+qsML33e;dKmb90}Zj+XuC^pw$* zj$s9(q!O27cdjmLQuRT~)YDZ{T^$*Xs`CmS6h!0P=+yxRa&qwu=#@u3eX@6Zon~MF zcJ^tg{}wMmO=W6ojGR#G$Z0aGy8200Rt{_+R2d&1U(C+Ml|BgvDFBc!t@Xu`yOip2 zCWBU(m`9pBw^Wo_Cp%LL>eBu5{e`L#fq@c3s_N?MKYn}?mf}v-{8=c{oY|wo6sXPK z(l6~K@M}S52d;P6*rax`h@k<=FH?9R7>Nk+@d@!iN=TGUp=~d~TY7GRxNQYb=U36@ zDA*1tbz}1}gFaG)=#b1$A)A*7kt4As`cI+B+S=?%&kz(NzJ8SvZj$76U^wsH+;}h| zA&5cWDMo|?apCJUEzkXzY{sb@&a@n0^WU66Zvlw=UHHk#LWdsnLX}m~Mmje~f>JqK z+yvVG5mgJ>)~Hz1iZkFeTl_;eOwF){0I@7l=QdX>2%V@O86Q?JHIF;sIx)Oxymjq! zIcG9eQnpka-Eu#MIV&(;2j^vH;}bdJ%me^%7gP`MjSug?d@TX+0(I?LQrefBvnB_( zp4qzDIMy#f>^G3iv+8*7F}1ArSDAxPK)6K^bAGNhA9$&D^jBM<bo-a!7rKo|48OV< z`alwDG&)w@CsRN_=;PCp=7WTOh4>WULYCc;w5aPy2o*A>;-*6-rV&(_WD-}g-wzm8 zYVylZfE`JqvJ~zCTu8%_w9peSn(UZ3wGxCVk#1HaTu(w3z-VU@5&|lTxw*MJD#!q& z1--pH!%_6WK#NKAi%h-T*t#U*_R7OGT}4UFxgE7muVC%=%HlOy8vNkEhO*^P@Ixy; zG5x54fPf4{{0;l^(o#By;o<IYQmxd;7@lfpCHO#k%0#oVI0Xn>`{$<r3S(vMhgn!; zc!;UVh!P-aJ^og6l@`E;?)JNifK^Z?_VZGDS-#}uJOM3Tr>l$0G-%D(Gk>>PW&~&i zv$<RxpDxa)lg=1~AswM45IIqP{v3IaQGYa|elpA#ZH?|4r4=eg$$IysCR3%t^5Wt! zWo1P9rO#Z_(jEJ=HAEzku=wzJkl^EfPe_T;`9*&@Jy~dx5YGF{bbI3&hRfNO5{sOL zme%4s7ZI15@cduFq9P*6{O2;Vvbv*r**iN$h&S(tl%0hyhugR2G<wCq0PrW5j?M&Z zmziU-+MP%nwEIr35Q*u)1(ni-&h#qOp4NdSE`n`wJeRQRFXO*ezB^O7H`UbSK2sTp z%S_9|t$$VSIXkNc3c9P@++61OElkxl!os4i)vgaq|4!1j{T7q~O!nu%4ajYC(FsB1 zc1DvzBbdVE?R*Yb&Cl-qC}No_;Ea#&v{{M-2y7bzL!h%H_98XD9g)f3&j_7(JM<4_ zB~8>HEzOq@lkA)*+|=w>3z915`tKjd^e|54=H$?x(Q$J-lhI*Ex;_dzz+=vmOdup6 zo|6<^&q`5u+%%^lXKaC$`L@L$z&kmut)Z=btDW80%meIW*k$J-^*2@Ov6+5;UzJN7 zso&LD^6gw6`%1*zU9UV3%m(t?q&hn}dD-vb(M-8lz{|02b~Z8GZkkJZ_glaj5wW{> zWo<Qz-Zt}%LfK5?i1lf$U@HgC5pqOCBcI2O@%`NsQUUjPK9k}0V4?uuTw?4FSjpiD z{X;eMX0?Bgmmv-813}x_^L*gudcUdp%N%e*PZX+sfOgU5fLaj+4aIhL(+N1YOC6cq zKG1)Q=m@^QkTZWXe*<SX?cI>m7r_eKJLl#CiKl`Tnm+l@@5OJ(jsSP9(kCsg91Tal z3|BT8Shfj(Q#uH{W=hcLn|CyZ-v4p9yNP|PFJ2jv^5)$ICiM#qw8%u%vYcqJo%HqD z?e$7PZLaCB23Hqi-e}ap!9j+b{qj2GP$dgc|K)%VF4@_U<I|wjZE!h_Z~FCV>1)7! zqF_-@PR+<rSeW%TeJ|$U0h3L!xTFB6Hd>zL<!uS5y!jb(69ZoI(5USF<$3_MmL};x zh*5dRlM_X8J=h3aem`3Lo|`!^_4ntgL@j&2NrLskY52*1mLo_raZ)k{H>#ZHj@AKv zK%3{_{-~Jw?-2M>D}Rc{bw*|uWN5m=tQGe`UkgMhfb|$lR>^pCX1;^b)zz(SS2tO! zwC#R<{(!?+Ei{gC*d^I+9Q-JlseB%~YAD`Yh=kx(OY7f4>-stAI^r=xYNeQz1U1=E z4I&6CfQoH!rKh{`6eC|QY=;(FN%ST}<SPZ*@O?x<IBjY6MIm<N!aYC%GO2x+?y<sF z7)r)lc2@GVjqL3AjY2!&4po*eC|TtdW+RyfX3o!zf}+k^&Gp_thU7$*2DfJo1Tc5k zC_ov*diu!I&UV|dci<a-Sw=OaubGIiukAh_DnQ~C+}U}_!Xu)RKzAho7z5d$UwqP2 zpevXT0m7YV+~`<P8p;Z;eCG1ppH@1%z-hWuZ!eu|@bdB=A5Sxyga$`N@ow3(aaMs2 znH<r=NM3$oul`^`I612}dVl%@FbK2~z(P})7<`qc8TJOK&Dq%5l=C$YCqjs!<;IJ8 zx6=Ore+CUBSCdzj!C_j{{rp&Vn7pml90}E2@<0AB1s&{ue?g@50Y-qCeBu!SJ%{%+ z%mgL`WJ_*1O%4h2KSiLC(M%q^aIjH~k_Ap~H&{clhPEe$fJW^b`zqc6hvj_hA62kv z3MPqLU)QJNnebMATCFHlG|=nhx6dzAk}69ua5&lCykUFuJvv%1&^;a);Zp6~(t>t& zJW~W_N^G-|ljlJPRZ|{vAj3}0O%sP&&3hyW;b9)}B}9CH^1Gg3qxGzQ-ndTSM?mP} zu$(nEw3LQA*FUzkJ^p}%v4(db?st1U!2RLLZA4+A@Nw~Y;jItcL#qT}%_?l+19+h1 z5<D^Ff@~VI?+*2pABh3P{l(D8AKj9ItAG5CSXe+8=UUHukCIGAjjCiG+svcqqtBFZ zaLA?`Ti$Y0DxL6A$C#P%GEtqO`RL;m)E+QUeEn@Hk-N7bIV?X6J)xw{iSO{OWr`zT zGZImdi|BhVg@v#c3%b>2=VC8-ON`FVRJG8Zd~A+BCGrb>`3|ZBx_5%6N@Zoox2dV` zy>+{oo7k-8-2kbE(~FOgYRST~wM6vd&*I)00F$A1SG^`=dXUro1syg9z|N2j4`Y^L z=}oyyessbi35$=OZnV&dAj#;jd*oFcB5Zfr{m^H~X}((S7qe!iUR%3Vf<HQu>3ma4 zV!fM<xcKMKodpS1!(}XiTEI(OoXqdS=X^B^n!OK^i=vb8eH0d61yU3s(rEBFj)teJ z<{#fD8m)-&o>G}Y?e1=z(d>ig8~U(uqQ0&(GB5&(ea2*dMo;waWR30MpWhKwQY@_O z7HPSJpo{Y5@j766+2XUG>+sR1h_G*`7417*+JJTP+Q9;Jep(RIkr5Z)0^NbKG-Wc3 z4As%`UjRJ@?SMEtrm7kmHpz~i9ffx)Soe=?7NRw2xO<9Naw}jl;o&a5T>-+Qpd-Q7 zOS~=b=T)r?2LN<L)aZLGl=L%qSoP>bQ7MjAm!hcX43M}unVXvO7<NZ)s}zOYJ7cCi zMGwSPS5u?a3+6*G{wNZJzex1r1p&_Oak`if5*pac0$!{;ksTIptor%$8_1^pXx=1E zVV0)jZ3F$)bu{+bh!OVKPNn%AuG78tF)pKYGM8MyHG<c)u-v=5qYMcE8O)VCOMuIC zQC<_oW4f_jd|&d$N7@B641LJv>|lM}3+(_!dsPdxlw;cy!aie4N^^5_*KZDWfyHEc znkR+3g?bt^|7i5NUx4s(P-QChL_^E1motH|sp(sYfaBdw&GCBRV|BKX2Di=bd3RR= zv7hnW3|bCHC!3(R^-Ctlb5E<^^*T*~mU|CET*98gU%Kt(CRzQ7UF(OHcc(GN3XfuX zMrm3V`<Uo?dCAM1aB4oj)1C*W8D4=#B#f7xeFORsMy=YfVb(w9M-)d-NVny83;?LB z+Kk0}S-A0D671}P&+TFt)Bn#8<`%3b3Skiu2Veup1|hiyuzI1PRv$lhUONKQQ=_-{ z-3zmAV737j74~+PXy_jJ5vf`S(1o&O<MO08KT};QfM#$(r@Gn(ay?Zhlfs`zL!A;9 z=N+Z?C{<)~Anw6c!`#&sQ>0k~Og8{(Q#8*L)&8_N$LpvHo$C?gW@_@{v|joO)HI6S z>ibl4wHCAW0m9{=e^SXc{$rszb}+@Rr)&##>eiN*j}L}g9If{O5TdB0go=vl5*Hsr z%v!0zxvUq1O3J+?tO^Rb4mWrAB>;=q)PR&rD=0`Lq&SY%s*%r@w;i33Wu-eqf?6gS z72P8`F|m31I1uq;iCQ6829=A@(b2mWSF+iZH?t=`?M#*&uQ9%uOUts9Q?|q=Jkwif zY=~iYu6M!dqhB#GHO6<`=Ga^h05b>XR*fYs4FsQpo_9CL>pwOLHhq=K2oM41q105! z1*R!R%U8$2D#v{gT;8xSjk*GuyIGQ_Bx3*T8$`fSd=wY2o%EJXnTJ8-hSH4QH#dXV z+1}Ll;-Y}lf$k8MM2|PP@hSd(Ha0bBo?VyMSI;oqBu00DE*Rc9+x!x28kbFbR9ZSe zKhHrfLP0@=2?;a?PG_K7PJ0`}&sU9z$dLBv-d(qn0X9&1eso5a2AiIa$dc^)C}V5m zfQyFDGpe2uW-~rv4p`*usYj!N!}9W=w=t;D&8L`$wkNFz_T~&xNpvlloQIVGnrb4& z(c(XYO3Ji2ZAnE1G*37)D_cuTTk>vOl6ldLloSe!$|Y5@i$p4l-|yW|w-!{2aA&UW z=IX+!cfl4AJ3ACXlxK85OaPsjz#-LK5!EpXrFcisIN2J{Z@Y%JpK$U2arPEKS%qD= z=mrE4rKF@pKtW0r327umDe00BLAs<H6p#{;mJTJPQ@TW?ySux);Vl0DoVn-Rxik09 z{f2Qy2jScM+wc3XwVv9&I&sJ_eUp=Gh!&vWpdV4Joh7yDId$!4JPaW5+_>)K>@+N$ z&_SmR{ryn>>^oguF;5m|W?$debBl)wN};Z<=U&$@+}x5EC#&2q8J-0D!o1>pH9g{C zwKP@+wmkXfBpsV$)%<4-0Wc^dy!lc_CZ5Nrr;kCQjfJ_j-&$6->o|Z!O?39(7eDCa zMh93#E-JiBx`5A$F8c8!E~6U|ox5a#Qj%kDp<w>p%_!Sy#|jv57$<R`RdM@eRdn@4 z4V(T7JZ4hd8)61Ud2sLcEO%L%sNQ??N9D0t_?i_?*{VbqU5OvT>X?(`Y3nSJ>3Dg+ z*xYXa1sX=4-;pTF1xj+l@X7J<ihWN2u)z1WK#K5Md0}*t$Ze8Kw2*nx`7MI{Yi@ZN zM9QC9G~gXTtd#Y}fP{pmr+)zESXo73ibgt`fnUa0HT}Q%rVoK6yz3hb!ejKgtfR-J zUX-KKNXWc8-+2)1>rg5D!Y=Ta!F|EUFkg<<*jW93hlFI2Ry^o-@TaUXfGJstuXHSZ z(87W`hw_=t5*TtMbMT6xA8*jnz5e9s>T-E`OH5wg%2Z>_>w~UtvaW**9DW}ch$r>? z!9R*17?{e?_C9s9N08z=X$uSDZqQ`khcYZ396Ln!wtLfzCE%B@;4}AVlm9<qV;<#o zZgr@nj*jpZPM0z6yw7K|_b?&dnM+q&TN{w`+mEEAC4;_x#lgLLsmLikNTzsnXg0>% zeMgdsiN@c7C_Fyu0pIMbwU2LfhSA>gc#Q8EDysh{S65fRCRE&is6yHK&Vw6|UTCtj zv(L{F!Jid(Y@-C-tAm1Gd-Jw6wb9T>XQzhLTRo!y=4WW;me9Vcm4vZ_sHlVJwIG!y z*8CR$dnW=-`u|1%k`SzhZbXQ}k(BiMb)UQZ<pE~<+uNiDCYd8Y{eI_sO@fO4aO2;2 zg~f2W(ol3rEHjy@j`<@#%%kd`aqhMJG;B+z_cX4x9G<?JT>Ab!Y>%C$phyVNFXM^P zQhWWXcI8}60wT)LeU6ydpP)7eQvpyo)|;AwK>QpAJ6JZEzkWRz-QL~~sRt)g-<K*X zC8#2O&fkB*c!bp0t~faLb9vIokMLDgL>Lq3P7CtGP?l9LKKFyQ<3a<js>*@OZ668R z_vX**vWBg3D0vjw9J*&3M9fS9a=$@R$;7}FNqb^8>2{u?%1pC!UOn!Wn|oz!J=W0j zC)PI}{kpYPndsbQRl0$WU&9)b_!)Xwd#)!pa2&OYSmGfAqFi#KcM31md^}nAUCXF- z&|Us(qFhxL621VGY;0^W(-clrF?}G|C)Nk;-phY3{7sFG1{Y_?Z5@2j2zgKe<iZJ` z7&|+~Gs~%R!3#{cyUD4^!lJG2n)qa7bY#m;E&Ja?3Gg`vyN7F>55YuG&p@BpvJ72g zBfs9K2K~mh<jAI$mxr8Be{Ak9Pq-g#O)H?{7Z3KXzBi_$XQ`(L2wh0D+U-L0XHG`O zV7_kn<Wodw`I_ht@t~H4IZWRdION2{w?jIi!+v(GVXpeJ>1)kzsA3-^XT`<>tQKBk zO&&8XN_dCR=Ft3?g*B)7$oH@iVbR;1b%ssAb3ugI=(I__dpmrFhn`iGv+?d;$u3(m zl>&$%J>njXz>NsjOR=KmqwQJIpZ8fW=azfXad4no@E=fbX=;0zEizqMHdI>r^QWG> zwl+Xe#u)=YZ^X2(Ox950A0MCM2iE|RPz{?xRqPNQk$sV-p*i`tN*7-Zm&~QRT^bfq zX&HIIOKolUW7gImKeXTAl1YgILtZ99K<WRLzw3ijtiKR(#p>3{(pRw>;r4vmxf&r{ zUEA2W7&+fs0gF66xByC8(9EYw#rdx%!}mr*^hk106e&KsfQtjjG?RB(|7hI~P6-cB z{rn<dGG4$@S=~ZRa^(1AVt@CLo<>rVX_{1$Ns?v<AfDr$_X~rjGzEE&4c35h$~d>u zZ*oO%T>sE4qOM-9=kcjBw(&s_oOhyt`1M=acIX#&BnYy$>n|>RXbhy9gt8kNaeO($ zzmmX7PK}N}#l4G%*DTQ*%kLcFR{^eQ7(V&Yn%za#X437H?q<4n3y$M6n~S`C{}!gE z>k|a&)z#I$QgF*Ze_q#KU$0XKq-3xqA&U)kzc^lhJDVUzfAiQ|^zXE#Kf1e&RHajP zpMAD|)oIhqR|LTc?jDu~s+pTi15vn->60VzgCiel6UXNl{RL<`U8k<DQ&sfo`ue=y zd&z*{(D32}{x?E|6dEh^#L)I~>{q&Jim9my?a@7Y^!TB#7$F743<=)1MkYMGUyMwX zV27ctU1N0!gaT|rs74H4ClE{X27Ps`0v!gdm)ti)rUy&Gw40~Lt{1VE=OY~U(6fI3 zKK}J<$;Mdrq4g~k=*~$WzZI&PsPcRGjJ?P(LlYVV--nMMZ?(s8i3P(M(MdqRb#&HK z9`dg6<Patg<|N}@Ozdhn6!%S6CaNkzDl0t<J2&`6fBxt%f&pdb0{FGHFh1Z2_vKkW ze{0qbH3lJi<RH+YU{cQVra)AwEPn~@MT@`0O%i5b7oz?Wi%BdSI1+@U`q$zwPFY<O z>~hlYv2v!e!J|biDJcnW`dy3&iν;3dEo!4VE*baqwnLdCmFC|z8bz!BiP<5*ek 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Ú%O1H_)9Ccd#2M2PVPte}s#rED*l(rfCVW)j&ZZN| ztan{W_|p@B%<s--!$<X&&p2k3$;cndU8jXvdr52y=yDjZ7xcBE^Q8aqz|a~fFI&+? z(ok@izS8KY>V|}hm7=fmRZ7lRlKe+0yc(<D<oQ&IiC|C~Vd)qoCcGUSiZ(HgwRtl% zRy5Ud#PX9_CO-_pz8$F(e^DnwLht>1O5E^I9{@w@wAaAT)Ggf(_&21W{lI&e*_${} zB_EJdRD58{KNH0aMfe3s(6&o0H>cg<w48SOZSD^H+rx3x3fNDBusdSyaA7{Do3VCy z;^JWJAfBHOSZPkK2YnGfcQ!VW*5^fI3qR~QD?qiZUansUwn8txlRyGiXmzuA;_mWz zhRF<C_T5R}^m}CYn7*%UTX*1sn9n*f{a}048>p5Mu7Ddpn8ak~9<-TpFxNb~iT=s! zit^@k>kHthnGR<hZtNjKf*@=xt<lLvLPv)gy1OE|wuE^%>yD%W4oxO8V8~&!mtaw3 zye(~L9}`osJvw9Jll<jrHLpWuwiT7h`~)&LRKEwbD`G#$zdcIPI+!ca(t(&Kw$bzM z@{kvBP+_tL!<p?B-}2QLQx^DK{BHZH0a0SMmeygiXlx|1+XlPXG6|_c*_(BsvfL@q zfiJ~W*OEk0BP4q*<xnEc7$dS-_dPZVcCEuI54~d5-E{4xTBSk$fB0sUT2$at<bXN7 zNHLAHJm3ZaV$H|zgz^*C^O0|Zy-0jrZ!PWZnWd*_69#yghSyHbwUN=_vAfqCEx+RG zk6G5$+ilIjgp{>d2)fsRbPXa6gw586vNjX0_hpO15o%c22l*;uI{y?jL1_$86ujB& zx!7NDJ#ar>x=QqIpPXCc$^=jevx8Aq=CMJ&9pO;a{$%k)2o?qI+gsPU*zU)>o5Ce{ zWH4>I1c;c%{rv<oiBDQeB8S)XLFKmJR#{(+&i+dKN)<e^-}Q+f7&pCUHy!%=jdi}x zW@lqde4>f2F=zE?3B+$BC5u06ubROj@wz`bOyy{O9Fqi)jjpb>b?R@W*O`?{bhf(f zKex^V?>09w)yo*@-r}Gj-kQ09T&=~qnrC>7eD2qO7mnN8?~@GXB_td@_|nx&mFSLf zaSC8bCGe)VsdgNEB94m7=_dkSqAh&<jk=KvrBm(Hl9<Gn*L4sn4fEgi&(91-?(X}l zHdYw4&pR;%osSmhR%Vh0H|Veja@N=5A5|uK4uSjbp(FRR=}Mi)F=W=OgB8C$M@P;5 zX~1}WgN+(4E6b?gAO`>PCGo@k-!-T9WV6#n5Tt4bGyz)N+?hU?+~{Z!gKoobcU;ya z(T6sR3F;cN$E1{bJ20=waQ`(kBgv=%I(N~06?uHtg4z}%K#`5Omxv*5P(|kC;4ock zx=606(T~@_Uj%k+fq8*x#NjXPx#IUf%B84OckFRaoH+iUiCycZp~DHbSt}giez3Bz zy!WJKjnE!mvyVp=*S18xv99r32ii1rj<;i(ZQ7M@?6`@-rr+r@Mh$L#T-1rtI97{f zVBLU?qKU?SF{;u86c-}$R8Hq&%C?2ZKl9-k=LZwWeuXGne-A>ibO5k>e`h)b;y=pf zYT_6TU`}^H_NndR>FLemc2pHdZ8n@yXME?15$tI^U%SuwsB^RbXSm(2CylsTD{8sb z^ZZCHSKV&*I}9}I(n*Xsi>>t7s1)--)XsaSu;yb7LV?9ii5w0>*rF3A|Dwrs+8niF zhTIKPckduQ2czlbffj)A2DX%*;rc#<p1@#8W-h+hYx1d_6Kpju`-wR8>O_JkNiupA zFHl4~wZY+93|PelqY=*oE)FBs<?hlxfY7a`E66zWii$LIr$V~dC7P&X#`{*LE8u}D z;_7&@@$6uZ6+jQA#l=t2ZHVz^K5X`B04156ZrWNhd-Kb1aiCasAn3Rx<^@Qy=l!fh zz6`-)^%i|)3!mwEGJsyRxMoIYt|k-(zTMyMQ+}9fH10jw=uIu-cHjN|Q#6>0iVEO@ zm*9hpsv3Oc&WFCS7AW}q!?RC3`!1BxHaK2>11{`0ph&>R#^wTKFN(YFMUI+{C`7?~ z5G6LP49yB2?4V?FT!!_wUPicl4tA=ONKH%;!R?N+CD}N4k4Cq~H=F6&_51q7e{f5g zNTzfw+W2&C`^;ktC!tMXd9qdY^z3X-k9ItQ#r9HI`QTnFMhYMkT}JN+eoCIYZDOYT zGGEB2FWe`6=VkG&aeV0SV+37*<Ha8}h}o$J4KuWBZjChQ`HL6ha<JOz!P|>{D*0~% z`7{YQ@M)<n99URxAP*FXNjfD;f9!kNc7^0^esr}O`4<{{VKE`*?W?AiK#?O>6r<OA zYd2#X1=lehK`7bsHvnJ(DBrdf8sXCwbo7<i4rmsiI@zsgrewdJsm)k0VbmoP-d=a2 zj9~`?-yQuq%VuN29;48p94;Uk+gHzi{W`;%{Ojn>gWJE#+s)R&$jHc~T8@P#3e5&c zV;^zXPi`o;W|Xd8xO#sg&2ypY{GEW40Jz_5@)K-t6QvNmUlZ)oB}y?{*uoEeCYwYc z67a@`ynXB!R3ZO=eBj>({!^4GAEe}e0pb+Irmc&I!;ZDGLg=y}@MA1Efh@>+TOo?^ zrvBJaBUiu33)rL6+*xxNouLVD{^zi*VI9pEmHLA24^i*DI&kUY=}zxOC!9Scc(jx; zAZMO(Dase&;s;^wK|U{BJp&KeEZM(N(<e$DRhIQKvs=0xo_cKehL5pzuHjcA0H%q& zu#wUF^x*=HKXr!p_*_*30+V9p=|I@f`T2Da!n3I`8JQNo)>)E%6kBh6;iET9kBPxz z2X<_CE@L_3gq%R{_glSu{p$}VA(TdpdXKMia&q@qD}KRjFwbatX?G#3z5vEgpDt7I z|I1Mk>zVuTtD<d@(<<=Quks`oHjL%X-ehc<E^=3RRE`glMej>$YilK>L%(S+3sb(h zLq=F00Ej`pO22{?izJv0j}<LQN^(kobkWJ8=}J!CW8w0#&7Bn<@9W?Bd4p&W;@_Uh z8DfIe!7#-TLD%)J7z#;!?=2iB7eL8QV$}b$)QqPSn~)9<2@4BjgghtnYIJzGO`TYF zzsc7C9oYW<zK)(=LTpN#@g0Yj0tR41S<RF=xPC<;lTFJM`~G{%AK8o0UoXPblVdx7 zS|CPG$ED6Vl}q$F*?!|i8!~PHbz=*VMZm$s&Az3Agyw&gpKxFW3FB5OtEs8SCnSCs z{W}S+0*~8^P*}4eg+^Z~Ek^I5FR<1@fZ__|%FhU~PPcj%CJL`eez%XoJ0b(nk_Vi} zrQl;4v&Hy^BHstyHL&8rKb!g!@S39OT#pKx(fYeyBVsyodeqzc)jNkeGzLr6f=(6? z2r!~h$lha)_z6@Mls<vbI$lQce*s5-!)mf$CcA&oc1c8a@Vq)!hsng8(LHt(&Oaa^ z0I*c@mmRkO)y1#6q-Ih-^Mh1L<ky#M-&{Y|H&2;Q+Fm^a^uL^ub|>Dh+Q;)aMFY<p z6G^cRjGjn>X3vX1K=^PxSEwlBodkP8mZG5G=i}d+nyM}<qmaa))>A<84+#nR$G%k^ zpr?x>5yXI6y)K<icTuKP0U=!AX0>z4%MEY&Edx`fq5sLniO+7ff+D83=fGz1_74RK zaGxc)i&br(REWymnaHNjY@Y+P(Crwcz^j+m*ktFoj4w1?5{Zm#P0JFbpa}>HwqJ&P zh{rq<H2?6EOOl*-0ZvHMolD$7>b}Q9(iJ6}jU}L9$@H1aM->n8{2IpLoo9>Zm|T{x z)XT5C7iGz_X*vW+D^v@o%L9lBVs&Qg-5y2LNd}r-==U61`hV|HJW{rla5`~N^WL?( zt-$*y84&C>&|q0IS4nXl4|<%nrR^LDJs06{^kte5(ST2JvopR?9Nb~j6p9r0ZbN?? zbQ2uk56xtV_BAfvdMuN=yG9d34Zos!o{5piD3LPX!~)BaMgLz*<@&7yT1mcnvPouN z&>W_xuwDt;w$zB)%YweBRHF=^-BeE6qw%ElNn0DM>Cp9RAm(iB2v7_x-jE?9{o^wO zzp$^*1RdC&4!D{HTJP++-U|zVLXTKQ;SEyi+>81#2x3{5ct=;-TWTkZ9S9neB!Gw< zOvMxTwLxAYB_#p`^kGYXA-znmR;@;n6EJ@miFo4VT0uog*`+7Y(FeSYZtjjJ@IZm% zvJd>P>k13a_NU2!;B!}1(WUp;@gK7dj`Q`y*d`((5&|L;1V#1MHDdiU7kJfYcs1K6 zwFhFSAfeJR9!_R>a0AjMfWO&FeRb<vgXO(~<iAA8zi}IXsj1M{SKjM7@j=P{0w{W~ z`2po)taI+uKN@U7<NC|+l7fQj9F^ktA>A+RNbF*icK>ml`WyxZ2GwK|q!>=mE?i_F zw&8e<_mf5MMPfn<Tu?oL?oLEsPgms?{%YmaUZ4GsKXirVq&=u;sFripZ$w$`?R-nc z7#v-d`m*^bUzi2^M?a%2Eow=~)X>w~+dEw10V2HKg*mK$bk9Cl#`u4Dk^T?sxx^K} z(UIXPrYIClKa<Tqz~x0oMB<_60J;j4{lX7GItvJgx{Qh%IT!YQwl!3o?-AYY8+pDw z@ekmwZ*6S_;e@(o1iXHa5UT$#0y&gyQ@fo=ViKRzr<Xa(tw1JV<|7QwPF_XYf_83i zL?7MpU`h$zW~C}uZ{f!?yte}*!zR%A<KW2fgX!8YSDOX>$E%c@PC%^lj59GQ%rEGx zt}ZW@`yu&zul7YS<pG+JF*pRs5I>71W*7FI{gY61`Wx0+`svWF7f(m*fQ$y3Z8PrO zt*X@C6$kas#N4~4wDw365-xkgQgyNyp}|6wELWK|oz}W+^1QqV;5=3Eq4bdqdX&bl ziIEXOx5!ugua0cWj&`<|1b(z86>6vf4{N_-6SV}0RHJy?hud!dhmAr6HrZxHS{=!= zR7BOj(sCjj>WHu3eRVThjdB5$IZ;JeGCd8{Jxzi^^5yEBu2Rzg!hfq%i;eR6Kbk@J z?-Vu_cn<@8*@Ro?|H}o4`4`9RdTnopyiYfh#?9*8<uvdrVas6youE5CCZ@`5Gy@cI z)Nk}EfE0?9l8cL)xA}?uugqrGH&j&mE%s}+AF{<5jzG&Ye(YzCLuBm~2&%{iGq54f zVa<&WN2Wb?sH&;)fA}SKdc3vzDG;ER>Cw?y24u9f7O((BFEB=Hw)0a{t4m5MR9zQC zX{>yQ+^fe(7lw&C&t;$9$tZJbYmNK$Ybx-6NGabXii;SJD$l82SN9c|GZ!fzGtDa; zV?)Q@;>rC3W!X5h1+N>H0Ev!fFa{Amza<(Zm%$8+n{yJ;sh{>^f1ED&X@)IUSzU$3 zQ3J*H!%pNOJQ9YpN**I6)8llO@MzH_JDQNal9Hx-vXuGGi8HI2@88a-#~R~6Q0Y~+ zoSs&_q@InHY4q;RY{nqss<pfrNYeN2kDLJyfK8sX$IY7i!Y#-ASh!?fvylU>ny>Vf zl$7^?bfj^HH+1K?3~UU}*MdoS1f+tZ?*__;Kr_2Z?LR0kjzMTs*gjJNYiK<G>MUR& z#9?UD@CA_UjGLVb{fW{3#h^O<8-D`GSv|K(widlmiRQt_Cyf|U1XIb1&GB>2r-)UB zSAC|SlF!X{(c5Tdc)Y>e&=A$B&$!*LEw)qex)1GT(o@KI9G*$8f%g{=$EBNMKU}C= zs4|uWLcX4cpv&bh8i6FdCB{DzGM1v+s#djunFP*cK)3AO+CruHZN5s>T1{;V^YPBW zQ(`;0s#2ya7MQinlG%b4&e#J8lkmuw@IoTqcyUj8rw_C;E40q`+aB(i&4QnoB-tN- zzs@3M85w!^l$T{EzH{yS*#~J;`Et;9Ye#6?$XAq)@Z4Jb{30e>LH;7#`HePEHt$BX z!$ULDvrjq>?^~*4*8%z43_0Mpk4B|IyXS)^JR#WpkO~f?ZB$^g*^opl%eZ5ma^=?+ zXYQN!RNBbUfo?GEjfQi-Y20~5`vDnpsH(DSz1e0BM7r2t5#;2ox9Mc8H6Ig+{T_~n zDd_PBo0outgQws)>l0c>*VC6Zj@2iXSYW++0s>`CH7FR~9U3$0w`}@HKNqR!h%{dR zS2g!t9Q-SD^Lp0!m}6A`hbpCH_N!vVI}LqsQ)_!?pB_8xXt6B;v=kLyg;`m74Go`$ z=hIb+hlYl_Y5_qV3*24M?>|3jt9qn950uDAc5R-X+ASgZFZ<kaEWZKjdZWsMP1Nog z13&plPFuN2gVqYkV}1DBOMdSIO)a%8w{Sc^4ztKsM&OItC(b2kW@e%R4~dauxw1dE zq&jGWOQ+z>QnIQ&SX2oN(r*57_(ykiB*i=JCyNJqRAX7oJy=f=Bp$OL)?H^XGl8aB z#Ar=s{xkbkHNIP5P|%lz1nju(3jik?U+xO^v0#RN-2O^{Zjt@p9_BI(nO$*NKLbZi zP5krc#8MnQ95}$GtUyJFNT2_$lPQm?tgL~r8X)0yEvnOo+z-YiU;CV61#0~B!s+ad zd?K{|1w9$4CbA2HHx8hVg~6B5p94!UtI`Y9Lk~)U55(C`BUWgQ33??z(esp@o--@j z-5qG$2XDB5Y})xQ8A;*mo6?yl{xZeujvf$%1`l~Oa*Jd?hs?ixOBFaiOby>D7|kUZ zT-awP#|-77qmyC4h4*hAk4Iro3l<xXe)RTfNq@kIUWk*)hrU}~*$z&@7V8NAnVLj~ z^l#N!5h6mTfBx`TH35Y<W^~}sK>0GwnPxYVCsD`{(2|23MvMqFKxN->f*D7>r;~5< zbeTC?vTHf{vXxR@W_@5uI!VOki^!Aujqq=N`*9FDp!uWb%aB(X6Y{1mP*?4ZcD&i2 zJ3)kt&_;)3@>!TTL0S$r&2e7;mcFi3+#v9RDt}Y%ay32m<4Gs8+rHpOMF!kwh;UFy zSlBNtAehWM-und4WYFq)-xWG2Eq(IzDb+qD71e8AhX6SDSDaZ8<d0}D?B_9AB>1>^ zGy77Ji#M?;oyRAP2yIue<5~@9ktYgAe|82xS)Hvi2Gm~{O~cCl;l~G)t%2JNqf>@B zoUhLe>Q^Q=3WDKeD6u6ZBo^N?<UzNW`!l6>D|4CND*F0I`}@3hFmJ}B{R4a~k&D%P zYLXwNG0DkXp6BLHQ!ie=oM2@UfbCL9_H66^pCZ-N8bd@rG*Ba}M&3ee?og+GsGMge zI!OCJYAy3?*bAzd_vuoUpnf@!AOJp0fEG;tw0WKxAav$r=2(YoF;q#CUhcKeYt5y8 zVL&iO?vwVGz_Hh_&*q2gSZwenb4&(tg%6_s^BnX67p2E-#kVlug~a=O?8hN58V4{d zsl0Yw`}IaP36x-irDxAhO>-V66f?PebL=t&-Z>EWM3EdH*fS{8sC~YgPK*eRVAm=H zb7)Glq?m6O*~QV(&o@LG7cXrp{q)*1_<yjN75ats*T|_eGqTYL<1*aCyfBp5CKVE9 z+nmf~EdQ)`uK*HplVsEpC{4S9<$`q6&PaS`D|))5<7^ijxB+ZCe8EAJm7=Ecf2(7s zK;ga<T|Tgreg6Cz%8J&|VWk?8`S$JG$0?2n8?(c47Gc~$cql;z5dz<ob~)~mywBFj z&4FtbQCP~1ZAI&J4gLH0YSGJp&u@p-C}f|+8Vg{yqXU^kjW!~(-`!!3o7oW8!_^8| zc|fzX2cVDOV}=Ink}1l|ODnXAu%f{WJz;>k#=tHShv&edLZn3|;b4*r1NnWfUS&E$ zhNQv9M*XB=Ilg+W^J`C*HI$V{UWW&X#JNyj{Rl5F>H6Fr^VAw#BQS`9Q?^OE=*Sjz z+VL*PbvbX<XvEGp#)m@CFiALl?;HI_#?Xl83Wl!$<y8x0<EF5K$@{M$Oo98~B2m## zI?_l*TsQC2h!>_H|Kmgk{c7jX#^s(4U!PR)oq@@WzB|kV+MQ^|jI0sun<`?TpYOsI z?`L5>V4;eX2d<?3TYq0EbnE~f(Iwq2p~-izC5ig*k%8EyN>OFpQ>%+{k#z$#xQ~4q zpDq6#u%+cBt|jm-OX09dk;%Vxo@OBKq|{STXi6Ju6U&(7h79~#S0gxAoYjLWOht{z z7pfRbOZc2OLq3Cgb8c=7I0!^MlgDTi9S;67z4utue05=?ZhN!?B%NFIz7Glf8SHLH zWsOc3qdAZqqr3O&?`%cW;R1+~94l$CJaNzh!te)`p`nsLn@UPTg7}29w6ukqi;Gz5 zU+Fk1pTBFtSxKi}S4&rIK>i98DJ$u)%dOJ>9uFZ7LGy}$&NMDp@4adgB6}CPP!3Tr zM){<#5s38t_rkSdkDQtKE;bmUfEUzpC+KDNdPOW9c49^q$0mI|E<)QH8z0aSp!*sH zd!U>q2evq+h9Ru?GfrJe`F%W2_5~8Qo|Y!l-%S;vk$`==upC|f*ya4+cQWJO`iG9A zn25jV%2(#~p84LKvfqrHJ&dqg5VoE5I~gWF4R98CFC$T`q6{$%HXWb*LFM&I+<5a% zE?=d)yEl&9R)JcCuv!cxw@_jXB>V)TX%Gk=Au;UGqEIO4wC%h<?bbP~|MCtQ!<OTt zV(!$Rbr-5QP*0RB(E4Kuw}=KdB8HkyvEyS0)?(7q(vpUZw*G~4GeLyU5BSD^H(i+c z_HNJswobpoL!A?D%<B!~BO>x{Y%H&<8naMpZ`?DcW=2_<Cl%=M31-2{`e~T}lI__q zT)?Ymk+1O^t>B6RI%RC8vo&XOT6{d)hhO`Zt?GIjJCmebq|9s#o8HpJ>bW<Y8&TBq z>EuaGkl|qpJEf!j$YP^7BBBQ(BAYn1JU$cNFZWcN=`yWeKLOu`109ecvefsnvY?#b ze)qWpMcu>uXVTeT>tnrCaxw~vigz=}j|2U~3AS@5+L1Z03Hn*L+FEVX??!7i)GK}Y zAJ}WUW8>L;?;?r6ijb9aTz(-uJv((qYNZzWKrx6x$ic?RX;2u>>v4*yp~w~ztdw(n z3(Y&6Zju1H?s6M&%;7j7UGe9Ba6}V+PC|}CF0Y!$mnKmf5gK}-D;am?7mdUuZGnxL zvrA_`YR;lHWD1cYmCI(Ba0}3%5pf@7Ceu6?#$RVCG21Zc&7iVr+kE^8kkHtpqB!TY zU1gGA{C`Xr(vfPo-}1NOyi`?HxlgTLh~{{KgEM99_X$z>{;>WfaJa9ls{?=(=(Rzt zScfjUWF!&ydZPmnq7pJC87M_ZC!;{hF)=qD9&gi+3f1FQ&klx$t{b={1G$}ce4AY8 zp_cDP-KQX0b8Mae<~U!}<7x>#iVqf4*(#(h>ZmeaMdG{ao}tX#5>Y=P6OT&8!7-o3 z`MWj%#T!hAhf{Xc`4k<a&E!&l0PtP8;OR)Fpr5qNz{+vcew5&&bBY!N9ACA&LyJCj z(rk#F>t<h!56A%T$P0Z5;C0H-<e)v(0xEfY#Z7MM7Fk)vxS<!$O^DC%P&ht?WLK7X z&J|}!wJd%AAUbw)Hoh9a`7x{@ib!C*&&ko)0*lw-?{|iA`&IuZ1^3=Yl~LgUhOi!s z$|{{W^0HVFd?t-X$Z-w?7(bVg0!Z}`PshZ9YI1UN%7&a?oA$-#IG*nERR?q%Rav2D ztFVX>#8YXfv?*|MPQLV!_f=LDV>HSgv+M`!>rL!sQe2$qpG6OY?-P3$`T6;cRB`vN zJb{M6q$uNRSr(Syv?%nPqr@ra89O~*1`21|uz_vU+__|KYdfXyry4x6=M<}059n^F z6fzF1n4(=*4dV(%xfjr!IF^%BB?AzyyxT_=#NhqQ%7%a?5I3Na*Jt^EWiY4`iCxYU z67g{8I6r5L_3_^Qy$1Hj(G+&871#smv)2gzpfc3!pT%py6Z^#VcWJpb_e)fAbQ&5& zKp^=h5XjvMlLS+<CSsDn&#Eda#JPV>N7AG#Xm&b&iU!o+4}ATaD^??G_X0UI6AUq< z$<dus5qO)8^IV*pddU`TNKw|=OG--1aZ9yxG0>k{EYGul75VAFAU;9VJMe}>qbOdk zeb?O4LL$3wXkeWiMB9cH*aZBhW;qqHpcS8>io=4$go&69AuZMXk2$yEoZ973)~RZ` zpkGD~O?ad5b1|rIq<`BZ<3sZI@83iI+V}3G2GGpyI^Qnpz8pP^P~UGHlFQieexZX5 z{UpnV!L-A>joziwh8fLCC@za4><uyKy8B7lKZ~7Y?!yp%u7O7A$v$@AE8xq=%{_Ni zMjAq$Vu^}Q%rm(#LI$1fjNF*-a~ODia>k_;SH!?NKsmiPXm(x&t^3{G-Luu8u#ys= zmE$=5KO5^bDf8`*r`2YPnF=xrU_Tig8K_RB=a9Aoy+teKsC04N-kwEdKsq6)cqB14 z*H=?CX2wyqUum$Q4H|eBD6ym~IQ(&3<qaW~!u-5-y`Dq<IiO1IFU)5DQfOk*ze`Nx zovlKzsHjMmH1&HrHKM_R8ms+3e}IoMU4%L|V#dxEoVw<2J}}$CN+}`y%aJP6AML`G z*lNEfVs9T}{DoFtwd;#A&3hRtU_r=BA8w-c{mC`?4-60)92t5f>F5$_UNl3f^j)-x zhwP^?O(z-3IOC%G##g2`7%J3u=X#|&m^hct@4QRu!4Vl1AuT2Kx5SL&=d|jX<sefU z3BPa7c{NkS=wygS6>dUE&TMd-?ggv{3>;17CN^h}@W$2Oi%1CQH~*L(r%7MB{xu-j z{!l?GXkc5JMT13Jp(tjpdk~Z98&f$!&vyOE<1FYjEcEG99QG+(dM^(npFrm&0?{uB zGt*K|s;@nFm&`IB_6jqP3>sGF-x)8Q>Fv5>D=TN&kE<*WUc=71<5M{;H>IH2mYWsM z74I7Q8c<UX17X2trk{kd7X^awJbXgz*e!B&j^kl$pfqlk>Mo;N^MpAXQebIlq{-eU z1?3k73=opYUiNRE0vD)HLQFjDU|rEK)}Kbp!0<hJSmlH_opJdin>GV(Za)G@-)h?% zC{ZcaOiXYqw^_+V3;-8WcwUNRxDTK2<9F3ma0E*rvFB^R%|ldNL(GxmP=?Qf;A_v2 zt(!;K`Prx-N&9xn*l7*$5P8LYeaC<0IrmOST6(x4ba=r<G9GHbI@-5ldM+lB3uW9Z zAnD(XYeGWY-)NvsTwa1lcS2|p5&JqgpgkPud=4w2q#a)vIs{C@1~W=6mfJ_f|Bi`< zC7T;~J!#WG7rZ-|;BkWQWVS`%g_60Qs0JM}eQrZ%h(w>~5sCtH0!9Ic4k1Ol-*dxn zCWxolRBiRux4BhSrTB`$%EAqQLrvW~oDwO5L+gkvuXc98sH~}(b%EKyCZ>#A!%a<1 zO@F3a(T@O;LxU$><3=3t;xX%PTHkg;3?(OOyR8#Tef6mr1@!kxNRPD_n*RG;?IieB zlyGvQy=IwBFhqvHRI$Z#_WS&8lNwX`d4Zi&crvp?j!L<D$rMvr%X%;N^VRlR+Lj~W zh{<iBO_x5v<(#~^h=`0(z$krEP>&Ko8shfXhfB04h61}|DAkO^ihGku6o~3(BU|IJ z5ca<HdHwLr7^cg72E8gz+~7(WPz(!oI$!{sdtM;|q**?V>muwjuc_V?)NQRm#QYqR z!cTX`2~a6UfSg46pMHc_M(~$aN$-ZkeuDzXhS(fKn?s{-$aJZGQBaIADm!J)=1Z4g z>`W#xONJ6q8xJg7;5(N5?oz#K+F=)!g7?RM&Fv4<^a?JF?=9K64O3y+@e+KW5+2U} zaN{v0F1cLglgJoP2-e{->8G)I#C~*|sNItVv$MFV44-X+upPm>^>FLlDnF4&5I0N3 zMH9Va)2o=Kq;xLNT2StNlJ5^`2s06XCT}v>C82KdR<4ZsmT<AXVE3e>Ul2s_+{)El zKDzbVWdHohky_qTEt7wGcRI*~I41qzi?G*^U{MF6J)vkmvOTxC%qjS@?K1t;qcw6x z{%_SMD>~Zms&JG(JsBo+;cN2~y4{EpgbZtu<*9#l{!)OQNcMV7meUly{fZuTQiq2! z9%}!7`T#90%;dCjGr6nsgh<k}-0}fl>?ab$LCB=|_iIG>=l~ye`D$Bpz-H8<^bK|| zkxHPx;tRukaW?I8Mt#YN_(=kFR~O-86$g1tOol-?aV+s;&F<{_XIGTBca;b2Ik_gy z$(qzQ$IlUjqt%tP0COD6=eB_}e0PZu8W^N&SyQDp9=e!Wcxc|{8b8u3OZ;jqIE#K7 zKuU5@>88cjiSb#aYP}mzqvd*iX2tvAq&E|o3@U;vVZlC68%N!GxvleXEAb<B<!wMt z5wLk2ZX#XrYk!pR5DMKlNPO_RqI&a&z52l53tG%=5C`uwVNWXAq_=NKUagP_3hXE9 zL=yG?wq#SxWAOM>T*&w6r1h}e6VfH-vA<v&b<EC-S^o;kQn|SpDwim|xjmTPYPWuk zg>^D^KHPSRD9rQBwK^%?dPjdumG+x#j1_`10#rIBGr=}?+BfI>kdxOa^G4M9T}lC> za^J{1+61~Bq}WM~y%$MzE9@>g(P{ArywwH9?yn%tp>0`oBDAO4!})(dB`0e(>PoF1 zpw5OGW%fxy4Vp>>MgC=9zJwoiOSNwcM)ONP?+&j<5s<cV&W#|K>K(Jsk6vnfKQrmN zxQ?=p{aJ+UZ%g<15EI9{=qBV#8VnMi$pfk8mw1GOb<9GeFDp$~c)TvlYjpOp$N73A ziBq{e9BWL)O5*e-uJ$$bG-hIa$)u<QknHCdaiM_whsx$7o)q=3jUR@<G!>YHqCqdI z6{KWj=olHi!Iu_7kgF6;dZI4$B(EUvvS?Fw#me=yEjuLiea>@RJ$DLQJrRL!O-zeG zVu37#Ncz$-J|c}nG+M>r$!fJBwdiw%2z7eYfGJD0(kbA+s<MC_Hzt+GFZ|rGx|$|s zTT|T<{mH+rplcxJy?XduT7rjyCBcWnUGCwXguAk-qSVn2o3L^UU7ELu{>$^<n^2|B zua3+AER}FhaR<;;^yz<_`pwM8ci-7hLW3idQqae{CoqpC%oFghC~t*#qIur+(mKF> zclFcKim%t^-?g$b>&P8XNwKerGM?)vy#P0#8lNKn)d?CEC&#Zx!__rT5GeygS%LzE zlp8fGy;a}uY+E!1aBG5Upjo)4`xO?Jg7y`;)Qr(>e6g`D{ux-maR#ehu!oxJnts|> z;5LO)<%?K3XNOsK*A>%w9(o8XNx0Ku5)v#1MyWR*ZZGxDe~T(I>d_&#@h|25CbQ|f z;->+J@FZ)l90{77o^eYk|04hV>Uia`EA|bA#8(s)lylWmKxl;dj`9PYuIyRdLX@GP z4Kea7q#XD=kFzF}ao3Qt2?wsk%s7QTmy-u%O1fW+K76s$=w>5n{R4bSap_ym>~#Q* zQ!mA#8L+I2E#h<%ZJjf!+dm^k4Uouv607}82qUkjIF^(~qZ&cjd5eyVZGzN?8WfiO z{35DHn7Qu<(w_e$qc*p$47Ed-vAF7*1$QjCZ<TQF)%AUUI({mk^}s}L<}(6&K}H8~ z#sjvZHzT(fJEKWdiZX3mi8^erhJP@%;j_9PcpbOSj892?C8CA1UTB(Xo%>;<L+f7( z9FfasP{wVz9XCT%%3Yae4<9adcz;IL&lQX&V-dXy2q0d6{ia;$-SB~nXh6V$gsx5R zOXnsH^;TU29bT8y&EFlQfsD&p;q^67(a}<P_8j+yqB}Z3{{m!{R)048eTTNF1M;43 zWcvOozP-H#|B(++k?IZn0*P9x|Cj&@y}G(<Cpu?er7Q+6qi!D!b}?-+uiFt<(l=W9 z{=s2Ax|avhu3cA(G87V#49l%v3)AIHZGQv227#(Pis;=hdWAZiYC?GbzrVk4O7{cd z0=3_x&jL`Dz`F75+HbZ4F$H#sIW1oelgSiqXBAc8ZyZE3ig}sH55PC1Q8mT>WrJuK z7?^i2#)}b=j|7#~IrwsB&Yse1T2Zilo_QKTidbw>JMa5&yY<m*g3YJ+F_6JGqDUDP zv3$&Yvzpk0mPrs9BI=FJn;H0%5}PB!LK7wuIH#+vJ#gmj?cHL0PQrz-B0ZilW%T)Z zQAu&a{h9}?L^#k%9>@pim@KG;mEYeLbj7-D%zv6eXWGBe(dq{C{Mjsg;pc~*=2?cp z*Fm439b-QIu|iT$0n@hWeH-cQVxH1=k*Jf%2fMy7?vV<#YrmL|&6g$dIjDO2lA5RI zwBf^Ttp%^!F~|1yYaV<1^}LUT93W=y-S)OJ#JTKltkWtPebfy?i|d)%Z+aqr?g_%A zoUh|HZGN=H#8jMqNI?BkbHPP6%4onMz(LiX6>Tm0fN#?7tE`rw_F?UVXZo@^+x8Y7 z%E;*sm3*>25a-Mz-OVy;XvF+AjvssXfRL)B;+XMqyT9%|PUp4NL#OBGS59Y}HSf`K zFV85FQrR4gPP;;TeXl<ppmRbUW4XNuKTTP_K|%;)w&b7Slvw1P+kHbrLji-)c9Xl> zR8G#>M0{%3O2TfXEnS%gyzhD;-3@lKlj+%-QGm126T$DeiDGe!2B}gjwt4nNv)i?h z8F<gf7fZkF0b9Yz#3M{Y&8_iN;;~CC7PrZ3hLMFFF0Zg~>y^C2$q6`+Pwze8{XsX` zoMQ)gBe<1B!St%~any>jJ87U3Z{NA|*>s29-yq)HoOtSm4P_x06yGAqoV!S-Mi6o` z`kpJJ8cxYF@$WUcje|BcL$7N6;`|&4G`%KTryT(E8U46z-<eYa{(g<2dLA7h6CmYO zWn6{xdj|11&WHb?AH^eyT!x0F?8J>3TQUfgGvwmCNa(NR=z4J`aTQizhDE3)n(kIg zVXALrbI0(}kfQ5i>O}3Nxcu6>j5rL!N@_G~VNU?z8)pm9L#8-_(*f?1Pow?kykyM$ z6(M1$637yvK~VwifnEHVd95acPi_uCCNMR8TO`GMr2?{Me%~VRu5Y03hvikGHyIH$ ztNWq2i8oyh%QRLM)6&wEx@Z8TplO%sZ+x*TrrAfn$3-V_iyYlBByJez+^J1Xer^3Q zRH3&b^G5!uX}HT4@Jzbw*@vDJ;cIH@mZ=xd&)MbCPq;kl&yPF;(%xcMs4W`C;fkQ^ zf#!|W|A&_lsH1*Un%M(L3(%77?96zHUigZ?r<QcCs=6fRNGm6m$3#bKQgX#g+05=G z@i_15U)j7Jds}1bQ}0&k?P;#`cicpAKnFE1zmUK6Udyq?ez}FI{nqoGJ-7Y#Pbue$ zyD=b#Ld<4Iy3lO32P;(Ob$9qti%jHZ5h307fp?!uK?e89bcI%p<Cbh}CToHG0x&A_ z^wiFvy*hN+*X<6GE`77>e6}-+3`xHNcT1|k!|GZm^xbl600>5#{3^4g&EuBiD3CD~ z8c%r>z@8^p%Y4(?*W2p9D|aoLlD~8{-ZpcP2cA87d{vu`IP|)Q9QW}9)nQ?btyAVp zwq<VxUCKTNJB!aV?xO^_Zx2}%zYXk9-jG3X_AK|h9D3v6%0$&>$gXpM+956b4i(X^ zhWpavw>jI`yLUkDDCR#w_~M^*xxA!;k&&(`Cq{fCVEof^G>Dipj{GQe5PGK4ku~;_ z{OOO_vm}Hr`ql&>mMjx>Psg+O9&Ofr(tPyRcy6o}SlTsb2+d59CcgFhQ^&cY$!rHq zz}psbLV<gD+u`NHlaz;5l>g-d2yGN*@R^*h{tSeNhXc`4;6dzS`1nLNR}CQx`eC!= zxnHJ5yy2CUS9|`ez|Rgi3cq(zOPCUGM+wWhbQ6B)c4|6WkzG(OnW|9WeycarR}CP% z3YlZY6y~+k%65Wx>z0L2w3d6b!jChfX+i?Vl0|h@=<vhfP>b^NPK<jabR0~=7AE`S z4)Y{lkqR(IzNgo@`SncZjnk$*(o=qV28P%{CrVW7KY7wBtI6rME}B$QSpEG9!Ek0O z@w&{G#WGtG*0Bcjq7SkN?jKK#UKnl5)blv6uI}5l&f(h7zvVydTSF7ZHV;!sVb<3U zUL1_+l!Rz*xW+9ku3Br4GgIEnY#WgHO8t1XSK0mp$PhG|BLF+a#o{LhB!Ncaz(tW; z^xG?&k!F@m538_TSqDL0_4Egt!b{n$nQFp&^IKEtV-B4%D&vti2@yF$*wV{ZA3i)8 zJ%fMo5_q<VPlu}HtL!=70`VK1KPd{EeCk*3*fQK#FV=So6ZaiJ%G1fKa$JbPv__)T z1Yd&IN=desW4$GhSwd1$XUNp(B{4C&Jh7eLQ&(se@uxz$`XGrHf^u2DCH|KmcNVU1 ze`0_tLR3LvB-Fr<{{&FGVYh>o?HQzX^||B}XJ@A=>0ThC!_RKck&R-*dk--o7HrVp z1dMwEG5MmSqgU6a06zDGl!dM&-*&WRuK>95`<ag!Ipw<SROs=hz9>K;htMaRT<mfU zsSC?myiX_lwY28iToFz<j(9ug*@F_8b;`)H$rLy>>Auj?)6ZB=at^2M(aerP8@*Ay zX%4k-1-#(UC&5!b*766ydvYYCwZ4H>m~;yt0?E9Ii*bnG{Dix?vx7G)nA!IC*E0~Q zKmky%`;%Vcg?ic3MBPgnAC`nXIRV)9OEAT2;@eYMKiHcXcaZ2An~Z;NMCwM`EzD~r zyPTieIG#`Z;9N7$yFcAn|BZ`wPR#`l(_xEwJCi(p{b#5(JMLS3>zCr3%@NcK8=Q6F zM?KF0lf+d^@&!yY(v1lY7YFAX;h#Hk$>1+R(O8Kap@zMVEtEHU1KLxTpsajC3eaxx z35H(6^V_DT+xvSy7ETU<<@xw&R49OS)<u%vZyBb8m#$wqWf{TE4Ut|%uv1cgG&6Z3 zUd2#4X5RPqIj0myMf&sN*naOMhqr53BENo>(9=Kh&zXPaN{mDN688l|_wCaFA)X$L zfv373+&M@|zdw7^NsclOFD>tLI_$P=+bx#3fydZzJYlnthc(iZIXEJal>RWndt9c~ zdK)82V&fVEoV<PNcK~+6zdx;hZNK7km4J)a{@pTRX@?8Ze&c)(lw#{s8pc<lgPK|# zv=-ixW0MDhUihQq5B6_n8&&q9thP2Xww9y`RkBZ?c4TGEhErVbcQ)AT>P}VZzJx}E zegh`gegd$D2!T@kf;j~|PrZ8}f<Kf2X`F~ksv1dgsm<QqsM^AXJn_sFU`Llu82m37 zo|l(bP*@m)HVwGk{go!vUebP46?yrkNSKL{{VD>J*-CJtO+@J;fU9zM)NFVC7wex; z<nEy@a>2&=x9!0lzgJHr$;tt_&0+)q0aZ3XSyUiUc&s2zXC@U$A#V5SO2guU1k3%P zJ>n;jZ}oZD`Y(~zpQPPe7HqG==NM?M0!U>}9FhvLacHqoJ%Umivomtca|V>LO{z5e z^7Dm${0i_+SFp3Ojt_g9{8ruTCq_prz=hbb4nVt8rXeowadup6B_bN|M5r>nl9Mx@ z4SQ#2$Bdl~fo@e!Pmfzefm2D3@eQtU^lL<>Qnr%!%%KnHg`*~(EGI|J$MbDY)X??2 zfzQwIz7ny=0yX>5!qvs)VGAjPR#Ut(9f{{I87IA_*5y(A%3EmBX-2Q}OQV(k-WRhB zucK^9l0h!VhNAD^3x05L(a>;kxE@^R{f@M*9~bv{sGF&dpz@2@o|-BxluO4YBozJA zMX{86+`i(sG0aNb8}*vUdFf)N`P(e@xU|IvDEF-@T3vxaXOzj{NV9{HlKFd+G_8|r zZyFqR1ipFJ!7Zy?GSK!cCiSNZ`nA!s%M6TB0F<|oH({;MFoSl6@pXBA^-R#_CU{aV z=KSVB5T@iA+nD&frUB@1xg`ZZHe3mbYYDwv4pU6on_cI?^)d?fB9I#2*!*DYS`?4A zw`EzSUBfaOV>~{K4IOL`X#Cz^M-;BrL4W|uq4(tJ!%L40>VTB{ah353KDd#0R%*Fp z(F)ZO3|1^D)*KnNDGAQ};oXkg2L#W>%l(8vp$i5aM=y<u_wZioEKatm=c_2Q9j=M- z;^)7B+#?5vhbQ*eo#c8ZS271I&GGT^nT1OG*>sQ)k-pG(rc+T-gj5z)6uUU#$}U~V zA?dkHb%x_c;0t(PhhPOFV=~gvNd3(+p7n#BkyMMLJw+Sp<MNzRgYUl%Kzt_fxE|ho z+=vWiXjX563ypz+;o1aHKELL(N;B3PB%oH%Y0rLJ|NIpZ8^BxUt3@!^3?6U&;WQhK zy8kshRtC`+)b#ZGb+v5JH85;*Ej&v0*)PoW-L_m`3q)>*{n@v3J+2LRNcB5zC0zE= z$X0run!e&gpWbBI;V&&M%`lpIzp<&<elLSm`I?7~m0q?@BtU_amiy*%!4^+^tr1Tj z1r3eJP^yn@J3c;MOk8}4&1U|n)k{`J=JxXN8FX=RA-&N{!sY&5!<+`<gLQ4x;Uw_3 z-6?3Fors6qrf@rnR1bCyX|dYD`4<%xQNQ*XN{CP;h(v2j87FUYHeUdTISAaC+MAC~ z>nNl!yFs_!(ys`TYgBZJ@JL9A2?2FR%y+_e$jA0z1qizrGz{Q7i0hYcr+JUXf`VlW zVO$=k+1=q$kEi<!mHC1V<}sx>96o=4?jN@}wdH+WTWn-%Jw@%TJ@{GYrGX$BZHkrt zrVu3{IX!OpjIWdV;pJ^yVrAreH4UA&>U9$Gr}~J(@j5c$G}vKa9s`_;zI^!A*~z5e zAf*fpkLt96@)#XD6;IRew*H}6jtj7@_q4#x(j(G1eqc4ruug)Q2%AB#wydlrr#fKA zqp@MSS&;;UHPvb2pne`URi#T<TWby3Nl3uSp^2TYikwNHu2sQCgnVwrw88Qd2?!4l z<BD{$e2P6)Z?~fV;X__O1H>$20-SuYov42@%Ly4O>DiR~<m!aML4Gzu_EJiKgcvy{ z<@+3|6?Rn?rwD7T4%_i8WzQU$?W0LHY&UGKZyg-V6$oku)jdDWVjwYH6WgJh>Pn}c zk*>ElpuR%h_nB|qU@PgaW_WM4&tbtNa2>(NwheB}-i7p_?r+s;zvdI**bX*+JY3?< zIn1CKUMG3padOWj_`v3@si;VB^pu}Q_abFgm+dtf7l$+i;dJWKv_5~ndORsXg2!nG zyMLR?xwE+)ixvBk=kyPjs$CNnQ8JH5wMe!*m{&^?vvJzI+|*P5?;Q2=$GMr1cF?)% zrD>;np6mp=my&y&)zTM!-YwugE%rS;?CbqG>)r8(FBpVBOa>D_1tR4$>To>5kkce$ z7&IH~2PH{>G7{#wE@tiQyw4{Y{Tiq!qc${qYvED~;$?7p0X94k@f!Qp3pjb6RO5`Y z+7OxCLt-qf7cWXwSR`^|q~7z5!V6XY{R?KLsEEd;s}Jdj;Z;Niy6?pz!81KPEX+L; z9?IB|`eE@7J0@J_)f|q}WcM>X(3SD%wai(AQrt-EM|E|8iB?KM=<n_Kz!CH&iE*=` zpkUspYVy6toDYdpx2$qmMF}bzT5MW2ZAnFeI)H*TB<{Pr_rG#uTr|?k9PXIaX%lK$ zX_^y3Xi{?VMo%TtUo{p!?&NQeH>_$}NF?DN0B~5>;e1z_d={KB52`B^9h)M<)|}~k zJ6CL4Z@BiW+`#)a4uQw&DjD`ci-eq9EiLCLb?an|!moN>w?^)TzG}cU4e<U50GwvG zImLeSKMYu}uv?tx;sWF~+l)RhX89SBD|@Jy>o!_UP_fX^dQ#3Lm}uq9<#Sqyie<zN zih`0Yj*T~SCUD<EO3;M!TQ|yh_Bq3F1&;UC(rZU%;~wWiB&1dWHm-(}g6+PwPSt|h z88$sYrc8_y2t#=W#JJ3;uHdmO<w$RFv0AcK8cdK>ar$v9JUYz9QES+!DkO*Wc+pa0 zHgd~dxP_s}fr#FvG#W{I2BoI^56!GJ%eTgC*m<#PQmcv9c#m+oI;)JDPkJ+-K&b3Z zBleW_b#1p%acOB>g+hjoHHTMCK!7)OoOn#$?kUj@o7JphaqKhj@g9F?ECI=25#PJr z?O1xwfIOg~H%>2yk%OZ?E32&f*9pVX3!m<<1e{<`UXG7rwLCXBxC?M6yjpV!`q24B z=H@$_5&#kA+kBdHzftDD)w}#?Df8zoM)|k=X>^c8sMq97%k^v}4lgwh>2Nb!y_QFO z{@Grk^-Ku7a0`;9>#+T4RNUrj%GgXpb!d20DbG!BW+CkR#KFIZ1F+~sdxilXD$E>m zV$teZDlDh!m<s6Hwec-uB@^P5tSW>Gxl^WQW`Q(t;@!R7F;e`+pRDbb>@D^@>KJwc zKHx{F%UZ5UKR5myKsBFvACEn=jlUtm2ne<8*ogMU@C>={PpiLbJdIEX$-c!?mhx0D z8=E9@*K9Z<P1NYrbiG?LWlT)w?pyfw=yqho4p+z%WPUQop0UX<G&{dRMGSoNCz>(% zE>9ytWshAk8Y5t%A-*?l(ptvvY}mDZ`ez_=-_J=}RlPa6OaY(Ho(R0b3iHz%uii+F zi3!Df&-FI1<C~p78eSKU%ds!^NMCzwjsdXcNYH*&fkA1?huif4-vaCI5B;O=<vHue z-#+f?Vzx(H#|(Hw={2y{tG+6|+Y-HSBoDT<NzW-;6PD`jsXDbf_K!h%W1ngad7geP zIU}oh<v<!T)6rXQ%H?*+!2NsQxxzXCE)ZHhm~%S)X_lb{1AuDwCt-j@$((0>c_(~3 znW(C-MerJTySNu+yfwPs)0~}>h=GUa712ilkD>H*g29subo9g=5eQOlu|N5>h0haK zojfeITs`meVZThOC}O9kl0ncq*vUl>`%{jTbB09u(F8RM6VuEX9U~*mXs%l~PI{lj z(CSv3tJ-em|8ez}QCU4<zwib@LKLLCr9-Kkln{{akOq<N?hr(}Q&PISTa*-OkPhkY z&NKX<^PKgr*DttSF5P=(_BB`hLOT}a({mQoPkw2{U{pTs`n{mx@^ZI?={V-g?#qtx zR{KZ1MWMdNKConPAwEDJU}4-*I)h+*t@n3W(D$Z1O~Ps5ZeiuJfC6Q|k1$=eqAyhE zM*{Hk!$PC}nR!*w2wl8~`|gVb7A<2ALV%VkpBLsupaiJts{D*2>N>fy9&mb+k6HVi zGcz+|!VRyBQcSt?jf8W`UMSVf4~*sUq%Bl6i}8jzTXudXFMYz<Y+O*(RMUeRX{+%` zbZ-L*ng9x;-GAE>UO*_pD1h%-Tir8{?^hGVrS>issi!Y=`g6%opt|q)?wyyNV)UoH zu`WE^)&6P?#^3#LLKq0m<LW%XM!E3AMhSaKJ_o%oZfI8_7@l5T0kAH%k#zwr)t~rE zkpM)*H<guTp5$FOBJY0Dg(UbPxTVP2NGQ;mzAseFp75gsL+q6B3w{`ZFh(ce<&8zF znsR%`oX`sn!f-~STJa}PczF1zgjiQD|MW_GI`{n!3f~P;Sv#pqFv$RLMg!VhpB9Dv z1Lqva!eL<qW5w#M>M7wo4(slde4Vh~vj)5jA0V+g(Aapzt26gowV0X+wpBbFW6Isg zUw?Vjqs2?|n9aYn;Pj_$eiPvL)VFD-A2DCEmB^u~-;vNWkUWSeM?5ztj6`u-LWjqV zp11I)4wy)b7sjO+nHcflG-hQPf{Fp;7OZgzyy>qpt*km#;Vs#NC>7$wOY1%`0eQ;= zS_mk-rVKRp(iyx-0a>x6TN`nIau|<uhR4wnZ+r$>un<%4P&EoX2(W(S%tnva6zc;g zwRi%_i0J$hr#vt90rnWQc$^Kxl659Uq=L_g7mQPYNeAGc<wQT+9r$c~B2ZC6PM1}? zu4kSYP)L7=(dlq#SN!e=*wssn?2+DC%bbZ4slI{<b1=Wt<ekE)ZdPe}0n~}3x`uU< zm&1S+P|<JH<`AbnX$u5CKf3eq?Vi`?M(bb<s+R4{RO3PrGHO~&+@n#d=4J#^bIOUO zv1=p*giHUHyRx@s@!pikevZ#>Yww-bpF*~T2C@~JOwbajp9JbL&@o6}r26R$H4{hp z&1c@-%*%fR&)&vpwR_s&sId}M7)uLS&N6yp7@Zd1jVIC4ce^DZX?+ES8{H-_a{n2i z1TDE~5ji}0nX{qKLD;9q7@W_ZEF<a#OoagpFeXXt3vIYs3b#Ia-{<hnd0INU*D#nm z27<aD3AbAL35gV#OS)uWDp{AK#J&k!eNdawj=0?eNKyzmbO9cc)Bqy`1A`^kLfHX= z?ARR^7EeTA9<T55QfEXnC&Cf)1m_?hXY+yH=TjjO5&u4x%9fHp@v?4Wub_gv@iH`w zgOlCkwKiwCBg}M_D!%&@yRD?B<`YGUyQkc4QY9jpQ~yc=nE)&U>2tCUyK5CuH5V7W zkc5Q9jjsFrwNvr^mArjPx12NbG8~gjVJdO9N({Cfebt|jT%lRR`dmOM4I=-E#Unj} z3N^T9o{DU_$(N1(o||wMD^;VVriO&fB;U}N(Yk@pj<vjiNx+9^<Q}Zq1N6%+aNHwi zqu<Wc+M2YV>pV1=nT07zeFqESb92?lw3a&-??him^|zNxUimAJ{p48+`?4l;1p_-2 zD9PS|Rwi|G{Hv!1CMM>t>JUc#V|N+6<rWh$udTv@faUS3WCVS&HE+}7)^ik0KYl}% zGfkRM!*<c<J&&!fP~1hkn>{ege?yQF{<8C3P}Vr`kBOq~hKGE|<%F{*Vnh`|IS*+w zxNejz7Ar41HTku){H>2SWe-y#Ai_h3n0lnIS^#cH2|umtBV0(#MS1U^KaS%B(jlm? z`XaLmmVd&>2s06wauD`}IJxWa*QJBt1m|n;E-*T-DI@a16EsM8Y9EDZks#sEpLGv= zXo9*^cYptuN-*jH2=D+#N(mFHo!v%ty+-WQirp=f<XWHeD;!m)TIlts;qL(s>-?vi zh7nv~1_lso+#c7bs{Tmw5^~mhfiDq+=f<{3n|Noff5py!@Ya0`-5T`{pSL=Sx|RnW z>OwzWhn(vW2sdHHc#Bqjlx!-_p?gJ5y}G(Om1xGEB3X^7h@JD}&3As)?)WgaEcs7% z2Es^l;qMQL6XV??R)1h_aB4FDdOa$@#WDUX9y6!-hmbHvP!lcY4Wo%zPbYU;fFH@I z&NqH5_n2QNADm=Mi+lNU0@)3_PixC_pZsuH+_N*+=lEv-3>CPSmZ-nyJNX%cW1;5} zzT$Qq6Q7G<{h|H7K9&|F%IO~G(-F=f!3pa#C4B9Q!L!irVgrUD%|tMFwh_z9?yhc? z$%*JhpNE@yrDy8zX{c%IRZ3%d)%lM$4Y6o5M+3<v7`H@+bO5YVQd(Njb@O}i{MR=y znAM&ptH)ZObxBd4c&Q2)Of7+Plw(2Z<Y-0W{8Cp*5TT<x)|I!13plr+F!h9Hk#|iC zD{JtEPHU^H4>>SFzH~(@3<)dW8-1IrP2}ol9{!StCdEd%FKs&>sZMaJ;;fC%(__m# zQ*xn46;&h+FHm^RMT8Ef>3`*O%@g^AqRRZF%ocwl3eUX;DEu}r_l$Pi%A6X<*^Sx# z+jhP^w9&EA-VV-5?Xk>sP!?nDz$~Ng3oCBa>(oUr^9EAreH%~KyTsqS6wo3s8~tr* z(&SC&w@Ri(+(nMjfB&RJ^US{aA})$oy@Dw;S%-+{f11;hnm+pH1fye{Ohn366OhIU zP0xI{p>zWO^^~FRg1Ku0QS)5{-;7scqySyie&Bya&*(_4(-;8N5r%i`zZOy!M99*W z<T`egOIYEF05%Jz@=DKCc);~KT8TcUGyhNK9W_CTTO$pC-%Xc1cAEDY_ul|(K?5e- zQ1R>$BD9>3I>u_aJyk-ATtww(=s^(?;%o527&#hhW!i2J{tu9EAf5of<7UO@Cr>5v z+b)m$F9dHfAZ%<WAn!o3@k?1=pw;@<)315J#CD)+_dE?OmUZ)<^MKz?spZOk8XxFq zWk#IjIIx+GQUj}db01|J1-50BV+{$|yO0Vjh}dGPmZZ=@Ecl(UK~8Q<a@{$g2ILg! zzrU@($YCF&C++K1djfGVw10yQIo8f9{7Ku0EfueBenVJ*!<cS!vGWlfH77-wnkytP zrS$9ixUUQn1VEMl<wF2sSmg)_nKu<qY$r`|f3)HFmXpLsc>*|$QaVO_IL9qIuv2*% zCKi_HXK@jf+2Yy3!Qt%R!mR%qV53q_z1)gznGpUgj1!MT9^(GaPc8c?o**Ka+3!o~ z=-egOTI3{xd0pa*qM{6~N)hX;(ckf-M=gyfbvBEYJF_;$+ve{h32Q;sHj*vQ$;Gul zUw=?+(?-FyWik1+&Ly8M7<6e{!JG~I$4P&pV6EpBkisB#83_}4<Mw+Ms4tQA^=^Wz zpc`FKVIZ7b0O^13@}rE%F=&-<2m}4MtW<DWdZ4>x8Y39*&8)N8Yg~YiR7f((=-A=i zNm9)OKA-WQ4L#3kMyBxzYr`Ku;H>5zk5#Nq*AM^sskpvAcOB2-R(r(r??O!kIrhXo zmHYAJ^z*9M)s$N`46m|BOoNt<D?bEfVPj#XfM}EBuzh+BG-P5#Y>w>gj;S?5yOdOw zi9iPZ8vhTjg`&ad>>06<8dswq$&-hopiB<Ql6(jR_{1A*{SaW)BPceKqg9qd-hAn* z14uq19TEo=1Sa@TMWge~D5rStu|Wac1dCUVF9u=*#4woVUiThX2#|gU-o5)9dfsMh z+{dqKzW8P7x~*k|l6f~!5!1BXEO<}~nd%S6&?Yv$A$s$1b#T5}K7)6{F5S^sG!Tsx zeOB(@ee+4R<FxX_OjQ8!fz9^*_E(K+<2{Rzv>dp&Ft+yZ71J6@S;ZTfy42GN<JA^_ z@$KYQRK}<O$oyz)m5A)TNKUJn0Q4vmpwCUzzwokkwqfGX7G_+J<G=1~D6O1f2^6q? zkYY<*yekjILvXqIgejA+@H*!Mkz!nxLsh&~ye^*2Yy2E>tWMo+^2`y_IH`CJJSYc) zUj#&RyO+5mreORt=8T0c7P>?<F!-uU%2{c!T&fTM)IDLvEgeSSAmMB9aT${IQl=-k zXspa}Px~t<#FBo@j}GPzpiBMLfY=B15mcxQhFP(Zg1Qa*9qllix6Zq!TUXBjv5Yrw zF>DL=_VCADa49p=KMGJ6<v{C$8Tm?${e3~<TaVPD0Sl~o^d5MV^hEx5yn^ojZDNAM zD}rQ+5&r&uthy~reN6NtIQ%cpvLGd8r8jgXIv*0QbATG0aKs}BtR?&)qtkhBP7;nu zr*6Czr1_ukXUKr3mVIf|(h{P>dd)}5>2Lu3>mp-g1Ek}z;bEaMM_b!NAZp)D^XhDS z;$Q0zjGWn}x27t&pRUE;|4$Duhf){=G35uGbk-i)(<l8$jg5J`B{JfLyBWiRZ&_Fv z`TA$3l2R-}c4rd}c?83+fiMl+JsffWv8;d<1c^qkaED}xY6NhD8C?F~f{E?pV>Yv> zsbN&{ioU#hD)qW}WHi*W;?n4h11y5R*Jy5JuIcJ@*an%I_D{q!$q!WD`A;wEF(ys` zN5ee?KJh|qgy=bGU0oLFH5wL~3w>}>OQp;hDot#(K~is<B5}VI2oYP`9NdoiN2%M% zGtQ?7TQ!|s-F0HWCFSJgtPQk4HC9l84}H}W_|vMPua5zJP$(90=g%%DVD6d@Z!@k5 ztj-Zt|DnLD_u5X0?fgi{ovF<SzuESP66)M>9MGIW5bmq#`?s{DkDlVg_X>EIQBY(u zzo<dp75?mKL;R$nSHe^Rx%c<|Fo%(ZM3h!hTv+&qnBpoo00#lqP3|!}Y@9K^=uo#+ z0@9RJj9$UP!o-pek^ZB;twG#lN8IC3qAg05l`hry<!nz&X_cShGeSc&=ry23BDX7O zZm)Yw!n0<pY@a=inJZE&c1sE0;Eu40(=xA_0f=`9!dr`EIa?k!hx_r7tD1>XRq7+p zy{B>?db|`49+|wNqp){+eDgAoERaZ&$8mdMX(byDk~T#Z&`fRpIXCyr&ykt%&w9<N zBLKFOlfd@_ar$HBW>|4?F(MS+M8J-)g$a;QX9o@&F)MlijWBiiFMVjf&5N(l1a_S~ zGFxwRVVe-Q8Iq|BM(_jxg!ix2U5Ad5PfvTU#7Nc(Sd)0QEGf~#c_@(2<M-H`m7x{@ zkER9V*!pB69$gFs%p&ok$t}kt+)&kQMd@&(S1TY|f!0g$MA3-3*>=c_>cmXCVy08y zAPY#pRujx+hsPV^AMaK~KBeGD>=}@^YyL4#&dUweEJyPU3J!Lvj*ENCWON^crUog{ z6VPkmLmv{DSy+N2A`<>4s_<uho-v}-V#2jQ*e3yrsW2}(sddg!Di0DQU``e8Xh;nP z(Oi~O!&yma;+a#e7V6UFLBVCnewV1=?cN1GpRM<KxIlWrf4rH!&ped+mfh-_<G^)- z;4vb(bXA(Bjj;hE`dYVm^xsDGY+XsQhP9fK-?&C~K7TOhNH$_2`0>A30AJ_<i1@P2 zo3in^NMQGALjYe;d3401p|R)D-!kx5@J)2qX7Wrjfd7A|>kw;y*39M*A<@dc3WP(B zPb7kQTUm6=Ls=PE3d@QRpko%vR}T`|AK=~Od+F^JuPRrZDl14vpS!vq{rXILisXoR zk3yanHC?~Z^zZIM@bd5%7_B`+L$ftM0gg7F4O{O}m-d_Y&#OE@WCI{&#KnWRHmPq6 z0a*n2V+hzS*T1CFe#+H;v;VaydHWl?&2gSh8{*@>;=Fh3Ez}pKY=<Da-}{Oh3vX4; zX)J0rb8Wd2tW?;-s1;vo43|wZm?>qBJkE7hrPj5LX|fgYF)?Mza$325R9ZSaa|LCI zbU?oR=<56EN1fKG<0(`<Og)V8GKPj!kS(!GA&ahZ>h~PiqGU=3$qm$2mIceon6DKG z^hMFwjaZ089IeH2swkFJp^oU|=7Qt%QP$nbr>8@8)_flO+P`CHx!NAuvOAhw7Bph6 zbC5sEw0jS=AGTZw?AClTGPVZBHzg${(MCK(th_h*-{7}n<ps~$Y=S(j+w8grZQ7}N zewDY))DMD%ainWoY-DM8xX07e*3i*%IAMkz%rshD+R~CWf2w~;jPJVfFu&!6{u05= zg?Npk=Oz7jG*Ly~S0oY%$Fj~cmc%@-CL41mayI$hUZ+v7Zk;{NA5HfFEeoLa2>KA5 zHVh$<zJ<9t1#2J@1QH=_<=EG2>vqJ_O8&vNKsA(A7F(>x37IQp!1`t5GEJm8^;6u? zfEL3t%H4|a$BK4Cv{VV03$|M~uS5(yT*)ii*(un*CeS+@^1;Q$2L4|8IW;N>-{H7y z7IwAN`EafR0wl3$6V%n3VA;^yqlkAB(wE!C<pMBVxY4n(93{u3<}c(DlRqyabw|~* z0gb(Br#vMtb=SQ9jni-J#ikH)3BF~zJMIX8wo)33NR6?O7u8m#!*_E{tMN1B<>^2A zgv${yFPSf@7?txTKE@zUs=2M01;phjeJCow(4AY6r3Q?P^ZiI(_R}TPEMWeV(Y=kx zIW@1*BpRv)lYCusaz>7=B+$>Ytel~@j`5@qpliyXuF*gM9jd@TsXQnC;Ro{%KLpRo z_>rO2#dbXPGHMes=vC=di_r;4CA>BaH$)JUocagW;^QZE*xl!*jx6+~^C9aDFD*;U z68cHU!ylh#zCJ}=`W*0#ssdhrl2$-qZ)<G`9x}TP;oQPN*wS<i$!D#axa<+cweuSo zur{2oGHN>+LDFCRfB*;icaS4fa)+MBe4&O(rXlnI7II9qy&-)_!s9CkPj2y-nBb9; z%Hg_DPDPhY<R!KFweTkx0Vo1pt!60<pIgJayyZ_S@fPW`XV1{wTeFA7Px&zM3)G6A zy9*GM7nf2Xi9UB!nagpJaW|Rs>E*b20h1QCGO$#T*%<`2KKcGPb`$IAfY2fSi&ULC zPDI<WQv%j<cQ+tz+jdl<e7r?VmhslZ`lHflTdN10{+`7aWP361GVggZ0R6DP1#moF zcQYedr!&5TmK8(2XfA*hQSlB-CIS4nP`ON?o|nqw@F?eT`;2vWs`7~o5yCD}sG~G- zwOUHR6rZ?9UjQ}CK4vTdkKvW!@J{a5e?$s<fM*Lz%~vYS*)Jmur=j7BD6nLR4?(t7 zv!K#Qr7nocE7pAQ1)|KL2h<W48hN2y2ng(wCB)eZ67^IrKX3q2Z(8FUZnZ`TRvbXm zO9MFQJju`rfX5dG5pJs3Ie4PakD+$RDJ}0$vtNj6OaoYGWFBANAA28MVGM+$FLA(n zY4aZ_g5RcQWN4}CU}0lm;LNj{iLeDDy<hb_JA*;C^971>Lq&0as{1pxh^9A=XwwS{ zO15!uw{;GpoQ-cU?Wli75a0YI0M$sss0IfggwJ6*yfIq`h_Z857!@{5qjyp2CJvFx z6n$m`&Bp2#ST|ubSSaP}059tpl10C5pAonT)Wq|8xob5^u!wf@mEa)7Y5aiYKhx~w zA!kmth*u@!4u6eTCd@fe)~JfeAb?_dPQca~Up#<nK&`G`s1lq-J|C@%mk}FFB_H$Z z@HTf`Jy)uW4qLP$_Sj%v`)4aUbME)L*Sr;rsjVl$m>0)qjPh~u0Yyuq8XB^ORuy_t zX_bz+*?aDU&zTEJrg4ib%v&8OKqE~v+`T(&tL;4N*<t_D3iglZ>NL-0%a~p?>v#A) zvRw~aT{7IR%?{iHYuM@O3nB7}>XTYNaN?M=vCNzi=By;Z7m$+z+yvHjY3;{y$KQP} zENW_MD3H(;#zs7T5KnleL>R0cd#x!EfrEoH9Z&(<l_6PcFOuv}a=OdaidBKoT6kZT zm-|IufB!50=f>6TYCFNRa$6whgiXe!#Unzi5r1%tsi(G1uSZ9fLZ@ZMYWkAip<UCS z(u%ZS+_c7gZ|pD-&S$g;#zcasC@F)yO=zd!ge(=p9B~nwNfG;x%(lQA!UO1*goYar zBzn3ps~c0k`ytTgCnoT3yB~lROglNz`2u{COt2V6PN)dX23&%pq*1Q0uXcDRh%X9D zN*gfxkJLg{HHEj;K+D*Q>jt;jz6bj8W<#Y^O?otal~h*m{_vBA8URfg7C!s(dq|#5 zfkAbcD+k_r{i{1D@7UIR@nD;0Af`V8(_*z~{B&j)`w}P-2hz$)NX8i}LIPd_nn#Bn zne1YV$zP8$CB69!F_5BY1|lDBWcZ|WAEk870O$fQ9>2{KXp0e6`x_ksUDDk@9E7rE z^ppK<6cH^K3m#In$+zIgfg86pf`qiZhwIVD%6Dmi^suGRtCN~WLiwXm@L`qv5n;_? z-o8!?-ZXgR5ewo-W-{5$k_*PTr%|tR*LqP${RqQnD*KpvtE_WV)!^w3Y2lNS6DD?+ z`^?R2dFi+>fjX%Y7FtvQ+;0!<nm1Q*dGvjZ%lz~iNNm9h#fq`Q$$4vUT^kpR`Ax0+ zYh=Zox|B9kZ}54;Dt7w*V_#NyLB>cU2|?-zTd7IRe*rHJ`cYFj=I76f7kf4I{=see z=vD2R6ZHL45<pSJv$k!rv+@yi2n$cta$2suqOW#22=W8O+*D#d_5`bv!s3%AmmmRj z!Skfs%MK*6(@zQGEL^(fzsUJOvCHxwp0vAmQilxBq02C3-g+gpRLf+}G1jI<6eB0C zps+OBq?9*zLPshXR8)kuyu7?KW+^J6U0EZh#O3KJ7D^1Npt%jmYZ8;{trY)muQ0b> zK~cV(tt{!<1?sM@%f6rO!)4mOw{(5ks9zb6VM3Js)(CbV3<t5W7&WShS&`ut;>eMY zab^|{YI8j~ysA|aUc_^EVgb={1*vyYYA0PAT6p}2<j)n<)M%c2Kiu6TK082yFbz77 zZ@1O;I8z49EGDme2L`)*KL-omd1|AU-1HA;UWtj_v_C8imQ*x!S}f9$??sHW;Cgfc zBwOwgz<=On*xcQ;I_$T)ypYxThc;~m=p4b1jJ%Wbyxgnbk{JqWx^~;ZPbgphq(v4Z zmHL!ILR~bycDuU-hYhR$Na;mk#>`NqY*8GedF6-QGCB9sWTI^`MS!Ly524md7!Qsu znuHTlRD9VOCDQSMS<N2j|I!4l)5n@^o&Jvaz!H?mQ2vKY==S9KG7jh?@_s#YQ?8); zt^$U0%bYKW`4J%C4~C427WXufSxf4C=+{>?pueB+SDqQZ<?ehIkVcNu^3#G8v&BOp zrOaR=8{lH_ZF+j=Z)vRM+ne2Lz!TK=xx-&<2&y3{6k|FM0pGIpipPN5jCrT%MQkMB zKG*%tN~C~!ai#TL(?38gBIBtls>{pF?3mmqm$>=<w_r`9*tsTmmrxQB6hPuwxP;rk ze{4;tN_~AC1Z!z)Qz9-G#)XMzQ=sH`hGB<2fvO@jv!6m>o}Oo!8Ys3Fq`6^m#lyFe zD-8+B$duePF3?+o*Yk4?9Ltwe1R%{<l2rL}Y1b!z2vC<Yk;rb>67?Q&zqgk|3}0Wu zaoyc4ww=^qRW7yNz~9{gj46>DkI%ww`@9_z;y4yP{Sohc?@0EFQxgwpf_8U5S{T)r zQ9`z-OC6x<k9vq8<=^~QG9EX6(0+FwE1U92ZH{6IKX5Q4sV5|#wYpvDKw5M^k%fAH z|Gw@YHb}X@I{<d3m%Yk1)vhDUeAewGPz)_iY{)V4=yT-fC`T?7Q?;#qX4Qq?tsf)q zhE*Lvb|{hSDk_e=x*ODA;%=*`0L3R(t9-hpw5C!6CZzy91MOKY20};p_bo@t;C8CS zVbj{211ptwZ#h-zgZk*ln8q7-d~6R%$n3I)@7{Qm0nJNBpa&ohZhsr_;PUm>0?E<; zuxR;+-hD+YjB`rW$6psD^Ey4GiY)n1xqKK+)wKa|CVq1DZew|$pCDZh%C2Hgh7&l< zC;dg>mjlB97ZdQmw1gdSHv9RBK={0t1)hg@7ch7sAk4l!Q63ZB+1dHVuxt@1a}AB` zQvUQ1`*HyfeO0`i!9y^UPeoPoBey4(9^vSz^dqm+%y-sqDQcQAuPov;SNtMgtXisA zEFwZoJIaxp_04-^q%%p8E=aItfCe?|zeZA{;q&Kb6U04L;n=c__%w>;v}q<J6lpNi z<f5W7V<HV<jB!Gzf<H*{$D>Yn<J(b7`ttia7@fPRmgyS=U%}Ovp$!jJRaHaZPj9cH zmN1%~5QJ-zi0HtOoM`6wMf1O%YOQCC(jR|j8S9-*I_nXGWXCS2r3D@mF<KlW<~x4^ zg%R?wwWud?xZXKUdNny&I6K#Ya)&|NW3LtzbT|l=z?6*qHHgwTGk^mPE(e5U9a$@8 z?p~z~uex~nhLv-^)d$_L0blPg+6CQb1;J{<%PIq$^=zvFeE(6GnAjt}ry&(<n_(Co z5_u$}%Q&3AA8qWd!j`=_$Ur6?56d>&9>osHqLV7X*!7Iko5V6r1|gKVpA8l9DCE`$ z=r4e~rhc0E70-e(mRPjt$q`pdi1o(MgWt?gz<PY4Djbg@eoo}Cy64XJylTC_tU{Bh zbqPqCcyOm9K@l4{(PR-M*-&?6J7vHteoA;~n<)8VcK6>f$3(Nse?k<I$UwqBA==In zq;Vj9Nh$=jjC#*SGRan5dPX8^c&dO$SykRw_=feF5qoK24D6bNXNLglYFFd&>r1~| zHevX9X4c+)lo3zF*_;7e*GFq`u)Wet0xhKWEMyzqj<wbOJA^*&?<O2mOV=}ZKJ5w% z3gQL?DN0Is#O8Dv|LN3(^nJk9&dGmG{^m$qZ9Uzlz4_!}AHjF%?Ooh%mQDK}SEGg) zNJ|i&B3yP$BOKuZaR7N%A6%$ywiyqqNP0}cNgkUIU(w!PFFx!~HLmp0W>8aQSlxvY zhmr8<TAS5s{-Sbsd)%WYZlyh*?7mNLQb_oU>)bUc!)r}LWPxoQk&e+^O~FFycw540 zNku4<W0Okt+5JrK`!N{aIBu4HAO<c=iy$?3fd;!z>ECCA<Pt7x=^poOo?Ri4Z|@wJ zJA-RPj(+%~D}fk|M#kwLH^;QHsR%V(ZyUU|#}aN474KHOdSecz<&I9C<<qhmZ|^q2 zaB6I*Cqui*vBM9s{r*^56TmF2qRg!^@%sC*ZfLK6%RgSrqPc9FX9Ems%rP~ZikM|} zb$Ja1y@d=WlLmh)c}fh+wbbn#{K%U$i&hZ$z&t)kRKgZx+YWhjWbR=}5TvNJ3v(4q zpOFCJ={uCbBw5KmTkk@K_}YGz&cxzWdoVE}{rW^j)hTzviTWN?F|AveqvDUs3zWOP zl{RVM=$rBVPiBx}(|We9W%GGwUVMGp0a&)32Sm1I{=acIZEhj>yNLTZjI1@PwVEZ) zO3B*FW2UuA7Mf-u<UxQVEl1*j1A9NF5}4QVSd^uG8D9F%+ID$cH*0NCq1o5#b+Uf9 zNaE6K)plboFY85u`1-{wG=dA(4;5D{ktv+-2Ffg=V`5MtB>_IYW`B^Esd+vyZ8S_k zc+JlfHr&V64FBJ7T8+VL2hGosf<G+2n%w~_<!{7b0jIeZB2bPIeKl@ci!Fu~%nXS8 zjjdpoWklo_;jos(D9FeA{IM?DqNb*$HQ87NDqShz;eWRP)hC^QdT=RG&xZhJj3%ZS zn=f+|9GDh$L*}Y~(nAK*`Ul_6eqgTvfuU;>W+=HteWo)1V039WEt!wwzIL9EkZ<vP z_Y{%!rlMB(|98j?h=g@x?@+^E;*{t)I+_MGzb%QNa3Xn`vhEr`9EDM6SQ3Y3@g@b% zx4`~*tJ62jY*Z*aH^NP$Vuzw#|8WVUf({Q=S=(2)cO8Hg#a#7}`&fqDAgJnY516&+ ze3QHtC0Amv#m`QZZ?0zO9|M`4Nd7Q@k5lsBR`!s(7!HG4_2s`-2{FO{f_qNC!%%u- zPUZ$U_%}0&FGQ6(N^lt)5_Yv!Bd99P_V&Z(RacP`-Dk{ep`|1oMyGsEe6%!v(=zs3 zKc0}UbX1QU8_`m4M+M0Mn@K=re(cACyJl|0Edv5wA68WJXaBGCx=?#VjU%&{^`<!O zo8hV^ptO0!*El%fpt#9vK^S5kBfgILdw=|NOfC@}u%Gk!hXp;hm_)p9_FPc)M+EQx zS-c1TG)4{q@4-8AKk_{>ONBo{LC9Hpj)ol(O9mvceB*t-dgmy1hF8DrTe>W1B&#CM z(*!veHrn+gvJ6b3UN*D%(dn8t3}?}6=5i_En8H5jC^M26J^{@WUi7=Htgyz$Xs?^= z88A8rhx_UHE=JD#LqIhbc;9%aVBx@VLd{l2RUsX-7ZRmcvH8P0{WiJwraUX#bkl*L zQhH3kIOB5S7FSloGO5n>kD;?andf1fV`_4YUloa;BSI{V?D1SuR>9rPg-a^CPC%b> z9zM*PUr*cf?C>90xJEya@yVofg%ckvHpA%Y`(icBw#<~Wrv~o@XhAdU*-@);pw@GQ zqZb9*u71V6+!t)I#rnKGq}coAS}H1W@or^0Y!0pRpw^?^Dj<og+Aff~pi3hJ2qI}P z%X6hu3YtQ!4SrAReF+rT7Moob!@jY5?LD(c1he7@p5oeR`apD2Pxq^8=urU&@+C0@ zdJx8!y45G1#h<|k7}0<^LyR=vFH`oVF~NA|*pts>-JL*wRMCRaf{(>$!j2PrS2M7k za%tEqg`b0kU9ZJqsERSqq84B`RvVh~)JUzsB>p`)mx+*@{#dqzjEtwtudl$c>+i$_ z($lAxGbA~(sRCY_yo3J@6aC2N!{m-+Hv72zewHJF(<I0r>FdBM*7$N=GtNx<Hq&gz zcqP~?F?Nq%^8NGkXFua62GL~|y>4%6j1Xn~#W2eM(O?vUCLJ(#HnSM>zCW96Uv!!b ze7LSS!IL;61Q;d|93yqhQ}}Eal6J}uaB#&(YLr3c-{Ub2%MsJ&bggjY_rB#ObAK#= zUtZpS9`^cE?OA`+@%6dGMt#Z87hvv1#T@eAL*cFSTLw{F8CD<tH?cj}R@zl@jfn`M zF9zSp0tF?%Ct&=W0OCK;Z71`*q!>B^DIA#|-$bwiL;Qr3lT9liQiBVyJM4^H0LzT^ z{9vB3++?FK4yCUTNH}Q}nM_760L6?;2wZ>r(Fa@$!UG_kRU1h_<~EfxwrBk_9sbO3 z6Mvoj;(f8=tYk=-$VdPs75~c>pj`vHKQudk%OAWSE@nXp1}uTLqi%vW=X~V~>Q`%H zRvEAq&N-v|vpp8-SFhZZeho(aZ~5OmI?c%!e6}-*-h91{GbB)doSW#m7n(SAe+JX@ zJ_BaU6BC6h4380d&%bs=Q&pq%Zvjx_X|d%I#;A6va!WVC&+`%Sk-Qz<Sx)<HQfAA_ z&dD*Z{-I=GA&xu<ND0>XMFa(z)^PpaTf6@s9i-x}qQ3<M0e&*ke33Ol<wMrYB}~C6 zp~+qodf>Q%HAnvr0bSqb<F!QKF6lMC3+ZnRrrDGO36`VEH-Ot48MeEVe|}P{43-{w z`3p<-G@Ov1?nAk3ihG1H%y^Fb-A5m2s`|piQ|*1zbHFJCzv@sI7OU~=xkSd|lnR$W zs1>SA-;qeNYU%KRJ{?mJ9v)!r$W+6OtSoa(Llo(xLPAOQ*7gIwei4eje$Qz7exn(6 zFXpL5y+r6=rUGW|`~GzW9F=eSpW5HxFHZ{F!s`wFt>(9Y>FQ1XP-cS0E1f8*8uU8# zw&WFcjxUIXc?IvV&>&mjNT|m*O7FT;S`X>3pKj^-oP?KqJ%&^a7spova@YYOA*gyD z{{;SjNjhwtu(s6i;x+vQR<i0`R(5uW2JC}KF=Nj+`xEX6lBlFj$-Giz+v`&^jIP7O zpx)lMqhbPXSWTv1baZ9!k00J%Xt`a1ej)Q17tRC@tT>SeXQl0Jv(pu8isYECF!ufR z-aKe3>6{%pb;b_jOUzCudFUJN!)<IVLr~k?w5M6<yLu~g!-Hp!Nb*&Qr_gKEIVE@~ zmH!F}(YD8`{_6h*)vska)A0%MNQem6GvM#eh?+`B@QF`x7B@7)qSPZS6pNU?NsMqP zqNVI{8vN;l1A-n4#!n(WlrfsJ^np5bBkk|s5V<G{_`&~jrWgBt%Fo}JqcyN{8o{%` zToZ;J)8B6Bdg}U<;2(GA1~RD+3oYN^@j;GO?zM#-RsIX<Il=P(UL;Ln#);9<M?0+T za#HD=;7?Z{rkf8c^2#pYmTYJw$xEn1c2%)!8GebCdMuf$&Jm^7&TN_b)YjG3IZw}c z7nc&5lzK2)k82`Pe#B8AsCthn&Lt_~?V}z328BY1TybG&Wo%;|a38#EDqN4((Z)Zh z5gV9z-%Ro{ZlXsQtDA>4DC8<_&v2Y5umL@HOJO74@TcKP;WtXXSZj;_PUbfiGQUXS z)NE9cA&ZGFlon|MeJsm$%#}~6k<BJzTwhLHp(q;cSjq1rKP}48Z0Zu%D1g1g*5QX1 z={H9Zd5k2N%^WfmOC#^>XwO!#-sxDh_wc%{#M1L8tt>H(NO=ixQ6G1fDpXm=!%hVv z3V@4C2w@6YYFn~@HEtJ=AZ~p1wvAj+kcofpZ{?%7`})-VyX<dePg|yDhd-)6p~%S} zlq^j6qggr`1@nK#NjNq;umzJqJEe;4BMkrAp<iR(RqSB7)So^wCj0*Rie1~@Rd{*z z&?&oJCq6GwZGO$?@8r0NFwg5KN`i|>s?Ly?5lkh%`VXIXmNK@t^NSiSW=gIdyziuD z`+D!kX<n8unjvuhNRwCLSVuOhe>O)}dctjveRZEc!(|CutYfC2_*WWDWkvF6knkyD zPY_pg6!?%c3*|?UR2F~67*#jv9*Bw4_Q(1}6S%&Wzv}qp4hU_27Vco8d6zwsOm;oF zbau8I(&4BA+|ZH>vlj<Tv$QJl+C~Qw?ryK~XiUZ_zbNz@T<=f`lv$p~ypm2}(U~D0 zX+h(4-aKqy^wv6?cac6hzV-C7B6$IxL4|R4WA}$&*;A;YYPz`np{?(oFmkKq_MZmM zjU-M=$@es|PV_wULV~!laL^~VzCXk5ytF56qG(k%31|V;IdY6We|5N1n?(!?nq$R_ z3$4UU3AkC%DNY%#Jg2K><ama+_N}c+fREk?d&n^+OZbeV^X}B3K6iryH_+52dGk?J zMMd5Pb}^ICoAlO8oINlQcmQlo-9O0$yQpvTgyK{wbF83~;{)3_nNM?JNY~#8u1)$r zEhL0Z<@<@jK@zNqOzlTv_=(b%vK9t}Wp!yR7$Tdm&eo3C>R$X?W4GAnUw#*WyEFxE z%?L7>GJylo2L58%d!B*vxZv(abgJf*2KghVj=?;<;pR~}7OS5Y67edL#D0l4%`-GP z1rE973g>Q{NuuhxZtn^9QL~L`rVS)dZ)MdDyaCVJ8dD>VMDx!T4xGNaGjneypqsy* zlabC&N|zX)#+=xf#H6O6|NT{IYY|FwAqxBN9Hn$B_5fB6_EBc}xPyUn1`NFIjq#u( zI~fL*B405$jpvXMe&ou*a=zZ@sk5IG9TV~Y;KemsW}KUnl3%|gkEaRa8Ad=42g26- zNf~SY;2EYP)lXt6M36a&{B@|%p8lp+HE)!83fX_##UT|^r~Md46bg^X_U#+areh;d zBcY?4!2D$c>MKj4L)A|yz5I%Ap-oKZCRBRQe-(x&TiBaRgK*5jNnFJl#2gD-B6#>^ z4kpa;s+7y$+nRfhjf~XL{Ck$8B|kB81r7I$logZ}6*=138L<&tl7y!H)OZUPSQpp% zdh4YJ5i$jzqE?nHje12AT5Pj;%~WS9K_`AaTVc&!wViV}3LB-D_#bbhvGk3z)1DrH zoqOs&&Fd##y!CT!4hI?TM=+{6bIxG^q|e4<+QK8w9Z4G{^~S&i@T_boU*NK8s+8Bv zUw)A<!SBvZy8IhaS~>+(aQA@=nO^CKql5NIoZseIUxZzPLbiDTfRUiGQU$fE?jHr% zs{**)P5<1cJmcBA%O^MJk4NnjEn4^RR!(lN8AtNpQUO=~vMU`bTP>6{oe>QqQR@H2 z0?ZDSo8<QoyeTAC`|Pbd<m#FF;thxVg;Lg2Uc{fSLp{?I-@>TiEjnW<zC?x3H+XwZ z1--;9RPk}*YOJ~jZaQ6^oi=S(#zW}>z?Pyy!xJnQhB=1E738*ZeHI)`gA*V3Bh;c} z`+|!_uWff{$D$bdr3iC)-y27WJeCmv_#hR=c>RvDm)+GyT9(HVQyU$hFvBJKUN-XF zo$dZPcp;27;E?4fdRMdBlYY=PxU;&lD@zm2oUtE5q`;9*6<X^$LJ1X=U~YY#(eUe8 z)(Hu&SHt(z_~z8JL-FYWct>%W4(r$Ei9Zv9U$Seotc(4?1ngWz^P9dmH26Hg;SFZ& z5a1ZCeAo*X&%WC@UgPVNbaO+T_-$UQcGL6qc~dpWnkMYs0w?wA4ZeW4i_-D59zQS_ z+G`Cr0{tq7NfxcAGcA|!24-d`P{9P}C$@d900oC)t03agK62-;PT$9zICm^VxWQ<T ziHYttX~X2tmxgOWwHrZ9DJ+v*|2kzNsK!>89lygkB4yyiag$VnUWAd_xl&G!C{ALV zbDin@h!CQQw!>r;d7h_I*b`2aKRWJOcl6=pgmvUyU}X~8a-2+=1h?1r%|W|-ql<iQ zApxJar`%vH?oDoVCBV~@aN8rKKgT17+uYcV$l$&QnuYO+&xp=bo`cP*LY-wDD%mkN zh2wSEZMZ0JXJBM__6(J6lpXaMD){}y{h9iQd^yN=w^K4#O2@>%Jj}_b<XLDCa%fNi zhN@()l2)L<f;2Y%64_{7nw@v4*UdQy@%*HC(4Pn0(X>}Du<Zk^mvog8ZrMin$c0M; zOl+kTn5F+cQ$~QlL%p7GMhjk?dFc0l=X2NA!v~`!W{km3RP7H-5kbyWAI%FVx?EeM z_B~K93kwb&d9@4qc6|aJ)H%>tRI_A)4iWvBQ@CcB6!@xb9@?G&1`XVtj?R<2+c3t? z?g98=Qa<;bE5mnS;~Xs?RA=9ldH-N#-LT^>_PO*v9yfbx61)Hyc7H&DHl$T?xDxqR zyV<!^cG=Qf8jsccBJBzqZd9fv|HsYu#WK5&0tMV$&ki?7sA@H3bCvX-c@OCGmxyP3 zrCxm~Ra2(J#tar!IXOB)gr3HZ#JuOlmvK3BI=|ww7x#9HuGb>M^c63D$@oeX5f3Tx zVy3HtK<;CFjfnQvptI4~^axT<f@;4ePsMq}RMCWaPe!ULdF)Hs($@Nw$+vnI&?dHR z-io98m*HX?Aev3>n-on&OK_Iu^cQ$6Ybe@nZjQ*Nz=nJ-=GW1N-lFs~8g~zT<mM)x z^U)t(5`G^^Ld56YB1{6q+wlG2D;=CjE1PT?Oa2mEn-zhn^O^4gB_T5J!_Rg<<rX{X zmFxCq+zyvA6Jo0kD?b31HYCCQ2A85)6#o0jCPQwFcs7x|K5eX|{16*HHRiX1?vHFA zWYAMYEoe{kJGN2Z2g(hba_T&gQphg||FNI2qCB!%4fAiz4+^JWHRo1Nr7K9FH}@@% z;~D+HKG?m5=?p25$A$~ECdqw`AWmoe)rC6*uFe4lW&skYJB-MrZ6?WX<prsLl!|zJ z`CY4KX)>4d&+i@ne^e}1Mrh9V=Z!;A!C7WAzDd;)GeU$A5T5?k7>iz$Pyy=ad<Nc6 zQ17al-F8sYip-<$IX>K-ty|+QCIHI^4o%xE5mY^7$l6hY)yp$*$Ye~Y1YUh+%zk+- zEryTYGn0sfA?{Eo((S=zWs6sIr8VpA&Q0TU(gW4Z2|pE9EKR+5Rp&|+Ry{T2`KNA7 zq~AW>;D}+c{rFf#&1Pn#Bd}UjB$Z`fjbL;zNS#Upce*z=>B(tQH+J`MZ;|lmQ$#Ul z`2aWi6C^DKDh$9$;7fAG)!zF7lVwK}E&ZQ^mtGEbwlsBN$Qws!a&{X0@7W|cAqeyA z#Ln6BeLjo!pw8zg$pEQ|lVe*_);X#cfxt8xY!_P>Qc@02z4Z?4&k!V{)&4h3{t7il zqO;iNe)_K>N5X_lWGgmSq=ykX-|EgrY(l!-{@fK$^+r;m^Z71Mmc2ul(IlzhZv<cG zz1fs<@!U~hOKxZ#7yqsHc-E#&w^2!3Nh)8_%hNL}@I@NT#Ts~Ld!=m8mM_-sOb)1U zdmb(Y{rg4qk_o(?$ETa2C|qYwh`hZ5qnQvG`WV}@&=x6M9n6+(?sYfvXR(FCL&E|6 z8aQX+?V$jHpuXOjswsrXee{>t2d^F8j>66$oo*47D0ed2$qIk6e)!uf?oMm)W!JyF zk;9k-IimDy+aKSNwg}!wkPZM_CuS_iqvbBD_mMHs(-*H{I5lhJY<5mB5Qojp3*x@| zs3{eVW97><rMO4B78WU*@O!5o0g0?y3!mHjn~MdX_6}w$aEb9)W>kaF4IDwH+I=2o ziga3Bj{qt1fYq~{2LzN_+oxK|$plt`r{8=Q(R4B6(+bEH{jqTNQNM^Si$I4iM_9d= zzX=uKb5KYTnx48=w_4-Ohgf25?d+c9FsQr4Gd|xxyy7F<O&#?{jknxi<h-TO{Mi@W z>N=9uUBA*>)iLZ!8tOt%vk>z9F-;+>3XH-5>aiOawe1#gKoZ|^vsckSSG5)*f|cmi zm<HqeqP=#pCee$k$0%bN1a2Klh2x%_g))Qx><K*+`(kP5Wm`9datG1{7%ACAG)nm$ z&UgQ1zn>r+=#frTGOM{d*?@hY2AI2KrURhl=Kl_OAAPF-pG8;zT7g4?<>`Djx>l{v zF@f)h$Uy((bbei9YHyf(tIdKXD-8~{Ipli1IGxxA=lhz)<tD1s5w(D`;`Ex#M_}Qm zK!mOsjt0kCj=OI6dPCF;7m+~~f&_DR@3!_Anqwm;66$_Y#Ntv$TgF;fqp}5uv42nu z1!SYDPkk|D-q%~7et!Ggq6YkYEQw|Y`=Vb(|0c~d(FW>TN=&2hQ4pvM2r)4~?zrv& zp<!Dkd;9h5z<H1J*UHQreX)aSe6U?yP;v3Q-!?pnPl$`dCY*_&OMT?bJwc+8PeX;s zyl#(H`(kypw_9~a3!<rra52I4lNi0{;M`R9RjJhdz#l!qr>&)KLHt0swE`sD=EgJ| z_F23d_iZ>q&w}S^(Q=Rx#A22O{C!9r+@py|z&Q|Y)P9aKjnXtvd;VO@rFQ8zI=u&+ zP<FtV-7haYsKT_s3xg|e0>-GWrlw{+Ra2<M#Or#ALG1mn1Q&u9zQKTDt==ppuLp<e z;gVKg--C8Dmr-}v%(k|ijAu;BO^3(x)a4W4@e93nJtWup8S&bBcM9BF)-z4OY+b<l za=2!y;cIOq$PWW5yar#KHW5PldG&9|kfuS^0C&Q7%_Qmi(#gEoc-Rj%%Q!wy-#TZT zb}&c`3s)PPsdVCV$q%!aEJ#r<lb|ey1M(SH=-Y?3li>3!XvTtMUZmZQ&9@RVLqc@< zBuQB#=09CivD*}2r|9f1;JvzM7Jc$#BzCy0Io?h%Q+}MT8VY<)G;^ysT`ES#+60^k zGYxyb{Xt)F-zgo9!OY?Zjy>9RGP075NlC7kn<K!xYtUmO?P*OrAV6ltU_zS{)%i!$ zHf=giOG_OgMMcuV!H>2w6rV^XizjAyzvj!O@;91K)Jyicgvr+)E_}_;r-iTq@`o1# zgb0(qQ>7E9up!J>nZ)Oj0_qc{oLF+LdZk`%;_zu`QUha#^W9ZUs2F{GVvjXTVzbp@ z!q{~F1^+?{L&+tVefQ=tN;mBJihX;yrsS@IV!2xt^LC<bsQU-$I4S8Hl8`5Ju=BNl zTU*l~AK>wD6X#m)Z43-POEB3P^SQaXxf~FzO?3bIYX{`v6&3qjWIXqMO@1Ms@6Qpi zTWdejBz^m_bNXZhZfRz%e_n=}9p-g?DsXfD94Kg<7LMW870$xA+=sufu6{Cb3wV+S zyuptE&?cNzpb1VGQ}g(N6?jBqmn<aKh1xlPc?pE|@!t|ZRxF<~n7-+nx5=s2_AZr_ zc{eG@WDf_#e7yTY5}h&@{Z@LR&-};MG$v?mP-0+9OE=ZLxH;{1hw-i^wjbK$?BmkI z!+jI2I}`?WXzt2HHx&&{_g}>p4sWe$VBh-22>$aCeMIq2k!mqvLd6r`u+!80J=+Ev zMsNYc3mF-yJ|UFnc8TDQVk|Ddzd4uy;*ZR9hvoAgO^#+uqaFkF6#xEcWv7?*xZL)R zY;IE2g(FdX+07tX+eMz56+)gS%9WDMpSYf_TBG)2n%4OFiDX_2bY)~x!9Gk7I;n}N zMd#2>eM_fTa{gz}p()$&o;wz`X>IQlr_ig<*VDGP^FMfT5vjK~Sc5HEr*%o@(#YaM zJ?8|Ti%=SOeLdn9#c!xZ7U``cee3RcE+aC!x0<6>UuAD!1Eu^ej|>m5b<$>*uHT<O zIX)hurq*t>f3+bgr)rd&9UB{2?~>8x_4PT?zED1_VJ##?YWYX-0GGz+emf*ctTsz` zfS2tXkdxUbB-mP8lgu5F3YD(2Ui5zG@bA%>R<vocJNkJ=D)7guP#Ep*HF^B+ZJc*h zAQS4Wlu~SWfhfLck~jBHx3X2hz77{t@NERkFc|RgB0jw&%CIuiiq@>E{vu4`UvH{@ zdQPj_*k9)JcKH(iu9#F6IgliUY;fg{Z{Ieu{r#5s>`N3rLSNK$<4q|2MVs=tP(jLA zq)o~7a`)t~hymIduRWe!#l3E#Zqb@Nm>+sQuJBn`VmznL3O{ZnK0=6Qkl@3u!+eI% z3~xw+G(#+$ufPA3co70F%Yuo-#pvHTop9lD>>8gtKEVq)In}ONdAFOZeyX=tK^1Ga z9gU+0`mO`6w;xoqNd<Um_-F(BY)wtaK{~$sa(y=$^}HLy9T9XbzNv_0Di|pRADQy4 zd`qtjspio*PP(Sr4O^sS3r_usN2m=VkUHVqzmp*Wo_s-pgzrUb;#)YFnJxTc<of^R zY=k)|U6i>~T^$<gwDNHolo%KehG#x9%&Qv#B}R`uxJho7gvn9I-Kl>o=x@=U?O+lR zG@2eQE2E&)MHCp>Il0inb=pkn8!vwF82dHujH~@(<7Yr9ur4T%2|~nK+nIbg8VMwu z`0Ll#6)yw4UckpC_}XMr1?*5%X;Q{-O;$(XuD2-~R?Tj$3>(AB|M0gvWp5(=mmF5e zJ08nN6&m>>dnc`i?a5CH-<1$EiJdEEEt(|Dd9i)*o~4`b{6V`wru9Z;LRBduPwjEY ztG4+sV~|AC{`su}WK!%Ne=X<VprEzqzP9<{3-`Q@HCU9_=ibww)yF96a}MI3#h%Oo z`+{o()B8#pREQyWt2`Cko(JOQ{$L=ZU98rEE_iL)^}8HyX>-KT*xvbk=`uR|dS`l? z3;zp-JN*=m$>h>PxAgdgsf-O8#khW_iW;kp4NP6Vm;)al^k`9nl$i!nylGfu>5LV~ zb?8X#JcaRCHp+yMA)SWQ6{`FC)!z?BK{=lz;wZ(QN9Rc6g&4|xyKFIFGeCmS#g5HT z*qy~~GLl}ulBL^U+HWzGxQ$p17tA3uQlc<hMxnF{6r>r~=f^!zlJUgi90Z4O>rmiS zs>yy&^H)>6=8yYL<x<x<rMHU=^z5<P^V&hFX`)Ql^G)$~h@UHnA^aC;#dFp|?QNoi z`yF>TYGxH%qVLf=ICsJQr)wEo-E6-{h$68!8~7CgX@scqr-c^@a1sEB9?IZ`tg51h z9BNjWyehy{$)iWk(aQhPE*LR&>9mpMcHz2_w01U5_&`Y!D`{<QO+itPcy;5`cH0k1 zDP#AiU!pXut;=Md`uEky2`1@#kCPhvIljn07+_^Rw!0uE;r&cUumUR)J$BJ>;;fAS zBC4_1@ja0)?v)a76{UWf21kxlSW`4(Z=bgr*_a)ZslsrzSgXgFGXV+Fj!6hfmG>e* zF}U|GR^enlDacQKWC{#=so4fKttgTU67lh1)#?WeYLN*DIm5;W676hFj$8KYb3EP} z%FIdxgfnm3E0CctBEkx`QFZ~TyOxlxlT+pIJ=fCoJVddNm8yiIj|Um7k0H<NPZJ@) zk@&QxCUfMS$<Q}}kC%tW4F|c!>MjSf?}^9g#-k?vNI&t{to}R#%B=$4#1L^o&2+Vi zn5Z~ialFZ3x`5~DX6+8_H-g_vk35IL95O{{V`Gz_)6=QU>prYC*5=mv@E17K82@m@ zR(mO1vO=tF9y^kNm8?un!I0P+-yiFO*#n=Orwbb$Iw<5+$WpNKwvTrGMu|a#LrcO4 z6eX$%r_^mT**4r>gXb2<I>U6?1)E{<_fLl4qNW{Yt0}W-N;}ovZ+t-m&!3GB>MVMs z+^)9DHH(eP8`Y24EoWn65YodL=NjyuK&ckfs&#D$o^S1zemZmMVNrY;mhRz7i915{ zbE`HsgX4hmG39!InnYgs#zudliIE9x%L^PK7NC?<n!=S!O)H%nlid@cWj_JZ%;2&l z#+0<UxYM2TcDWSZN8_KH^Zh%ENfwCPV_(EtS2tEX0z<?(;saNi2+AIhC72?Vy$<Uy zRr&nH6wY@;$ZY2iwH#tqA&EB8@s^)y$kOGq;70>(>rW{XHlPX*THE{SO8n>`%QPa| zDhge0u0$3W6_w!7>XA=X*}YSV+<!{4)#~$LRjSo;oF|)hZmcri#i*WKaF_WmJJ^49 zwy)a+=yE$8A49$ygWwpj(9mEaW$vYz2fTgk`F>2Xb9N+j+G}zm^FAHPlTE3&3S})X z!c>WSxCFK|_ovF`1qEQk!%1Krn$o>HDSR&0Ps*-6uk4rg=gD?N-sxS|+s;i@CbH<x z)i~{_>v<E9EvoFylY?b7=!v>S$)^#-2my14S)A58GkVEq(1Z{?<n8plT~iL*By<AG zdO8<iT9np2Ca+kWu=v4FogB@{<@${|PJqmb%Moy$|5YEy2y8p<yL3Kdgw=fqMM`XP zSt4+!C*|`r)wE2-$wK%(Rsh`Y9y{>H#(CcF-8C(DzlIZ~0Dn}5Z-Oqmw)#tb>?XIj zcfWXDoE@Ap$4G+C<ex`L9D;V=nbpGpY>}7`j47zzvuMj<{~xB_GOWt3ix$2C0R;(3 zC8ebW0ZB!=k(QDM>F!jz8$`OhyOHkh4(XC^_!d6z`Oe|mmw#ll*S+?NIp-L2jHg~| z2PgCMjpO52$RH?xB?1U4Of`QuiJROLqEUckODGYuO-|8mGObdB>)q|$-SeHk^?+y% z*Q;h*pl0AHq}pWS==v|0+BCUhbON1_py}yh!G4L5%gv;3W58f2aSXaWIc$Eoy*aE$ z#*vC=Go9>L2HHbaT3(O^XqbGAegB^ReF+SZExiQ;am{Dz&RV|1;j@{w5@GP=P|%{| zet3ghJF<eBEWLLXM%635g8Z0_s-6f*$#=hreY(DG56}0WGb2{~8y4b%1E-Qtpa?ao zROZtsH8)Sn++E^qCnr`*9VkywbNs(di$C!I1!-kkgKVAQ@DJ7p35{oI`;!}lb1O3; z1ntr#Y~<fW22r8&+q-H~%8mA1IT)Dxa{VC?=P0YIyKd~w@C%2aW4kHe$;lUgMNlG? zX1CtIwuS!wJ)az!DZJMk=<ym`G@X5p$9;JgLRh255G}+=OFdI(I@fq}0plT*l>o$N z!IxmdoAVeZ#O+&4=rS9QcZa6~iE%mx|D`%TFm3Q19kR79K$ZwhgG(d-4bae$N@QCI z?<f;>$d;x;N34@MK==U*x1gp*lb6RpMTv^XQu2x)T-rB$5}}Q4o4zLw0>31bv={J2 z$I%DZ1grd6Y7*l_(8~-aXL-(LCAbfMjwH}+Qy^SkZ~R$5>hqSw@+=~AJ?#z$w`g~f z(}-Q)SX=t5PR+xG`eFn5A?Js?>Vu(=XMNP<qxMUMDkT<LuK09s7(#%HbPYE-`?s!h zpjP$*B@`RfkQ>Wf2c^35gS$5SVqBX{W*&2IAl(W?!77EU4?oR16T8$HUmWBs70r_8 zjXUSIf2uB8Fv?%sJX8vII&8kVcywJgk_qxH*?)=Qp8v+bYn3~<_ssri>>KN$T|)Ng z8*#l`B*9wbg)@^uM~1$E@PnTUXBlek_7<8PpA8iz6x8Qit+1~mj4XvOP`9yP?Jvx& z`<+A?37Qw@sNP2Tn|3Mm2wu=0I+r&Z*!j`M#C)sx1;R|)I``kPNA-?&??McePVES^ zz$j#6PBENMx56W1r+|@B2m!0npBx#xiNGq=jrXusIGn+C07))ZD!ScF&Zp?e1futI zUB=%|OTahg<>fV=pPTG{<@hHj{Jr^NO}tfgMTPtux?)8|t}=pp`@?gP<e=fRRUA-0 zqEiWbZw#{ESuBIqkEkf`kK=kf0@}b~QnIqL2J?T32sv?DqQ6A{tV(E5^$yC&Hek88 zOG--W^!{;dRaEc1hA;e-gqAa*$$n;ke}#MTBy$(aqG->0`lQ{`Amk=J&#LyQVEVXq zvnwx~t7oG-nPL1+#0ei7rKt9gy?BQKEuS|VC#zc+oVW|mS=HFX4<QzM9kFxynk2hX zhP?ce9f*i&*FAXjhzBcvc^=D1TRth$sN^9}^KK>{bW4<7H$JYXf0<F{#CgiwA+U<x zu(Lb(=7w8ViZ<Bv=sJGZ)C4azlLFgTP&+$4F6l~0lqj06wC;+bSCy5O6HTf9ltM2r zFOPw!MpRtI`5X}ufFA|pj1AUQ>kIaqm|d^XfE3^qZS&V=Hy)_s=#<-K>oX>N5GdG? zH8+U3Z*xKb?%o9z*DxA7^MIS)N^+13LI9Sk4m1ZSxW7YQo*)A%%1k&;s=g3_9cXsN z2O_?b#;&140Y=_#T4QGz`+2wkuzQ*+R92j@P-#2`8u}Ull#;0;Xv5sii+6Rdii}HF zq97t07sam099KC3Jk6okIE^JRX<y`{T`r2;MBTJx+_YXm4wFsOg*}YlCEe7)2&>lD z4wS=Du8}*hIB&cxYi&czjR`14jkyP<+)cT_tv4RQ!CCf8TO?5wthrYbl#slV(k?Dr zLF~81NUB;|MHfA##&6&nd&(N2{%7w=>+$~F>U-10sKk>eNv;%^Dxa4D3o}bPbiJm2 zhNTW+XRNwdEH$T|=y7QY`AYfy4PgH1Ugx|O0+u>np^pS9=I#uDP1k!Z`p~m#-_=Uc z=qSw|C>AKL6xNaBeC>JTJU@4c;w?rZ6UbH5l*HJVKQdV}wvZpCuxL^obo@NHN<YQi zJy&I9vXM|@aLR}k3nSB4360rbVjdpy!-ru2<X0!hFV(RkHW}_Jjdcxas}oy-p!mq= zr@5A}us!xHzS`u2<!S~_g#cCCcd_`lmaThn@0^7MXV}<&koC#XMZ$WhF%%a{Nd_Z8 z(}V0~aH%*?#`rZWG}Zo<Oa&>!8xy#t^%H9pT>9EZ`11>|LX%a}Co*EQqs9C5CMLGa zd_%qBxGB3L_hm8*oanl3wCa$ee~39|ej&5Y0yMRqpyMFa1k~u>ym*QpatzU|7)MS= zM~+GvW0tuC^U&iU?a!~i7r|UtpWB`v*`9+Kk83PZ{S^b0GGYX3>>(zYqLktBH-(>` zRzl!Q!~U0!u(Jq42!w{tyZ@dwC)^~aoU6qBL73QGt#`An{JZT7^}7C~ch1Lua_K1B z6lGpn+gg)2>A-$yuHp>XF?x((D-Q~<{x9Zc_0B{z6uoSG-0PM7<*hlHK@e)9=I)n0 z_@kt^xtiO$(*YQeM;QUoeCvoFB}ij0eG|#fo)Dj=bkmDGwYY!=X>ku8Y$evI`W~^T zP=Jfk2Fb=|(-glU^JcMn-AMCaej+hP;#Dvh@imS23o7&+(b&$+`sBC@<R7+uICmj7 z^W(YA_f3;vPlIa<-H3ed&mIB_k;_#tcAD?XYI_o!>uf>XJ1(Hr5UJUZjAANH#~6_q zIaaOlG168*`vv6XQ&oOYICWQgFsG33r-KlzztH)D4<&}Gm#T`Zo6$UrB65%TD5+)? zq>j&#-u%*wZN+MOD;<RfwTF^<Gd_Wo@ZPXk_zp>TOT8}hwPKxTXj&L3SG8^jgAoM> z&xWo6oJW3sV5OPZY1)c%-rykD=)aLZ2P4HORwIFVzBOmRQ4puo8I(SK^tx;?ku#ac zod`0cSOB81Sv{P!(pE6bXCa9N&b#o33_y0|IdpnBMcg$5@&}hhSHFE!mw8L~pV>Bt zqCA~5tST=<`6UJ^%nCmaG9+{bq6XbFZ=-1^r~{N<Kj0Zj{Ayn>o{K51A}z)<F8nhc zQN|;1n?uX}`l`EG{z^qqOW$ZXfN#7$>x6-Z+&x%nowwc4>2)X}S$H?8Omt;y_dp*q z>NA-C<!cg?wN7V751%~y$9sAQ&8C`oJcTf0l!gr@Bj6~`gH5X>htc_BTF&+=R7_<p zF-lbuRMJ0$J2nXAJ0?!~i)GP_2c*XdThpF=hh;UY6p>kPwTaGKkHgmcU~}GPB#QEE z9=Kaur0~W45@?{K3V)-L5?-;O0w1NMRAKq;uH={`enTMptx@-{B%*~^HoirLWbbdQ z*Au0z*J+fEyA-jQgQq=yTw0<dPd9E5t#(?#?-m+NrMW$;&hd5C`>%v(tV>o+xo4fm zrA$FIcYJzU(W{|JdyWC4`BiOx_Tz(zi#)`u^Hu~R=h_lUSMsR5cmMR1M4-e;V^)86 z#t<e?fyRNYWC?@q3iaqQfEue)urySb5$yps?VX|c=ATzKC-Px5`=?74rKeY%?4Hh) z<75dw`SO3b07;;NN7#e!F7mNAqqTVrRrr=i<z%m#BQhh}IM_{3Q~-i_#pJ~NmNwSg z{gUv8-Ie)&;JsF-c7}y6Qjt8Kh*5iBK?e$y5Yz(r`6|b8MOxYlT&rD7cM=KroSwQE zud>_IVmt(O=%3<^mKf_9Il3G~*X@$XErMp?(sUt!Q)lF4=#IAgHy5jSty|d`9A;(> zYLq}wH}5ZQy#QNt^`#J&XS~MgO)TJc^up_B<EWn*GnoF<G$FR$QEp(%*!M&l_qpO5 ztZeCo;b=5MCccL}eniy4UtCo5JUaUG1?AaNAe`v``1W(5;!?fy#pz6WmsFAo?(r;W zL@prOZ&oTM;<kaHKUS|2rK+87Kvnf6Y36gtsKTQDGRv(t&+#Mnab_8S5d%G~6)Htu zN0+^M9T6D+4)QVyku+fRyH3%XiV+iMG7v@&qyYI+`hlLF-ujqlK<~PSOR9!7sOay8 zT>SsBGa~Rl1^%oBGv)O{LW)XC$sEq-!{KBCi5iLzSQGiNm8<g9Sd&JN;3l8lAe*(0 zso?v8-`s11VX~Pa!HK00%b(VIu`srQP=4dhd8L>a<%$G_R~RAlPkd+Q-3<J;h4}sb z!_|unnrhytScZOd#aLrj6@S^)^}XE5yu+yZ#3{o;p9i*0g&2Vfqr+Ys%=`}Q<Gj7& z`AIsnQu*ahT_s~(4Ix*V*MqTnx>Mq2-gVv<aSf*d6<?DY{}^3C&EFA;34czTX_r<A zq)&v2>S~)6NXhjpo5?hLsgAdi4#z76TI<m7QT&h*9&uqjsy|e8JzWt-@k312_psJ^ z!Pi{}s@9zeiO(uszdHih&UCK&;bdqcVpSF|cw>K!mBnd#zSf$LZg++CrP~kiwc{K8 z?@zZRBqkwj?meyAp&%W9`40-%b+Vl-FMsw?W2sZ(&DIjY?e6aiU!nn05q{*_xC9Qy zJ6Zp7a5pFP?m6E&_u@sXq&F%5!fHpQ3&+ki9w&`1kd^tQ#Kj#Ii@?FjHKJ}Ma20{K zwSy6r-d!wD<Eq9kRy#UYC@D5VM*l1!hnFN$*f)eBI_fwdo`<KdTDuA(x4jL{7h7Ds zVdkr2nu}gA4gXIza!nB<Wuvv~pS({=TE1%c0ZUW7X8Qa4yPIfi>;M(FQ*w;$+pCiS zf|uawGRDfR>=<$9Jz+`4`?DzfYyM>_^=Z}dj88nCQR!QKp?hs8cgeTrN;TL<mcAjH zi^1ga^9#ZqpB|gcm#;FY&~``YcL7)rBv$C#R0a`g5r@*>F!sy6P6S9(_EVAD?0ok7 zNlXe+Oli$oRFI0SU&8)w`3*<R<7BeS3qmIn>$e65&6EGnH8iJ*&R5*PEpt!!VJR5Z z{?Y{$)g!$HYEx8Vr~r{J9zk2d+NHQ9g<E=hyL$rc6Sf1iz|UmSqJ0@Oxjk~+IA~+5 zTMB8PX>Lxp6XT-QH<3PFCUSsJnrlr+yi@sm@S{|x6XJbvyR%Fn<jcu@4E|0W+QT^2 z%?5QzWCm?D<6ap|VPUZ{29=Y&%|)M~EXy?y9;P*K_xG+$ti!@w0$7zbg6HQ*m6JZk z(DE|ExPD?_ls&vm($w?;aHJ+bJ#HUL&A~ypqZ$IDSU5<Y#*Pd`#9APSS<Bp&z=3U9 ze4%Q|!v%hgG12qU?YBZSa$_LgVE4=arUcLtwm8=2)l9twTBYpSx<R`d{m(aXqgrBP z9UF(Mh!DvEP!W;SeqluZA8PxD`akOD00A1`z%l?@$vt}He*H<N0iV$w@R+~x<+%B2 z*<%Ov+I;#&+jggabXNUC$i;O{703G%#fTZs(z&)Hb{`U#)humPFYOOH#0W+BWz^5t zCWfyOzA3BZz{+w}S;y3feIm8Bv+9eEzG1Hs<DH+R7bucB{+aObWSb1uC+8F49)?<K zj>-Bo62zPTg2pS+ArV#$4!PaC&h|or66Xcq1|YvBTm-1#F)|MAB~Y<&E=+!ZWS`oC z{dL#s3bv@7-?R{0P#1M%H`2OQ+TZN@o3p$yq-a4X<8~FCl^ER~PoPXERxDmw;9)}~ zBG7JEn)}#Gl-Ym;S^aqhL18Em+96>9Jq8ZEE-QNHnnz3&Df-JplRz-Jukbl-rt3c5 zcMtXl?afa7kNLWc$9rxJ3QDb{q~Jv(0Kn|+!g(-d9NSglk}Jrz&$v{>Cp>6TWG`E> zzVlX>7n<^e6{Y(C@<ms?Xs7#DcvZw7;LlIMbj{2#&cDYY(KWZ3>&6QL$HOD`4AxTH zcIi`A_@;vXer2LS-<y_{SaD5{2S7NAaXS_Ti0tRjVTEnrg7q@;=HR;VzUd_O+6yzo zS5_NBO~q-wmBNbEUbPhDKDC-D)!~9F&cBT{@prAX`8K}5?pU!fy7}R9efnwupAd}e zl;9ski6D<CEiDbb0lA><YjCw-ROV>3((h=6J7$iKy7{i|6zH3CaDiXBMGopuXL>2% zCWZWYQvxTGZ{!cm4C?&@c%n(YvnCecdVf|0D5o5U4e1)K8C;iFS4|_k!L`;K-oCyw zG;fgw8(&06xfmR3xC4UTG$)R{uTkdcRF^?_$|o+n{W4oR@abh0+Ld*zS{kMXnKZc+ zuXw!nA}6<6$kpNzz_DPeHHfPGT}?Uh=+d%ttxI*S+O^c>3Y05mIMY=2=b9O*ucUnK zOqsN%Y^+X>fAI4`%PxF;01?9<i-JqMzbeynFVHYg>{dyd)eoBFh?H;Uv(uA`t6(XU z)D6#=9?KmFZp9ZI)rNw}21GN^muTv-2cL;!XDu?gEwBBNp`>5Q_Yn5Qz|Nt&DQSb~ zU$rcKAJBZ;hka|7w2-5V7t9y@jZnGhjeQzNSq^Z}jx^i{MUM)Qw?WH?t4a^=;Yj2^ zl4JDvAL#DBK`;B@e2_~D*7Wt`+4g_Adgrx>9i?r;*QfjW6GlWlE;g%w{1x&Qb6J03 z(<<40TXH+y8mS5yd}1p(KqdYW#-mu##dP;eSmwrn`$hTCM`;muOhTUa$<hYh|M#R; zl{Hg)taSo@EFb}FnA>E%hJzpxJ%vn&{Pm}%JR(aPuwe`*Fmhs`mdFHEfva=j*t7h? zrut^guCt^P3<v<}3nN^+mS|weTXBrBjMcVJ!8!~Rd>sCLqtn@PDjf7Wwr|U(4qH`G zUa3!)Ia4-w;+v>0MxvBK>6hn-zSmW4kDM$7$jjUI8S*ak&VKa`8o?K84EnESx_`Q5 z?0y=!TqN2f1qAv&$72CD#j0ID=mfK65K#zfmK(jNitpy~u!kmB8dyL*05&&D5azqQ ziUPfrr3IUY*>NkZ<#%4nvBb29Plbj}!fzEBoa=JXHE7<w;s&c7jQVLKb2qSco-q2e zCBtQRFk5Pk8$V!|<IXog9xN0e9UXmjX(^+X>M?|i1P{`>oRYUEM{5NIbir9N_z?|@ zxpMOISkNDAtfx<4J#W5BNvJhAhyt&9AP*LaSw9uu=%#!Us3v1NEMlTY5d3@VOrO#7 z7zPeu_+?Osc+ATvG&~l+PECnlEVYAw4;CeZmufK~#p17~E|Wt`$(@=B9In@wM{A(3 zb;Zi@IpsSb#Co#cm+8cT3<qk5r&}{^-+$ZKS_e9j?Ev`;#W&HN6W8av!a8rY*H)qB zor!$)dRuGFw|94UOU@6j_kre7-XTO>Y<BbP053y`+}_!l1%=^>kHu^?wh9W^!M{_O zUdCc#8neu5Ox|J;5e@2>a}W#y{u<ER%Xt`-NaP%t8j5XOcRM}m(k^XZwySk?tjo%a z?lo5`bZV3XR>oC<fxE5n$j@nRu5K_fbzn3#ZCET*53JI1QSgltcku`aBy`?(O8-pJ zcsY|P{?+Y1Php8|xzVUpjUWNDlYpH?o4@rZ+;wf?Y_Fu^U)ysYu8n2?>Pgf6hmJ<- zE~$pfmBlC>{2RA(g{hk2y1`3oqu<AWxA`09?ld+<+ZyJo)4q|ZsoZ?7d|o)|o0U0H zDl}~Ue7KBvZt*wuy!YlIv<6oviRz>yB$E8lSi6;9WSO6ib3fwTv&yh0OGV7Xbv~S1 z{lI;8o@~%X(C+nkCO)q137@q+m6(JClUg;i<0v(Tp`IR8BqSq=n_s`OJuTGK)KB}S z3h(aLGR4ot%_tX|;%uDTu2Bqzk}pmin~D^dnq2J;XCk9)REu)-nUf4?lK*VLwg6Ly zQ+%1Jakct$M(C7yxOi|HNIXE$S0bYQ*{Z@qsnv=6eD^EC3uY?DL*HaKPRrZr<|%Uw zGNdze9+3RHBBG)*W?DJQ9w%n};c9-kcW#Y)SGllSz2v5T+><RpnO>5id)FBZO8>QP zYcWdrp`2?}BIKi`I$dfa664V#*a3g)?IRBt7fQ6+;@)k-!rh`Uybvds;c=c9m8AFz znDOnj0G6sP(>uvBl*`@+@$Gp+?JtAv=t}on%azuv`1g^gOD>6k<5HwfHb(rx>6{^l z&18m@uK3b;NCO8o@ATvh5GlU(#T1@wH0rpV_eRs!0^NwW@658?90jI|pc4DTCJpzy ziL#rNY$Mf*!CP%R1Z-G!IPkLZZglx7k}JLQ_63ynyF$pv=<AXJVod}g-?<McS(fNO zX5>8woy+Mldn4(>h-id$mTN*XTAvi6yE{5&#`@~Pg99}+z9d%|f3VYM&_l|NKhfj~ zR8s6cwW<ZXlKpStSD@epwM_N(t#tG>pg!-cVbZBGng2Vq-WL~2{IS>Jvduo<;oxAV zwic5rXsUR|y@eMVhHkCb1ByOVD*eI53WE-^GZhs5ZPp*Y)@O~5|BDZIgXo!#Fd&=5 zkv54$U^dV>@YC`x*}Ye+?_OLokq{T4%*;e?Cj;*hSeI05!bGO&Rm(CeGERRtIwv!# z3L(g9iT0#?hYR-2gK1fBZ|_KU;dGfUd61PO{^)W!lbsC9YiT$W(Gj@wJSk=5Te>f5 zZP-tdY}r`XbLG+Cc)d)$nK)(qsp8GL+K)Yb#2-v@j(D3dJ~}+ydm=8m-bf0ms2GZF zZ(~xy-rZI}$hZymfK@qTy>aSRK2<xGEgleHZ#stnZKDxSu%+#%103k`@5qDeaStHf ziHVCbCh*{6y|h^Vn+iI&`II(6%$RF`fZo-GN}QXQGk&+dP|XNc7|*e-FE-ww5xuN# zX8k|}aXWB(X71j?!ou)=mPv|^)?0D*262*Oko0B7QYyRny@-OWDq`TUwR@53RH<Ax z@LJrl;p5wJzexVGo_TNoV8hoMtKm8U{!28H@_m^SD8xQxCED0i3A2J}9^@>W-TXdj z`0yRB{dF#Q)}`ffuv{Nz8-e=uD_|#nadPzR@5Rk!dT8X~yru42vn5eb$re=_o0^;J z>cfN>cCf+mZL(0O;1J88;vpWJgjQK^bHxl*tXl075ar0{Mn*)yq&Q!g>E{W0`I^s{ zkT5fk4s_J2&sDkKUu_PP@I#t?8<N)(vT}!}A)$yK;h<N3qBr`Whyh4qYA|TrUnDg{ zDPBVwM`uWDoyY-!Yx@1{py*v+WqNmatLSnzaqD;j0m>M^e%8{?jqCmcI7zbPa;NTV z&nIv-Y_>;d20CWC=4ct%&J|@N0x`MXQEi6W8lxPlezCb8&jn58i0}w?^>xpICj+=O zpx60|K@P_4%bz?4lenfp{Vt?_&dVROEBF;06c5;LuXsOM9{Hf`Hh(QmGZpcx&ld-L z%FXspn3hmrlB6cfH?B3j9U>)t@rqoLd;E?BLFv-L3AUx`(i9=M?@s{eScc=B?~g;s zzJ<H>_Y`P^@%eXHqR7drTwld%7{M6bSpWT-IuwJ)(DNALvcBt|sl;N%E4=z-_arlS zecFgDl2+HsTb{Ds`TbeEd2`|iS57Dh|J??VUo81^%tl1y>H8eUqkL22=h1BQ0|b=h zj~unMwY7P9Tgs0&Ya0NE5Ec+j;C33O(tTgGpANO~TF*2}?a$#ywRd#D@;WLgxP3}3 zvN(wufOrwU)Sr7lnE^IGh-Zgr5Wo)E%o2oB?;EZ+aq&Wf;UJW6hvZaKS5KjmjaXLb z?@<@AJ(%<5sL<*uXW|AlsNU{?nVr?H|0iIb?#2R4$mU@B1;hdYOWcv<Y!*i#DUGhE zxbv}C3iKhAzSBMv&l>cjn4PKB@udibATVEu9>79ys-ebhb;<c&Hg5s~vJ(at&)R<f z4)1vaMW&xT&eBKWUu&5^9mMbV0`GrM{wCFZL#baOLaH_V?XW-5`E+<CsG=h6#}Du? z*!V-q??XlHhhYhLY-cC6K<H?+ZNXC?la`g$8DTVgZNh(az9n<b*aLB`R!>$Ddhz83 zEj3(imFn0ZE*9n#jBXW5Km675aU1yH>SVrD`;LNDfhLlp><eUZwCd>o-~k+q?@s%M z>eP~CGn*{e5TMgtr3-C4*!wXiAJAi_pXcrE{VJ*g#j%cAUDUEPv>Mma<*Zi^+B)mR zCn{9MA1D6kc3T^Wn`w3B{&073y<5DS9I!LvIbb)+_-y|#i{KYo6_rggT|GVQm?#Kv zVqEpCye++@2)STe?kZSpB~haJMxxPzL)eN4um}>I9-2a94FEQcy#7gA0|ys-J4uO3 zzyGCY#AKoB)y*|`Pv67lY-Ofqc+O%YObQ<zr`=xnmQ1?sI!Fv)c@N(&zWo}32GtOR zRHS%lC|-OSi6N7Y(%3AsL0}DLbd-%ohMERHXlJ%}{N@0CV%y^zc9zV(J=8Hcu_A#q zSkWeR)@BMt8A2EnS(|5R_#{QenaJ<N)^AO;KE+LPip#-=Z?}w}nk`VNC%pK*zq+w} zp0d+~+c%fEJ!rZ7q!uw!R9CGBm871JG+c!X@1D$WSbXL0N*iE;HgM0~o&a%6X=!zi z&^{ET=LBpfTU5#S8vQxp)VaC7p#+nM`H$)Dz;kQ6^FT)Qn3x#ILq(mR^8L9dlOUtN z4nppW_oEP<N=1$Flo^8IYY4aw5U_mv{K>Mk2U$=-;hOOV?d20l#RGJuthD)vl8=r* z9QfLAAL}PC>b~ab?O#Rq;${HgrxMVWbYL^<YbY}~`LVFDFd%QeX@w$YGsdk~wweEz z+c5$eN)_@vhEn)_Lxy&^nYw2jcWjZK1sUYui)Ic@HNP9|3a8dZNK8sPVkzg)oqqc+ zGzI<*ZcMdN$2)5c&{h@)EwAhSjMm{O^Mk9MZ?{<(9{#-6in`DBp{EaoR!o@DABbY- z=t)-<t&S(@kLuhk^z}CeGUmX3!8JanVTg@a{rtK_)6E{4iB+qU@WaQ1F2K`Ri1?+Y z#t>Eknj!8f<S?=_K?_?;nnyicWS5l$Q+@c+3W0Ve-$Kdf{6dQ4Oqm~8Wo3*|3rdq& z(5Ctwr<U5mL23-@CSVzP8I_waxj_!JPC3=NAAnU~<q^B<MnQ7u1-Q`uRYbadEX)e- zR4%&eO8or53rQwges)?fo>~_pJc}vxes%H1MxwOHXKE~~+|$lVW6%Z(54kyBb<2=N z(^R^#(zk$P2wVZ%@;lk$v0vGpt8!AprlUN*@JMF5r8X(yqq%DkLp3%ahydC!GRVuj z`vWOs^|paeJj8Ja;docq`@j^gtZeS88sv~i2)a-7{F%)+Oh$ViMU4fZ2|Ko;4m*8J zMAGo?Wvm&A*;C~?5UMkn6(P9K`glRSfExOEBw2MJN2cUfF2(ZY@)#GhGOdpGjEo4R zMq)yK!AVm=AS8fVW~>eRl7i#s>R5@OFQ`FBYg9iQ1ky(!XxYaTR7|LPo7*<)A2}V# zRK3+1`T@LQt++cH5daMW*zN0lm`{~}`DjtLc4#U41oi~&v6P~`+8Mk{?m@!u^D}qt zU<YHSayNK)DxUsd$?4_B-rm#?d)y3is%&zqdX9SbU%k=ev0SlA282Kac}YJPOH4qZ z{Xo55J6jsjLpV+u7__Fld4sz^pWE#@gos9<c6Bz@=zOtZ$<dzmq;j1Uaf{wi*hFZg zR{SOO{N>xvN_+|X=D)S=py8bvh%@!`mnB4&PVKi4FWn3L<OsiH98RwI?k!dy%o{_t zx9jJo(R^APp%kM1KH)#F9Yx78AkC>wM=Gg=_LLD82q-+mfnH)47j8%*iMuB?rhw_l z)3_u5=FmcXd3O(Ua82P2NkZ4Vk35P>?}GY3yYnd{03e^OS^62#Az2Xq)KV)FFwJ7Z zM_#j{Pe6W*YT{&6IuRkpWX^j@OKVH&wRn6tK*oB?%F0C~H?sPFN`rZVV=B9UHdfUb zG=I(b|LD<WCLq9@zX$4IhnJ-~t-Za(?w4A>TfNN~q$AmLFJxg_!h3>3*ls_Zd^O7J z$pRjW^?Gx_v)3?MAq`9()MC6p3&Y#|!L{k`pdJ|F_F+$midMs<Xe>3ww0Anj?B<p@ zRQ!5%4|9(;`fgNW-`4^Zt+Q=!@9>Aql8cMQw6qI3A)rl1j>=qK2F~4Sk4}6>9v;^} zbLRM1A4Gt04GauSOm&+syF?tPp7?DQy=pa`avAxG&5x8c0!V-0m%<!H>#-HItUY)T zr#>=AuQnvrob{WcKHYv5fIxt0jE5ALQ3O+%OAUWrp+cWIl0Wu%A_jlwsE?s|{rW8x z)tv5ZNRKYUlP7FhmN=26+8qJj#4fLaO6S%3X0cMi>t5^tBWQU1+w&a_&^}j%ec(s0 zT?rwg?m34Yg*`{dB6tq*ENux=L|P*w-On}#ek)4WTifH~o0aX+trUukj+-gT9s{<K z$)Je`bUAe5K6PMZ_+I_c0s~p-GNa&>8#jaya#=0R10L?<eFr);3g>FPQHeQEx2cl1 zVxwYWczXH}J-(VZq|#=LCWS=HO*NhL>?xO5x10C%I$Et=+iG9<4_A?dhlf+rg0Dcf zmH+~6<ilIO4z^!DY)L4MU1F${_CK<RQ+<`}A%}ql3oS9|B@s)*r{9mIqx07EU}3Yb zZh$@LAm9~e1UMz3Y(xV%*pFq$=bN2Xbh^ycZ{BqGbtwU|0%hd(`WikK*7#*2gZ@z5 z?)nN0)O>dxFK}!_r1zN@AX?EA{;>?(Mq+wpSBHbeg^7xV4xeD|p%Sb0_t0>qF?s15 z{6ryFG8!ZZm~=dY+!hxr>4{7{q|)tnC$S;3#kz?UD(Bw?ape#%TnX@7zB>ji#KcFu z7N~WMUDm%;Ewf>Q2)JDwE)EtbX}`ggm6iQko%G_$&E>LdC|Ubmv_A)dmLbz?8+DS{ z6PxtVG+;0BD<CLnZ@7pax~*|K0}1W#z1Q`C3;VuiYb;yZ(-RPAbXE06%VZ66kBEaO z|EltM{TfeDF0X_DVyCLu=XRQzsTcU+_U~k221mL6dutQ0yuv<!_*B4*VGuZmr|xrk zRhZ(=Ht~b%su__nnM`*E$aY{Mz&vGbE+RqlMIruer3tlMKEt%%n@&>tYyp&Gy8Zlu zd_!UHj1u=In>E})0hRi@LEFJo*PAm$55BbdvQKu>jC*rvU|JfKAG(;wYpt_qEG;36 zt?qDa4L4;Oir)VI+l@JMDv6(<Le0I1+t>W<Ry_!KjtZNf?mdG_%k?D_IYA<RLXnxN zT}u9*@$hupi$Xm1`uef}oO)R`tiS6e<2kH1U9TpTLWy{2iVNzj)_b!|kDwBeL9h`G zHT&76jLkKk<3R<g)eQ9XK>6O7MJ2e?0-+a>PGFWVdm{0MBfhiP?%3oAnn|Go_1}5V zA3uJr);=CVo-e3y&bhD*ZhaZscz(;2t6cX`jd&ucON$*Jodv&or{Cs-0xC$65oQ`v z67wZm{QW<fn%vx)i#3+2OuI*MvvL26VZb_6!(#U5tGd_ln4Ycy#msdatb!}Ofi%HD zWeK0i$Tg6dWOsEc`sL{lBnr!u!2mmHPHGMguJ=>ATzA(OOBJ@Xmh&3sBXux$*F|5h z&c--hcbRsK0H-q_D4FMEkn`}6u~ewT5lJo`8czkZuYz)k%SjvB((PZ*qWQiyvX%Z< zY;(Ec`|$!Kky44AprUe0))lhPQ{sO3{jSq?r}D(ywGhnddS7hu_5F>)l6x^N!8@nZ zDGhhi&(=V&$9mC`>gr%&aAl>g_2k(z*HgDBK<E5Yrkg7!2M2+37^iEYu<B;9$rcl$ zlz3^Lxe0)^aTf==MG)SvSv|rou#^H}rh5z3A1hqz(^exesic$G9Y>exj#$@T;?oO0 zW=-46>|DBfy3E^sjLlD=Qi<z1bLlP@$prSJQEy~0^<2zxy02{m{c3DhT7TeD#o%pC z6@RqkB?(V+YRsiQoJ`M#i$1TAdT<IV-vvtFQ+^iEbgi+HD^WKKjdz*zRFRHvsDPI( z2^>4~OLel==9}~QAmPy2O4GT^b7N4OJwKeY2e2PdJ_QUz&d-Lrkb!WQAA>qh!^vRo z8kO7C)n-<GeSDz!=>8liUf^I52xQB~+4$DJGq`Uw2nDti)6>&DAOUwhkp%CY)mJN@ zk<#f3Aqnx{?yPitB&U|g>vu8%o)#sb0jY9TvE8@nRF>I(%URcEdevNbA19S*1QYZy zoI4)+@zUZ-iI#Eu#P9!b0Za%f!8>C@<TqnPyEnLbcz*AVYIgH+*_kA>+9zfE3LivL zRfVkUMa0MA5@5gz!L8!~%h;><wKY}CT4433pNB%gBEk>}gmni3s)f3({?{y}tNI_* z0WAZPzj4>(q|xNq80G^k88RsLNF}kmt!)gnw(^yJ>DMoBY-n(@IlMogBa8nw=+*f9 zK?6W%|KQ@<(j53WZoQoVY>iE99HI|a4yQRIRjApSa)2#)z6VoYFO5C{4ue|vWPkq_ za0a3Cp=|7|a_jX*Q3Eei&=3ax5=%cohT<fIOd9hhzI`8`CRBd`j2oibd{Kjm9&_bI zG}Pyh)mK&FaXv$q*@FJAWS47y`P8lX+%e!kVw|rmC-=_sw#F<xd}M_G7fVLlwzHts zQIN&hTpOX(QoP33KWhgZoHjq=aCQoGTtt&f&>^)~Aqo@BYsR*w8?m??vae<$fXJt` z$yBYbEMXsBM)U&L!{v|AdMXH=9vzVZwII(Z4l`Jp6thC#s)Ht1fL=%TW$R9W;&Z8J zv4WgjRQ;O(`B7Q;W}*D>-1T*_7ts<cwC&Mixw3Gq5Z>#FFPC08e=RkuwAqmrFcgAk zJy%qUA`mznMHMjY>uCK2K>y-sj}3zNLDx~$Z7`rxgJ}Vsd(dO37@Du-UT=hL*`G3E zg5OV@F1I<T92Zv=k|yYEa4=8LWryBn60;UgCY&&{H%lY;CW_w|?Y*stW7@4=b#?ih zVMYhP;_}d*ax<HpZl9;cZ`P1-CYc=l4=CahR&k3b%p(P1X2!Uc#c1shK{I6kd$;=| z??(7dnlc#34+m<AMu?`l%QBKlQ0eohyxMr(tdgWbPZffkFAnos_&m(vjIWVEeCf;M zfWfGpSeJ>g&W(T9Bg;la%0)yjB&ZV*5<aTJO#WGICnDlG1?|0yNl8^9@PMe)>d0LL z*QYDy$F7>{WdUfE3E>pBL5$DVto(H-vD<0dz}Mq*R8vQXANOSB`-m;u0pKO3dc7s0 z3hJ961iB`o@X9D*8m(IOTHL6Vd;blAj~?mZ(-B4s_U{))2nrLVxQLsxgB$+GyZx_} zWxHA;^VA?vcc(_jon-qlG&KWSl$JV2)+7ewwpzZ?%%mNS)M=ig0onlkDxY*Vo4we9 zm$TQV|FJlE2La`UmZOlcSr@FOo1^Xe-xe*$wE6Ke`Ai`N2F4-WO^(km<FGk0SDF3s z<jFt7<P^N$C<=VH$y%MFCfcM%VZ1rXrlC09w~NwLF+Mbt%tz_S?o_hPFo-$`h<lTD zI&c;LLm^F9h_G@T`x96}yFdA8%s~8^I9;my1nskjN1oAcnUe;dwH+hO?GsR7WE=mF zx+GWyz|nE;Z_g2q1S4fr-@YmJI>=MP_z$Z5hnfDHo-n~I$%HQk&mM!N<bSCi_}WZB zy?M;NN9Sl~o)Dj;&vc=xa1i5hXMO<S<G-~y(+~7ePBm2Q^9sCmtvVjc?U%G9)lH$6 zC0@SPMP|J|bb_Y`-hN0ElZ}<yGP`Dkl_84FMwNpqs@TE{3dl9^f(1X86`xqX)%Dy% z(V`$<BE}tKAqU+PtvAjNvys3j+i@s9{-?9mA<v5!_8<V#*3qD(qEu2;3h(*D(Ai0p zl!OUl22RsDJox5!kHk!o$-f2?|5n|&<NkwbGf;3I-yTDQNBH1+pVm+p06*NVyRosU z(d;<(@pVhb%y!RO*D)%ls08p&1wXF*o`3a4ML{|^Qugeb?Pn8@^}d+>g=*YG^icE& zjN1Y9f6v|XtJKHxPljBAZ%3sdH`RQPgq0O@WCtw7&(jEM@)!HNhNB%BsijQk6Zz!^ zgNjq5<saP$IE+s3+z(J+vVUfHLE3}I;l%Rn^?_bNetdqIzG~I2!`U^;dXgt><ye!e zb7&I#r>LnSW!fdc?ht#{_1`KEE65F#*L6ps(;$ECh=O0GfA)*1Nv9?oGZA!8qkX)+ zyxP>!XbR9_VcNX90kBjby_i?nDsZ@2!LsN_B_T&~Fn#R#_d?%kIDa^wTkw0j^ng13 zBIr5FfzZ6IoeiwVX+Z(-G@1d*NU~o*OtVh?+AB<V#qlu>0afdhG?`q!7$ZZ&+8TDM zOmaA0(7+L-&4=XCV<Jl?_lFQ(_8X`Q4oD1@l$NV|Qh_$+47mRd9UWs!k`Gp<q_ir= zoE%u5ARQ0%ORhh@gWSW@7qy2A$t#Sxjp>o%0Y2-}867+NS2zqr!;81SOLb@w#!kfT zfKG_nCg*rMEwjd;uEM5YI>S0KQLL?_qoW}i&#XWR^Oy(RuKXnA6Z!DPWU}uzHc3B; zhI|p<SYJ_}we)94Wyf9r%?t4{TIPT)?{<D|L3_-LnpSr0v%Ne5+Qg#v06I2g=+y9f zB6uQZ7N>TCm?ID`9uHG|ss5#%lAJ>M==LwwyAjzr(n{{Tk*=Q{3!6E4IX+oFoOtZm z6FAWm(Wh?@42#W&zG<t8G`#K8!x4<;Yro|_^!{G=Nm)JDH&<BJFoI3NcN*)6F8PPS zpD8TJqqfRBF^Qh)En9tVjLcNJIGU6=PJAYxZ0U&U2TQVgnl81zJ-vHz9Tc6>><X;$ zKk?t}N+&BF75?@vwDVNGp5$F9$*7tZX{+)33flZwB*BxJXu^bv@G_4vPh`JpVsuoJ zRhnPuMu9NIm$+WB<BtE~p>{wp*)rbA%@U)}q5h`J%6)lhAvz>Ty-w}OdbN&{xnM&` z?B;S^N~tQWpcE}pRFMBB&%A&#{98+rZ_Ilqj7T2kfzm*JL)Y5iDg`lxy!0Z_aauW6 zZq2$!lw{krkn>(4+9*p;j5OCOB2qaH9!d}ZX~t_Cr^4D=$G&TzFU?e?xHMg}wOj0e z9Dv<-W@9^xO%M^8v$X}<IjyHkU_uDECU*kFW9VX3K7-}(dDo&}$`U&^3I_)?`9#iS zq>+}U>v>_p1P<)nT-0z<=0vV^1bsfxs-Ic0UJDTSXD&T;(*Bz@UEbc7JywMFlt`n? z#H=6{NeaQovLo|ANXSI9E0(1=Ckr;1?lToXA?AE=kVpFl=(5u`#mtGEwl%?k_WaS5 zCrsz>(NgD4)og7R6%=4vifU4(%8T;za?b17i>myq8QZh2U*abdS{ofCI&w>o_kB(l zkX?C#03CGtY<4EBn2C<NI2zpNuWDmsluWN?$lGjw5U~E}Vsn95BwYLfyEpzpniR(4 z2_n#?4W9WKb3p_p#jeBgx^RReO37c;;6Lmgt*;lTT2fFz%Vs7Hix&w`$iQL0qCfO2 zIw=|+VpCMFHd~+s8{{VeA;AaycRnX?_XY_uT7baEgdxj^LQ!&NWd+dqa~YNjx}9Ux zqaLRdnO#4-hN!Dut;y;cw6kM0F+To>5S7^8Y^lj=-KzEG!v7F+cV`E5`()Zx?tuMn zXsFNDYw#y(`<=Xkf`8{%G9hlKV=rf0?AN*ZV<sl1^)qv!N3UM}JzG5wMf!Z{c5zM4 zO3^XfEB2Y29FoI~{L15eYO#HPmnB(OSC=5@f}bBwy%B?xbZ}6AaZp)Ng3i<J)7hEq zc6+4Iy4#+Sk=9Cz6KMMF+w$t_>c(EfQP%(^r3=Ft`X4I`i{VUh(ViZlW*8j&+!k*l zRrNiHui;@}zAi4#(~pgg-dF2cgVuH#(MPK{OVMXc4DC6^xOdy+Z>l+~{ZXLdcAxnj zHQL0Dsm!v}yq{nD429?l^NLrvCEhqKw6kV(=<+i)D)M6o7#qXftG8%-{-R+i{XVJv z!a$H!L9^t3VY|%8%5gU8J&Q%}Gr{6u*7~<s!C6c*ymH<coIKT>v0M&(qNY6C&CYgA zjWO92GID&``MI!>9h=mg<)gD@tFs$w*ki`D_<1(D4oS#-BCjPSQI4c?jSbI!vA*Zy z2eY24R_h|juRd-6JfmA5xb#_XNDT6??yeT!xY^oTM{E4ICqzuDqK3A3_l49}Npcxe zFh;sHrIJ{vZ_S=SL1$+R72Cc=it0VOy<PM3TU$BJ_nZ$qXU5C#LD$_V1vRyIPS4Pg zxQN3Y=o@Slmw@#+R4fKesd^78EbJo+lk2ElpkZfT8+9{h*XOW<kB55jU^`c&4lU0Y zs<y_zC;uIspGOmkiD|#T=z4MQ3U0ojemdJ<CCZyMcNLB&L-qFg5U_}|z3z|GWv1BM z2nKQ<<L_STQ>rgEx)v7}QuNxLKUBFdT%$nCpr3DJKy`0#f2m3IOS9HppOPhnesSxq zIz*JviI$e;;^GRElJD*K;09#omm0;z5Uzq}V7}r9PIcNP80%pF<^STusbCP!N1cHi zQo~FPky0fxkFdOO=GxfUz?k{|-t1aysHqX+rI2fFGe>*HoN+fNfV6rVHwL|R9L0Lk zY)Q=|+6dB@r!UAK)PDtICB^;wX@9S(qWViQMo~qTrn3$lM<jB&x-_<vdovQ0<$9j^ zQ$?@vUm57@SsM8`JBH`V(;6Em#hlL8J<hv)UQ7&*=Tg?Jm!DBmvwJ>0e8)TO_NUrp zB(V&Yvp)y)>(BN?vt&aFI7pqsl0)%@vt*?cIXl!H4;Oh>9pB&m^?ZX*P5ro_N#$}E z!P-7MLqQ1%2?3wKU!7mGdvbhYzJ$t{pF>VGcyd9NBz0QyVh4cfBn3bJn~EH23y$4Q ztI6V&tQ4NP@NU%Gw$P6l4`N0}MuNh^)$X28sVQ$;K*^{l;?mx5aZELA6a)@@5kIKB zq+VGW4%Q5>^D_*@p>tA@Q~w-kN4G=<=FVNxNl&2SRQ{odGu+J`B{R&<Q1>&=#qRE$ zi9*AiG5vuA6zJ@^kgT@0Y8@%IYLy8I(!+cst=J9GLOonddRM5Rd%$!}joG=~{r&xX zG<dFb;gBaDEp5Jn92aMMGh=7Z5um;K+Q9mxysWDIO;ac=JhDUGT;FJCmrID)Jn6Bs z=~<=a7#f%TAp(TwZM7+NIh@MBPWUL5<;6)&P`<0yyVINHJG6MbY9n^ld@(9UUA%C- zdV2bIM$c9+%|sWt)(McjefwGDow&8NBnpZQ+c(n%mpi&dDcsCP`P#EBQ7kJf$3wGD z+>x%dG}0H<$<c}G^0Lg<8wD|eSyJ&xkb;fVsV8Eg+2-{bKBQ@=KUrN&HI()YlQK6# zWTuu_@cFaHaLMaz_dR-SdtSZ_*}?p8>Zeh%GBTyU!pZC6u}Fs2H+D6?*}}?#nf+;x zBUfo<s+aN_Y5!v3ZYisbvXm*R$BIlAi+%x%nO4+9vI;i!bA0aU-@iYRe%CYDM28or zU5r<d`No12yuqsNC6FY7MUyawAlNWL7LNisIXRJ<eLP<mhh7f5^Y#gPBA}8Y9UWPc zni-%s>pWvcs+A_bXb2?@=6H;m{7TO256|zah#{7oih6r81XMioL%%S2wc8uM*7}Rq z!%<G7)13D9KPkwYdRUlXxb0{mGq$8tAJni}G=)Xz3Z>{Asa(iHi8|5Koj{@)D<WTM zdxp#K74iVzG>(22#*DsmgL5P=R=;38QdL$FDl|XuR52S7_A}}UWOr^yk2^Cn_r6+G z0;4HB^a{S+yYxI+aYf76SPArpYKwsRL074CI{W_d9)cwC_LJT3x0jlm8_4)ZkB1hV z$szlTMZVcE1qJnmx+Q<~Z7FK-j<BfZpXyXrA6RQ9*bb3ZIofE+-g&;UvA4n?Ltu+n zP*sw?%{0*cTJPq%752#y9-c-mcD{-@^7kKZ<W1@JXA$m;i`@2w7f%^wW}6)^q@o2> zDlAg{N~5EqAdk2>$38(_1qDf4Tj&h~wV@taGD8RJ_Nccx9400vPKojEA2zDTP<#Bl zOTE#=?>1i;URC~+`@8O#i$vaD@)b!~$i~_VXR#nK+_E)(irN415m!U$4xzB1sEKIH zr8cRs(H%vzIhn7DQdp;_XB|(;noC5Kk}sHLmt@ib?AvugG!*1yDU|qw!TX6i(n{|0 zXGp)^x;2DV{*;tNbh|tIs!I-iQB{$O{}7oC!?Y|CWt^9fxzs$@Xdo>nCMIHG5zEj? z+9@<&9t!M8)$^p}vZp3SjJ*<3pFx$U8wm1v5BuM~eFLDGLZ%O=WP1zPc&USiCo%NC z9~RQ=*Q=LwH+2m*bx%wUCnoZwiS1wc_++Hj<h+DzY;C>Yr;p^o!>28lyadk`fdF<T z9nB7{fT7~j_?vwZ6<}*~1a`+Y+RGfF@H5mnrO&*nM<GUWaW=J<Yd(2MhptkWsO&{5 zRW`S{8Wm@bqV#NwYK*swH1u<xDf<<ckAi_=+HZ>P?4txc(^3nw==TkRLP9p8st>10 zGS)#89xxxK*mnpsVPR!`X5OM-s$8Hr`&fgO_13XV^d^$b5XJbGXVi+nh0l`wRY~S6 zgV4*3tSnGM5vcX=80_t>bGzG#8F=8b_#5hrrbC)el!MG}Ss>YdFJ`JUVY~9fTRfHl zoXuF4(as}GCg^XiIzzLvC?6HTPk7*pnwo%iU1f!rxd6Z1uAKAzCduT)B#cLh6z#{? zk7;UvzRKlA!ZGs=Qy+pW*}lQ;ynT>$wOLvP0gFXSh36;c<(<hp+t&EY=`R-_T)kNO zdIu~qb`^o7f>&4uSk?wwDQ3$##UnfGr9QKT&-Z6$r!l<SqoVA5GV=J!$}5%6_Vb9$ zcy2p`1A{|>mCa36q3T@i3>(wC?TD!H`4_CLNOA8B=|0ZGg>+D4q7ez00%Fg~Ks*S) zA4&`({f55j>OO(s;o<G7*ti41f?}<-f!?yPn1F?DrlTaU)?W?Kg6~LSe_J1GJcQo= z@?m#(bJ`;MRicK-Jl3V+*a1uucqW7My-TmN_pN-J$W6pY+wZcM8XRxRO`2mL4<2p{ z)Bq{ns<sNnIh*${*t~Hd(01-MZJ3sxMvjgNL6?`8Uw*~Gv@E%6M2)iv3XtZ0%Ng_g zxB_R#9TfaLTO#Rp>j=}9#&)jCbo*5tX_3gSW_--ASt}WRAp|BFpFnZi_kvY#-(^Nn zLt(w<T;MJVH`5*OZ6O9bGlN}Tgog4LWx_`tl>10Jl5sZ}7-ZI*3e}YtfIzo0x7;1x z0wj&|!bFgpztXKuKjx)o?D|ynCLVCj#9RA|s{C@|($Yg+T~vFM^jAJCsdEAba9X(P zbuW$TU)CZm`T1}Tbaf#@X~aBY;^L9=CLk7p!V(i{b5VMIO2b#)5EJ9HY!JJHCDi14 z1KR?`FH{)7#&{vKwZ^a~hVsKeLmF~8{$trE*q@c9WNC>L6GQ3)W(}Mwj^7Lo4{mH3 z@uz8<t|ou~*4m#vluBTKL4e@`3|S_OC#UD;if`?(BRlZ+*V2pg$qqHa{b*|h#*a;h z;|$OO<0;qVxbW@GO)kwAkDtD1R1&``0LzO*NKhv8cH6bRBkZ9uLH&7UXy{XUlFBA= zmu53UnJ*2x{$cvWC&*isg+ub<-8};^5V$~J%+aC_0piK)OIeYCZ@9>+s>-kM@euCr z?E3^sNMa#y^jQOgU~pdsGJZhxNC<T-EiL5^1mdrqx}`vMRlpy}N`dl1xiWf*=Jar? ziO1gj{1V!IsqRb}hjp`BnaRv=eqXB(ZsbMIU&>xemx1k1Zt(alz_7@_#(rpKgo&PK z?Ko3>Wo0Flm?tfQI-bqkjH8uQ9AO8+J@m@hxVf0%?17NbdUR@f_AtM>>sBwt>~*gY z(1*fV2COKVkrC^Se!bFZ`Z+Hj@7jw!Wm#F$UIc!A{uAUtNOL(Q#NK$bXDk~I!q@C# zZ1$@OFi8F&O8f!11o_k-f0CEKT&Rai9C|Qh^ecV>$M0Z17>~2v2W#9Ukk$Y|8U`{c zC=dwx-(y~_UBEF&g_wB6xEBpdO%<sf;d3c2GJzejvuA;d)T0Bpx7Y}5jGiFix&6|c zXlv8C^FjG&I#*{sRTQ?Y$>Ad`lPO{Oi@C#4Oj%u7kUx`1L8(2J)2#Wy5`e)}tBZ{( z;v}rB6CVNQ6CGU{kZ0t!*yYQ_<evEPL9Jz&Jboar&^T$Q!oR1#x3|IW?mC2UAYFa8 zd9!hj#ajr@<2M|lkf2Z%tH_LnjSazg^U|8Z5THWWIG)7Byc4hZvvS~ebFknYh=YrR zBbm$*$w%qyv#3_?L=XLpvzaMLx{#W_KiN!fc3=WY;4kBsgTuV;yH$m|ljeQ_{#Umr zj8!HxCdLL22mA47_><ZCx=>5Q)rn&jCNA#M@NmNIs&u3hx9fG(SW2jGHXi&(Ot9u{ zg>rLqL9s`pqob>{DJa-gL0#PULF%J-R8XM!h1b+GOUolPowRZ*t303(ZDUhVScgi; z*<gS8^*H3QSP9$0#AWF45>rlD&QyO?@9*;O`LlBUfosFL$&wOPu))|Q?O#)X<)R%l z`C|OdpW%{{f%x}_bM=gL+}w2B3EAMVi=k6C(bpf8OV;?3kw0W$q!JLYv(m!P?~97f zNOU!OJ*G&kp@GxF*u2N?w)Z7}U#VF2!d^tgNa%45%y-+8aqGZ&s%lkNRC+I1ht1`g zE9vR#A`tQ5xxFU^SzC6}lfQlE`#etPe+)lrt$H>5fKBR6{rWY*YP8<|{QR8s1J~oZ z#WGoRchK_tBPh2;z=6Q$;GnR-#Rp7Lk2n=xdA-|u?}YJGo>5*OEzJosQdxP~D@h6T z6<m3oK-cr}p1<`kw&Rqya}6h0S!rm<U0q#;yUfnn*iJUxSpj9~;5<BB2723TfHh>d zXJT5X^5u`q?d54tBw($GRN0pa!%kP(?p~kmnyb~`9_yL#^TR#bQ>)^~Cp9`dpYC>9 zTh|S_cCp*<cB-fIk><*bOGwtAS{=S~n0`xW`r-X7^5wBOw54xOr7bUT^9fG1xiiL3 zSXC|qhIu8}*V%D@v5Nkx4G}v+Ou?3QDa2xIa@6VO+|*{=({}_dARutYq^hau9#Hdz zFE594#$)yyeNob7-Z<6O(c|8^Ew_|qiXRFK0OD?HYH7GodTpKE#j7;~y@^V_HA74) zg)w8VCt2pNH(oM4o}#Ht@jnxo1*88zzTPsfs-W!~U4$s5lpr7?(jZ79Qc6j8cXvp4 zC?Vb5-60*4N_Tg6cjp<rpZhuQIUnBr<Aa2I#hx{D&GoO{$-a9v>9W@=k7^<`SO_Db zZ$n>Kcnb)<pFcss(A&4rDGHtvi~DqT-IwsViNt>Y?C|i^(A2OV6W#Lc+BUt#(|sQm z@A!byHlXqTdNhu4XQF7P%9eT{8{x&9TMm}<-Mk18LWsd>r7b=N`d>o|;7}x#N!z?N zGPc;1WjszxzSJi%Qz1$$n+YsMhUVt9?ay66o-XKxaP9B!yI$AS)#)1;uz&mn3%0$} z<TT7?Gv_Hf=^5Z79-~+VQ|a~fm1~1xn5U=b<jmtU4LnOUINa40Wp#~==$-p#OK@ly z7@1#Mm@NO>=pw#5Iv7sc<oLZ$OWPAeYj$NOT4TM@j}B+&G(9~uL{CfG&*%F2^XJYi zk@EFk7>@|@ht)Tac8-tBeJ6mcR|#OHS%Og31E&~QG|16j;EMHTz90<ea{1_RxVWFh zu285tHI6DTE8iDOfA?mBCYiC^y6RxE)P13(<AH<4Y@5l?8_;_MwQSPq*^e57?hd!? zbbdZ3Tt=Bh&lZovaD2EwiXg|FC%2j~F*1VrEQXpAfL36V4+`m@1N_1NPUIQU)JHsr zkIVbqZCP1k%wu4SY|0X#K`lLebD?c|JJu7UL8Bab%5~He$H;whQeIhYzz~aAvSR*q zwgDZx%4x3d_ropbYm7e^*%U5wh%YqiwE6ACgBy$YNBuClZ%hm0yd9^(+BlGWwc)m! zSgSE#V|TZ@#rQD}XhA7)ZxwOK$jE$Z44P{5C>IDz#tYS)Z&$m#E+>Le$Tk)PRq#!q z&i;P$DK6FxVrWuPMTGvJ{RJrEG;hxLW<aHt$_^g}K^}K`Z+-k^vVo$;<$lV5Ts&!6 z_8foEy=5XGhE~l9yypx$IuXu?-m{bs-Q$~;l@ZyZM!F0zZ%_3No7`OeuDRa4kum6f z1>oP-2Ins^AMCB|=KnC);(}35n)>bl!kXTj=^IJAzPdU#)3h)!Fwq->-+d}2mDoMs zFbA{P7O=q)G{VSGV6ufJS5_VnAp7Tk&_=|l<gi-H5i&J`q{ClyPPV8}C{*m_C95FU z*4A#mP$#FMfCGsWa84^~d}u#sYr39MnW<2%)8A80KitJVX!-FLC@IJgb`ef@dT@WO zC^k4TOMP_TPkc25Ry%23hvX!>5=?bWZ#UN)L}Nx!iUjWNvRYsY1RWC@`=Aiy7i1-A zC<2*RMvLb|!@!(3G7hA<J2}vqpFbRkN0cX6(n*ny;}q|>KDMf|#WWzIBBh};B&n5Q zBF5BNaQ_U_SI#C0r%ITU75u<3v^(6YPaZ{fJsF53@;go{ZcBSpT2f`xXxVY??@QD& zpB%rhO0G)sa`Fmh)KF*I#wqL8j@C3Q-TgP>h@n<<;o?iW2|anyd0q@;ZDbwS_X5nJ zc!pTh8M7U3c5akeLR(QvZKqT!1OZk8wV(WubcY>o1`e_p@(ozo@IK~y2%Fownak-D zcovlu7ZnQ^X^k36Gw1IZPiB&R2tX&yA2~KY?%6sUuWJt)O#L#nYq5<R?WPiwuOTg0 zSX``?rgff8A{KyB_36BnbcnFH?Y~?ABP<3Rg=*ovfqjcvYR_cz0-YWbW<4x}F<vt` zPrW>?Xt{)ikzXoOu6`{1F``lg+AP1y(mn+wcj=dQ8&jPaBcm8zC$H~U_A0wFb8_0= z1^Ne;O_x<{2NJEr;VTAR%etB|7tQ8}#LEW#nEtU}M~kAFE$gC5hi4pX8=sGtk0odJ za!=W=DB-&aX@-9*tgEdn2BM;=of0owM2m|QS`Qh0ACqXnPLG*QQ681CK)k?&bTKo1 ze1%cnT`y-i6;~kB1uVvvm=bKnP-Z$$zWx|)_}M%Txg0}&k<I&_oo?&xO%#X#BeF~= z-_-CO3^eFb)Z(M;;UtaU&oQW94wH%;R46t^T||9hdnhH7wmP={8_(t--^{33uQ;El zbhOF=z$GKSGTxctYEgfuS{_SiKX#|pXULkjHKibEY_&KiFAo^u)z#J^yjT2q&e*i@ zf-srUBKg(K#_jgO($<g_<xzyYfSsMCQl2k<z3mQ*6nNNFd$NcH916m^f<*Pf??7YC znXCqoT`~;;ToIeux{g0KH8qW7tYc#E6!P;EO2orxuCrY*o33~48YY!`p^b8C1G6|* zP?OYj3kxljsF1JX`Uwd*fIwqh+*iJ1a9$)j<9oG7qz`W8yE>+~F$cI%EcUsaxtW>; zFYj9zdpNG-H&?R$u#g9JtEV+#x+7k)xc_RNpY!QW&buwXY3{`9)`^&pXKgQAM>%Yv zP&DW0+@KPN_DWo7q6UOi1Sqxmd#<p=?+YWMyuy5V2+G%p^nry&qd<1C`o;I;=bx$c zKFb?@3Kaw)ASPCjAnOSxv}iVlzn{}tLJPgUlZixvpqJ2L>f59o_Bd4j5~_pG$X#6* z%JS;oHPKOCCULMhFi>O+O!LXG%l=_%_O_ZZ3B*BpEz)e9Szi{?7X%|b1r2h5ROPeJ z`4%^NJY#@oD$C0Bg_ja~EfM&3yF|Z!*(fg!Dfrswh%_sa0ENhF+F!h6?Zym=yo2v` zSlERS#EXEO_yrW15Bi3=l~J}1mjoIM^k#Eh8w&31Fn<kNCGO?M#@<=bB~yS|$T^$< z%FPYEKDBhezI_6bkdQ0_#PAs<=Ie6I?E3m26t8gck&Sh94Z(%Id^sCsGU0~v@}(_k zakH!76B4E<f4ZB$yLs<n#tl}2Ey}T2^za&hAMPK0q+zJ1qU|s4hVhu4{sj4cczO0y z+siB0?8jxev}@%$0m?uX?=!zIVnGbn+p>;dzhfyoIUztFKizHUGouCt&Atc<3cPkW zXLH^!e5GTTsBwpi8g$9>*6kR0`e9jm8X5I9J%BdZ$wF!o0lj`qY-DTocc#arq5^MZ zn8nqj6|jCsO`QP4^_(9%c7Fy<w)noNsi{fg$Jc!VR!nl13i-LAf6V8u?=IkS#FOh^ z+6C~Wq2O{jjBSstv<JVu4|H*dU%#=Y=V8#v8mX)fBQlsQ_Ca(F4Dvg|5<#_<8Yt(@ zWuD!bTJiu8D+d;m-okgd<6v0IitTtnFC8BudlN1v8?RWX?1U=8NDSwhBaz};>e^p& zuRJ~Nf{(_1HNom@Q(iw^=hPoqrB)YvxR5G!viNqu2!8hRjpX1~WqNBf4!!2re_*v& zCVa<krZ@ayU$;f0(p6AB+!sMu+RLOBXYSvNrQ}C$b`IR^ONVZc&@`4mp7(IG<}bxQ zUajeP<(Fe}geS+2@p++w-roG$rYR={-26d*s$sx0%**RZp;AzIYyT=3w7twS($c<Q zIfxTKQq+c)Vw33N@#4oouOqjh0CP0E5i}|*Y;AOLuz8L(a|}#!43MGO6-p;2HO_ci z3ApFZckAr=AMtG9Jo5TSYGUdVPO*<|7S3*hZ_-K#4rcobI290;T=g$-d7`U~jZ(7q zl+<8oc56K}&P0_uh!nX`*7MxHH9y)s$SNr+XBy}Zo5X(|uVb@wMhC&H_&p<q`99)5 zsutSiq?X1wz$v2Vb+SX=**OawucV|^-{*=68R0^kTU$c6Qvo8v3ysbf=X302<$fn3 zZ^0Y~N;N@KkoyAfQD3jRtn~l`Hwgi>kd~Hmslv$6)aB^bJE@`BXwz$ObdUroPyk^8 z0X!?RFywtlgJX9W6dCHxd5)EpeK9rN$4oyWIzmpcz|<-9I(Q0kWqCM>0-W$O<A|{2 z=MbnCG2G8V=eO3`p~l%EQbBHb%f`=w@bMHt*HC{ll*rVh8nKVDX&{jv6N(iRwXit& zrBW>|EzR@y4+83I$q7lIn1QFS8n_y35@_!I1x|#CN-XjbRQUMRl%L=Gmi5x8LJBVj z{TYM(zN&yLXGY^23w>bIFzg8i`|0*n00oEpk*Z_@7<I6pUsNZ96Velj0cA>iTl@CT zCYYUtU4UWC;~CkqlyCGC?CcbzW$|<D&P<#P-rx22_jgfJVv>tl?Mzt@uXb6?HxMpv zfp#PreboW;YygGJW$2&kFQPU~P^`_?yJdu@plybgPRLiS+Ku3FUw<XpW-|G!iq9Y1 z^nWAC&8@F`u+Eh|(ZaLh^fYkSRPHV6#c}v$IX*rvSZKgkcvn6Z)ur&iQz9BwN4UP8 zC{|OccH_*^9||W$JUSW*3&UqMzcp@r=w73~|76cX^+_O!Y<R7JV|^e+0&Aat)~uF^ zhLdysNC*1G#E5C@dEbZ6VfkY~F8AVKPNb(3g76E9ftn1RSQA_~67ohWn*Qcs8UW#r zkpqsAkbdy~$Pr6wAJJR@8JC0Q_8*x2R~eO5rIi(d>yW5^gunmsEDX-Sfs`hzFtIyd zo^bLjJ>4<8-~ZU3kkw+{yw+?-K2E?#*RUD5{sH^{2fL47(TtShXksvazJLZxG`P`O zKLU$1p!;TGhzkLZRrk02pk}R&xd*B!KCScD^#Z_hF%mU+s!|&Swu5FH3IsMJ2UF!S z<q?<$Ls>mBAt@Y)5T~kY=FuqFAWS#vJeA6px|Dbcob$owISpbhO*i)EXm(8Sw;i`F zd&LoNk2($@x<4jfDj{#AosgEFy?eK8E^WoI@b{@4#@2}+rsMcA9{uuA1UdA}Xr=wZ z5)~WlF^X^QZ&Io)o_YZ5Lq1LiO?_kG_t&-$CFmFXFdoIx=hI^*nWF^YJ{}MIweR}- z`y2Gfw>VA?PG06U8fFd%ir-DrHx@MA1fLALC%c=;o%xj;V9wWX%@x=;-MgZqq9}?L zCf3)pS}f#4Mwu7Sk_k0Q_2#B4feHb}10dwEh+u;KH$Zb6<lU=-;lG`1%WVZsT@9Qx zx!nnD7OA*$a>8N1-`v@n8XWva{%*Ou(uB{`)%kq0TCdUfY{8w-?PeTcr&~%&0B^r^ zI?|rlrv-XmHmlo@pl-kCILe8}o`1jtw_6Of3JMBJ0^BZh^*AHimWvPc4F*OuxBOp< zC=`O=rTZ;LgEw4(j#uxZdD0Z^Dlhe~{P_d0KYjWnOsR?b?*+YG@-F>%y3#skdTqHS zG4@!30;6NOXF;ghDdKVw;i;*M-#rn?>K&~q=t6(1NAX>+#SrvFf3O%C&owr#HeZON zH`~5@`hqIIz<zJ)uTo~Q0H+hvw?CIh+VD!s^7@avV1ICgODan0h~2}-b2izirnmU_ zLTrCbBLhP-oZcF_{4`LMEP`^(Kq@2D6L{MKx6;2q>7QJAgK5OAF~#pLqN%YM7y#QB ztN(VozxCc2NCAtxin4NVGN-}NL;y{1>udL2(~;Sz$S4?(u<zgN;iQyfwQ!qBdOkac zi^59EMXi2R0mt9@1{!paQwWh4NsqIay;FPFX$4bAqpOO=+;i|U7)V5KaFx~7EifY! zkNs!~dk}QkDzBhIohN4dtX0SxL=7B2=QGms(Ssu1!y!ej_MeRicUWy664}3aVgDlJ zIA8cv679ja|6JPkVdK3MJ>ud%_d_T9BPllb<s)+=nnn#92Ol2?zn~<eAkXh2@;{rk zT;M#hU8{3*zQfA9vb?<ZFZhoHMIFDO26W2-TLQ*IR6fccc#Aw<0HtTS!N4ngd|Udh zVGy|f9qt-9Z_N(>;ZaL!uRe;==#Q{;c>K$!!GOl~?{q!|c<^grvij@8aX4P@c8wVD z;H^BCPDE^f{=?g1rlz6Raj!d}<*{njF5ePk=FaDsDK0Az0|up0LX;$#Om34ELi0qA zILteu(kWBN4v))~Ui_V<rIz-sM06fOapCT6K?wEi4BRAa3MM@0RrQ_5YwQ62oDpVb zW;t2-c`60Tgy=IDlUFDRQNnBLt<|dXQZU+g8C{P4RdzCw!uvl>Sw=@?PrOi}y+92~ zl6Ncs#7dQ<_@e>4Z;I^5HhqHOOTcX)r6(t6kbngIq|tb~kvev<CLVxQ;N#3f=65z1 zBVJNulH1Y36&zm1&^$CCL5I%)&WsNKb&c~kYFcVINMPetIi|DuP4&S%Sn^ui+QD>Q zRVmiv)X4nX{@&_*R%15cGWu%>9;qFUZ;qh}D}Uaqo1(0&sn%E&xhZ65aQovOdTC3H z^+use)0az;<|H$s4_}?tVM|wV^j`2KVK-D^LrhFeg2%z|;2e!H>sjP2X;kV=yH~sT zrdnGgV?)x##(^(eTPWI5;{`QoX$XH5hQ8;|+FCY!PdNJ*<_>8TV4*W~LO>w#=piBk zkSUuzXYd+$GwE-SgXrT4FwFVSKo%KP1Rk42nQtFSg5YO+dfM7`Mk@lCm@@R!6@?or zjDRGO%>ScX+y1))xXoW4Z?m#;yvtwn|GAD;AsJ;?#G1d@_g0-;_vhS?jY_Z3^p=|` zO2&GY=%?!Y9jN6ka3w)&KEIz<i$|f7Zkm2Q;Q1Ot7@3YN*d=Mm)VMK%m=DMZURYku zU332#{-AUar(h#p3*mOVI69Kb7@}aB-WthSBM2+II%!P-4K*uE%c0?67A7WOYdc!o z)ZfKUp|`^A&gCtza%F906>hKEy#l)PJt)@qB*$3)Wj}(GJ1uE$Zsz^|{WzE>Zf~K9 zo0%Di%#C_uhpwJnz0lT9*VYCtHMgr_Qpca!rq>r|Hs3be9SzNW$_s=7{o<wo!01So z@s5}q8w;TFiti-8>-?ig8fU{#Fxs8c+MHf~p{(;j;{nF=1x;6WyCCTF{GjRO8}MjH z4*IRQpYQG!r_H<24$s&h)PHqYc!tUe+z5ble+@q&9KayW3kw?aQWWF{<T)cb;+7M? z6isDhWT3;8gAZXj%_cfgQ;l#>51kpSK{HYG*;9Q_@P)tsW|j_Qig-yHl)nX;eQNAL zts@Q_Uauo14wmLslt~zmgo2&wg2pEvow*dXZC;YU&8F&W>+`KXKLC&D{_swOBaZ)J zV1|ZMzo+W$?|a#htf^;2*_RsnQCdbuqpiKsKOiK?^$GxQ0+=JSqfFF{<zp|wt&m9J z#K$B^(vZv*AhO?^KD)8qSzn}7qY<S03zRVU<0Y(gbcVKby@iFuUtwW1fs5eY!H?w# zy>Q|TK<m{xLq+jHdBfp!YA9sKTiWF&K}$(9(_sGs+MTKtk&}~q*8m#${~52L;ov!N z>=CZ=a0+g}cFN=TYAv<fvw!;herUWB54ZOTjD{M@^Yu}>_*ekZz`s|ORabA+UK93f zpDYz(`3rtVLP|DY?<h0qk3*aI;zdYjcmJao6uu_NL<EV+n2e{vyyHUmHx}Zx2@PuB zB!49&sHmhg{0*}VM+7T}4vbBCH9no@=LBMGsN}!Ad`j+f_Xoj2mm%VW1wv`jUNW*A zQ7O^{Jp6z%U^CC?=lP8)uFUjkIl}!7x7Frg>(Po*vwDNM+S`8S7XC6^1dqet_TIXe zR{=3No}O>GT@j#%nKHeRY{Kc8@4=t-h3xDP?q(WY5iO7Sy}bcuWNB-69U8sQ`R7K* z?Ymc9dW~*9IVQjWVIUZdC%%OC$RsTI4?_Q*L#(9hlL3Q)6u4&pm(*&`Hi0R2Dcr8t zEJQ?{oDJDN^PQTxQWPvK@_z*!E{+aE?G4{ug@zxq5G{%E@K_27$zY1`CarI;vvdy( zfc0TMt@6wA&BZ_p*Ij71w6c6Z!ubzxWDtfEWiOe#k~U~q#Jc>`Yh#Ks8OU8o$w<#E z?d=anI>yGBHRtQCzkK;qVh{GLvkJ&KupY@(b~ZMF0RfB#Lm=MC!pj>FXu7((#^vQ* z6jJE4v=uM+R=x(?g#W%2VfhP)Q+@G_Umbju-rHGO9mg>m00P+p;Bebr5-`fh2-%C2 zc5-#W>&uJ)LXdi+|BchqA5Zs+tJf95{O3abJw4@B<uWjxeSOR<4B?6rlg}*u+zwL} z4%D~t;_K?_KpzMN6*<D5&nhA^5tzL{U3a_6DlcdB7ABR+%Mnisx0kf~YpOj5B(?w; zn4OzrX09B~l@$@`Q7SjsSY7XCXS(`$zi|ZAV9F{g1yXqk2nbwUT);pc+!!P+KpNAf ziW1FIZ?F@aFYWB$aCd(P$KehbUB}PG%!}2)<i-1Rn!fJ0okE7R^Vz=)(Je-Ol-Eq5 zm(`kJLvsAQ$d<CJi|>z^SRdEJasZ`F4$v9~iDpUXj)HUVWUpg+^~sdt;wG2zfj1Cs z+2lS(Bm5sHjmWI9u*h#9G<ET9GCzm}K??vz_)m(s+-|-4Z?8uBQOc)wzj!`H9-!+u zc=|jvZxjTB`Vp8tCG8<usIl}E&6=K^^nLu^ljP^^9c!HMo%ZeJ`PUv)F!&#|OD9F5 zX?l7)Pftz=z(djd_a`Qq7%(8Iu3rfc0kiDbLecM6SdsBz-^nus=9@NH&1V50=Hvvq z{;QMwQ5(+o_I67QEsa{4;(S_H2e4f%QEkvRGh?<~<|8-Ac}h>OL8JK5u^Y>=gVbOG zL^wCv2!WZ=>)w?U6kA<)td3UXbDZ7O1=uvIo7=miO(i+?Iz|bY9S`q6l=z0Yy8?k? z(+71IKouyMRCFbn!%s^C3F#5`Hbrmqaz!tf12%6iPEJnDRh!;myiN=cKi=7&GxdmC zaEV9^2d#7dvnd0efh4Y^%kw>h#>V5|Cq$z}z_ktZ>H&K@Z>u72#3B0n@*4e-5yH$6 zTTe}luA6D_tcwo%2p(NS+~fz4q~_)A&0KnTxWi2ns|z4nsB;H?qP<G)CIaYS;2<D7 zjxp8zsQ>f6(*7X%`1rWuG!X28fLR>3+o`W`w&`>|8+bm!{rR4du(NH^*v9+hhrh?) zrbFM~1e=o*KYTr}p1w$DpAD-&wV6%BHBv<TwRoB*GwTizff#$q<5Cdsb==*JNiH7V z1#aXp3s?_EB_9UPY|M*`shgA#A^V4`ui{_)x?5U^NIp6&rhb`?qLwc{#bXJ4f`)<d zuB3U|`0iq1AeJ7uc6=XonV|<oNy1F^U%wwIgeeCn2-i+k^74@6fF_5pf4H8e@XFl` zE8lkuADHIeRxG}rU(wOoRDP|n6x7sFhJggh@DZx=%1BT=9$t8$1Z4$x7a{WTX{BxB z<t=g-f{%_}E|`r0Pw%hKb7rPNa$^n-j&X}g2x7P23pX)5F8$B)b|m?Iac{5h;&5QT zzZj0-MhI=7#pUUz@R;Oab|%kEa!@~QN_TEsC^*`LIyYAe1FtWT;+S6#hb}{S!3BjT zL=Yc*2HSN3b@F;LB#?x(GULJ6u#!-X$lxzjtDBvJ`Q!^ONDF_5RHT0ibRA-*Rb)Z> zBrVS0DW4#cu~Cq~L)T{;O-cQQcS7R#q1S8mj#N|_Z$5#QYIIjiR8&u_vd#VAg3V<7 zJ@gFucblnkxQwb`T3l@GVku!-24Poq#4&0gMdRq`=wfOr;6nxCF?TmNhw@|qUY`j* zzSMY-f8Z&|O_`rp|3@|{0nC(zB9)l<c&e#q)Kmr7?-exx8)>J?%mtsq4aY%OU+)RR z8w8Id4W@@5@$vE3Gxv7{q;8O)xHtkNV{I*tx*@kYRiKbi7aAQ;7DM~iOELkhg&0rR zRa6>LP4{+vd9<~|1GS}T*=lR~zDW9raS>=*8GK}6d9<*a?T7_A!Y3(!F98z9cXx9{ zD&DGxudHbN^zkX<QZww;E_I)K*hvFqH_fwrIcbz?9gGiMub+5(Q&Lj4a=lm5^|L@1 zQZ+W-E|{Dg9Q*|!_HAXLoln{KBL2VNnY=yifVl`QP8Q+YXC)N{Rr%=K(r{AJ5A}%= z>0c9<9Z}J8v7GCf?iR3+l29=m1JB@hWSJSEnmqOO_2>I@Guft*Q8CtpH(dne_+Zm1 zEGmu=CIbWgw%_~Yv>WSiBhW+aSR1j%o;8++%m4Ps%T%#xzPb7HAXS)@6r#mE_;h09 z<DY{*DZrsHc9Ee%wVS!`p3A-GW1X6`&o2FA|0XvZYLfwq{pr$Q5J72wFk1`C4WTEs zR%`yl{{E?{Z<&!&J^*Jb)i?%|=vN6*dN|PHAMX=%`v)z$SD<2-Na50fGgWPJ1DQ92 z!3s;GDekn&jfp3c`A62y04dx%oPp>pZ{gFkIoXH*0j{hM{qM^kKR=bI7zMN^#5y{S zsDUU656qxfyjbjhMrFP=ObUfYCZa$p)n=SltIq&8BSE9Vir)#w{v*IiA3xp7%1S?2 zdmn2n>zsl3tYU$)(^J6l0^~r^>q8jG<!jJ%V?)HeIN!6Q@Wi+%Hrs0(GgPq`5--eX z_JCqHGBPF%a+|s@Z*7XFf;kHBwLI^|wYIhffmD7^!6WQ1uD_7O$WRV7*NEUGJM|P} z`*l&qDJl8W=}!<nm(ddf3M=FnO_=CJPAv0{t_hKmt!(EJ>_U3Hr>-mRD)$#eG?i;% z^|M_LOnjGvf$u`wzkZe0UIwg;Cq)iR2TiqvcIDN`&yk`Rb12HU7MvHPWxImsb{9xV z1Im^`#Z|IUj|j;!=(YTSUPy$r`?Ry8qbrnX7?dd%OcW8zPyjl&k-Jx#mKKiZ57_ma z7l6%U;Yn7UGXAn0*=ys2dUBIP7)1eeYta*3Y0^ae#!B6rrR@c9O(2X`x_x~X6a-RL zv|)PV*vb`3k~!2M2$``w<m&33IfxaCJ1W7{oqghkh5^?QEsh0PfmbZ4uK6X!`OC!< zz}A1R97sqX)&|E%!(Ac?l!!gQV8QFf@<<UQ&ElTpvN4=)k6i#SmfOqH#<Z5{4uh-k zHXxF+-WlSZhOy^cCUx|RQ5dYXrtA`GYa<2N!M(Nq@48yYt4l>?MM3t(V8MD4YuV^1 z*NeUC;b)>>LQ2q{ZroHLg{meJ@N<(G?p$oe$K!zv07H(Mq48k^kL~>K^K(87tOq)| zc9Mip&z~=vTrb31P0@b3KRSxMzUfkPe$EB%XdY}PX+V?tNTVh9_I-rGKw8`5CuGHx z`R~~Y3JC^PEF2u1%0B-7e!~r*Av=dulvWlM7WxJS%~e?b{hg_MfIe@8yEUyGewDs3 z*QR$hoaG9Nshd+vTid?=e!FirrnW_oOoX|ik#SHRSz20>ZNtIB^3bZqGaEdI3Y8nK z%S&~NiV8oPxV}U?++5;aQW+l`bG^T1+t32<0el#Lzrx*{xhP1Ld;gy1Wj^wwVZ(&G z@@)8V_1%s8OjA=>i>QbgCt!R@aNl9QKE2pGWY^EmZY?;BOGz2Xm3r4MVY4)Mb7AKH zP{L?XwKqwmehZHsz^OBR+PaDb)F!+?;n>b**`*akM2Iml(SLutTNk5>J6>)>M*j_^ zHz4smZvB>rKv!M7xTK(9WhV7rrlBhMxqU-J!(Et8M<zishGYiQLZ_mn4{o49dUKK% z4NVcfo14z<E%==k+J`PskVa&SN7<PQ^McRP6r^Jbe}}=RtOCZBZh%n?GM<o;0)XR4 zrz};RaAjE)cH=ns8BiT$XO9E@&g@wW5m764E|appJoZI8;A(~CjjFI(9Ge;gY+0A; z3`{@an_|wEWk>6KD%c4$+C09dp?R{z#Kc3Gf6Q(#5y9V#=E-1e|7;axAu3r};qO97 z=rcFgMrWI<aBIlC9(J3Z%FWF+97*sN&7wtmwpff~xnO9hTkoE7d3UihmOHB6;IzKB zA(HuF@AULYXR2NXFtb4I+Dr4^c+*CF?c0YB3{g&J)6Af7cagr{G(1b<(WHw5mC0L~ zycV1fRprD#d?$&4rXpQQ@|$E&)}#I+`ugU^dgA8t677uV9?+s|72-AyB(kL~e0;1F zkQV4y=buP%(N3D4|G$MS4tEZ+nZNr(^4wk^*mtw(QjMi0@M>v=rLv^En_{SeE?xSj znr6T`)iXz9@4KI`h)6U}nr@{pbAA>j(HtRSIzDhMAb_L~BE0vCHIm9wcDhCS4s-F$ ze;8e;nXnk&za~>c_+%b#*;`C(v_teIp;4klxgj1@`iO{2Mhh7RA<;k8k$Cbu9A-at zr}5liz7uAdRQ>5bOU#UvRrEAPmx`H-HrOD{ck1o4PvHvi!_GOr^h_DgNWw!wQ65lZ z@oQ=qpa7sOw=GZz!1-3dw<Tp`Q*p?WXJo_&2gVHxnj7zbxd7Q@^3KaZy(*V63?wO* z4_lj?;d!I`#dCmLbysGc^GZ!nLIkG)88s;I+~!N@_BI|vRK7qK!$ZP5bbG30xkcRN z)llhMjVJJE-}Tm3pBa%YcaRx;RleEFj~2<gz_5vQ_eJMn7~i(MG|=h5ND%>kK#Mb) z`?Iy65#6*OArEG=0$i>d_ohRXl<O0T-e2Ehb#XUqgxVc-q9jE{Mb*E+K$HK=5&5<? zoF&lSG!Za0tqAwoQVLz-W;QVd($q1dNz%*;jzG1R837iYm8Q)}X#Itsghd^A;P>9l z!U6(T9hSDavD1NDX10%yY(^BzzUk@qT!KL!#nfW#e=Ba=-UbR{PTo^{ByxO(5>+{v zVc=ocAP~5C+t%O@=OLEB;uQ3%)Ovze>Fo0#<-5&q71eM<=cv#(D=SzJyiaPwT2(E3 zGfR9e0|PM@aL(-PD%8|at^u9240pxJmSVHp=_=xdh8Zs>l$n{$>2yp&DU?`yHQ(gQ zi^aF~$1|6Lo)-sje`TWhv|%EnqWnug9Z}WP)Euf&1zkQ8d(KOm0#Q-k5oZ*>r<rN` z(jUCK)MXHEh+7X2us*T|r}KA60~#C~GmD_>#h3OoA$|5BOQ-aT>8LmrC5MD{ArzkR zJ&R}=3WX^ced36I7p`^o7WR<f)nUpC*h2Jz@(Qrq-Y-JDM_re6az}^~f(1WSFt~3c zO6>GKRoFvT*Ti>+(2P*}D1OLuf9e$#{j&PquWVQvN)4sN2q@Y6Z()o%st*hY`O+43 z)SZ(H%F2F7X$+jOIxK#Mo*^P>k4~g;*$M~t=|5J?Qgw&xW<Op@4CRAjmAP~(o+%!f z`n)Q@EcsEImX?YT9^?-2W}qWt8XODq_XlKkqX&fVCSS`i>B1^1G+-Z_o&8NKiSARi zQBexIAQc4);=$ctBkgI96tJ&eS0cXDe+3;QBSVa{TwrWTPLiy|CSlaMKfICpw$tJc zO-@Y2<d8xr1fNDNPB#H}Ys@u%_2Y*R7E_=i`nC2`4Cpo}1>TD#as|I3{l;S=&LfS1 zsfQk+S{aYl`1>j3HCID#dU*)C<F3s1{lG7g#P*V0V_A>*Vx@x>5pmW)Pv2nU{gsmx zW&)?nCYnxZ@ao#Wt;>mJ4aEVLI7=oIcy^WNSg#!%4lCe2Zf}2F9L!s$7<D1|1_vrv zYr#Q*r?`|!n*8CXTPJ<}<MNXDGZNf%fE?cWE}NyhtB({Z-G+$1RBfdVu%s1=Rkf_d zHejLuqw*&4t5jN+lbl%OCd3t_b%Q2rEJwhO`mECS9WgNhe*z&dRw6;yVCaKE68vwl z5bd$rY)Udl&_baKl4!3nddp8!4rlnZjw30Ju@aM|URT*w@i3r3ltx<~xaNfa8BRwp z<#;G5`^W=ukz=7^mFo3{cA1gknw=80-}4y?5{!&8|6eM^DcBr}Fl**5>+*J@Ba;(d zT|Fc#A8*Ue4rlc-@{o~|!!?hasQ|GXETq4_4xYs@>E_{aW1h?XHy~Ink;x1XIz8JQ zX*OL}B}0S&7Q4f~`{tcGi+ZEWW8G=XoF6msE!<z&Nm+Rq;EIomK>!S9y)LW3a;>9P zkF-Y``1(`Y*mi-AnGqCGQx501Q$YA%$;`yb!3h#Kf!*Tur+Zr=M_k0km_5)T*7{NL z7d!p`<a>O^+C0TmY8@3gOL3FN$U+7H(Vk;*;_U2Jxqe=O6elOAXkYK9&8G`?S5T5K zn?*ak{D>J*Ns@QD(BN9VG2seKOgDcy54=gv+Pj)v-xd7FdJxP<_Bxm-c0D{KqL|=r zeMW=}G?6=hN^szskF$D!8Oqx3YO4~K%@zif8!iY&TbPOqK}sl!MxD#mRZmRp()nMK z9uI9Y+>YHyw1%pyXdx`-`>#)!&ek<93kvdUcI0FQzdk2WF12ba`lSLm8J&wQ1@a|t zSnUcQXGL+A(Xl7V6U{<`YGyP!Wp()sEL_RImHIpC0Sh0}RF`~v^;s`#%<FIth!he^ zE?m%Ww)uCd_s>Df!fuU@-LhT=00X&Ar?E~JTY!9T%f<=FhEhTZKnpL?50gxoU31Gw zm(KSG82iZ~&$C9i8^5IGqCWw%@&26iR5<BC3b*skx|t(Cn;%~p9qYwSFL(~K-n?-! zmwzjw?f#1Dxzc`CVznb^=tbm60D3Rq{8np0YW}-Js;5G28VVD)NL9CkKIg9H0e1wv z97?rpvk%zR9pFx;o#z%8Pc;~@ZfFS$0D?=T!flNsqkXxVO0`w@{mE^KMiaWzj=ZC- zoQA}J#}njhCno?D%=-D(pkpIIH|M)j!PJ5zJY~3zAb3{OM+IPg9>XNyJ`cL15U{+z zA0f3$ngvCQfNMj2h9nlyD}oom3#4M>;?1v)zFr=Eb$pthn*NS>jo`;DV0QvFYg2v3 zqC`--{D2`mgdnq+iQ6l2Vifu$<r!Jk`N6CF{61c_bek_h!e#^3LR)6y^+@lln&XT~ zUN#vlG)iBSg8+@vctscd$3fHd@Z9)80H9Nu|ADtTqAF3(IHG1dmLN1Ntlb0d539#( zP6#WKns0N|p9q4_L$S)G_7ryi8%cr|^lFb0gRvJ5V2r{My7ehZ7{mWd@i?=!<@=)Y z^{W7V*9&rd+Z3lc4057v0vBvqsfu{CS<V{UWYcf7<Ctqn>8Dc=`Z+2>Mi_-nr0FYr zqsAM>FUieUq)14}em|0v8{cai69-8U4yD_)@HNj7tp+%}#KXgX!Yp}s31;+stZ!Qd z%l0rtqlkG@ojCm|P1ZZ(y;~!{m1BW_JaaD7*QYltUqcG7?V{>4WDtHZ-1Z&61U<bd zdmCZcM|3n+mt#O2acgS_7-)bL!Mf?zOpzW0(k#6`nzK_~yf}_;W&c<(sN_WP@yZNH zB5ulJ&j1MWNrEM}Vx3W&&oPI>mF2USYX+#MYxSOX0Y#Aga{8asK$H@6;>)V8OD6h) zEIoxOelmuB)iH1tZEZ>dT9r?Zs7A+-UgIkKy9_ECno|2;7E_;(z+}2TSXflp$`u0i zHQ=REc0@tg`wK-gT<^0{cp&I`6XC?{^QBb)<(H@UnQMGR5IEKsGpt)Wxw8K~x0<iK z@ReH}kM}m{k3{vzHpSHDSUHZA!~Jq?DhucZkRoMcub27e1(|Y*2~r8;IMp1bu&Fir zDx_VG5b&r-|2r*V39+@Af9C{x{G(EfU=93pFftpt_<tTMQj>|V3@k>#cE^wBYnM+- z$_J^M|AUeOrAkpee?F&+6W3Yy`|K@Pd9-R`VtQdQ367{p$jE>!@bU<5A{gt2p=xdT z`4HI90!%I#_Hiz9OIgo`|Ctv~%0UD`(H+?-$sa>#UB+h_K&J?Ol4bFEPGGD*`~><B z%S44`vfBQGR4j;z@<$TNZt-g$@0UNN&6UDB+9zx+kd#rG`Lgn~n1GUoy8Qogq$I}+ z2Li%@@(LL}UPJ+2l7g|2;K&M_O~a|lYa{K#HIW!{*H03m-?om|R>&n_J*fPE6djul zo*XZ0i>D)qkjs_`FhM%@U>|W2$)BIK%cqWmVf?75*=JgY(4k&2v2q4R?+Omr^;0lK z%XCG?lzvD`O8j^hL#vU@=FIXqM;|PZPftw?GHV)P(i8EqK%X^K$gj0f$oM3AFw~pQ zHx~#a-{FG@1pzX$x5o)jpvHLijm;x&wzKXEi$!+tpP3l%I!ynOX-*FK&cG`3H5jyj zQK`(<SgC7Ojzu-OEr&A)RjMK20|5VCad2X!JS}ZWoUav75q%Mw_U5P)jCS$y@PYld zLI2<2$tU{?UrsM!Qe&JCF8qY7LJ03?ysxjXL6kiK-wx~%6$KB@KR7k=Rqzz$r_vXQ zk;gX`7_YO1qkR$4E1a9%F|7^{mjEl}hqNwlpr?e~TaZDa$aaoO`U*AdeOIH*N5n84 zmXCjfi<aZ)3c^}WFH&%<uB>{Z^GSw*)J5@ZkE+XS60g76sQ{}A`CTIt&BptilgUz2 zYK1CO%9YDB0yRTjx~I?aVh`6*B^q`gOA-J!w*rpr(9(sGx$w7GDy6+C&Py`*@|L0% z{eK^<$np&W6nKt{i;YJXcR4M-`-1lmaFUitVLLh068+*v<jqsMYrM2^GnLMdOu#>r z&F9+?gMpQXtbL%6`s#@HrY<x-zRq@rr54OTVAKlw0dimZ-~T=!)8)>e1H2p@QD@2x zEOPqVi<8(x-f(BXzVX2b^bw5KU7+OSVKG&-Ff^pt68xtu2iyzX|7Ak_y8y*+^Z)g? zdK^ty$p8Oe{|8J5zk2-hHbBYzpMO4nPl^5df4Dy2hpWBQ?LIsiN;8v>ERWFiw>|98 zzyI`j;@V|p<pi$@X6odPh5aj|qI_q#ZLgUi(WH-El|KP237*IO>9d`q5)HU!7k78` z1!h4GfFwK~^YK0Ws2Dk2Z-NPcd21zg@Kl=kCa~H9-7R<z^uIpfp2$A><^0cyt!Zf+ z<6&U6$|%Vy)|jpdr_WkZmPU^f^FB+f`d{=FtVo_fEv0qqklbCkYbsv5CJiVBpFci* z^53@shxLE*U)!HY)gj>36-*Rv&Hau^Zsdx}Ha9l@q~9AG`}BoFJg2XJ`k*0KV`J-I z4^k1p_}Bo>jw6ZD@3C*dRt>a)m>C&!@(Kz}3}fTsLI_y*H;0HpzbhPR#$c49|D?U6 zNxjY{FCrqMs*1&1fc@|WCS43Pn7=Q)0B);eU0p&VA_>A7xOjNydplPk3esq6i>BJh z&`>aK2-r<HY(HGC*o#XrmY3DwWMyWe0ZG_^xy&sHOg+L~%P3CM($$>>DP^GG8yg>k z^O*2OZ$-E&9&6Q30mk8=fR-PZ$HR*U6)o5>a{z*%#Y)L~U&f#zFi3%*@;pj9x^JC> zL;?csOt!Y5q5p7o65#Le&8Mia@Jsv33Ry%XzOF7f*xY_%zbBf;9SEHg>biyoCm%b_ z0D}Vq!qCuI%4i$dK!eEE#Ty=|x#RW+;N96-*`*H~0tzh(A=hq95<9>Gl&gSb&ZZ|R zG$B>V&+nzHKoG1)dirvoN)>oBUKJG;8Ihi`KHI-OL0NihvwL?N1380+t$n-TEhl1b zXqxBBiW`>za0(JO=mFJc0(9pqcISRioZ>RV!ofLK`FUwQDwqEa6=51i>HyI!40nzI zmb*i^wUKxG+-3wxv9YiAqou;aXc8>%fwg3t(bnD`O>SIN<ynD(B@J;!Sru8d|9oB; z7gy`a{@ibcy{3WVnePjrThp^K;0-UDCQW=Ww=%UJnJ43y1v<sEXBvTo14>7eM>?|s zuy8Lh&p@{UjT2}s?F%ZOb%8F9wAC@F&>Bmy68hYZSN(#5P#5-llh~`%!dgb${^6ga zOX})zQ&SC27sj>Yt6dKk2mLF?!V8cG_u6=EH9zpPOc2cSdPkJSj}b1bO`=Q3s88pK zdlNsW$P<@FrxQ~YE}JeDiS1veFkN|Yb9Z+%ey3({EixRtakCXN@;mV)d1f#1hU<d! zfIUb9*<!XP?QKc(i6XT^F~+^9$^|x7W@>7uwFLtM!|a-?i_0bo!oZ*J-@m{12I(}l z3tqdI4Zj8XP4E*A55KXoIqv^G+Zx%JDrb_vVoOejotG-qmPqE<nyLQKq&;K5Yj{v_ zk>Y*wUqTkz^#`Z()2Sc)$Scb${9jtTEd49J+ZKs<U!e#L-K2MR`j+E-P@b7|>b1JK zS*gj*eFg>65yZWIpx~l^v`B`2nf*ohDHNgPEHg5yX@-yYYV-7fySvvkHTg}FxP`GX z6)ly&Ga7zM>?;@Q-r3pP!S8U^8v{F$<&)(W8ei0tI|}1i#>c1OfE~uBl%iy6dOi|_ zAst?>sx~$@ih_zNCwn6-ECiU6^767=67F`~Wb4yGiz(3`L_`Hac*#=}3-yzAwFWl= z$R*@8U|+Ed^>#Y}Q7JI?FgA`mm{0m>sr`KdRz3>z9tL_#OuDzb`(D(ur>BQgf8aSH zGMtCEHRqgx8!;)3oRSp!$pClQ&=A;2qab+xmIs~2bZ_JVjd~K;MJ7G}yrW-Q?PLwB zt5np~B?t%t0$)=az7bs=t*p4;(z~=i3$C-6Z=}a(vs(3Cvexg%GdHH1D>o3cJp<t% zv}z!%nPOG<bMtEniSuJ`?*p6<x930$h~lr@sN0n(6yem}$;8Uq)YDr}@Wze$o%X`_ zy9*s1@#Mpa{gS((lcN0m_`5#VFKKCzrk<7-hpumJZ7rBXnCMHlySq0xH&@9eCVMv4 z*1&G*z)m;wna5vvc6(M<HO@Q#<6~zjDXEJGzdD?~?R_q@?$s4?*vw24Z^ssHs=F&| z9GsZ0h}Z2(ikn;bgSe;R>FJ@Nq1G`U)^M<tXB5dvNzSFV;h_1Msv^bvlWEi)Pacp3 z_JX@<>2Dz0`T0k-sp0PY{Ooqk(EC-y^Nfx_DQS6gu<Z4I5R`B}zikVEnZ9GsntDLg z_+;q&-$lh$ougwahzVav8suaCQPUf#J0qDG7zp7^VxHb#^}{4E?CMo2H^d?(qMSO` za{AdZHAF$h#nlK$gNXcFEF%|qq^=8+6K7&!VJT4pe2UoYIby9)aBSjjtS;cI`)0mZ zt&!|pxd&3=%x;$tANEx@wnl0nq(#Y2VqQ`UYA?R*m(m9oJdJ5#^&U>wPP<#Wi3CCE z<3$<+Y6a=((uwINCMMRI5iLI2F6xsP{B3||&g37zxp+7fp~n#S^Tq48W|w+xNLt+k zu}id?OoS%QD;5P4zc9EhAK&NC-@mmcbM?5wRu5dZ{*M<$yWLN)uMD2Rx3vHu|1p5& ziq-!Z5%?_a!v`=G_IfR|+3&}gBWvi=zH%GcN!|Cm?dlX2*kv)Fe=m>&4sy<~?2Wel zoQk^O4JjFnM_}Y>H8PGRPV6>Ekg00DO&(?l`?w1VVEi$!t*zU2KmQv1%3ND}_`5$4 z{X=Lsi$q`Rz~lx+%17d0VTDI_`hvKQSM1}UZXg2|)aYSLMM_~|x_`T;g*#WkiWp{k zTYn3DKwmc9{wbIDXyS%WM+U#eZ?`5<(+VUoTVq4@E_Y<q><PpQ@S0m?YqOP^Sy=$3 zVkj@i$4gN31LEL`VvVN|wTMXahr)W*1CTuf*PPVJzWee@$m#YKw5hHA$V@j}TE|`o z;0p8^OS7#zYWB%^k(vk#Z6f!@Py?cn(3h6!>3H_J?&<i}Kn6wzuZ4sP-JQ***34E3 ziy3!dSN3R&f0ytKmyXI&gM^0WtQMcRes#42z;tjPmO35bZypQvQ@sY)lXz3b8N~~< zmrJy%+=ijgAk4QcWL0oC7KWzN09IOS?s2TWsywq5Er!h^%>rre1e1(Ut*wz;o&X22 zfn@fZ!zIs{59;#ra?Fg}h9WEqUOnB@+a=`&K>T=e%H@i+gO9i0(F%D46$RD2GV9$O z0+s;iOXxi@G*3NzeSOE3<yrnzoV!X{io0<^ofq3hIXOLQ&7-4{v}E!Vlby+zyHn+5 z-NKNhyi~2z9^L?FOmuVwwzzBleDw$C=&ERW3nkp-N~d$+X04Z%1vWt>Yv!YB$FOIS zVN3RfKJ5sQp{bGE$$I5}^Y?m*sIgzi4A8IA%BaXtG*t{J90L<iB_2l8H!Q4P)nXqO z$WF_KhxMX>Gy4=U@UUudcC|?%%qmW6VN_EMB%>ylkyclilOw&IH*F6gfA|QDm?)hd z+|GBW+S?Nc2Hp{A^*(p?7W`>fl`!KMLH-1*{59*oo9TP#c4=qlYU%dLW>ZF4neoBF z4Wt>~(9m_bq*2F~lmW<w$Ktxu(pEe?JT9s(M*M6-7KH^jWvILldZ5;tsc-0FX@9h; zw0-(=ttchT#@3N980=#*x-Rzb8Z$E+^GdU;#D5G0TaE*{KI81%{Ms`-Aq5Qu>f7f} zBo$=VV#a1?IjqMEn+p`4$Qm>}f6u~FrAti8HU+fMo6Z-4u>;15%#fmz%2!}vHP<jR z`v(iA2IuYtgfdLf$=KXVlS9LooAK9PnsM)bT4H2)N``?!Ss}lH5MShzC2V9QmSyIz zWy@KoK|@Hg=e!z3g}lXA08Gz6<oX@b%Bt^cphpK6nC8?ko?OZpkkzz+#`D#aDtM3Y zb#R33+^`<?vx(w<Q$ttoq@o6NsrB_~X<-^LZ~8`tl$y-%vS|`jpyxN&Z_dw{2PdrU z>`F_k@W6_aQ+>|;1eE`24;A6V7#LqevjJotI|ndo3-7NkTk@#``-d%_{;t=DJyD^% ziEMtq1AXc~`9wWhc4SRYkJANt3`q<R4<CpKL#Y*oqCe6|R+AYQ8p^Ax@=Z)5qeE@1 zt;fbj<U(T%=t%hZ_+j2MFdXNm5JDAnwH@=e@JanTZ3xSgVZ<bwUol@+R#&qEGLf8A zSZE{~PL3c94r_Jxx_+>7x3KVCWrcc!>&<%_0_felcQBs?gq=Fkh`~UtQfji);gyl; zy>pk9mBmX)fSTL&>qCpc%0_}89_~W;EHr$%7p$%5Ru51!fhGp}UQ0QNM3$c39-F*p z=-v_+Wir)tqdCrDRb+TL8UC8;(ReUA`VxKrsZ60-`Ls=|FJR}--fR$(ecmpw7&S;> zHJd6d&Ii3xZ2OD2B<GrvSC1oW)8wz|%`G|7I|R?uWDeJJy%|p~%-@KZOrv8>Hq?(3 zvOD$oaweF+Zo6gWs}N$Hy1J2?Hb74>{44w2!|h+oX{O-W`ozR@=2J|*#|K{Aeedw_ znI36>td5x)XOllmRaHqa0W~G{6OY3~I_OuGQPM%LZjB#FlDe7#4mz&UG|L=FNc<Hs zRk|!THs(TDz3PS`qg+Qmb$Gd+u;PACxmx;3pw5hb92Lk})XLXK>?vqz5$eVLbCNk# zQkGsGR_V5J>ghUgANCaGZLOT_+tRA2;H#)4lpXuK-}^N>+~3wB<EVJVMMbR8+t2T? zTClHq-+gFirT~}ULoAbNF<W0NbFR-ezPzcG@{_)FY)lRj@#6{gzuNo-=gcy}*47pW zGH^b685IdZ{Fo*ao&b7bh50P69M2A<mL&^~X7(!V`M*FxXlJ_6LI8rrCrZ?h3k2m! zD5z*@sY@IZK|t)dnG_qkhb5qOp}ldtv6OxX`NDqtaP~LEct+G3_<<}dtoNDp#|X+* zR?5rEM~6P${?+I@)(QLt^>cPZQM^ROgkEO<GM>TuIdD}^1GDIOZC#dDIDD<h#P1h@ z>b7zZLe;!YOvxjnw%EE_mR9p*+W7hL$BT&l9;d7KE)V?ECncVbtl#VDLdD8%lg0_) ztZ&3QeS`&FQ-wv*16Ba&zJglt4X3_n3YW0WC*DAD?r(<>Wds`G!Pe5!BAsRDFD=(= z3Mm_er2fIt;j-5TYy;NfvNPJ>INCTJ4(HPO0iYfo7M8V%;@=;-H`ep*aMABMrb3A_ ze>XflyzkH!GInKgM|Iy!0(@TAz+5gxIIY9nq)&VHOQ1`7#U>40kY4B7ThwZikpa|V zrrLDrs;x4ph=%Q=)eFAF(Yixfu_Bp(mxotoq`!Z^I;sGG;Oysrsw(InIMz3o8Pp0i zxWSRb!&#UZ0Gl1L-XZKao#PWh9f$p(_g@Rr^18~?gNpXbb0nJ1;w{+vrG=E@(m^6- zR>jRl%BQiT*aInsd=`*5GW6q#{P=jj>&-AOh7}T01R2|FAoPsJej}l_H&@xy*JqX( zHTGF;E}4O0^=x!>IG)4tct9j(ZEX$FF!NQCc)u$kA7vIVT0i6#78c5JKP;~@jZL=l ziK{1z8~BcFNlOm{XuhJV^qku*F~bGS-yq;8DJe<J=S56Jj6nl#pqQwts_OIonVH@* zFNNO~;0jMq03Qfn%UF1xE|b$WG7<pxMP`LDE)R1#yM#oeMTTc1WcXl}?W?DaH5y0` zlP#Ch-`!e8SI~5>`Of>L#Tlqd$JgWVUt^7yBG`WhKA8~8;LuVWJ_g30lJv@`%4eSi z<j0fP(N{^#OdlRjcO3BXA;9_MTMqgAGvOKGh-_$#jGQ#s2oHx>Ful>r`}u-!oaNhd z==CSlToO+h=;ENm=JK2-vlKgeRcJ`1numRDYfYVj0YXDZr`6ni-7~1wuAR;ay#*VE zbnQ11@Z=;Up=%$RuFv(v^Z}1kf~CwcXt}qqk90@b274&v4*6R|c)03s{k}+{2q^W* zTQZhx%$bvye+_idm-(W9y)x6sw%vF>0E^FRLB^Qs{nMvxAXA(wpMo-r)A<~j>bwAE zQO-y2K9E<J=7Er70R@E#NePR;(KHRZdKde%xcG!IKtBhJO?i1Uyx@5yG!_g)@2`Wv zgv8baBjOukD}Mx(dv75jzAv&1r6wCa6Bfr-Rz2N4am`peUt}a@2S-OYbJCWU=sUtE zKHK1{%={i2a=*NO&ceiDHM!BY!#XgM5)%~@;Ol$3m66N-ZILd6$Yi`ECfs--P(e&g z42C@TD`@0IB_+j$DM?B`6U|PnPXtuMeE)6<ZdzOutuFP({QT`jz*G+*Z0hUnbvUW2 z%l1icwLJquDW>-VA?M1sNj0xF<OF$T7+JYB_=Ws7ek_BGoXm}Z2CHXz&!98r%BCV! z%ailHz`(%kYXo{cF_GUX#lgY93wD@raOAImhTz_mP{VER*U<zjzEV@MQiBtq?(4E2 zF1Ph46xV~J_V&J~r8Uy3@;yrx5*EtO%iG%Cymeg{{jJXHRX5)z67%QJ-!>zrkg0MU z2S=&M%M+XrV<7d!Ei(4-!W+2`4na{-d3$TSyQ^z#VqyUa85sqop73VzwD#odiyMc& zi{*Km9qruo%nI!_BpNX>dORBP4;M>+YeE-8XA@r^B(cLZcek%EU!4@zIwvM2f_7KS zv|o#6Mo3jtTB%XwRA)zC-ZE4C#%l?gktI&2!DJ30Hn&>`VdL$yMa_kkj)-u=6V(^{ z<3+zLaA?xcQXPBm^#REu97SL{0O#k6E57*#e8&rO>F$WZ1XlLLa3`mJHs_@uRnhDI z8g5`=_YL&ruwUZ2KG{&PnEg06+w1ltrTEvcLETG01Z3>cnV+p)ULFOGz_-B!J>C7! zpEt;<%A1?%nQ@ILiVtn{pC#^W31ysp+}^RL=2(_@;Byp1y(lNgfrCro5W+Q~2ZSp* z5t;IwKv7;-H4sea-Sa)I+9Kupri7f5lH;e&uaw^zo`31No9eFXB-k!~{rc4<^IF9N z5d!;JYt9Y4S193;;Z&5g!ouRupCbha`Ngrja}~IN)?F;UPX5j|q<Q%EE=wfld}J6S zV@SQ;$#uO~16)dt(~5wSW81Y@!t@zZxe8Fc&EGY_LA;6a%qH2TewGL74PfgB=-ikX zm=-_1^_o^x)zFDf4@hZfm}eanU3jz|<<{uA7uo`Ftg&jaUkS3PW=j}I7;w%h4H%Hg zBY3K-{Xflp^+Qx`)a{@GA|Oh4N=tY9f^?&FD)j<Gx8nekN-8A{GAP~BlF}eU4?{O1 zJ%BXaNAG>_cmIUTZyXMDVxDvM-fOMBw&?|iHBJ|re<OKSgbym$&VM2Mm@fR?8con* zeX@-nD9`=+b^LvM2!otzL%@zCq=1X_cx=>WEw;KACx|>Ke-rt}`Nusb&Fo!|wv7i6 zFz4h1DR;ftJJ)Pa<V*Gtf|T$CNusEzSgC32?g{*2+Pl-|!`9qDKu75N;o)z=^4TG{ zA1_Z=*mvDP-!xX>jX4TX{43paO+I+MvkK2`ipIvHz|d*P_B?=chv;arjiO#PG+y0g z6}wtJ5d|Io(}Ug&1bB@Hs_boHB4U>M-WSXHSLeqpH0C!YyRBp-pUUsY<o-)4g8HuD zCIC=Kz0rk*?54)B&#bMHG@{PTwz<2rOJyJqNO!*`h{*-<;59JQ3S7FJhr@6QD4%$E zdwYwOT52N-KwU@>h6sLqKJ3qRJWi=nAAN3LC;!+*(?clk}gr+$`Y&sQ^$@Sk(KC z^z`(AhcHr$z2^G#kZ4y4fK$U9j@<;l0+BCORCvwm_W|#D=D7jt=8~Ko6|QN`6vk85 zWgUHUXRCizenmb@EKWBCV=(&?u$)k(G%|L=F}c4PrjQmb^<Op26+#j}CL~xkcuauV zx;4&QqM!tg{}&21TNv(jC)HB~JJ{2J)(8LV2_rHGQW4m1XqPO!7CHyYGUFS_4G_>p z>5}$I!hSz4e(emuN-8$Iy1Z1G3_d#qJqi8is_NS8U9t2s^7n?R2;w9>U&G@pzIkm9 zrna6iOu4>rP#xLac|~}}6fso+L`&N-8$%AH#}YoVjr3bYX&+M0MmkEik^oTMiUFey z`7B#jwE~aNMH(dgdiy6QQJ$+f*tm7(gg@Ph7(7-dCs4T9xYhX;*ZybCNFhNX)i(eU zq&1ei!QjW_uCA>KRaH%mMMbJd$Hb`eP#7A<nyd<{@Rrh&0b^kO=lZGuJ|IT^-tTN2 z0(ZDCPOi$bTsu=%ag-33#$%k=ZRzC#&xv=OzOJTu%!(^1J-t?yjg9Ta@s_>SzeYMb zz5SZ%>elA423PJEFY1b&92?Tzb9dbEDR?h`HdNc=iTh$zc^=x>*r;?dBtKqiq2o^- zOiX+}=>u1=zQMZcBYb<21brbGXwsOdq&q1pN^5-SvbEa!{m0JDUIsZ^g0QNRLGs3p zI)1_*zvCt3Ly!$rxCn1EL>kozg@@Ys`H92M*4N3abrHRaDJ#_ay1J^4rDiP|8<pET zJF0JH>N=*zLP8XbvO^t6$rvblvbayJ`L$Q=diJh6Yy>kizKnA8|NHh~PwBV)D;Q{< zYp2Uz2r$(wYZQ*em{bI@7#bU=D(S9T{{~=kn5$4i-|O@b?N%!95pr+ey+BS^+Y@aa zFP)y6oL)C)WJs%8Ho4H95SE4Y5!}CzuJY!FEt?S$wP!XhefcuWPz>ND0PIR!U5t#( z)&Q?;WVY1C$_mRMxPtY_y37wJzjtP_%Pd=muAMwE)_NAvxmuaBU0F4@TcTAA4x3s2 zXJ^~S;UT6l$9yfgPFSB!EQ4H@&A~-QJN(3k$#uXonb%r-Hqfdy2<Z)M2gJbwJ;`j| zhkr<Gq%J)DHNhRA{B)b&E}}*LD<5?=i(EiJz_#&(NDY9-9;p{+PlAPv_T=U+Hu|R- z2-{=7f6n_tPC?-*rr_p#?&)P<Zf5S_{6Tq_{u&e;B*et%XBlA5`WlG#QR)Lz>W*KJ zufUMAuF7ofH~{4RT5j;%HokS9P@?S$^VzS53#Muie<95;0D3R?4JAdzgOUl0U~8(( zDo^U}?H2OwkJJHjWMoNs{9CWc7#J4bSciqpu}vT|&eB<;$lB#RPAmAEez^^n<&|VG zF{vU7B&u7N%94(GP4)C5pWB2@<9SelPe0l~HgKPx)3espy3DX?T;NT5+m&<~?V1^E zuuF->$y|+D`$(@m6?I1WyIU~4?unsM_CWX_3!kP+IFZNXK6=EO-XJLtbSqc^MpdED zQ+Jn{HO^Qfh!QXtCpSao(P$1K9ED&+Lfc;L5M4Dl2S?rk9u`Yz%PnbZAAmb{psQC( zN>sKTdMiF9uxopGcvMwaKhrb#^7ANFXl|k9$Kw2qwtDhg-Nd4_>G8tYG4n4?K<Zat zUm;5cpl=s@du2p{teP4L`?QpVgoL=pxETL~{GVeP8K65*eXA&C4&8d493THhH_;23 z1)i8^`I3@ase+D!l#xS}b}v0fZ$g7&wL#Y{<%Faf<L~di)CqlNbuM&$g8a0DaMWqR z#mR0=T{X$yqujqwl9`dgruB7C&MN3za7UcnYgb3fU?orog&-!=QLgJl2R{L;Ab}8A zUw_7??c<T=Xm2kzIAtU+AFrgVHTI>_aMNfI3>9Q!XKg^Hj1>F2s&aCIP|*VhG-;-< zi`zz)mhLPvDUmAX>yB614*2aR%!H&E*>5=Hg+)ffLBkp7Yy#&%OG|sc^|QCP*DVo9 z{Xs>hn~^)l;W++tWc7IDSH7YJ`G&(7Jv+PSb5%7B;W|q7YmRO<w%BK1#3dxa<vbhH z@y%L)YVma_5=}-*nifl|ir{dMbaA#8g1_2oh4g`*g-6CA5tQiZX>h;Xy)s^kI+Egr z+!qo!`;Ic~MG^i*x<WUHt8Tnr4Z6%<p3T-6y<nj+rKfm$6Eqo%2JrF{^7#|r#xbd4 zFgY%_CT7#`W5VGG22h2<vX)o^se`AdewcO@dA%yILS?qVI@|fB9UyF{+%0sULDp;- z9U$0V8LfquAhh<e#DBr-L@UrFux>5sQ*s`zRHYE>4$AX)Uu*f8LTB|OtbIzNHa;js z_!(SYM=<zV4ENd&kGOLoP0B4=*=p<t-6$}mDNqzuY`Mi-?=4iqtZAJ~Wq#nxK`l*% zO#9LpFnfN^!%OS#WNCk$3`3N$FK+CfRSKPqFIMkcQGv);SL>zxYnmF-eKKJiZ@<<4 zz8I|!hwV3&diHD=6%{);Tl$KKis1P(1E2&yKtPI_M+UxGWg8ws2&^bOIn{J^N4h7I zSH@%`K!?XvY@IEGSdV*VTtnajG%;0N5kxBL`=Xb}sD*hu8-DaIzWIY{Yr)jLsK`Lm z=I*w(ASR|hD;3ajU;iWJAuX-E2e$8PoL|32PYDo1KL%LrD`7~NC7Qvdz65sgG;v5a zgL%v>O3_n5#YKfzhCnDFIKW#cfGi|9WCP|8lt18rqg2t?x6ifRy=I&3Pr#T%2{j*a zJ7r<9x)RH}vYVjm(NUQ$4mFd;{H&I&sN&+dxHx`oX}5y1LQvla&4uErsr4_DX6BB8 zpxA0&!FV_)m9@68wpwD`RC^PIwM@#&$0yhQdQjBWHFlmPB3(>@jxL{zg9GFm!NIuz zbf@xRKmD!*v-asM1VMdgr>~*n#(qLfI6Q35qS~hvl)&NPI3Y|Rcu-OiT72^p@ZG1t z3kM|K_*wGx5s5FeQ?3|~H{tHA`-;g%9_;*i!CL6uN$9IeBKpQA<SMU~TzddxIhDP! zQ188lR}Uc>(%zBK$L6&qt}`!{Zh<+tsnEf6IqgDihFCLTE-qy{GdxpAla?kQ>@t`p zqTXwF*BT8F{C6um+r;q+Sc?w*B>H8lx3S+_sXU*2-umjev8qbV#H47<<lQj4)a(5m zW|SNS6VqAy^CS>p8RksQ%r3#STL#(JAk7_!?B^2fqEz?!jqB;Bc;gud6_?a<wnWVA zEqxcS60rHHlZ6fL!PWKYZ3um*?BWoe%qvo)3CP=R5MN7J1`1;6Wx}OC)C`-d;>A%R zq%<@&W9%E_bD7bU$4i4hLp^3-V83X<&{l3PhaHLq2gfHQU_1_;wzkCW-VgQl(Thf( z;LmezWC1QnLp{Gde?ayhVmXl-Z<`5uef^~O@2vv5FqlIuMxGrsnClnjfP<@w_wHeL zw>utQ`GQ?EjeWywv_})(?;R6PVy5v-hk{};OlrV=h!^gC=pLy<czF1Wx{f=f{4^q5 z>#}k0egj>n#JVk;-_ZJF&}}@!z{A3ant{z2>^YnIuix|2gfPnR#8@U*#m6r;c7XP% z=;*hLDvx=}{nAtME?uu60AtGi-ubSBcDWO*YOO3%9mZX(I3&?yFggIZ5YK=0ujcPL z=fJ~(_r)`OeEiTS_*)AXmuVdo-Dn%NACbb}?$U8bYS$}Zk2heiJI>%v5J*FT+BaPa zAo+GqPS#FNEES(sI4G+XEO}t2GyWFRY?}7Q)po~GhUHRM^`MIU^ohy0u_|5={S%SX z#$wn|TKC<_ImZ``20B$1_$J`@?8+wm#T&;SXHFS6`-(+E#qm&zfv1eg(5aXWcO)d} z-S6L^e7oHS8h@n3>`)DGhl_W=DR|9`N($*k`k`z6NeTJl{ryMVZZo~pjF%pD{;=xx zMB9_i?1*8*K5zkq-rg_Nii!*G^_Bvu#>&z|zvH4HL9(^A?ben7$L95)TU&TzLE0b2 zYA;i7WkXn<^mb;==ndsTD9oxc!e1Qs{&}PRPgai$XXJSz9HWr$*As0Nu{Bp*m(xA& z$=ggpK_T~jZpU1!EGQ)TAoA#8rpGQCz1Q2F^AAo(BGT_7eD(|=*IUc$Z1ryLs>;h1 zq2=Y}VA`po_i;$QpP{d>ZcuwTjvYb?NLPK9pW;R@009^U@G5<>rB*XJX<5&C7w+)) z9-qxOgV1}AqXGzDkq@iEIZz<I3~nmywH>e;W;2T$!*O~FpFPvVCVac{Q>)tRrM*aT zX_QMFH*?>PxoIFYr;HbQtAusK(-ZrcMk>eiVia_(Hr^oRB+kw@`7DP_E1uZ22fvY& z1UTvXx;4PeHl3Rk3#1TZRJT0l%*+8+h!w=f<p^AEpwN=SLQb@(UR<YgT3R}~IMMK{ zg=gMpKeJ&;Lw#FT^aF~Gt35WJIcg<7zVgK(ASS!gAlwoJ*nKem*Dc!r%Msjx=(DoI zU@&tTb8LVA@X)-sZ|^$!FRT;YEN7N|+o@$;Jzev-7I^9cv^8`Nz<HgLn)-_@ywUb> z9k^^fM@`f~9_8n;<>%2KACi#l9PHHLf2-ST>jlywcq72A>s;r7-aeG&3W#?A)r|G0 zAQ$R6#Q#e0Y4;9bKD-4-=w)Q}ax&>u#0*i1<IfE&P4pEN<@JImeAm#KyZe=QzzZ8E zh@P2Q=BeB$>=75YNfY|=+`0t2gPY6GtGX!;JT#n~g)?=oz$XkDkMUr8avnvo$!Bqz zE$!dC;Wm6s6B#LuqlKw<{~n&Z{BqX|<Ld>|8Ubq@UtalaZKwtT-qhw1>ON7Nj=}k2 z-@&xxkn6*{sab+Hh^iutXPu5(qsZf_;kG7$q@+^RgH&zG+ZVPXA|l@C%39|+wOc-N zJjPY_CoX_JsMU?hPLI}@F)gT4OTm=Xz3EC30M6st#l{dwPD!5EYVSja?C&6%cy-GE zJ3s?!<M-6TR?%Ah@P*|<uha+N1o<^?ZVRwGc*)t>Vja-D-5@Mr@+)~8cXD#_n}53d z%5+VSGYi>$hTk9J<4M1fgtoi_OS53kME3CKZJ#`;QbzWV@87qLe8d6Mh>-v2$yZf< zX-w^dy1ckYQk$^LNhkq<BqizJ!(e8yi;7Gx9Asd%i1e$5h=6^-vaank|CoW9s)0Vw z!K;)hT;JWN>tv)rqfbO9D$K<62G$`P&>g*WFv}ZNmX)>G{^_oFqp9=Z;`UTa$OZG^ z`Gk5_jqtdsy%FsE2)*G%^Qmb1+-mP4I2iQqds3(bUS~iH3XZO3V>T%xiP>p@S(G$> zVn9cA#ts?vD-wv!=g+>L*xQiB<C!}1F@i}_LhWbILOIK)4P+5l2{PW%1qHotAAVPk zrqr^dyGPhuWA(=H`r^a^Y1#QyInFs<o17_hIA103%;Prdxx29L2=L#=WN;9Ex=9PX zy3KOeTT=G{*7a>kNKQpX&H%MS;}}9Y)&1o2n?O+P=%D`H$<3GcXV&nqX(?UH&d)!5 z{0H5s`h;1EBu}gthm0Tk2Oq<AKkzHxXaETd1+STxAR{BU5cl~IoudC)M=rCgh0rk5 zk?V)-kIJGr`zGaVj~<2EmkO+xl3ZGnh~v{s=^B(|J1J?kYiKIJk6F!ol!Yy?pwQQ? zQvG3P+VkUw1gEQc=5!QCZD(g*cXHW<Xl~A;4CG$`TV3w5igOe=rM<8bHj3B64YJ=v zf=PuS7j3q+_44+DFbYXsOcWbtH^a@?G%BQC9dV!oxZG<07*cgm@;}+QOcnCn7^E65 z&lZniyT{y|2aBb4XbjkyE-86jeippWs{FI{Hh3J}nYjsU?CcJ>-Lg>_?QFbFEp>iB zq+%C{ClW@rr7+lWnvS{G*oV?B%K3XuUDZ!|f7H6v7IMNGGrrM65|fiegfV_bkJ-K? zSib&H+Y^z>vlGP<Ei6<`Z;uBp_GCPA?KF9jOr~Vd$;$~;G<--C@EwiN6x@cO{r#2W zXdkXWDKXwC3Wbr!+hS~#E9r$Hev~KgrNr3z<k}Xpp;A&(bxufgrG*^t)UXOu>9U9> zpS@rG-TahZ5Wlnd9z)r`=v;9(8Y`$LLjuxv=kyq58OFIM5=f6WYH*yehmr@TnV8sw zpu+?V0Dok1{D3S~)Oi{Jk|4I~8|qJ>Cdga(zR`I50s}Vb?2&(dw&MM{G1St2{18%d zvd^CnC>hDAUvXy^+h3f$-}TaT=J8Dq+CAE6qt0vrkpaqN5R)R?TywY`*df;%<Z1I# zPY+W%^8&)Cg^<ul8_ZIid;rB-v^bFgiY^@snR)H@NS5*1z)a<;6l-e=t*2o+`7{!_ z-lQ{)$6LRqvSwdfK40Y@Y55v_axMy4+-c4PIpFmn;?ys87O+k4-=}YLnwVVmb|XTS zcN{;JXdw4MhX5p4!PORCujHd@eD<|4*2YJaU0HeZR@I!QB^ep<vWAM5Ec{#;mJ9%h zkL6~Y{oO!@aXTpTm*d{f40;UAFCphKnN8v`27c}~1#=TyD1bY%Aom=yWG-&LqoP_b z{&{9j2ywZCi#)+Bi%ErMms>`FM(xCJz!Ey(r2f0Ctc`+tdXLcbUs+)0{f%mcw_|y# z_knl<QUN`yT3meayJ3cyBmo#WG*$_)C`XHXo$iO!*MlJ1STD|f1=k%}RZY0#l`oZ9 zS$Qzd`K-*M6+p03^ONi6HCwbK>b7>aNu(buCId$4#NQ{D7nXZ^q)~eu8kE;=E&<sl z04i7z(*dW~xM-sM7+<#(Kg^K><n*{s-<s#K(ZHdtjh&XKhvR~gIMY%5CZ}q?A!=gH z9h)4Bu{FmE*nmV)@Qf}UPch;#P!b94ZYwd3dw<dL+`ZT;2P+i_2x^3dDR@o9a{_Mw z7XcXR3DI$6mdMu8Lf~PEI3O)iN!-5M(-XHe><vF+TPy&$I_EfNjcm22N9NwW#!rQX z0`9po#otCAut*rAm#eBSDl0AU$u+X1Q;G8-ZR3L_sGiB#soEbGS~jaI<Imyd%?*d^ zv6Qmkl!->zwe@Z;50StU4x*#0hdGv-^e<Q2Fuj`jh0e-?@CUXBA02rin3Skog@Co) zN6a>QY6Jnk)A^5yUYfv@#oR|qkQgEgo%UiE^cY=L?eFj3!@n1IdIq9eLsJ77M&IIO zl3P^bwLWN^@1Vs4Y3Yf@#=&W9YN7$~e0)4FFPECCCSjwy^|zYi%9S2fe|G^B9i9E3 zx`=^dF72yhR8kvvSs5>w6S~F24pbb5I!61es%lfErog!tpMq!GD1obgpw=1C%@;l^ zObSXd^guSl%{^1xSj2TW*Q8Fto7egp4>C#|zwUe+2?8Qhs4RChnyJ%aUYgH!Z-;el z?V;~30iC08;Joxiiz91S7YJ6^7I>tHcbaM90tLnNYPR0_#_-MVFWt&<#9Eosto7g> zcAC8(=qP!)wk5`A*-B+&wYa)!<Lb)C#f$->J<znAGBpLj^r~{y?$#E_EI+1a-*5=1 z=C}U7JhKSFrLnQIaXFl~SQx(xQNqD7t#w%wk6cMC1gsD^-7{gHxwa=aGp-bXRZ>(` zyt+ay{NVY)J2XVWXSq9jNbPFxyEa|(wxA#=2%^{}Yg0Lgb^9EU5-1evf>vVLbM@`~ zlgvtM9s-=rljMZr@?vD)k7fWVAUYrEJ}|C)skl+QF*ZkVFY;Z~ik2mC1HCBcHY{1K zE8;ufdq9COZ+_)`={FOP!2nXz8ERc_mXQgEU)?dYsfEs$<mMd>^d|u)fb?27Ek+)$ z^Y)H3W=NCIPR7lSJVf08{HU*X$!_V>Cvt}LAxpDpax!n<RgP*P2tTElT8C|i>}MRj zXEH3a*x}(mJgC0%0L;}x3WmU+`!Cqq%9?K&n4KM50uDxPSrF~!lf*LzwWgxZf4dr= zDk>-J6#yaF(_5F?<0vsN<H7q7fItB!0obHiHE09DkBYocE7_?Vv;s>5>91;EpQp5) za!)6yQW=Quiqk)6(^UkV(h4E5!&NdblY|75M5>gfrv4h{^Aoe4zms>(|3<I)<Yds& z7a#IHZ#w+^>jqzd@$rqn56CN!nNk$+n}Cm9+bX`V22%uR;SLXSrRFw)T#`Zd?P1Ew zLsH_=TW)9lWU<PPPZecT#>~om%Rve>_C=CSHo(llxWV^kZ@Ym6>Ws{k<Kyl2CnF{! zYj9i21=*CYLtj&d*=Xe*h&wgU;_18d^Kh*=G#H$;WT(=b9vzJxMP5maDzRvGzj|eG z!?SZ1^>rfy`Sh7^B@hFHeA>qaCOcQNg^J6T?8<DhM&XXx0XIkhPXWWpk;Q!ED3}P~ zyK-KGa-F}G-~g50u3Ipuj*DNhKk!{>7;>{b8$g0`d4RhgEV>I0uKS{bRn;}#p4ol6 zQ{Sy)lMPxCEiFV0(!E1{&PxQncbQpPsr)uaMP2s-|4xZ8F)<+}T~&@1_Vo77oHx&} zT&Zx~n?I;sfy3dzutY&O@xzD}Fhk?3;+QWlHZV>}-;?v>Kc8=2jwi+m`BYX``)Z<G zXx1LbEv!ve%+vD_^lfHI`eT%Ih7qTy%ggcW$#%w6R5Eb*fcr|o=`Ji5;|SLWegX&t z0%=*luYCl-o+|F*;;w&%6|u3wQ319uEh8f}ONoykl@}Tc>^TG~iS)9+*xA}mOrl1f z!Z^6N2&e?d-HTRAj2GM%YJt25ydWsp<Spr_6-PK6%OWBcUjl(-US4afobPT^Mn-lr z@5IQ+3;suWd3gi`1V9jKd3r6A&^KG*KvGBvnD-O+2@&BtVo+r4&MgmrgVxsvxo_TJ zDagmS1L|$qEnR>`Ts*Wn88BhWWI(VVkk3}1%Ma}7DEKT&<Wwx><@Es2v}E-idm#YE z!ch>W4gA`88|oX23X4amq5-~3@3|ftHb?&YZG07`W^0m)l3GngjjOl-06N<szG|?I z0jh1mQWJ1dHV3nxf+7L7?5xxc+|R%%cXC9Mf~gQB+yf|-Z*2YskmCa<Fdi)c+bS3v zqvz+dRtWbw#qXcLBj+`G;w1GDOO7fvHPb`<KVg2RR%qY$(dMVWcj|dwZYKnSCG<xN z@OJ~4+!3+$pX=kFE#u8r|8JAZr`<m)wg26(^5+x1`9Rh2Kff2i+W)6l1pIvt|F72X zzx{t%00!d!90&Z9&PniphJAlGHd25W`+w*8|M#J9Zj+o=_d$1FD?-4Js-o7@GI^`u F{{@Sj<Qf0~ literal 0 HcmV?d00001 diff --git a/docs/source/changelog/index.rst b/docs/source/changelog/index.rst index 378c73b3..f16d7a6e 100644 --- a/docs/source/changelog/index.rst +++ b/docs/source/changelog/index.rst @@ -11,33 +11,37 @@ edge case bug fixes, speedups, and small new features might bump up the last digit of the version number. For example, the difference between 0.2.1 and 0.2.0 represents this kind of small change. -Version 0.1.0 + +Version 0.3.2 ------------- -This was the initial release. The output count matrix was constructed via -imputation, so that there were no explicit guarantees that CellBender would -only subtract counts and never add. +Small improvements aimed at reducing memory footprint, along with bug fixes. -This version has been deprecated, and we do not recommend using it any longer. +Improvements: -- Imputes the "denoised" count matrix using a variational autoencoder +- Make posterior generation more memory efficient -Version 0.2.0 -------------- +New features: -A significant overhaul of the model and the output generation procedure were -undertaken to explicitly guarantee that CellBender only subtracts counts and -never adds. The output is not constructed by imputation or smoothing, and -CellBender intentionally tries to modify the raw data as little as possible in -order to achieve denoising. A nominal false positive rate is approximately -controlled at the level of the entire dataset, to prevent removal of too much -signal. +- WDL workflow updates to facilitate automatic retries on failure +- Added to list of allowed feature types to match 2024.04 CellRanger definitions -- Uses a variational autoencoder as a prior +Bug fixes: -- Computes the "denoised" count matrix using a MAP estimate and posterior regularization +- Fix bug with MTX inputs for WDL +- Fix Windows bug during posterior generation +- Fix report generation bugs on Mac and Windows + + +(Version 0.3.1 -- redacted) +--------------------------- + +WARNING: redacted + +If you managed to obtain a copy of v0.3.1 before it was redacted, do not use it. An integer +overflow bug caused outputs to be incorrect in nearly all cases. For more information, see +`github issue 347 here <https://github.com/broadinstitute/CellBender/pull/347>`_. - - CellBender never adds counts Version 0.3.0 ------------- @@ -84,6 +88,37 @@ a workflow using Google Colab on a GPU for free. hundreds of samples in automated pipelines. This file can be parsed to look for indications that a sample may need to be re-run. + +Version 0.2.0 +------------- + +A significant overhaul of the model and the output generation procedure were +undertaken to explicitly guarantee that CellBender only subtracts counts and +never adds. The output is not constructed by imputation or smoothing, and +CellBender intentionally tries to modify the raw data as little as possible in +order to achieve denoising. A nominal false positive rate is approximately +controlled at the level of the entire dataset, to prevent removal of too much +signal. + +- Uses a variational autoencoder as a prior + +- Computes the "denoised" count matrix using a MAP estimate and posterior regularization + + - CellBender never adds counts + + +Version 0.1.0 +------------- + +This was the initial release. The output count matrix was constructed via +imputation, so that there were no explicit guarantees that CellBender would +only subtract counts and never add. + +This version has been deprecated, and we do not recommend using it any longer. + +- Imputes the "denoised" count matrix using a variational autoencoder + + Human-mouse mixture benchmark ----------------------------- @@ -137,3 +172,14 @@ v0.3.0 .. image:: /_static/remove_background/v0.3.0_hgmm.png :width: 750 px + +This represents a real improvement over the results published in the paper. + +v0.3.2 +~~~~~~ + +.. image:: /_static/remove_background/v0.3.2_hgmm.png + :width: 750 px + +This appears identical to v0.3.0, as the changes were intended to fix bugs and +reduce memory footprint. diff --git a/docs/source/reference/index.rst b/docs/source/reference/index.rst index ead0ce72..2f476294 100644 --- a/docs/source/reference/index.rst +++ b/docs/source/reference/index.rst @@ -185,4 +185,5 @@ The information contained in the posterior can be used to quantitatively answer questions such as "What is the probability that the number of viral gene counts in this cell is nonzero?" For help with these kinds of computations, please open a -`github issue <https://github.com/broadinstitute/CellBender/issues>`_. +`github issue <https://github.com/broadinstitute/CellBender/issues>`_, or see +the `semi-worked example on the github issue here <https://github.com/broadinstitute/CellBender/issues/299>`_. From 1198d8f0b6b56bfa82707cc3a593e7ee28e7034f Mon Sep 17 00:00:00 2001 From: Stephen Fleming <sjfleming@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:58:37 -0400 Subject: [PATCH 18/19] Update wdl for benchmarking compatibility --- wdl/cellbender_remove_background.wdl | 1 + 1 file changed, 1 insertion(+) diff --git a/wdl/cellbender_remove_background.wdl b/wdl/cellbender_remove_background.wdl index f7507ec3..d3a964b9 100644 --- a/wdl/cellbender_remove_background.wdl +++ b/wdl/cellbender_remove_background.wdl @@ -90,6 +90,7 @@ task run_cellbender_remove_background_gpu { git clone -q https://github.com/broadinstitute/CellBender.git /cromwell_root/CellBender cd /cromwell_root/CellBender git checkout -q ~{dev_git_hash__} + yes | pip install -U pip setuptools yes | pip install --no-cache-dir -U -e /cromwell_root/CellBender pip list cd /cromwell_root From d7d228b491858054fac7e4780f575bc366bc9165 Mon Sep 17 00:00:00 2001 From: Stephen Fleming <sjfleming@users.noreply.github.com> Date: Mon, 24 Jun 2024 13:00:20 -0400 Subject: [PATCH 19/19] Bump version to v0.3.2 --- cellbender/VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cellbender/VERSION.txt b/cellbender/VERSION.txt index 6833eaa5..9fc80f93 100644 --- a/cellbender/VERSION.txt +++ b/cellbender/VERSION.txt @@ -1 +1 @@ -0.3.1.dev0 \ No newline at end of file +0.3.2 \ No newline at end of file