{
"cells": [
{
"cell_type": "markdown",
"id": "2780fd26",
"metadata": {},
"source": [
"# Using custom labelling schemes"
]
},
{
"cell_type": "markdown",
"id": "874e3ada",
"metadata": {},
"source": [
"[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/lucasmiranda42/deepof/blob/master/docs/source/tutorial_notebooks/deepof_custom_labels_tutorial.ipynb)"
]
},
{
"cell_type": "markdown",
"id": "b059b912",
"metadata": {},
"source": [
"##### What we'll cover:\n",
" \n",
"* Labelling schemes supported by DeepOF.\n",
"* How to create a new labelling scheme and integrate it with the unsupervised pipeline."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "998be631",
"metadata": {},
"outputs": [],
"source": [
"%load_ext autoreload\n",
"%autoreload 2"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "25ccbea4",
"metadata": {},
"outputs": [],
"source": [
"# # If using Google colab, uncomment and run this cell and the one below to set up the environment\n",
"# # Note: becasuse of how colab handles the installation of local packages, this cell will kill your runtime.\n",
"# # This is not an error! Just continue with the cells below.\n",
"# import os\n",
"# !git clone -q https://github.com/mlfpm/deepof.git\n",
"# !pip install -q -e deepof --progress-bar off\n",
"# os.chdir(\"deepof\")\n",
"# !curl --output tutorial_files.zip https://datashare.mpcdf.mpg.de/s/knF7t78isQuIAr0/download\n",
"# !unzip tutorial_files.zip\n",
"# os.kill(os.getpid(), 9)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "80e4b2fc",
"metadata": {},
"outputs": [],
"source": [
"# os.chdir(\"deepof\")\n",
"# import os, warnings\n",
"# warnings.filterwarnings('ignore')"
]
},
{
"cell_type": "markdown",
"id": "7632cba8",
"metadata": {},
"source": [
"Let's start by importing some packages. We'll use python's os library to handle paths, pickle to load saved objects, pandas to load data frames, and the data entry API within DeepOF, located in deepof.data"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "4d85f5bf",
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"import os\n",
"import pandas as pd\n",
"import pickle\n",
"import deepof.data"
]
},
{
"cell_type": "markdown",
"id": "ffdcefa1",
"metadata": {},
"source": [
"We'll also need some plotting gear:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "e438d39f",
"metadata": {},
"outputs": [],
"source": [
"from IPython import display\n",
"from networkx import Graph, draw\n",
"import deepof.visuals\n",
"import matplotlib.pyplot as plt\n",
"import seaborn as sns"
]
},
{
"cell_type": "markdown",
"id": "983af8b4",
"metadata": {},
"source": [
"### Recap: labelling schemes supported by DeepOF"
]
},
{
"cell_type": "markdown",
"id": "9c41de92",
"metadata": {},
"source": [
"DeepOF supports two labelling schemes out of the box: the `deepof_14` scheme, selected by default, and `deepof_8`, a reduced set of tracking labels that is common among, for example, [SimBA](https://goldenneurolab.com/simba) users.\n",
"\n",
"**NOTE**: This is not necessary if you use the matrix representations introduced in the previous tutorial. If you'd like to try out the graph representations we explored, however, but you have a different labelling scheme, this is the place to be."
]
},
{
"cell_type": "markdown",
"id": "2e2d3ae5",
"metadata": {},
"source": [
""
]
},
{
"cell_type": "markdown",
"id": "0a3c0b08",
"metadata": {},
"source": [
"While, as mentioned above, `deepof_14` is selected by default, the provided alternative can be selected when defining a new `deepof.Project` instance:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "7abae556",
"metadata": {},
"outputs": [],
"source": [
"my_deepof_project = deepof.data.Project(\n",
" project_path=os.path.join(\"tutorial_files\"),\n",
" video_path=os.path.join(\"tutorial_files/Videos/\"),\n",
" table_path=os.path.join(\"tutorial_files/Tables/\"),\n",
" project_name=\"deepof_tutorial_project\",\n",
" arena=\"circular-autodetect\",\n",
" animal_ids=[\"B\", \"W\"],\n",
" video_format=\".mp4\",\n",
" bodypart_graph=\"deepof_8\", # Can also be set to 'deepof_14' (default), or take a custom graph\n",
" video_scale=380,\n",
" enable_iterative_imputation=True,\n",
" smooth_alpha=1,\n",
" exp_conditions=None,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "94d8c03b",
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Setting up project directories...\n",
"Loading trajectories...\n",
"Smoothing trajectories...\n",
"Interpolating outliers...\n",
"Iterative imputation of ocluded bodyparts...\n",
"Detecting arena...\n",
"Computing distances...\n",
"Computing angles...\n",
"Computing areas...\n",
"Done!\n"
]
}
],
"source": [
"my_deepof_project = my_deepof_project.create(force=True)"
]
},
{
"cell_type": "markdown",
"id": "65393407",
"metadata": {},
"source": [
"We can take a look at the constructed graph in this case (you can see how the default looks like in the previous tutorial, or change the labelling scheme to `deepof_14` in the cell above if you're following in colab):"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "630bd119",
"metadata": {},
"outputs": [],
"source": [
"graph_preprocessed_coords, adj_matrix, to_preprocess, global_scaler = my_deepof_project.get_graph_dataset(\n",
" animal_id=\"B\", # Comment out for multi-animal embeddings\n",
" center=\"Center\",\n",
" align=\"Spine_1\",\n",
" window_size=25,\n",
" window_step=1,\n",
" test_videos=1,\n",
" preprocess=True,\n",
" scale=\"standard\",\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "eeada2e4",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"