{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# LineageOT with static lineage tracing\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "While designed for dynamic lineage tracing with continuously edited barcodes,\nLineageOT can be applied to any time course where a lineage tree can be created,\nincluding static barcoding data. \n\nWith some forms of static barcoding, more information is available than LineageOT uses.\nLineageOT does not account for the possibility that the same barcode could be observed\nat multiple time points. If that happens in your data, you can still use LineageOT,\nbut should also consider other methods.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import anndata\nimport lineageot\nimport numpy as np\n\nrng = np.random.default_rng()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Creating data\n\nFirst we make a minimal fake AnnData object to run LineageOT on. Here, the lineage\ninformation is encoded in a Boolean matrix with cells as rows and clones as column,\nwhere entry ``[i, j]`` is 1 if and only if cell ``i`` belongs to clone ``j``.\nThis example has two initial clones labeled at time 0 and four subclones labeled at time 7.\n\nIn addition to the clone identities, LineageOT also needs a time for each clone. This is encoded in the vector ``clone_times``, whose entries give the time of labeling of the clones.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "t1 = 5;\nt2 = 10;\n\nn_cells_1 = 4;\nn_cells_2 = 8;\nn_cells = n_cells_1 + n_cells_2;\n\nn_genes = 5;\n\n# clones labeled at time 0\ntime_0_clones = np.concatenate([np.kron(np.identity(2), np.ones((2,1))),\n                                np.kron(np.identity(2), np.ones((4,1)))])\n# clones labeled at time 7\ntime_7_clones = np.concatenate([np.zeros((4,4)),\n                                np.kron(np.identity(4), np.ones((2,1)))])\nclones = np.concatenate([time_0_clones, time_7_clones], 1)\n\nclone_times = np.array([0, 0, 7, 7, 7, 7]) \n\nadata = anndata.AnnData(X = np.random.rand(n_cells, n_genes),\n                        obs = {\"time\" : np.concatenate([t1*np.ones(n_cells_1), t2*np.ones(n_cells_2)])},\n                        obsm = {\"X_clone\" : clones}\n                       )\n\nprint(clones)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Fitting a lineage tree\n\nBefore running LineageOT, we need to build a lineage tree from the observed barcodes.\nFor static lineage tracing data, we provide an algorithm to construct a tree of possibly-nested clones, assuming there are no barcode collisions across clones so the phylogeny is straightforward to reconstruct.\nThis step is not optimized. \nFeel free to use your own preferred tree construction algorithm.\nYou can import a tree saved in Newick format with ``lineageot.read_newick``.\n\nThe tree should be formatted as a NetworkX ``DiGraph`` in the same way as the output of ``lineageot.fit_tree()``\nEach node is annotated with ``'time'`` (which indicates either the time of sampling (for observed cells) or the time of division (for unobserved ancestors).\nEdges are directed from parent to child and are annotated with ``'time'`` equal to the child node's ``'time_to_parent'``.\nObserved node indices correspond to their row in ``adata[adata.obs['time'] == t2]``. \n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "lineage_tree_t2 = lineageot.fit_tree(adata[adata.obs['time'] == t2], t2, clone_times = clone_times, method = 'clones')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Running LineageOT\n\nOnce we have a lineage tree annotated with time, we can compute a LineageOT coupling.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "coupling = lineageot.fit_lineage_coupling(adata, t1, t2, lineage_tree_t2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Saving \nThe LineageOT package does not include functionality for downstream analysis and plotting.\nWe recommend transitioning to other packages, like `Waddington-OT <https://broadinstitute.github.io/wot/>`_, after computing a coupling.\nThis saves the fitted coupling in a format Waddington-OT can import.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "lineageot.save_coupling_as_tmap(coupling, t1, t2, './tmaps/example')"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.7.9"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}