From 656f699c56c1096a61d38c229509bb85c494180e Mon Sep 17 00:00:00 2001 From: Jacob Schreiber Date: Fri, 6 Sep 2024 13:18:58 +0000 Subject: [PATCH] ADD FIMO/TOMTOM updates --- cmd/tangermeme | 25 +- docs/tutorials/Tutorial_D1_FIMO.ipynb | 2136 ++++++++++++++--------- docs/tutorials/Tutorial_D2_TOMTOM.ipynb | 337 ++++ tangermeme/tools/fimo.py | 449 +++-- tangermeme/tools/tomtom.py | 7 + tangermeme/utils.py | 140 +- tests/data/test2.meme | 60 + tests/test_io.py | 4 +- tests/test_utils.py | 92 + tests/tools/test_cmd_tomtom.py | 3 - tests/tools/test_fimo.py | 250 ++- tests/tools/test_tomtom.py | 24 +- 12 files changed, 2292 insertions(+), 1235 deletions(-) create mode 100644 docs/tutorials/Tutorial_D2_TOMTOM.ipynb create mode 100644 tests/data/test2.meme diff --git a/cmd/tangermeme b/cmd/tangermeme index 793a76d..ebe041f 100644 --- a/cmd/tangermeme +++ b/cmd/tangermeme @@ -2,8 +2,14 @@ # tangermeme command-line toolkits # Author: Jacob Schreiber +import sys +import pathlib +sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent)) + import argparse + from _tomtom import _run_tomtom +from _fimo import _run_fimo desc = """tangermeme is a package for genomic sequence-based machine learning. This command-line tool contains many methods that are useful for @@ -59,8 +65,25 @@ tomtom_parser.add_argument("-p", "--thresh", type=float, default=0.01, ### -# +fimo_help = """Scan a set of motifs from a MEME file against one or more + sequences in a FASTA file.""" +fimo_parser = subparsers.add_parser("fimo", help=fimo_help, + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + +fimo_parser.add_argument("-m", "--motif", type=str, required=True, + help="""The filename of a MEME-formatted file containing motifs.""") +fimo_parser.add_argument("-s", "--sequence", type=str, + help="""The filename of a FASTA-formatted file containing the sequences to + scan against.""") +fimo_parser.add_argument("-w", "--bin_size", type=float, default=0.1, + help="""The width of bins to use when discretizing scores.""") +fimo_parser.add_argument("-e", "--epsilon", type=float, default=0.0001, + help="""A pseudocount to add to each PWM.""") +fimo_parser.add_argument("-p", "--threshold", type=float, default=0.0001, + help="""The p-value threshold for returning matches.""") +fimo_parser.add_argument("-r", "--norc", action='store_true', default=False, + help="""Whether to only do the positive strand.""") ############## diff --git a/docs/tutorials/Tutorial_D1_FIMO.ipynb b/docs/tutorials/Tutorial_D1_FIMO.ipynb index 36043ad..11b4ce5 100644 --- a/docs/tutorials/Tutorial_D1_FIMO.ipynb +++ b/docs/tutorials/Tutorial_D1_FIMO.ipynb @@ -1,26 +1,15 @@ { "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "e9287110-b662-4baa-bb59-dbefc5e7b328", - "metadata": {}, - "outputs": [], - "source": [ - "import os\n", - "os.environ['CUDA_VISIBLE_DEVICES'] = '0'" - ] - }, { "cell_type": "markdown", "id": "0eeb3efa-4c3e-440c-b00f-a9444896346e", "metadata": {}, "source": [ - "### Tutorial D1: FIMO\n", + "### Tutorial D1 (Built-in Tools): FIMO\n", "\n", "The name `tangermeme` is a play on `MEME` and the `MEME suite`, which are one of the original collection of tools for biological sequence analyses. These tools included `MEME`, which would discover repeating patterns in collections of short sequences, `FIMO` which would scan a PWM over sequences and find statistically significant matches, `TOMTOM` which would compare a PWM to a collection of PWMs, and many other tools that have been developed over decades.\n", "\n", - "Although the scope of `tangermeme` is larger than that of the MEME suite -- in that `tangermeme` implements operations and analysis tools for machine learning models -- many of the MEME suite tools are implemented in PyTorch because they are used in downstream `tangermeme` methods. Because these implementations are in PyTorch they are generally much faster than the original implementations because they can make use of GPU acceleration, the latest computational advances, and other things such as mixed precision if desired. As those tools get added to tangermeme, short snippets demonstrating their usage will be added to this tutorial." + "Although the scope of `tangermeme` is larger than that of the MEME suite -- in that `tangermeme` implements operations and analysis tools for machine learning models -- some of the MEME suite tools are also implemented because they are used in downstream `tangermeme` methods. So far, these implementations are in numba and not in PyTorch because they can be sped up much more efficiently when not treated as a dense batched operation." ] }, { @@ -28,248 +17,258 @@ "id": "05c3b40e-a7bb-4436-86fd-6de03458105d", "metadata": {}, "source": [ - "#### FIMO\n", + "#### Using FIMO\n", "\n", "Finding Individual Motif Occurances ([FIMO](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3065696/)) is a tool for scanning PWMs across sequences and returning statistically significant occurances. There are basically two steps to the procedure: calculating a score that is just the convolution of the given PWMs and the one-hot encoded sequence, and converting that score to a valid p-value. The first step is trivial to implement. The second step involves using a dynamic programming algorithm that accounts for the length of the sequence and the information content at each position. \n", "\n", - "This algorithm is implemented in `tangermeme.tools.fimo`. \n", + "This algorithm is implemented in `tangermeme.tools.fimo` in the function `fimo`. Minimally, one must provide a filename for a MEME-formatted file of motifs and a filename for a FASTA-formatted file of sequences to scan against.\n", "\n", - "Let's begin by loading up some PWMs from a MEME-formatted file." + "NOTE: This API has changed significantly in v0.3.0. Rather than having `FIMO` class that is a PyTorch module, there is now only a `fimo` function that uses numba." ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "094e6849-c905-4454-9c88-ec392bb4e533", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "dict_keys(['MEOX1_homeodomain_1', 'HIC2_MA0738.1', 'GCR_HUMAN.H11MO.0.A', 'FOSL2+JUND_MA1145.1', 'TEAD3_TEA_2', 'ZN263_HUMAN.H11MO.0.A', 'PAX7_PAX_2', 'SMAD3_MA0795.1', 'MEF2D_HUMAN.H11MO.0.A', 'FOXQ1_MOUSE.H11MO.0.C', 'TBX19_MA0804.1', 'Hes1_MA1099.1'])" + "12" ] }, - "execution_count": 2, + "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "from tangermeme.io import read_meme\n", + "from tangermeme.tools.fimo import fimo\n", "\n", - "pwms = read_meme(\"../../tests/data/test.meme\")\n", - "pwms.keys()" + "hits = fimo(\"../../tests/data/test.meme\", \"../../tests/data/test.fa\") \n", + "len(hits)" + ] + }, + { + "cell_type": "markdown", + "id": "189d30c8-73ca-4d00-adc3-9e7a573cf1da", + "metadata": {}, + "source": [ + "There are 12 motifs in `test.meme` and so there are 12 dataframes returned -- one for each motif." ] }, { "cell_type": "code", - "execution_count": 3, - "id": "8f352269-a771-4c5d-9c0b-1e22ff0a2df0", + "execution_count": 2, + "id": "848a15ad-7171-4cea-b5bd-c5b748413f2b", "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", + "
motif_idmotif_alt_idsequence_namestartstopstrandscorep-value
0MEOX1_homeodomain_1NaNchr713501360+11.4465720.000075
\n", + "
" + ], "text/plain": [ - "array([[0.46108, 0.06971, 0.40428, 0.06493],\n", - " [0. , 0.02336, 0. , 0.97664],\n", - " [0.08387, 0.0601 , 0.83039, 0.02564],\n", - " [0.00467, 0.99249, 0.00284, 0. ],\n", - " [0.08078, 0.90826, 0. , 0.01096],\n", - " [0.29973, 0.70027, 0. , 0. ],\n", - " [0.50961, 0.14513, 0.2637 , 0.08156],\n", - " [0.15743, 0.44981, 0.25291, 0.13985],\n", - " [0.15539, 0.35412, 0.20466, 0.28583]])" + " motif_id motif_alt_id sequence_name start stop strand \\\n", + "0 MEOX1_homeodomain_1 NaN chr7 1350 1360 + \n", + "\n", + " score p-value \n", + "0 11.446572 0.000075 " ] }, - "execution_count": 3, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "pwms['HIC2_MA0738.1']" + "hits[0]" ] }, { "cell_type": "markdown", - "id": "a8f50670-9718-4275-abe9-16739ea82a87", - "metadata": {}, - "source": [ - "Next, let's create the FIMO object and pass these motifs in." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "58a3909e-5d66-4fdf-aac2-f57f47026d5d", + "id": "ce292182-f7a2-4d29-aef7-4cf33843e366", "metadata": {}, - "outputs": [], "source": [ - "from tangermeme.tools.fimo import FIMO\n", + "The format of the returned dataframe is meant to match the output from FIMO closely EXCEPT THAT THE COORDIINATES HERE ARE 0-based not 1-based. This decision was made to keep everything in tangermeme consistent -- everything is 0-based. This means that the starts will be 1 position lower than those returned by FIMO. Further, the stop coordinates are inclusive in FIMO and not inclusive here, meaning that position 1360 (0-indexed) is not included in the hit here. This means that the stop coordinates will be the same in both implementations, but the logic `start:stop` to extract a slice is correct when using the coordinates when returned by tangermeme.\n", "\n", - "model = FIMO(pwms)" + "You might notice that there are two missing columns from this format: `q-value` and `matched_sequence`. `q-value` is not implemented because, in my opinion, q-values are not meaningful for this task and are very compute- and memory-inefficient to calculate. Likewise, `matched_sequence` takes a fair amount of time to calculate compared to everything else, since the main implementation is in numba, and is not always used. I decided to remove it to speed things up for the majority of people who do not need it." ] }, { "cell_type": "markdown", - "id": "671fde28-26ee-4e7d-816d-16f892a213b3", + "id": "a9748e44-96ac-482e-9f54-6117d2851b8c", "metadata": {}, "source": [ - "When the model is created, it runs the dynamic programming algorithm pre-calculating a mapping of scores to p-values for each motif. This was recently converted to a numba-accelerated set of functions so should be pretty fast, but may take a few seconds if using thousands of motifs, i.e., because you're running all JASPAR motifs against sequence.\n", + "#### Alternate Inputs\n", "\n", - "Next, let's load up some sequences to run FIMO on." + "One of the main reasons I implemented these built-in tools was so they could be easily accessable via Python without the need for intermediary files. So, if you already have a set of motifs you would like to scan, you can pass in a dictionary where the keys are motif names and the values are the PWMs. Note that the PWMs can be either `numpy.ndarray` or `torch.Tensor` objects but they must be formatted to have the shape `(len(alphabet), motif_length)`. The built-in `read_meme` command will read motifs into this format automatically, but you can also scan your own custom motifs built however you'd like." ] }, { "cell_type": "code", - "execution_count": 5, - "id": "baf47b92-2ea8-4d30-866e-125c20e49d1b", + "execution_count": 3, + "id": "28ebf10a-1f36-41a5-8a91-8ac7974c5bf3", "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", + "
motif_idmotif_alt_idsequence_namestartstopstrandscorep-value
0MEOX1_homeodomain_1NaNchr713501360+11.4465720.000075
\n", + "
" + ], "text/plain": [ - "torch.Size([5, 4, 40])" + " motif_id motif_alt_id sequence_name start stop strand \\\n", + "0 MEOX1_homeodomain_1 NaN chr7 1350 1360 + \n", + "\n", + " score p-value \n", + "0 11.446572 0.000075 " ] }, - "execution_count": 5, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "from tangermeme.io import extract_loci\n", + "from tangermeme.io import read_meme\n", "\n", - "X = extract_loci(\"../../tests/data/test.bed\", \"../../tests/data/test.fa\", in_window=40).float()\n", - "X.shape" + "motifs = read_meme(\"../../tests/data/test.meme\")\n", + "hits = fimo(motifs, \"../../tests/data/test.fa\")\n", + "hits[0]" ] }, { "cell_type": "markdown", - "id": "d4938d91-45c2-4d23-aa0a-4d52401a3436", + "id": "09d91065-3c64-4896-9d5b-bb0f505d0f37", "metadata": {}, "source": [ - "The most basic thing we can do is calculate the scores -- which are just the convolution scan of the PWMs against the one-hot encoded sequence. This can still be done efficiently when motifs are of differing lengths because the shorter motifs are padded with zeroes." + "You can also pass in `numpy.ndarray` or `torch.Tensor` objects as your sequences. In this case, the sequences must be a single object that has the shape `(n_seqs, len(alphabet), sequence_length)`. " ] }, { "cell_type": "code", - "execution_count": 6, - "id": "a2d521a2-9d63-40db-bdc6-fecec13b57bb", + "execution_count": 4, + "id": "70a39b85-b646-40cb-959a-b5a9ef692f0e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "torch.Size([5, 12, 2, 21])" + "torch.Size([1, 4, 2000])" ] }, - "execution_count": 6, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "y = model(X)\n", - "y.shape" - ] - }, - { - "cell_type": "markdown", - "id": "ac7ce071-b8da-454d-b565-5b4cbf5a85a9", - "metadata": {}, - "source": [ - "The shape of the return is `(batch_size, n_motifs, n_strands, n_positions)`. Note that `n_positions` is not necessarily equal to the original length of the sequence because the motif is only run against entire spans of sequence. So, `n_positions` will actually be the original length of the sequence minus the length of the longest motif." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "72d83538-c2e0-405f-aa5a-a96943d27ebf", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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6XYhISF46aWXkJqaCq1Wi88++wwPPvggPvjgA4wdO9aBR9wzw4cPx4YNGxAfH4/q6mps3boVc+bMwRdffIGAgIAO27vq9QOA77//Ho2NjZgxY0an27ja9WuPf91Ze02WlZV1er+qqqoO9wkKCur0dSwUGo0Gr732Gu644w54e3t3ut3gwYOxbt06JCcno6mpCe+//z7mzp2Lzz77DPHx8Y474B646aabcPvttyMyMhIlJSV466238MADD+DAgQOQyWRW7+Oq1w8ADh48CC8vL/zhD3/ocjshXkNrnwtCfg1ScORg7b+FcxzX5Tdza9tbu11IXnzxRVy5cgV79+7tcrvBgwdj8ODB5p9HjhyJ69ev47333hPkh+vNN9/c5ueMjAzceuutOHToEBYsWGD1Pq54/QDg008/xU033YSwsLBOt3G169eZzq5Rb+8j5Guq0+nw5JNPguM4rFmzpsttMzIykJGRYf551KhRmDFjBj788EM8++yz9j3QXpo6dar530lJSUhLS8PkyZPx008/dRlAuNr143366aeYPn065HJ5l9sJ8Rp29bkgxNcgDas5SEBAAMRiMaqqqtrcXl1d3SG7wLOWVaqpqYFEIoG/v7+9DrVfXnrpJfz444/YvXs3wsPDe33/ESNGoLCw0A5HZnuenp5ISkpCQUGB1d+74vUDgNLSUhw9erRHqfv2XOn6hYSEAECvXpOA8bq2v09NTU2X93EmnU6H5cuXo6SkBDt27Ogya2SNSCRCenp6p89zIQkNDUVkZGSXx+pq14936tQp5Ofn45577un1fZ19DTv7XBDya5CCIweRyWRITU3FkSNH2tx+9OhRjBw50up9MjIycPTo0Ta3ZWdnIy0tDVKp1G7H2hccx+HFF1/Et99+i927dyMmJqZP+8nJyTG/YIROq9UiNze30+N1petn6cCBAwgKCsKkSZN6fV9Xun7R0dEICQlp85rUarU4efJkp69JwHhd27+Os7Ozu7yPs/CBUWFhIXbt2mV1+Lc7HMe5zHWtra1FeXl5l0PWrnT9LO3fvx+pqalISUnp9X2ddQ27+1wQ8muQhtUcaMGCBVixYgXS0tIwcuRIfPzxxygvL8ecOXMAAK+//joqKirwyiuvAADmzJmDPXv2YN26dZg9ezbOnDmDTz/9FK+//rozT8OqF154AV988QXeeecdeHl5mTMm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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from matplotlib import pyplot as plt\n", - "import seaborn; seaborn.set_style('whitegrid')\n", + "import pyfaidx\n", "\n", - "plt.plot(y[0, :, 0].numpy(force=True).T)\n", - "plt.xlabel(\"Start Position of Motif\")\n", - "plt.ylabel(\"Score\")\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "id": "41188a27-a7fd-451a-a783-b85cdfa187c9", - "metadata": {}, - "source": [ - "Converting all of these scores to p-values can be time-consuming, so the score to p-value mapping is calculated internally just to determine the score threshold for a given p-value threshold. This way, you don't need to spend a lot of time computing p-values for scores that are known to not be relevant. Finding all such p-value hits can be done using the `hits` method." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "0d53afaa-9b9d-4997-adba-1d712ac63107", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/users/jmschr/anaconda3/lib/python3.11/site-packages/torch/cuda/__init__.py:628: UserWarning: Can't initialize NVML\n", - " warnings.warn(\"Can't initialize NVML\")\n", - "30it [00:00, 19639.32it/s]\n" - ] - } - ], - "source": [ - "hits = model.hits(X, threshold=0.01)" + "from tangermeme.utils import one_hot_encode\n", + "\n", + "X = pyfaidx.Fasta(\"../../tests/data/test.fa\")['chr7'][:].seq.upper()\n", + "X = one_hot_encode(X).unsqueeze(0)\n", + "X.shape" ] }, { "cell_type": "markdown", - "id": "a5fd60ab-7014-488d-bd75-170ae1c36749", - "metadata": {}, - "source": [ - "By default, the return from `hits` is a list of pandas DataFrames, where each DataFrame is bed-formatted and contains all hits for a single motif. So, if you loaded 23 motifs into the FIMO object initially, there will be 23 DataFrames returned. " - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "48514313-7dda-4c6f-9f46-4bdb9cd69239", + "id": "dba02b44-8d1c-4c1d-bd19-dd3a4a38c4c4", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "12" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "len(hits)" + "Once you have the sequence object, you can pass it in instead of the filename." ] }, { "cell_type": "code", - "execution_count": 10, - "id": "95fff982-378a-4f66-bdcf-5ecdf4d10d99", + "execution_count": 5, + "id": "c22a2bf2-1b53-4af9-a142-d3d969b8974a", "metadata": {}, "outputs": [ { @@ -293,111 +292,64 @@ " \n", " \n", " \n", - " example_idx\n", + " motif_id\n", + " motif_alt_id\n", + " sequence_name\n", " start\n", - " end\n", + " stop\n", " strand\n", " score\n", " p-value\n", - " seq\n", " \n", " \n", " \n", " \n", " 0\n", + " MEOX1_homeodomain_1\n", + " NaN\n", " 0\n", - " 12\n", - " 22\n", - " +\n", - " 3.512175\n", - " 0.004463\n", - " ACTAACTGAC\n", - " \n", - " \n", - " 1\n", - " 0\n", - " 20\n", - " 30\n", + " 1350\n", + " 1360\n", " +\n", - " 4.261113\n", - " 0.003427\n", - " ACTGATGATG\n", - " \n", - " \n", - " 2\n", - " 0\n", - " 20\n", - " 30\n", - " -\n", - " 1.616617\n", - " 0.008347\n", - " ACTGATGATG\n", - " \n", - " \n", - " 3\n", - " 0\n", - " 23\n", - " 33\n", - " -\n", - " 3.592150\n", - " 0.004342\n", - " GATGATGATG\n", - " \n", - " \n", - " 4\n", - " 1\n", - " 16\n", - " 26\n", - " -\n", - " 3.232642\n", - " 0.004923\n", - " TACCATGACT\n", + " 11.446572\n", + " 0.000075\n", " \n", " \n", "\n", "" ], "text/plain": [ - " example_idx start end strand score p-value seq\n", - "0 0 12 22 + 3.512175 0.004463 ACTAACTGAC\n", - "1 0 20 30 + 4.261113 0.003427 ACTGATGATG\n", - "2 0 20 30 - 1.616617 0.008347 ACTGATGATG\n", - "3 0 23 33 - 3.592150 0.004342 GATGATGATG\n", - "4 1 16 26 - 3.232642 0.004923 TACCATGACT" + " motif_id motif_alt_id sequence_name start stop strand \\\n", + "0 MEOX1_homeodomain_1 NaN 0 1350 1360 + \n", + "\n", + " score p-value \n", + "0 11.446572 0.000075 " ] }, - "execution_count": 10, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ + "hits = fimo(motifs, X)\n", "hits[0]" ] }, { "cell_type": "markdown", - "id": "f8e7b74a-b027-407a-9efa-7b3e202bf315", + "id": "5011d094-a73a-4a66-9e6b-1ac6d41cbb48", "metadata": {}, "source": [ - "However, sometimes you are interested in all of the hits on a locus-specific axis rather than a motif-specific axis. For instance, if you have a single locus that you want to annotate, you are interested in all of the motif hits anywhere on that sequence and it can be a pain to have to aggregate that across many DataFrame objects.\n", - "\n", - "If you are interested in the locus-specific axis you can pass `dim=1` in." + "Note here that the sequence name will just be the index of the sequence that the hit matched to, but that the score and p-value are still identical. For simplicity, we only had a single sequence, but you can use as many sequences as you would like." ] }, { "cell_type": "code", - "execution_count": 11, - "id": "e6513551-c5cb-4baa-96bb-d93115573324", + "execution_count": 6, + "id": "70dbf9bd-be81-49c1-9066-0485e896efc6", "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "30it [00:00, 15109.16it/s]\n" - ] - }, { "data": { "text/html": [ @@ -419,292 +371,233 @@ " \n", " \n", " \n", - " motif\n", + " motif_id\n", + " motif_alt_id\n", + " sequence_name\n", " start\n", - " end\n", + " stop\n", " strand\n", " score\n", " p-value\n", - " seq\n", " \n", " \n", " \n", " \n", " 0\n", " MEOX1_homeodomain_1\n", - " 12\n", - " 22\n", + " NaN\n", + " 1\n", + " 4220\n", + " 4230\n", " +\n", - " 3.512175\n", - " 0.004463\n", - " ACTAACTGAC\n", + " 12.104512\n", + " 0.000031\n", " \n", " \n", " 1\n", " MEOX1_homeodomain_1\n", - " 20\n", - " 30\n", + " NaN\n", + " 2\n", + " 4774\n", + " 4784\n", " +\n", - " 4.261113\n", - " 0.003427\n", - " ACTGATGATG\n", + " 11.133726\n", + " 0.000093\n", " \n", " \n", " 2\n", " MEOX1_homeodomain_1\n", - " 20\n", - " 30\n", - " -\n", - " 1.616617\n", - " 0.008347\n", - " ACTGATGATG\n", + " NaN\n", + " 4\n", + " 1498\n", + " 1508\n", + " +\n", + " 12.225502\n", + " 0.000027\n", " \n", " \n", " 3\n", " MEOX1_homeodomain_1\n", - " 23\n", - " 33\n", - " -\n", - " 3.592150\n", - " 0.004342\n", - " GATGATGATG\n", + " NaN\n", + " 5\n", + " 4973\n", + " 4983\n", + " +\n", + " 13.126775\n", + " 0.000007\n", " \n", " \n", " 4\n", - " FOSL2+JUND_MA1145.1\n", - " 24\n", - " 39\n", - " -\n", - " -0.538747\n", - " 0.008368\n", - " ATGATGATGCATGCT\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 8\n", + " 2169\n", + " 2179\n", + " +\n", + " 11.218552\n", + " 0.000086\n", " \n", " \n", - " 5\n", - " TEAD3_TEA_2\n", - " 30\n", - " 38\n", - " -\n", - " -5.082814\n", - " 0.008408\n", - " ATGCATGC\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", " \n", " \n", - " 6\n", - " PAX7_PAX_2\n", - " 14\n", - " 24\n", - " +\n", - " -10.314709\n", - " 0.009835\n", - " TAACTGACTG\n", + " 74\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 90\n", + " 665\n", + " 675\n", + " -\n", + " 11.118969\n", + " 0.000093\n", " \n", " \n", - " 7\n", - " PAX7_PAX_2\n", - " 18\n", - " 28\n", - " +\n", - " -7.193218\n", - " 0.005223\n", - " TGACTGATGA\n", + " 75\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 92\n", + " 2941\n", + " 2951\n", + " -\n", + " 12.177395\n", + " 0.000031\n", " \n", " \n", - " 8\n", - " PAX7_PAX_2\n", - " 14\n", - " 24\n", + " 76\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 94\n", + " 870\n", + " 880\n", " -\n", - " -10.090963\n", - " 0.009407\n", - " TAACTGACTG\n", + " 11.619565\n", + " 0.000063\n", " \n", " \n", - " 9\n", - " PAX7_PAX_2\n", - " 18\n", - " 28\n", + " 77\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 94\n", + " 4133\n", + " 4143\n", + " -\n", + " 12.225502\n", + " 0.000027\n", + " \n", + " \n", + " 78\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 94\n", + " 4626\n", + " 4636\n", " -\n", - " -5.894826\n", - " 0.003964\n", - " TGACTGATGA\n", + " 11.568620\n", + " 0.000071\n", " \n", " \n", "\n", + "

79 rows × 8 columns

\n", "" ], "text/plain": [ - " motif start end strand score p-value \\\n", - "0 MEOX1_homeodomain_1 12 22 + 3.512175 0.004463 \n", - "1 MEOX1_homeodomain_1 20 30 + 4.261113 0.003427 \n", - "2 MEOX1_homeodomain_1 20 30 - 1.616617 0.008347 \n", - "3 MEOX1_homeodomain_1 23 33 - 3.592150 0.004342 \n", - "4 FOSL2+JUND_MA1145.1 24 39 - -0.538747 0.008368 \n", - "5 TEAD3_TEA_2 30 38 - -5.082814 0.008408 \n", - "6 PAX7_PAX_2 14 24 + -10.314709 0.009835 \n", - "7 PAX7_PAX_2 18 28 + -7.193218 0.005223 \n", - "8 PAX7_PAX_2 14 24 - -10.090963 0.009407 \n", - "9 PAX7_PAX_2 18 28 - -5.894826 0.003964 \n", + " motif_id motif_alt_id sequence_name start stop strand \\\n", + "0 MEOX1_homeodomain_1 NaN 1 4220 4230 + \n", + "1 MEOX1_homeodomain_1 NaN 2 4774 4784 + \n", + "2 MEOX1_homeodomain_1 NaN 4 1498 1508 + \n", + "3 MEOX1_homeodomain_1 NaN 5 4973 4983 + \n", + "4 MEOX1_homeodomain_1 NaN 8 2169 2179 + \n", + ".. ... ... ... ... ... ... \n", + "74 MEOX1_homeodomain_1 NaN 90 665 675 - \n", + "75 MEOX1_homeodomain_1 NaN 92 2941 2951 - \n", + "76 MEOX1_homeodomain_1 NaN 94 870 880 - \n", + "77 MEOX1_homeodomain_1 NaN 94 4133 4143 - \n", + "78 MEOX1_homeodomain_1 NaN 94 4626 4636 - \n", "\n", - " seq \n", - "0 ACTAACTGAC \n", - "1 ACTGATGATG \n", - "2 ACTGATGATG \n", - "3 GATGATGATG \n", - "4 ATGATGATGCATGCT \n", - "5 ATGCATGC \n", - "6 TAACTGACTG \n", - "7 TGACTGATGA \n", - "8 TAACTGACTG \n", - "9 TGACTGATGA " + " score p-value \n", + "0 12.104512 0.000031 \n", + "1 11.133726 0.000093 \n", + "2 12.225502 0.000027 \n", + "3 13.126775 0.000007 \n", + "4 11.218552 0.000086 \n", + ".. ... ... \n", + "74 11.118969 0.000093 \n", + "75 12.177395 0.000031 \n", + "76 11.619565 0.000063 \n", + "77 12.225502 0.000027 \n", + "78 11.568620 0.000071 \n", + "\n", + "[79 rows x 8 columns]" ] }, - "execution_count": 11, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "hits = model.hits(X, threshold=0.01, dim=1)\n", + "from tangermeme.utils import random_one_hot\n", + "\n", + "X = random_one_hot((100, 4, 5000), random_state=0)\n", + "\n", + "hits = fimo(motifs, X)\n", "hits[0]" ] }, { "cell_type": "markdown", - "id": "44113c88-b843-4f18-a67b-4b671e2838a0", - "metadata": {}, - "source": [ - "Looking at the first DataFrame will tell us what motifs occur and where on the first sequence." - ] - }, - { - "cell_type": "markdown", - "id": "0792ec91-6953-4823-aa06-0c95c8515a90", - "metadata": {}, - "source": [ - "Finally, if you want an aggregated matrix of motif hits where each row is a different locus, each column is a motif, and the value is the maximum score of each motif at each locus, we can use the `hit_matrix` method." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "0a9efa68-3e54-435c-86ab-6e6acab6440b", + "id": "9ecd3ba5-864d-4cca-b370-ced8bf8a83bc", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "torch.Size([5, 12])" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ - "y_hits = model.hit_matrix(X)\n", - "y_hits.shape" + "#### Annotating Sequences\n", + "\n", + "Sometimes, rather than getting all the hits for a motif across all sequences, you would like to annotate each sequence according to what motifs bind to it. In a sense, this is asking to transpose the results -- rather than one dataframe per motif, you would like one dataframe per example. You can easily do this by passing in `dim=1`." ] }, { "cell_type": "code", - "execution_count": 13, - "id": "8b417ec4-8f25-4db4-9f4e-36edf2461a4b", + "execution_count": 7, + "id": "ff35de0d-32c9-4c95-b0ee-c69e169ce2f3", "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "tensor([[ 4.2611, -3.9193, -3.0517, -0.5387, -5.0828, -8.0606, -5.8948,\n", - " -11.8521, -8.1839, -25.0211, -9.2288, 3.4261],\n", - " [ 3.2326, 0.3824, -7.8207, -5.1872, -5.2034, 0.3497, -18.1375,\n", - " -3.5999, -1.3253, -26.7751, -8.9245, 1.4679],\n", - " [ -0.7967, 4.1468, 5.0787, -2.0847, -17.2555, -8.1860, -16.7593,\n", - " -3.4265, -0.9905, -17.7709, -15.4074, 3.0202],\n", - " [ -4.3711, -2.1672, -6.6681, -7.6389, -11.3639, -1.6247, -14.1465,\n", - " -7.1743, 1.7523, -22.9861, -14.0714, 1.2057],\n", - " [ -4.3711, -0.2420, -3.2560, -7.6389, -5.8535, 1.1055, -14.1465,\n", - " -7.1743, 1.7523, -23.4009, -10.1734, 0.5615]])" + "100" ] }, - "execution_count": 13, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "y_hits" + "hits = fimo(motifs, X, dim=1)\n", + "len(hits)" ] }, { "cell_type": "markdown", - "id": "eadec40a-a24d-4332-a6bc-10ba23c8df95", + "id": "1176a35a-0497-43be-90c4-a515d3699214", "metadata": {}, "source": [ - "### Comparison with command-line tool" + "Now, we are getting 100 dataframes because there are 100 sequences, rather than getting 12 because there are 12 motifs." ] }, { "cell_type": "code", - "execution_count": 14, - "id": "cf4341b1-1634-4808-bf76-1167eacaaffd", + "execution_count": 8, + "id": "23576196-4fb7-491d-89e3-a07fbfbf4c79", "metadata": {}, "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Using motif +MEOX1_homeodomain_1 of width 10.\n", - "Using motif -MEOX1_homeodomain_1 of width 10.\n", - "Warning: Z is not a valid character in DNA alphabet.\n", - " Converting Z to N.\n", - "Using motif +HIC2_MA0738.1 of width 9.\n", - "Using motif -HIC2_MA0738.1 of width 9.\n", - "Warning: Z is not a valid character in DNA alphabet.\n", - " Converting Z to N.\n", - "Using motif +GCR_HUMAN.H11MO.0.A of width 15.\n", - "Using motif -GCR_HUMAN.H11MO.0.A of width 15.\n", - "Warning: Z is not a valid character in DNA alphabet.\n", - " Converting Z to N.\n", - "Using motif +FOSL2+JUND_MA1145.1 of width 15.\n", - "Using motif -FOSL2+JUND_MA1145.1 of width 15.\n", - "Warning: Z is not a valid character in DNA alphabet.\n", - " Converting Z to N.\n", - "Using motif +TEAD3_TEA_2 of width 8.\n", - "Using motif -TEAD3_TEA_2 of width 8.\n", - "Warning: Z is not a valid character in DNA alphabet.\n", - " Converting Z to N.\n", - "Using motif +ZN263_HUMAN.H11MO.0.A of width 20.\n", - "Using motif -ZN263_HUMAN.H11MO.0.A of width 20.\n", - "Warning: Z is not a valid character in DNA alphabet.\n", - " Converting Z to N.\n", - "Using motif +PAX7_PAX_2 of width 10.\n", - "Using motif -PAX7_PAX_2 of width 10.\n", - "Warning: Z is not a valid character in DNA alphabet.\n", - " Converting Z to N.\n", - "Using motif +SMAD3_MA0795.1 of width 10.\n", - "Using motif -SMAD3_MA0795.1 of width 10.\n", - "Warning: Z is not a valid character in DNA alphabet.\n", - " Converting Z to N.\n", - "Using motif +MEF2D_HUMAN.H11MO.0.A of width 12.\n", - "Using motif -MEF2D_HUMAN.H11MO.0.A of width 12.\n", - "Warning: Z is not a valid character in DNA alphabet.\n", - " Converting Z to N.\n", - "Using motif +FOXQ1_MOUSE.H11MO.0.C of width 12.\n", - "Using motif -FOXQ1_MOUSE.H11MO.0.C of width 12.\n", - "Warning: Z is not a valid character in DNA alphabet.\n", - " Converting Z to N.\n", - "Using motif +TBX19_MA0804.1 of width 20.\n", - "Using motif -TBX19_MA0804.1 of width 20.\n", - "Warning: Z is not a valid character in DNA alphabet.\n", - " Converting Z to N.\n", - "Using motif +Hes1_MA1099.1 of width 10.\n", - "Using motif -Hes1_MA1099.1 of width 10.\n", - "Warning: Z is not a valid character in DNA alphabet.\n", - " Converting Z to N.\n" - ] - }, { "data": { "text/html": [ @@ -734,216 +627,167 @@ " strand\n", " score\n", " p-value\n", - " q-value\n", - " matched_sequence\n", " \n", " \n", " \n", " \n", " 0\n", - " MEOX1_homeodomain_1\n", + " HIC2_MA0738.1\n", " NaN\n", - " chr7\n", - " 1351\n", - " 1360\n", + " 0\n", + " 3263\n", + " 3272\n", " +\n", - " 11.4342\n", - " 0.000072\n", - " NaN\n", - " ACTCATTACC\n", + " 11.987469\n", + " 0.000011\n", " \n", " \n", " 1\n", - " GCR_HUMAN.H11MO.0.A\n", + " HIC2_MA0738.1\n", " NaN\n", - " chr1\n", - " 70\n", - " 84\n", + " 0\n", + " 3480\n", + " 3489\n", " +\n", - " 10.9091\n", - " 0.000068\n", - " NaN\n", - " ATGACTGACTGTACT\n", + " 11.316123\n", + " 0.000034\n", " \n", " \n", " 2\n", - " FOSL2+JUND_MA1145.1\n", - " NaN\n", - " chr5\n", - " 39\n", - " 53\n", - " -\n", - " 10.1440\n", - " 0.000095\n", + " ZN263_HUMAN.H11MO.0.A\n", " NaN\n", - " GAGTTGCGTCATCAG\n", + " 0\n", + " 4178\n", + " 4198\n", + " +\n", + " 11.073596\n", + " 0.000043\n", " \n", " \n", " 3\n", - " FOSL2+JUND_MA1145.1\n", - " NaN\n", - " chr7\n", - " 396\n", - " 410\n", - " +\n", - " 10.7920\n", - " 0.000065\n", + " ZN263_HUMAN.H11MO.0.A\n", " NaN\n", - " TCATTACTTCACTGA\n", + " 0\n", + " 4049\n", + " 4069\n", + " -\n", + " 10.941541\n", + " 0.000046\n", " \n", " \n", " 4\n", - " SMAD3_MA0795.1\n", + " TBX19_MA0804.1\n", " NaN\n", - " chr5\n", - " 104\n", - " 113\n", + " 0\n", + " 4653\n", + " 4673\n", " +\n", - " 10.4474\n", - " 0.000046\n", - " NaN\n", - " tatctagaCA\n", + " 12.223569\n", + " 0.000015\n", " \n", " \n", " 5\n", - " SMAD3_MA0795.1\n", + " TBX19_MA0804.1\n", " NaN\n", - " chr5\n", - " 104\n", - " 113\n", + " 0\n", + " 4653\n", + " 4673\n", " -\n", - " 10.4474\n", - " 0.000046\n", - " NaN\n", - " TGTCTAGATA\n", + " 10.531827\n", + " 0.000035\n", " \n", " \n", " 6\n", - " MEF2D_HUMAN.H11MO.0.A\n", + " Hes1_MA1099.1\n", " NaN\n", - " chr7\n", - " 1037\n", - " 1048\n", + " 0\n", + " 1101\n", + " 1111\n", " +\n", - " 11.0779\n", - " 0.000056\n", - " NaN\n", - " TGCTATATATAT\n", + " 9.933365\n", + " 0.000050\n", " \n", " \n", " 7\n", - " FOXQ1_MOUSE.H11MO.0.C\n", + " Hes1_MA1099.1\n", " NaN\n", - " chr5\n", - " 122\n", - " 133\n", + " 0\n", + " 2855\n", + " 2865\n", " +\n", - " 3.5000\n", - " 0.000095\n", + " 9.928051\n", + " 0.000050\n", + " \n", + " \n", + " 8\n", + " Hes1_MA1099.1\n", " NaN\n", - " AGTTGTATATAT\n", + " 0\n", + " 1101\n", + " 1111\n", + " -\n", + " 9.933365\n", + " 0.000050\n", " \n", " \n", "\n", "" ], "text/plain": [ - " motif_id motif_alt_id sequence_name start stop strand \\\n", - "0 MEOX1_homeodomain_1 NaN chr7 1351 1360 + \n", - "1 GCR_HUMAN.H11MO.0.A NaN chr1 70 84 + \n", - "2 FOSL2+JUND_MA1145.1 NaN chr5 39 53 - \n", - "3 FOSL2+JUND_MA1145.1 NaN chr7 396 410 + \n", - "4 SMAD3_MA0795.1 NaN chr5 104 113 + \n", - "5 SMAD3_MA0795.1 NaN chr5 104 113 - \n", - "6 MEF2D_HUMAN.H11MO.0.A NaN chr7 1037 1048 + \n", - "7 FOXQ1_MOUSE.H11MO.0.C NaN chr5 122 133 + \n", + " motif_id motif_alt_id sequence_name start stop strand \\\n", + "0 HIC2_MA0738.1 NaN 0 3263 3272 + \n", + "1 HIC2_MA0738.1 NaN 0 3480 3489 + \n", + "2 ZN263_HUMAN.H11MO.0.A NaN 0 4178 4198 + \n", + "3 ZN263_HUMAN.H11MO.0.A NaN 0 4049 4069 - \n", + "4 TBX19_MA0804.1 NaN 0 4653 4673 + \n", + "5 TBX19_MA0804.1 NaN 0 4653 4673 - \n", + "6 Hes1_MA1099.1 NaN 0 1101 1111 + \n", + "7 Hes1_MA1099.1 NaN 0 2855 2865 + \n", + "8 Hes1_MA1099.1 NaN 0 1101 1111 - \n", "\n", - " score p-value q-value matched_sequence \n", - "0 11.4342 0.000072 NaN ACTCATTACC \n", - "1 10.9091 0.000068 NaN ATGACTGACTGTACT \n", - "2 10.1440 0.000095 NaN GAGTTGCGTCATCAG \n", - "3 10.7920 0.000065 NaN TCATTACTTCACTGA \n", - "4 10.4474 0.000046 NaN tatctagaCA \n", - "5 10.4474 0.000046 NaN TGTCTAGATA \n", - "6 11.0779 0.000056 NaN TGCTATATATAT \n", - "7 3.5000 0.000095 NaN AGTTGTATATAT " + " score p-value \n", + "0 11.987469 0.000011 \n", + "1 11.316123 0.000034 \n", + "2 11.073596 0.000043 \n", + "3 10.941541 0.000046 \n", + "4 12.223569 0.000015 \n", + "5 10.531827 0.000035 \n", + "6 9.933365 0.000050 \n", + "7 9.928051 0.000050 \n", + "8 9.933365 0.000050 " ] }, - "execution_count": 14, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "import os\n", - "import pandas\n", - "\n", - "os.system(\"fimo --text --no-qvalue --bfile --uniform-- ../../tests/data/test.meme ../../tests/data/test.fa > test.fimo\")\n", - "\n", - "df = pandas.read_csv(\"test.fimo\", sep=\"\\t\")\n", - "df.head(n=20)" + "hits[0]" ] }, { - "cell_type": "code", - "execution_count": 15, - "id": "4e65e835-ecd4-42a7-9a1b-f0782fa990af", + "cell_type": "markdown", + "id": "8e34b844-b67c-4d17-ba3d-3ce547f0759a", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "13it [00:00, 10469.65it/s]\n", - "/tmp/ipykernel_3680183/2984672063.py:35: FutureWarning: The behavior of DataFrame concatenation with empty or all-NA entries is deprecated. In a future version, this will no longer exclude empty or all-NA columns when determining the result dtypes. To retain the old behavior, exclude the relevant entries before the concat operation.\n", - " hits = pandas.concat(hits)\n" - ] - } - ], "source": [ - "import torch\n", - "import pyfaidx\n", - "\n", - "from tangermeme.utils import one_hot_encode\n", - "from tangermeme.predict import predict\n", - "\n", - "fasta = pyfaidx.Fasta(\"../../tests/data/test.fa\")\n", - "seqs = [fasta[i][:].seq.upper() for i in range(len(fasta.keys()))]\n", - "max_len = max([len(seq) for seq in seqs])\n", - "seqs = [seq + 'N'*(max_len - len(seq)) for seq in seqs]\n", - "\n", - "ignore = 'NZ'\n", - "X = torch.stack([one_hot_encode(seq, ignore=ignore) for seq in seqs]).type(torch.float64)\n", - "fimo = FIMO(\"../../tests/data/test.meme\", bin_size=0.25, eps=0.0001)\n", - "\n", - "y = predict(fimo, X)\n", - "y.shape\n", - "\n", - "motifs = read_meme(\"../../tests/data/test.meme\")\n", - "motif_names = list(motifs.keys())\n", - "seq_names = list(fasta.keys())\n", - "\n", - "\n", - "hits = FIMO(motifs, bin_size=0.01, eps=0.0001).hits(X, dim=0)\n", - "\n", - "for i, df in enumerate(hits):\n", - " df['motif_id'] = [motif_names[i] for _ in range(df.shape[0])]\n", - " df['sequence_name'] = [seq_names[i] for i in df['example_idx']]\n", - " df['stop'] = df['end']\n", - " df['motif_alt_id'] = ['' for _ in range(df.shape[0])]\n", - " df['q-value'] = ['' for _ in range(df.shape[0])]\n", - " df['matched_sequence'] = df['seq']\n", - " del df['example_idx'], df['end'], df['seq']\n", + "When looking at one of these dataframes, we can see that multiple motifs are binding, and that `sequence_name` is constant across them. Basically, we are getting all the motifs that are found in this example, rather than having to do some operations manually after calling FIMO, as one would have to do with the command-line tool." + ] + }, + { + "cell_type": "markdown", + "id": "61f6c084-903f-4fa8-8e10-b7b7c50f9db2", + "metadata": {}, + "source": [ + "#### Optional Arguments\n", "\n", - "hits = pandas.concat(hits)\n", - "hits = hits[['motif_id', 'motif_alt_id', 'sequence_name', 'start', 'stop', \n", - " 'strand', 'score', 'p-value', 'q-value', 'matched_sequence']]" + "In addition to the motifs and sequences, the `fimo` function has a few optional arguments. The first is that you can change the p-value threshold for which hits are reported." ] }, { "cell_type": "code", - "execution_count": 16, - "id": "7fceb4cd-7666-41d8-8222-32dd360234d1", + "execution_count": 9, + "id": "257f6c13-e5d6-462a-a534-51606e6af44d", "metadata": {}, "outputs": [ { @@ -975,8 +819,6 @@ " strand\n", " score\n", " p-value\n", - " q-value\n", - " matched_sequence\n", " \n", " \n", " \n", @@ -984,146 +826,117 @@ " 0\n", " MEOX1_homeodomain_1\n", " NaN\n", - " chr7\n", - " 1351\n", - " 1360\n", + " 5\n", + " 4973\n", + " 4983\n", " +\n", - " 11.4342\n", - " 0.000072\n", - " NaN\n", - " ACTCATTACC\n", + " 13.126775\n", + " 0.000007\n", " \n", " \n", " 1\n", - " GCR_HUMAN.H11MO.0.A\n", + " MEOX1_homeodomain_1\n", " NaN\n", - " chr1\n", - " 70\n", - " 84\n", + " 40\n", + " 4426\n", + " 4436\n", " +\n", - " 10.9091\n", - " 0.000068\n", - " NaN\n", - " ATGACTGACTGTACT\n", + " 13.126775\n", + " 0.000007\n", " \n", " \n", " 2\n", - " FOSL2+JUND_MA1145.1\n", - " NaN\n", - " chr5\n", - " 39\n", - " 53\n", - " -\n", - " 10.1440\n", - " 0.000095\n", + " MEOX1_homeodomain_1\n", " NaN\n", - " GAGTTGCGTCATCAG\n", + " 48\n", + " 4472\n", + " 4482\n", + " +\n", + " 13.074241\n", + " 0.000010\n", " \n", " \n", " 3\n", - " FOSL2+JUND_MA1145.1\n", + " MEOX1_homeodomain_1\n", " NaN\n", - " chr7\n", - " 396\n", - " 410\n", + " 49\n", + " 997\n", + " 1007\n", " +\n", - " 10.7920\n", - " 0.000065\n", - " NaN\n", - " TCATTACTTCACTGA\n", + " 13.268936\n", + " 0.000005\n", " \n", " \n", " 4\n", - " SMAD3_MA0795.1\n", + " MEOX1_homeodomain_1\n", " NaN\n", - " chr5\n", - " 104\n", - " 113\n", + " 69\n", + " 91\n", + " 101\n", " +\n", - " 10.4474\n", - " 0.000046\n", - " NaN\n", - " tatctagaCA\n", + " 13.338450\n", + " 0.000004\n", " \n", " \n", " 5\n", - " SMAD3_MA0795.1\n", + " MEOX1_homeodomain_1\n", " NaN\n", - " chr5\n", - " 104\n", - " 113\n", + " 5\n", + " 4973\n", + " 4983\n", " -\n", - " 10.4474\n", - " 0.000046\n", - " NaN\n", - " TGTCTAGATA\n", + " 13.126775\n", + " 0.000007\n", " \n", " \n", " 6\n", - " MEF2D_HUMAN.H11MO.0.A\n", - " NaN\n", - " chr7\n", - " 1037\n", - " 1048\n", - " +\n", - " 11.0779\n", - " 0.000056\n", - " NaN\n", - " TGCTATATATAT\n", - " \n", - " \n", - " 7\n", - " FOXQ1_MOUSE.H11MO.0.C\n", - " NaN\n", - " chr5\n", - " 122\n", - " 133\n", - " +\n", - " 3.5000\n", - " 0.000095\n", + " MEOX1_homeodomain_1\n", " NaN\n", - " AGTTGTATATAT\n", + " 40\n", + " 4426\n", + " 4436\n", + " -\n", + " 13.126775\n", + " 0.000007\n", " \n", " \n", "\n", "" ], "text/plain": [ - " motif_id motif_alt_id sequence_name start stop strand \\\n", - "0 MEOX1_homeodomain_1 NaN chr7 1351 1360 + \n", - "1 GCR_HUMAN.H11MO.0.A NaN chr1 70 84 + \n", - "2 FOSL2+JUND_MA1145.1 NaN chr5 39 53 - \n", - "3 FOSL2+JUND_MA1145.1 NaN chr7 396 410 + \n", - "4 SMAD3_MA0795.1 NaN chr5 104 113 + \n", - "5 SMAD3_MA0795.1 NaN chr5 104 113 - \n", - "6 MEF2D_HUMAN.H11MO.0.A NaN chr7 1037 1048 + \n", - "7 FOXQ1_MOUSE.H11MO.0.C NaN chr5 122 133 + \n", + " motif_id motif_alt_id sequence_name start stop strand \\\n", + "0 MEOX1_homeodomain_1 NaN 5 4973 4983 + \n", + "1 MEOX1_homeodomain_1 NaN 40 4426 4436 + \n", + "2 MEOX1_homeodomain_1 NaN 48 4472 4482 + \n", + "3 MEOX1_homeodomain_1 NaN 49 997 1007 + \n", + "4 MEOX1_homeodomain_1 NaN 69 91 101 + \n", + "5 MEOX1_homeodomain_1 NaN 5 4973 4983 - \n", + "6 MEOX1_homeodomain_1 NaN 40 4426 4436 - \n", "\n", - " score p-value q-value matched_sequence \n", - "0 11.4342 0.000072 NaN ACTCATTACC \n", - "1 10.9091 0.000068 NaN ATGACTGACTGTACT \n", - "2 10.1440 0.000095 NaN GAGTTGCGTCATCAG \n", - "3 10.7920 0.000065 NaN TCATTACTTCACTGA \n", - "4 10.4474 0.000046 NaN tatctagaCA \n", - "5 10.4474 0.000046 NaN TGTCTAGATA \n", - "6 11.0779 0.000056 NaN TGCTATATATAT \n", - "7 3.5000 0.000095 NaN AGTTGTATATAT " + " score p-value \n", + "0 13.126775 0.000007 \n", + "1 13.126775 0.000007 \n", + "2 13.074241 0.000010 \n", + "3 13.268936 0.000005 \n", + "4 13.338450 0.000004 \n", + "5 13.126775 0.000007 \n", + "6 13.126775 0.000007 " ] }, - "execution_count": 16, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "df = pandas.read_csv(\"test.fimo\", sep=\"\\t\")\n", - "df.head(n=20)" + "hits = fimo(motifs, X, threshold=1e-5)\n", + "hits[0]" ] }, { "cell_type": "code", - "execution_count": 17, - "id": "eeba3f37-9fc9-4d68-8eb7-3fac59bff14e", + "execution_count": 10, + "id": "8e383d81-62f0-4e65-8855-94eef0ebbb56", "metadata": {}, "outputs": [ { @@ -1155,232 +968,889 @@ " strand\n", " score\n", " p-value\n", - " q-value\n", - " matched_sequence\n", " \n", " \n", " \n", " \n", " 0\n", " MEOX1_homeodomain_1\n", - " \n", - " chr7\n", - " 1350\n", - " 1360\n", + " NaN\n", + " 0\n", + " 205\n", + " 215\n", " +\n", - " 11.446572\n", - " 0.000072\n", - " \n", - " ACTCATTACC\n", + " 4.453169\n", + " 0.003351\n", " \n", " \n", - " 0\n", - " GCR_HUMAN.H11MO.0.A\n", - " \n", - " chr1\n", - " 69\n", - " 84\n", + " 1\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 0\n", + " 255\n", + " 265\n", " +\n", - " 10.891225\n", - " 0.000067\n", - " \n", - " ATGACTGACTGTACT\n", - " \n", - " \n", - " 0\n", - " FOSL2+JUND_MA1145.1\n", - " \n", - " chr5\n", - " 38\n", - " 53\n", - " -\n", - " 10.156786\n", - " 0.000096\n", - " \n", - " CTGATGACGCAACTC\n", + " 4.307101\n", + " 0.003472\n", " \n", " \n", - " 1\n", - " FOSL2+JUND_MA1145.1\n", - " \n", - " chr7\n", - " 395\n", + " 2\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 0\n", " 410\n", + " 420\n", " +\n", - " 10.791449\n", - " 0.000066\n", - " \n", - " TCATTACTTCACTGA\n", + " 1.666516\n", + " 0.008586\n", " \n", " \n", - " 0\n", - " SMAD3_MA0795.1\n", - " \n", - " chr5\n", - " 103\n", - " 113\n", + " 3\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 0\n", + " 676\n", + " 686\n", " +\n", - " 10.445715\n", - " 0.000046\n", - " \n", - " TATCTAGACA\n", - " \n", - " \n", - " 1\n", - " SMAD3_MA0795.1\n", - " \n", - " chr5\n", - " 103\n", - " 113\n", - " -\n", - " 10.446602\n", - " 0.000046\n", - " \n", - " TATCTAGACA\n", + " 4.730534\n", + " 0.002991\n", " \n", " \n", - " 0\n", - " MEF2D_HUMAN.H11MO.0.A\n", - " \n", - " chr7\n", - " 1036\n", - " 1048\n", + " 4\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 0\n", + " 742\n", + " 752\n", " +\n", - " 11.063244\n", - " 0.000056\n", - " \n", - " TGCTATATATAT\n", + " 1.547685\n", + " 0.008838\n", " \n", " \n", - " 0\n", - " FOXQ1_MOUSE.H11MO.0.C\n", - " \n", - " chr1\n", - " 281\n", - " 293\n", - " +\n", - " 3.391391\n", - " 0.000082\n", - " \n", - " CATAAAAAAAAA\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", + " ...\n", " \n", " \n", - " 1\n", - " FOXQ1_MOUSE.H11MO.0.C\n", - " \n", - " chr4\n", - " 237\n", - " 249\n", - " +\n", - " 3.391391\n", - " 0.000082\n", - " \n", - " TATAAAAAAAAA\n", + " 9872\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 99\n", + " 4417\n", + " 4427\n", + " -\n", + " 3.817555\n", + " 0.004143\n", " \n", " \n", - " 2\n", - " FOXQ1_MOUSE.H11MO.0.C\n", - " \n", - " chr4\n", - " 236\n", - " 248\n", + " 9873\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 99\n", + " 4452\n", + " 4462\n", " -\n", - " 4.655060\n", - " 0.000050\n", - " \n", - " ATATAAAAAAAA\n", + " 2.583183\n", + " 0.006454\n", " \n", " \n", - " 3\n", - " FOXQ1_MOUSE.H11MO.0.C\n", - " \n", - " chr5\n", - " 121\n", - " 133\n", - " +\n", - " 3.174771\n", - " 0.000095\n", - " \n", - " AGTTGTATATAT\n", + " 9874\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 99\n", + " 4574\n", + " 4584\n", + " -\n", + " 8.203560\n", + " 0.000618\n", " \n", " \n", - " 0\n", - " TBX19_MA0804.1\n", - " \n", - " chr5\n", - " 11\n", - " 31\n", - " +\n", - " 8.525637\n", - " 0.000088\n", - " \n", - " TACGACATATACGTACTACA\n", + " 9875\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 99\n", + " 4624\n", + " 4634\n", + " -\n", + " 1.326745\n", + " 0.009375\n", " \n", " \n", - " 1\n", - " TBX19_MA0804.1\n", - " \n", - " chr5\n", - " 11\n", - " 31\n", + " 9876\n", + " MEOX1_homeodomain_1\n", + " NaN\n", + " 99\n", + " 4898\n", + " 4908\n", " -\n", - " 8.929814\n", - " 0.000074\n", - " \n", - " TACGACATATACGTACTACA\n", + " 7.031611\n", + " 0.001109\n", " \n", " \n", "\n", + "

9877 rows × 8 columns

\n", "" ], "text/plain": [ - " motif_id motif_alt_id sequence_name start stop strand \\\n", - "0 MEOX1_homeodomain_1 chr7 1350 1360 + \n", - "0 GCR_HUMAN.H11MO.0.A chr1 69 84 + \n", - "0 FOSL2+JUND_MA1145.1 chr5 38 53 - \n", - "1 FOSL2+JUND_MA1145.1 chr7 395 410 + \n", - "0 SMAD3_MA0795.1 chr5 103 113 + \n", - "1 SMAD3_MA0795.1 chr5 103 113 - \n", - "0 MEF2D_HUMAN.H11MO.0.A chr7 1036 1048 + \n", - "0 FOXQ1_MOUSE.H11MO.0.C chr1 281 293 + \n", - "1 FOXQ1_MOUSE.H11MO.0.C chr4 237 249 + \n", - "2 FOXQ1_MOUSE.H11MO.0.C chr4 236 248 - \n", - "3 FOXQ1_MOUSE.H11MO.0.C chr5 121 133 + \n", - "0 TBX19_MA0804.1 chr5 11 31 + \n", - "1 TBX19_MA0804.1 chr5 11 31 - \n", + " motif_id motif_alt_id sequence_name start stop strand \\\n", + "0 MEOX1_homeodomain_1 NaN 0 205 215 + \n", + "1 MEOX1_homeodomain_1 NaN 0 255 265 + \n", + "2 MEOX1_homeodomain_1 NaN 0 410 420 + \n", + "3 MEOX1_homeodomain_1 NaN 0 676 686 + \n", + "4 MEOX1_homeodomain_1 NaN 0 742 752 + \n", + "... ... ... ... ... ... ... \n", + "9872 MEOX1_homeodomain_1 NaN 99 4417 4427 - \n", + "9873 MEOX1_homeodomain_1 NaN 99 4452 4462 - \n", + "9874 MEOX1_homeodomain_1 NaN 99 4574 4584 - \n", + "9875 MEOX1_homeodomain_1 NaN 99 4624 4634 - \n", + "9876 MEOX1_homeodomain_1 NaN 99 4898 4908 - \n", "\n", - " score p-value q-value matched_sequence \n", - "0 11.446572 0.000072 ACTCATTACC \n", - "0 10.891225 0.000067 ATGACTGACTGTACT \n", - "0 10.156786 0.000096 CTGATGACGCAACTC \n", - "1 10.791449 0.000066 TCATTACTTCACTGA \n", - "0 10.445715 0.000046 TATCTAGACA \n", - "1 10.446602 0.000046 TATCTAGACA \n", - "0 11.063244 0.000056 TGCTATATATAT \n", - "0 3.391391 0.000082 CATAAAAAAAAA \n", - "1 3.391391 0.000082 TATAAAAAAAAA \n", - "2 4.655060 0.000050 ATATAAAAAAAA \n", - "3 3.174771 0.000095 AGTTGTATATAT \n", - "0 8.525637 0.000088 TACGACATATACGTACTACA \n", - "1 8.929814 0.000074 TACGACATATACGTACTACA " + " score p-value \n", + "0 4.453169 0.003351 \n", + "1 4.307101 0.003472 \n", + "2 1.666516 0.008586 \n", + "3 4.730534 0.002991 \n", + "4 1.547685 0.008838 \n", + "... ... ... \n", + "9872 3.817555 0.004143 \n", + "9873 2.583183 0.006454 \n", + "9874 8.203560 0.000618 \n", + "9875 1.326745 0.009375 \n", + "9876 7.031611 0.001109 \n", + "\n", + "[9877 rows x 8 columns]" ] }, - "execution_count": 17, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "hits" + "hits = fimo(motifs, X, threshold=1e-2)\n", + "hits[0]" + ] + }, + { + "cell_type": "markdown", + "id": "c1ead08b-560d-4d82-b606-adc457030dbc", + "metadata": {}, + "source": [ + "As you might expect, setting a loose threshold will result in a lot of hits." + ] + }, + { + "cell_type": "markdown", + "id": "07fcfb58-7969-4aee-849c-9c8596adf82b", + "metadata": {}, + "source": [ + "You can also add a pseudocount to the motifs. This is supposed to just be for numeric stability, but you may find it useful to tweak. As the pseudocount is increased, the chance of observing very low p-values goes down and so there will be fewer hits (after all, if the pseudocount were a very large number, all regions would be equally likely to be hits)." ] }, { "cell_type": "code", - "execution_count": null, - "id": "478b19e2-7669-461d-8c07-9f157a9bb90a", + "execution_count": 11, + "id": "75726687-b743-4191-9449-d22c57ea5a73", "metadata": {}, - "outputs": [], - "source": [] + "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", + " \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", + "
motif_idmotif_alt_idsequence_namestartstopstrandscorep-value
0MEOX1_homeodomain_1NaN142204230+12.3905640.000043
1MEOX1_homeodomain_1NaN414981508+12.5098320.000029
2MEOX1_homeodomain_1NaN549734983+13.3792010.000009
3MEOX1_homeodomain_1NaN821692179+11.5397050.000094
4MEOX1_homeodomain_1NaN9962972+13.2361330.000010
...........................
67MEOX1_homeodomain_1NaN8635953605-11.9166400.000069
68MEOX1_homeodomain_1NaN9229412951-12.4813230.000035
69MEOX1_homeodomain_1NaN94870880-11.9228700.000069
70MEOX1_homeodomain_1NaN9441334143-12.5098320.000029
71MEOX1_homeodomain_1NaN9446264636-11.8627760.000075
\n", + "

72 rows × 8 columns

\n", + "
" + ], + "text/plain": [ + " motif_id motif_alt_id sequence_name start stop strand \\\n", + "0 MEOX1_homeodomain_1 NaN 1 4220 4230 + \n", + "1 MEOX1_homeodomain_1 NaN 4 1498 1508 + \n", + "2 MEOX1_homeodomain_1 NaN 5 4973 4983 + \n", + "3 MEOX1_homeodomain_1 NaN 8 2169 2179 + \n", + "4 MEOX1_homeodomain_1 NaN 9 962 972 + \n", + ".. ... ... ... ... ... ... \n", + "67 MEOX1_homeodomain_1 NaN 86 3595 3605 - \n", + "68 MEOX1_homeodomain_1 NaN 92 2941 2951 - \n", + "69 MEOX1_homeodomain_1 NaN 94 870 880 - \n", + "70 MEOX1_homeodomain_1 NaN 94 4133 4143 - \n", + "71 MEOX1_homeodomain_1 NaN 94 4626 4636 - \n", + "\n", + " score p-value \n", + "0 12.390564 0.000043 \n", + "1 12.509832 0.000029 \n", + "2 13.379201 0.000009 \n", + "3 11.539705 0.000094 \n", + "4 13.236133 0.000010 \n", + ".. ... ... \n", + "67 11.916640 0.000069 \n", + "68 12.481323 0.000035 \n", + "69 11.922870 0.000069 \n", + "70 12.509832 0.000029 \n", + "71 11.862776 0.000075 \n", + "\n", + "[72 rows x 8 columns]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hits = fimo(motifs, X, eps=1e-2)\n", + "hits[0]" + ] + }, + { + "cell_type": "markdown", + "id": "ccdd1e78-9684-49f5-99b7-7f4381930b9c", + "metadata": {}, + "source": [ + "By default, all motifs will be scanned in both the forward and backward direction. If you want to only scan in the forward direction, you can set that as an option." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "18dbbad1-ce3b-44ef-a125-b57357b9cbf5", + "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", + " \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", + " \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", + " \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", + "
motif_idmotif_alt_idsequence_namestartstopstrandscorep-value
0MEOX1_homeodomain_1NaN142204230+12.1045120.000031
1MEOX1_homeodomain_1NaN247744784+11.1337260.000093
2MEOX1_homeodomain_1NaN414981508+12.2255020.000027
3MEOX1_homeodomain_1NaN549734983+13.1267750.000007
4MEOX1_homeodomain_1NaN821692179+11.2185520.000086
5MEOX1_homeodomain_1NaN9962972+12.9746580.000011
6MEOX1_homeodomain_1NaN1037353745+12.0202410.000037
7MEOX1_homeodomain_1NaN1348174827+11.6186730.000063
8MEOX1_homeodomain_1NaN1818001810+11.6381340.000063
9MEOX1_homeodomain_1NaN1819451955+12.7104490.000013
10MEOX1_homeodomain_1NaN2219651975+11.4465720.000075
11MEOX1_homeodomain_1NaN2438793889+12.1771600.000031
12MEOX1_homeodomain_1NaN2536393649+12.0023060.000037
13MEOX1_homeodomain_1NaN3115281538+12.0202410.000037
14MEOX1_homeodomain_1NaN3523552365+12.5892940.000016
15MEOX1_homeodomain_1NaN3625442554+11.7806750.000056
16MEOX1_homeodomain_1NaN4044264436+13.1267750.000007
17MEOX1_homeodomain_1NaN4326532663+11.1569360.000093
18MEOX1_homeodomain_1NaN4410481058+11.8849200.000051
19MEOX1_homeodomain_1NaN4844724482+13.0742410.000010
20MEOX1_homeodomain_1NaN499971007+13.2689360.000005
21MEOX1_homeodomain_1NaN4918741884+11.1569360.000093
22MEOX1_homeodomain_1NaN5430713081+11.8802590.000051
23MEOX1_homeodomain_1NaN55316326+12.7104490.000013
24MEOX1_homeodomain_1NaN6144974507+11.9824650.000045
25MEOX1_homeodomain_1NaN6543804390+12.1773950.000031
26MEOX1_homeodomain_1NaN6991101+13.3384500.000004
27MEOX1_homeodomain_1NaN7627752785+11.8133670.000051
28MEOX1_homeodomain_1NaN8244354445+12.7113410.000013
29MEOX1_homeodomain_1NaN8327042714+11.2789830.000086
30MEOX1_homeodomain_1NaN9227522762+11.9677080.000045
31MEOX1_homeodomain_1NaN9337623772+12.1773950.000031
32MEOX1_homeodomain_1NaN9424922502+11.3044110.000080
\n", + "
" + ], + "text/plain": [ + " motif_id motif_alt_id sequence_name start stop strand \\\n", + "0 MEOX1_homeodomain_1 NaN 1 4220 4230 + \n", + "1 MEOX1_homeodomain_1 NaN 2 4774 4784 + \n", + "2 MEOX1_homeodomain_1 NaN 4 1498 1508 + \n", + "3 MEOX1_homeodomain_1 NaN 5 4973 4983 + \n", + "4 MEOX1_homeodomain_1 NaN 8 2169 2179 + \n", + "5 MEOX1_homeodomain_1 NaN 9 962 972 + \n", + "6 MEOX1_homeodomain_1 NaN 10 3735 3745 + \n", + "7 MEOX1_homeodomain_1 NaN 13 4817 4827 + \n", + "8 MEOX1_homeodomain_1 NaN 18 1800 1810 + \n", + "9 MEOX1_homeodomain_1 NaN 18 1945 1955 + \n", + "10 MEOX1_homeodomain_1 NaN 22 1965 1975 + \n", + "11 MEOX1_homeodomain_1 NaN 24 3879 3889 + \n", + "12 MEOX1_homeodomain_1 NaN 25 3639 3649 + \n", + "13 MEOX1_homeodomain_1 NaN 31 1528 1538 + \n", + "14 MEOX1_homeodomain_1 NaN 35 2355 2365 + \n", + "15 MEOX1_homeodomain_1 NaN 36 2544 2554 + \n", + "16 MEOX1_homeodomain_1 NaN 40 4426 4436 + \n", + "17 MEOX1_homeodomain_1 NaN 43 2653 2663 + \n", + "18 MEOX1_homeodomain_1 NaN 44 1048 1058 + \n", + "19 MEOX1_homeodomain_1 NaN 48 4472 4482 + \n", + "20 MEOX1_homeodomain_1 NaN 49 997 1007 + \n", + "21 MEOX1_homeodomain_1 NaN 49 1874 1884 + \n", + "22 MEOX1_homeodomain_1 NaN 54 3071 3081 + \n", + "23 MEOX1_homeodomain_1 NaN 55 316 326 + \n", + "24 MEOX1_homeodomain_1 NaN 61 4497 4507 + \n", + "25 MEOX1_homeodomain_1 NaN 65 4380 4390 + \n", + "26 MEOX1_homeodomain_1 NaN 69 91 101 + \n", + "27 MEOX1_homeodomain_1 NaN 76 2775 2785 + \n", + "28 MEOX1_homeodomain_1 NaN 82 4435 4445 + \n", + "29 MEOX1_homeodomain_1 NaN 83 2704 2714 + \n", + "30 MEOX1_homeodomain_1 NaN 92 2752 2762 + \n", + "31 MEOX1_homeodomain_1 NaN 93 3762 3772 + \n", + "32 MEOX1_homeodomain_1 NaN 94 2492 2502 + \n", + "\n", + " score p-value \n", + "0 12.104512 0.000031 \n", + "1 11.133726 0.000093 \n", + "2 12.225502 0.000027 \n", + "3 13.126775 0.000007 \n", + "4 11.218552 0.000086 \n", + "5 12.974658 0.000011 \n", + "6 12.020241 0.000037 \n", + "7 11.618673 0.000063 \n", + "8 11.638134 0.000063 \n", + "9 12.710449 0.000013 \n", + "10 11.446572 0.000075 \n", + "11 12.177160 0.000031 \n", + "12 12.002306 0.000037 \n", + "13 12.020241 0.000037 \n", + "14 12.589294 0.000016 \n", + "15 11.780675 0.000056 \n", + "16 13.126775 0.000007 \n", + "17 11.156936 0.000093 \n", + "18 11.884920 0.000051 \n", + "19 13.074241 0.000010 \n", + "20 13.268936 0.000005 \n", + "21 11.156936 0.000093 \n", + "22 11.880259 0.000051 \n", + "23 12.710449 0.000013 \n", + "24 11.982465 0.000045 \n", + "25 12.177395 0.000031 \n", + "26 13.338450 0.000004 \n", + "27 11.813367 0.000051 \n", + "28 12.711341 0.000013 \n", + "29 11.278983 0.000086 \n", + "30 11.967708 0.000045 \n", + "31 12.177395 0.000031 \n", + "32 11.304411 0.000080 " + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hits = fimo(motifs, X, reverse_complement=False)\n", + "hits[0]" + ] } ], "metadata": { @@ -1399,7 +1869,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.7" + "version": "3.12.4" } }, "nbformat": 4, diff --git a/docs/tutorials/Tutorial_D2_TOMTOM.ipynb b/docs/tutorials/Tutorial_D2_TOMTOM.ipynb new file mode 100644 index 0000000..b45a085 --- /dev/null +++ b/docs/tutorials/Tutorial_D2_TOMTOM.ipynb @@ -0,0 +1,337 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "8ef3314b-3f86-4532-ac9a-3a8d50a49f8d", + "metadata": {}, + "source": [ + "### Tutorial D2 (Built-in Tools): TOMTOM\n", + "\n", + "`FIMO` is a tool for taking a set of PWMs and scanning them against a set of one-hot encoded sequences; in contrast, `TOMTOM` is a tool for comparing pairs of PWMs to determine their similarity. Classically, tools like `TOMTOM` are used to identify redundancies in motif databases and to estimate similarities between binding profiles of proteins. However, `TOMTOM` is also frequently used by researchers who see motifs that are highlighted by some method (such as attributions from machine learning models) and need to know what that motif corresponds to. In this manner, `TOMTOM` serves as a useful automatic annotation tool for discoveries made using `tangermeme`.\n", + "\n", + "Although at first glance `FIMO` and `TOMTOM` appear similar because they involve comparing motifs with something to identify statistical similarities, the difference between operating on long one-hot encoded sequences and a second motif require large methodological changes. First, calculating a background distribution for `FIMO` can be done exactly because you know that the sequences being scanned are limited to being one-hot encoded, whereas the background distribution for `TOMTOM` must be empirically calculated from the set of provided motifs. Second, because motifs are much shorter than the sequences usually being scanned by `FIMO`, the best alignment between two motifs likely involve some amount of overhang on either end of the alignment. Calculating scores and p-values in a manner that don't automatically undervalue imperfect alignments is non-trivial. \n", + "\n", + "For more information about `TOMTOM`, I'd suggest reading [the original paper](https://genomebiology.biomedcentral.com/articles/10.1186/gb-2007-8-2-r24) and the [subsequent follow-up work](https://pubmed.ncbi.nlm.nih.gov/21543443/) that improves the calculation of p-values for alignments with overhangs." + ] + }, + { + "cell_type": "markdown", + "id": "7bf7195e-914c-4e2d-82dc-894b502eac04", + "metadata": {}, + "source": [ + "#### Using TOMTOM\n", + "\n", + "One can run the `TOMTOM` algorithm by calling the `tomtom` function on a pair of lists, where both lists are PWMs that are each of shape `(len(alphabet), motif_length)`. The background distribution is built primarily using the targets, so make sure that the first list is the queries you want to evaluate and the second list is the target distribution you want to match against. For example, if you want to score a single one-hot encoded sequence, you can do the following:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "29dff7e7-ca13-4967-bf5c-2e9385a73571", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(1, 1646)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import numpy\n", + "\n", + "from tangermeme.io import read_meme\n", + "from tangermeme.utils import one_hot_encode\n", + "\n", + "from tangermeme.tools.tomtom import tomtom\n", + "\n", + "q = [one_hot_encode(\"ACGTGT\").double()]\n", + "\n", + "targets = read_meme(\"JASPAR2020_CORE_non-redundant_pfms_meme.txt\")\n", + "target_names = numpy.array([name for name in targets.keys()])\n", + "target_pwms = [pwm for pwm in targets.values()]\n", + "\n", + "\n", + "p, scores, offsets, overlaps, strands = tomtom(q, target_pwms)\n", + "p.shape" + ] + }, + { + "cell_type": "markdown", + "id": "ed6a712d-71fd-46b6-8f18-957b98b67aac", + "metadata": {}, + "source": [ + "You will get several properties of the best alignment between the provided queries and each of the targets. Here, because there was only one query, the first dimension of each returned tensor only has one elements.\n", + "\n", + "If we want to get the names of the statistically significant matches we can easily cross-reference the p-values with the names in the target database." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "2a66616d-457c-4d25-8eb0-f831309aa415", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array(['MA0310.1 HAC1', 'MA0622.1 Mlxip', 'MA0930.1 ABF3',\n", + " 'MA0931.1 ABI5', 'MA1033.1 OJ1058_F05.8', 'MA1331.1 BEH4',\n", + " 'MA1332.1 BEH2', 'MA1333.1 BEH3', 'MA1493.1 HES6'], dtype=' thresh: + score_idx = int(score / bin_size) - smallest[k] + score_idx += score_to_pval_lengths[k] + hits[k].append((numpy.int64(l), i, i+n, score, + 2.0 ** score_to_pvals[score_idx])) + + return hits + + +@numba.njit +def _fast_convert(X, mapping): + for i in range(X.shape[0]): + X[i] = mapping[X[i]] + + +def fimo(motifs, sequences, alphabet=['A', 'C', 'G', 'T'], bin_size=0.1, + eps=0.0001, threshold=0.0001, reverse_complement=True, dim=0): + """An implementation of the FIMO algorithm from the MEME suite. + + This function implements the "Finding Individual Motif Instances" (FIMO) + algorithm from the MEME suite. This algorithm takes a set of PWMs and + identifies where these PWMs have statistically significant hits against a + set of sequences. These sequences can either come from a FASTA file, such + as an entire genome or a set of peaks, or can be one-hot encoded sequences. + + This implementation uses numba to accelerate the inner loop, and + parallelizes across the motif axis. No support exists for calculating + q-values as, in my opinion, q-values do not make sense here and are both + compute- and memory-inefficient. - For efficiency, all PWMs are put in the same convolution operation - regardless of size and so are simultaneously scanned across all of the - sequences, and p-values are only used to calculate thresholds on the score - rather than calculated for each position. - - Because this method is implemented in torch, you can easily use a GPU to - accelerate scanning and use half precision for additional speed ups (if - your GPU supports half precision). - - There are a few ways to use this method: - - (1) Use the `.predict` method to get raw scores of each motif on each - example on both strands. - (2) Use the `.hits` method to get a pandas DataFrame in bed format - showing all locations where the score is higher than the score - threshold at the provided p-value threshold. - (3) Use the `.hits` method with `axis=1` to get a pandas DataFrame in - bed format showing all motif hits at each example. - (4) Use the `.hit_matrix` method to get a matrix of size (n_examples, - n_motifs) showing the maximum score for each motif in each example. - Parameters ---------- motifs: str or dict - A set of motifs to scan with. If a string, this is interpreted as a - filepath to a MEME file. If a dictionary, the keys are interpreted as - the motif names and the values are interpreted as the PWMs. - - alphabet : set or tuple or list, optional - A pre-defined alphabet where the ordering of the symbols is the same - as the index into the returned tensor, i.e., for the alphabet ['A', 'B'] - the returned tensor will have a 1 at index 0 if the character was 'A'. - Characters outside the alphabet are ignored and none of the indexes are - set to 1. This is not necessary or used if a one-hot encoded tensor is - provided for the motif. Default is ['A', 'C', 'G', 'T']. + A MEME file to load containing motifs to scan, or a dictionary where + the keys are names of motifs and the values are PWMs with shape + (len(alphabet), pwm_length). + + sequences: str or numpy.ndarray or torch.Tensor + A set of sequences to scan the motifs against. If this is a string, + assumes it is a filepath to a FASTA-formatted file. If this is a numpy + array or PyTorch tensor, will use those instead. + + alphabet: list, optional + A list of characters to use for the alphabet, defining the order that + characters should appear. Default is ['A', 'C', 'G', 'T']. bin_size: float, optional - The bin size to use for the dynamic programming step when calculating - p-values. Default is 0.1. - + The size of the bins discretizing the PWM scores. The smaller the bin + size the higher the resolution, but the less data may be available to + support it. Default is 0.1. + eps: float, optional - A small value to add to a PWM to stabilize taking the log. Default is - 1e-4. - """ + A small pseudocount to add to the motif PWMs before taking the log. + Default is 0.0001. - def __init__(self, motifs, alphabet=['A', 'C', 'G', 'T'], bin_size=0.1, - eps=0.0001): - super().__init__() - self.bin_size = bin_size - self.alphabet = numpy.array(alphabet) + threshold: float, optional + The p-value threshold to use for reporting matches. Default is 0.0001. - if isinstance(motifs, str): - motifs = read_meme(motifs) - - self.motif_names = numpy.array([name for name in motifs.keys()]) - self.motif_lengths = numpy.array([motif.shape[-1] for motif in - motifs.values()]) - self.n_motifs = len(self.motif_names) - - motif_pwms = numpy.zeros((len(motifs), 4, max(self.motif_lengths)), - dtype=numpy.float32) - bg = math.log2(0.25) + reverse_complement: bool, optional + Whether to scan each motif and also the reverse complements. Default + is True. - self._score_to_pval = [] - self._smallest = [] - for i, (name, motif) in enumerate(motifs.items()): - motif_pwms[i, :, :len(motif.T)] = numpy.log2(motif + eps) - bg - smallest, mapping = _pwm_to_mapping(motif_pwms[i], bin_size) + dim: 0 or 1, optional + Whether to return one dataframe for each motif containing all hits for + that motif across all examples (0, default) or one dataframe for each + example containing all hits across all motifs to that example (1). + Default is 0. - self._smallest.append(smallest) - self._score_to_pval.append(mapping) - self.motif_pwms = torch.nn.Parameter(torch.from_numpy(motif_pwms)) - self._smallest = numpy.array(self._smallest) + Returns + ------- + hits: list of pandas.DataFrames + A list of pandas.DataFrames containing motif hits, where the exact + semantics of each dataframe are determined by `dim`. + """ - def forward(self, X): - """Score a set of sequences. - - This method will run the PWMs against the sequences, reverse-complement - the sequences and run the PWMs against them again, and then return the - maximum per-position score after correcting for the flipping. + tic = time.time() + log_threshold = math.log2(threshold) + + # Extract the motifs and potentially the reverse complements + if isinstance(motifs, str): + motifs_ = read_meme(motifs) + elif isinstance(motifs, dict): + motifs_ = motifs + else: + raise ValueError("`motifs` must be a dict or a filename.") + + motifs_ = list(motifs_.items()) + motifs = [(name, pwm.numpy(force=True)) for name, pwm in motifs_] + if reverse_complement: + for name, pwm in motifs_: + motifs.append((name + '-rc', pwm.numpy(force=True)[::-1, ::-1])) + + # Initialize arrays to store motif properties + n_motifs = len(motifs) + motif_pwms, motif_names, motif_lengths = [], [], [0] + _score_to_pvals, _score_to_pvals_lengths = [], [0] + + _smallest = numpy.empty(n_motifs, dtype=numpy.int32) + _score_thresholds = numpy.empty(n_motifs, dtype=numpy.float32) + + # Fill out these motif properties + for i, (name, motif) in enumerate(motifs): + motif_names.append(name) + motif_lengths.append(motif.shape[-1]) + motif_pwm = numpy.log2(motif + eps) - math.log2(0.25) + motif_pwms.append(motif_pwm) + + smallest, mapping = _pwm_to_mapping(motif_pwm, bin_size) + _smallest[i] = smallest + _score_to_pvals.append(mapping) + _score_to_pvals_lengths.append(len(mapping)) + + idx = numpy.where(_score_to_pvals[i] < log_threshold)[0] + if len(idx) > 0: + _score_thresholds[i] = (idx[0] + smallest) * bin_size + else: + _score_thresholds[i] = float("inf") + + # Convert these back to numpy arrays + motif_pwms = numpy.concatenate(motif_pwms, axis=-1) + motif_names = numpy.array(motif_names) + motif_lengths = numpy.cumsum(motif_lengths).astype(numpy.uint64) + + _score_to_pvals = numpy.concatenate(_score_to_pvals) + _score_to_pvals_lengths = numpy.cumsum(_score_to_pvals_lengths) + + # Extract the sequence from a FASTA or torch tensors + if isinstance(sequences, str): + fasta = pyfaidx.Fasta(sequences) + sequence_names = numpy.array(list(fasta.keys())) + X, lengths = [], [0] - Parameters - ---------- - X: torch.tensor, shape=(n, 4, length) - A tensor containing one-hot encoded sequences. - """ + alphabet = ''.join(alphabet) + alpha_idxs = numpy.frombuffer(bytearray(alphabet, 'utf8'), dtype=numpy.int8) + one_hot_mapping = numpy.zeros(256, dtype=numpy.int8) - 1 + for i, idx in enumerate(alpha_idxs): + one_hot_mapping[idx] = i - y_fwd = torch.nn.functional.conv1d(X, self.motif_pwms) - y_bwd = torch.nn.functional.conv1d(X, torch.flip(self.motif_pwms, (1, - 2))) - return torch.stack([y_fwd, y_bwd]).permute(1, 2, 0, 3) - - @torch.no_grad() - def hits(self, X, X_attr=None, threshold=0.0001, batch_size=256, dim=0, - device='cuda', verbose=False): - """Find motif hits that pass the given threshold. - - This method will first scan the PWMs over all sequences, identify where - those scores are above the per-motif score thresholds (by converting - the provided p-value thresholds to scores), extract those coordinates - and provide the hits in a convenient format. - - - Parameters - ---------- - X: torch.tensor, shape=(n, 4, length) - A tensor containing one-hot encoded sequences. - - X_attr: torch.tensor, shape=(n, 4, length), optional - A tensor containing the per-position attributions. The values in - this tensor will be summed across all four channels in the positions - found by the hits, so make sure that the four channels are encoding - something summable. You may want to multiply X_attr by X before - passing it in. If None, do not sum attributions. - - threshold: float, optional - The p-value threshold to use when calling hits. Default is 0.0001. - - batch_size: int, optional - The number of examples to process in parallel. Default is 256. - - dim: 0 or 1, optional - The dimension to provide hits over. Similar to other APIs, one can - view this as the dimension to remove from the returned results. If - 0, provide one DataFrame per motif that shows all hits for that - motif across examples. If 1, provide one DataFrame per motif that - shows all motif hits within each example. - - device: str or torch.device, optional - The device to move the model and batches to when making predictions. - If set to 'cuda' without a GPU, this function will crash and must be - set to 'cpu'. Default is 'cuda'. - - verbose: bool, optional - Whether to display a progress bar as examples are being processed. - Default is False. - - - Returns - ------- - dfs: list of pandas.DataFrame - A list of DataFrames containing hit calls, either with one per - example or one per motif. - """ - - n = self.n_motifs if dim == 0 else len(X) - hits = [[] for i in range(n)] - - log_threshold = numpy.log2(threshold) - - scores = predict(self, X, batch_size=batch_size, device=device) - score_thresh = torch.empty(1, scores.shape[1], 1, 1) - for i, smallest in enumerate(self._smallest): - idx = numpy.where(self._score_to_pval[i] < log_threshold)[0] - - if len(idx) > 0: - score_thresh[0, i] = (idx[0] + smallest) * self.bin_size - else: - score_thresh[0, i] = float("inf") - - - hit_idxs = torch.where(scores > score_thresh) - for idxs in tqdm(zip(*hit_idxs), disable=not verbose): - example_idx, motif_idx, strand_idx, pos_idx = idxs - score = scores[(example_idx, motif_idx, strand_idx, pos_idx)].item() - score_idx = int(score / self.bin_size) - self._smallest[motif_idx] - pval = math.pow(2, self._score_to_pval[motif_idx][score_idx]) - - l = self.motif_lengths[motif_idx] - start = pos_idx.item() - if strand_idx == 1: - end = start + max(self.motif_lengths) - start = start + max(self.motif_lengths) - l - else: - end = start + l - - char_idxs = X[example_idx, :, start:end].argmax(axis=0).numpy( - force=True) - seq = ''.join(self.alphabet[char_idxs]) - strand = '+-'[strand_idx] - - if X_attr is not None: - attr = X_attr[example_idx, :, start:end].sum(axis=1) - else: - attr = '.' + for name, chrom in fasta.items(): + chrom = chrom[:].seq.upper() + lengths.append(lengths[-1] + len(chrom)) - entry_idx = example_idx.item() if dim == 0 else motif_idx.item() - entry = entry_idx, start, end, strand, score, pval, seq + X_idxs = numpy.frombuffer(bytearray(chrom, "utf8"), dtype=numpy.int8) + _fast_convert(X_idxs, one_hot_mapping) + X.append(X_idxs) - idx = motif_idx if dim == 0 else example_idx - hits[idx].append(entry) - - name = 'example_idx' if dim == 0 else 'motif' - names = name, 'start', 'end', 'strand', 'score', 'p-value', 'seq' - hits = [pandas.DataFrame(hits_, columns=names) for hits_ in hits] - if dim == 1: - for hits_ in hits: - hits_['motif'] = self.motif_names[hits_['motif']] - - return hits - - @torch.no_grad() - def hit_matrix(self, X, threshold=None, batch_size=256, device='cuda'): - """Return the maximum score per motif for each example. - - Parameters - ---------- - X: torch.tensor, shape=(n, 4, length) - A tensor containing one-hot encoded sequences. - - X_attr: torch.tensor, shape=(n, 4, length), optional - A tensor containing the per-position attributions. The values in - this tensor will be summed across all four channels in the positions - found by the hits, so make sure that the four channels are encoding - something summable. You may want to multiply X_attr by X before - passing it in. If None, do not sum attributions. + X = numpy.concatenate(X) + X_lengths = numpy.array(lengths, dtype=numpy.int64) + + elif isinstance(sequences, (torch.Tensor, numpy.ndarray)): + sequence_names = None + X = ((sequences.argmax(axis=1) + 1) * sequences.sum(axis=1)) - 1 + X_lengths = numpy.arange(X.shape[0]+1) * X.shape[-1] - batch_size: int, optional - The number of examples to process in parallel. Default is 256. + if isinstance(X, torch.Tensor): + X = X.numpy(force=True) - device: str or torch.device, optional - The device to move the model and batches to when making predictions. - If set to 'cuda' without a GPU, this function will crash and must be - set to 'cpu'. Default is 'cuda'. + X = X.astype(numpy.int8).flatten() + X_lengths = X_lengths.astype(numpy.int64) + # Use a fast numba function to run the core algorithm + hits = _fast_hits(X, X_lengths, motif_pwms, motif_lengths, + _score_thresholds, bin_size, _smallest, _score_to_pvals, + _score_to_pvals_lengths) - Returns - ------- - y_hat: torch.Tensor, shape=(X.shape[0], n_motifs) - The score of the strongest motif hit in each sequence. Note that - this is the raw score, not a p-value. - """ - y_hat = predict(self, X, batch_size=batch_size, device=device) - return y_hat.max(dim=-1).values.max(dim=-1).values + # Convert the results to pandas DataFrames + names = ['sequence_name', 'start', 'stop', 'score', 'p-value'] + n_ = n_motifs // 2 if reverse_complement else n_motifs + for i in range(n_): + if reverse_complement: + hits_ = pandas.DataFrame(hits[i] + hits[i + n_], columns=names) + hits_['strand'] = ['+'] * len(hits[i]) + ['-'] * len(hits[i+n_]) + else: + hits_ = pandas.DataFrame(hits[i], columns=names) + hits_['strand'] = ['+'] * len(hits[i]) - def motif_hits(self, X, device='cuda'): - """...""" + hits_['motif_id'] = [motif_names[i] for _ in range(len(hits_))] + hits_['motif_alt_id'] = [numpy.nan for _ in range(len(hits_))] - length = max(self.motif_lengths) - if X.shape[-1] < length: - flank = torch.zeros(*X.shape[:2], length, dtype=X.dtype, - device=X.device) - X = torch.cat([flank, X, flank], dim=-1) + if sequence_names is not None: + hits_['sequence_name'] = sequence_names[hits_['sequence_name']] + + hits[i] = hits_[['motif_id', 'motif_alt_id', 'sequence_name', 'start', + 'stop', 'strand', 'score', 'p-value']] - y = predict(self, X.float(), device=device) + hits = hits[:n_] - score, offset = y.max(dim=-1) - score, strand = score.max(dim=-1) + if dim == 1: + hits = pandas.concat(hits) + _names = numpy.unique(hits['sequence_name']) + hits = [hits[hits['sequence_name'] == name].reset_index(drop=True) + for name in _names] - int_score = numpy.round(score.numpy(force=True) / self.bin_size).astype(numpy.int32).T - int_score -= self._smallest[:, None] + return hits - pvals = [self._score_to_pval[i][int_score[i]] for i in range(int_score.shape[0])] - pvals = numpy.stack(pvals) - return pvals, offset, strand - diff --git a/tangermeme/tools/tomtom.py b/tangermeme/tools/tomtom.py index 2d22b0b..e2dea62 100644 --- a/tangermeme/tools/tomtom.py +++ b/tangermeme/tools/tomtom.py @@ -4,6 +4,7 @@ import math import numpy import numba +import torch from numba import njit from numba import prange @@ -346,6 +347,8 @@ def _tomtom(Q, T, Q_lens, T_lens, Q_norm, T_norm, rr_inv, rr_counts, n_nearest, if reverse_complement == 1: _merge_rc_results(_results[pid]) + else: + _results[pid, :, 4] = 0 if n_nearest == -1: results[i] = _results[pid, :n_in_targets] @@ -461,6 +464,10 @@ def tomtom(Qs, Ts, n_nearest=None, n_score_bins=100, n_median_bins=1000, if n_nearest is None: n_nearest = -1 + + if isinstance(Ts[0], torch.Tensor): + Ts = [T.numpy(force=True) for T in Ts] + Q_lens = numpy.array([Q.shape[-1] for Q in Qs], dtype='int64') Q = numpy.concatenate(Qs, axis=-1) diff --git a/tangermeme/utils.py b/tangermeme/utils.py index 7f91e81..364b439 100644 --- a/tangermeme/utils.py +++ b/tangermeme/utils.py @@ -197,7 +197,7 @@ def _fast_one_hot_encode(X_ohe, seq, mapping): if idx == -2: raise ValueError("Encountered character that is not in " + "`alphabet` or in `ignore`.") - + X_ohe[i, idx] = 1 @@ -254,9 +254,10 @@ def one_hot_encode(sequence, alphabet=['A', 'C', 'G', 'T'], dtype=torch.int8, ignore = ''.join(ignore) - seq_idxs = numpy.frombuffer(bytearray(sequence, "utf8"), dtype=numpy.int8) - alpha_idxs = numpy.frombuffer(bytearray(alphabet, "utf8"), dtype=numpy.int8) - ignore_idxs = numpy.frombuffer(bytearray(ignore, "utf8"), dtype=numpy.int8) + e = "utf8" + seq_idxs = numpy.frombuffer(bytearray(sequence, e), dtype=numpy.int8) + alpha_idxs = numpy.frombuffer(bytearray(alphabet, e), dtype=numpy.int8) + ignore_idxs = numpy.frombuffer(bytearray(ignore, e), dtype=numpy.int8) one_hot_mapping = numpy.zeros(256, dtype=numpy.int8) - 2 for i, idx in enumerate(alpha_idxs): @@ -331,3 +332,134 @@ def random_one_hot(shape, probs=None, dtype='int8', random_state=None): ohe[i, choices, numpy.arange(shape[2])] = 1 return torch.from_numpy(ohe) + + +def chunk(X, size=1024, overlap=0): + """Chunk a set of sequences into overlapping blocks. + + This function will take a set of sequences of variable length and will + return a set of fixed-length blocks that tile the sequence with a fixed + amount of overlap. This is useful when applying a method, such as FIMO or + even a larger predictive model, to variable length sequences such as + chromosomes. + + Unless the total sequence length is a multiple of the size, the final chunk + produced from a sequence will be shorter than the size. In this case, the + final chunk is excluded because it would not be an accurate representation + of that sequence regardless. + + + Parameters + ---------- + X: list of torch.Tensors + A list of one-hot encoded sequences that each are of shape (4, -1). + + size: int, optional + The size of the chunks to produce from the sequence. Default is 1024. + + overlap: int, optional + The overlap between adjacent chunks. This is, essentially, the stride + of the unrolling process. Default is 0. + + + Returns + ------- + y: torch.Tensor, shape=(-1, len(alphabet), size) + A single tensor containing strides across the sequences. The chunks + are concatenated together across examples such that the final chunk + from the first item is followed by first chunk from the second item. + """ + + if not isinstance(X, list): + raise ValueError("X must be a list of tensors.") + + if not isinstance(size, int) or size <= 0: + raise ValueError("size must be a positive integer.") + + if not isinstance(overlap, int) or overlap < 0: + raise ValueError("overlap must be a non-negative integer.") + + return torch.cat([x.unfold(-1, size, size-overlap).permute(1, 0, 2) + for x in X], dim=0) + + +def unchunk(X, lengths=None, overlap=0): + """Unchunk fixed-length segments back into variable-length sequences. + + After chunking a set of variable length sequences into fixed-length chunks + and applying some method on the chunks that results in some bp-resolution + result, merge the chunks back into a tensor of the same length as the + original sequence. When the final chunk was discarded due to the original + sequence not being divisible by the chosen size, that portion will not + be reconstructed by this method. + + The overlap value should be the same as when the sequence was chunked, and + should correspond to the number of positions that are shared across adjacent + examples. When overlap is set to a value greater than 0, half of the overlap + goes to the elements as follows: + + <------------* | + overlap + | *-----------> + + + Parameters + ---------- + X: list or numpy.ndarray or torch.tensor, shape=(-1, n_outputs, size) + A set of fixed-length tensors for any number of outputs. Usually the + result of applying `chunk` and then some form of model. + + lengths: list or numpy.ndarray or torch.tensor, shape=(-1,) or None + The *original lengths* of the elements that were chunked. This is not + the number of chunks produced, which will be influenced by the overlap, + but the actual length in bp of the original sequences. If None, assume + that all chunks in `X` come from a single variable-length sequence. + Default is None. + + overlap: int, optional + The number of bp overlap between adjacent chunks. Default is 0. + + + Returns + ------- + y: list of torch.Tensors or one torch.Tensor, shape=(n_outputs, -1) + A list of variable-length tensors if `lengths` is provided, otherwise + a single tensor. + """ + + X = _cast_as_tensor(X) + if X.ndim <= 2: + raise ValueError("`X` must have at least three dimensions, with the " + "last dimension corresponding to length.") + + lengths = _validate_input(_cast_as_tensor(lengths), "lengths", shape=(-1,), + min_value=0) + + size = X.shape[-1] + lengths = (lengths - size) // (size - overlap) + 1 + lengths_csum = 0 + + y = [] + for length in lengths: + X_ = X[lengths_csum:lengths_csum+length] + + if overlap > 0: + s = overlap // 2 + e = -(overlap - s) + + if X_.shape[0] == 1: + X_ = X_[..., s:e].moveaxis(0, -2).reshape(*X_.shape[1:-1], -1) + elif X_.shape[0] == 2: + X_ = torch.cat([X_[0, ..., :e], X_[1, ..., s:]], dim=-1) + else: + X_ = torch.cat([X_[0, ..., :e], + X_[1:-1, ..., s:e].moveaxis(0, -2).reshape(*X_.shape[1:-1], -1), + X_[-1, ..., s:]], dim=-1) + else: + X_ = X_.moveaxis(0, -2).reshape(*X_.shape[1:-1], -1) + + y.append(X_) + lengths_csum += length + + return y + \ No newline at end of file diff --git a/tests/data/test2.meme b/tests/data/test2.meme new file mode 100644 index 0000000..eef101a --- /dev/null +++ b/tests/data/test2.meme @@ -0,0 +1,60 @@ +MEME version 4 + +ALPHABET= ACGT + +strands: + - + +Background letter frequencies +A 0.25 C 0.25 G 0.25 T 0.25 + +MOTIF MA0636.1 BHLHE41 +letter-probability matrix: alength= 4 w= 10 nsites= 9573 E= 0 + 0.302309 0.109266 0.582263 0.006163 + 0.013032 0.002261 0.243484 0.741223 + 0.000358 0.998925 0.000538 0.000179 + 0.993583 0.002139 0.003743 0.000535 + 0.000179 0.998746 0.000179 0.000896 + 0.000359 0.000179 0.999462 0.000000 + 0.003378 0.002844 0.002844 0.990933 + 0.000179 0.000179 0.999641 0.000000 + 0.815747 0.179862 0.001024 0.003366 + 0.008609 0.648441 0.114588 0.228362 +URL http://jaspar.genereg.net/matrix/MA0636.1 + +MOTIF MA0641.1 ELF4 +letter-probability matrix: alength= 4 w= 12 nsites= 1059 E= 0 + 0.564684 0.102927 0.151086 0.181303 + 0.748408 0.077495 0.015924 0.158174 + 0.151261 0.710466 0.057296 0.080978 + 0.015274 0.889488 0.094340 0.000898 + 0.051088 0.943236 0.005676 0.000000 + 0.000815 0.000000 0.999185 0.000000 + 0.000000 0.000000 0.998371 0.001629 + 0.994616 0.000000 0.002692 0.002692 + 0.985294 0.006684 0.002674 0.005348 + 0.033752 0.014129 0.947410 0.004710 + 0.003749 0.052484 0.026242 0.917526 + 0.379473 0.078154 0.435970 0.106403 +URL http://jaspar.genereg.net/matrix/MA0641.1 + +MOTIF MA0042.2 FOXI1 +letter-probability matrix: alength= 4 w= 7 nsites= 5832 E= 0 + 0.105967 0.006687 0.887346 0.000000 + 0.013847 0.011228 0.006549 0.968376 + 0.899687 0.093880 0.006433 0.000000 + 0.995575 0.004425 0.000000 0.000000 + 0.977706 0.004345 0.005479 0.012469 + 0.025363 0.836026 0.007754 0.130856 + 0.992901 0.002302 0.004797 0.000000 +URL http://jaspar.genereg.net/matrix/MA0042.2 + +MOTIF MA0033.2 FOXL1 +letter-probability matrix: alength= 4 w= 7 nsites= 4933 E= 0 + 0.426110 0.002635 0.542875 0.028380 + 0.001921 0.079908 0.000000 0.918171 + 0.874657 0.114913 0.010430 0.000000 + 0.989034 0.007863 0.000000 0.003104 + 0.973127 0.016694 0.010179 0.000000 + 0.000000 0.778870 0.000000 0.221130 + 0.985364 0.011132 0.000000 0.003504 +URL http://jaspar.genereg.net/matrix/MA0033.2 diff --git a/tests/test_io.py b/tests/test_io.py index 6a0207d..a6dc504 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -739,7 +739,7 @@ def test_read_meme(): assert len(motifs) == 12 assert isinstance(motifs, dict) assert all(isinstance(key, str) for key in motifs.keys()) - assert all(isinstance(pwm, numpy.ndarray) for pwm in motifs.values()) + assert all(isinstance(pwm, torch.Tensor) for pwm in motifs.values()) assert all([key in motifs.keys() for key in keys]) assert_array_almost_equal(motifs['FOSL2+JUND_MA1145.1'], pwm) @@ -754,7 +754,7 @@ def test_read_meme_n_motifs(): assert len(motifs) == 6 assert isinstance(motifs, dict) assert all(isinstance(key, str) for key in motifs.keys()) - assert all(isinstance(pwm, numpy.ndarray) for pwm in motifs.values()) + assert all(isinstance(pwm, torch.Tensor) for pwm in motifs.values()) assert all([key in motifs.keys() for key in keys]) diff --git a/tests/test_utils.py b/tests/test_utils.py index 2fca19c..88ec94a 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -6,6 +6,8 @@ from tangermeme.utils import characters from tangermeme.utils import one_hot_encode from tangermeme.utils import random_one_hot +from tangermeme.utils import chunk +from tangermeme.utils import unchunk from numpy.testing import assert_raises from numpy.testing import assert_array_almost_equal @@ -318,3 +320,93 @@ def test_random_one_hot_raises_type(): def test_random_one_hot_raises_shape(): assert_raises(ValueError, random_one_hot, (2, 3)) assert_raises(ValueError, random_one_hot, (3,)) + + +### + + +def test_chunk(): + X0 = [torch.randn(4, 10), torch.randn(4, 14)] + X = chunk(X0, size=2) + + assert X.dtype == X0[0].dtype + assert X.shape == (12, 4, 2) + assert_array_almost_equal(X, torch.stack([X0[0][:, :2], X0[0][:, 2:4], + X0[0][:, 4:6], X0[0][:, 6:8], X0[0][:, 8:10], X0[1][:, :2], + X0[1][:, 2:4], X0[1][:, 4:6], X0[1][:, 6:8], X0[1][:, 8:10], + X0[1][:, 10:12], X0[1][:, 12:14]])) + + X0 = [torch.randn(4, 10), torch.randn(4, 14)] + X = chunk(X0, size=5) + + assert X.dtype == X0[0].dtype + assert X.shape == (4, 4, 5) + + +def test_chunk_overlap(): + X0 = [torch.randn(4, 10), torch.randn(4, 14)] + + X = chunk(X0, size=2, overlap=1) + assert X.shape == (22, 4, 2) + assert_array_almost_equal(X[:10], torch.stack([X0[0][:, :2], X0[0][:, 1:3], + X0[0][:, 2:4], X0[0][:, 3:5], X0[0][:, 4:6], X0[0][:, 5:7], + X0[0][:, 6:8], X0[0][:, 7:9], X0[0][:, 8:10], X0[1][:, :2]])) + + + X = chunk(X0, size=5, overlap=2) + assert X.shape == (6, 4, 5) + assert_array_almost_equal(X, torch.stack([X0[0][:, :5], X0[0][:, 3:8], + X0[1][:, :5], X0[1][:, 3:8], X0[1][:, 6:11], X0[1][:, 9:]])) + + +def test_chunk_raises(): + assert_raises(ValueError, chunk, [torch.randn(4, 10)], -1) + assert_raises(ValueError, chunk, [torch.randn(4, 10)], 1.2) + + assert_raises(ValueError, chunk, [torch.randn(4, 10)], 2, -1) + assert_raises(ValueError, chunk, [torch.randn(4, 10)], 2, 0.3) + + assert_raises(ValueError, chunk, torch.randn(4, 10), 2) + assert_raises(ValueError, chunk, torch.randn(3, 4, 10), 2) + + +### + + +def test_unchunk(): + lengths = [50, 67] + X0 = [torch.randn(4, lengths[0]), torch.randn(4, lengths[1])] + + X = chunk(X0, size=4, overlap=3) + X1 = unchunk(X, lengths, overlap=3) + assert_array_almost_equal(X1[0], X0[0]) + assert_array_almost_equal(X1[1], X0[1]) + + X = chunk(X0, size=4, overlap=2) + X1 = unchunk(X, lengths, overlap=2) + assert_array_almost_equal(X1[0], X0[0]) + assert_array_almost_equal(X1[1], X0[1][:, :66]) + + X = chunk(X0, size=23, overlap=8) + X1 = unchunk(X, lengths, overlap=8) + assert_array_almost_equal(X1[0], X0[0][:, :38]) + assert_array_almost_equal(X1[1], X0[1][:, :53]) + + X = chunk(X0, size=23, overlap=0) + X1 = unchunk(X, lengths, overlap=0) + assert_array_almost_equal(X1[0], X0[0][:, :46]) + assert_array_almost_equal(X1[1], X0[1][:, :46]) + + X0 = X0[:1] + X = chunk(X0, size=23, overlap=6) + X1 = unchunk(X, lengths[:1], overlap=6) + assert_array_almost_equal(X1[0], X0[0][:, :40]) + + +def test_unchunk_raises(): + lengths = [50, 67] + X0 = [torch.randn(4, lengths[0]), torch.randn(4, lengths[1])] + X = chunk(X0[:1], size=7, overlap=2) + + assert_raises(IndexError, unchunk, X, lengths, overlap=2) + assert_raises(ValueError, unchunk, X[0], lengths[:1], overlap=2) diff --git a/tests/tools/test_cmd_tomtom.py b/tests/tools/test_cmd_tomtom.py index 2cd5787..65f6afb 100644 --- a/tests/tools/test_cmd_tomtom.py +++ b/tests/tools/test_cmd_tomtom.py @@ -3,7 +3,6 @@ import pytest import pandas - from numpy.testing import assert_raises from numpy.testing import assert_array_almost_equal @@ -29,7 +28,6 @@ def test_cmd_tomtom(): assert_array_almost_equal(tomtom_results['Offset'], [2, 2, 0, 3]) assert_array_almost_equal(tomtom_results['Overlap'], [7, 7, 10, 10]) - strands = ['-', '-', '+', '-'] for i, strand in enumerate(tomtom_results['Strand']): assert strand.strip() == strands[i] @@ -56,7 +54,6 @@ def test_cmd_tomtom2(): assert_array_almost_equal(tomtom_results['Offset'], [2, 2, 0, 3]) assert_array_almost_equal(tomtom_results['Overlap'], [7, 7, 10, 10]) - strands = ['-', '-', '+', '-'] for i, strand in enumerate(tomtom_results['Strand']): assert strand.strip() == strands[i] diff --git a/tests/tools/test_fimo.py b/tests/tools/test_fimo.py index 4d2146e..15f96be 100644 --- a/tests/tools/test_fimo.py +++ b/tests/tools/test_fimo.py @@ -7,13 +7,17 @@ import pandas from tangermeme.utils import random_one_hot +from tangermeme.utils import chunk +from tangermeme.utils import unchunk + from tangermeme.ersatz import substitute from tangermeme.predict import predict from tangermeme.tools.fimo import _pwm_to_mapping -from tangermeme.tools.fimo import FIMO +from tangermeme.tools.fimo import fimo from numpy.testing import assert_raises +from numpy.testing import assert_array_equal from numpy.testing import assert_array_almost_equal @@ -41,10 +45,6 @@ def long_log_pwm(): pwm = pwm / pwm.sum(axis=0, keepdims=True) return numpy.log2(pwm) -@pytest.fixture -def fimo(): - return FIMO("tests/data/test.meme") - ### @@ -53,7 +53,7 @@ def test_pwm_to_mapping(log_pwm): smallest, mapping = _pwm_to_mapping(log_pwm, 0.1) assert smallest == -596 - assert mapping.shape == (586,) + assert mapping.shape == (600,) assert mapping.dtype == numpy.float64 @@ -66,14 +66,14 @@ def test_pwm_to_mapping(log_pwm): [-28.], 4) assert numpy.all(numpy.diff(mapping[~numpy.isinf(mapping)]) <= 0) - assert numpy.isinf(mapping).sum() == 103 + assert numpy.isinf(mapping).sum() == 117 def test_short_pwm_to_mapping(short_log_pwm): smallest, mapping = _pwm_to_mapping(short_log_pwm, 0.1) assert smallest == -78 - assert mapping.shape == (65,) + assert mapping.shape == (67,) assert mapping.dtype == numpy.float64 assert_array_almost_equal(mapping[:8], [ 8.3267e-17, -9.3109e-02, @@ -83,14 +83,14 @@ def test_short_pwm_to_mapping(short_log_pwm): [-4], 4) assert numpy.all(numpy.diff(mapping[~numpy.isinf(mapping)]) <= 0) - assert numpy.isinf(mapping).sum() == 4 + assert numpy.isinf(mapping).sum() == 6 def test_long_pwm_to_mapping(long_log_pwm): smallest, mapping = _pwm_to_mapping(long_log_pwm, 0.1) assert smallest == -2045 - assert mapping.shape == (2035,) + assert mapping.shape == (2085,) assert mapping.dtype == numpy.float64 assert_array_almost_equal(mapping[:8], [-9.79656934e-16, -7.45058160e-09, @@ -103,14 +103,14 @@ def test_long_pwm_to_mapping(long_log_pwm): [-99.], 4) assert numpy.all(numpy.diff(mapping[~numpy.isinf(mapping)]) <= 0) - assert numpy.isinf(mapping).sum() == 436 + assert numpy.isinf(mapping).sum() == 486 def test_pwm_to_mapping_small_bins(log_pwm): smallest, mapping = _pwm_to_mapping(log_pwm, 0.01) assert smallest == -5955 - assert mapping.shape == (5850,) + assert mapping.shape == (5864,) assert mapping.dtype == numpy.float64 assert_array_almost_equal(mapping[:8], [-4.5076e-07, -4.6939e-07, @@ -123,14 +123,14 @@ def test_pwm_to_mapping_small_bins(log_pwm): [-28.], 4) assert numpy.all(numpy.diff(mapping[~numpy.isinf(mapping)]) <= 0) - assert numpy.isinf(mapping).sum() == 1024 + assert numpy.isinf(mapping).sum() == 1038 def test_pwm_to_mapping_large_bins(log_pwm): smallest, mapping = _pwm_to_mapping(log_pwm, 1) assert smallest == -60 - assert mapping.shape == (60,) + assert mapping.shape == (74,) assert mapping.dtype == numpy.float64 assert_array_almost_equal(mapping[:8], [-3.5277e-07, -3.9577e-07, @@ -140,96 +140,125 @@ def test_pwm_to_mapping_large_bins(log_pwm): [-27], 4) assert numpy.all(numpy.diff(mapping[~numpy.isinf(mapping)]) <= 0) - assert numpy.isinf(mapping).sum() == 8 + assert numpy.isinf(mapping).sum() == 22 ## -def test_fimo(fimo): - assert fimo.bin_size == 0.1 - assert tuple(fimo.alphabet) == tuple(['A', 'C', 'G', 'T']) +def test_fimo(): + hits = fimo("tests/data/test.meme", "tests/data/test.fa") - assert len(fimo.motif_names) == 12 - assert_array_almost_equal(fimo.motif_lengths, [10, 9, 15, 15, 8, 20, 10, - 10, 12, 12, 20, 10]) - assert fimo.n_motifs == 12 + assert len(hits) == 12 + for df in hits: + assert isinstance(df, pandas.DataFrame) + assert df.shape[1] == 8 + assert tuple(df.columns) == ('motif_id', 'motif_alt_id', 'sequence_name', + 'start', 'stop', 'strand', 'score', 'p-value') - assert_array_almost_equal(fimo.motif_pwms[0][:, :3].detach(), [ - [ 0.2726, -2.441 , -3.7744], - [-0.0912, 1.0043, -1.116 ], - [ 0.3947, 0.7401, -4.0455], - [-0.8884, -2.8234, 1.7683]], 4) - assert_array_almost_equal(fimo.motif_pwms[1][:, :3].detach(), [ - [ 0.8834, -11.2877, -1.574 ], - [ -1.8404, -3.4137, -2.0541], - [ 0.6938, -11.2877, 1.732 ], - [ -1.9428, 1.966 , -3.2798]], 4) - assert_array_almost_equal(fimo.motif_pwms[2][:, :3].detach(), [ - [ 0.911 , -1.4407, 0.829 ], - [-2.4391, -4.6295, -0.6795], - [ 0.5022, 1.7452, -0.1969], - [-0.9423, -2.0565, -0.4572]], 4) - assert_array_almost_equal(fimo._smallest, [ -536, -535, -520, -470, - -741, -626, -821, -712, -604, -1260, -721, -203]) + assert hits[0].shape == (1, 8) + assert hits[9].shape == (1, 8) - assert_array_almost_equal(fimo._score_to_pval[0][:5], [ 2.495928e-08, - -9.287154e-07, -1.882391e-06, -3.789744e-06, -5.697101e-06], 4) - assert_array_almost_equal(fimo._score_to_pval[1][:5], [ 5.833474e-08, - -3.045972e-05, -6.097871e-05, -6.097871e-05, -9.149863e-05], 4) - assert_array_almost_equal(fimo._score_to_pval[2][:5], [5.533182e-08, - 5.160652e-08, 4.415594e-08, 3.298005e-08, 1.435360e-08], 4) - assert_array_almost_equal(fimo._score_to_pval[3][:5], [5.517863e-08, - 5.424730e-08, 5.145333e-08, 4.493405e-08, 3.003285e-08], 4) + assert hits[0]['motif_id'][0] == "MEOX1_homeodomain_1" + assert hits[0]['sequence_name'][0] == 'chr7' + assert hits[0]['start'][0] == 1350 + assert hits[0]['stop'][0] == 1360 + assert hits[0]['strand'][0] == '+' + assert round(hits[0]['score'][0], 4) == round(11.446572, 4) + assert round(hits[0]['p-value'][0], 4) == round(0.000075, 4) -def test_fimo_forward(fimo): - X = random_one_hot((5, 4, 30), random_state=0).type(torch.float32) - y_hat = predict(fimo, X, device='cpu') + assert hits[9]['motif_id'][0] == "FOXQ1_MOUSE.H11MO.0.C" + assert hits[9]['sequence_name'][0] == 'chr5' + assert hits[9]['start'][0] == 121 + assert hits[9]['stop'][0] == 133 + assert hits[9]['strand'][0] == '+' + assert round(hits[9]['score'][0], 4) == round(3.17477, 4) + assert round(hits[9]['p-value'][0], 4) == round(0.000099, 4) - assert y_hat.shape == (5, 12, 2, 11) - assert y_hat.dtype == torch.float32 - assert_array_almost_equal(y_hat[:2, :2, :, :5], [ - [[[-13.5308, -23.0580, -20.2292, -28.6583, -19.3354], - [-27.0516, -10.3653, -18.6258, -20.7399, -24.2299]], +def test_fimo_bin_size(): + hits = fimo("tests/data/test.meme", "tests/data/test.fa", bin_size=1) - [[-22.6512, -34.5771, -44.5998, -15.7849, -25.4221], - [-19.6063, -43.5123, -16.0468, -30.2433, -24.7719]]], + assert len(hits) == 12 + for df in hits: + assert isinstance(df, pandas.DataFrame) + assert df.shape[1] == 8 + assert tuple(df.columns) == ('motif_id', 'motif_alt_id', 'sequence_name', + 'start', 'stop', 'strand', 'score', 'p-value') + assert hits[0].shape == (0, 8) + assert hits[9].shape == (1, 8) - [[[-20.7360, -38.8207, -5.8913, -20.0417, -30.2949], - [-23.1269, -19.9556, -11.8838, -20.5346, -15.5351]], - [[-25.6979, -22.5750, -39.6650, -20.1621, -20.5930], - [-22.2861, -32.6734, 0.8325, -17.1021, -20.2180]]]], 4) + assert hits[9]['motif_id'][0] == "FOXQ1_MOUSE.H11MO.0.C" + assert hits[9]['sequence_name'][0] == 'chr5' + assert hits[9]['start'][0] == 121 + assert hits[9]['stop'][0] == 133 + assert hits[9]['strand'][0] == '+' + assert round(hits[9]['score'][0], 4) == round(3.17477, 4) + assert round(hits[9]['p-value'][0], 4) == round(0.000099, 4) -def test_fimo_hits(fimo): - X = random_one_hot((18, 4, 50), random_state=0).type(torch.float32) +def test_fimo_threshold(): + hits = fimo("tests/data/test.meme", "tests/data/test.fa", threshold=0.001) - hits = fimo.hits(X, device='cpu', dim=1) - assert len(hits) == 18 + assert len(hits) == 12 for df in hits: assert isinstance(df, pandas.DataFrame) - assert df.shape[1] == 7 - assert tuple(df.columns) == ('motif', 'start', 'end', 'strand', - 'score', 'p-value', 'seq') + assert df.shape[1] == 8 + assert tuple(df.columns) == ('motif_id', 'motif_alt_id', 'sequence_name', + 'start', 'stop', 'strand', 'score', 'p-value') + + assert hits[0].shape == (13, 8) + assert hits[9].shape == (157, 8) + + assert_array_equal(hits[0]['sequence_name'].values, ['chr1', 'chr2', + 'chr7', 'chr7', 'chr7', 'chr7', 'chr7', 'chr7', 'chr7', 'chr7', 'chr7', + 'chr7', 'chr7']) + assert_array_equal(hits[0]['start'].values, [ 190, 183, 667, 1096, 1106, + 1161, 1350, 1384, 393, 1096, 1106, 1161, 1350]) + assert_array_equal(hits[0]['stop'].values, [ 200, 193, 677, 1106, 1116, + 1171, 1360, 1394, 403, 1106, 1116, 1171, 1360]) + assert_array_equal(hits[0]['strand'].values, ['+', '+', '+', '+', '+', '+', + '+', '+', '-', '-', '-', '-', '-']) + assert_array_almost_equal(hits[0]['score'].values, [ 7.83938732, 7.40117477, + 7.40117477, 10.07583028, 10.07583028, 10.07583028, 11.4465722, + 9.66039708, 8.30576608, 7.42200964, 7.42200964, 7.42200964, + 7.54405698], 4) + assert_array_almost_equal(hits[0]['p-value'].values, [7.60078430e-04, + 9.22203064e-04, 9.22203064e-04, 1.89781189e-04, 1.89781189e-04, + 1.89781189e-04, 7.53402710e-05, 2.45094299e-04, 5.88417053e-04, + 9.22203064e-04, 9.22203064e-04, 9.22203064e-04, 8.81195068e-04], 4) + + +def test_fimo_rc(): + hits = fimo("tests/data/test.meme", "tests/data/test.fa", + reverse_complement=False) + + assert len(hits[3]) == 1 + assert len(hits[7]) == 1 + assert len(hits[10]) == 1 + + +### + + +def test_fimo_tensor(): + X = random_one_hot((18, 4, 50), random_state=0).type(torch.float32) + hits = fimo("tests/data/test.meme", X) - hits = fimo.hits(X, device='cpu', dim=0) assert len(hits) == 12 for df in hits: assert isinstance(df, pandas.DataFrame) - assert df.shape[1] == 7 - assert tuple(df.columns) == ('example_idx', 'start', 'end', 'strand', - 'score', 'p-value', 'seq') + assert df.shape[1] == 8 + assert tuple(df.columns) == ('motif_id', 'motif_alt_id', 'sequence_name', + 'start', 'stop', 'strand', 'score', 'p-value') - -def test_fimo_hits_ap1_axis0(fimo): X = random_one_hot((1, 4, 50), random_state=0).type(torch.float32) X = substitute(X, "TGACGTCAT") - hits = fimo.hits(X, device='cpu') + hits = fimo("tests/data/test.meme", X) assert len(hits) == 12 assert_array_almost_equal(list(map(len, hits)), [0, 0, 0, 2, 0, 0, 0, 0, 0, @@ -237,75 +266,14 @@ def test_fimo_hits_ap1_axis0(fimo): for df in hits: assert isinstance(df, pandas.DataFrame) - assert df.shape[1] == 7 - assert tuple(df.columns) == ('example_idx', 'start', 'end', 'strand', - 'score', 'p-value', 'seq') + assert df.shape[1] == 8 + assert tuple(df.columns) == ('motif_id', 'motif_alt_id', 'sequence_name', + 'start', 'stop', 'strand', 'score', 'p-value') df = hits[3] - assert tuple(df['example_idx']) == tuple([0, 0]) + assert tuple(df['sequence_name']) == tuple([0, 0]) assert tuple(df['start']) == tuple([18, 17]) - assert tuple(df['end']) == tuple([33, 32]) + assert tuple(df['stop']) == tuple([33, 32]) assert tuple(df['strand']) == tuple(['+', '-']) assert_array_almost_equal(df['score'], [16.0935, 15.5552], 4) assert_array_almost_equal(df['p-value'], [2.251e-06, 3.411e-06], 4) - assert tuple(df['seq']) == tuple(['GCGTGACGTCATCAT', 'AGCGTGACGTCATCA']) - - -def test_fimo_hits_ap1_axis1(fimo): - X = random_one_hot((1, 4, 50), random_state=0).type(torch.float32) - X = substitute(X, "TGACGTCAT") - - hits = fimo.hits(X, device='cpu', dim=1) - - assert len(hits) == 1 - assert_array_almost_equal(list(map(len, hits)), [2]) - - df = hits[0] - assert isinstance(df, pandas.DataFrame) - assert df.shape[1] == 7 - assert tuple(df.columns) == ('motif', 'start', 'end', 'strand', - 'score', 'p-value', 'seq') - - assert tuple(df['motif']) == tuple(['FOSL2+JUND_MA1145.1', - 'FOSL2+JUND_MA1145.1']) - assert tuple(df['start']) == tuple([18, 17]) - assert tuple(df['end']) == tuple([33, 32]) - assert tuple(df['strand']) == tuple(['+', '-']) - assert_array_almost_equal(df['score'], [16.0935, 15.5552], 4) - assert_array_almost_equal(df['p-value'], [2.2510e-06, 3.4114e-06], 4) - assert tuple(df['seq']) == tuple(['GCGTGACGTCATCAT', 'AGCGTGACGTCATCA']) - - -def test_fimo_hit_matrix(fimo): - X = random_one_hot((8, 4, 50), random_state=0).type(torch.float32) - X = substitute(X, "TGACGTCAT") - - hits = fimo.hit_matrix(X, device='cpu') - - assert hits.shape == (8, 12) - assert hits.dtype == torch.float32 - assert_array_almost_equal(hits, [ - [ 5.5792e+00, 4.2629e-01, -1.3749e+00, 1.6094e+01, -6.5121e+00, - -2.0851e+00, -9.2959e+00, -7.4332e+00, -2.5657e+00, -2.5400e+01, - -6.5174e+00, 6.3290e+00], - [-3.0198e-01, 3.8548e+00, 5.6321e+00, 1.2371e+01, -5.1043e+00, - -3.6458e-01, -1.2893e+01, 2.1829e+00, -1.6118e+00, -1.3580e+01, - -1.2783e+01, 4.5077e+00], - [-2.0197e+00, 8.4375e+00, -1.2127e-01, 1.4284e+01, 3.4388e+00, - -8.7771e+00, -3.1086e+00, 2.2791e-02, 2.9074e-01, -2.3285e+01, - -4.4699e+00, 1.1758e+00], - [ 9.3114e+00, 6.3890e+00, -1.1486e+00, 1.3424e+01, -1.1651e+01, - -5.5341e+00, -1.2394e+01, -1.4051e+01, -4.8145e+00, -2.4022e+01, - 2.2819e+00, 2.1922e+00], - [ 4.4532e+00, -5.3541e+00, 2.2351e+00, 1.6020e+01, -7.5375e-01, - -5.9520e+00, -1.5792e+01, -5.7051e+00, 1.7323e+00, -2.7297e+00, - -9.6288e+00, 4.7946e+00], - [ 4.3071e+00, -5.2839e+00, 2.2718e+00, 1.3015e+01, -8.1554e+00, - -5.4550e+00, 1.4410e+00, -2.5368e+00, -4.5676e+00, -2.8154e+01, - -8.8911e+00, 1.1646e+00], - [ 1.3561e+00, -2.0182e-01, 3.1246e+00, 1.2345e+01, -5.2504e+00, - 3.4990e+00, -2.0052e+01, -7.9282e+00, -7.4422e+00, -3.2059e+01, - -1.0036e+01, 1.9807e+00], - [ 6.0968e+00, -6.5309e+00, -5.8497e-01, 1.3620e+01, -7.4371e+00, - -2.0684e+00, -1.5606e+01, -1.3648e+01, 4.9869e+00, -1.1849e+01, - 2.9037e+00, 4.3577e+00]], 3) diff --git a/tests/tools/test_tomtom.py b/tests/tools/test_tomtom.py index 03e2116..895c38e 100644 --- a/tests/tools/test_tomtom.py +++ b/tests/tools/test_tomtom.py @@ -122,7 +122,7 @@ def test_pairwise_max_fallback(): def test_merge_rc_results(): - results = numpy.random.RandomState(0).randn(1000, 4) + results = numpy.random.RandomState(0).randn(1000, 5) idxs = results[:500, 1] > results[500:, 1] best_p = 1 - (1 - numpy.minimum(results[:500, 0], results[500:, 0])) ** 2 @@ -132,11 +132,11 @@ def test_merge_rc_results(): _merge_rc_results(results) - assert_array_almost_equal(results[:500, 0], best_p) - assert_array_almost_equal(results[:500, 1], best_scores) - assert_array_almost_equal(results[:500, 2], best_offsets) - assert_array_almost_equal(results[:500, 3], best_overlaps) - assert_array_almost_equal(results[:500, 4], idxs) + assert_array_almost_equal(results[:500, 0], best_p, 4) + assert_array_almost_equal(results[:500, 1], best_scores, 4) + assert_array_almost_equal(results[:500, 2], best_offsets, 4) + assert_array_almost_equal(results[:500, 3], best_overlaps, 4) + assert_array_almost_equal((1 - results[:500, 4]).astype(bool), idxs) ### @@ -177,8 +177,8 @@ def test_tomtom(): 1., 11., -6., -7., -7., 5., -4., -6., 2., 3., 1., -7., -8.]) assert_array_almost_equal(overlaps[0], [16., 7., 4., 4., 6., 7., 5., 16., 3., 4., 7., 5., 4., 12., 10., 8., 5., 16., 6., 4.]) - assert_array_almost_equal(strands[0], []) - + assert_array_almost_equal(strands[0], [0., 0., 0., 0., 0., 0., 0., 1., 0., + 0., 0., 0., 1., 0., 1., 0., 1., 0., 1., 1]) def test_tomtom_subsets(): @@ -239,7 +239,8 @@ def test_tomtom_meme(): 2.0, 1.0, -2.0, 7.0, 0.0], 6) assert_array_almost_equal(overlaps[0], [10.0, 9.0, 10.0, 8.0, 8.0, 10.0, 8.0, 8.0, 10.0, 8.0, 10.0, 10.0], 6) - assert_array_almost_equal(strands[0], []) + assert_array_almost_equal(strands[0], [0., 1., 0., 1., 0., 1., 0., 0., 0., + 1., 1., 0.]) def test_tomtom_reverse_complement(): @@ -262,7 +263,7 @@ def test_tomtom_reverse_complement(): 2., 1., 1., 7., 0.], 6) assert_array_almost_equal(overlaps[0], [10., 9., 10., 9., 8., 10., 8., 8., 10., 10., 10., 10.], 6) - assert_array_almost_equal(strands[0], []) + assert_array_almost_equal(strands[0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) def test_tomtom_n_jobs(): @@ -318,5 +319,6 @@ def test_tomtom_n_target_bins_small(): 2., 1., -2., 7., 0.], 6) assert_array_almost_equal(overlaps[0], [10., 9., 10., 9., 8., 10., 8., 8., 10., 8., 10., 10.], 6) - assert_array_almost_equal(strands[0], []) + assert_array_almost_equal(strands[0], [0., 1., 0., 0., 1., 1., 0., 0., 0., + 1., 1., 0.]) \ No newline at end of file