From adad838d1eb48457a6ba3dea49e2f0873f5573b8 Mon Sep 17 00:00:00 2001 From: Mathis Lab Date: Wed, 30 Jan 2019 14:48:06 -0500 Subject: [PATCH 01/37] Create README.MD --- DLC_2_MotionMapper/README.MD | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 DLC_2_MotionMapper/README.MD diff --git a/DLC_2_MotionMapper/README.MD b/DLC_2_MotionMapper/README.MD new file mode 100644 index 0000000..cf2840a --- /dev/null +++ b/DLC_2_MotionMapper/README.MD @@ -0,0 +1,10 @@ +**DeepLabCut --> MotionMapper** + +(1) download the code from Gordon Berman; here is a lightly modified version that I forked +that I know works with the script I supply: https://github.com/MMathisLab/MotionMapper + +(2) Make sure the whole folder is on-path in MATLAB (see Gordon's instrustions too) + +(3) Place my two helper functions into the MotionMapper folder: https://github.com/AlexEMG/DLCutils/tree/master/DLC_2_MotionMapper + +(4) Open the .m file called deeplabcut_into_motionMapper.m and follow the instructions! From 58364afbd1f6ba5cb0b9fd59284650e8d8d09a8c Mon Sep 17 00:00:00 2001 From: Mathis Lab Date: Wed, 30 Jan 2019 20:07:34 -0500 Subject: [PATCH 02/37] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cc91c4d..d7f47b6 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,10 @@ https://github.com/AlexEMG/DLCutils/blob/master/convertDLC1TO2.py Contributed by [Alexander Mathis](https://github.com/AlexEMG) ## Running project created on Windows on Colaboratory +#UPDATE: as of Deeplabcut 2.0.4 you no longer need to use this code! You can simply create the training set on the cloud and it will automatically convert your project for you. -This solves a path problem when creating a project and annotating data on Windows (see https://github.com/AlexEMG/DeepLabCut/issues/172). This functionality will be included in -a later version of DLC 2. - + - This solves a path problem when creating a project and annotating data on Windows (see https://github.com/AlexEMG/DeepLabCut/issues/172). This functionality will be included in +a later version of DLC 2 (DONE!) https://github.com/AlexEMG/DLCutils/blob/master/convertWin2Unix.py *Usage:* change in lines 70 and 71 of https://github.com/AlexEMG/DLCutils/blob/master/convertWin2Unix.py From 13741e33a740ee2c9d8e3d289f8528a6114ee63c Mon Sep 17 00:00:00 2001 From: Mathis Lab Date: Mon, 4 Feb 2019 13:48:53 -0500 Subject: [PATCH 03/37] added pupilDLC.py --- pupilTracking/pupilDLC.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 pupilTracking/pupilDLC.py diff --git a/pupilTracking/pupilDLC.py b/pupilTracking/pupilDLC.py new file mode 100644 index 0000000..20ad2fb --- /dev/null +++ b/pupilTracking/pupilDLC.py @@ -0,0 +1,33 @@ +# libraries +import matplotlib.pyplot as plt +import pandas as pd +import numpy as np +import os + +# data selection +path = input('path to csv files (eg. C:\\Users\\) :') #C:\Users\Windows\Desktop +path = os.path.normpath(path) +os.chdir(path) +files = [os.path.join(path, file) for file in os.listdir(path) + if file.endswith('.csv')] +print(files) +i = input('which file to selecet (eg: 0 or 1) ?') +i = int(i) + +# dataset +df = pd.read_csv(files[i]) # store the csv file in dataframe df +df = df.iloc[2:len(df.index), np.r_[0,1,2,4,5,7,8,10,11]] # subselect dataframe +df.columns = ['frame','x1x','x1y','x2x','x2y','y1x','y1y','y2x','y2y'] +df = df.convert_objects(convert_numeric=True) +df = df.assign(diamH = ((df.x2x-df.x1x)**2 + (df.x2y-df.x1y)**2)**0.5, diamV = ((df.y2x-df.y1x)**2 + (df.y2y-df.y1y)**2)**0.5) #obtain horizontal and vertucak pupil diameters respectively diamH and diamV + +# plot +figure = plt.figure() +plt.plot('frame','diamH', data=df, linestyle='none', marker='o', markersize=1, alpha=0.1) +plt.plot('frame','diamV', data=df, linestyle='none', marker='o', markersize=1, alpha=0.1) +plt.xlim(0,len(df.index)) +plt.axis('off') +plt.box(False) +#plt.show() + +figure.savefig(files[i]+'.png', bbox_inches='tight', transparent=True, dpi=300) \ No newline at end of file From 5a7a627ce54f6789909fbb000c2a7412e51cc1bb Mon Sep 17 00:00:00 2001 From: AlexEMG Date: Sun, 10 Feb 2019 16:22:12 -0500 Subject: [PATCH 04/37] Examples for scalable analysis --- README.md | 12 ++++++ scale_analysis_oversubfolders.py | 48 +++++++++++++++++++++++ scale_raining_and_evaluation.py | 65 ++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 scale_analysis_oversubfolders.py create mode 100644 scale_raining_and_evaluation.py diff --git a/README.md b/README.md index d7f47b6..0461687 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,18 @@ Various scripts to support [DeepLabCut](https://github.com/AlexEMG/DeepLabCut). Feel free to contribute your own analysis methods, and perhaps some short notebook of how to use it. Thanks! +## Example scripts for automation of anlysis & training + +These two scripts illustrate how to train, test and analyze videos for multiple projects automatically (scale_raining_and_evaluation.py) and +how to analyze videos that are organized in subfolders automatically (scale_analysis_oversubfolders.py). Feel free to adjust them for your needs! + +https://github.com/AlexEMG/DLCutils/blob/master/scale_analysis_oversubfolders.py +https://github.com/AlexEMG/DLCutils/blob/master/scale_raining_and_evaluation.py + +Contributed by [Alexander Mathis](https://github.com/AlexEMG) + + + ## DLC1 to DLC 2 conversion code This code allows you to import the labeled data from DLC 1 to DLC 2 projects. Note, it is not streamlined and should be used with care. diff --git a/scale_analysis_oversubfolders.py b/scale_analysis_oversubfolders.py new file mode 100644 index 0000000..0c8d753 --- /dev/null +++ b/scale_analysis_oversubfolders.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Sun Feb 10 16:04:37 2019 + +@author: alex +""" + +import os + +import deeplabcut + +def getsubfolders(folder): + ''' returns list of subfolders ''' + return [os.path.join(folder,p) for p in os.listdir(folder) if os.path.isdir(os.path.join(folder,p))] + +project='ComplexWheelD3-12-Fumi-2019-01-28' + +shuffle=1 + +prefix='/home/alex/DLC-workshopRowland' + +projectpath=os.path.join(prefix,project) +config=os.path.join(projectpath,'config.yaml') + +basepath='/home/alex/BenchmarkingExperimentsJan2019' #data' + +''' + +Imagine that the data (here: videos of 3 different types) are in subfolders: + /January/January29 .. + /February/February1 + /February/February2 + + etc. + +''' + +subfolders=getsubfolders(basepath) +for subfolder in subfolders: #this would be January, February etc. in the upper example + print("Starting analyze data in:", subfolder) + subsubfolders=getsubfolders(subfolder) + for subsubfolder in subsubfolders: #this would be Febuary1, etc. in the upper example... + print("Starting analyze data in:", subsubfolder) + for vtype in ['.mp4','.m4v','.mpg']: + deeplabcut.analyze_videos(config,[subsubfolder],shuffle=shuffle,videotype=vtype,save_as_csv=True) + + \ No newline at end of file diff --git a/scale_raining_and_evaluation.py b/scale_raining_and_evaluation.py new file mode 100644 index 0000000..d9154bc --- /dev/null +++ b/scale_raining_and_evaluation.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Sat Nov 17 14:12:43 2018 + +An example script to automate analysis on 3 different GPUs for different projects. Feel free to adapt this to your needs! + +@author: alex + +First start container: +python3 scale_raining_and_evaluation.py 1 (2 or 3) + +""" + +import subprocess, sys +import numpy as np +import itertools +import os + +import deeplabcut + +Maxiter=int(1.5*10**5) + +model=int(sys.argv[1]) + +Projects=[['project1-phoenix-2019-01-28'],['ComplexWheelD3-12-Fumi-2019-01-28', 'maze-ariel-2019-01-28'], ['TBI-BvA-2019-01-28','group-eli-2019-01-28']] + +shuffle=1 + +prefix='/home/alex/DLC-workshopRowland' + +for project in Projects[model]: + projectpath=os.path.join(prefix,project) + config=os.path.join(projectpath,'config.yaml') + + cfg=deeplabcut.auxiliaryfunctions.read_config(config) + previous_path=cfg['project_path'] + + cfg['project_path']=projectpath + deeplabcut.auxiliaryfunctions.write_config(config,cfg) + + print("This is the name of the script: ", sys.argv[0]) + print("Shuffle: ", shuffle) + print("config: ", config) + + deeplabcut.create_training_dataset(config, Shuffles=[shuffle],windows2linux=True) + + deeplabcut.train_network(config, shuffle=shuffle, max_snapshots_to_keep=5, maxiters=Maxiter) + print("Evaluating...") + deeplabcut.evaluate_network(config, Shuffles=[shuffle],plotting=True) + + print("Analyzing videos..., switching to last snapshot...") + #cfg=deeplabcut.auxiliaryfunctions.read_config(config) + #cfg['snapshotindex']=-1 + #deeplabcut.auxiliaryfunctions.write_config(config,cfg) + + for vtype in ['.mp4','.m4v','.mpg']: + try: + deeplabcut.analyze_videos(config,[str(os.path.join(projectpath,'videos'))],shuffle=shuffle,videotype=vtype,save_as_csv=True) + except: + pass + + print("DONE WITH ", project," resetting to original path") + cfg['project_path']=previous_path + deeplabcut.auxiliaryfunctions.write_config(config,cfg) \ No newline at end of file From 407d7ccf6115537c920f2a1da56fcdcdbdbc9d5b Mon Sep 17 00:00:00 2001 From: Alexander Mathis Date: Tue, 12 Feb 2019 18:11:14 -0500 Subject: [PATCH 05/37] Update conda-environment-cheatsheet --- conda-environment-cheatsheet | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conda-environment-cheatsheet b/conda-environment-cheatsheet index 9778550..967446a 100644 --- a/conda-environment-cheatsheet +++ b/conda-environment-cheatsheet @@ -2,6 +2,8 @@ conda create -n dlctest python=3.6 conda env export > environment.yml +to create: +conda env create -f environment.yml ##Remove: conda remove --name dlctest --all From f6005e58041c196c785e46e582288e4b5c8b5992 Mon Sep 17 00:00:00 2001 From: Mathis Lab Date: Thu, 2 May 2019 10:24:55 -0400 Subject: [PATCH 06/37] Update README.md --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0461687..05f9a4b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![Image.sc forum](https://img.shields.io/badge/dynamic/json.svg?label=forum&url=https%3A%2F%2Fforum.image.sc%2Ftags%2Fdeeplabcut.json&query=%24.topic_list.tags.0.topic_count&colorB=brightgreen&&suffix=%20topics&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAABPklEQVR42m3SyyqFURTA8Y2BER0TDyExZ+aSPIKUlPIITFzKeQWXwhBlQrmFgUzMMFLKZeguBu5y+//17dP3nc5vuPdee6299gohUYYaDGOyyACq4JmQVoFujOMR77hNfOAGM+hBOQqB9TjHD36xhAa04RCuuXeKOvwHVWIKL9jCK2bRiV284QgL8MwEjAneeo9VNOEaBhzALGtoRy02cIcWhE34jj5YxgW+E5Z4iTPkMYpPLCNY3hdOYEfNbKYdmNngZ1jyEzw7h7AIb3fRTQ95OAZ6yQpGYHMMtOTgouktYwxuXsHgWLLl+4x++Kx1FJrjLTagA77bTPvYgw1rRqY56e+w7GNYsqX6JfPwi7aR+Y5SA+BXtKIRfkfJAYgj14tpOF6+I46c4/cAM3UhM3JxyKsxiOIhH0IO6SH/A1Kb1WBeUjbkAAAAAElFTkSuQmCC)](https://forum.image.sc/tags/deeplabcut) -# DLCutils +# DeepLabCut-Utils Various scripts to support [DeepLabCut](https://github.com/AlexEMG/DeepLabCut). Feel free to contribute your own analysis methods, and perhaps some short notebook of how to use it. Thanks! @@ -25,7 +25,7 @@ https://github.com/AlexEMG/DLCutils/blob/master/convertDLC1TO2.py Contributed by [Alexander Mathis](https://github.com/AlexEMG) ## Running project created on Windows on Colaboratory -#UPDATE: as of Deeplabcut 2.0.4 you no longer need to use this code! You can simply create the training set on the cloud and it will automatically convert your project for you. +#UPDATE: as of Deeplabcut 2.0.4 onwards you no longer need to use this code! You can simply create the training set on the cloud and it will automatically convert your project for you. - This solves a path problem when creating a project and annotating data on Windows (see https://github.com/AlexEMG/DeepLabCut/issues/172). This functionality will be included in a later version of DLC 2 (DONE!) @@ -58,10 +58,16 @@ Contributed by [Mackenzie Mathis](https://github.com/MMathisLab) ## Using DeepLabCut for USB-CGPIO feedback paper: https://www.biorxiv.org/content/early/2018/11/28/482349 + code: https://github.com/bf777/DeepCutRealTime maintainer: [Brandon Forys](https://github.com/bf777) +## A wrapper package for DeepLabCut2.0 for 3D videos (anipose) +code: https://github.com/lambdaloop/anipose + +maintainer: [Pierre Karashchuk](https://github.com/lambdaloop) + ## Pupil Tracking - From Tom Vaissie - tvaissie@scripps.edu - Please see the README.txt file https://github.com/AlexEMG/DLCutils/tree/master/pupilTracking for details; this code makes the video in case study 7 http://www.mousemotorlab.org/deeplabcut/. From ed38c209b0babc63dcb004312f683a0af6728aa4 Mon Sep 17 00:00:00 2001 From: Alexander Mathis Date: Wed, 8 May 2019 20:18:48 -0400 Subject: [PATCH 07/37] Update and rename scale_raining_and_evaluation.py to scale_training_and_evaluation.py --- ...ning_and_evaluation.py => scale_training_and_evaluation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename scale_raining_and_evaluation.py => scale_training_and_evaluation.py (94%) diff --git a/scale_raining_and_evaluation.py b/scale_training_and_evaluation.py similarity index 94% rename from scale_raining_and_evaluation.py rename to scale_training_and_evaluation.py index d9154bc..aa3ca64 100644 --- a/scale_raining_and_evaluation.py +++ b/scale_training_and_evaluation.py @@ -8,7 +8,7 @@ @author: alex First start container: -python3 scale_raining_and_evaluation.py 1 (2 or 3) +python3 scale_training_and_evaluation.py 1 (2 or 3) """ @@ -62,4 +62,4 @@ print("DONE WITH ", project," resetting to original path") cfg['project_path']=previous_path - deeplabcut.auxiliaryfunctions.write_config(config,cfg) \ No newline at end of file + deeplabcut.auxiliaryfunctions.write_config(config,cfg) From 2da865ea49fdb9ca44846e8cadd93813ef395b17 Mon Sep 17 00:00:00 2001 From: AlexEMG Date: Tue, 11 Jun 2019 21:40:59 -0400 Subject: [PATCH 08/37] Example notebook for loading data and roi analysis --- Demo_loadandanalyzeDLCdata.ipynb | 5288 +++++++++++++++++ ...t_resnet50_openfieldOct30shuffle1_15001.h5 | Bin 0 -> 282371 bytes time_in_each_roi.py | 6 +- 3 files changed, 5291 insertions(+), 3 deletions(-) create mode 100644 Demo_loadandanalyzeDLCdata.ipynb create mode 100755 m3v1mp4DeepCut_resnet50_openfieldOct30shuffle1_15001.h5 diff --git a/Demo_loadandanalyzeDLCdata.ipynb b/Demo_loadandanalyzeDLCdata.ipynb new file mode 100644 index 0000000..751c37e --- /dev/null +++ b/Demo_loadandanalyzeDLCdata.ipynb @@ -0,0 +1,5288 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "N0gDJMy1ywm8" + }, + "source": [ + "# DeepLabCut Toolbox - demo for post processing\n", + "\n", + "https://github.com/AlexEMG/DeepLabCut" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "hTtJxcQ7ywnB" + }, + "outputs": [], + "source": [ + "# Importing the toolbox (takes several seconds)\n", + "import pandas as pd\n", + "from pathlib import Path\n", + "import numpy as np\n", + "import os\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "WOEHc0MeywnJ" + }, + "outputs": [], + "source": [ + "# this is example data from the public project: https://github.com/AlexEMG/DeepLabCut/tree/master/examples/openfield-Pranav-2018-10-30\n", + "video='m3v1mp4.mp4'\n", + "DLCscorer='DeepCut_resnet50_openfieldOct30shuffle1_15001'\n", + "\n", + "dataname = str(Path(video).stem) + DLCscorer + '.h5'\n", + "\n", + "#loading output of DLC\n", + "Dataframe = pd.read_hdf(os.path.join(dataname))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\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", + " \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", + " \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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
scorerDeepCut_resnet50_openfieldOct30shuffle1_15001
bodypartssnoutleftearrighteartailbase
coordsxylikelihoodxylikelihoodxylikelihoodxylikelihood
075.86107288.5070020.99863572.025992102.7499170.99963885.85531390.1997040.999799142.480108180.3720460.999833
174.64714886.4391780.99941470.35006899.6213880.99983685.88981987.0618890.999841141.605256179.3654150.999991
273.19410384.0195960.99893270.25904197.2084030.99971184.49419584.3643510.999868144.028973175.5096240.999990
373.43876080.5111570.99791569.01925694.7772820.99972383.49111481.9676550.999787147.907935174.8481150.999971
472.88661878.1187250.99879368.07669591.4361650.99983981.37581378.2915110.999795150.296287170.7332740.999970
\n", + "
" + ], + "text/plain": [ + "scorer DeepCut_resnet50_openfieldOct30shuffle1_15001 \\\n", + "bodyparts snout \n", + "coords x y likelihood \n", + "0 75.861072 88.507002 0.998635 \n", + "1 74.647148 86.439178 0.999414 \n", + "2 73.194103 84.019596 0.998932 \n", + "3 73.438760 80.511157 0.997915 \n", + "4 72.886618 78.118725 0.998793 \n", + "\n", + "scorer \\\n", + "bodyparts leftear rightear \n", + "coords x y likelihood x y likelihood \n", + "0 72.025992 102.749917 0.999638 85.855313 90.199704 0.999799 \n", + "1 70.350068 99.621388 0.999836 85.889819 87.061889 0.999841 \n", + "2 70.259041 97.208403 0.999711 84.494195 84.364351 0.999868 \n", + "3 69.019256 94.777282 0.999723 83.491114 81.967655 0.999787 \n", + "4 68.076695 91.436165 0.999839 81.375813 78.291511 0.999795 \n", + "\n", + "scorer \n", + "bodyparts tailbase \n", + "coords x y likelihood \n", + "0 142.480108 180.372046 0.999833 \n", + "1 141.605256 179.365415 0.999991 \n", + "2 144.028973 175.509624 0.999990 \n", + "3 147.907935 174.848115 0.999971 \n", + "4 150.296287 170.733274 0.999970 " + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#Let's have a look at the data:\n", + "\n", + "#these structures are awesome to manipulate, how -->> see pandas https://pandas.pydata.org/pandas-docs/stable/index.html\n", + "Dataframe.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "ROlflqQLywnP" + }, + "outputs": [], + "source": [ + "# The plotting functions below are put here for simplicity and so that the user can edit them. Note that they \n", + "# (or variants thereof) are in fact in standard DLC and accessible via:\n", + "\n", + "import deeplabcut\n", + "deeplabcut.utils.plotting.PlottingResults?" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def get_cmap(n, name='hsv'):\n", + " return plt.cm.get_cmap(name, n)\n", + "\n", + "def Histogram(vector,color,bins):\n", + " dvector=np.diff(vector)\n", + " dvector=dvector[np.isfinite(dvector)]\n", + " plt.hist(dvector,color=color,histtype='step',bins=bins)\n", + "\n", + "def PlottingResults(Dataframe,bodyparts2plot,alphavalue=.2,pcutoff=.5,colormap='jet',fs=(4,3)):\n", + " ''' Plots poses vs time; pose x vs pose y; histogram of differences and likelihoods.'''\n", + " plt.figure(figsize=fs)\n", + " colors = get_cmap(len(bodyparts2plot),name = colormap)\n", + " scorer=Dataframe.columns.get_level_values(0)[0] #you can read out the header to get the scorer name!\n", + "\n", + " for bpindex, bp in enumerate(bodyparts2plot):\n", + " Index=Dataframe[scorer][bp]['likelihood'].values > pcutoff\n", + " plt.plot(Dataframe[scorer][bp]['x'].values[Index],Dataframe[scorer][bp]['y'].values[Index],'.',color=colors(bpindex),alpha=alphavalue)\n", + "\n", + " plt.gca().invert_yaxis()\n", + "\n", + " sm = plt.cm.ScalarMappable(cmap=plt.get_cmap(colormap), norm=plt.Normalize(vmin=0, vmax=len(bodyparts2plot)-1))\n", + " sm._A = []\n", + " cbar = plt.colorbar(sm,ticks=range(len(bodyparts2plot)))\n", + " cbar.set_ticklabels(bodyparts2plot)\n", + " #plt.savefig(os.path.join(tmpfolder,\"trajectory\"+suffix))\n", + " plt.figure(figsize=fs)\n", + " Time=np.arange(np.size(Dataframe[scorer][bodyparts2plot[0]]['x'].values))\n", + "\n", + " for bpindex, bp in enumerate(bodyparts2plot):\n", + " Index=Dataframe[scorer][bp]['likelihood'].values > pcutoff\n", + " plt.plot(Time[Index],Dataframe[scorer][bp]['x'].values[Index],'--',color=colors(bpindex),alpha=alphavalue)\n", + " plt.plot(Time[Index],Dataframe[scorer][bp]['y'].values[Index],'-',color=colors(bpindex),alpha=alphavalue)\n", + "\n", + " sm = plt.cm.ScalarMappable(cmap=plt.get_cmap(colormap), norm=plt.Normalize(vmin=0, vmax=len(bodyparts2plot)-1))\n", + " sm._A = []\n", + " cbar = plt.colorbar(sm,ticks=range(len(bodyparts2plot)))\n", + " cbar.set_ticklabels(bodyparts2plot)\n", + " plt.xlabel('Frame index')\n", + " plt.ylabel('X and y-position in pixels')\n", + " #plt.savefig(os.path.join(tmpfolder,\"plot\"+suffix))\n", + "\n", + " plt.figure(figsize=fs)\n", + " for bpindex, bp in enumerate(bodyparts2plot):\n", + " Index=Dataframe[scorer][bp]['likelihood'].values > pcutoff\n", + " plt.plot(Time,Dataframe[scorer][bp]['likelihood'].values,'-',color=colors(bpindex),alpha=alphavalue)\n", + "\n", + " sm = plt.cm.ScalarMappable(cmap=plt.get_cmap(colormap), norm=plt.Normalize(vmin=0, vmax=len(bodyparts2plot)-1))\n", + " sm._A = []\n", + " cbar = plt.colorbar(sm,ticks=range(len(bodyparts2plot)))\n", + " cbar.set_ticklabels(bodyparts2plot)\n", + " plt.xlabel('Frame index')\n", + " plt.ylabel('likelihood')\n", + "\n", + " #plt.savefig(os.path.join(tmpfolder,\"plot-likelihood\"+suffix))\n", + "\n", + " plt.figure(figsize=fs)\n", + " bins=np.linspace(0,np.amax(Dataframe.max()),100)\n", + "\n", + " for bpindex, bp in enumerate(bodyparts2plot):\n", + " Index=Dataframe[scorer][bp]['likelihood'].values < pcutoff\n", + " X=Dataframe[scorer][bp]['x'].values\n", + " X[Index]=np.nan\n", + " Histogram(X,colors(bpindex),bins)\n", + " Y=Dataframe[scorer][bp]['x'].values\n", + " Y[Index]=np.nan\n", + " Histogram(Y,colors(bpindex),bins)\n", + "\n", + " sm = plt.cm.ScalarMappable(cmap=plt.get_cmap(colormap), norm=plt.Normalize(vmin=0, vmax=len(bodyparts2plot)-1))\n", + " sm._A = []\n", + " cbar = plt.colorbar(sm,ticks=range(len(bodyparts2plot)))\n", + " cbar.set_ticklabels(bodyparts2plot)\n", + " plt.ylabel('Count')\n", + " plt.xlabel('DeltaX and DeltaY')\n", + " \n", + " #plt.savefig(os.path.join(tmpfolder,\"hist\"+suffix))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "bodyparts=Dataframe.columns.get_level_values(1) #you can read out the header to get body part names!\n", + "\n", + "bodyparts2plot=bodyparts #you could also take a subset, i.e. =['snout']\n", + "\n", + "%matplotlib notebook\n", + "PlottingResults(Dataframe,bodyparts2plot,alphavalue=.2,pcutoff=.5,fs=(8,4))\n", + "\n", + "# These plots can are interactive and can be customized (see https://matplotlib.org/) [in the code above]\n", + "# note that the snout and other bpts jitter in this example that was not trained for long." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "h9H7eqDLywnV" + }, + "source": [ + "## Great so let's use Federico's code for ROI analysis\n", + "\n", + "Functions to extract time spent by the mouse in each of a list of user defined ROIS!\n", + "\n", + "https://github.com/AlexEMG/DLCutils/blob/master/time_in_each_roi.py" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "jg96O2acywnW", + "scrolled": false + }, + "outputs": [], + "source": [ + "import time_in_each_roi #the function needs to be in the same folder as the notebook\n", + "\n", + "#let's calculate velocity of the snout\n", + "bpt='snout'\n", + "vel = time_in_each_roi.calc_distance_between_points_in_a_vector_2d(np.vstack([Dataframe[DLCscorer][bpt]['x'].values.flatten(), Dataframe[DLCscorer][bpt]['y'].values.flatten()]).T)\n", + "\n", + "fps=30 # frame rate of camera in those experiments\n", + "time=np.arange(len(vel))*1./fps\n", + "vel=vel #notice the units of vel are relative pixel distance [per time step]\n", + "\n", + "# store in other variables:\n", + "xsnout=Dataframe[DLCscorer][bpt]['x'].values\n", + "ysnout=Dataframe[DLCscorer][bpt]['y'].values\n", + "vsnout=vel" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "application/javascript": [ + "/* Put everything inside the global mpl namespace */\n", + "window.mpl = {};\n", + "\n", + "\n", + "mpl.get_websocket_type = function() {\n", + " if (typeof(WebSocket) !== 'undefined') {\n", + " return WebSocket;\n", + " } else if (typeof(MozWebSocket) !== 'undefined') {\n", + " return MozWebSocket;\n", + " } else {\n", + " alert('Your browser does not have WebSocket support.' +\n", + " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", + " 'Firefox 4 and 5 are also supported but you ' +\n", + " 'have to enable WebSockets in about:config.');\n", + " };\n", + "}\n", + "\n", + "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", + " this.id = figure_id;\n", + "\n", + " this.ws = websocket;\n", + "\n", + " this.supports_binary = (this.ws.binaryType != undefined);\n", + "\n", + " if (!this.supports_binary) {\n", + " var warnings = document.getElementById(\"mpl-warnings\");\n", + " if (warnings) {\n", + " warnings.style.display = 'block';\n", + " warnings.textContent = (\n", + " \"This browser does not support binary websocket messages. \" +\n", + " \"Performance may be slow.\");\n", + " }\n", + " }\n", + "\n", + " this.imageObj = new Image();\n", + "\n", + " this.context = undefined;\n", + " this.message = undefined;\n", + " this.canvas = undefined;\n", + " this.rubberband_canvas = undefined;\n", + " this.rubberband_context = undefined;\n", + " this.format_dropdown = undefined;\n", + "\n", + " this.image_mode = 'full';\n", + "\n", + " this.root = $('
');\n", + " this._root_extra_style(this.root)\n", + " this.root.attr('style', 'display: inline-block');\n", + "\n", + " $(parent_element).append(this.root);\n", + "\n", + " this._init_header(this);\n", + " this._init_canvas(this);\n", + " this._init_toolbar(this);\n", + "\n", + " var fig = this;\n", + "\n", + " this.waiting = false;\n", + "\n", + " this.ws.onopen = function () {\n", + " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", + " fig.send_message(\"send_image_mode\", {});\n", + " if (mpl.ratio != 1) {\n", + " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", + " }\n", + " fig.send_message(\"refresh\", {});\n", + " }\n", + "\n", + " this.imageObj.onload = function() {\n", + " if (fig.image_mode == 'full') {\n", + " // Full images could contain transparency (where diff images\n", + " // almost always do), so we need to clear the canvas so that\n", + " // there is no ghosting.\n", + " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", + " }\n", + " fig.context.drawImage(fig.imageObj, 0, 0);\n", + " };\n", + "\n", + " this.imageObj.onunload = function() {\n", + " fig.ws.close();\n", + " }\n", + "\n", + " this.ws.onmessage = this._make_on_message_function(this);\n", + "\n", + " this.ondownload = ondownload;\n", + "}\n", + "\n", + "mpl.figure.prototype._init_header = function() {\n", + " var titlebar = $(\n", + " '
');\n", + " var titletext = $(\n", + " '
');\n", + " titlebar.append(titletext)\n", + " this.root.append(titlebar);\n", + " this.header = titletext[0];\n", + "}\n", + "\n", + "\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._init_canvas = function() {\n", + " var fig = this;\n", + "\n", + " var canvas_div = $('
');\n", + "\n", + " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", + "\n", + " function canvas_keyboard_event(event) {\n", + " return fig.key_event(event, event['data']);\n", + " }\n", + "\n", + " canvas_div.keydown('key_press', canvas_keyboard_event);\n", + " canvas_div.keyup('key_release', canvas_keyboard_event);\n", + " this.canvas_div = canvas_div\n", + " this._canvas_extra_style(canvas_div)\n", + " this.root.append(canvas_div);\n", + "\n", + " var canvas = $('');\n", + " canvas.addClass('mpl-canvas');\n", + " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", + "\n", + " this.canvas = canvas[0];\n", + " this.context = canvas[0].getContext(\"2d\");\n", + "\n", + " var backingStore = this.context.backingStorePixelRatio ||\n", + "\tthis.context.webkitBackingStorePixelRatio ||\n", + "\tthis.context.mozBackingStorePixelRatio ||\n", + "\tthis.context.msBackingStorePixelRatio ||\n", + "\tthis.context.oBackingStorePixelRatio ||\n", + "\tthis.context.backingStorePixelRatio || 1;\n", + "\n", + " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", + "\n", + " var rubberband = $('');\n", + " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", + "\n", + " var pass_mouse_events = true;\n", + "\n", + " canvas_div.resizable({\n", + " start: function(event, ui) {\n", + " pass_mouse_events = false;\n", + " },\n", + " resize: function(event, ui) {\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " stop: function(event, ui) {\n", + " pass_mouse_events = true;\n", + " fig.request_resize(ui.size.width, ui.size.height);\n", + " },\n", + " });\n", + "\n", + " function mouse_event_fn(event) {\n", + " if (pass_mouse_events)\n", + " return fig.mouse_event(event, event['data']);\n", + " }\n", + "\n", + " rubberband.mousedown('button_press', mouse_event_fn);\n", + " rubberband.mouseup('button_release', mouse_event_fn);\n", + " // Throttle sequential mouse events to 1 every 20ms.\n", + " rubberband.mousemove('motion_notify', mouse_event_fn);\n", + "\n", + " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", + " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", + "\n", + " canvas_div.on(\"wheel\", function (event) {\n", + " event = event.originalEvent;\n", + " event['data'] = 'scroll'\n", + " if (event.deltaY < 0) {\n", + " event.step = 1;\n", + " } else {\n", + " event.step = -1;\n", + " }\n", + " mouse_event_fn(event);\n", + " });\n", + "\n", + " canvas_div.append(canvas);\n", + " canvas_div.append(rubberband);\n", + "\n", + " this.rubberband = rubberband;\n", + " this.rubberband_canvas = rubberband[0];\n", + " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", + " this.rubberband_context.strokeStyle = \"#000000\";\n", + "\n", + " this._resize_canvas = function(width, height) {\n", + " // Keep the size of the canvas, canvas container, and rubber band\n", + " // canvas in synch.\n", + " canvas_div.css('width', width)\n", + " canvas_div.css('height', height)\n", + "\n", + " canvas.attr('width', width * mpl.ratio);\n", + " canvas.attr('height', height * mpl.ratio);\n", + " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", + "\n", + " rubberband.attr('width', width);\n", + " rubberband.attr('height', height);\n", + " }\n", + "\n", + " // Set the figure to an initial 600x600px, this will subsequently be updated\n", + " // upon first draw.\n", + " this._resize_canvas(600, 600);\n", + "\n", + " // Disable right mouse context menu.\n", + " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", + " return false;\n", + " });\n", + "\n", + " function set_focus () {\n", + " canvas.focus();\n", + " canvas_div.focus();\n", + " }\n", + "\n", + " window.setTimeout(set_focus, 100);\n", + "}\n", + "\n", + "mpl.figure.prototype._init_toolbar = function() {\n", + " var fig = this;\n", + "\n", + " var nav_element = $('
')\n", + " nav_element.attr('style', 'width: 100%');\n", + " this.root.append(nav_element);\n", + "\n", + " // Define a callback function for later on.\n", + " function toolbar_event(event) {\n", + " return fig.toolbar_button_onclick(event['data']);\n", + " }\n", + " function toolbar_mouse_event(event) {\n", + " return fig.toolbar_button_onmouseover(event['data']);\n", + " }\n", + "\n", + " for(var toolbar_ind in mpl.toolbar_items) {\n", + " var name = mpl.toolbar_items[toolbar_ind][0];\n", + " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", + " var image = mpl.toolbar_items[toolbar_ind][2];\n", + " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", + "\n", + " if (!name) {\n", + " // put a spacer in here.\n", + " continue;\n", + " }\n", + " var button = $('');\n", + " button.click(method_name, toolbar_event);\n", + " button.mouseover(tooltip, toolbar_mouse_event);\n", + " nav_element.append(button);\n", + " }\n", + "\n", + " // Add the status bar.\n", + " var status_bar = $('');\n", + " nav_element.append(status_bar);\n", + " this.message = status_bar[0];\n", + "\n", + " // Add the close button to the window.\n", + " var buttongrp = $('
');\n", + " var button = $('');\n", + " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", + " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", + " buttongrp.append(button);\n", + " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", + " titlebar.prepend(buttongrp);\n", + "}\n", + "\n", + "mpl.figure.prototype._root_extra_style = function(el){\n", + " var fig = this\n", + " el.on(\"remove\", function(){\n", + "\tfig.close_ws(fig, {});\n", + " });\n", + "}\n", + "\n", + "mpl.figure.prototype._canvas_extra_style = function(el){\n", + " // this is important to make the div 'focusable\n", + " el.attr('tabindex', 0)\n", + " // reach out to IPython and tell the keyboard manager to turn it's self\n", + " // off when our div gets focus\n", + "\n", + " // location in version 3\n", + " if (IPython.notebook.keyboard_manager) {\n", + " IPython.notebook.keyboard_manager.register_events(el);\n", + " }\n", + " else {\n", + " // location in version 2\n", + " IPython.keyboard_manager.register_events(el);\n", + " }\n", + "\n", + "}\n", + "\n", + "mpl.figure.prototype._key_event_extra = function(event, name) {\n", + " var manager = IPython.notebook.keyboard_manager;\n", + " if (!manager)\n", + " manager = IPython.keyboard_manager;\n", + "\n", + " // Check for shift+enter\n", + " if (event.shiftKey && event.which == 13) {\n", + " this.canvas_div.blur();\n", + " event.shiftKey = false;\n", + " // Send a \"J\" for go to next cell\n", + " event.which = 74;\n", + " event.keyCode = 74;\n", + " manager.command_mode();\n", + " manager.handle_keydown(event);\n", + " }\n", + "}\n", + "\n", + "mpl.figure.prototype.handle_save = function(fig, msg) {\n", + " fig.ondownload(fig, null);\n", + "}\n", + "\n", + "\n", + "mpl.find_output_cell = function(html_output) {\n", + " // Return the cell and output element which can be found *uniquely* in the notebook.\n", + " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", + " // IPython event is triggered only after the cells have been serialised, which for\n", + " // our purposes (turning an active figure into a static one), is too late.\n", + " var cells = IPython.notebook.get_cells();\n", + " var ncells = cells.length;\n", + " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", + " data = data.data;\n", + " }\n", + " if (data['text/html'] == html_output) {\n", + " return [cell, data, j];\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}\n", + "\n", + "// Register the function which deals with the matplotlib target/channel.\n", + "// The kernel may be null if the page has been refreshed.\n", + "if (IPython.notebook.kernel != null) {\n", + " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", + "}\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.patches as patches\n", + "fig,ax = plt.subplots(1)\n", + "\n", + "#plot snout + bounding boxes for rois\n", + "plt.plot(xsnout,ysnout,'.-')\n", + "\n", + "rect = patches.Rectangle(rois['rightside'].topleft,rois['rightside'].bottomright[0]-rois['rightside'].topleft[0],rois['rightside'].bottomright[1]-rois['rightside'].topleft[1],linewidth=1,edgecolor='purple',facecolor='none')\n", + "ax.add_patch(rect)\n", + "rect = patches.Rectangle(rois['leftside'].topleft,rois['leftside'].bottomright[0]-rois['leftside'].topleft[0],rois['leftside'].bottomright[1]-rois['leftside'].topleft[1],linewidth=1,edgecolor='orange',facecolor='none')\n", + "ax.add_patch(rect)\n", + "plt.ylim(-11,491)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'avg_time_in_roi': {'leftside': 176.8, 'rightside': 56.2},\n", + " 'avg_time_in_roi_sec': {'leftside': 5.8933333333333335,\n", + " 'rightside': 1.8733333333333335},\n", + " 'avg_vel_in_roi': {'leftside': 4.798367612314975,\n", + " 'rightside': 7.978920763420923},\n", + " 'cumulative_time_in_roi': {'leftside': 1768, 'rightside': 562},\n", + " 'cumulative_time_in_roi_sec': {'leftside': 58.93333333333333,\n", + " 'rightside': 18.733333333333334},\n", + " 'transitions_per_roi': {'leftside': 10, 'rightside': 10}}" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import time_in_each_roi #the function needs to be in the same folder as the notebook\n", + "\n", + "res = time_in_each_roi.get_timeinrois_stats(bp_tracking.T, rois, fps=30)\n", + "\n", + "#print results:\n", + "res" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "name": "Demo-labeledexample-MouseReaching.ipynb", + "provenance": [], + "version": "0.3.2" + }, + "kernelspec": { + "display_name": "Python [conda env:DLC2]", + "language": "python", + "name": "conda-env-DLC2-py" + }, + "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.6.6" + }, + "varInspector": { + "cols": { + "lenName": 16, + "lenType": 16, + "lenVar": 40 + }, + "kernels_config": { + "python": { + "delete_cmd_postfix": "", + "delete_cmd_prefix": "del ", + "library": "var_list.py", + "varRefreshCmd": "print(var_dic_list())" + }, + "r": { + "delete_cmd_postfix": ") ", + "delete_cmd_prefix": "rm(", + "library": "var_list.r", + "varRefreshCmd": "cat(var_dic_list()) " + } + }, + "types_to_exclude": [ + "module", + "function", + "builtin_function_or_method", + "instance", + "_Feature" + ], + "window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/m3v1mp4DeepCut_resnet50_openfieldOct30shuffle1_15001.h5 b/m3v1mp4DeepCut_resnet50_openfieldOct30shuffle1_15001.h5 new file mode 100755 index 0000000000000000000000000000000000000000..ad4a2475af3dca9a0590d8ad83cfa16989f8da0a GIT binary patch literal 282371 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

5-E5Nzd8N6HP(R)ra)-#A5#VIDXW*zc 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 z

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 z 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 literal 0 HcmV?d00001 diff --git a/time_in_each_roi.py b/time_in_each_roi.py index e1ab240..d5562e1 100644 --- a/time_in_each_roi.py +++ b/time_in_each_roi.py @@ -127,7 +127,7 @@ def get_roi_at_each_frame(bp_data, rois): def get_timeinrois_stats(data, rois, fps=None): """ - Quantify number of times the animal enters a roi, comulative number of frames spend there, comulative time in seconds + Quantify number of times the animal enters a roi, cumulative number of frames spend there, cumulative time in seconds spent in the roi and average velocity while in the roi. In which roi the mouse is at a given frame is determined with --> get_roi_at_each_frame() Quantify the ammount of time in each roi and the avg stay in each roi @@ -176,8 +176,8 @@ def get_indexes(lst, match): avg_vel_per_roi[name] = np.average(np.asarray(vels)) results = dict(transitions_per_roi=transitions_count, - comulative_time_in_roi=data_time_inrois, - comulative_time_in_roi_sec=data_time_inrois_sec, + cumulative_time_in_roi=data_time_inrois, + cumulative_time_in_roi_sec=data_time_inrois_sec, avg_time_in_roi=avg_time_in_roi, avg_time_in_roi_sec=avg_time_in_roi_sec, avg_vel_in_roi=avg_vel_per_roi) From 0bb97961bebaa049e3d61843169cb086bb47248c Mon Sep 17 00:00:00 2001 From: Alexander Mathis Date: Wed, 19 Jun 2019 14:30:31 -0400 Subject: [PATCH 09/37] ubuntu 18 conda environment as used for woods hole course --- dlc_ubuntu18.yml | 106 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 dlc_ubuntu18.yml diff --git a/dlc_ubuntu18.yml b/dlc_ubuntu18.yml new file mode 100644 index 0000000..8c33461 --- /dev/null +++ b/dlc_ubuntu18.yml @@ -0,0 +1,106 @@ +name: dlc +channels: + - conda-forge + - defaults +dependencies: + - _tflow_select=2.1.0=gpu + - blas=1.0=openblas + - c-ares=1.15.0=h14c3975_1001 + - ca-certificates=2019.5.15=0 + - certifi=2019.3.9=py36_0 + - cudatoolkit=10.0.130=0 + - cudnn=7.6.0=cuda10.0_0 + - cupti=10.0.130=0 + - gast=0.2.2=py_0 + - hdf5=1.10.4=nompi_h3c11f04_1106 + - libblas=3.8.0=7_openblas + - libcblas=3.8.0=7_openblas + - libedit=3.1.20181209=hc058e9b_0 + - libffi=3.2.1=hd88cf55_4 + - libgcc-ng=9.1.0=hdf63c60_0 + - libgfortran-ng=7.3.0=hdf63c60_0 + - liblapack=3.8.0=7_openblas + - libopenblas=0.3.6=h5a2b251_0 + - libprotobuf=3.8.0=h8b12597_0 + - libstdcxx-ng=9.1.0=hdf63c60_0 + - mock=3.0.5=py36_0 + - ncurses=6.1=he6710b0_1 + - numpy-base=1.14.6=py36h2f8d375_4 + - openblas=0.3.5=h9ac9557_1001 + - openssl=1.1.1c=h7b6447c_1 + - pip=19.1.1=py36_0 + - python=3.6.8=h0371630_0 + - readline=7.0=h7b6447c_5 + - setuptools=41.0.1=py36_0 + - sqlite=3.28.0=h7b6447c_0 + - tensorflow=1.13.1=gpu_py36h3991807_0 + - tensorflow-base=1.13.1=gpu_py36h8d69cac_0 + - tensorflow-estimator=1.13.0=py_0 + - tk=8.6.8=hbc83047_0 + - werkzeug=0.15.4=py_0 + - xz=5.2.4=h14c3975_4 + - zlib=1.2.11=h7b6447c_3 + - pip: + - absl-py==0.7.1 + - astor==0.8.0 + - chardet==3.0.4 + - click==7.0 + - cloudpickle==1.2.1 + - cycler==0.10.0 + - decorator==4.4.0 + - deeplabcut==2.0.6.3 + - easydict==1.9 + - grpcio==1.21.1 + - h5py==2.9.0 + - idna==2.8 + - imageio==2.3.0 + - intel-openmp==2019.0 + - ipython==6.0.0 + - ipython-genutils==0.2.0 + - jedi==0.13.3 + - keras-applications==1.0.8 + - keras-preprocessing==1.1.0 + - kiwisolver==1.1.0 + - markdown==3.1.1 + - matplotlib==3.0.3 + - moviepy==0.2.3.5 + - networkx==2.3 + - numexpr==2.6.9 + - numpy==1.14.6 + - opencv-python==3.4.5.20 + - pandas==0.21.0 + - parso==0.4.0 + - patsy==0.5.1 + - pexpect==4.7.0 + - pickleshare==0.7.5 + - pillow==6.0.0 + - prompt-toolkit==1.0.16 + - protobuf==3.8.0 + - ptyprocess==0.6.0 + - pygments==2.4.2 + - pyparsing==2.4.0 + - pypubsub==4.0.3 + - python-dateutil==2.7.3 + - pytz==2019.1 + - pywavelets==1.0.3 + - pyyaml==5.1.1 + - requests==2.22.0 + - ruamel-yaml==0.15.0 + - scikit-image==0.14.3 + - scikit-learn==0.19.2 + - scipy==1.1.0 + - simplegeneric==0.8.1 + - six==1.11.0 + - statsmodels==0.9.0 + - tables==3.5.2 + - tensorboard==1.12.2 + - tensorflow-gpu==1.12.0 + - termcolor==1.1.0 + - tqdm==4.32.1 + - traitlets==4.3.2 + - urllib3==1.25.3 + - wcwidth==0.1.7 + - wheel==0.31.1 + - wxpython==4.0.3 +prefix: /home/fairhalllab/Downloads/yes/envs/dlc + From d0c11046be6e9991be3f65c5aaceee6641a5771d Mon Sep 17 00:00:00 2001 From: Alexander Mathis Date: Mon, 1 Jul 2019 13:26:21 -0400 Subject: [PATCH 10/37] Update conda-environment-cheatsheet --- conda-environment-cheatsheet | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/conda-environment-cheatsheet b/conda-environment-cheatsheet index 967446a..53efc0e 100644 --- a/conda-environment-cheatsheet +++ b/conda-environment-cheatsheet @@ -7,3 +7,11 @@ conda env create -f environment.yml ##Remove: conda remove --name dlctest --all + + +## A nice environment for CPU on Ubuntu 16.04 +conda create -n DLC2 python=3.6 +pip install deeplabcut +pip install https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-16.04/wxPython-4.0.3-cp36-cp36m-linux_x86_64.whl +pip install tensorflow +pip install ipython spyder From 32584ca2d4de95c7fc3aff9db46fcaace3fcb154 Mon Sep 17 00:00:00 2001 From: Alexander Mathis Date: Fri, 19 Jul 2019 20:29:53 -0400 Subject: [PATCH 11/37] Installation... --- installDLCandAnaconda.sh | 21 +++++++++++++++++++++ testDLC.py | 13 +++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 installDLCandAnaconda.sh create mode 100644 testDLC.py diff --git a/installDLCandAnaconda.sh b/installDLCandAnaconda.sh new file mode 100644 index 0000000..62fab03 --- /dev/null +++ b/installDLCandAnaconda.sh @@ -0,0 +1,21 @@ +sudo apt install curl +sudo apt-get install git + +#download anaconda: +curl https://repo.anaconda.com/archive/Anaconda3-2019.03-Linux-x86_64.sh --output anaconda.sh +sudo chmod 777 anaconda.sh + +./anaconda.sh + + +cd Desktop +git clone https://github.com/AlexEMG/DeepLabCut + +# YOU NEED TO RESTART TERMINAL... +## An environment for CPU on Ubuntu 18.04 +conda create -n DLC python=3.6 +conda activate DLC +pip install deeplabcut +pip install https://extras.wxpython.org/wxPython4/extras/linux/gtk3/ubuntu-18.04/wxPython-4.0.3-cp36-cp36m-linux_x86_64.whl +pip install tensorflow +pip install ipython spyder diff --git a/testDLC.py b/testDLC.py new file mode 100644 index 0000000..162e825 --- /dev/null +++ b/testDLC.py @@ -0,0 +1,13 @@ +import deeplabcut +import os + + +configpath=os.path.join('/home/neudata/Desktop/DeepLabCut/examples/openfield-Pranav-2018-10-30/config.yaml') + +deeplabcut.load_demo_data(configpath) + +deeplabcut.train_network(configpath,maxiters=5) #trains for 5 iterations + + +#manually test GUI... +deeplabcut.label_frames(configpath) From bb981fb6ce728f341dc8981bef2bd8a823a9195c Mon Sep 17 00:00:00 2001 From: federico claudi Date: Sat, 5 Oct 2019 08:50:06 +0100 Subject: [PATCH 12/37] bugfix + importvements to roistats --- test.py | 30 +++++++++++++++++++ time_in_each_roi.py | 70 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 83 insertions(+), 17 deletions(-) create mode 100644 test.py diff --git a/test.py b/test.py new file mode 100644 index 0000000..a2b3b37 --- /dev/null +++ b/test.py @@ -0,0 +1,30 @@ +import pandas as pd +import os + +from time_in_each_roi import * + +# Get data +datafile = "/Users/federicoclaudi/Downloads/c190m615 b vs aDeepCut_resnet50_Network_Training_11Sep11shuffle1_1030000.h5" + +data = pd.read_hdf(datafile) +scorer = data.columns.get_level_values(0)[0] #you can read out the header to get the scorer name! +bps = sorted(list(set(data[scorer].columns.get_level_values(0)))) # get the bodyparts names + +# Get nose tracking data +pcutoff = 0.5 +x, y = data[scorer][bps[1]]['x'].values.flatten(), data[scorer][bps[1]]['x'].values.flatten() + +# get speed +speed = calc_distance_between_points_in_a_vector_2d(np.vstack([x, y]).T) + +# define rois +from collections import namedtuple +position = namedtuple('position', ['topleft', 'bottomright']) +bp_tracking = np.array((x, y)).T + +#two points defining each roi: topleft(X,Y) and bottomright(X,Y). +rois = {'Familiar': position((0, 0), (213.4, 126.76)),'Novel': position((273.5, 339), (480, 480))} +print(rois) + +# get results +print(get_timeinrois_stats(bp_tracking, rois, fps=16, returndf=True)) diff --git a/time_in_each_roi.py b/time_in_each_roi.py index d5562e1..ebbf4df 100644 --- a/time_in_each_roi.py +++ b/time_in_each_roi.py @@ -1,6 +1,7 @@ import numpy as np from collections import namedtuple from scipy.spatial import distance +import pandas as pd """ Functions to extract time spent by the mouse in each of a list of user defined ROIS @@ -81,13 +82,16 @@ def get_roi_at_each_frame(bp_data, rois): """ Given position data for a bodypart and the position of a list of rois, this function calculates which roi is the closest to the bodypart at each frame - :param bp_data: numpy array: [nframes, 2] -> X,Y position of bodypart at each frame - [as extracted by DeepLabCut] --> df.bodypart.values + :param bp_data: numpy array: [nframes, 3] -> X,Y,Speed position of bodypart at each frame + [as extracted by DeepLabCut] --> df.bodypart.values. :param rois: dictionary with the position of each roi. The position is stored in a named tuple with the location of two points defyining the roi: topleft(X,Y) and bottomright(X,Y). :return: tuple, closest roi to the bodypart at each frame """ + def sort_roi_points(roi): + return np.sort([roi.topleft[0], roi.bottomright[0]]), np.sort([roi.topleft[1], roi.bottomright[1]]) + if not isinstance(rois, dict): raise ValueError('rois locations should be passed as a dictionary') if not isinstance(bp_data, np.ndarray): @@ -107,35 +111,45 @@ def get_roi_at_each_frame(bp_data, rois): roi_names = list(rois.keys()) - # Calc distance toe ach roi for each frame + # Calc distance to each roi for each frame data_length = bp_data.shape[0] distances = np.zeros((data_length, len(centers))) for idx, center in enumerate(centers): cnt = np.tile(center, data_length).reshape((data_length, 2)) dist = np.hypot(np.subtract(cnt[:, 0], bp_data[:, 0]), np.subtract(cnt[:, 1], bp_data[:, 1])) - - - distances[:, idx] = dist - # Get which roi the mouse is in at each frame + # Get which roi is closest at each frame sel_rois = np.argmin(distances, 1) roi_at_each_frame = tuple([roi_names[x] for x in sel_rois]) - return roi_at_each_frame + # Check if the tracked point is actually in the closest ROI + cleaned_rois = [] + for i, roi in enumerate(roi_at_each_frame): + x,y = bp_data[i, 0], bp_data[i, 1] + X, Y = sort_roi_points(rois[roi]) # get x,y coordinates of roi points + if not X[0] <= x <= X[1] or not Y[0] <= y <= Y[1]: + cleaned_rois.append('none') + else: + cleaned_rois.append(roi) + + return cleaned_rois -def get_timeinrois_stats(data, rois, fps=None): + +def get_timeinrois_stats(data, rois, fps=None, returndf=False): """ Quantify number of times the animal enters a roi, cumulative number of frames spend there, cumulative time in seconds spent in the roi and average velocity while in the roi. In which roi the mouse is at a given frame is determined with --> get_roi_at_each_frame() Quantify the ammount of time in each roi and the avg stay in each roi - :param data: trackind data is a numpy array with shape (n_frames, 3) with data for X,Y position and Velocity + :param data: trackind data is a numpy array with shape (n_frames, 3) with data for X,Y position and Speed. If [n_frames, 2] + array is passed, speed is calculated automatically. :param rois: dictionary with the position of each roi. The position is stored in a named tuple with the location of two points defyining the roi: topleft(X,Y) and bottomright(X,Y). :param fps: framerate at which video was acquired - :return: dictionary + :param returndf: boolean, default False. If true data are returned as a DataFrame instead of dict. + :return: dictionary or dataframe # Testing >>> position = namedtuple('position', ['topleft', 'bottomright']) @@ -149,6 +163,14 @@ def get_timeinrois_stats(data, rois, fps=None): def get_indexes(lst, match): return np.asarray([i for i, x in enumerate(lst) if x == match]) + # Check arguments + if data.shape[1] == 2: # only X and Y tracking data passed, calculate speed + speed = calc_distance_between_points_in_a_vector_2d(data) + data = np.hstack((data, speed.reshape((len(speed), 1)))) + + elif data.shape[1] != 3: + raise ValueError("Tracking data should be passed as either an Nx2 or Nx3 array. Tracking data shape was: {}. Maybe you forgot to transpose the data?".format(data.shape)) + # get roi at each frame of data data_rois = get_roi_at_each_frame(data, rois) data_time_inrois = {name: data_rois.count(name) for name in set(data_rois)} # total time (frames) in each roi @@ -175,12 +197,26 @@ def get_indexes(lst, match): vels = data[indexes, 2] avg_vel_per_roi[name] = np.average(np.asarray(vels)) - results = dict(transitions_per_roi=transitions_count, - cumulative_time_in_roi=data_time_inrois, - cumulative_time_in_roi_sec=data_time_inrois_sec, - avg_time_in_roi=avg_time_in_roi, - avg_time_in_roi_sec=avg_time_in_roi_sec, - avg_vel_in_roi=avg_vel_per_roi) + + + if returndf: + roinames = sorted(list(data_time_inrois.keys())) + results = pd.DataFrame.from_dict({ + "ROI_name": roinames, + "transitions_per_roi": [transitions_count[r] for r in roinames], + "cumulative_time_in_roi": [data_time_inrois[r] for r in roinames], + "cumulative_time_in_roi_sec": [data_time_inrois_sec[r] for r in roinames], + "avg_time_in_roi": [avg_time_in_roi[r] for r in roinames], + "avg_time_in_roi_sec": [avg_time_in_roi_sec[r] for r in roinames], + "avg_vel_in_roi": [avg_vel_per_roi[r] for r in roinames], + }) + else: + results = dict(transitions_per_roi=transitions_count, + cumulative_time_in_roi=data_time_inrois, + cumulative_time_in_roi_sec=data_time_inrois_sec, + avg_time_in_roi=avg_time_in_roi, + avg_time_in_roi_sec=avg_time_in_roi_sec, + avg_vel_in_roi=avg_vel_per_roi) return results From 762a90be2b48f47047e1a4acb53c193e6f8f5249 Mon Sep 17 00:00:00 2001 From: federico claudi Date: Sat, 5 Oct 2019 08:55:31 +0100 Subject: [PATCH 13/37] roi name check --- time_in_each_roi.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/time_in_each_roi.py b/time_in_each_roi.py index ebbf4df..01dffde 100644 --- a/time_in_each_roi.py +++ b/time_in_each_roi.py @@ -171,6 +171,9 @@ def get_indexes(lst, match): elif data.shape[1] != 3: raise ValueError("Tracking data should be passed as either an Nx2 or Nx3 array. Tracking data shape was: {}. Maybe you forgot to transpose the data?".format(data.shape)) + if "none" in list(rois.keys()): + raise ValueError("No roi can have name 'none', that's reserved for the code to use, please use a different name for your rois.") + # get roi at each frame of data data_rois = get_roi_at_each_frame(data, rois) data_time_inrois = {name: data_rois.count(name) for name in set(data_rois)} # total time (frames) in each roi @@ -197,8 +200,6 @@ def get_indexes(lst, match): vels = data[indexes, 2] avg_vel_per_roi[name] = np.average(np.asarray(vels)) - - if returndf: roinames = sorted(list(data_time_inrois.keys())) results = pd.DataFrame.from_dict({ From dfa42b86146f6f314b98229275a868efb109caa5 Mon Sep 17 00:00:00 2001 From: Federico Claudi Date: Mon, 7 Oct 2019 17:01:04 +0100 Subject: [PATCH 14/37] Update test.py --- test.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/test.py b/test.py index a2b3b37..1f3ef59 100644 --- a/test.py +++ b/test.py @@ -14,9 +14,6 @@ pcutoff = 0.5 x, y = data[scorer][bps[1]]['x'].values.flatten(), data[scorer][bps[1]]['x'].values.flatten() -# get speed -speed = calc_distance_between_points_in_a_vector_2d(np.vstack([x, y]).T) - # define rois from collections import namedtuple position = namedtuple('position', ['topleft', 'bottomright']) From 8a0bfacdce98ff7ba31d8d7ecaff8c6e70870e52 Mon Sep 17 00:00:00 2001 From: federico claudi Date: Mon, 7 Oct 2019 19:40:06 +0100 Subject: [PATCH 15/37] added check_inroi param --- test.py | 30 ---------------------------- time_in_each_roi.py | 48 ++++++++++++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 44 deletions(-) delete mode 100644 test.py diff --git a/test.py b/test.py deleted file mode 100644 index a2b3b37..0000000 --- a/test.py +++ /dev/null @@ -1,30 +0,0 @@ -import pandas as pd -import os - -from time_in_each_roi import * - -# Get data -datafile = "/Users/federicoclaudi/Downloads/c190m615 b vs aDeepCut_resnet50_Network_Training_11Sep11shuffle1_1030000.h5" - -data = pd.read_hdf(datafile) -scorer = data.columns.get_level_values(0)[0] #you can read out the header to get the scorer name! -bps = sorted(list(set(data[scorer].columns.get_level_values(0)))) # get the bodyparts names - -# Get nose tracking data -pcutoff = 0.5 -x, y = data[scorer][bps[1]]['x'].values.flatten(), data[scorer][bps[1]]['x'].values.flatten() - -# get speed -speed = calc_distance_between_points_in_a_vector_2d(np.vstack([x, y]).T) - -# define rois -from collections import namedtuple -position = namedtuple('position', ['topleft', 'bottomright']) -bp_tracking = np.array((x, y)).T - -#two points defining each roi: topleft(X,Y) and bottomright(X,Y). -rois = {'Familiar': position((0, 0), (213.4, 126.76)),'Novel': position((273.5, 339), (480, 480))} -print(rois) - -# get results -print(get_timeinrois_stats(bp_tracking, rois, fps=16, returndf=True)) diff --git a/time_in_each_roi.py b/time_in_each_roi.py index 01dffde..464f7d3 100644 --- a/time_in_each_roi.py +++ b/time_in_each_roi.py @@ -78,7 +78,7 @@ def calc_distance_between_points_in_a_vector_2d(v1): return np.array(dist) -def get_roi_at_each_frame(bp_data, rois): +def get_roi_at_each_frame(bp_data, rois, check_inroi): """ Given position data for a bodypart and the position of a list of rois, this function calculates which roi is the closest to the bodypart at each frame @@ -86,6 +86,8 @@ def get_roi_at_each_frame(bp_data, rois): [as extracted by DeepLabCut] --> df.bodypart.values. :param rois: dictionary with the position of each roi. The position is stored in a named tuple with the location of two points defyining the roi: topleft(X,Y) and bottomright(X,Y). + :param check_inroi: boolean, default True. If true only counts frames in which the tracked point is inside of a ROI. + Otherwise at each frame it counts the closest ROI. :return: tuple, closest roi to the bodypart at each frame """ @@ -125,19 +127,22 @@ def sort_roi_points(roi): roi_at_each_frame = tuple([roi_names[x] for x in sel_rois]) # Check if the tracked point is actually in the closest ROI - cleaned_rois = [] - for i, roi in enumerate(roi_at_each_frame): - x,y = bp_data[i, 0], bp_data[i, 1] - X, Y = sort_roi_points(rois[roi]) # get x,y coordinates of roi points - if not X[0] <= x <= X[1] or not Y[0] <= y <= Y[1]: - cleaned_rois.append('none') - else: - cleaned_rois.append(roi) - - return cleaned_rois + if not check_inroi: + cleaned_rois = [] + for i, roi in enumerate(roi_at_each_frame): + x,y = bp_data[i, 0], bp_data[i, 1] + X, Y = sort_roi_points(rois[roi]) # get x,y coordinates of roi points + if not X[0] <= x <= X[1] or not Y[0] <= y <= Y[1]: + cleaned_rois.append('none') + else: + cleaned_rois.append(roi) + return cleaned_rois + else: + print("Warning: you've set check_inroi=False, so data reflect which ROI is closest even if tracked point is not in any given ROI.") + return roi_at_each_frame -def get_timeinrois_stats(data, rois, fps=None, returndf=False): +def get_timeinrois_stats(data, rois, fps=None, returndf=False, check_inroi=True): """ Quantify number of times the animal enters a roi, cumulative number of frames spend there, cumulative time in seconds spent in the roi and average velocity while in the roi. @@ -149,6 +154,9 @@ def get_timeinrois_stats(data, rois, fps=None, returndf=False): two points defyining the roi: topleft(X,Y) and bottomright(X,Y). :param fps: framerate at which video was acquired :param returndf: boolean, default False. If true data are returned as a DataFrame instead of dict. + :param check_inroi: boolean, default True. If true only counts frames in which the tracked point is inside of a ROI. + Otherwise at each frame it counts the closest ROI. + :return: dictionary or dataframe # Testing @@ -171,11 +179,15 @@ def get_indexes(lst, match): elif data.shape[1] != 3: raise ValueError("Tracking data should be passed as either an Nx2 or Nx3 array. Tracking data shape was: {}. Maybe you forgot to transpose the data?".format(data.shape)) - if "none" in list(rois.keys()): + roi_names = [k.lower() for k in list(rois.keys())] + if "none" in roi_names: raise ValueError("No roi can have name 'none', that's reserved for the code to use, please use a different name for your rois.") + if "tot" in roi_names: + raise ValueError("No roi can have name 'tot', that's reserved for the code to use, please use a different name for your rois.") + # get roi at each frame of data - data_rois = get_roi_at_each_frame(data, rois) + data_rois = get_roi_at_each_frame(data, rois, check_inroi) data_time_inrois = {name: data_rois.count(name) for name in set(data_rois)} # total time (frames) in each roi # number of enters in each roi @@ -200,6 +212,14 @@ def get_indexes(lst, match): vels = data[indexes, 2] avg_vel_per_roi[name] = np.average(np.asarray(vels)) + # get comulative + transitions_count['tot'] = np.sum(list(transitions_count.values())) + data_time_inrois['tot'] = np.sum(list(data_time_inrois.values())) + data_time_inrois_sec['tot'] = np.sum(list(data_time_inrois_sec.values())) + avg_time_in_roi['tot'] = np.sum(list(avg_time_in_roi.values())) + avg_time_in_roi_sec['tot'] = np.sum(list(avg_time_in_roi_sec.values())) + avg_vel_per_roi['tot'] = np.sum(list(avg_vel_per_roi.values())) + if returndf: roinames = sorted(list(data_time_inrois.keys())) results = pd.DataFrame.from_dict({ From 10be75b1421811eb95453f83b8cffec732541e4c Mon Sep 17 00:00:00 2001 From: Mackenzie Mathis Date: Thu, 10 Oct 2019 15:19:27 -0400 Subject: [PATCH 16/37] Update README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 05f9a4b..801b791 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,14 @@ https://github.com/AlexEMG/DLCutils/tree/master/DLC_2_MotionMapper Contributed by [Mackenzie Mathis](https://github.com/MMathisLab) +## Behavior clustering with B-SOiD + +B-SOiD: An Open Source Unsupervised Algorithm for Discovery of Spontaneous Behaviors <-- use the outputs of DLC to feed directly into B-SOiD (in MATLAB). + +paper: https://www.biorxiv.org/content/10.1101/770271v1.abstract + +code: https://github.com/YttriLab/B-SOiD + ## Using DeepLabCut for USB-CGPIO feedback paper: https://www.biorxiv.org/content/early/2018/11/28/482349 From df368b6d49a8ce1aa31ff50bb5064cd55e17b711 Mon Sep 17 00:00:00 2001 From: Mackenzie Mathis Date: Thu, 10 Oct 2019 15:27:08 -0400 Subject: [PATCH 17/37] Update README.md --- README.md | 70 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 801b791..35fbaa8 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,24 @@ [![Image.sc forum](https://img.shields.io/badge/dynamic/json.svg?label=forum&url=https%3A%2F%2Fforum.image.sc%2Ftags%2Fdeeplabcut.json&query=%24.topic_list.tags.0.topic_count&colorB=brightgreen&&suffix=%20topics&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAABPklEQVR42m3SyyqFURTA8Y2BER0TDyExZ+aSPIKUlPIITFzKeQWXwhBlQrmFgUzMMFLKZeguBu5y+//17dP3nc5vuPdee6299gohUYYaDGOyyACq4JmQVoFujOMR77hNfOAGM+hBOQqB9TjHD36xhAa04RCuuXeKOvwHVWIKL9jCK2bRiV284QgL8MwEjAneeo9VNOEaBhzALGtoRy02cIcWhE34jj5YxgW+E5Z4iTPkMYpPLCNY3hdOYEfNbKYdmNngZ1jyEzw7h7AIb3fRTQ95OAZ6yQpGYHMMtOTgouktYwxuXsHgWLLl+4x++Kx1FJrjLTagA77bTPvYgw1rRqY56e+w7GNYsqX6JfPwi7aR+Y5SA+BXtKIRfkfJAYgj14tpOF6+I46c4/cAM3UhM3JxyKsxiOIhH0IO6SH/A1Kb1WBeUjbkAAAAAElFTkSuQmCC)](https://forum.image.sc/tags/deeplabcut) -# DeepLabCut-Utils -Various scripts to support [DeepLabCut](https://github.com/AlexEMG/DeepLabCut). Feel free to contribute your own analysis methods, and perhaps some short notebook of how to use it. Thanks! - - -## Example scripts for automation of anlysis & training - -These two scripts illustrate how to train, test and analyze videos for multiple projects automatically (scale_raining_and_evaluation.py) and -how to analyze videos that are organized in subfolders automatically (scale_analysis_oversubfolders.py). Feel free to adjust them for your needs! - -https://github.com/AlexEMG/DLCutils/blob/master/scale_analysis_oversubfolders.py -https://github.com/AlexEMG/DLCutils/blob/master/scale_raining_and_evaluation.py +[![PyPI version](https://badge.fury.io/py/deeplabcut.svg)](https://badge.fury.io/py/deeplabcut) +[![PyPI - Downloads](https://img.shields.io/pypi/dm/deeplabcut.svg?color=purple&label=PyPi)](https://pypistats.org/packages/deeplabcut) +[![GitHub stars](https://img.shields.io/github/stars/AlexEMG/DeepLabCut.svg?style=social&label=Star)](https://github.com/AlexEMG/DeepLabCut) -Contributed by [Alexander Mathis](https://github.com/AlexEMG) - - - -## DLC1 to DLC 2 conversion code - -This code allows you to import the labeled data from DLC 1 to DLC 2 projects. Note, it is not streamlined and should be used with care. -https://github.com/AlexEMG/DLCutils/blob/master/convertDLC1TO2.py +# DeepLabCut-Utils DLC Utils -Contributed by [Alexander Mathis](https://github.com/AlexEMG) +# DeepLabCut-Utils +Various scripts to support [DeepLabCut](https://github.com/AlexEMG/DeepLabCut). Feel free to contribute your own analysis methods, and perhaps some short notebook of how to use it. Thanks! -## Running project created on Windows on Colaboratory -#UPDATE: as of Deeplabcut 2.0.4 onwards you no longer need to use this code! You can simply create the training set on the cloud and it will automatically convert your project for you. - - This solves a path problem when creating a project and annotating data on Windows (see https://github.com/AlexEMG/DeepLabCut/issues/172). This functionality will be included in -a later version of DLC 2 (DONE!) -https://github.com/AlexEMG/DLCutils/blob/master/convertWin2Unix.py -*Usage:* change in lines 70 and 71 of https://github.com/AlexEMG/DLCutils/blob/master/convertWin2Unix.py -```basepath='/content/drive/My Drive/DeepLabCut/examples/'``` +## Example scripts for automation of anlysis & training -```projectname='Reaching-Mackenzie-2018-08-30'``` +These two scripts illustrate how to train, test, and analyze videos for multiple projects automatically (scale_raining_and_evaluation.py) and how to analyze videos that are organized in subfolders automatically (scale_analysis_oversubfolders.py). Feel free to adjust them for your needs! -then run this script on colaboratory after uploading your labeled data to the drive. Thereby it will be converted -to unix format, then create a training set (with deeplabcut) and proceed as usual... +https://github.com/AlexEMG/DLCutils/blob/master/scale_analysis_oversubfolders.py +https://github.com/AlexEMG/DLCutils/blob/master/scale_training_and_evaluation.py Contributed by [Alexander Mathis](https://github.com/AlexEMG) @@ -81,5 +61,35 @@ maintainer: [Pierre Karashchuk](https://github.com/lambdaloop) - Please see the README.txt file https://github.com/AlexEMG/DLCutils/tree/master/pupilTracking for details; this code makes the video in case study 7 http://www.mousemotorlab.org/deeplabcut/. +## Older utility functions: + +## DLC1 to DLC 2 conversion code + +This code allows you to import the labeled data from DLC 1 to DLC 2 projects. Note, it is not streamlined and should be used with care. + +https://github.com/AlexEMG/DLCutils/blob/master/convertDLC1TO2.py + +Contributed by [Alexander Mathis](https://github.com/AlexEMG) + +## Running project created on Windows on Colaboratory +#UPDATE: as of Deeplabcut 2.0.4 onwards you no longer need to use this code! You can simply create the training set on the cloud and it will automatically convert your project for you. + + - This solves a path problem when creating a project and annotating data on Windows (see https://github.com/AlexEMG/DeepLabCut/issues/172). This functionality will be included in +a later version of DLC 2 (DONE!) +https://github.com/AlexEMG/DLCutils/blob/master/convertWin2Unix.py + +*Usage:* change in lines 70 and 71 of https://github.com/AlexEMG/DLCutils/blob/master/convertWin2Unix.py + +```basepath='/content/drive/My Drive/DeepLabCut/examples/'``` + +```projectname='Reaching-Mackenzie-2018-08-30'``` + +then run this script on colaboratory after uploading your labeled data to the drive. Thereby it will be converted +to unix format, then create a training set (with deeplabcut) and proceed as usual... + +Contributed by [Alexander Mathis](https://github.com/AlexEMG) + + + Please direct inquires to the **contributors/code-maintainers of that code**. Note that the software(s) are provided "as is", without warranty of any kind, express or implied. From adf551903a79683b6ffe9f4d42b18f7662d6939a Mon Sep 17 00:00:00 2001 From: Mackenzie Mathis Date: Thu, 10 Oct 2019 15:27:23 -0400 Subject: [PATCH 18/37] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 35fbaa8..8f504ed 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ # DeepLabCut-Utils DLC Utils -# DeepLabCut-Utils Various scripts to support [DeepLabCut](https://github.com/AlexEMG/DeepLabCut). Feel free to contribute your own analysis methods, and perhaps some short notebook of how to use it. Thanks! From d7cc2428cfb84b6c5f4a312d4f7b6186cea4cbb2 Mon Sep 17 00:00:00 2001 From: Mackenzie Mathis Date: Mon, 14 Oct 2019 22:32:28 -0400 Subject: [PATCH 19/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f504ed..4376427 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Various scripts to support [DeepLabCut](https://github.com/AlexEMG/DeepLabCut). -## Example scripts for automation of anlysis & training +## Example scripts for automation of analysis & training These two scripts illustrate how to train, test, and analyze videos for multiple projects automatically (scale_raining_and_evaluation.py) and how to analyze videos that are organized in subfolders automatically (scale_analysis_oversubfolders.py). Feel free to adjust them for your needs! From ef62acf0c819b55718f5153733650a8dc01afa4e Mon Sep 17 00:00:00 2001 From: Mackenzie Mathis Date: Sun, 10 Nov 2019 19:05:53 -0500 Subject: [PATCH 20/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4376427..279c86b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![GitHub stars](https://img.shields.io/github/stars/AlexEMG/DeepLabCut.svg?style=social&label=Star)](https://github.com/AlexEMG/DeepLabCut) -# DeepLabCut-Utils DLC Utils +# DeepLabCut-Utils DLC Utils Various scripts to support [DeepLabCut](https://github.com/AlexEMG/DeepLabCut). Feel free to contribute your own analysis methods, and perhaps some short notebook of how to use it. Thanks! From 213664d8dadfcecc23a7243aabef8f61bada9d39 Mon Sep 17 00:00:00 2001 From: AlexEMG Date: Thu, 14 Nov 2019 19:54:08 -0500 Subject: [PATCH 21/37] Colormaps from Gordon Berman Thx! --- DLC_2_MotionMapper/saved_colormaps.mat | Bin 0 -> 2859 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 DLC_2_MotionMapper/saved_colormaps.mat diff --git a/DLC_2_MotionMapper/saved_colormaps.mat b/DLC_2_MotionMapper/saved_colormaps.mat new file mode 100644 index 0000000000000000000000000000000000000000..a58b2174ff62fdae6e3f27197cdbf8e28f4b5062 GIT binary patch literal 2859 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 pH0 Date: Sat, 8 Feb 2020 10:55:54 -0500 Subject: [PATCH 22/37] link to dlcanalyzer --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 279c86b..bc5a80c 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,14 @@ https://github.com/AlexEMG/DLCutils/blob/master/time_in_each_roi.py Contributed by [Federico Claudi](https://github.com/FedeClaudi) +## Behavior Analysis with R (ETH-DLCAnalyzer) + +Deep learning based behavioral analysis enables high precision rodent tracking and is capable of outperforming commercial solutions. Oliver Sturman, Lukas von Ziegler, Christa Schläppi, Furkan Akyol, Benjamin Grewe, Johannes Bohacek + +paper: https://www.biorxiv.org/content/10.1101/2020.01.21.913624v1 + +code: https://github.com/ETHZ-INS/DLCAnalyzer + ## Behavior clustering with MotionMapper - (adpated from https://github.com/gordonberman/MotionMapper) From 1268c76a4e78267d00a622c87e369b5bd4fc476f Mon Sep 17 00:00:00 2001 From: AlexEMG Date: Sat, 29 Feb 2020 17:39:53 -0500 Subject: [PATCH 23/37] Code of conduct and contribute --- CODE_OF_CONDUCT.md | 76 ++++++++++++++++++++++++++++++++++++++++++++++ contribute.md | 9 ++++++ 2 files changed, 85 insertions(+) create mode 100644 CODE_OF_CONDUCT.md create mode 100644 contribute.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..f4396c3 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at alexander.mathis@bethgelab.org. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/contribute.md b/contribute.md new file mode 100644 index 0000000..85809ad --- /dev/null +++ b/contribute.md @@ -0,0 +1,9 @@ +# How to Contribute to DeepLabCut utils? + +DeepLabCut utils is library to collect useful scripts, software and other packages that are related to https://github.com/AlexEMG/DeepLabCut. + +We welcome community involvement and are happy to receive code extensions, bug fixes, documentation updates etc. + +If you want to contribute to the code, please make a [pull request](https://github.com/AlexEMG/DLCutils/pull/new/) that includes what new functionality you added or what you edited. + + From 95589bc4c8c446e3a00edd05b3bcd07cb900c0f2 Mon Sep 17 00:00:00 2001 From: AlexEMG Date: Sat, 29 Feb 2020 17:59:58 -0500 Subject: [PATCH 24/37] Fixed links --- README.md | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index bc5a80c..86e9d81 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![Image.sc forum](https://img.shields.io/badge/dynamic/json.svg?label=forum&url=https%3A%2F%2Fforum.image.sc%2Ftags%2Fdeeplabcut.json&query=%24.topic_list.tags.0.topic_count&colorB=brightgreen&&suffix=%20topics&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAABPklEQVR42m3SyyqFURTA8Y2BER0TDyExZ+aSPIKUlPIITFzKeQWXwhBlQrmFgUzMMFLKZeguBu5y+//17dP3nc5vuPdee6299gohUYYaDGOyyACq4JmQVoFujOMR77hNfOAGM+hBOQqB9TjHD36xhAa04RCuuXeKOvwHVWIKL9jCK2bRiV284QgL8MwEjAneeo9VNOEaBhzALGtoRy02cIcWhE34jj5YxgW+E5Z4iTPkMYpPLCNY3hdOYEfNbKYdmNngZ1jyEzw7h7AIb3fRTQ95OAZ6yQpGYHMMtOTgouktYwxuXsHgWLLl+4x++Kx1FJrjLTagA77bTPvYgw1rRqY56e+w7GNYsqX6JfPwi7aR+Y5SA+BXtKIRfkfJAYgj14tpOF6+I46c4/cAM3UhM3JxyKsxiOIhH0IO6SH/A1Kb1WBeUjbkAAAAAElFTkSuQmCC)](https://forum.image.sc/tags/deeplabcut) +[![Image.sc forum](https://img.shields.io/badge/dynamic/json.svg?label=forum&url=https%3A%2F%2Fforum.image.sc%2Ftags%2Fdeeplabcut.json&query=%24.topic_list.tags.0.topic_count&colorB=brightgreen&&suffix=%20topics&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAABPklEQVR42m3SyyqFURTA8Y2BER0TDyExZ+aSPIKUlPIITFzKeQWXwhBlQrmFgUzMMFLKZeguBu5y+//17dP3nc5vuPdee6299gohUYYaDGOyyACq4JmQVoFujOMR77hNfOAGM+hBOQqB9TjHD36xhAa04RCuuXeKOvwHVWIKL9jCK2bRiV284QgL8MwEjAneeo9VNOEaBhzALGtoRy02cIcWhE34jj5YxgW+E5Z4iTPkMYpPLCNY3hdOYEfNbKYdmNngZ1jyEzw7h7AIb3fRTQ95OAZ6yQpGYHMMtOTgouktYwxuXsHgWLLl+4x++Kx1FJrjLTagA77bTPvYgw1rRqY56e+w7GNYsqX6JfPwi7aR+Y5SA+BXtKIRfkfJAYgj14tpOF6+I46c4/cAM3UhM3JxyKsxiOIhH0IO6SH/A1Kb1WBeUjbkAAAAAElFTkSuQmCC)](https://forum.image.sc/tags/deeplabcut) [![PyPI version](https://badge.fury.io/py/deeplabcut.svg)](https://badge.fury.io/py/deeplabcut) [![PyPI - Downloads](https://img.shields.io/pypi/dm/deeplabcut.svg?color=purple&label=PyPi)](https://pypistats.org/packages/deeplabcut) [![GitHub stars](https://img.shields.io/github/stars/AlexEMG/DeepLabCut.svg?style=social&label=Star)](https://github.com/AlexEMG/DeepLabCut) @@ -7,23 +7,21 @@ # DeepLabCut-Utils DLC Utils -Various scripts to support [DeepLabCut](https://github.com/AlexEMG/DeepLabCut). Feel free to contribute your own analysis methods, and perhaps some short notebook of how to use it. Thanks! - - +This repository contains various scripts as well as links to other packages related to [DeepLabCut](https://github.com/AlexEMG/DeepLabCut). Feel free to contribute your own analysis methods, and perhaps some short notebook of how to use it. Thanks! ## Example scripts for automation of analysis & training These two scripts illustrate how to train, test, and analyze videos for multiple projects automatically (scale_raining_and_evaluation.py) and how to analyze videos that are organized in subfolders automatically (scale_analysis_oversubfolders.py). Feel free to adjust them for your needs! -https://github.com/AlexEMG/DLCutils/blob/master/scale_analysis_oversubfolders.py -https://github.com/AlexEMG/DLCutils/blob/master/scale_training_and_evaluation.py +https://github.com/DeepLabCut/DLCutils/blob/master/scale_analysis_oversubfolders.py +https://github.com/DeepLabCut/DLCutils/blob/master/scale_training_and_evaluation.py Contributed by [Alexander Mathis](https://github.com/AlexEMG) ## Time spent of a body part in a particular region of interest (ROI) -https://github.com/AlexEMG/DLCutils/blob/master/time_in_each_roi.py +https://github.com/DeepLabCut/DLCutils/blob/master/time_in_each_roi.py Contributed by [Federico Claudi](https://github.com/FedeClaudi) @@ -35,23 +33,23 @@ paper: https://www.biorxiv.org/content/10.1101/2020.01.21.913624v1 code: https://github.com/ETHZ-INS/DLCAnalyzer -## Behavior clustering with MotionMapper +## Behavior clustering with MotionMapper - (adpated from https://github.com/gordonberman/MotionMapper) -https://github.com/AlexEMG/DLCutils/tree/master/DLC_2_MotionMapper +https://github.com/DeepLabCut/DLCutils/tree/master/DLC_2_MotionMapper Contributed by [Mackenzie Mathis](https://github.com/MMathisLab) ## Behavior clustering with B-SOiD -B-SOiD: An Open Source Unsupervised Algorithm for Discovery of Spontaneous Behaviors <-- use the outputs of DLC to feed directly into B-SOiD (in MATLAB). +B-SOiD: An Open Source Unsupervised Algorithm for Discovery of Spontaneous Behaviors <-- use the outputs of DLC to feed directly into B-SOiD (in MATLAB). paper: https://www.biorxiv.org/content/10.1101/770271v1.abstract code: https://github.com/YttriLab/B-SOiD -## Using DeepLabCut for USB-CGPIO feedback +## Using DeepLabCut for USB-CGPIO feedback paper: https://www.biorxiv.org/content/early/2018/11/28/482349 code: https://github.com/bf777/DeepCutRealTime @@ -63,31 +61,31 @@ code: https://github.com/lambdaloop/anipose maintainer: [Pierre Karashchuk](https://github.com/lambdaloop) -## Pupil Tracking +## Pupil Tracking - From Tom Vaissie - tvaissie@scripps.edu -- Please see the README.txt file https://github.com/AlexEMG/DLCutils/tree/master/pupilTracking for details; this code makes the video in case study 7 http://www.mousemotorlab.org/deeplabcut/. +- Please see the README.txt file https://github.com/DeepLabCut/DLCutils/tree/master/pupilTracking for details; this code makes the video in case study 7 http://www.mousemotorlab.org/deeplabcut/. -## Older utility functions: +## Olderutility functions: ## DLC1 to DLC 2 conversion code This code allows you to import the labeled data from DLC 1 to DLC 2 projects. Note, it is not streamlined and should be used with care. -https://github.com/AlexEMG/DLCutils/blob/master/convertDLC1TO2.py +https://github.com/DeepLabCut/DLCutils/blob/master/convertDLC1TO2.py Contributed by [Alexander Mathis](https://github.com/AlexEMG) ## Running project created on Windows on Colaboratory -#UPDATE: as of Deeplabcut 2.0.4 onwards you no longer need to use this code! You can simply create the training set on the cloud and it will automatically convert your project for you. +#UPDATE: as of Deeplabcut 2.0.4 onwards you no longer need to use this code! You can simply create the training set on the cloud and it will automatically convert your project for you. - - This solves a path problem when creating a project and annotating data on Windows (see https://github.com/AlexEMG/DeepLabCut/issues/172). This functionality will be included in + - This solves a path problem when creating a project and annotating data on Windows (see https://github.com/AlexEMG/DeepLabCut/issues/172). This functionality will be included in a later version of DLC 2 (DONE!) -https://github.com/AlexEMG/DLCutils/blob/master/convertWin2Unix.py +https://github.com/DeepLabCut/DLCutils/blob/master/convertWin2Unix.py -*Usage:* change in lines 70 and 71 of https://github.com/AlexEMG/DLCutils/blob/master/convertWin2Unix.py +*Usage:* change in lines 70 and 71 of https://github.com/DeepLabCut/DLCutils/blob/master/convertWin2Unix.py -```basepath='/content/drive/My Drive/DeepLabCut/examples/'``` +```basepath='/content/drive/My Drive/DeepLabCut/examples/'``` ```projectname='Reaching-Mackenzie-2018-08-30'``` @@ -99,4 +97,3 @@ Contributed by [Alexander Mathis](https://github.com/AlexEMG) Please direct inquires to the **contributors/code-maintainers of that code**. Note that the software(s) are provided "as is", without warranty of any kind, express or implied. - From eb278a19b41dd261282f3cd989ed4373251c5ebc Mon Sep 17 00:00:00 2001 From: Mackenzie Mathis Date: Sat, 29 Feb 2020 18:26:36 -0500 Subject: [PATCH 25/37] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 86e9d81..1599a89 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ maintainer: [Pierre Karashchuk](https://github.com/lambdaloop) - Please see the README.txt file https://github.com/DeepLabCut/DLCutils/tree/master/pupilTracking for details; this code makes the video in case study 7 http://www.mousemotorlab.org/deeplabcut/. -## Olderutility functions: +## Older utility functions (no longer required in DLC 2+): ## DLC1 to DLC 2 conversion code From 5a67498b385b41006ff3a9bf9f457c8be189cd82 Mon Sep 17 00:00:00 2001 From: MMathisLab Date: Sun, 8 Mar 2020 17:20:29 -0400 Subject: [PATCH 26/37] refactoring for clarity --- .../scale_analysis_oversubfolders.py | 0 .../scale_training_and_evaluation.py | 0 convertDLC1TO2.py => conversion_scripts_LEGACY/convertDLC1TO2.py | 0 .../convertWin2Unix.py | 0 dlc_ubuntu18.yml => ubuntu_install_helper_files/dlc_ubuntu18.yml | 0 .../installDLCandAnaconda.sh | 0 testDLC.py => ubuntu_install_helper_files/testDLC.py | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename scale_analysis_oversubfolders.py => SCALE_YOUR_ANALYSIS/scale_analysis_oversubfolders.py (100%) rename scale_training_and_evaluation.py => SCALE_YOUR_ANALYSIS/scale_training_and_evaluation.py (100%) rename convertDLC1TO2.py => conversion_scripts_LEGACY/convertDLC1TO2.py (100%) rename convertWin2Unix.py => conversion_scripts_LEGACY/convertWin2Unix.py (100%) rename dlc_ubuntu18.yml => ubuntu_install_helper_files/dlc_ubuntu18.yml (100%) rename installDLCandAnaconda.sh => ubuntu_install_helper_files/installDLCandAnaconda.sh (100%) rename testDLC.py => ubuntu_install_helper_files/testDLC.py (100%) diff --git a/scale_analysis_oversubfolders.py b/SCALE_YOUR_ANALYSIS/scale_analysis_oversubfolders.py similarity index 100% rename from scale_analysis_oversubfolders.py rename to SCALE_YOUR_ANALYSIS/scale_analysis_oversubfolders.py diff --git a/scale_training_and_evaluation.py b/SCALE_YOUR_ANALYSIS/scale_training_and_evaluation.py similarity index 100% rename from scale_training_and_evaluation.py rename to SCALE_YOUR_ANALYSIS/scale_training_and_evaluation.py diff --git a/convertDLC1TO2.py b/conversion_scripts_LEGACY/convertDLC1TO2.py similarity index 100% rename from convertDLC1TO2.py rename to conversion_scripts_LEGACY/convertDLC1TO2.py diff --git a/convertWin2Unix.py b/conversion_scripts_LEGACY/convertWin2Unix.py similarity index 100% rename from convertWin2Unix.py rename to conversion_scripts_LEGACY/convertWin2Unix.py diff --git a/dlc_ubuntu18.yml b/ubuntu_install_helper_files/dlc_ubuntu18.yml similarity index 100% rename from dlc_ubuntu18.yml rename to ubuntu_install_helper_files/dlc_ubuntu18.yml diff --git a/installDLCandAnaconda.sh b/ubuntu_install_helper_files/installDLCandAnaconda.sh similarity index 100% rename from installDLCandAnaconda.sh rename to ubuntu_install_helper_files/installDLCandAnaconda.sh diff --git a/testDLC.py b/ubuntu_install_helper_files/testDLC.py similarity index 100% rename from testDLC.py rename to ubuntu_install_helper_files/testDLC.py From 51fb99624f4284d6522c90e9765c581c8d7061d5 Mon Sep 17 00:00:00 2001 From: Mackenzie Mathis Date: Sun, 8 Mar 2020 17:27:54 -0400 Subject: [PATCH 27/37] Update README.md --- README.md | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 1599a89..b6dabc2 100644 --- a/README.md +++ b/README.md @@ -14,16 +14,28 @@ This repository contains various scripts as well as links to other packages rela These two scripts illustrate how to train, test, and analyze videos for multiple projects automatically (scale_raining_and_evaluation.py) and how to analyze videos that are organized in subfolders automatically (scale_analysis_oversubfolders.py). Feel free to adjust them for your needs! -https://github.com/DeepLabCut/DLCutils/blob/master/scale_analysis_oversubfolders.py -https://github.com/DeepLabCut/DLCutils/blob/master/scale_training_and_evaluation.py +https://github.com/DeepLabCut/DLCutils/tree/master/SCALE_YOUR_ANALYSIS/scale_analysis_oversubfolders.py +https://github.com/DeepLabCut/DLCutils/blob/master/SCALE_YOUR_ANALYSIS/scale_training_and_evaluation.py Contributed by [Alexander Mathis](https://github.com/AlexEMG) ## Time spent of a body part in a particular region of interest (ROI) +You can compute time spent in particular ROIs in frames. This demo Jupyer Notebook shows you how to load the outputs of DLC and perform the analysis (plus other plotting functions): + +https://github.com/DeepLabCut/DLCutils/blob/master/Demo_loadandanalyzeDLCdata.ipynb + https://github.com/DeepLabCut/DLCutils/blob/master/time_in_each_roi.py -Contributed by [Federico Claudi](https://github.com/FedeClaudi) +Contributed by [Federico Claudi](https://github.com/FedeClaudi) and Jupyter Notebok from [Alexander Mathis](https://github.com/AlexEMG) + +## Behavior clustering with MotionMapper +- (adpated from https://github.com/gordonberman/MotionMapper) + +https://github.com/DeepLabCut/DLCutils/tree/master/DLC_2_MotionMapper + +Contributed by [Mackenzie Mathis](https://github.com/MMathisLab) + ## Behavior Analysis with R (ETH-DLCAnalyzer) @@ -33,12 +45,6 @@ paper: https://www.biorxiv.org/content/10.1101/2020.01.21.913624v1 code: https://github.com/ETHZ-INS/DLCAnalyzer -## Behavior clustering with MotionMapper -- (adpated from https://github.com/gordonberman/MotionMapper) - -https://github.com/DeepLabCut/DLCutils/tree/master/DLC_2_MotionMapper - -Contributed by [Mackenzie Mathis](https://github.com/MMathisLab) ## Behavior clustering with B-SOiD @@ -66,13 +72,13 @@ maintainer: [Pierre Karashchuk](https://github.com/lambdaloop) - Please see the README.txt file https://github.com/DeepLabCut/DLCutils/tree/master/pupilTracking for details; this code makes the video in case study 7 http://www.mousemotorlab.org/deeplabcut/. -## Older utility functions (no longer required in DLC 2+): +## LEGACY utility functions (no longer required in DLC 2+): ## DLC1 to DLC 2 conversion code This code allows you to import the labeled data from DLC 1 to DLC 2 projects. Note, it is not streamlined and should be used with care. -https://github.com/DeepLabCut/DLCutils/blob/master/convertDLC1TO2.py +https://github.com/DeepLabCut/DLCutils/tree/master/conversion_scripts_LEGACY Contributed by [Alexander Mathis](https://github.com/AlexEMG) @@ -81,9 +87,9 @@ Contributed by [Alexander Mathis](https://github.com/AlexEMG) - This solves a path problem when creating a project and annotating data on Windows (see https://github.com/AlexEMG/DeepLabCut/issues/172). This functionality will be included in a later version of DLC 2 (DONE!) -https://github.com/DeepLabCut/DLCutils/blob/master/convertWin2Unix.py +https://github.com/DeepLabCut/DLCutils/tree/master/conversion_scripts_LEGACY -*Usage:* change in lines 70 and 71 of https://github.com/DeepLabCut/DLCutils/blob/master/convertWin2Unix.py +*Usage:* change in lines 70 and 71 of https://github.com/DeepLabCut/DLCutils/tree/master/conversion_scripts_LEGACY/convertWin2Unix.py ```basepath='/content/drive/My Drive/DeepLabCut/examples/'``` From 728bbdfb0754c61bb08e9084490a79c33899e500 Mon Sep 17 00:00:00 2001 From: Mackenzie Mathis Date: Mon, 16 Mar 2020 11:35:30 -0400 Subject: [PATCH 28/37] added DLT code link --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index b6dabc2..366ed32 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,14 @@ https://github.com/DeepLabCut/DLCutils/tree/master/DLC_2_MotionMapper Contributed by [Mackenzie Mathis](https://github.com/MMathisLab) +## 3D reconstruction with EasyWand/Argus DLT system with DeepLabCut data: + +Written by [Brandon Jackson](https://github.com/haliaetus13), post our DLC workshop in Jan 2020: + +A small set of utilities that allow conversion between the data storage formats of DeepLabCut (DLC) and one of the DLT-based 3D tracking systems: either Ty Hedrick's DigitizingTools in MATLAB, or the Python-based Argus. These functions should allow you to use data previously digitized in a DLT system to create the files needed to train a DLC model, and to import DLC-tracked points back into a DLT 3D calibration to reconstruct 3D points. + +code: https://github.com/haliaetus13/DLCconverterDLT + ## Behavior Analysis with R (ETH-DLCAnalyzer) From 60edc2f09c441cb2f3e2fb95d27e6535cfc499ee Mon Sep 17 00:00:00 2001 From: Mackenzie Mathis Date: Fri, 27 Mar 2020 22:58:10 -0400 Subject: [PATCH 29/37] updated notebook --- Demo_loadandanalyzeDLCdata.ipynb | 4921 +----------------------------- 1 file changed, 129 insertions(+), 4792 deletions(-) diff --git a/Demo_loadandanalyzeDLCdata.ipynb b/Demo_loadandanalyzeDLCdata.ipynb index 751c37e..955fc1d 100644 --- a/Demo_loadandanalyzeDLCdata.ipynb +++ b/Demo_loadandanalyzeDLCdata.ipynb @@ -14,7 +14,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": { "colab": {}, "colab_type": "code", @@ -32,7 +32,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": { "colab": {}, "colab_type": "code", @@ -52,7 +52,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -210,7 +210,7 @@ "4 150.296287 170.733274 0.999970 " ] }, - "execution_count": 3, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -224,7 +224,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": { "colab": {}, "colab_type": "code", @@ -241,7 +241,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -324,4033 +324,133 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": { "scrolled": false }, "outputs": [ { "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "window.mpl = {};\n", - "\n", - "\n", - "mpl.get_websocket_type = function() {\n", - " if (typeof(WebSocket) !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof(MozWebSocket) !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert('Your browser does not have WebSocket support.' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.');\n", - " };\n", - "}\n", - "\n", - "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = (this.ws.binaryType != undefined);\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById(\"mpl-warnings\");\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent = (\n", - " \"This browser does not support binary websocket messages. \" +\n", - " \"Performance may be slow.\");\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = $('

');\n", - " this._root_extra_style(this.root)\n", - " this.root.attr('style', 'display: inline-block');\n", - "\n", - " $(parent_element).append(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", - " fig.send_message(\"send_image_mode\", {});\n", - " if (mpl.ratio != 1) {\n", - " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", - " }\n", - " fig.send_message(\"refresh\", {});\n", - " }\n", - "\n", - " this.imageObj.onload = function() {\n", - " if (fig.image_mode == 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function() {\n", - " fig.ws.close();\n", - " }\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "}\n", - "\n", - "mpl.figure.prototype._init_header = function() {\n", - " var titlebar = $(\n", - " '
');\n", - " var titletext = $(\n", - " '
');\n", - " titlebar.append(titletext)\n", - " this.root.append(titlebar);\n", - " this.header = titletext[0];\n", - "}\n", - "\n", - "\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._init_canvas = function() {\n", - " var fig = this;\n", - "\n", - " var canvas_div = $('
');\n", - "\n", - " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", - "\n", - " function canvas_keyboard_event(event) {\n", - " return fig.key_event(event, event['data']);\n", - " }\n", - "\n", - " canvas_div.keydown('key_press', canvas_keyboard_event);\n", - " canvas_div.keyup('key_release', canvas_keyboard_event);\n", - " this.canvas_div = canvas_div\n", - " this._canvas_extra_style(canvas_div)\n", - " this.root.append(canvas_div);\n", - "\n", - " var canvas = $('');\n", - " canvas.addClass('mpl-canvas');\n", - " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", - "\n", - " this.canvas = canvas[0];\n", - " this.context = canvas[0].getContext(\"2d\");\n", - "\n", - " var backingStore = this.context.backingStorePixelRatio ||\n", - "\tthis.context.webkitBackingStorePixelRatio ||\n", - "\tthis.context.mozBackingStorePixelRatio ||\n", - "\tthis.context.msBackingStorePixelRatio ||\n", - "\tthis.context.oBackingStorePixelRatio ||\n", - "\tthis.context.backingStorePixelRatio || 1;\n", - "\n", - " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband = $('');\n", - " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", - "\n", - " var pass_mouse_events = true;\n", - "\n", - " canvas_div.resizable({\n", - " start: function(event, ui) {\n", - " pass_mouse_events = false;\n", - " },\n", - " resize: function(event, ui) {\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " stop: function(event, ui) {\n", - " pass_mouse_events = true;\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " });\n", - "\n", - " function mouse_event_fn(event) {\n", - " if (pass_mouse_events)\n", - " return fig.mouse_event(event, event['data']);\n", - " }\n", - "\n", - " rubberband.mousedown('button_press', mouse_event_fn);\n", - " rubberband.mouseup('button_release', mouse_event_fn);\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband.mousemove('motion_notify', mouse_event_fn);\n", - "\n", - " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", - " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", - "\n", - " canvas_div.on(\"wheel\", function (event) {\n", - " event = event.originalEvent;\n", - " event['data'] = 'scroll'\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " mouse_event_fn(event);\n", - " });\n", - "\n", - " canvas_div.append(canvas);\n", - " canvas_div.append(rubberband);\n", - "\n", - " this.rubberband = rubberband;\n", - " this.rubberband_canvas = rubberband[0];\n", - " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", - " this.rubberband_context.strokeStyle = \"#000000\";\n", - "\n", - " this._resize_canvas = function(width, height) {\n", - " // Keep the size of the canvas, canvas container, and rubber band\n", - " // canvas in synch.\n", - " canvas_div.css('width', width)\n", - " canvas_div.css('height', height)\n", - "\n", - " canvas.attr('width', width * mpl.ratio);\n", - " canvas.attr('height', height * mpl.ratio);\n", - " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", - "\n", - " rubberband.attr('width', width);\n", - " rubberband.attr('height', height);\n", - " }\n", - "\n", - " // Set the figure to an initial 600x600px, this will subsequently be updated\n", - " // upon first draw.\n", - " this._resize_canvas(600, 600);\n", - "\n", - " // Disable right mouse context menu.\n", - " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", - " return false;\n", - " });\n", - "\n", - " function set_focus () {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "}\n", - "\n", - "mpl.figure.prototype._init_toolbar = function() {\n", - " var fig = this;\n", - "\n", - " var nav_element = $('
')\n", - " nav_element.attr('style', 'width: 100%');\n", - " this.root.append(nav_element);\n", - "\n", - " // Define a callback function for later on.\n", - " function toolbar_event(event) {\n", - " return fig.toolbar_button_onclick(event['data']);\n", - " }\n", - " function toolbar_mouse_event(event) {\n", - " return fig.toolbar_button_onmouseover(event['data']);\n", - " }\n", - "\n", - " for(var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " // put a spacer in here.\n", - " continue;\n", - " }\n", - " var button = $('');\n", - " button.click(method_name, toolbar_event);\n", - " button.mouseover(tooltip, toolbar_mouse_event);\n", - " nav_element.append(button);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = $('');\n", - " nav_element.append(status_bar);\n", - " this.message = status_bar[0];\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = $('
');\n", - " var button = $('');\n", - " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", - " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", - " buttongrp.append(button);\n", - " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", - " titlebar.prepend(buttongrp);\n", - "}\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(el){\n", - " var fig = this\n", - " el.on(\"remove\", function(){\n", - "\tfig.close_ws(fig, {});\n", - " });\n", - "}\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(el){\n", - " // this is important to make the div 'focusable\n", - " el.attr('tabindex', 0)\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " }\n", - " else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._key_event_extra = function(event, name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager)\n", - " manager = IPython.keyboard_manager;\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which == 13) {\n", - " this.canvas_div.blur();\n", - " event.shiftKey = false;\n", - " // Send a \"J\" for go to next cell\n", - " event.which = 74;\n", - " event.keyCode = 74;\n", - " manager.command_mode();\n", - " manager.handle_keydown(event);\n", - " }\n", - "}\n", - "\n", - "mpl.figure.prototype.handle_save = function(fig, msg) {\n", - " fig.ondownload(fig, null);\n", - "}\n", - "\n", - "\n", - "mpl.find_output_cell = function(html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] == html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "}\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel != null) {\n", - " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", - "}\n" - ], + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] + "metadata": { + "needs_background": "light" }, - "metadata": {}, "output_type": "display_data" }, - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "window.mpl = {};\n", - "\n", - "\n", - "mpl.get_websocket_type = function() {\n", - " if (typeof(WebSocket) !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof(MozWebSocket) !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert('Your browser does not have WebSocket support.' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.');\n", - " };\n", - "}\n", - "\n", - "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = (this.ws.binaryType != undefined);\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById(\"mpl-warnings\");\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent = (\n", - " \"This browser does not support binary websocket messages. \" +\n", - " \"Performance may be slow.\");\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = $('
');\n", - " this._root_extra_style(this.root)\n", - " this.root.attr('style', 'display: inline-block');\n", - "\n", - " $(parent_element).append(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", - " fig.send_message(\"send_image_mode\", {});\n", - " if (mpl.ratio != 1) {\n", - " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", - " }\n", - " fig.send_message(\"refresh\", {});\n", - " }\n", - "\n", - " this.imageObj.onload = function() {\n", - " if (fig.image_mode == 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function() {\n", - " fig.ws.close();\n", - " }\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "}\n", - "\n", - "mpl.figure.prototype._init_header = function() {\n", - " var titlebar = $(\n", - " '
');\n", - " var titletext = $(\n", - " '
');\n", - " titlebar.append(titletext)\n", - " this.root.append(titlebar);\n", - " this.header = titletext[0];\n", - "}\n", - "\n", - "\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._init_canvas = function() {\n", - " var fig = this;\n", - "\n", - " var canvas_div = $('
');\n", - "\n", - " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", - "\n", - " function canvas_keyboard_event(event) {\n", - " return fig.key_event(event, event['data']);\n", - " }\n", - "\n", - " canvas_div.keydown('key_press', canvas_keyboard_event);\n", - " canvas_div.keyup('key_release', canvas_keyboard_event);\n", - " this.canvas_div = canvas_div\n", - " this._canvas_extra_style(canvas_div)\n", - " this.root.append(canvas_div);\n", - "\n", - " var canvas = $('');\n", - " canvas.addClass('mpl-canvas');\n", - " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", - "\n", - " this.canvas = canvas[0];\n", - " this.context = canvas[0].getContext(\"2d\");\n", - "\n", - " var backingStore = this.context.backingStorePixelRatio ||\n", - "\tthis.context.webkitBackingStorePixelRatio ||\n", - "\tthis.context.mozBackingStorePixelRatio ||\n", - "\tthis.context.msBackingStorePixelRatio ||\n", - "\tthis.context.oBackingStorePixelRatio ||\n", - "\tthis.context.backingStorePixelRatio || 1;\n", - "\n", - " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband = $('');\n", - " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", - "\n", - " var pass_mouse_events = true;\n", - "\n", - " canvas_div.resizable({\n", - " start: function(event, ui) {\n", - " pass_mouse_events = false;\n", - " },\n", - " resize: function(event, ui) {\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " stop: function(event, ui) {\n", - " pass_mouse_events = true;\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " });\n", - "\n", - " function mouse_event_fn(event) {\n", - " if (pass_mouse_events)\n", - " return fig.mouse_event(event, event['data']);\n", - " }\n", - "\n", - " rubberband.mousedown('button_press', mouse_event_fn);\n", - " rubberband.mouseup('button_release', mouse_event_fn);\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband.mousemove('motion_notify', mouse_event_fn);\n", - "\n", - " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", - " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", - "\n", - " canvas_div.on(\"wheel\", function (event) {\n", - " event = event.originalEvent;\n", - " event['data'] = 'scroll'\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " mouse_event_fn(event);\n", - " });\n", - "\n", - " canvas_div.append(canvas);\n", - " canvas_div.append(rubberband);\n", - "\n", - " this.rubberband = rubberband;\n", - " this.rubberband_canvas = rubberband[0];\n", - " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", - " this.rubberband_context.strokeStyle = \"#000000\";\n", - "\n", - " this._resize_canvas = function(width, height) {\n", - " // Keep the size of the canvas, canvas container, and rubber band\n", - " // canvas in synch.\n", - " canvas_div.css('width', width)\n", - " canvas_div.css('height', height)\n", - "\n", - " canvas.attr('width', width * mpl.ratio);\n", - " canvas.attr('height', height * mpl.ratio);\n", - " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", - "\n", - " rubberband.attr('width', width);\n", - " rubberband.attr('height', height);\n", - " }\n", - "\n", - " // Set the figure to an initial 600x600px, this will subsequently be updated\n", - " // upon first draw.\n", - " this._resize_canvas(600, 600);\n", - "\n", - " // Disable right mouse context menu.\n", - " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", - " return false;\n", - " });\n", - "\n", - " function set_focus () {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "}\n", - "\n", - "mpl.figure.prototype._init_toolbar = function() {\n", - " var fig = this;\n", - "\n", - " var nav_element = $('
')\n", - " nav_element.attr('style', 'width: 100%');\n", - " this.root.append(nav_element);\n", - "\n", - " // Define a callback function for later on.\n", - " function toolbar_event(event) {\n", - " return fig.toolbar_button_onclick(event['data']);\n", - " }\n", - " function toolbar_mouse_event(event) {\n", - " return fig.toolbar_button_onmouseover(event['data']);\n", - " }\n", - "\n", - " for(var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " // put a spacer in here.\n", - " continue;\n", - " }\n", - " var button = $('');\n", - " button.click(method_name, toolbar_event);\n", - " button.mouseover(tooltip, toolbar_mouse_event);\n", - " nav_element.append(button);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = $('');\n", - " nav_element.append(status_bar);\n", - " this.message = status_bar[0];\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = $('
');\n", - " var button = $('');\n", - " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", - " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", - " buttongrp.append(button);\n", - " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", - " titlebar.prepend(buttongrp);\n", - "}\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(el){\n", - " var fig = this\n", - " el.on(\"remove\", function(){\n", - "\tfig.close_ws(fig, {});\n", - " });\n", - "}\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(el){\n", - " // this is important to make the div 'focusable\n", - " el.attr('tabindex', 0)\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " }\n", - " else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._key_event_extra = function(event, name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager)\n", - " manager = IPython.keyboard_manager;\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which == 13) {\n", - " this.canvas_div.blur();\n", - " event.shiftKey = false;\n", - " // Send a \"J\" for go to next cell\n", - " event.which = 74;\n", - " event.keyCode = 74;\n", - " manager.command_mode();\n", - " manager.handle_keydown(event);\n", - " }\n", - "}\n", - "\n", - "mpl.figure.prototype.handle_save = function(fig, msg) {\n", - " fig.ondownload(fig, null);\n", - "}\n", - "\n", - "\n", - "mpl.find_output_cell = function(html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] == html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "}\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel != null) {\n", - " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", - "}\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "bodyparts=Dataframe.columns.get_level_values(1) #you can read out the header to get body part names!\n", - "\n", - "bodyparts2plot=bodyparts #you could also take a subset, i.e. =['snout']\n", - "\n", - "%matplotlib notebook\n", - "PlottingResults(Dataframe,bodyparts2plot,alphavalue=.2,pcutoff=.5,fs=(8,4))\n", - "\n", - "# These plots can are interactive and can be customized (see https://matplotlib.org/) [in the code above]\n", - "# note that the snout and other bpts jitter in this example that was not trained for long." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "h9H7eqDLywnV" - }, - "source": [ - "## Great so let's use Federico's code for ROI analysis\n", - "\n", - "Functions to extract time spent by the mouse in each of a list of user defined ROIS!\n", - "\n", - "https://github.com/AlexEMG/DLCutils/blob/master/time_in_each_roi.py" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "colab": {}, - "colab_type": "code", - "id": "jg96O2acywnW", - "scrolled": false - }, - "outputs": [], - "source": [ - "import time_in_each_roi #the function needs to be in the same folder as the notebook\n", - "\n", - "#let's calculate velocity of the snout\n", - "bpt='snout'\n", - "vel = time_in_each_roi.calc_distance_between_points_in_a_vector_2d(np.vstack([Dataframe[DLCscorer][bpt]['x'].values.flatten(), Dataframe[DLCscorer][bpt]['y'].values.flatten()]).T)\n", - "\n", - "fps=30 # frame rate of camera in those experiments\n", - "time=np.arange(len(vel))*1./fps\n", - "vel=vel #notice the units of vel are relative pixel distance [per time step]\n", - "\n", - "# store in other variables:\n", - "xsnout=Dataframe[DLCscorer][bpt]['x'].values\n", - "ysnout=Dataframe[DLCscorer][bpt]['y'].values\n", - "vsnout=vel" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "application/javascript": [ - "/* Put everything inside the global mpl namespace */\n", - "window.mpl = {};\n", - "\n", - "\n", - "mpl.get_websocket_type = function() {\n", - " if (typeof(WebSocket) !== 'undefined') {\n", - " return WebSocket;\n", - " } else if (typeof(MozWebSocket) !== 'undefined') {\n", - " return MozWebSocket;\n", - " } else {\n", - " alert('Your browser does not have WebSocket support.' +\n", - " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", - " 'Firefox 4 and 5 are also supported but you ' +\n", - " 'have to enable WebSockets in about:config.');\n", - " };\n", - "}\n", - "\n", - "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", - " this.id = figure_id;\n", - "\n", - " this.ws = websocket;\n", - "\n", - " this.supports_binary = (this.ws.binaryType != undefined);\n", - "\n", - " if (!this.supports_binary) {\n", - " var warnings = document.getElementById(\"mpl-warnings\");\n", - " if (warnings) {\n", - " warnings.style.display = 'block';\n", - " warnings.textContent = (\n", - " \"This browser does not support binary websocket messages. \" +\n", - " \"Performance may be slow.\");\n", - " }\n", - " }\n", - "\n", - " this.imageObj = new Image();\n", - "\n", - " this.context = undefined;\n", - " this.message = undefined;\n", - " this.canvas = undefined;\n", - " this.rubberband_canvas = undefined;\n", - " this.rubberband_context = undefined;\n", - " this.format_dropdown = undefined;\n", - "\n", - " this.image_mode = 'full';\n", - "\n", - " this.root = $('
');\n", - " this._root_extra_style(this.root)\n", - " this.root.attr('style', 'display: inline-block');\n", - "\n", - " $(parent_element).append(this.root);\n", - "\n", - " this._init_header(this);\n", - " this._init_canvas(this);\n", - " this._init_toolbar(this);\n", - "\n", - " var fig = this;\n", - "\n", - " this.waiting = false;\n", - "\n", - " this.ws.onopen = function () {\n", - " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", - " fig.send_message(\"send_image_mode\", {});\n", - " if (mpl.ratio != 1) {\n", - " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", - " }\n", - " fig.send_message(\"refresh\", {});\n", - " }\n", - "\n", - " this.imageObj.onload = function() {\n", - " if (fig.image_mode == 'full') {\n", - " // Full images could contain transparency (where diff images\n", - " // almost always do), so we need to clear the canvas so that\n", - " // there is no ghosting.\n", - " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", - " }\n", - " fig.context.drawImage(fig.imageObj, 0, 0);\n", - " };\n", - "\n", - " this.imageObj.onunload = function() {\n", - " fig.ws.close();\n", - " }\n", - "\n", - " this.ws.onmessage = this._make_on_message_function(this);\n", - "\n", - " this.ondownload = ondownload;\n", - "}\n", - "\n", - "mpl.figure.prototype._init_header = function() {\n", - " var titlebar = $(\n", - " '
');\n", - " var titletext = $(\n", - " '
');\n", - " titlebar.append(titletext)\n", - " this.root.append(titlebar);\n", - " this.header = titletext[0];\n", - "}\n", - "\n", - "\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._init_canvas = function() {\n", - " var fig = this;\n", - "\n", - " var canvas_div = $('
');\n", - "\n", - " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", - "\n", - " function canvas_keyboard_event(event) {\n", - " return fig.key_event(event, event['data']);\n", - " }\n", - "\n", - " canvas_div.keydown('key_press', canvas_keyboard_event);\n", - " canvas_div.keyup('key_release', canvas_keyboard_event);\n", - " this.canvas_div = canvas_div\n", - " this._canvas_extra_style(canvas_div)\n", - " this.root.append(canvas_div);\n", - "\n", - " var canvas = $('');\n", - " canvas.addClass('mpl-canvas');\n", - " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", - "\n", - " this.canvas = canvas[0];\n", - " this.context = canvas[0].getContext(\"2d\");\n", - "\n", - " var backingStore = this.context.backingStorePixelRatio ||\n", - "\tthis.context.webkitBackingStorePixelRatio ||\n", - "\tthis.context.mozBackingStorePixelRatio ||\n", - "\tthis.context.msBackingStorePixelRatio ||\n", - "\tthis.context.oBackingStorePixelRatio ||\n", - "\tthis.context.backingStorePixelRatio || 1;\n", - "\n", - " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", - "\n", - " var rubberband = $('');\n", - " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", - "\n", - " var pass_mouse_events = true;\n", - "\n", - " canvas_div.resizable({\n", - " start: function(event, ui) {\n", - " pass_mouse_events = false;\n", - " },\n", - " resize: function(event, ui) {\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " stop: function(event, ui) {\n", - " pass_mouse_events = true;\n", - " fig.request_resize(ui.size.width, ui.size.height);\n", - " },\n", - " });\n", - "\n", - " function mouse_event_fn(event) {\n", - " if (pass_mouse_events)\n", - " return fig.mouse_event(event, event['data']);\n", - " }\n", - "\n", - " rubberband.mousedown('button_press', mouse_event_fn);\n", - " rubberband.mouseup('button_release', mouse_event_fn);\n", - " // Throttle sequential mouse events to 1 every 20ms.\n", - " rubberband.mousemove('motion_notify', mouse_event_fn);\n", - "\n", - " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", - " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", - "\n", - " canvas_div.on(\"wheel\", function (event) {\n", - " event = event.originalEvent;\n", - " event['data'] = 'scroll'\n", - " if (event.deltaY < 0) {\n", - " event.step = 1;\n", - " } else {\n", - " event.step = -1;\n", - " }\n", - " mouse_event_fn(event);\n", - " });\n", - "\n", - " canvas_div.append(canvas);\n", - " canvas_div.append(rubberband);\n", - "\n", - " this.rubberband = rubberband;\n", - " this.rubberband_canvas = rubberband[0];\n", - " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", - " this.rubberband_context.strokeStyle = \"#000000\";\n", - "\n", - " this._resize_canvas = function(width, height) {\n", - " // Keep the size of the canvas, canvas container, and rubber band\n", - " // canvas in synch.\n", - " canvas_div.css('width', width)\n", - " canvas_div.css('height', height)\n", - "\n", - " canvas.attr('width', width * mpl.ratio);\n", - " canvas.attr('height', height * mpl.ratio);\n", - " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", - "\n", - " rubberband.attr('width', width);\n", - " rubberband.attr('height', height);\n", - " }\n", - "\n", - " // Set the figure to an initial 600x600px, this will subsequently be updated\n", - " // upon first draw.\n", - " this._resize_canvas(600, 600);\n", - "\n", - " // Disable right mouse context menu.\n", - " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", - " return false;\n", - " });\n", - "\n", - " function set_focus () {\n", - " canvas.focus();\n", - " canvas_div.focus();\n", - " }\n", - "\n", - " window.setTimeout(set_focus, 100);\n", - "}\n", - "\n", - "mpl.figure.prototype._init_toolbar = function() {\n", - " var fig = this;\n", - "\n", - " var nav_element = $('
')\n", - " nav_element.attr('style', 'width: 100%');\n", - " this.root.append(nav_element);\n", - "\n", - " // Define a callback function for later on.\n", - " function toolbar_event(event) {\n", - " return fig.toolbar_button_onclick(event['data']);\n", - " }\n", - " function toolbar_mouse_event(event) {\n", - " return fig.toolbar_button_onmouseover(event['data']);\n", - " }\n", - "\n", - " for(var toolbar_ind in mpl.toolbar_items) {\n", - " var name = mpl.toolbar_items[toolbar_ind][0];\n", - " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", - " var image = mpl.toolbar_items[toolbar_ind][2];\n", - " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", - "\n", - " if (!name) {\n", - " // put a spacer in here.\n", - " continue;\n", - " }\n", - " var button = $('');\n", - " button.click(method_name, toolbar_event);\n", - " button.mouseover(tooltip, toolbar_mouse_event);\n", - " nav_element.append(button);\n", - " }\n", - "\n", - " // Add the status bar.\n", - " var status_bar = $('');\n", - " nav_element.append(status_bar);\n", - " this.message = status_bar[0];\n", - "\n", - " // Add the close button to the window.\n", - " var buttongrp = $('
');\n", - " var button = $('');\n", - " button.click(function (evt) { fig.handle_close(fig, {}); } );\n", - " button.mouseover('Stop Interaction', toolbar_mouse_event);\n", - " buttongrp.append(button);\n", - " var titlebar = this.root.find($('.ui-dialog-titlebar'));\n", - " titlebar.prepend(buttongrp);\n", - "}\n", - "\n", - "mpl.figure.prototype._root_extra_style = function(el){\n", - " var fig = this\n", - " el.on(\"remove\", function(){\n", - "\tfig.close_ws(fig, {});\n", - " });\n", - "}\n", - "\n", - "mpl.figure.prototype._canvas_extra_style = function(el){\n", - " // this is important to make the div 'focusable\n", - " el.attr('tabindex', 0)\n", - " // reach out to IPython and tell the keyboard manager to turn it's self\n", - " // off when our div gets focus\n", - "\n", - " // location in version 3\n", - " if (IPython.notebook.keyboard_manager) {\n", - " IPython.notebook.keyboard_manager.register_events(el);\n", - " }\n", - " else {\n", - " // location in version 2\n", - " IPython.keyboard_manager.register_events(el);\n", - " }\n", - "\n", - "}\n", - "\n", - "mpl.figure.prototype._key_event_extra = function(event, name) {\n", - " var manager = IPython.notebook.keyboard_manager;\n", - " if (!manager)\n", - " manager = IPython.keyboard_manager;\n", - "\n", - " // Check for shift+enter\n", - " if (event.shiftKey && event.which == 13) {\n", - " this.canvas_div.blur();\n", - " event.shiftKey = false;\n", - " // Send a \"J\" for go to next cell\n", - " event.which = 74;\n", - " event.keyCode = 74;\n", - " manager.command_mode();\n", - " manager.handle_keydown(event);\n", - " }\n", - "}\n", - "\n", - "mpl.figure.prototype.handle_save = function(fig, msg) {\n", - " fig.ondownload(fig, null);\n", - "}\n", - "\n", - "\n", - "mpl.find_output_cell = function(html_output) {\n", - " // Return the cell and output element which can be found *uniquely* in the notebook.\n", - " // Note - this is a bit hacky, but it is done because the \"notebook_saving.Notebook\"\n", - " // IPython event is triggered only after the cells have been serialised, which for\n", - " // our purposes (turning an active figure into a static one), is too late.\n", - " var cells = IPython.notebook.get_cells();\n", - " var ncells = cells.length;\n", - " for (var i=0; i= 3 moved mimebundle to data attribute of output\n", - " data = data.data;\n", - " }\n", - " if (data['text/html'] == html_output) {\n", - " return [cell, data, j];\n", - " }\n", - " }\n", - " }\n", - " }\n", - "}\n", - "\n", - "// Register the function which deals with the matplotlib target/channel.\n", - "// The kernel may be null if the page has been refreshed.\n", - "if (IPython.notebook.kernel != null) {\n", - " IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);\n", - "}\n" - ], + "image/png": "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\n", "text/plain": [ - "" + "
" ] }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] + "metadata": { + "needs_background": "light" }, - "metadata": {}, "output_type": "display_data" } ], @@ -5197,24 +517,34 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 17, "metadata": {}, "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Warning: you've set check_inroi=False, so data reflect which ROI is closest even if tracked point is not in any given ROI.\n" + ] + }, { "data": { "text/plain": [ - "{'avg_time_in_roi': {'leftside': 176.8, 'rightside': 56.2},\n", + "{'transitions_per_roi': {'leftside': 10, 'rightside': 10, 'tot': 20},\n", + " 'cumulative_time_in_roi': {'leftside': 1768, 'rightside': 562, 'tot': 2330},\n", + " 'cumulative_time_in_roi_sec': {'leftside': 58.93333333333333,\n", + " 'rightside': 18.733333333333334,\n", + " 'tot': 77.66666666666666},\n", + " 'avg_time_in_roi': {'leftside': 176.8, 'rightside': 56.2, 'tot': 233.0},\n", " 'avg_time_in_roi_sec': {'leftside': 5.8933333333333335,\n", - " 'rightside': 1.8733333333333335},\n", + " 'rightside': 1.8733333333333335,\n", + " 'tot': 7.7666666666666675},\n", " 'avg_vel_in_roi': {'leftside': 4.798367612314975,\n", - " 'rightside': 7.978920763420923},\n", - " 'cumulative_time_in_roi': {'leftside': 1768, 'rightside': 562},\n", - " 'cumulative_time_in_roi_sec': {'leftside': 58.93333333333333,\n", - " 'rightside': 18.733333333333334},\n", - " 'transitions_per_roi': {'leftside': 10, 'rightside': 10}}" + " 'rightside': 7.978920763420923,\n", + " 'tot': 12.7772883757359}}" ] }, - "execution_count": 11, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -5227,6 +557,13 @@ "#print results:\n", "res" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -5237,9 +574,9 @@ "version": "0.3.2" }, "kernelspec": { - "display_name": "Python [conda env:DLC2]", + "display_name": "Python [conda env:DLC-CPU] *", "language": "python", - "name": "conda-env-DLC2-py" + "name": "conda-env-DLC-CPU-py" }, "language_info": { "codemirror_mode": { @@ -5251,7 +588,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.6" + "version": "3.7.6" }, "varInspector": { "cols": { From e928ab8e407d6c0b3b65f40a70aced686b01e935 Mon Sep 17 00:00:00 2001 From: Mackenzie Mathis Date: Fri, 8 May 2020 14:39:38 -0400 Subject: [PATCH 30/37] Update README.md --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 366ed32..9b7cda8 100644 --- a/README.md +++ b/README.md @@ -53,10 +53,20 @@ paper: https://www.biorxiv.org/content/10.1101/2020.01.21.913624v1 code: https://github.com/ETHZ-INS/DLCAnalyzer +## Behavior Analysis with Classifiers (SIMBA + +A pipeline for using pose estimation (i.e. DeepLabCut) then behavioral annotatation and generatation of supervised machine-learning-based classifiers. <-- you can use the outputs of DLC to feed directly into SIMBA (in Python). + +Code written by: [Simon Nilsson](https://github.com/sronilsson) (please direct use questions to Simon). + +paper: https://www.biorxiv.org/content/10.1101/2020.04.19.049452v2 + +code: https://github.com/sgoldenlab/simba + ## Behavior clustering with B-SOiD -B-SOiD: An Open Source Unsupervised Algorithm for Discovery of Spontaneous Behaviors <-- use the outputs of DLC to feed directly into B-SOiD (in MATLAB). +B-SOiD: An Open Source Unsupervised Algorithm for Discovery of Spontaneous Behaviors <-- you can use the outputs of DLC to feed directly into B-SOiD (in MATLAB). paper: https://www.biorxiv.org/content/10.1101/770271v1.abstract @@ -64,6 +74,7 @@ code: https://github.com/YttriLab/B-SOiD ## Using DeepLabCut for USB-CGPIO feedback + paper: https://www.biorxiv.org/content/early/2018/11/28/482349 code: https://github.com/bf777/DeepCutRealTime From 319c50c68c951c08c88560e2e7b6b40032d66d5f Mon Sep 17 00:00:00 2001 From: Mackenzie Mathis Date: Fri, 8 May 2020 14:43:10 -0400 Subject: [PATCH 31/37] Update README.md --- README.md | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 9b7cda8..1a112ee 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ This repository contains various scripts as well as links to other packages related to [DeepLabCut](https://github.com/AlexEMG/DeepLabCut). Feel free to contribute your own analysis methods, and perhaps some short notebook of how to use it. Thanks! -## Example scripts for automation of analysis & training +# Example scripts for scaling up your analysis & training: These two scripts illustrate how to train, test, and analyze videos for multiple projects automatically (scale_raining_and_evaluation.py) and how to analyze videos that are organized in subfolders automatically (scale_analysis_oversubfolders.py). Feel free to adjust them for your needs! @@ -19,6 +19,8 @@ https://github.com/DeepLabCut/DLCutils/blob/master/SCALE_YOUR_ANALYSIS/scale_tra Contributed by [Alexander Mathis](https://github.com/AlexEMG) +# Using DLC outputs, loading, simple ROI analysis examples: + ## Time spent of a body part in a particular region of interest (ROI) You can compute time spent in particular ROIs in frames. This demo Jupyer Notebook shows you how to load the outputs of DLC and perform the analysis (plus other plotting functions): @@ -29,6 +31,8 @@ https://github.com/DeepLabCut/DLCutils/blob/master/time_in_each_roi.py Contributed by [Federico Claudi](https://github.com/FedeClaudi) and Jupyter Notebok from [Alexander Mathis](https://github.com/AlexEMG) +# Clustering tools (using the output of DLC): + ## Behavior clustering with MotionMapper - (adpated from https://github.com/gordonberman/MotionMapper) @@ -36,16 +40,17 @@ https://github.com/DeepLabCut/DLCutils/tree/master/DLC_2_MotionMapper Contributed by [Mackenzie Mathis](https://github.com/MMathisLab) -## 3D reconstruction with EasyWand/Argus DLT system with DeepLabCut data: +## Behavior clustering with B-SOiD -Written by [Brandon Jackson](https://github.com/haliaetus13), post our DLC workshop in Jan 2020: +B-SOiD: An Open Source Unsupervised Algorithm for Discovery of Spontaneous Behaviors <-- you can use the outputs of DLC to feed directly into B-SOiD (in MATLAB). -A small set of utilities that allow conversion between the data storage formats of DeepLabCut (DLC) and one of the DLT-based 3D tracking systems: either Ty Hedrick's DigitizingTools in MATLAB, or the Python-based Argus. These functions should allow you to use data previously digitized in a DLT system to create the files needed to train a DLC model, and to import DLC-tracked points back into a DLT 3D calibration to reconstruct 3D points. +paper: https://www.biorxiv.org/content/10.1101/770271v1.abstract -code: https://github.com/haliaetus13/DLCconverterDLT +code: https://github.com/YttriLab/B-SOiD +# Machine-learning helper packages (using the output of DLC): -## Behavior Analysis with R (ETH-DLCAnalyzer) +## Behavior analysis with machine-learning in R (ETH-DLCAnalyzer) Deep learning based behavioral analysis enables high precision rodent tracking and is capable of outperforming commercial solutions. Oliver Sturman, Lukas von Ziegler, Christa Schläppi, Furkan Akyol, Benjamin Grewe, Johannes Bohacek @@ -53,7 +58,7 @@ paper: https://www.biorxiv.org/content/10.1101/2020.01.21.913624v1 code: https://github.com/ETHZ-INS/DLCAnalyzer -## Behavior Analysis with Classifiers (SIMBA +## Behavior Analysis with machine learning classifiers (SIMBA) A pipeline for using pose estimation (i.e. DeepLabCut) then behavioral annotatation and generatation of supervised machine-learning-based classifiers. <-- you can use the outputs of DLC to feed directly into SIMBA (in Python). @@ -64,14 +69,24 @@ paper: https://www.biorxiv.org/content/10.1101/2020.04.19.049452v2 code: https://github.com/sgoldenlab/simba -## Behavior clustering with B-SOiD +# 3D DeepLabCut helper packages: -B-SOiD: An Open Source Unsupervised Algorithm for Discovery of Spontaneous Behaviors <-- you can use the outputs of DLC to feed directly into B-SOiD (in MATLAB). +## A wrapper package for DeepLabCut2.0 for 3D videos (anipose) +code: https://github.com/lambdaloop/anipose -paper: https://www.biorxiv.org/content/10.1101/770271v1.abstract +maintainer: [Pierre Karashchuk](https://github.com/lambdaloop) -code: https://github.com/YttriLab/B-SOiD +## 3D reconstruction with EasyWand/Argus DLT system with DeepLabCut data: +Written by [Brandon Jackson](https://github.com/haliaetus13), post our DLC workshop in Jan 2020: + +A small set of utilities that allow conversion between the data storage formats of DeepLabCut (DLC) and one of the DLT-based 3D tracking systems: either Ty Hedrick's DigitizingTools in MATLAB, or the Python-based Argus. These functions should allow you to use data previously digitized in a DLT system to create the files needed to train a DLC model, and to import DLC-tracked points back into a DLT 3D calibration to reconstruct 3D points. + +code: https://github.com/haliaetus13/DLCconverterDLT + +## Pupil Tracking +- From Tom Vaissie - tvaissie@scripps.edu +- Please see the README.txt file https://github.com/DeepLabCut/DLCutils/tree/master/pupilTracking for details; this code makes the video in case study 7 http://www.mousemotorlab.org/deeplabcut/. ## Using DeepLabCut for USB-CGPIO feedback @@ -81,15 +96,6 @@ code: https://github.com/bf777/DeepCutRealTime maintainer: [Brandon Forys](https://github.com/bf777) -## A wrapper package for DeepLabCut2.0 for 3D videos (anipose) -code: https://github.com/lambdaloop/anipose - -maintainer: [Pierre Karashchuk](https://github.com/lambdaloop) - -## Pupil Tracking -- From Tom Vaissie - tvaissie@scripps.edu -- Please see the README.txt file https://github.com/DeepLabCut/DLCutils/tree/master/pupilTracking for details; this code makes the video in case study 7 http://www.mousemotorlab.org/deeplabcut/. - ## LEGACY utility functions (no longer required in DLC 2+): From ed95860a7331f2ba37044711faf9638a7c5e6ab5 Mon Sep 17 00:00:00 2001 From: Harry Carey <38996929+PolarBean@users.noreply.github.com> Date: Thu, 4 Jun 2020 02:24:09 +1000 Subject: [PATCH 32/37] Added my GUI ROI tool :) (#12) * Update README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 1a112ee..8ce4df0 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,11 @@ https://github.com/DeepLabCut/DLCutils/blob/master/time_in_each_roi.py Contributed by [Federico Claudi](https://github.com/FedeClaudi) and Jupyter Notebok from [Alexander Mathis](https://github.com/AlexEMG) +## A GUI based ROI tool for time spent of a body part in a defined region of interest. +https://github.com/PolarBean/DLC_ROI_tool + +Contributed by [Harry Carey](https://github.com/PolarBean) + # Clustering tools (using the output of DLC): ## Behavior clustering with MotionMapper From 04374810d4108d7425516c08177de2fda1f7f268 Mon Sep 17 00:00:00 2001 From: fcatus <56323389+fcatus@users.noreply.github.com> Date: Tue, 22 Sep 2020 21:26:20 -0500 Subject: [PATCH 33/37] Make all warnings suppressible --- time_in_each_roi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/time_in_each_roi.py b/time_in_each_roi.py index 464f7d3..b4b19e6 100644 --- a/time_in_each_roi.py +++ b/time_in_each_roi.py @@ -138,7 +138,7 @@ def sort_roi_points(roi): cleaned_rois.append(roi) return cleaned_rois else: - print("Warning: you've set check_inroi=False, so data reflect which ROI is closest even if tracked point is not in any given ROI.") + raise ValueError("Warning: you've set check_inroi=False, so data reflect which ROI is closest even if tracked point is not in any given ROI.") return roi_at_each_frame From 4bb188ddb4e3bc6a696270eb58969b1fa1fab28b Mon Sep 17 00:00:00 2001 From: fcatus <56323389+fcatus@users.noreply.github.com> Date: Wed, 23 Sep 2020 11:04:16 -0500 Subject: [PATCH 34/37] Update time_in_each_roi.py --- time_in_each_roi.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/time_in_each_roi.py b/time_in_each_roi.py index b4b19e6..04b6043 100644 --- a/time_in_each_roi.py +++ b/time_in_each_roi.py @@ -2,6 +2,7 @@ from collections import namedtuple from scipy.spatial import distance import pandas as pd +import warnings """ Functions to extract time spent by the mouse in each of a list of user defined ROIS @@ -138,7 +139,7 @@ def sort_roi_points(roi): cleaned_rois.append(roi) return cleaned_rois else: - raise ValueError("Warning: you've set check_inroi=False, so data reflect which ROI is closest even if tracked point is not in any given ROI.") + warnings.warn("Warning: you've set check_inroi=False, so data reflect which ROI is closest even if tracked point is not in any given ROI.") return roi_at_each_frame From 1978c8f38e2e6a6bcb91a85b0224450d533ce2f6 Mon Sep 17 00:00:00 2001 From: Alexander Mathis Date: Sun, 31 Jan 2021 23:09:52 +0100 Subject: [PATCH 35/37] VAME added --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 8ce4df0..91e75d2 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,12 @@ Contributed by [Harry Carey](https://github.com/PolarBean) # Clustering tools (using the output of DLC): +## Identifying Behavioral Structure from Deep Variational Embeddings of Animal Motion + +paper: https://www.biorxiv.org/content/10.1101/2020.05.14.095430 + +code: https://github.com/LINCellularNeuroscience/VAME + ## Behavior clustering with MotionMapper - (adpated from https://github.com/gordonberman/MotionMapper) From 3bd9a73ea6f4256380e6b217a9de2b215fe491fd Mon Sep 17 00:00:00 2001 From: jakeshirey <94328784+jakeshirey@users.noreply.github.com> Date: Sun, 21 May 2023 09:16:40 -0400 Subject: [PATCH 36/37] Added a Utility to the DLCutils readme page (#23) * Added a Utility to the DLCutils readme page * Update README.md - minor re shuffling --------- Co-authored-by: Mackenzie Mathis --- README.md | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 91e75d2..138c03b 100644 --- a/README.md +++ b/README.md @@ -10,29 +10,40 @@ This repository contains various scripts as well as links to other packages related to [DeepLabCut](https://github.com/AlexEMG/DeepLabCut). Feel free to contribute your own analysis methods, and perhaps some short notebook of how to use it. Thanks! -# Example scripts for scaling up your analysis & training: +# Example scripts for scaling up your DLC analysis & training: These two scripts illustrate how to train, test, and analyze videos for multiple projects automatically (scale_raining_and_evaluation.py) and how to analyze videos that are organized in subfolders automatically (scale_analysis_oversubfolders.py). Feel free to adjust them for your needs! -https://github.com/DeepLabCut/DLCutils/tree/master/SCALE_YOUR_ANALYSIS/scale_analysis_oversubfolders.py -https://github.com/DeepLabCut/DLCutils/blob/master/SCALE_YOUR_ANALYSIS/scale_training_and_evaluation.py +code: https://github.com/DeepLabCut/DLCutils/tree/master/SCALE_YOUR_ANALYSIS/scale_analysis_oversubfolders.py + +code: https://github.com/DeepLabCut/DLCutils/blob/master/SCALE_YOUR_ANALYSIS/scale_training_and_evaluation.py Contributed by [Alexander Mathis](https://github.com/AlexEMG) -# Using DLC outputs, loading, simple ROI analysis examples: + +# Using your DLC outputs, loading, simple ROI analysis, visualization examples: ## Time spent of a body part in a particular region of interest (ROI) You can compute time spent in particular ROIs in frames. This demo Jupyer Notebook shows you how to load the outputs of DLC and perform the analysis (plus other plotting functions): -https://github.com/DeepLabCut/DLCutils/blob/master/Demo_loadandanalyzeDLCdata.ipynb +code: https://github.com/DeepLabCut/DLCutils/blob/master/Demo_loadandanalyzeDLCdata.ipynb -https://github.com/DeepLabCut/DLCutils/blob/master/time_in_each_roi.py +code: https://github.com/DeepLabCut/DLCutils/blob/master/time_in_each_roi.py Contributed by [Federico Claudi](https://github.com/FedeClaudi) and Jupyter Notebok from [Alexander Mathis](https://github.com/AlexEMG) -## A GUI based ROI tool for time spent of a body part in a defined region of interest. -https://github.com/PolarBean/DLC_ROI_tool +## DeepLabCut-Display GUI + +Open and view data to understand pose estimation errors and trends. Filter data by likelihood threshold. + +code: https://github.com/jakeshirey/DeepLabCut-Display + +Contributed by [Jacob Shirey](https://github.com/jakeshirey) + +## A GUI based ROI tool for time spent of a body part in a defined region of interest + +code: https://github.com/PolarBean/DLC_ROI_tool Contributed by [Harry Carey](https://github.com/PolarBean) @@ -47,7 +58,7 @@ code: https://github.com/LINCellularNeuroscience/VAME ## Behavior clustering with MotionMapper - (adpated from https://github.com/gordonberman/MotionMapper) -https://github.com/DeepLabCut/DLCutils/tree/master/DLC_2_MotionMapper +code: https://github.com/DeepLabCut/DLCutils/tree/master/DLC_2_MotionMapper Contributed by [Mackenzie Mathis](https://github.com/MMathisLab) From 324d8438e67a8b12d2039a1525d2fe43721a61f2 Mon Sep 17 00:00:00 2001 From: Michael Schellenberger <97124047+MSchellenberger@users.noreply.github.com> Date: Tue, 1 Jul 2025 07:16:56 +0200 Subject: [PATCH 37/37] Added functionality: linear transformation and scaling of DLC data. Fixed outdated email in code of conduct (#24) --- CODE_OF_CONDUCT.md | 2 +- README.md | 10 + transform_and_scale/DLCTransformer.py | 208 ++++++++++++++++++ transform_and_scale/README.md | 28 +++ .../__pycache__/DLCTransformer.cpython-39.pyc | Bin 0 -> 6045 bytes .../__pycache__/read_config.cpython-39.pyc | Bin 0 -> 721 bytes transform_and_scale/config.yaml | 7 + transform_and_scale/read_config.py | 21 ++ ...DefenseCircuitsLab2023_Rotarod_testfile.h5 | Bin 0 -> 11929605 bytes .../transform_and_scale_tutorial.ipynb | 63 ++++++ 10 files changed, 338 insertions(+), 1 deletion(-) create mode 100644 transform_and_scale/DLCTransformer.py create mode 100644 transform_and_scale/README.md create mode 100644 transform_and_scale/__pycache__/DLCTransformer.cpython-39.pyc create mode 100644 transform_and_scale/__pycache__/read_config.cpython-39.pyc create mode 100644 transform_and_scale/config.yaml create mode 100644 transform_and_scale/read_config.py create mode 100644 transform_and_scale/test_data/DefenseCircuitsLab2023_Rotarod_testfile.h5 create mode 100644 transform_and_scale/transform_and_scale_tutorial.ipynb diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index f4396c3..339757e 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -55,7 +55,7 @@ further defined and clarified by project maintainers. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at alexander.mathis@bethgelab.org. All +reported by contacting the project team at alexander.mathis@epfl.ch. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. diff --git a/README.md b/README.md index 138c03b..246783a 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,16 @@ code: https://github.com/PolarBean/DLC_ROI_tool Contributed by [Harry Carey](https://github.com/PolarBean) +## Linear Transformation and Scaling of DLC output data (transform_and_scale) + +This package is designed for anyone who wants to know where a tracked marker is within a reference frame (i.e. behavioral context). DeepLabCut outputs coordinates in relation to the field of view of the recorded video. With this tool, these coordinates can be linearly transformed and scaled to the reference frame of the behavioral context, meaning that the output coordinates are distances [cm] to a corner of the behavioral context, instead of distances [px] to a corner of the video field of view. + +code: https://github.com/DeepLabCut/DLCutils/tree/master/transform_and_scale/ + +tutorial: https://github.com/DeepLabCut/DLCutils/tree/master/transform_and_scale/transform_and_scale_tutorial.ipynb + +Contributed by [Michael Schellenberger](https://github.com/MSchellenberger) + # Clustering tools (using the output of DLC): ## Identifying Behavioral Structure from Deep Variational Embeddings of Animal Motion diff --git a/transform_and_scale/DLCTransformer.py b/transform_and_scale/DLCTransformer.py new file mode 100644 index 0000000..b53226a --- /dev/null +++ b/transform_and_scale/DLCTransformer.py @@ -0,0 +1,208 @@ +import pandas as pd +import numpy as np +from read_config import read_config +from typing import Optional + +class DLCTransformer: + def __init__(self, config_filepath: str, dlc_filepath: Optional[str] = None, dlc_df: Optional[pd.DataFrame] = None): + self.config = read_config(config_filepath) + self.dlc_filepath = dlc_filepath + if self.dlc_filepath is not None: + if self.dlc_filepath.endswith("h5"): + self.dlc_df = pd.read_hdf(dlc_filepath, header=[0, 1, 2], index_col=0) + elif self.dlc_filepath.endswith("csv"): + self.dlc_df = pd.read_csv(dlc_filepath, header=[0, 1, 2], index_col=0) + else: + raise ValueError("DeepLabCut file must be .h5 or .csv") + else: + if dlc_df is not None: + self.dlc_df = dlc_df + else: + raise ValueError("One of the arguments dlc_filepath or dlc_df must be specified") + + # read metadata + self.origin_marker = self.config["origin_marker"] + self.basis_vector_h_marker = self.config["basis_vector_h_marker"] + self.basis_vector_v_marker = self.config["basis_vector_v_marker"] + self.scale_factor_h = self.config["scale_factor_h"] + self.scale_factor_v = self.config["scale_factor_v"] + self.dlc_immobile_marker_threshold = self.config[ + "dlc_immobile_marker_threshold" + ] + self.show_angle = self.config["show_angle"] + self.scorer = self.dlc_df.columns.get_level_values(0).unique()[0] + + def run(self) -> pd.DataFrame: + """ + Translate and scale DLC data. + First get median coordinate of origin marker and basis vectors, then transform and scale the data. + + :return: pd.DataFrame with transformed and scaled DLC data + """ + # get basis vectors and origin + origin, basis_vector_h, basis_vector_v = self.get_basis_vectors( + df=self.dlc_df, + origin_marker=self.origin_marker, + basis_vector_h_marker=self.basis_vector_h_marker, + basis_vector_v_marker=self.basis_vector_v_marker, + dlc_immobile_marker_threshold=self.dlc_immobile_marker_threshold, + ) + + if self.show_angle: + print( + "Angle between basis vectors :", + self._calculate_angle(basis_vector_v, (0, 0), basis_vector_h), + ) + + # transform df + df_transformed = self.transform( + self.dlc_df, origin, basis_vector_h, basis_vector_v + ) + df_scaled = self.scale_df( + df_transformed, self.scale_factor_h, self.scale_factor_v + ) + return df_scaled + + def get_basis_vectors( + self, + df: pd.DataFrame, + origin_marker: str, + basis_vector_h_marker: str, + basis_vector_v_marker: str, + dlc_immobile_marker_threshold: float, + ) -> (tuple, tuple, tuple): + """ + Returns the origin and basis vectors of the coordinate system + + :param df: pd.DataFrame with tracking data + :param origin_marker: name of origin marker + :param basis_vector_h_marker: name of horizontal basis vector marker + :param basis_vector_v_marker: name of vertical basis vector marker + :param dlc_immobile_marker_threshold: minimum likelihood of a constant marker to be included into the median coordinate calculation + :return: coordinates of origin, basis_vector_h, basis_vector_v + """ + origin = self.get_median_coordinate( + df, origin_marker, dlc_immobile_marker_threshold + ) + + # bring coordinates into origin system + basis_vector_h_coord = self.get_median_coordinate( + df=df, + marker=basis_vector_h_marker, + dlc_immobile_marker_threshold=dlc_immobile_marker_threshold, + ) + basis_vector_v_coord = self.get_median_coordinate( + df=df, + marker=basis_vector_v_marker, + dlc_immobile_marker_threshold=dlc_immobile_marker_threshold, + ) + + # calculate basis vector transformation + basis_vector_h = ( + basis_vector_h_coord[0] - origin[0], + basis_vector_h_coord[1] - origin[1], + ) + basis_vector_v = ( + basis_vector_v_coord[0] - origin[0], + basis_vector_v_coord[1] - origin[1], + ) + + return origin, basis_vector_h, basis_vector_v + + def get_median_coordinate(self, df, marker, dlc_immobile_marker_threshold) -> tuple: + """ + Returns the most likely coordinate of a vector + + :param df: pd.DataFrame with tracking data + :param marker: name of marker of which the median coordinate should be calculated + :param dlc_immobile_marker_threshold: minimum likelihood of a constant marker to be included into the median coordinate calculation + :return: median coordinate of marker + """ + # filter df + df = df.droplevel(0, axis=1) + marker_df = df.loc[ + df[marker, "likelihood"] > dlc_immobile_marker_threshold, marker + ].copy() + x_coord = np.nanmedian(marker_df["x"]) + y_coord = np.nanmedian(marker_df["y"]) + coords = (x_coord, y_coord) + return coords + + def _calculate_angle(self, a, b, c) -> float: + """ + Calculates the angle between three points a-b-c + + :param a: tuple of coordinates + :param b: tuple of coordinates + :param c: tuple of coordinates + :return: angle between a-b-c in degrees + """ + + # Calculate the vectors AB and BC + vector_AB = (b[0] - a[0], b[1] - a[1]) + vector_BC = (c[0] - b[0], c[1] - b[1]) + + # Calculate the magnitudes of AB and BC + magnitude_AB = np.linalg.norm(vector_AB) + magnitude_BC = np.linalg.norm(vector_BC) + # + # Calculate the dot product of AB and BC + dot_product = np.dot(vector_AB, vector_BC) + + # Calculate the angle in radians using the dot product and magnitudes + angle_radians = np.arccos(dot_product / (magnitude_AB * magnitude_BC)) + + # Convert the angle to degrees + angle_degrees = np.degrees(angle_radians) + return angle_degrees + + def transform(self, df, origin, basis_vector_h, basis_vector_v) -> pd.DataFrame: + """ + Transform the coordinates of the df into the new coordinate system + + :param df: pd.DataFrame with tracking data + :param origin: coordinate of origin + :param basis_vector_h: coordinate of horizontal basis vector + :param basis_vector_v: coordinate of vertical basis vector + :return: transformed pd.DataFrame + """ + transformed_df = df.copy() + final_transformed_df = df.copy() + + # 2d rotation matrix + a = basis_vector_h[0] + b = basis_vector_h[1] + c = basis_vector_v[0] + d = basis_vector_v[1] + + for marker in df.columns.get_level_values(1).unique(): + + # shift coordinates into origin system + transformed_df.loc[:, (self.scorer, marker, "x")] -= origin[0] + transformed_df.loc[:, (self.scorer, marker, "y")] -= origin[1] + + # linear algebra 2D transformation + final_transformed_df.loc[:, (self.scorer, marker, "y")] = ( + (transformed_df.loc[:, (self.scorer, marker, "y")] / b) + - (transformed_df.loc[:, (self.scorer, marker, "x")] / a) + ) / ((-c / a) + (d / b)) + + final_transformed_df.loc[:, (self.scorer, marker, "x")] = ( + transformed_df.loc[:, (self.scorer, marker, "x")] + - c * final_transformed_df.loc[:, (self.scorer, marker, "y")] + ) / a + + return final_transformed_df + + def scale_df(self, df, scale_factor_h, scale_factor_v) -> pd.DataFrame: + """ + :param df: pd.DataFrame with tracking data + :param scale_factor_h: horizontal scale factor + :param scale_factor_v: vertical scale factor + :return: scaled pd.DataFrame + """ + scaled_df = df.copy() + for marker in df.columns.get_level_values(1).unique(): + scaled_df.loc[:, (self.scorer, marker, "x")] *= scale_factor_h + scaled_df.loc[:, (self.scorer, marker, "y")] *= scale_factor_v + return scaled_df diff --git a/transform_and_scale/README.md b/transform_and_scale/README.md new file mode 100644 index 0000000..fae5edc --- /dev/null +++ b/transform_and_scale/README.md @@ -0,0 +1,28 @@ +# Easy transformation and scaling of DeepLabCut Data + +#### Background +DeepLabCut is a widely used markerless pose estimation toolbox in behavioral science. The output of DeepLabCut is coordinates in pixels for each frame for each marker. However, in most cases the coordinates first need to be translated (i.e. adapted to the coordinate-space of the behavioral maze) and scaled (e.g. to cm) to enable meaningful behavioral quantification. + +#### Functionality +The Transform_DLC repository takes care of a specific task: It takes DeepLabCut dataframes as the input and outputs transformed and scaled DeepLabCut dataframes. Requirements for this transformation and scaling are that the behavioral maze or a reference has to be rectangular and its corners have to be tracked with DeepLabCut. + +#### Usage +For an example usecase check out the tutorial notebook! + +1) Set hyperparameter in config file: Specify the name of the horizontal and vertical basis vector markers (in a rectangular maze these are two opposing corners) and the origin (the corner that connects the two basis vector corners). Additionally, set the DeepLabCut-likelihood threshold for those markers, and the scale factors (optional, if you don´t need scaling set them to 1). For quality control set show_angle to True. + +2) Instantiate the DLCTransformer class with the filepath to your DeepLabCut tracked data and the config-filepath. + +3) Use .run on your instantiated class object and save the output in a variable of your choice. + + +#### Contribution +This is a [Defense Circuits Lab](https://www.defense-circuits-lab.com/) project written by [Michael Schellenberger](https://github.com/MSchellenberger) for [DLCutils](https://github.com/DeepLabCut/DLCutils). + + + +
+ + DefenseCircuitsLab + +
\ No newline at end of file diff --git a/transform_and_scale/__pycache__/DLCTransformer.cpython-39.pyc b/transform_and_scale/__pycache__/DLCTransformer.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f81d283dd76cb642cd68d26c43a3a03bb55af54 GIT binary patch literal 6045 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 literal 0 HcmV?d00001 diff --git a/transform_and_scale/__pycache__/read_config.cpython-39.pyc b/transform_and_scale/__pycache__/read_config.cpython-39.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f303f86670ab180c7133b660d63e16bb8b0ba42 GIT binary patch literal 721 zcmYjP&59F25U%d&{4hyCFYZO8@gj3s);&g9gsgj7gBWDlFc5mDJISmw-9vW|n2=mt zui^{%0>08*L_GNl9$afCK~h6~Lv{Uq)zxA!2m$5i_J@2%0e;oSp#*5WLUoT3BuJ9M z6ckZZ(r;7-l6_{=K#~bWt=|{{Yg?4je^BMA*xkO|tws^m@-JKp6tEzWkvwGc+5THXzpPZ6DrG(y7O8?UPZrcvf m6EWMtUlrhnDkjs!H^&X71L)T=-IuwMWv0&Rx8>@Iy1_r{iNS6F literal 0 HcmV?d00001 diff --git a/transform_and_scale/config.yaml b/transform_and_scale/config.yaml new file mode 100644 index 0000000..763d295 --- /dev/null +++ b/transform_and_scale/config.yaml @@ -0,0 +1,7 @@ +origin_marker: 'RodLowerLeft' +basis_vector_h_marker: 'RodLowerRight' +basis_vector_v_marker: 'RodUpperLeft' +scale_factor_h: 5.8 +scale_factor_v: 3 +dlc_immobile_marker_threshold: 0.9 +show_angle: True \ No newline at end of file diff --git a/transform_and_scale/read_config.py b/transform_and_scale/read_config.py new file mode 100644 index 0000000..94b43e6 --- /dev/null +++ b/transform_and_scale/read_config.py @@ -0,0 +1,21 @@ +import yaml + + +def read_config(config_path: str) -> dict: + """ + Reads structured config file defining a project. + + :param config_path: path to config file + """ + + try: + with open(config_path, "r") as ymlfile: + config_file = yaml.load(ymlfile, Loader=yaml.SafeLoader) + except FileNotFoundError: + raise ( + "Could not find the config file at " + + config_path + + " \n Please make sure the path is correct and the file exists" + ) + + return config_file diff --git a/transform_and_scale/test_data/DefenseCircuitsLab2023_Rotarod_testfile.h5 b/transform_and_scale/test_data/DefenseCircuitsLab2023_Rotarod_testfile.h5 new file mode 100644 index 0000000000000000000000000000000000000000..f4c61844aaf4a7937ecc5ace0a1a466fb83421f5 GIT binary patch literal 11929605 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

5_d4o4X@5H=tAl(?r z^>t5N48CSnn1KA{TK4N52*mpA{%Vug~=En*WVomP92Y-?^JyHbDGenfTH%ze2&6BaHKpFb9C6!UZRVTHg!J=MhF`+;N)H%^???Fkk7PqCJcB zbESOL*Qbq`uVC!&Qn%9;rT3}y2Sd3%qsP(nI&{)Rs;6_^jv^?Jo|TWz)sov=u>UJt z{0;D>H(W#h$#3CY2p#j+MEg7XG1~H-9YEEpmyzrp=h$qm znJy3oX~q0eC%yKFK%8cfpllW9x9Kj zbcoLf7_o)#g;awZ!GB*ODl_VnE92on`kl}rgRJMBzlL|Bbm^N9>u#0=GlW^`GUZ$F zrJi_|$9qKY8QVSU(+}~{JH8+u!IaCMfeXD6@hYn9H~h|dee6VVq50lyw_9Jk*@;@HnV)UeHJU&haUovBxmBf+USgC5L^;hUX zjDvFB)Oc{0P_ZfaGKQnR+M`txp6@oSE%Y;5Z4@8 za4q&{3Atzr;@V5EW^2U6?8T0!x=`TGw*-4C3@^mc5qt}=Il05eZ&t$)) z81fA5yunCMe93AZ?D4TK_wVyz4~Z{x)3KS%JMRM&g98G=*RA5Mz>!|YS@P>tXE3P4aVZ@{HHFM<%j;ujZqE z?(vJ-kUZ40ynDcxvh6RA(lv=AU1YT#|J8!|>QufDrMt!k`hqXpKc$upLHw64AHx0# z=W^y{T_E4f-OJgE`TaJO_NR&2nQ`x{on!x)RwmpgjU;3E$2`koELH^)K_JBOp#^Do5f2livDl=a$Pboe}rHpAr@^@T~8i@8(_PKVx zDf5wh^xfahz?W>t^M?g*yOLbZ*U5T>T7QLZ$@BHV&hSI%t))!XU+Z|jUMJCuo|kcJ zw}UVBVhN3RdPAKwcwg+<=G@M%_o)5l0&my}DsW{Ae6Q=k-(ZeEf%R=Mddp_;rGmht zqtb0YcVy-SzCTYVI!Ml{>4i3wuYNweGPm2IRirnSQ4Z%%h;xM{-fR1-<*?(=z*pwv zy^!u4$Q&)`@g4qyUsZV=)VIN-DpS6oRWF^)tr*8;8~u-g-@6xkQ9kZ>pJUz4x*(?o zl}Bbilpgiz)vs5e^}RK5^n(3crWnReJ*IOG=IGPq$=37Y?CoaseD$2QaSog1KxlQq zvl0CepWv78vA!+N^|#~8J=UY%=Z-7-o&LR^?JqR~?I!!iHzNII99VV)?XPV6{?hS1 z#8+fhFPw)goM)JqQ7hw#uWzw#tiQws)@#XL`Vn8s`I+|*nPXZ1R}WfFe7U|k$lQsI zd9c2HEnO|*OPw4)9`*lsK2Mq}g~8W?*b&Uva^~nx;b7uLcz0b9N`GZ{%;RL(k2#dC z{?-fwU!u?flD8TiD=6Lk@8~VoUwJsbq1h4e<(%gi$b6l>j_1d$#`?CZ)E?_c!f5h~ zxDb7NM^gE=2G&{&zRY^?qss@4?qXgSoRkNDb-NJC#~jnA9_1@TI-Z6861j_${Kdi7 z^GSa#PMeSQrtzKSmZIcY@U_NJD35%_>3!92;!8A{*8=)WoM1gZdq6qV_xjgS(3=id z_|HXF?S_1spF9cuCDI+HaoM%a5R5-+^vl}3o+wZCq4KOd4S$>n$~2Dq!O~?*t#q04 zWm&3k2`4Q~YfrF)>>V*bbK;7h#b_%Gd) z`(aR2CF0B3ex)5BE%MX(U%FiKNXXxJ%Ovn+*zv1nd=Ve#Q+AgJ^VJ38QFP(-JHS_} zj)Oy~T#gXMP24R-$x$;LI=ZWn>;n_K3()!j0aiTBi?Y z`7}L*=j-`LQav56XRv-G%r-;8MaTr6-!_eS#`^06Ume~i08`RKxTmx3>Oq6gj^u+p^wFOq)r6$;4LMz?U?+U(FubgZNTYbMgK(nVX;g ze5V)j<}}p z;Qjj|S0(r-raoWMA=G-0kabWmG3Ll5^yiVqX0!fU+<@e&d;Y@xAZE7kWMTBYYJP+G zihs2o`vK$2By{2SG~m~FzB<#7>Z$7&#`zRN_XwnXeD-Ib4jxm!zYM!1}A?-MLiX;Eq4HfiHRD3OI7z;Q>ysCeMub>g~zsz1n|VKa}6) zbn!szcUDjTK>N4E-3;)Thz}#uF<&=sQGAYLQ^r1ce)k9L`?D@giiq{}rXS)X%WZf< z-y83<@;a*CcLeYM)_onNJ8KqZ{iQEq+%dK;hTWmR`D?bD?ESS>AGRQlOzVCq<|`B& z`QHy#l`=B>#lDbtB}ja*V*a z7{cInb?*ch>|4{D=lDQ>Ilsc*5v3LMmv+`;|AZqD`b&Mebe!ZZZ`|GtzGSThsIOR+ zjnbpn-Yo{cj4oL)pX%D9D9J(WduK9VW#P}zL(0#gdb)N!QySl^{PQRu!)@bU{QvB! z55SkGaF^2Kg9>k=c30^d^prJQcBXP}a?c39B=19r-oA1%)l0AK@6P%w8Te9NGUNPcReala z=r1)tj>boynF(jmerwf(o|K;mZV+gtivbBoiFesDx*YgYEuO|u`GeoX-z~=#szvXy z0wd3bdp4ne;A5O{y-4zq+cSSazQ%F(2jvUhK&(>%k?Lw~%}mhrRiQ^K*1&9v3RbzX3;~9@Rpv?}cv1 z{)vEudz9`xGo1C8Ts8xIbx&W4(o4RrDZrPWmiYzAwPrJ3e|&#+7}`_!o(wMf?_EIk zjPE;_^_S6cETt>mlE=q~&sKmh=T*p4c|VzjcJI5W6YG&y=jnMpy1;76SNlw;j{2#P z(MJ0dqp0u@6g$qyIIexSuS2km(4i6S)l;pOU+u!=aB14=*RK3E1f{Q zkDq&px#$PKMeYnA4};TgEo(DhJ$YPik$fh`$16oo^7yF3no_;KZvKq%apC$lD5p3# zda;!*U1q|MrBe6eeQ=fnQ=U!5zmLjY>^}Ni%7ms|-U;w$n-`a29Zg(+v=Dshw}{Vk z)Z8@+{3I)Tn7O#Y_1pb=9gUCT`Dc#5S0~u7>{9(4@ue4T<^5^eK5uVh73|+OvNpHZ zANd^DU#ZW-KPj^|*&ImuStn1EA5Z)Wd_?s!<~n>)Ud8+3#DFbRAs_Fj>7c*V5bz}e z%OEaHWiHe+)cT!u{wl{8_V)Tr@;>~s;a=!3=SG~@C^Bw^pGfbSmx=XP=1OEwtvI?1 z^QI?paYG>=$5h1On0x9YK1Z%>UIOKj^#_8xwVmOYb{3tS2Iu3Nfrr3R^3FccUw*4uJbrD~z8hmbuc9Wjru;Usvx=#AS3Qz2W_v)A2UmK6TN?e%xqB?VVDnR~v zLV;l7%ekWm$KNYHzerBq^ONdpK2OX0E>$h)Q;~ai2<4+!J+R|8)*Pe$-Z zZE%i)b!_FqZ512thLe|8-Gru`pbN8Y=3N;lBYeJSr76@4%(hb z->c45`20dKc`xK~tj==CEukN;56Qy3UOF*vAL2{K73KH|Vedm!ex->cnW_q}KdKn! z?v$5kY^58AFBbu)syExCDX*@8{%Tc>_orzG^O!VyZcFQVkrdzoe#N&IwEn0DhT`5X zN3~?Iw}o~hf5-5l8;CFY^~Fu-FPRSgR>|MbNUqWKKU4~({A3v0UkNfZJ#XwO6al`} zi-uHRvC#ZY&&x?`zw`WYxmV^j?$GW-8fPm zM*sOtyp2Un7ncMn1+})LV_}-V}UYd)b-wpfBeWKHUUg zRa)8SPw3p3KUQ9KjrzCD+_e(wW1lOmhuvC0^3l27`F_e#i0>CV}{ynoyLuL0d>A&)l1ep6FMjD&pTmnhON z`o{iA)DDik6TWkL>fOjEY28lr*T;3{fG?fI>*2*mP9(lWrDxyJ&T{xeJYVthe)|3V zitjmoLV6!Y`tjm<3gQ zqWS*zq+^TlUcC?V4e9kOi8z%l^0fkAs!}(4ue@;(=aC8bms2=?RZQ++rHdNdvVq?( z1FP})_^IOpO5dG+71dYz$2H;kW8Kb?o-M2|>`$9Lu(Qmsk9nTroCo{f5&s7MFI8h3 z?@u#oLGL)r__c=q+Baw)xNzG3`?4*tzt%i;oc$Bx3+t(b_8W*VN1ZS}KS%SueLlwg zam1HdvTg|SG41>L_IurGVWk^4#@gqv_FRK?)H(%rQoVH8Ro)LJ**~E+e&%yCAAT>! z<6}Seqx75z`(8dc!RG^rWf(Wr%qIm%p0e|Z#o)^^Y8~WyXzdm1f6DWA9*mD7Rfa^8 z_mO>{s2z32*KCJ7r@@|jv7ui9=t%vWP@q~i8xB)(*9W!7K9zJI`( zW)Zc&u61Dn^q1iC^4BFjeFVLdG`kVr>*&erVe&*K$|wGQi#_;WAK#8~dF-3%;A+o> zZ}h#@5@RSnM~#?+{cmD&3(0(W1QA~u$`ppbTh$tg{qok1+W`|iThb5lQTgk_&m~iK z;W#!k!y?Fg?Cfd8rQ`6P5a=B_7yUo?&_38dWNh(Y3NF-d?mw=@LdpIzyI+oie$~8w zBkm^jq480!Kk9*eY(KOpJAX9srLT^({ituD@7!w+4I%xd(p{^H{H>eshg$WJ0|RhR zj`DiW`pdY0_sS->Oyb4Z|KJCYj}D$c4orKI*!~H=mr9*%n1!DA2=ku-zVwUX zRA2qLEcS^QSsLU3UuNK+NA%vLvwzXPUy`%EBmZK3MdtS$N%d6C!r_0lHUjRad{l`p z9AB63JuaXfI&|_)>a&Z>$f9gHw1NSU6k;Sm}Dnec1ORbKd!^ zzkJ3F_iSbTfImJ1eq14rqI1n`i+ZTTNAVv0b}6N6vn=mVllxF_>!2d+i_;78?L_;V z&$%8;7r}q8njdBVgzn1eHF6+s$9V3}`b*45y8bmA=gT>>jpOr892^g!qCDZRv%-2D zf!6zlxYwM{ms1x)S5m)GnPa@DT$aI#d{k`81|&ZlwJ+DG976f1VqA%8&vkm`7axtDq3}N}C14rVa&tmWu zS;7 z;>a+DV~o)`pis)NaGtY=-=ABvnUynD)4k*rpxHNAF+uoAp;^=r46P z4*JV{{a?#a>w96ifIC&BTW)&ZZ&mzK@TD@9L4UeC1pW+1#qGJkm#jATj`d!BrC&;V zpPG@PALJveVgBRzupox`(uwDbp*(sR;#ZBvBX~UM)nXs?m%N028M)&9Vzm38Wo+Mz z$KX!Ah{QQwa$i6<)X!}623$8tiSu(r>`#u{Fiq~S5xc$-7jCs2tk?80<}SW&JopN@ z7!Q6OU%;1mG4((6o2Y{)d3+4x@%Qd`tYZde%{P+yx(EN4n362O&&pr4i{659$m+R> zUoF>u9OZ8Y@9&LriciI7QoDH111Ea)s`|a?ccRkng`TbHANc4?QxYJ*zk%79uW=V4 z@4An+L2fQKU(OKN_s-hhL-F2_Wz3h;o%AT{$6Ke z|3SW;>xeHi#pF)lNbQFFWU+j&TUzOAce#J#<3fthF;Y&%`bp%50QP@5IqqM5J6Iij zz4K)My|Eegj+9GrAC`_YT7fS;j{Eboi?I7sFKe|Le2FYPADp-vdhK4(w5-2Wx!8-= zd&T@-;KxYkf;b1^NFPq}k^L(lB00#-W7$6;j$!|!>{WapMSYH$JZ%VZLfWq}V zQ2tjRVtvBuLAk)!-GM8R|J9q7n6KSSmss_3Z0mA?>MJJ<_2uz#LBq|SZN$G%pRw7& zmzeyF_i@T09Dmi#1`m6f7GQ^Q_tL{4RCwrn_ zsbS%(C|!k>xA%9nV!k3G))QaCr5c~(E7_mnY&i7{cyI3R9!TGd>K*BRaUYlR2dQ3W zXfr>w-@kdqrZMG-FVi=$IL1e_ChSC6x5Ya2+dCn>Lapzu0A!TkQ9sWGE8Vels*3}B z$@a$~*CtoO==rJPbMiuei6Nm!hzpso6v`tXbVYkQSGL9TeF|Y7@3``X{UxgE0UFn2 z*{$G9ok@2Ed^zjGAK=LPa~!%|@_JWDJ>H+D(od&(tJ)dff%uAE z^Nr&+w7p+>|J~xmm$OJN``o!0mb35TJONg^I+t(-eChS9zvhJFUJB8zLv?=dmJU>Y zeYMS7@HMjAG3YNxxBBplGL9TAiuh$Hd4CwywCd|MGX3bt9NItZ;Or( zR)8BC6`QgD-q^?bsHV>iO4okP8t^zf4ec+crN#L<>beX2zodOW%&7uL zp}&@#sLuSFb!mT^PIiAA`c2xrO~IG8<8#(%_#33LqY?NLec`89ACDtW!qM&C)KKgF zmLUti+TELWgg7!Qy^;v-$Fc-K4Vh zbWlGsj?Clu3GLDX?KXK6$J5Q(`xJc1w(w7w)swFWUq@q?pq-5^dm!hO9!r?pAx~I; zRmMIo2!8w65ZPu)=M$N2%(^SbtsZwcN9v^&o#n-FpZBz1q@@*S8(HPEfs7>|^HZ&DRC2 zzihu~jqMm8m6@9T_x3m?I#xxTmk8W;68g*F{n!pO?mO`%{g3haIm(Ci*U3dkp}%~# z*!~H&*UY-ZU=ONkJLaH2h)5r*N6y!aj#Is+{&_h9^^vyT+!=-a9jc)BIPj&KgJ0)s z7YE5zo|tR%m6QAP^c52z?`E5pfiJVpL2%(U3Fn*}o|j9q{+f{s_oa*;kM+gd+m4Ok z@#uFd$S0;f&b?8Yo3`ZgyxEHM1MFXw)mLPLeeYZj{UzQ^WdB#OM)Sff7w@&_MV7r|kp7b2{k)MbE3*D7u`6AGm9DGQP7RKw zy$|8#C&XWhfpcxH1G}KUx#~iHxt=JQ2>m5}oislYqjqxtaExxq^6%4={EzBT<8vry z@}?&_-H4lFrOOZdv0p+Ac{~~E(sk)+PhTq|{j>oj{iDQq?nhLE{<1T4Zg%d?r)*Frjvc2|L2(DG zFOSrZNq&>BRe&4@-ePeXr+*-t2cu{c!^ zYWMbgR^uL9pAom-w?^rKfxJ>gnk@2w)^w*Uuw*SjMXX0K^LE`J%v<21i zJAIq&tS-lspucWbc+K|Lf6!kS+;8*x;}7?b&|kV4?=w#<0lrkdojt*qt~!VKG6r0{ zh4w3;kF)>YOw)gnJ@Dd?TJclWXX(HUQt<5&N!5Baol17BZ?Z$kMT zX~36?pRtM3WwEF#$j7*hd7KV7mzngJYCDzvUz+a+6W6MjrSVZ#y=?pMBd3!7O8Msf zQPgWsLvOU_zk4Su<>2{a1`jvzW%7LnGNjG}@YQgkZ>W`@khedhJ+~f){u-YvWIXc~ zdJ^dyPT`yx84;8gd>QUJ;Qx9WTaMmmwhWny_7thE(DO1h>ps*oPj#$+TL&Pp9d~2b zA;{aS!YSr!FxEr#&e-M9D`QtR!1$<6fp<~zUJUY;6BX)bE(Ujo^LP*N<+jU?`_Inu zoGtSbU#iGGw(k|&A>y(BdGHmPbd>oj!`#)$lAiccJ}KCLFFo1cTdGMJ<>O}zNy&WmoJM@9(tUQIzB7iE;PG*k>k`in z)(`ljyRX7}zf(9l4p&{re8)BTN(AJZ>dJa>;XH?O>0ig;zxS`Q!1jOH_glrwU5%tA z_tv*hL+&Q;*AvC&VPCh%_m0nxmWSA0_;j~C_&WM$GW3*b$KMajQ-}Bx9k#Vcy2#x% zgzC5ID*SqS&d7dLE@AT}-8&T}`OMsrSP^_V2lM!wY0Nz0OXR9JER_Blnc?SD-7XBG z^vJ5iSAs8jE(!joA5X$bKBuO6v3;-3{zv2Er#UB*)BBvoFY|swS#As3VO2fcOC^ra zYLD`$@rWag4|mR@|94z3T!6>N0r$c0z?%m6YO=B(xBs%$NN-xspyyTF*coUy$M*n~ zr+T9_#Fx$;9SZ(bBJ{qzw>u4SArJLuyWcUI#|e*$>xnOsz6YP5qus!l9+l}8)mN41 zIgPpgdkydXb@2e%_aZ~FKHy8FPEG0V_s(&Aw@3CptdHDQ(fsPuyXbLL&fDqp_Qp6U z{9coN?>e%>FiMw8Qa9lA`0Beo{j7}n6FgxA?s+uRF6B5Q@!&n?5ig^r((gpgT)aNy zr~!Q&eE*Cu@uNys-p}oC`zIdFxe31Rhw}M8PEY1&T;*gmK8lU@`?3c`6pF+ zdY@0D!(&*_JW8N;(1lyUzBk1Zj^_|};MY-cm*LNr@3UrR|LR*lZ(bGeLVW3~efOcA zP2&OOqjuleNcpOoSxT_|y)8f5KW~$K#Fydh!SAN7Iy@PEm26B~gq`Hkgj zwC3|ovh~c%_7}(BCUv`nxXs&_74PqGZiHSl(^XU?Z(~6tw!fq&{G7tuy8zNRd@lsP z%&6A1{wQj^W&de}iU40?IiK^@WIyctbt?~bMtRJQJTL1~>^S~^)RcnYOBdpEa-PI> zhW;wOxEA!6eq4j(Y$QzE1HQI*;(Julik*!yLyzmk=LUila@ zALS4EaEtYqk1$CNz2`)L$2kq$SWo5tK>H%p@It&_ed&4JD_~s&8yD^AZ~cHj-pl-- zQ+~2r#XQ_UcRvPSr)FS%NF?;P&j(nAdPIMZfqz2%xWn-|%HBT|`~&+R<%c%B{^%GC zd8ms47l<$Q_e^E*Wkm4!b!OrmjE@bM+3|%V@x0@AitogiOiW*exzovUe$JaoxHr}O zSST;*uWqrt!+lDSe9Z1`-@$)xre!_Vv++dYMMeK;7i#?#VixRvk^V^(rJHVD_n`HLbo9&Y z{#Sno(R*d;M`+LKzXqe-!y68O{u2B6`5U=mf9W>8F+Ud0S|NDeTj9J@mA6Anw2Pj_ z@;n$`9$Z{qUxM4KEZRj(b%`SVr90Op}kXS+y1Rz0C5U63XjLhWD$<16SjBp))x?N0mXlEuP;O`~L1VUl4)zx8s!6 z^&6AHQB<8h(5sH-T<^x^yeZwhHi*yvk`<88fZoB$!Poff-H?xLz`P{ImIPmsQ)(hz zL|3NqQ5GqU^Znk(`63?6ni#XZdxd5r`KU>=c7ZR|6a1>eq2oxdk)gM9fiIPUxo&SR zr*voX3_~Yaf30&3cT#(*aWyJax|uO5BlA`1<83Ql+$~%Z{2VyBi`zM}FP@L@&3rXm zQW@Xt=4_W`-pTXFH8IDSuXrbTIhGmmU*g;Rs?1j?;uxH}zn`Fd)%4lCzrd)4aaJ~I zgnOn$-8#H(pzQdiYA3;$=rDrk`_8>AH)G9qwEu!p*TI)#9FG&7`X+~bCZ1!ybP~>U z5slIyjx2iLQ1nl0J$Etc)otM_=-pS%0y#cMr*A{@X%mq#fXZ3?56&^N7LdkGqV!*U z|FPO}-iyb_QF%i>J6nR|kMgrN97v1%tl3Ml{9g0>bG%|ZV#qz)zuFw-HFw1fN5B1) zjQtbJZs$jBXM?Zf!`MF|=P+N37a}g-$oQoa^p_()`zKm_8bW+I7tix!zIgpZWIJ=1 z_;OC`X77J=@86&5ad+i7>Nl$6r(|ePgU>e+tMX!gB$~(01z*-qcC=@MqS()<>fX!~ zYW>a%9B1zGSDHl}IgH#K|D_)Dd_6;;EBM-*o#Q8ThJrUBzxS}eR7~h}$j2zv2l;P# zj`cZ5)r-77tuA$;%5)ySFcGn ziuKokyK}63be}y3&>k%d6kh_3v&GQgA(^Pn);UuKPnAaE@^Fkh>4)Fm#|j0DyPVl;D9=>z;z(eJh- z@%We;{mD`4;2o;3k<-NefL7oW>_m}e(qQoQwT8Vem3P)tt2~Y`o|x~6((Bw={);un z!Qno!sOOO6k2w9swprHmy4>{5NH0I*B+})tBigfzB{=@vo*f7Os@$EA<3QBH8<3MD z7XDRTFNpmUn)kW8{&d6mczC;vf!@*oalHoxEGLevYbS4GeAEZIovZKv+Q>?GjCZl) z?+e2J<$M;%utTzr@-TB``jAINuKG!gb#$YUhQ2!-+3h;)omSW8W*U-X;AY z`KfdbXM!)oK5xGKsI*9*aHC78^}W#PIX?Pxv%Hipu2=mGeIC!x zTKI?BU3nZ!&+R`t1Eo7Jwd3*eXcoSI+X#zC-0a)E!%2VXQnhFCdl#^tns%xhapBAn zXrBw_!|6ZI9qdf`=gy8eMxps$NZoBR>@RWi_&SWs`o#&9r`gLKl#kf; zRoXqUi-hMY+dq-}0L2&R7Spk=5*d-KeW3L_OTqoZx@5mW;7dJjVee;q_japiS9$=S zq*LzqsJ-Ow^Sr-9qzp62 z4{5&7SGc;qCB8(NQyl*#-*P@tLn_nw_+o(DaOC5(&r>~FZzS=hKi;?FSCif${=Rby zzTefaX+H3!4zXNk1R?%J&h%f!eA)3o-uJ%}FODmx$A(&eg?PvF-zhHG=jb|p#V+Q{ zc@y$(dB~fdmrdrB1z);u_w$xq#k>I6uj+V9`@EVy6(FC?rx8b-w5n`(l*gR17Wr%q zfInMIzsBoBYAEJQveMKcG(O5YUw5LN9cf{QsDv%Ii63p2|A28vO~iad#C@6wz7~|3 z$ok8kKNdX5@e@l*@VcZN&iboO!>z=Z(RuYZ@GI>2m9YL@!OxJ}yuPh>96{2Ka6Dc;{9mVBpl8Mqhw;&tD89KUMtJ|6vg z2JTl-x82x(FK)3Nw0_5S;!D-8T?(A4r#z2)ysQB6CC#zCKBU=Bm5aI$B)(k7?z8PL zb1~^JoqS&}s+a2L!{;?i_Lr%QuilbAl4(cs_~;zZ{Fd$Zj(E|#299ICesdgY&uI^= z^ytm{^D6M=xV8`S4jk%A&u{#)j^~fM{J1Oh-d4@CkbG2{GwZpXPZpu)^>}~yk@e;I z)xnoe2fJTa{d!9c$l=5{h@#x9ptc^8 zv)-JD{vn18?N0j3xU(DMf_0JB8CnlB%U*tl_r16kP4cijMahR)=_};gPmCzL0`E*+Rn>9R?iwctW4 z)Z<$%Z}?YrpYTJ_I}RQn#gq*O?5uS?*njWni}BIC?Kg&sK*1iu>FO>EgwIW3Bp$`D+pPEj==1M|}kQKdfV&;;3FK_TVJwFI|E2 zUy(VH)@(xA&d#8;jy)T;umVo|Jt(xz(-fQ^3 zeF=FtD|G~a#peJ#|9<}v*r6_md41cg3_DJCau1{OshmS{fG=lN%m>B#c7LgT)xphM zdH#4Qf;f_G{%)XrgEQ{C$@;4W>}=JosxR^7tm85P?{zA+Ll%!^`#!D7=W6PHT;HgD z!Niy2^~>MjNF^cNEc66?shcY&5dv}C*`hwOU<=UV(cwf_M z=}8`zq&m_1uaU5IIs9Kq`5JNhui?a(qwl(!XpfF@n$vx~HhFfZAM$5)~4ekiJ&a2D&JEZOZ>e3^Fm$b?|$}5)j>U18zd?)%+ zy7*nR9gnkoKBfx(2LHYOFWngCXf8kh?Co&kOL?UFw>}g`@%JL*l3bAgmcQ>%PW${i zzj7~dUYv0I)dhSxhC+WuR*`4X|DH7A^C!ePj8nmFEA6LrrKca@@o~vv=!@I)o|Al> zKIck-FL5ehh4o%tFz^+<&n&TEFWze`zeMs;a|-ePv^5buAYW(Edz3EAWuHX>tcMoxndmNYuf$q z*F~&vo29+kpCs+L*3P$li7)Z1hkbu7uRp455q$n?@zy7xANBmFlz*Sx-H#D3j&(ga zKFmx=Mfy~xt9cde7d&+f`?H*lyIbkz{n~fH*O=6EI6eAs5Iw)3(|44AuxHs`^nNjH z{shk+^bdS`)|};peEMz(K|OS8?&rBb!~Rm^M=fRjH30K$zgk|sz*ouoe14Aj&Ro2T zhM!9@{|4&pT>^_U(!BDG^kZ?@b$NoeZEQL zWm^AIQ6s%c{?}b{JU}^}xA9&*VbTrgHP~={-h2%=;Z9 z?p~pEpKGW0Gha;>f|q`Yo|NuPH=5&DowtTRwB9Sy_DVzY(FISk{?dH@s(!pSg6iqo zZ%SLpPkTM2d_>~fBlQ2y*5`QsD6_modQ7@D#Fq@HJQM9K{v1U5?x)zFCWeM`{Jk;$ z0i_#_hI9N^wUrA{U&-g^sGv3#x>@-M|5k2DSK%!GfBAkORkj--5afyU1vKUIm(zpv&s7Jje8qA2^ngr`5%%k|Bi?$-07%demK zYn>=U@%K|FMfy>F^Zz_$>#vPjhkEw39^_A@USl57_o`?*dwu&S`nlS)7RqS7eY^k_s6=4<)GpEjmk5R(v7YuIDS=D<9vQxN`>+9 zO8o%jW7_A1-P~K0_>y-^cyRu~t~lSMYfbQ_YOOm4xf;8We{Pk8^PqL!eFfOQUx#$# z>!%CQQ`K(Q4Yl$UY902?=-q+1ug+YYYcBW_p(f;Ab6;(G-lgmX-oNdfnw8eK#qR>_ zzfT>_95}|qZ>3*noKAe@_DsX$wQ~a28C8J~h$m1>{7wd0-wS6W^h*)u>p^_EUrx^V zSm^~J;OJcFIjWDj{1ES>7G?3gO!Zo&vu zQEs1BocUVB@;^BP=N5}ruVZ-p9l`$dI&b<>K5E}wod0O8&;7!9-EDfE29&<6%|(u% z5M^3ga&UNzS<{`;pD({izq2&pK^j+-Uo)&%h@f$aY=6mmL7u(n0etkY4;)W+@rNhc z&D;-t9=RbN>)X{2FR}Nhu92YiBUleXW2Yu6J#Z z^2C?gGmGPM>~n&JF8&7`#q95dd=%>=;b@KfMTKL3edfz3MEY4AX#_uw8nbUJ_uI#u zf7^11M|DkA{>upKJywIVy}MxWIO0XT=+6Ex?SXm;bvuyK<+IMrm+5~9e4V(pC(ugQ z*^*N8__%8?%^#gV3%#cI>9sWxCoe?RHT1lUF4Yrq2zlBH`b+HxFXqBCbI@OZwMc>S zQBUD>$NV1DCcd1dc05Hp%PM8?-h|}Pi+WFr514=Hmpp#7JFyyk#k63%#l8<%%pC{) zWsJYZd^rkpyLb&=)!E8lJk0OId>v=LX5V~A?JlRDwcnfNJI3G2Q=z{cao4dQ)C%0= zIJHkVYoR{h_i`MvNNO;Ur}75$pzp|`kT{wV&|-OKI&2JNhj#4E&? zs+;l*`jvXi?Y!`OFXBr-N^9TGcZJh^eV-9us(SPYe7@e|Ie^_pVbG@iYp_7^!r zHc)#`S$W98{i!E&q;?=K&{!Orj?*hKN11kBB)-&?EANrN`40Wbai;hpl8^d3`5Ej! zUCf2@*C~%KgZ^?$wU_-0GaizCZ(d$%pFi2A4*I8v^rZL#bs*bDs+SqKjs4c*_FDK| zKlKl%bXC3I2Y%lFGq>u>|eF-?@)ffaK4=Ge(omt(%jCG6;rccY|zRk$VV0eU#f5Uzr>L!88Hrg8EmJj zC1dhax-Q+zw(lD@qIx)fM}RNqvABg?&J)a6k zO7D?bP<}OU`B+NN9yDYA1WMP1J<$GZ!j6*ux;Jn($A9S}8u9m2cd&n=>5=z%uep07 zJ+Dr5ok#Vw`b|TUpLNY^6w;?2#yoyh_$W8}w zf9WmXi=pdbJydjf^Md$_zg0Mj-+Puhnkj1#7dqkeZ|=txn7h*FUxTj#4K?_(&zDjD z;|~&F`dSR%49)&VHDCVTdwf8gUcD}MsjPgeWc3iXhD|CsvLg#D|7 z2ioyD{a}}?nGu7iUh-_}gWy8&`lEQ`iTE7lQwtZ{ zN0I%Nbf#h`@{y-m4;C$OiuiISA7uOQ{fbfjM9M33Nq=c07snGwCqF-UFZL%#*Y5os ze5tf7?@1#Qi6dn;_5fcxKif6YmnMU|mo1kwU$bgL-Ups=+}!U2Mws%h#vWPd4- z7MalgrRV-;`JC5yzG7*dpCguisLgzR#rlAX|AGBCs#=Yz;7hf92JXxs0|!yQOHP(y zKfy=rLz2z{rT<6Ob;swlJpI+9NAK4WMD*x{$O;l&^a$YyLDV36TfGxK2p+k5iRhix zqb7Ri=+UEherLY(-1qZ&&mT9}JbQM}&VF}hc6N3a@7I~=4f!lDY()Kk+;bCNM9^%W zPtuvMH#T2;8fR-@`l~#TYcTHi7k3M`>8fo?w(pI);DcO|nf=cR}%(pkD6PtRENiy01)0$S)Zi%K7gtr+=bq zcwWMh5fOHd`@M?g%eMBM-z1}NXO>^NSdRRx)&lFt9sc3Km;S?in$&j~;Y;01<@A3g z=MJ;`Cj+`7K1bY&P0jO}{r9Sfh4@~*@4ztNOV4Hf8x)=edb4fa->6^J#`;l~DvA8< zkuE_qfiHEW5XN)$&^9#x;@dTJWqeiAIPZ{SB=!r`)*IK+u2pm|m6v@kO~E`%^N8^! zhQj}>Mm0Q2{48HS*^}kh%-d8xvP{MV;HzL{UmoX6%ZYAYtNfMfwNf-~41DRE@9{n1 zvHuXhn z`$lT_E%;Bx^S^5tUs3Ib`}Cp$cpSYtT>!oc9jedc=8Ji*dn7`yzV7J7`Q^kGmJ8cr z>QTR}mq+Jg+$5iK6eexkhEHe|5BO;^PlI`_AGWBnM={pc^kksZ;^ zdQhEXd^PC$v?U+QP3C;5MYuH#-3T`%3Zi1-=TfA1HpA4NkxFLyr(`Q_3qKlB&lpvo+! z{XX;P4c;HR_nhxBbJS<~_;Kq=!k5@wG7q;Ki}@`w*9r!{`ptR;{F;+^J{>9hn#$`I z{q6xr&b$HAZQc{YkD24aTW+`cZ<13o%5~ z_ke#tK8+%}d9FSCzl0C)qBjQNUcg>cTsi(;e&Knw`qIn#RL`_jjC(no_349l_kg=o z9oc^`OJbf+bqhfpp*j^Z0^{$f&GoEr{S5f3nWGKpV*M`o@7q@ihkiU=YBum|h4H)% z9*=Vz%46Naf`yavh%NXYW+Zk(dUsU}vh$j#tf%(~d4djkk zQy`q{Pl5R=(o}dAO!Y5cRf6$ViRWMZMEDKVky@wFuKbi1=aW9APXT!}w&TZ8`#n2> zBK&dc;TFViIzGHO20q&!O4=V1E(h}hhueB&hM(2G*(QMKJ>I|%FVfuG$o-0|-`%H= z{R2O8yjNaYKT7w)!Qi9g7uJumL?y&Ai6tvI|Ggs%a3Okk#Jh#=^~*$1q>_6{&`Q7oA=ZsTYXPFxNKZeQ4PX z`c$+D$_;!4ZuMq8yN}oJ_XZ9RvD+05!~dW@Js=VFFI_(g<-L!mhn^MHVfTrDCh+?D zMy~7Nhi-rI4&kDB%Htu@{(J2DWZ=tsz;U^Af`AuQwk_wW6ah2HK2gKl@VT^oW?V46 zCp=5jxag7_*#1hl6zeA2j;prLr!N)2qu;rG0)HmltOR`NZs4DY{=S6h@l*dyX8Y?C zV4qL|Dq?`UnMc$x(7cI&8fWW zB#!?w`23Y9xT!SZOAqmNo_{oZ()w7w$ubFibDvWY^{e@4w|b?9$g3n5FPjH^IilI_ zxTT}P&(w1nr^Zpl9qFFU7ZTki=tp(nOUh0(K1QB@&Je!l&YPfsFY9_W&_{m9e!5D0 zdK~;QW1%1AUI*gu%%=UGf-Y}k-K|Qe+fIBl({_2uN- z+f2k8>E)}>LVh_O07s%hvz3Gw8U2*^$*pFPgVxTLyF+Yxa;guhS$@4_zg4;WPk^s? zJ>$5Z+NejpTZr>7VqwF}jIR-`juSr{%V?@cjN3PZ<=2fB)L%8D8}ywV)C>8|Y|3TG zsb0s15dWj1PH>)mVfG`xzCL|v7w}WUr5DSuo<}D6^s_5=KCydl(C>P|Hm4u&GVEYo zxI64Goo^P$f5}_GOX`>j$j>C+y>Z6pIM3Ja$%!~ZwXO^MC)7}szuBoZ^5@8<6Inls z>MZBCRjfz&GD|u4A9X**Y4xg=314c+Z>N5ABtbt;H%;K{>QvSjYB0;MgxQF97Tb56 z2EI(rt0vY?Elm7WCFZanO_kXM{<$A0N%X*jzkL~BO*x-TgFF8az8sB8E@S<;xHs7; zjwTCWe~I;)|B9*bPnhpZ!wwY{YNh~x)n1IhD3cQB`eghQmR~C9DYYxQd1VK_#->id zIG7)gKBD@+Z216u4)~Y#qa)>AlwbGj2;s$;e{}`RuN-WjOfDQ1V$)^0=UYHGr~W|s z-*3|5p1jTbXM<1jB-T;deeMUew`KQf;7jE_7f;{ws$l@tqX#|@q<#xE7WRNh9CgB% z{{8n^C)PKHC-7Ch;~$a}D&--Lo3T9t_3e6w?HCkF{Z|S5j-h_ht?4A6{&ofY=)n^% zfK5$N8c)h@L_6kr$OXsVg)K>bs86AsA3*T_kf^>MAx0tvj5AuPE<+XvJt-2vM}~fs6;Lw=CP3QWt30J`$qOXaQ*FmsPUnG z#5dJXLq7{KhRg4+7)Jcl0nHMDFLi|N-OLRtp}#k~c88qRO-^7O0)K5Le#)X#`T}28 z*;|AoF?{Ddn#Zbbhkd}8cJBoHJ4+DuJLTCmu)~G*nfJ-s*b z*a?*u^HmJmw>-qATcOD%S&q9fefq{uRNirQ<46s*U%lfJOyl(_->+uA(v0P;$InnLAO@v{}_-;WMo_=9m)4YHCPkxi~v#r%HJ zKZwVF=W={c;rhABj$ZHneKPp1uP}c)w(UrEx$ckzKamhIjHAa3w?KXkY&eSj6T4Yo zuZd>)_4WDz=uK5`J^U`4o_L4Y^{Der3b5Q6=|lK3-Oe4yyqLYdC+vS=btL|)53hK= z`ljkFrpH&Ldx`X!2M*w*V^ic^usORo(r1A9@3C|l=tpyNR%bk91ISzTJdo|ShRLIV zFJmnF5k93f%a8l}7XcThGyZ;N-^J7)%5|jiLOd!rE`BD^5tSC{qYIJkcvuzr-=QC=PQ7>@ZF)a^0LFJH)C z-TO*B;Yg;fI+^SF@qorn2K~-X^qzs=S$>II*f$it!iLg(RXtuh?;jdFm&*5P*ZL#j zD!h!rI8ys=65TPeco*uYqt0%Qn>K>5Zzw{;u%9dEbk)F@`U}0|=@Ry$pIu%K2)KlC z7MZ4zeJ{4=Lw*7CNfW1jEYItWI{!W)yr=>z#)F@N?Ex`mbT8nmnFsPL3lYqG?tI1{ z_&TxnIpm{bIj_e~Un-9FiuU;dKFO3#2w$>T{JIdke(|e~7x6;~U-VZ*b?Q^s{(jiNl{B;&xs#E~3AUAU$aAp2hj^g)?98%v62- zY`Ttb!1;6jJCD%iLk_~1@_EAg(Q%gR>F56r@~dO59$bIq@BVf_bR+M)nBNsfBQ8c* zPJOy+M@QnDZr+mp6M8An=X3A&gKu4CIoA){U}xzQbu`H-$KUM(AiwNHTZ9)QRo`bc zZfbU_*N|V1p)C;y|2-?@mdgFfx&L?;`_-!2JoqP6z|l*PYq}2Ph2!{ptc%P)UapV> zju`A4iLuoYA1z9^=6giNxbJ7}cCD#da}b{`kEtA=qsKi<}a z^NKrqETDFC_Hto7>lYVUKgQQ0IVEquM_jVp^P~>z$H2qnmyD~?5OEN~Ax<#9^p`0< zgX|9QQ@z;{_`mdn_IzHzNZ|GH*NfAs-{DX4O=El|L#_q183eu>rK`>1@prBtd-twG zI1+Lz^2*qZVZ4mlf&5?MW){AmPi$a*q-cJW~sCC{1M;ZxC^f@^f>09r*~n@%koF#SU<+$J0p+Rm_zt-6(=H4kE1R0yNaE#7yMaX zIt=&{5wnS}veBBg7`KrnZUSF2_il{ynko+oKWff8KL6;*d57rw|xJO)4YmBPpmAWCkof_Y;8PD}CEBHP1n^uBAw(9EFgU!6%Ws}&!{ z5?)+yu5$VbIQ~m4PI?<+)2+gtBhbG7m-+Dccp}!1^{@3{{rDR8y`y^SzQiAOwbcOd zPpi~qR|bqfI*0HjS4_*!`Z01F=|`)?wOyDO=U(&yKZIxg@islF?b=i5r^^E8d61m{ z&Z6(EG4K(-qiNVlE>eaBD z<$;2MRG+LEzJ$lksUNo<8BF*xtiZ3ax|+MPJa8%-@H!#xV|J2Xt_yoQ z<8wGZQ*6BAM!3@{Cs${DRql^-oPnFS5`PlCFSkSejtjt}6+G|`@kgzV-U58dde95% z!0s-DFHz`H4%A~5z7M?QxVDAx6+dueDDb7X^(FdiN1;Q+AEQN~v%r@)2s_^OP?O8V zm+F~zAWloj5?KF==ux%kJ5}p` z_)^C*V(>wa?T`2gG4C+n17rGz!u~4zsAGs-UNl@=8GO>e4^q44rhQrKQawEj z6?5uGqpeLB@$*aiQ~8C>JMp;aJft@hH+^r({Y_mB-*2A)2=Wf7|{Ib!(!A*(9W!`j0?p+gf{pQ~`D7tEZN@FiLoD9!!wY)5)tRUWqs-@o^00Q1`! z7hJOd{H0I&ByR`4L>k~)G z%^Gzle5ruunP4BuGBwWI{c_wJf%StJKjRwurvf8TzDb=Hz}Jog{n1}3nLlQQgb=$P z*>^kQH|&ewxW9|a4~G2e(C0qOuRIt>)ho0X$uBu{8|z=WuhA8|U3q+`8_6$`#-%>w zzZ?m>(r?M(F=(&G%3H(_TLWGkXP4K1Gw%Yud;tUUU&IxQwCO!ZKSSKJ3L9FT=~ov{ z@)<%e;<5U!;{BnS8F>HEG3YM!PmY;8g7DR?%on!rEs1`(7H`~)+Hv@$WBsUk|55D@ ztVZ|}>k@Y0I~;tzK%C54jBu~+on-xJEQb6Nw|aae9H~4-TVVXP#eA9^{08<{wonWZScBW4Nf zM}3<8>-7%|!n_>Yw<_=@JM;cyy1$5vSLX-sX8ky5?L)hMaW_{a>V0&d<7D*GE0AmV zM&~4aHEA8^wC_3JyIQd^DTKZ!dz#f~Upwd7mq-)xO9UQZ`E{M~HN8Ci57yehIa&WM z8bQvc{8mlV4+fvA^%?{@sn{PMm9GHj zzt23B^`rBAn($tN^JzxVf_>cYm6+$2XLpNmCtWwQepID+{?B#sfPQQ=*y-ou^`NNf ziTq#6{N%;>n(0CFM@BcmIc;@vhBxXLcX&P@9n_BaBR|zx!SZV!>@RUI%MZeljBS5w zr2W@++}r_MGC!*u>|$2 zXES~2JIv3q%y<16deF0dn*QKhtA|;EFXab2NK9Foj^vlvcpwMHSslAbDm2EIf` zp2xik<|6r&xUtk~#zidr5bA*$hI-s(X~=n1lGh;-7kQsy)2d&PZ$gZx_z89LPh~1E z*EQ*l_k`us-lpq+OiACNO5Lx{^!4`rX~V>Sj~c&fJ@}E;h3}_O9ysSNo~*(Cw#@g6 z?hPT_o-ta{P8Ka`w__E**Ouh^%}{rY@1=4&kYt$Gj0OZZars+f$g z58!L^ztgt^U)f%70KUWu_D>go;Yaj-B@-F|U*@wNm{0!gT?k*Q(yB`n?Z3itr6v5X zdJF6;l}$VKU^%w$x*sVFzP@b5@!Adp>j!I1TpQx2GIM$XU%E8DN4`Dxx-Zd3Zv4gL zywd?Y{%tAq81K?q_~(eUu&gujze(XXHDa-g2JRYya9iO(BBKfhz7uU(JI5#+qT zL(XCUM63smqpGuq<%*DwM)tUfu}iUks$yLFpdI0QrjO5X`v-o)Pkw~`rOxl~2KgmI zVMnO+o7n&5S)dQ&!V~k>sL~JqP31Nyisg$lE~(P8e;}uFKVth{&EfGknr#Q}E^RYV zkHPnjip0PG!k2U_!1;4D=Yv+q&#orDsb9Wv?r+Ccg8kK_YdYeOT9hpZ^ECtN*B#EB zp!uhVsj`f(*TApHTCNS@NS&y^6ZleD?*T`-Q~V?xnbp3w0KP1J4&xb@{R8Ct+1YWx zmn;T8IDV%70QqvrA93>bh3~+Z`J{Vm`VL3SO>E!G!xyO@*Vqib2wztEPcvA4wSzxa zbTAONtYz0;u)oy#pBL@&arvBau@$`BS$`EUsh-5#Irv}TNAvRsy zEDL|Sy)g?tC{o^S0Qr@t_j|^dE01H1F35Xe4cxbj<>s90Np}5K(Tiuve;d`wTn1dI zktL{I-6Po#`fjwxW8$B^(hTiu(`A0&F~o;NzupUo-?l}acA8BW^Xu;-x?H$(0Mk?3 z_Sy(4fG2R*>zkNwlXVToR}a?P*HXhyHIm*&02gWi=7TjWeiZT5xaq^^JDm5JiFAbr z0Y`Zb@%bUe{(JRzR|3)X!0~*4hk1qTk9G-!{QBt5`-A_T2PyWB?;na#PJAVo?P~YK z*l`v6*k-?4@6mq|1ANIFSCO|^J@u>!d^tEiR)kG*C;kLfTDF4m^#^v4?F(6_c$uF6?SW4a>>Qa{Eh5nX#4){K%#b}mayTfVx#mKwZ z?}<;-pK&Dkyx-x1jSq*|^*H=LvHc~T`?h`kT!60(w~jNucA;Il=+IKgr&eq00ACKT z%w*q*v>RPW|1DUY-wpWEh1XJljZ&pvfWHC5+JR4^dS_a{%Naf{nAaa3ykUBvH|WEA z+yWo!K5}6^8k=VLjIFD?cy2JX^7VthHSLVlTkC9s}R z;njHk=-@nps=eJ#L&vsj)_ z-Ow5I;P*~^S?zigKdzj^J-=e~zvxzWEg)e2p0sylSHTSExZ(!0*6U@Xu%R_``OVT*LDt z-t@wEj4)$(UOr;~*N$N9_X@9`#Ua0B2>50V_P9m(($DufFwP?6JM`oA%fP2BcX2cD zrLuX!E_*!&{&?wmnEexq&#PN+CT|L{>ygo|qS3zW1U`%MrGEw6bXD!`1>j4@f)6TB z0_VF)pYA*AH+~leA2J$IgfG=9e{PmvKQj_tb$PxD_-b3|9JOO}a3lFwRqrWmf1bVF z0QCsh7@SL;d^RP%Lnq{8`##yx-)9uPh(|UajQc&5TRz?&5+!gxF8;y5Fv6F4v)W>o zUrB72_rBDW>eC(zx3m3qo%`p$AqC+}-TQn3?TPZBtBBONUsUc&$NP^~X6P5;(QGr} z$g}0e0jS4%$a*bHu6Tt~2pL1zfJfe7z4ms;%>zcDLzbXZ@Ct zUosWzi>~*u-y;{DIK=X+0{rgc_~*UE2Yql_Ti{DS9RYra{}~uU^sVk}f2q}HuiEYE zJp17P5(BbAjtQBG>;Ds8h`vLWJ+lw^(uE$P9`|9jh;P-~#iwNb7{>DM$~s@d*L<-= z0AIRYF_K@2b4!KL`?BSASB#rpJO*}9VqL^T=!w;Kqrc`t=4b9J(?Y0x1;5jvJI_U` zqNflqrdmzs`~&(E@MXCMBkoJpU&#B9df{NI-!(S)8sTe*Z=XNlpU8d@?WP?p6^^2S*Y5k}I4h0gv zq(|Knj4#FfuK6T0@kf5y;=}l=iFU=G!vT=v0j_I+FFlCma_69ym}d!B>i}P3_ff)y zx&CM(@yAqIk3fDISzwpx_gN8_v!ZfGj?YoUS0p07?!OiNHF*6f zD(_wvV%Hm&t}5p#Qj3{ylf8}w+jMc^W_`#nD>c@ws>HiJq#yO_A?JV#<$i(soAe>! zAobUXh#m+1Dbmd%y4B@z&bl^TP0vvr<8DX9Hnr(uYUz@|muec#_!5oDE)xq693*_n zHxYL^u2nV+@EK$Oz>lnZ?HTZudp72gFxid}Yu2(K+Oy>*mS2&uUqtG$$ZsOj{=1d& zwTAnbloUqz5<_=ze2$|f(>M1^L-;?3a%0uW;X`oZr{6oavdq{!8*p z?OWQ8@fF#W_J_>X&GJKjxs+u8m*)6;hijkbu(OWdn+ALdXI}2?V>1%Ij7BS;vVL3+ z`zU@};~ybZf3|77Kcp+iK<=y>6iNJ6MGLThLUmK{f1RC=eG#RXy#Wps+xMcTg8xh1 z@jn5&UWWZ`Ju3s`ms;Gg1vLB-U%2l1xP(6;wS&x7(Gp{fB5S{Tbj)GwKL>Mm|S3H>%V|C<|fYWlPU?l<4ZA+q^@B)Zk5m{8pQuq-#uXe3C;W4>dCB|gfDYg#7yAJD$9Cy zhu3qGQ{Q&a`U-p*sn|bpYV55Lo38v{wH#;v6;=Y`hyyNd97*^xJ)2&I{1TIHV?L*N z2DufP`pg&b$7DZ^4(L#v`l)3S+x^NL^1@|ObL5keFFgeCr7!U~dlad{^6N6=%gX$g z_5nrWuVPehz~JOdjIY&)fv<=l>?i622Fod(iutxBcWm%$@LBC*`uh!+gKfIl zb-6j@mwp6$z%yX<9Kuh77gO#4U)JS?)Gt+X-Z|>8Ox$`q_}z zA?Bf0^qu!I9t6Jpvt(j?otQ-HNBK`8?+;yA^qc9TNhKd;zratx^m>RF*Ed#sfq&X> zHnnd)D8PPb**psPl6;@`>j|6T{}Pjy?ZNmP&invx=Hq^M9o^wN`YkiDo+`BJGH}-~ ztOe>3&U1OW`eY$|nd#SY{Dg4w>FHmb-_|`YI{mJB^U(gP`n;ko@jvm`TjZ?~n#=2& z#qJQkbn_IEz?V4)_)7fL@;Kqk<>=Edz?b7N?4!J$lJ+*FZJyK z@zb?WJJ{X2_po>#w^8D;O^@ucvK8v}@#~54QCVI?Z#J5~6!I%zWjy$4*5>)WEn~kB zyWKR7Qtv>wzOud^8J`#Bi>>Mg9E;v}sa<`ys3QERp7q+WU*y~*T37TeK50MnS?)?W zza|XxKDC=%q~^u-kPoq^wv-02Q_)hOB@S{zx;qVJGT7VThq z<=(S=#@X-jW4$Qx0rIP7y{71=ns6NWZnAV8(ap$UK3{A8gK?8HzA4nVZz-RDbmplP z6`uwZj?||`*U)c=;(k~7i~RR;bNY6yA5ZcA&3E_SgfAU^b|7&2-}%~WZFA!NP`_)W z-|QOe!GBy~7vcy#cQ=~I^`FMP)#K*ACO)XNTMh$XY9zi>M;?Dq_%hrd=HYoT^BVf~ z{Pl_uDnHxk3Vb;}aK4YO-UTq9YTc!1`hM}M&U?_!{!H(AB@^LGzV`ph{)vq^FQ*!wjUjwld77l) zcGHd~9LeXNe}J!{-3PGT?CMSYx!bAKBj78d={V-U%eF~2T|bzff!cFi-Is!KH}Nmw zE6HojeWJ^J$)C9V!P0Ym#*6qo;I z6nUA4~NfpK~g>nS~@?IpsI z=#!h}m-66xHlIjpO6A+9cjgE1tOtC(c*OIpT;NRL*K~0C@h>uUx66l*4`F=i1k|sB zn`fu_6rNDpgXLph*dubO*QF4u|4?`*;7gvsJQtzA@Q`}lI1j3vJ|E+pCC635i*@bFVf0t?c>~?-`?L_7F0Xcc!t@!;2cNJeR9;LN zb&TyVzR%vwRpl!1Rb>RMg1rL45NC4$G-Q(Kl>o}D#E+E8P*)%IrHvT;)mVR znAU`^1~FJK>296Uhe-S1!k8Is(*xu7-6wgc-4aTM*nfqnHF&bmMEV~*s&YH5A8mhW zY2eH9hFz;Yf374xd2VYy6u3~GF>f79iXeVNk1OEdapU+xRd&Ku;4Arn(?4;D=bLGj zCwxg2!};%Z57;Rp^yt*)HeJ_BU>qrqUsV&X9fJJYHMKI!M^(Fn-4D~H$rh4dMul9^ z&q6ule?p7aApR)Fi!-brH?bUSlBEpf^#tFCkYDC9_*ZpA*(V`(dGp%vrofjtd>#C* z++`Z^(^wb%6!Oc;;6-$qx^qh6gIeDWd4BCgQ;e_r51Ig9?vwc3npgu|TZak`L;1s( zy8vH$IotQC6Js!LuYdABjjYs|>Q|%lP6Xe}bYeS59vJ}oBro<)K*g>qmhmHCVF*j3i)Mx>Vp1`DQ-|bBH~p%@TXnI z5?$w;{mPf)ny)<@Wz(IV)CDUJ9%A#00{Z%KMY`tq>jB_)M}3 z@)Q40!&k%)`7ny@OjQ*)lBav^Ai87Wfz7~|u7LR&aOTzs>X#l8w-e)UT;~409?ACC z`Yq?tZ|#&XDJSd#?urER{g2LjYSpBgh@UX-WF3Thv~wRbXnPppOIOd}$M{NaK=!4T z`w-t_=vIgA5zYQpQL!rG2vwbS9~ocm@%>_afmwtvT{;`bkr^|1Kdw!KMkL>p+r>-( zzN`#$!0+kbju5^)nv_p9$^I*}8bIe0Bj@`6rSW&fZg(es*mTSrSvMH?62&Jy1wI_- zA*Wo*ME3!{`b?P(e90d17`Iffw*p_4c0{qB(%-R9Ga<`7dOti>4EtBjbDc?!h>Sfw zu-=~%!TCHyJo7mubWn(0-Z1kggU_-s(|yrNr?Ya^`7-cyVmwY z^gXI->2RtiaB<3Fz@OE@1K*kP_W{VG&-I-9cCr@sv3s2A3w*68Q4samktx7kSZsi_ z>rrVf6MV3jRJD92i~khvwDi%tNJtR`Ik*IMLX zm7_O?Futtoy@=n#t00e~`78y`XML2*zZuy$@bB`N_;=&=%Hy*kLqv> zeC>7&anM#Ss~_+sdk!YLki9+;z5+_N%>aCfkVhEjJ2SEZSDzya;;+#a_3NWQLomL7 zIzjUdCT2{Lr#@0`e%R^3yp# zx$XqM2K+wNoA|09By)U@c*p%d=g#+}<$o3jzDt&0a?G9*{&sm~oi4?Cb~oyg+3O*` z&^6}<_H#+zKNo%SHH3bAI^G#y=y96P--%BxI8R6L*?y>BhoW7zufPN1gY?_8i|u=h z^;ZRr{cSxpPkP4bd-%W9ukflQ*Ww;7;qyakVia)Krb&8|YmTX9{!Fz0+6mbn(LS@b z=MVUDy;wTnOIL>8iJZ|0ei~hb_nAI&7!!;oJp=PBZYnRxCp$uDtq z`EBBpy|7x1^UX0M)8RW$pC1znx|~CPqv8Ep!9U?xY0hN&%;66YeqFv%?;+u-k)0*Yi zkbC&fVk#2&S};AC@ii5BW*qB!a{TiBVc8j9S7B#4IxORL^y(B3z&FYF<_1>lI27et zpYH>FnRPJEy5Q9>H14wYiA2^@4T}R`KG~Pk`zq(hA;6cT_e-LSIR{I@KOx%kc^Sp` zr-`eLmWSBo&5PZiF}|F17s>HC;-)L`CA0B7dm4cFLMb*?Lc1z0k8kk=-mh45f%B~x zzo$T6XL-F3`0|Tw#_Pnm%@jYZCnkM|ofUME<4i<=7tMQZoX?K$$QvKS<&!Iq@|k9L zfS)s00uzWIa^gCt{F={xle(tI*T=HU2M;|lD1Rk~v~qRUzh z>H%M()fU2+`WTRsa5wDVsAs^JsIG{vcXa&-{CMTyJie+s^pXBv7vEu48-EMGt4-j~ z<^d&}fNv2!iZH$=fUeKAnLy*N_BC+kk=t+xIQlo4^D+#}AHjC>h!((mzB3<59vLet z^Zt-j=DFX3#?e9GWe!3K_69T#z+tV&D_Z{GU z*vV@vGkx8@7@z6(d;F*h^)pfa9945B$45JE@;*Vg#qh6c$2Q)7l*i%U(H-7k{it$o zWB;mT|AcH>3;7F0WGUyq7@r>#&1!J`M4wyrSwH^7{1@IshBUX^HCAV5|Cij!a`5V^ zBhZhpo;PRt<&uNuiAs!3LHv;|4^;(Ug)=Yru;%%Qf4Z}m1M=&?dyl?-`9?U>!}9#Y z^PoHSw{I_vLHxa=#(;2^UvU<2l&x+&;Y$>H^?>EqKcLJ0pO7C@=CA1k+^9?7!?S!R zo6&d3{RLhDU$&=#>QPezdEcYn$OXWc?eXUEoO+4y6}hfeTF4RIqBiXhsWq7wLw-#i z*B#?8ySGC5Y4e7X{8C@PU*`G5`?Wfo&zeg3tboI)|X9g9(BR@BV{L-(_vz=zXWIv(*Xq*!j&F{@% zy*8QcesLRmK{WRR)V-wtjS_`^l75uUqJLt3Dd&1K>Ivtey)nWQ_)^6n zzm(6yw}dZqu;UZ_6UqzUZ%(;>E&wjrQzg6Oy0yjZ-RAWBB+ufSV ztCo`=v;T|pwdNgDo$kXC%G0$m+SM5l7b0G+s2XC^#r=~Rx!uoL=QLJ0cTsf9jY=&51vHWv1)Emv+YA zS4`cC_~)AGRUY6=G+_IyaMrqHmnrW;?7vqD2QY8XuJR_jeA153r#Z5AB)aAA6-&5t zjL3Tc_!1LWqkNUQuEd8#=?^(3R9)~vF7Ao-qa3>Z2FsC|4}hceFS~-@)gL_vzKrP^ zKtHo^KlEe6_H2JSh83jzuD=TZxkT^l%yqi4T>FeXyXx~B*!Sju-0V+uECYX}=a-ow zc6l|w&qLr#SHt&+?jx%Zz5-5Gu14($vnkG-$h-M*4}eIl#{PR9cAeG_t|zC&lDxS* zX-OT%T}&a^U){@0>PPR_owSblWIv@Tj!