{ "cells": [ { "cell_type": "markdown", "id": "a6b9d9f4", "metadata": {}, "source": [ "## Model Developer Workflow Example\n", "\n", "### Using czbenchmarks to evaluate an in-development model on a single task\n", "\n", "This notebook demonstrates how to leverage the czbenchmarks library to generate benchmark metrics for a previously published model (using existing model weights) and integrate czbenchmarks into the developer workflow for iterative evaluation of model performance during parameter tuning.\n", "\n", "We focus on the `Cell Clustering` task as an example, but the same approach can be applied to other tasks supported by `czbenchmarks`. For a comprehensive overview of all tasks, refer to the `scvi_all_task_sbenchmark.ipynb` notebook.\n", "\n", "In this example, we use scVI, a popular tool for single-cell analysis, to compare the performance of published model weights against variations obtained through iterative re-training. \n", "\n", "> **NOTE**: This workflow can also be adapted for the development and evaluation of entirely new models.\n", "\n", "### Key Highlights:\n", "- **Benchmark Metrics**: Evaluate clustering performance using Adjusted Rand Index (ARI) and Normalized Mutual Information (NMI).\n", "- **Iterative Development**: Demonstrate how to fine-tune model parameters and assess performance improvements.\n", "- **Generalization**: Showcase how the workflow can be extended to other tasks and models.\n", "\n", "### Step 1: Setup and Imports\n", "\n", "To begin, ensure your environment is properly configured. This includes setting up a virtual environment, installing required dependencies, and registering the environment as a Jupyter kernel. Below is the setup process:\n", "\n", "#### Virtual Environment Setup (Optional)\n", "If you need to create a new virtual environment, uncomment and run the commands in cell below\n" ] }, { "cell_type": "code", "execution_count": 1, "id": "0b596f76", "metadata": { "vscode": { "languageId": "shellscript" } }, "outputs": [], "source": [ "# # Create isolated virtual environment for scVI and czbenchmarks (run once)\n", "\n", "# !python3 -m venv .venv_scvi\n", "\n", "# # Install model required packages\n", "# !.venv_scvi/bin/python -m pip install --upgrade pip\n", "# !.venv_scvi/bin/python -m pip install ipykernel numpy pandas scvi-tools matplotlib seaborn\n", "\n", "# # Register the new environment as a Jupyter kernel (if not already registered)\n", "# !.venv_scvi/bin/python -m ipykernel install --user --name venv_scvi --display-name \"Python (.venv_scvi)\"\n", "\n", "# print(\"Virtual environment '.venv_scvi' created, dependencies installed, and kernel registered.\")\n" ] }, { "cell_type": "markdown", "id": "5d093bce", "metadata": {}, "source": [ "#### Import Libraries\n", "\n", "This notebook requires the following libraries:\n", "\n", "- **czbenchmarks**: For dataset loading and task evaluation.\n", "- **scVI**: For model inference and fine-tuning.\n", "- **Visualization tools**: For plotting benchmark results (matplotlib, seaborn, pandas)." ] }, { "cell_type": "code", "execution_count": 2, "id": "1f6678a2", "metadata": {}, "outputs": [], "source": [ "from czbenchmarks.datasets import load_dataset\n", "from czbenchmarks.datasets.single_cell_labeled import SingleCellLabeledDataset\n", "from czbenchmarks.tasks import ClusteringTask\n", "from czbenchmarks.tasks.clustering import ClusteringTaskInput\n", "\n", "import scvi\n", "import functools\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "import seaborn as sns\n", "import warnings\n", "\n", "warnings.simplefilter(\"ignore\")\n", "sns.set_theme(style=\"whitegrid\")" ] }, { "cell_type": "markdown", "id": "5f9bcfda", "metadata": {}, "source": [ "### Step 2: Load and Prepare the Dataset\n", "\n", "\n", "In this step, we load the pre-configured `tsv2_prostate` dataset, which is specifically designed for single-cell analysis tasks. The `czbenchmarks` library simplifies this process by automatically handling dataset download, caching, and loading as a `SingleCellLabeledDataset`.\n", "\n", "### Key Features:\n", "- **Gene Expression Data (`dataset.adata`)**: AnnData object with gene expression matrices and metadata.\n", "- **Cell Type Labels (`dataset.labels`)**: A pandas Series containing cell type annotations, which serve as ground truth for benchmarking tasks like clustering and label prediction.\n", "\n", "---\n", "\n", "> **NOTE**: Always verify that dataset is compatible with the model input requirements before running inference." ] }, { "cell_type": "code", "execution_count": 3, "id": "20bb6d6e", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO:czbenchmarks.file_utils:File already exists in cache: /Users/sgupta/.cz-benchmarks/datasets/homo_sapiens_10df7690-6d10-4029-a47e-0f071bb2df83_Prostate_v2_curated.h5ad\n", "INFO:czbenchmarks.datasets.single_cell:Loading dataset from /Users/sgupta/.cz-benchmarks/datasets/homo_sapiens_10df7690-6d10-4029-a47e-0f071bb2df83_Prostate_v2_curated.h5ad in memory mode.\n" ] }, { "data": { "text/plain": [ "TSP25_Prostate_NA_10X_1_1_AAACCCAAGTGGTTAA endothelial cell\n", "TSP25_Prostate_NA_10X_1_1_AAACCCACATGCACTA luminal cell of prostate epithelium\n", "TSP25_Prostate_NA_10X_1_1_AAACGAAGTTCTGACA endothelial cell\n", "TSP25_Prostate_NA_10X_1_1_AAACGCTTCTACCCAC erythrocyte\n", "TSP25_Prostate_NA_10X_1_1_AAAGAACCAGTTGTCA smooth muscle cell\n", " ... \n", "TSP25_Prostate_NA_10X_1_2_TTTATGCTCTTGGTCC fibroblast\n", "TSP25_Prostate_NA_10X_1_2_TTTCACAAGATCGGTG basal cell of prostate epithelium\n", "TSP25_Prostate_NA_10X_1_2_TTTCACAGTGCCTTCT fibroblast\n", "TSP25_Prostate_NA_10X_1_2_TTTCATGCAATAGTAG CD8-positive, alpha-beta T cell\n", "TSP25_Prostate_NA_10X_1_2_TTTCCTCAGGTGATCG fibroblast\n", "Name: cell_type, Length: 2044, dtype: category\n", "Categories (14, object): ['fibroblast', 'T cell', 'mast cell', 'endothelial cell', ..., 'neutrophil', 'mature NK T cell', 'luminal cell of prostate epithelium', 'basal cell of prostate epithelium']" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dataset: SingleCellLabeledDataset = load_dataset(\"tsv2_prostate\")\n", "dataset.adata\n", "dataset.labels" ] }, { "cell_type": "markdown", "id": "b4df4868", "metadata": {}, "source": [ "#### Optionally Transform Data\n", "\n", "After loading the dataset, you may need to transform the data to meet the requirements of your model." ] }, { "cell_type": "code", "execution_count": 4, "id": "6ab4ce47", "metadata": {}, "outputs": [], "source": [ "# Prepare the dataset for scVI model\n", "adata = dataset.adata.copy()\n", "required_obs_keys = [\"dataset_id\", \"assay\", \"suspension_type\", \"donor_id\"]\n", "adata.obs[\"batch\"] = functools.reduce(\n", " lambda a, b: a + b, [adata.obs[c].astype(str) for c in required_obs_keys]\n", ")" ] }, { "cell_type": "markdown", "id": "78a14fb9", "metadata": {}, "source": [ "### Step 3: Obtain Pre-trained Model, Run Model Inference, and Generate Output\n", "\n", "In this step, we leverage the pre-trained scVI model to generate cell embeddings for evaluation within the benchmarking framework. The pre-trained model weights serve as a reference point for comparison against fine-tuned or newly developed model variants.\n", "\n", "---\n", "\n", "> **NOTE**: For your own model, adapt the loading and inference steps to match your model's requirements. " ] }, { "cell_type": "markdown", "id": "7a5a184b", "metadata": {}, "source": [ "#### Load Pre-trained Model Weights" ] }, { "cell_type": "code", "execution_count": 5, "id": "28b579ad", "metadata": {}, "outputs": [], "source": [ "import os\n", "import boto3\n", "\n", "\n", "def download_scvi_weights(local_model_dir=\"czbenchmarks_scvi_model\"):\n", " if not os.path.exists(local_model_dir):\n", " os.makedirs(local_model_dir, exist_ok=True)\n", " if not os.listdir(local_model_dir):\n", " s3 = boto3.client(\"s3\")\n", " bucket_name = \"cz-benchmarks-data\"\n", " prefix = \"models/v1/scvi_2023_12_15/homo_sapiens/\"\n", " print(\"Downloading model weights from S3...\")\n", " paginator = s3.get_paginator(\"list_objects_v2\")\n", " for page in paginator.paginate(Bucket=bucket_name, Prefix=prefix):\n", " for obj in page.get(\"Contents\", []):\n", " key = obj[\"Key\"]\n", " if key.endswith(\"/\"):\n", " continue\n", " local_path = os.path.join(local_model_dir, os.path.relpath(key, prefix))\n", " os.makedirs(os.path.dirname(local_path), exist_ok=True)\n", " s3.download_file(bucket_name, key, local_path)\n", " print(f\"Downloaded model weights to {local_model_dir}\\n\")\n", " return local_model_dir\n", "\n", "\n", "model_weights_dir = download_scvi_weights()" ] }, { "cell_type": "markdown", "id": "a12a5b8d", "metadata": {}, "source": [ "#### Generate Embeddings with Pre-trained Model\n", "\n", "Extract cell embeddings (latent representations) from the model, which will be used for downstream benchmarking tasks." ] }, { "cell_type": "code", "execution_count": 6, "id": "1aed62da", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u001b[34mINFO \u001b[0m File czbenchmarks_scvi_model/model.pt already downloaded \n", "\u001b[34mINFO \u001b[0m Found \u001b[1;36m44.05\u001b[0m% reference vars in query data. \n", "\u001b[34mINFO \u001b[0m File czbenchmarks_scvi_model/model.pt already downloaded \n", "Generated scVI embedding with shape: (2044, 50)\n" ] } ], "source": [ "scvi.model.SCVI.prepare_query_anndata(adata, model_weights_dir)\n", "scvi_model = scvi.model.SCVI.load_query_data(adata, model_weights_dir)\n", "scvi_model.is_trained = True\n", "scvi_output_embedding = scvi_model.get_latent_representation()\n", "print(f\"Generated scVI embedding with shape: {scvi_output_embedding.shape}\")" ] }, { "cell_type": "markdown", "id": "33a034dc-a4f1-417b-bb5b-57cae6072a71", "metadata": {}, "source": [ "### Step 4: Clustering Task Evaluation\n", "\n", "Evaluate the quality of embeddings generated by pre-trained and fine-tuned scVI models using the `ClusteringTask` from `czbenchmarks`. Metrics include:\n", "\n", "- **Adjusted Rand Index (ARI)**: Measures similarity between predicted clusters and ground truth labels.\n", "- **Normalized Mutual Information (NMI)**: Quantifies mutual dependence between predicted clusters and ground truth labels.\n", "\n", "Higher ARI and NMI scores indicate better clustering performance." ] }, { "cell_type": "code", "execution_count": 7, "id": "5c838888", "metadata": {}, "outputs": [], "source": [ "# Utility function to run clustering task\n", "def run_clustering_benchmark(cell_representation, obs, labels):\n", " task = ClusteringTask()\n", " task_input = ClusteringTaskInput(obs=obs, input_labels=labels)\n", " results = task.run(cell_representation=cell_representation, task_input=task_input)\n", " return {r.metric_type: r.value for r in results}" ] }, { "cell_type": "markdown", "id": "fbad691c", "metadata": {}, "source": [ "#### Pre-trained Model Evaluation\n", "\n", "Benchmark the clustering performance of the embeddings generated by the pre-trained scVI model." ] }, { "cell_type": "code", "execution_count": 8, "id": "17a912db-2c31-480e-83c7-eebb2f2dd77e", "metadata": {}, "outputs": [], "source": [ "benchmark_results = {}\n", "\n", "# Pre-trained scVI\n", "benchmark_results[\"scvi_pretrained\"] = run_clustering_benchmark(\n", " scvi_output_embedding, dataset.adata.obs, dataset.labels\n", ")" ] }, { "cell_type": "markdown", "id": "be13cbf0", "metadata": {}, "source": [ "#### Baseline Comparison\n", "\n", "Compute clustering metrics for a baseline method (e.g., PCA) to establish a reference point for comparison." ] }, { "cell_type": "code", "execution_count": 9, "id": "6c39fb3b", "metadata": {}, "outputs": [], "source": [ "baseline_embedding = ClusteringTask().compute_baseline(dataset.adata.X)\n", "benchmark_results[\"pca_baseline\"] = run_clustering_benchmark(\n", " baseline_embedding, dataset.adata.obs, dataset.labels\n", ")" ] }, { "cell_type": "markdown", "id": "f8b0e3d6", "metadata": {}, "source": [ "#### Iterative Model Evaluation\n", "\n", "Extend the workflow to evaluate clustering performance for fine-tuned or newly developed model variants." ] }, { "cell_type": "code", "execution_count": 10, "id": "653e0095", "metadata": {}, "outputs": [], "source": [ "# Function to fine-tune the scVI model\n", "def fine_tune_scvi_model(adata, n_latent=10, max_epochs=10):\n", " model = scvi.model.SCVI(adata, n_latent=n_latent)\n", " model.train(\n", " max_epochs=max_epochs,\n", " plan_kwargs={\"lr\": 0.0005},\n", " early_stopping=True,\n", " early_stopping_patience=10,\n", " )\n", " return model" ] }, { "cell_type": "markdown", "id": "14e7bf27-d67b-4cd8-af3a-7095766827a9", "metadata": {}, "source": [ "**Demonstrating Iterative Model Evaluation and Hyperparameter Tuning with czbenchmarks**\n", "\n", "In this section, we demonstrate how `czbenchmarks` supports iterative model evaluation and hyperparameter tuning within a development workflow. By leveraging the `fine_tune_model` function, we simulate the process of updating model parameters—such as varying the latent dimension (`n_latent`)—and assess the impact on clustering performance.\n", "\n", "**Workflow Overview:**\n", "1. **Generate Model Variants:** Create multiple scVI model versions by adjusting key parameters (e.g., `n_latent`).\n", "2. **Fine-Tune Each Variant:** Train each model variant using the scVI training API with custom configurations.\n", "3. **Evaluate Performance:** Apply `czbenchmarks` to compute clustering metrics (ARI, NMI) for each variant, enabling direct comparison and informed parameter selection.\n" ] }, { "cell_type": "code", "execution_count": 11, "id": "76cda22c-0354-4120-ac6c-21c712d502e0", "metadata": { "scrolled": true }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "INFO: GPU available: True (mps), used: False\n", "INFO:lightning.pytorch.utilities.rank_zero:GPU available: True (mps), used: False\n", "INFO: TPU available: False, using: 0 TPU cores\n", "INFO:lightning.pytorch.utilities.rank_zero:TPU available: False, using: 0 TPU cores\n", "INFO: HPU available: False, using: 0 HPUs\n", "INFO:lightning.pytorch.utilities.rank_zero:HPU available: False, using: 0 HPUs\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "7e886df2a13a45e0be1cfe933448a23c", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Training: 0%| | 0/10 [00:00\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
scvi_pretrainedpca_baselinescvi_n_latent_3scvi_n_latent_5scvi_n_latent_10scvi_n_latent_25
MetricType.ADJUSTED_RAND_INDEX0.719370.6421490.5066750.5287590.5183800.507529
MetricType.NORMALIZED_MUTUAL_INFO0.866540.8331380.7342230.7557200.7321440.740127
\n", "" ], "text/plain": [ " scvi_pretrained pca_baseline \\\n", "MetricType.ADJUSTED_RAND_INDEX 0.71937 0.642149 \n", "MetricType.NORMALIZED_MUTUAL_INFO 0.86654 0.833138 \n", "\n", " scvi_n_latent_3 scvi_n_latent_5 \\\n", "MetricType.ADJUSTED_RAND_INDEX 0.506675 0.528759 \n", "MetricType.NORMALIZED_MUTUAL_INFO 0.734223 0.755720 \n", "\n", " scvi_n_latent_10 scvi_n_latent_25 \n", "MetricType.ADJUSTED_RAND_INDEX 0.518380 0.507529 \n", "MetricType.NORMALIZED_MUTUAL_INFO 0.732144 0.740127 " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Prepare and display results\n", "results_df = pd.DataFrame(benchmark_results)\n", "display(results_df)" ] }, { "cell_type": "markdown", "id": "7e36e4f2", "metadata": {}, "source": [ "#### Visualizing Benchmark Results Across Model Variants\n", "\n", "The bar plot below shows the Adjusted Rand Index (ARI) and Normalized Mutual Information (NMI) scores for each model variant (including the pre-trained scVI, fine-tuned variants, and PCA baseline). Higher scores indicate better clustering performance." ] }, { "cell_type": "code", "execution_count": 13, "id": "f421343f-a140-49b1-b228-6571d30a49fc", "metadata": {}, "outputs": [ { "data": { "image/png": "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tkXLqaFHjS/aZ/oNeMecyu8dX+F0fOq71G9vwIABVrhw4dBrOudqPdpO0fp1bGv9+p1rf6lh64477rCXXnrJTTAWNAWRogYPryFE5xn91v1lDadrXqRrms7f+l71nSmIVUOnGjZ0ntD+Cr+2pGTv3r3JJpnTMaRsMf029B34f7v6Peu8pOf0W9N5RcHsO++8434PKo/OyfrNqAFO37uOK5039VvUOrVuHcve70bfg36L+v71O9R26JjQ961hQjonplc010Y1QujaqGBa5yGlwatxVMe0JlHV8aAhKECelwQgV6tXr15SkyZN0v2+vn37JtWoUSNp9erV7u85c+a4v0eMGHHEsh06dHCveW677bak+vXrJx0+fDj03KFDh5I6deqU1K1bt9Bz3333nXvfqFGjQs8tXrzYPTdgwIBkn3HgwIGkLl26JNWpUyfpr7/+cs+99957blmtN9x5552X1Lx589Df+gwte/PNNyclJiaGnp87d657vnfv3snKX7NmTVcWf/lvvfVWt6z2TWq8fdWrV6+krVu3hh5btmxJWrhwYdJdd93lXr///vtD7xk7dqx7bvr06cnWpfc0atQo6ZJLLjniu3nmmWfS/C7k+uuvd899//33yZ6fPXu2e75z586h5/R/PffOO+9E3KbGjRsn7dy5M/T8hAkT3PPa13v27Ak9P3HiRPf822+/7f7etm1bUu3atZN9/567777bLfvzzz+7v9etW+f+PvXUU5PWrl0bWk7H04UXXuiOgb1797rn5s2bF/r+/N/rmjVr3Ofdcccd6d6/0dJ3qnU++uijyZ7Xd9yyZcvQtmu/NGjQwD23a9eu0HL79+9Puvjii90+PXjwYGgbzz333KRmzZol+/3o+D/77LOTLrvssiPK4R0P+o5S4+3Xe++91/19wQUXJLVr1y7ZMsOGDUtq2rSpO97DzwHz5893f+t4Unn826HfoF7T70neffdd9/fo0aOTrf+NN95wz+v3mZlj3ytTanSu0rJff/11sueHDBninv/ll1/c36+99pr7+9NPP0223I4dO9yxdumllx5xHunTp88Rn6fn9fvz3Hnnne4Y3rRpU7LlvvrqK7fsY489dsTv7sUXX0y2rPafnn/rrbeO2C7/960y6ljy03Gn5/v375/qfvK+k08++STZ81dddZU7Nr3vWud0nQP9Nm7c6H6T4d9z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LnO36QIAAAAAABkcgz1mzBg7ePBg8KUBAAAAACAvBdjqvX7xxRdt9erVduDAgeBLBQAAAABAXkgR//rrr23jxo1uYrNIfvvtt8yWCwAAAACA3B9gP/7448GXBAAAAACAvBZgn3XWWe5fpYivXLnSEhMT3Szi1atXD7p8AAAAAADk3gB7586d1q9fP5s1a5aVKlXKDh8+bHv27LEzzzzTnn/+eStZsmTwJQUAAAAAILdNcjZ48GDbtGmTTZ8+3ebOnWsLFiywjz76yPbu3WvDhg0LvpQAAAAAAOTGAPuLL76wAQMGWNWqVUPPKT38kUcecb3aAAAAAADkNRkKsAsXLmwJCUe+NV++fC5dHAAAAACAvCZDAfb5559vjz32mK1duzb0nCY8U+r4ueeeG2T5AAAAAADIvZOc9enTx+68805r2bKlm+RMduzYYeecc471798/6DICAAAAABD3MhRgH3XUUTZx4kRbvny5u02XUsZ1my7/mGwAAAAAAPKSDAXYBw4csGeeecYqVapknTp1cs+1b9/emjRpYvfcc48VLFgw6HICAAAAAJA7b9M1e/Zsq1WrVui5O+64w7766it74okngiwfAAAAAAC5N8CeOXOmDR8+3Bo2bBh67sILL3T3wNa9sQEAAAAAyGsyFGAnJSXZ/v37Iz5/8ODBIMoFAAAAAEDuD7BbtWrlZgtfsGCB7d271z0WLlxoAwYMsIsuuij4UgIAAAAAkBsnOevXr5899NBDdsMNN1hiYqJ7Ln/+/NamTRt78MEHgy4jAAAAAAC5L8D+559/7Oijj7YRI0bYzp07bfXq1TZ//nx3qy7NJF6sWLGsKSkAAAAAALkhRXzPnj3WvXt3a968uQuqZdasWdahQwebNGmSe1x++eW2adOmrCwvAAAAAAA5O8AePXq0bdiwwd544w2rWrWqG3et23Wddtpp9tlnn9mMGTOsWbNmbnZxAAAAAADymoT03JpL4651a658+fLZt99+63q1u3TpYgULFnTLKEVczwMAAAAAkNdEHWD//fffdsIJJ4T+/v77793EZuq19hx77LG2b9++4EsJAAAAAEBuCbDLlStn69atC93vevbs2VavXj0rVapUaJlFixZZhQoVsqakAAAAAADkhgBbt+AaMmSIm9hs6NCh9tdff9l1110Xen3ZsmVuZvHWrVtnVVkBAAAAAMj5t+m6/fbbbffu3e4+1xqDfffdd9tll13mXnviiSdswoQJ1qJFC7ccAAAAAAB5TdQ92AUKFLB+/frZ3Llzbc6cOXbHHXeEXmvbtq1NnTrVxowZ4+6HHa3ExEQbNWqUu/VX/fr1rWvXrqE09LR8+OGHVrNmTVu/fn3UnwcAAAAAQMwD7NQo0K1du3a63/fCCy/Y5MmTbdCgQTZlyhQXcN9666124MCBVN+n24UNHDgwEyUGAAAAACAOA+yMUBA9fvx4l2qu1PJatWrZyJEjbdOmTe6WYClREN6nTx+rU6dOtpYXAAAAAIC4DLA1KZruo924cePQc0cddZTrCZ8/f36K71Ma+sGDB61bt27ZVFIAAAAAAAKc5Cxo6qmW8Nt6lS1bNvRauJ9//tn1er/77ru2efPmbCknAAAAAABxHWDv27fP/VuoUKFkz2uStB07dhyx/N69e+2+++5zjypVqgQWYOue3lo3ci7Nal+0aNFYFwOA7/yucyuA2OHaCMQXro05m747nVfjOsAuUqRIaCy293/Zv39/xAvC4MGD7aSTTrIOHToEWg6lm//222+BrhPZS8dLRibZA5A1Vq1aFWpEBRAbXBuB+MK1MecL7xiOuwDbSw3fsmWLnXDCCaHn9bdmJQ/33nvvuY1q0KCB+/vw4cPuX92Lu3v37u6REQULFrTq1atncCsQD6JtTQKQPdQYSis9EFtcG4H4wrUxZ/vjjz+iXjZmAbZmDS9RooS7r7YXYO/cudOWLl1qnTt3PmL58JnFFy9e7GYTHzt2rNWoUSNTF6BixYpl+P0AgORISwUAIDmujXmn0TJmAbZ6oxVIDx8+3MqUKWOVKlWyp556ysqXL28tW7Z0PdTbtm2zkiVLuhTyE088Mdn7vYnQKlasaKVLl47RVgAAAAAAEOPbdInugX3VVVfZww8/bB07drT8+fPbuHHjXNr2X3/9Zc2aNbPp06fHsogAAAAAAMR3D7YooFaatx7hKleubMuXL0/xvY0aNUr1dQAAAAAA8kwPNgAAAAAAuUVMe7ABAAiK5u7QrReBeKJhb8rYAwDkDQTYAIAcTbc90cSX//77b6yLAkSkyVg1iSu3zgKA3I8AGwCQo3nBddmyZd1tFwliEE+NP3v37rUtW7a4vytUqBDrIgEAshgBNgAgR6eFe8H1McccE+viACne+1ZBto5T0sUBIHdjkjMAQI7ljblWzzUQr7zjkzkCACD3I8AGAOR4pIUjnnF8AkDeQYANAABSHEMMAACiR4ANAEAO1qVLF6tZs6Z16NAhxWV69erllnnggQeiXu+PP/5ot912W5rLjR492q0bAAAwyRkAADleQkKC/fTTT25Gdd0Oyk+zWH/55ZfpXuc777xjK1euTHO5q6++2po3b57u9QMAkBvRgw0AQA5Xu3ZtK1y4sH366adHvKbgWjNZlytXLks+WwF9/fr1s2TdAADkNATYAADkglmqzz333IgB9vTp061Vq1ZWoMD/n7SWmJhoY8eOtYsuushOPfVU9/rEiRNDryuV/P3337cNGza49O+pU6fa+vXr3f8nTJhgrVu3tnr16tl7770XMUV82rRp1q5dO7dMixYt7Omnn7YDBw5k8V4AACD2CLABAMgFLrnkklCauGf37t329ddf22WXXZZs2QEDBtioUaPsiiuusDFjxriAeejQofb888+71++44w4XsB933HH21ltvuSDZo4C6a9eu9uSTT1rTpk2PKMekSZOsb9++VqdOHXvuuefcOG4F74MHD87S7QcAIB4wBhsAgFxAQbBSwdWLfeONN7rnPv/8czvmmGOsYcOGoeVWrVplb7/9tvXu3Ts0iVmzZs3craReeuklu+666+yEE06wMmXKWKFChULp3xrLLRdffLFdeeWVEcugnnEF6RdeeGGygHrfvn32ySefuPtAFyxYMEv3AwAAsUQPNgAAuUCRIkXs/PPPT5YmrqBWAbH/Psxz5sxxt9/SsocOHQo99Pf+/fvd7OGpOeWUU1J8TcH71q1bXeq53y233OLSzAmuAQC5HT3YAADkEgqme/To4dLENenZDz/8YD179ky2zL///uv+vfTSSyOuY/PmzWmO906Jt271mgMAkBcRYAMAkEucc845Vrx4cdeLrUC4cuXKbhIzv6OOOsr9+9prr7llw1WsWDHDn++te9u2bcme3759uy1dutQaNGiQaoAOAEBOR4o4AAC5hMZMa/zzZ599ZjNmzIjYS33GGWeEgt66deuGHgqKn3322VAvtO6tnV5Vq1a1o48++oj7bn/wwQduvLfGYAMAkJvRgw0AQC6bTbxbt24uQH744YePeF231NLs4f3793e34VIPt8ZOjxw50vV4V6lSJdQb/c8//9js2bNTHXftlz9/frvrrrts4MCBLk1c47q1bs1Y3qlTJytVqlTg2wsAQDwhwAYAIBdp0qSJC44rVKhg1apVi7jMsGHD3IzhU6ZMceO1FQwrMNd4bQXJ0r59exdc33nnnXb33Xe716OhQFpp4OPGjXO3+Cpfvry7rZceAADkdgTYAADkYLrHtJ9m6p43b94Ry33xxReh/xcoUMAFznqkpEaNGi7N3G/58uVHLKceaz382rVr5x4AAOQ1jMEGAAAAACAABNgAAAAAAASAABsAAAAAgAAQYAMAAAAAEAACbAAAAAAAAkCADQAAAABAAAiwAQAAAAAIAAE2AAAAAAABIMAGAAAAACAABNgAAORyNWvWtKlTp8a6GLZx40b75JNPMrWOuXPnuu1Zv369ZaXzzz/fRo8enaWfAQDIfQrEugAAAGSFxMQkS0jIl+c+O5Jvv/3WSpYsGetiWN++fa1SpUp26aWXZngdDRo0cNtTpkyZQMsGAEAQCLABALmSAtzhk3609Zt3ZevnVi5X0u7r1NDiyXHHHWe5RaFChXLV9gAAchcCbABArqXgeuWGHZZTzJ4925599llbuXKlFStWzM4991zr16+flSpVytasWWOPP/64zZs3zwoUKGBNmza1hx56yP744w+7/vrrbfr06VatWrXQuvRc2bJlbfjw4S6letiwYda+ffs0y6DU6wsuuMCeeOIJe+WVV2zt2rVWq1Yt1/vcsOH/NRw88MADtnfvXtu9e7f99NNPdvvtt1vXrl3tyy+/dGnVKlO5cuVcT/Udd9zhguIuXbq4sov+/eKLL1wadqtWrdx2b9261b1XZX3qqafcc9u2bbOjjjrKlUfbWrRoUZcirm2bNWuWVa5c2a2jU6dOrhzq2dZnXX755a6M2k+ycOFCe/rpp23JkiWu5/u8886ze++910qUKOFe37Vrlw0ePNitU+/p1q1bFn3DAIDcjjHYAADEAQWTPXr0sCuvvNIFy88995zNnz/fnnzySdu5c6cLIg8cOGCvvfaaTZgwwQW+PXv2tLPOOssFmh999FFoXZs2bXLvjSagTomC+e7du9v7779vVatWtZtvvtnWrVsXev2zzz6zJk2a2HvvvWeXXXaZff31164811xzjX388cf26KOP2owZM6xPnz5ueQXPSu+++OKL7d133w2t54033rCHH37YBfP169d3gfHSpUvd9usz1MAwbdo0e+utt1IsqxolzjzzTPvwww/t/vvvd+tUGWTZsmV20003WfPmzd3ranD49ddf3fYkJSW5ZVTun3/+2caMGeP27VdffWUbNmzI8L4DAORd9GADABAHNm/e7ALoihUrunHKeijgO3z4sAu49+zZYyNGjHC92aIeV00YdvDgQWvXrp0LQhUoioJL9SCfffbZGS7Pbbfd5gJnGTRokM2ZM8fefvtt1/MrKsett94aWl7PK7ju0KGD+/uEE06wxx57zG644QbXK65GgIIFC1qRIkWSjZ9WL70CdY965hUsqydb9D4FzL///nuKZW3WrJnr1Zbjjz/eJk6c6Hqt27Zta+PGjXPrVGOBVKlSxfVmX3jhha4nXenm6vl+9dVX7YwzznDL6HX1cgMAkF4E2AAAxIFTTjnFBbQKBBX0KShs0aKFXXTRRS6wVWDoBdeitG09RIGkenwXLVrkeonVU9umTRtLSMh4olqjRo1C/1dgfOqppyYLck888cRky6vXWb3A/t5pr4dYKe8KlCMJX891113n0sfVc7569WqXbq4AXb3oKfGnxosmdFPDg1cupddrv4RTubZv3+7+X7du3dDzxx57rAvUAQBILwJsAADihHpO77zzTpdu/f3337v0ao179npzU6LgVaniShMvXry4LV++PNO3mPLGL3vUk+4P2NUT7ZeYmOh6tNWbHi61Scn869E6NP55xYoVrrHhkksusTp16lj//v1TLavGXYfzgnutU2OyvR5sP/Wkaz97y6W2/QAARIMx2AAAxIHFixfb0KFDXU/tjTfeaGPHjnV/KzVbParqzdVkXB6NI27cuLEbby0abz1z5kyXNn766acf0TOcXpoQzKPUdX2egt2UnHzyybZq1Sr3ud5DZdMYcqW3R+O3335zjQsaU33ffffZFVdc4VLNNd7cC5jTS+VSL7i/XIcOHXKTvv31118uc0CUUu7RmHd9JgAA6UWADQBAHNCM1pMnT3YzaCulWenYGnut1HDNwK30cPVoa9KuX375xU0iVqNGDStfvrx7v2bj1szeGn+cmcnNPM8884yb7EvB6YMPPmj79u1zY6xTolnENSmZUtUVaP/www9ugjI1Cng92Opd1+RhXqNAODUkqOdYk6NpQjUF+RpX/vfff7sgPyM0mZnSxDUeXCnhSqPXeHE1WGjfKoBv3bq1DRw40PVma79rorSMfh4AIG8j/wkAkGvpntQ55TM1jlhp3QpQFWgrHVuTlL388svu9lSarEu9rppETGnVGp+tW2d5tIxm6FYPtv7NrI4dO7pbdW3cuNHq1avnAnfd9islClJHjhxpL730kpucrXTp0u4WWuqJ9qjsKrN6phWAh9PEbJq9XPth0qRJLjDXdqpHX+OyM0Izk2uGcvWKK31dtz9Tz7/K4aWWazv16NWrl0sVv/baa92s7gAApBcBNgAgV0pMTLL7OjWM2WcnJORL9/s0c3VKs1crAFegmJohQ4a4RziNyU4vzait8eCRKAiORIF9asG9gmXdx9oTKWjWeGk9wqk33Jt8zb89kdahxgA/BdR6pEQNFsoI0AMAgMwgRRwAkCtlJMDNDZ8NAABihx5sAADyCKVma2xzat57771sKw8AALkNATYAAHmExkZ794dOiSb9ykhKOQAAIMAGACDPqFixYqyLAABArsYYbAAAAAAAAkCADQAAAABAAAiwAQAAAAAIAAE2AAAAAAABIMAGAAAAACAABNgAAAAAAASAABsAkCslJSbmyc/OjPPPP99Gjx4d0zI88MAD1qVLF/f/9evXW82aNW3u3LkxLRMAANHiPtgAgFwpX0KCbZn2jB3Yuj5bP7fQMZWtbNue2fqZuVWFChXs22+/tVKlSsW6KAAARIUAGwCQaym4PrBpVayLgQzKnz+/HXfccbEuBgAAUSNFHACAOKBU6EmTJtk111xjdevWtcsvv9xmzZqVbJlvvvnGrr32WqtXr56dc845NnLkSDt8+LB7bePGjdarVy9r3Lix1alTx73+1FNPWWI609X//vtvu/XWW10ZlDKuMvm98847rmynnXaa1a9f36677jpbsmRJ6PWff/7ZPdegQQM788wz7a677nJl82zevNmV84wzzrBGjRpZ9+7dbfXq1RHLEp4irtTx4cOH24MPPujef/rpp9u9995ru3fvDr1n5cqV1rVrV/f5zZo1c69rmwAAyA4E2AAAxAkFj23atLEPPvjAzj33XOvRo4ctXLjQvbZo0SK77bbbrGHDhjZ16lQbPHiwTZkyxV544QX3+u233267du2yCRMm2Keffmo333yzvfLKK/bFF1+kqwxvv/22C14//PBDu+mmm2zIkCH2+eefu9f078CBA10APmPGDHv11Vdt//799vDDD7vXFex369bNBdZ6v15XcK2AWPbu3RsaX/3GG2/YxIkT7eijj3aNCgq8o6F1Hnvssfbuu++6BgQ1Qug50ToU3J944onu9TFjxrjgW40S+mwAALIaKeIAAMSJ9u3bW6dOndz/77vvPps3b54LRNVTq2BUPdf333+/e71atWou2N26dav9999/LjC/+OKL3bhlufHGG+3ll1+25cuX24UXXhh1GbSsepXlpJNOsp9++snGjx9vF110kZUuXdoF3FdccYV7vVKlSnbVVVe5coiC2e3bt1vZsmXda8cff7w988wzrozyySef2M6dO11gXKDA/1VBtD71UCuwV293WqpXr269e/d2/69SpYo1bdrUNT7Im2++aeXLlw8F/KLPP/vss12jg/YvAABZiQAbAIA4oZRpP6U5f/fdd+7/v//+uwsm/Vq1ahX6f+fOnV0QqRTtNWvWuMD6n3/+SXeKuHrI/RTUz5492/1fPdNKwX7++eftzz//DH2O9xmajEy924MGDbJRo0a5wFY98Qr8ZenSpbZjxw63Hj/1gmu90ahatWqyv0uWLOmCdm/9K1ascPsto+sHACAzCLABAIgTXq+uRynXCQkJEV/zU/qzAmz1ZLdu3dratWvnxkh7veHp4X2eR8FzoUKF3P8/+ugjdxstjcFWr3qHDh1c4O/1YHs970rTVlD+ww8/uGBbqerTpk1z61Kv+IsvvnjE5xYrViyq8nlliUTrV1D/6KOPHvGaAnEAALIaY7ABAIgT/snCRKnPmrDMSwkPf/21116zq6++2t3K6tdff7XXX3/d7r77brvkkkusRIkSLjU7KSkpXWXQevx+/PFHO/nkk93/x44d61LCH3/8cRe8qyd63bp17jV9jnq1Fdwec8wx1rFjR9eLreBavcfLli2zGjVquDHZCnY1TlqPihUr2tNPP23z58+3zFI59VlKk/fWr171oUOHuoYAAACyGgE2AABxQgGzeolXrVplTzzxhEu/vuGGG9xrSr3WeOhnn33WzbqtHmJNcNaiRQs37lg0sdiGDRtswYIFdscdd9jBgwftwIED6SqDxklrzLWCZQXUmthM6xIFrpp0TUH42rVr3eRiGiMu+hxNWKb3P/LIIy7Q1Xa8//77LshVarfGbuv/agRYvHixW0Y94l9//bWbLTyz1HOuid7Ui66AXg/NWK6GCQX3AABkNVLEAQC5VqFjKueoz1TKtYJW9bbWqlXLxo0b5/6VU045xY19Vq+wJi/TRGLXX3+9mz1cad39+vVz79WkXuXKlXO92AqIw3u903LLLbfYl19+aSNGjHATlal32Rsb3r9/fxc8Kx1dqdoq25NPPhkKYjX7uMqm92hmcKW461ZemtlcPeqigFzv0efodfXQK6BXD31maVI1rV+frx503Udbqezq2S9Tpkym1w8AQFoIsAEAuVJSYqKVbdszZp+dL2wsczQ0Q7Y3S3gk5513nntEolnD9ciMtG7ppQBWwXI4BfMeTTDm9WqntI7Ro0en+LrSzz2VK1d2vfgezaSe2vJSu3Zt1zABAEAskCIOAMiVMhLg5obPBgAAsUMPNgAAuZxm+dZY6NQo/bxJkybZViYAAHIjAmwAAOKAPxU6aD169AhNlpYSjekGAACZQ4ANAEAupwm+mOQLAICsxyAxAAAAAAACQIANAAAAAEAACLABAAAAAAgAATYAAAAAAAEgwAYAAAAAIAAE2AAAAAAABIAAGwCQKyUmJebJz46kZs2aNnXq1Gz7vPXr17vPnDt3btTvWbFihX311VeBlmPjxo32ySefpOs933//vV199dVWr149O+ecc2z48OF24MCBQMsFAMi9Ynof7MTERHvuuefsnXfesV27dtmZZ55pjzzyiB1//PEpXnyfeuopW7x4sSUkJLjlH3jgAatYsWK2lx0AEN8S8iXYqDnjbcPOTdn6uZWOKm93n32zxZNvv/3WSpYsafGsW7du1q5dO2vRokVg6+zbt69VqlTJLr300qiWX758uSvHzTffbE8//bStW7fOrUMB9oMPPhhYuQAAuVdMA+wXXnjBJk+ebI8//riVL1/eBc+33nqrffTRR1aoUKFky27fvt1uuukmO/30023ixInuYqf3afn333/fChcuHLPtAADEJwXXq7avs7zuuOOOi3URcoS//vrLBfm9evVyf59wwgl2ySWX2HfffRfrogEAcoiYpYgrQB4/frzdfffdrrW6Vq1aNnLkSNu0aZPNnDnziOX/97//2d69e+3JJ5+0GjVq2KmnnuoC8pUrV9rChQtjsg0AAARp9uzZ1r59e5ee3LhxY5eltWPHDvfamjVr7Pbbb7eGDRtao0aNrHfv3rZ161aXhq10bF0P/a6//nq777770p0i7qV3f/bZZy5VWtfb888/3956661MXfOfeOIJtx6t76yzzrJ77rnHtm3b5l7X8xs2bHBZbV26dHHPKbOtf//+dvbZZ7tt1vYsWbIktM7Ro0fbjTfeaGPHjnWp3HXr1rXOnTuH9oPWM2/ePNcIr/VHQ/WRgQMHuv8nJSXZzz//7OofTZs2zfC2AwDylpgF2MuWLbM9e/a4CoTnqKOOstq1a9v8+fOPWF7Lqce7SJEioeeUJi47d+7MplIDAJA1FGz26NHDrrzySps+fboLNnU9VMOyrnOdOnVygeprr71mEyZMsLVr11rPnj1dsFq5cmWX/eVRY7Xeq2A9o4YNG2bdu3e3GTNmuMBzwIABLmU6I7QNajxX5pkCd/07Z84ce/HFF93r7777rstkU2q2AmcFt127dnWf99JLL9nbb79t9evXt44dO9rSpUtD612wYIH9+OOPLshWRpwaHB577DH3mtbToEEDu/jii9360+Pw4cPu89TAUKpUKfe9AAAQ1yniuvhLhQoVkj1ftmzZ0Gt+qjzo4acLqgJujcXOKF3E1TOOnCtfvnxWtGjRWBcDwP+zb98+d27NDvv373fzeSgg0sMvf/78Fkvh5YlmQi4F0Ao0vcfzzz/v1vPxxx/b7t27XeaWAj5RT6sm8Prvv/+sTZs29uGHH9pdd93lXtP/dT3V9dErh7ef0qLl5IYbbgiNh1a22aRJk2zRokVRzXvircP7zDp16thFF13keqJF26aGc4151uvaJjWa65quseJKyf7pp5/cv6VLl3bvUY+3gmk1MAwdOtSt+9ChQ64hwNsn1157rZuUTOvUegoUKOCGkOn19HwfBw8etNdff901emj9Go6mAF7Xm4zQZ6u8+m14+yarcW0E8u61EcHTdxftNaBALA8yCR9rrQuhlw6XGo3DfuONN+zhhx+2MmXKZLgcuoj+9ttvGX4/Yk8VCGU+AIgPq1atCp3js4OCKAXafgrWYh1cKFhOTzB10kknWevWre2OO+6wY4891qVGN2/e3M477zybMmWKnXjiie4aqYBa9LeW1Weol1ZZXkoXV3q5AmxN7OWf/VrXO++9qfH2pRq1veULFizo/lWDdHrWoc/X8i1btnRlU0+2Ut1Xr17t/lUPs7c+VV4UMOtvpWbr7wsuuCDZer1t0EPLHnPMMcn2if7v304vwI+mzOGqV6/u/lXPveaA0eziXgNBeml/qLx//vmnZReujUDevjYieOFxa9wF2F6qty6+/rRvXYRSqxTpgvvss8+6tDKNRfPGamWUKg3eRRQ5U0Z7FABkDQWK2dmDrZ5fBVb+a0lOuhD7jRgxwvVCf/PNNy6gUyOyJvfUmGid61LaxqpVq7pU8c8//9w1OuuuG6NGjUq2vK530ewjb9LQEiVKHLG8GjPSsw7tAy2vIFWp4W3btrULL7zQzbuiNPfNmzeH1qft89av7AN9vu4yEs5bp5b1/u/fRvGeU0OL1hXtsaH0c4391hh3j8Z2y7///pupY0zl1aRp2TUpK9dGIO9eGxG8P/74I+plYxZge6nhW7ZscRccj/5WRSIStUr369fPpcrpX01uEsQFqFixYpleDwDg/2Rnz7ECKC+IinVKeLj0lke3oFTKt24HpYZf9ZqqJ7pPnz7WrFkz1+OrHmTvdlu//vpr6E4aSrnWeGulR2s+EwXlCrr9vP2UFm9+k0jLZ2QdGj+uMdSayFQzcvt7c3T99dan67G3ftUDlBKvHmh/I7gaHBScazIzLav3+Mvjfa5/neHLpEZj3zXmXBObKSCWX375xf2rCVYzeozpfV5WRbw1BAHIHrHOqkL2NVrGbJIzXSDVOq2UMY8uwmo9TmlM9f3332+ffvqpuzdlEME1AADxQtdEjfPVOGsF07///rsL+KpUqeKytTSOWMG2JglV0Pfoo4+6oE/BtbRq1coF4BpClZnJzbJiu9QoMGvWLLddGnet2cHVQOBPYS9evLhLHf/nn39cavwpp5zibpelydD0Po2F1kzo1apVi/qztU7NTh5pbpdINImahqk98sgjrgFAmQQPPfSQ27eqtwAAELc92ErrUgu0WtuVzlapUiVXqVBFQWO1NGZKk4vooqzWXl1UVdFQkK00uL///ju0Lm8ZAAD8Kh1VPsd8pgJHzXyt2cMVaKvHU+OwX375ZdfzMW7cOBdkdujQwV3zNAFZ3759Q+/XMhqLrV5w/RsvlLatoV2aOfzyyy93DQXebcY0Q7jGJKrsakTQrbyU3q6ee93KU/UCzZSuZbR/tG/8dx9Ji/aV9tEVV1xhP/zwQ5o90Mqo0yRq+lw1UihAV5m9+2IDABC3AbY3K6km/VDKlyYgUc+1KhC6GOs+nJrcRJUJXeSUFi6aIEUPP28ZAAA8iUmJdvfZN8fssxPypT9JTBOa6RGJAsxXXnkl1fcPGTLEPcKp1zhamtws0vKZWYfuI+2/jZinW7duof9fc8017uFR47uu7ynRWHVv1nSP6gL++oAaIfyZctE47bTTXBYAAAA5LsBWS7LS3fRI6+KslmwAAKKVkQA3N3w2AADIowE2AADIPkqVXrduXarLqMc3tRnQg1hHdtNs5boFWmo0W7jufQ0AQGYQYAMAkEeMGTPG3ZEjNd6trrJyHdlN9xWfNm1aqstk1+2zAAC5GwE2AAB5RMWKFeNiHbEYknbiiSfGuhgAgDyAQWIAAAAAAASAABsAAAAAgAAQYAMAAAAAEAACbAAAAAAAAkCADQAAAABAAAiwAQAAAAAIAAE2ACBXSkpMzJOfHUnNmjVt6tSp2fZ569evd585d+7cqN+zYsUK++qrrwItx8aNG+2TTz5J13tefPFFV/bwBwAA0eA+2ACAXClfQoL9PuIZ27tufbZ+brHjK1uN3j0tnnz77bdWsmRJi2fdunWzdu3aWYsWLQJbZ9++fa1SpUp26aWXRv2e5cuXW5s2baxPnz6BlQMAkHcQYAMAci0F13v+XGV53XHHHRfrIuQYv//+u11zzTXsMwBAhpAiDgBAnJg9e7a1b9/e6tWrZ40bN7YHHnjAduzY4V5bs2aN3X777dawYUNr1KiR9e7d27Zu3erSsJXCvHLlymTruv766+2+++5Ld4q4l9792Wef2dVXX22nnnqqnX/++fbWW29leLsOHDhgTzzxhFuP1nfWWWfZPffcY9u2bXOv6/kNGzbYc889Z126dHHP7dq1y/r3729nn32222Ztz5IlS0LrHD16tN144402duxYO+ecc6xu3brWuXPn0H7QeubNm2fvv/++W3+05Vy9erVVrVo1w9sKAMjbCLABAIgDCjZ79OhhV155pU2fPt0Fm/Pnz7cnn3zSdu7caZ06dXIB4GuvvWYTJkywtWvXWs+ePV2wWrlyZfvoo49C69q0aZN7r4L1jBo2bJh1797dZsyY4dK2BwwYYOvWrcvQurQNM2fOtMcff9wF7vp3zpw5bryzvPvuu1a+fHm7+eabXeCclJRkXbt2dZ/30ksv2dtvv23169e3jh072tKlS0PrXbBggf34448uyJ48ebJrcHjsscfca1pPgwYN7OKLL3brj8Yff/xhhw8fdmVs1aqV226lim/ZsiVD2w0AyHtIEQcAIA5s3rzZBdAVK1Z044b1GDNmjAv4FHDv2bPHRowYYaVKlXLLDx482E3gdfDgQTd2edq0aS7glo8//tjKlSvnen8zSr3DF1xwgft/r169bNKkSbZ48WI7/vjj070u9S63bt3azjjjDPe3tq1JkyYuHVvKlClj+fPnt2LFilnp0qXthx9+sJ9++skF4fpb1GO/cOFCe/31112ALocOHXLBu7dPOnToYE899ZT7v95XsGBBK1KkiFt/NLzyFC1a1J599lkXsGufq/dc+1frAgAgNQTYAADEgVNOOcUuu+wy12us8b9NmzZ1PagXXXSR68GtUqVKKJCUWrVquYe0bdvW9XgvWrTI9dp++OGHbqKuhISMJ6pVq1Yt9H9vgjQF8xmhsnz//fc2fPhwl4L9559/2qpVq0IBd7hff/3V9WKfd955yZ5XA8T+/ftDfx977LHJ9onKmdEyevtR6eb+gPzkk092z33xxRd2ySWXZHjdAIC8gQAbAIA48fTTT9udd95pX3/9tQtIlZ6s8cdp3SZKKeJKFVeaePHixd1M2EqRzoxChQod8ZyC3ox45JFHXNq1AliNh9Y2jhs3zvXaR5KYmGglSpSIOG7cX65IZcys8N7usmXLut5wpd0DAJAWxmADABAHlH49dOhQN8GWN3mX/laatHpq1fOrib/8vbyaCM0L/DTeWuOclTZ++umn24knnmjxYPv27W6CtEcffdT69evnyqneevVipxSw16hRw3bv3u16o7Ud3uPll1+2WbNmZVlZR44c6cZe+8ulSd+0DdWrV8+yzwUA5B4E2AAAxAH12GqiLo0h1ozhGg+ssddKDdeM2EqFVo/2smXL7JdffnEBqwJRTQ4mCgz37t1rEydOzNTkZlmxXUrdVmCs7VLvumYHVwOBUr496nlXI8I///xjzZs3d0G4xn6rgUHv06Rr6tH2p66nRevU7OTR9j4rHV/La0I3pbBrori77rrLNVioTAAApIUUcQBArlXs+Mo55jMVOCqtW2OpFWhr/LQmKVOvrSbdUkq1gkxN5KXJtjQ+u2/fvqH3axnNmK0ebP0bLzTRmCYM08Rkl19+uWso8G4zphnC9+3b58quRgTdymvFihVuDPn48eNdY4MmbtMy2j/aN+q1j5b2lfbRFVdc4SZO00RqqdEtxLS/VV41UigFXRO9aR358uULYG8AAHI7AmwAQK6UlJhoNXr3jNln58vABGOa1Ct8Yi+PAsxXXnkl1fcPGTLEPcKp1zhaGs8dafnMrEMTtvlvI+bp1q1b6P/XXHONe/jHQqtBISXqWdbDT0Gxv/dejRC6T3h6KIBPTxAPAIAfKeIAgFwpIwFubvhsAAAQO/RgAwCQRyhVet26dakuox7f1GbnDmId2U2zles+3Gndq1v32AYAIDMIsAEAyCPGjBmT5n2iNWY6q9eR3TQL+7Rp01JdpnDhwtlWHgBA7kWADQBAHlGxYsW4WEd20+Rm8XLbMgBA7sYgMQAAAAAAAkCADQAAAABAAAiwAQAAAAAIAAE2AAAAAAABIMAGAAAAACAABNgAAAAAAASAABsAkCslJiblyc+OpGbNmjZ16tRs+7z169e7z5w7d27U71mxYoV99dVXgZZj48aN9sknn2Tovfv377crrrgi4n6bNGmSXXDBBXbaaafZddddZ0uXLg2gtACA3ID7YAMAcqWEhHw2ddIi+2fzrmz93GPLlbT2nRpYPPn222+tZMmSFs+6detm7dq1sxYtWgS2zr59+1qlSpXs0ksvTdf7du3aZT179rTly5cf8dr7779vTz75pA0aNMhq165tY8eOtZtuuslmzJhhZcqUCazsAICciQAbAJBrKbjetGGn5XXHHXdcrIuQY3zxxRcueD766KMjvj5mzBjr3Lmz692WoUOH2oUXXmjvvPOOayQAAORtpIgDABAnZs+ebe3bt7d69epZ48aN7YEHHrAdO3a419asWWO33367NWzY0Bo1amS9e/e2rVu3ujRspWOvXLky2bquv/56u++++9KdIu6ld3/22Wd29dVX26mnnmrnn3++vfXWWxnergMHDtgTTzzh1qP1nXXWWXbPPffYtm3b3Ot6fsOGDfbcc89Zly5dQr3I/fv3t7PPPttts7ZnyZIloXWOHj3abrzxRteDfM4551jdunVd4OvtB61n3rx5rsdZ64/W//73P+vQoYNNmTLliNe0v1evXu2+G0+BAgXsjDPOsPnz52d4/wAAcg8CbAAA4oCCzR49etiVV15p06dPd8GmgjalI+/cudM6derkAtXXXnvNJkyYYGvXrnVpzApWK1eubB999FFoXZs2bXLvVbCeUcOGDbPu3bu71GelbQ8YMMDWrVuXoXVpG2bOnGmPP/64C9z175w5c+zFF190r7/77rtWvnx5u/nmm13gnJSUZF27dnWf99JLL9nbb79t9evX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e9pZZ51llStXto8++ii0rk2bNrn3RhNQp0QBeffu3W3GjBnWokULGzBggOvFzQhtw8yZM10DgYJs/Ttnzhx78cUX3evvvvuulS9f3m6++WYXOCclJVnXrl3d57300ksuXbt+/frWsWNHW7p0aWi9CxYscEH22LFjbfLkybZ161YXYIvW06BBA7v44ovd+qOhwFmf4/fyyy+7DAA1Uoh6sPVd6ftQcK8yff311xnaLwCA3IcebAAA4oAmz1IAXbFiRatUqZJ7jBkzxg4fPuwC7j179tiIESNcb7YMHjzYTeCl3t127dq59GYF3PLxxx9buXLl7Oyzz85weW688UbXky29evWySZMm2eLFi10vbnqp17l169Z2xhlnuL+1bQpOFayKerHz58/verZLly5tP/zwg/30008uCNff0rt3bzcB2euvv+4CdDl06JAL3r190qFDB3vqqafc//W+ggULWpEiRdz6M+KJJ55wE6+psUPr0uf9+eefVr16dXvggQesRIkS7ju47bbbXKOHeuUBAHkbATYAAHHglFNOscsuu8z1GqvHVCng6jm+6KKLXA+uxv16gaTUqlXLPaRt27YuCFy0aJHrtf3www+tTZs2bhx6RvnToEuWLOn+VTCfESrL999/79LVV69e7YJUTSjmBdzhfv31V9eLrXRtPzVA7N+/P/T3sccem2yfqJwZLaOf1vHII4+4RotBgwbZhRde6J5Xar5mRldjgAJ3OfXUU90M6OPGjSPABgAQYAMAEC+efvppu/POO13KsQJSjTnW7aK89OSUKEVcqeJKEy9evLgbJ6wU6cwoVKjQEc8p6M0IBatKDVdDgMZbaxsVkKrXPqVZ2NU7HOnWV/5yRSpjZu3evdul6iv9XBkDSjH30/4Nd/LJJ7uZxAEAYAw2AABxQOnXQ4cOtapVq7r0bI0r1t9Kk1ZPrXp+NfGXv5dXPaYaby0ab61xzkpZPv300+3EE0+0eKDJx9566y03oZkmbFM51VuvXuyUAvYaNWq4QFc9ydoO76Hx0LNmzcqysqqHXJO56dZcagAID67VU619G35/719++cWljQMAQIANAEAcUI+tJurSGGLNGK7xyRp7rdRwzYitVGj1aOs+zAroFLAqENXkYNKqVSvbu3evm4E7M5ObZcV2KXVbgbG2S73r/fv3dw0ECmj9PcNqRPjnn3+sefPm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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Plot ARI and NMI for each model variant\n", "results_df.plot.bar(figsize=(10, 5))\n", "plt.title(\"Clustering Performance: scVI Model Variants vs. PCA Baseline\", fontsize=14)\n", "plt.ylabel(\"Score\", fontsize=10)\n", "plt.xlabel(\"Model Variant\", fontsize=10)\n", "plt.xticks(rotation=0)\n", "plt.legend(title=\"Metric\")\n", "plt.tight_layout()\n", "plt.show()" ] } ], "metadata": { "kernelspec": { "display_name": ".venv_notebooks", "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.12.11" } }, "nbformat": 4, "nbformat_minor": 5 }