{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# SarcGraphTools - Analysis\n", "\n", "All demos are availble on GitHub at https://github.com/Sarc-Graph/sarcgraph/tree/main/tutorials.\n", "\n", "To run demos with `jupyter notebook` check [Installation Guide](https://sarc-graph.readthedocs.io/en/latest/installation.html).\n", "\n", "SarcGraph includes the tools which enable the recovery of basic sarcomere characteristics and the ability to run further high level analysis.\n", "\n", "In this notebook we provide a tutorial on how to use the SarcGraph package using demos and examples. The focus is on the ``SarcGraphTools.Analysis`` class in the ``sg_tools`` module." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Initialization" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Methods in the ``SarcGraphTools`` class need the information that will be saved by running ``SarcGraph.sarcomere_detection()``.\n", "\n", "To showcase this we use ``samples/sample_1.avi``." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Frame 79: 91 trajectories present.\n" ] }, { "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", "
framesarc_idxylengthwidthanglezdiscs
783639100.959195106.77514124.39012621.4969510.622702-35,-28
8221153.78483564.93630721.56329825.7627651.102697-40,-22
57325271149.771889188.18583412.03229710.8725912.30634868,89
33567641242.743014250.96731611.9673629.3834412.0957742,6
5361167144.302499178.56318113.9592538.3178372.68462949,68
\n", "
" ], "text/plain": [ " frame sarc_id x y length width angle \\\n", "783 63 9 100.959195 106.775141 24.390126 21.496951 0.622702 \n", "82 2 1 153.784835 64.936307 21.563298 25.762765 1.102697 \n", "5732 52 71 149.771889 188.185834 12.032297 10.872591 2.306348 \n", "3356 76 41 242.743014 250.967316 11.967362 9.383441 2.095774 \n", "5361 1 67 144.302499 178.563181 13.959253 8.317837 2.684629 \n", "\n", " zdiscs \n", "783 -35,-28 \n", "82 -40,-22 \n", "5732 68,89 \n", "3356 2,6 \n", "5361 49,68 " ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import pandas as pd\n", "\n", "from sarcgraph import SarcGraph\n", "\n", "sg = SarcGraph(output_dir='../tutorial-results', input_type='video')\n", "sarcomeres, _ = sg.sarcomere_detection(input_file='../samples/sample_1.avi')\n", "\n", "sarcomeres.sample(5)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "By default ``sg.config.save_output=True`` and the following information will be saved in ``../tutorial-results``:\n", "\n", "- raw video frames (grayscale)\n", "- filtered video frames\n", "- zdisc contours\n", "- segmented zdiscs information\n", "- tracked zdiscs information\n", "- detected sarcomeres information" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "The next step is to run ``SarcGraphTools.TimeSeries()`` to apply GPR on timeseries data related to each sarcomere." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from sarcgraph import SarcGraphTools\n", "\n", "sg_tools = SarcGraphTools(input_dir='../tutorial-results')\n", "_ = sg_tools.time_series.sarcomeres_gpr()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "This step is used for noise reduction as well as interpolating missing values of the timeseries (``x_position``, ``y_position``, ``length``, ``width``, ``angle``, ``length_normalized``)." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Characterization Analysis" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Here is a list of available functions in the ``SarcGraphTools.Analysis`` class:\n", "\n", "- ``compute_F_J()``: Computes the average deformation gradient (F) and its jacobian (J) for the whole movie\n", "\n", "- ``compute_OOP()``: Computes Orientation Order Parameter (OOP) for the whole movie\n", "\n", "- ``compute_metrics()``: Computes (`OOP`, `C_iso`, `C_OOP`, `s_til`, `s_avg`) as defined in the [SarcGraph paper](https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1009443)\n", "\n", "- ``compute_ts_params()``: Computes (`contraction time`, `relaxation time`, `flat time`, `period`, `offset`, etc.) for timeseries\n", "\n", "- ``create_spatial_graph()``: Generates a spatial graph of tracked z-discs where edges indicate sarcomeres and edge weights indicate the ratio of the frames in which each sarcomere is detected\n", "\n", "**Note**\n", "\n", "Check the api reference for [SarcGraphTools](https://sarc-graph.readthedocs.io/en/latest/reference/sg_tools.html)\n", "\n", "" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "To run these functions, create an instance of the ``SarcGraphTools`` class and set the ``input_dir`` to the directory used previously to save the output of sarcomere detection (in this case ``input_dir='../tutorial-results'``)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from sarcgraph import SarcGraphTools\n", "\n", "sg_tools = SarcGraphTools(input_dir='../tutorial-results')" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Now, any of the functions listed [above](#analysis-functions) can be executed. For examples, run the following for ``F`` and ``J`` computation:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "F, J = sg_tools.analysis.compute_F_J()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "This also saves ``F`` and ``J`` in the specified input directory ``input_dir`` if ``save_results=True`` in ``SarcGraphTools``" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Run the rest of the function:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "OOP, OOP_vec = sg_tools.analysis.compute_OOP()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "metrics = sg_tools.analysis.compute_metrics()" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "ts_params = sg_tools.analysis.compute_ts_params()" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "**Note**\n", "\n", "``create_spatial_graph()`` needs access to the original video/image file ``file_path`` or a dataframe that contains information of detected and tracked z-discs ``tracked_zdiscs``. So, below we show two ways to run this functions:" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "1. Specifying ``file_path``" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Frame 79: 91 trajectories present.\n", "output_dir = output\n", "input_type = image\n", "save_output = False\n", "sigma = 1.0\n", "zdisc_min_length = 10\n", "zdisc_max_length = 100\n", "full_track_ratio = 0.75\n", "tp_depth = 4\n", "skip_merge = False\n", "num_neighbors = 3\n", "avg_sarc_length = 15.0\n", "min_sarc_length = 0.0\n", "max_sarc_length = 30.0\n", "coeff_avg_length = 1.0\n", "coeff_neighbor_length = 1.0\n", "coeff_neighbor_angle = 1.0\n", "score_threshold = 0.1\n", "angle_threshold = 1.2\n" ] } ], "source": [ "sg_tools.analysis.create_spatial_graph(file_path='../samples/sample_1.avi')" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "2. Specifying ``tracked_zidscs``" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "output_dir = output\n", "input_type = video\n", "save_output = False\n", "sigma = 1.0\n", "zdisc_min_length = 10\n", "zdisc_max_length = 100\n", "full_track_ratio = 0.75\n", "tp_depth = 4\n", "skip_merge = False\n", "num_neighbors = 3\n", "avg_sarc_length = 15.0\n", "min_sarc_length = 0.0\n", "max_sarc_length = 30.0\n", "coeff_avg_length = 1.0\n", "coeff_neighbor_length = 1.0\n", "coeff_neighbor_angle = 1.0\n", "score_threshold = 0.1\n", "angle_threshold = 1.2\n", "output_dir = output\n", "input_type = image\n", "save_output = False\n", "sigma = 1.0\n", "zdisc_min_length = 10\n", "zdisc_max_length = 100\n", "full_track_ratio = 0.75\n", "tp_depth = 4\n", "skip_merge = False\n", "num_neighbors = 3\n", "avg_sarc_length = 15.0\n", "min_sarc_length = 0.0\n", "max_sarc_length = 30.0\n", "coeff_avg_length = 1.0\n", "coeff_neighbor_length = 1.0\n", "coeff_neighbor_angle = 1.0\n", "score_threshold = 0.1\n", "angle_threshold = 1.2\n" ] } ], "source": [ "# loading saved tracked_zidscs from 'tutorial-results' folder\n", "import pandas as pd\n", "\n", "tracked_zdiscs = pd.read_csv(\n", " f\"{sg_tools.input_dir}/tracked_zdiscs.csv\", index_col=[0]\n", ")\n", "\n", "sg_tools.analysis.create_spatial_graph(tracked_zdiscs=tracked_zdiscs)" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "After running all functions the following files will be added to ``input_dir``:\n", "\n", "- ``recovered_F.npy``\n", "- ``recovered_J.npy``\n", "- ``recovered_OOP.npy``\n", "- ``recovered_OOP_vector.npy``\n", "- ``recovered_metrics.json``\n", "- ``spatial-graph.pkl``\n", "- ``spatial-graph-pos.pkl``\n", "- ``time_series_params.csv``" ] } ], "metadata": { "kernelspec": { "display_name": "sarcgraph-dev-update-only", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.16" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }