{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# smol, mash and CMash comparison\n", "\n", "(the smol gather experiment)\n", "\n", "This experiment compares smol scaled minhash sketches, CMash and mash screen for containment queries.\n", "Experiments were run for ksizes of `21, 31, 51` (except for mash, which only supports `k<=32`).\n", "For mash there is also data for both `num=1000` and `num=100000`.\n", "You can change the numbers below and rerun the notebook to compare results.\n", "\n", "There is also an exact version to use as baseline/truth set. It is implemented in Rust, using the `HashSet` in the standard library." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "ksize = 31\n", "num = 1000\n", "scaled = 1000" ] }, { "cell_type": "code", "execution_count": 349, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "%config InlineBackend.close_figures = False\n", "\n", "import numpy as np\n", "import pandas as pd\n", "from IPython.display import Image\n", "import hvplot.pandas\n", "import matplotlib.pyplot as plt\n", "import seaborn as sns\n", "from ficus import FigureManager\n", "\n", "pd.options.plotting.backend = \"hvplot\"\n", "\n", "sns.set()\n", "sns.set_palette(\"tab10\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading data\n", "\n", "Loading four dataframes, one for each method plus the exact counts. Harmonize filenames so we can merge the dataframes further down in the analysis." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### smol\n", "\n", "`smol` is a minimal implementation of Scaled MinHash and Gather for demonstration purposes. It doesn't include any of the conveniences for working with real biological data like sourmash does, but it's nice for explaining the basic ideas (and both Python and Rust versions are under 250 lines of code, and can interchange sketches since it's a JSON file)." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "smol = pd.read_table(\n", " f\"../outputs/smol_{scaled}/search-SRR606249-k{ksize}.csv\",\n", " sep=\",\",\n", " header=None,\n", " names=(\"filename\", \"smol_c\"),\n", " usecols=(\"filename\", \"smol_c\"),\n", ")\n", "smol[\"filename\"] = smol[\"filename\"].str.replace(\n", " r\".*/(?P\\d+).fa.*\", lambda m: m.group(\"id\") + \".fa\"\n", ")\n", "smol.set_index(\"filename\", inplace=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### CMash\n", "\n", "#### CMash for published manuscript" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "cmash_paper = pd.read_table(\n", " f\"../outputs/cmash_paper/SRR606249-k{ksize}-n{num}.csv\",\n", " sep=\",\",\n", " header=0,\n", " names=(\"filename\", \"intersection\", \"cmash paper\", \"jaccard index\"),\n", " usecols=(\"filename\", \"cmash paper\"),\n", ")\n", "cmash_paper.columns = [\"filename\"] + [c for c in cmash_paper.columns[1:]]\n", "cmash_paper[\"filename\"] = cmash_paper[\"filename\"].str.replace(\n", " r\".*/(?P\\d+).fa.*\", lambda m: m.group(\"id\") + \".fa\"\n", ")\n", "cmash_paper.set_index(\"filename\", inplace=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### mash\n", "\n", "`mash screen` outputs the `mash containment` in the first column, and a hashes proportion in the second `(matched hashes / sketch size)`.\n", "I'll be using the proportion, and also harmonizing filename to be able to join dataframes later.\n", "\n", "Since `mash sketch` has a cutoff parameter `-m` that can be used to discard k-mers below the cutoff during sketch construction, I tried using `-m 1` and `-m 3` (which is also used in the mash screen paper for the SRA metagenomes comparison) to see if there are differences:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "if ksize <= 32: # mash doesn't support k>32\n", " mash_mn = pd.read_table(\n", " f\"../outputs/mash_screen/SRR606249-k{ksize}-s{num}-m3.tsv\",\n", " header=None,\n", " names=(\n", " \"identity\",\n", " \"hashes\",\n", " \"median abundance\",\n", " \"p-value\",\n", " \"filename\",\n", " \"description\",\n", " ),\n", " usecols=[\"filename\", \"hashes\"],\n", " )\n", " mash_mn[\"filename\"] = mash_mn[\"filename\"].str.replace(\".*/\", \"\")\n", " mash_mn[\"mash_m3\"] = mash_mn[\"hashes\"].apply(lambda x: eval(x))\n", " del mash_mn[\"hashes\"]\n", " mash_mn.set_index(\"filename\", inplace=True)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "if ksize <= 32: # mash doesn't support k>32\n", " mash_m1 = pd.read_table(\n", " f\"../outputs/mash_screen/SRR606249-k{ksize}-s{num}-m1.tsv\",\n", " header=None,\n", " names=(\n", " \"identity\",\n", " \"hashes\",\n", " \"median abundance\",\n", " \"p-value\",\n", " \"filename\",\n", " \"description\",\n", " ),\n", " usecols=[\"filename\", \"hashes\"],\n", " )\n", " mash_m1[\"filename\"] = mash_m1[\"filename\"].str.replace(\".*/\", \"\")\n", " mash_m1[\"mash_m1\"] = mash_m1[\"hashes\"].apply(lambda x: eval(x))\n", " del mash_m1[\"hashes\"]\n", " mash_m1.set_index(\"filename\", inplace=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If we plot a histogram of the differences we see that the results mostly agree, but in a few cases it is quite far (which makes sense, for low coverage genomes `-m 3` is pretty strict).\n", "Using `-m 1` from now on (which also matches the default sourmash and CMash behavior)." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": {}, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "
\n", "
\n", "" ], "text/plain": [ ":Histogram [0] (0_count)" ] }, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1001" } }, "output_type": "display_data" } ], "source": [ "if ksize <= 32: # mash doesn't support k>32\n", " with pd.option_context(\"display.max_rows\", None):\n", " display(\n", " (mash_m1[\"mash_m1\"] - mash_mn[\"mash_m3\"]).abs().sort_values().hvplot.hist()\n", " )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exact\n", "\n", "The exact code uses the Rust `HashSet` from the standard library to keep all k-mers in the query metagenome, as well as each of the reference genomes, storing it on disk for later comparisons. It uses [needletail]() for FASTA/Q parsing, keep the canonical k-mer (smaller between k-mer and reverse complement), and its sequence normalization method (described in the [docs](https://docs.rs/needletail/0.3.2/needletail/sequence/fn.normalize.html), copied here for easier reference):\n", "```\n", "Transform a nucleic acid sequence into its \"normalized\" form.\n", "\n", "The normalized form is:\n", "\n", " only AGCTN and possibly - (for gaps)\n", " strip out any whitespace or line endings\n", " lowercase versions of these are uppercased\n", " U is converted to T (make everything a DNA sequence)\n", " some other punctuation is converted to gaps\n", " IUPAC bases may be converted to N's depending on the parameter passed in\n", " everything else is considered a N\n", "```\n", "\n", "All tools agree with this normalization process:\n", "\n", "- sourmash and smol: converts all bases to uppercase, skips k-mers with N (or any non-ACGT bases), keep canonical\n", "- cmash: same as sourmash\n", " * ref https://github.com/dkoslicki/CMash/blob/db7da08cd897edabfccbbe7bd252572799737c5e/CMash/MinHash.py#L166\n", "- mash: uppercase (unless `-Z` is set), skip bad k-mers (not in alphabet), keep canonical (unless `-n` is set)\n", " * ref https://github.com/marbl/Mash/blob/a1afacd0ef3f503ba0133a1b8bb57b79b795dfe7/src/mash/Sketch.cpp#L509\n", " \n", "(another discussion about sequence cleanup in `khmer`: https://github.com/dib-lab/khmer/pull/1590)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "exact = pd.read_table(\n", " f\"../outputs/exact/SRR606249-k{ksize}.csv\",\n", " sep=\",\",\n", " header=None,\n", " names=(\"filename\", \"exact\", \"intersection\", \"|A|\"),\n", " usecols=(\"filename\", \"exact\"),\n", ")\n", "exact[\"filename\"] = exact[\"filename\"].str.replace(\n", " r\".*/(?P\\d+)-k\\d+.set\", lambda m: m.group(\"id\") + \".fa\"\n", ")\n", "exact.set_index(\"filename\", inplace=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### sourmash\n", "\n", "`sourmash_c` uses `sourmash search --containment` to report containment (above a threshold) for every dataset in a collection." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "sourmash_c = pd.read_table(\n", " f\"../outputs/scaled_{scaled}/containments_SRR606249-k{ksize}.csv\",\n", " sep=\",\",\n", " usecols=[\"containment\", \"filename\"],\n", ")\n", "sourmash_c.columns = (\"sourmash_c\", \"filename\")\n", "sourmash_c.set_index(\"filename\", inplace=True)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "sourmash_g = pd.read_table(\n", " f\"../outputs/scaled_{scaled}/SRR606249-k{ksize}.csv\",\n", " sep=\",\",\n", " usecols=[\"filename\", \"f_match_orig\"],\n", ")\n", "sourmash_g.columns = (\"filename\", \"sourmash_g\")\n", "sourmash_g[\"filename\"] = sourmash_g[\"filename\"].str.replace(\n", " r\".*/(?P\\d+).sig\", lambda m: m.group(\"id\") + \".fa\"\n", ")\n", "sourmash_g.set_index(\"filename\", inplace=True)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Series([], dtype: float64)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sourmash_diff = np.abs(sourmash_c[\"sourmash_c\"] - sourmash_g[\"sourmash_g\"])\n", "sourmash_diff[sourmash_diff > 0.01].sort_values()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "#sourmash_c = sourmash_g" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Containment checks\n", "\n", "Merging the three dataframes, and since the `containment` for each method is in a column with the method name, it is easy to get the proper labels for plotting later." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "# all_methods = pd.concat((exact, smol, cmash, cmash_all, cmash_paper, mash_m1, mash_mn, sourmash_c, sourmash_g), axis=1)\n", "if ksize > 31: # mash doesn't support k>32\n", " #all_methods = pd.concat((exact, smol, cmash_paper, sourmash_c), axis=1)\n", " all_methods = pd.concat((exact, smol, cmash_paper), axis=1)\n", "else:\n", " #all_methods = pd.concat((exact, smol, cmash_paper, mash_m1, sourmash_c), axis=1,)\n", " all_methods = pd.concat((exact, smol, cmash_paper, mash_m1), axis=1,) " ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": {}, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "
\n", "
\n", "" ], "text/plain": [ ":NdOverlay [Variable]\n", " :Curve [index] (value)" ] }, "execution_count": 14, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1106" } }, "output_type": "execute_result" } ], "source": [ "all_methods.sort_values(by=\"exact\").hvplot(height=400, width=1000, xaxis=\"top\", rot=45)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "mash containment is always above .95, but it is hard to visualize what is happening in this graph. Let's try to use a table, and filter out results where they agree (where \"agree\" is at most an 1% difference in containment):" ] }, { "cell_type": "code", "execution_count": 15, "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", "
exact smol_c cmash paper mash_m1
20.fa0.1302740.1245930.1180000.115000
66.fa0.1299100.1258500.1070000.111000
67.fa0.1255110.1362550.1290000.143000
55.fa0.7428090.7436730.7140000.761000
17.fa0.7642050.7692950.7370000.781000
7.fa0.9060820.9059750.8960000.908000
58.fa0.9413580.9410680.9290000.946000
63.fa0.9491380.9492170.9360000.948000
16.fa0.9684150.9612670.9600000.957000
46.fa0.9772150.9768720.9620000.972000
47.fa0.9740650.9774000.9640000.979000
23.fa0.9865630.9853160.9760000.983000
41.fa0.9963670.9956640.9860000.996000
9.fa0.9985790.9978450.9880001.000000
3.fa0.9985860.9981330.9880000.999000
50.fa0.9993770.9990950.9880001.000000
38.fa0.9973620.9991110.9870000.999000
26.fa0.9982900.9992210.9880000.999000
25.fa0.9989330.9993740.9870000.999000
42.fa0.9995120.9994280.9890001.000000
48.fa1.0000001.0000000.9900001.000000
10.fa0.9991701.0000000.9880001.000000
11.fa0.9997491.0000000.9890001.000000
60.fa0.9995871.0000000.9890001.000000
14.fa0.9995091.0000000.9890001.000000
54.fa1.0000001.0000000.9900001.000000
29.fa1.0000001.0000000.9900001.000000
56.fa0.9997051.0000000.9890001.000000
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def highlight_diff_from_exact(s):\n", " diff = np.abs(s - s[\"exact\"])\n", " colorized = []\n", " for v in diff:\n", " if v < 0.001:\n", " colorized.append(\"background-color: white\")\n", " elif v < 0.01:\n", " colorized.append(\"background-color: yellow\")\n", " elif v < 0.05:\n", " colorized.append(\"background-color: orange\")\n", " else:\n", " colorized.append(\"background-color: red\")\n", " return colorized\n", "\n", "\n", "with pd.option_context(\"display.max_rows\", None, \"show_dimensions\", True):\n", " df = all_methods.sort_values(by=\"smol_c\")\n", " df = df[df.apply(lambda x: any(np.abs(x - x[\"exact\"]) > 0.01), axis=1)]\n", " display(df.style.apply(highlight_diff_from_exact, axis=1))" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": {}, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "
\n", "
\n", "" ], "text/plain": [ ":BoxWhisker [Variable] (value)" ] }, "execution_count": 16, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1426" } }, "output_type": "execute_result" } ], "source": [ "all_methods.apply(lambda s: s - s[\"exact\"], axis=1).hvplot.box(height=600)" ] }, { "cell_type": "code", "execution_count": 17, "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", "
exactsmol_ccmash papermash_m1
0.fa0.9999720.9997600.9901.000
1.fa0.9996260.9986470.9900.999
2.fa0.9998001.0000000.9901.000
3.fa0.9985860.9981330.9880.999
4.fa0.9980830.9974460.9890.997
...............
63.fa0.9491380.9492170.9360.948
64.fa0.0188830.0178070.0240.019
65.fa0.0098270.0084660.0130.006
66.fa0.1299100.1258500.1070.111
67.fa0.1255110.1362550.1290.143
\n", "

68 rows × 4 columns

\n", "
" ], "text/plain": [ " exact smol_c cmash paper mash_m1\n", "0.fa 0.999972 0.999760 0.990 1.000\n", "1.fa 0.999626 0.998647 0.990 0.999\n", "2.fa 0.999800 1.000000 0.990 1.000\n", "3.fa 0.998586 0.998133 0.988 0.999\n", "4.fa 0.998083 0.997446 0.989 0.997\n", "... ... ... ... ...\n", "63.fa 0.949138 0.949217 0.936 0.948\n", "64.fa 0.018883 0.017807 0.024 0.019\n", "65.fa 0.009827 0.008466 0.013 0.006\n", "66.fa 0.129910 0.125850 0.107 0.111\n", "67.fa 0.125511 0.136255 0.129 0.143\n", "\n", "[68 rows x 4 columns]" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "all_methods" ] }, { "cell_type": "code", "execution_count": 18, "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", "
exact smol_c cmash paper mash_m1
66.fa0.1299100.1258500.1070000.111000
47.fa0.9740650.9774000.9640000.979000
41.fa0.9963670.9956640.9860000.996000
9.fa0.9985790.9978450.9880001.000000
3.fa0.9985860.9981330.9880000.999000
50.fa0.9993770.9990950.9880001.000000
38.fa0.9973620.9991110.9870000.999000
26.fa0.9982900.9992210.9880000.999000
25.fa0.9989330.9993740.9870000.999000
42.fa0.9995120.9994280.9890001.000000
48.fa1.0000001.0000000.9900001.000000
10.fa0.9991701.0000000.9880001.000000
11.fa0.9997491.0000000.9890001.000000
60.fa0.9995871.0000000.9890001.000000
14.fa0.9995091.0000000.9890001.000000
54.fa1.0000001.0000000.9900001.000000
29.fa1.0000001.0000000.9900001.000000
56.fa0.9997051.0000000.9890001.000000
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# low coverage genomes\n", "low_coverage = (\n", " # From Awad 2018\n", " 27, # Leptothrix cholodnii\n", " 23, # Haloferax volcanii DS2\n", " 46, # Salinispora tropica\n", " 16, # Deinococcus radiodurans\n", " 58, # Zymomonas mobilis\n", " 44, # Ruegeria pomeroyi\n", " 63, # Shewanella baltica OS223\n", " 6, # B. bronchiseptica D989\n", " 7, # Burkholderia xenovorans\n", " 17, # Desulfovibrio vulgaris DP4\n", " 55, # Thermus thermophilus HB27\n", " 19, # Enterococcus faecalis\n", " 20, # Fusobacterium nucleatum ATCC 25586\n", " # From mash screen paper\n", " 67, # Streptococcus parasanguinis strain C1A\n", ")\n", "\n", "with pd.option_context(\"display.max_rows\", None, \"show_dimensions\", True):\n", " df = all_methods.sort_values(by=\"smol_c\").drop([f\"{i}.fa\" for i in low_coverage])\n", " df = df[df.apply(lambda x: any(np.abs(x - x[\"exact\"]) > 0.01), axis=1)]\n", " display(df.style.apply(highlight_diff_from_exact, axis=1))" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": {}, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "
\n", "
\n", "" ], "text/plain": [ ":BoxWhisker [Variable] (value)" ] }, "execution_count": 19, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1666" } }, "output_type": "execute_result" } ], "source": [ "df.apply(lambda s: s - s[\"exact\"], axis=1).hvplot.box(height=600)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Similarity and Containment matrices" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABEwAAAMgCAYAAAA5kPcVAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAPYQAAD2EBqD+naQAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nOzde5CV9Z0m8Occu2kBFScEQVuMVzSC2bV03FVEVide4gBxVhOiltlk43qbiuV4ycWxEAVjKeOlsioTJorLxtn1MqMxrsbgDRTM6jowjjrleE0bo6BOjd3KpQF7/yB25FWbbjjt2+fw+aTeyjlvH16+bdXbdXj6d35PpaurqysAAAAAdKuWPQAAAADAQCMwAQAAACgQmAAAAAAUCEwAAAAACgQmAAAAAAUCEwAAAIACgQkAAABAgcAEAAAAoEBgAgAAAFAgMAEAAAAoEJgAAAAAFAhMAAAAAAoEJgAAAAAFAhMAAACAAoEJAAAAQIHABAAAAKBAYAIAAABQIDABAAAAKBCYAAAAABQITAAAAAAKBCYAAAAABQITAAAAgAKBCQAAAECBwAQAAACgQGACAAAAUCAwAQAAACgQmAAAAAAUCEwAAAAACgQmAAAAAAUCEwAAAIACgQkAAABAgcAEAAAAoEBgAgAAAFAgMAEAAAAoEJgAAAAAFAhMAAAAAAoEJgAAAAAFAhMAAACAAoEJAAAAQIHABAAAAKBAYAIAAABQIDABAAAAKBCYAAAAABQITAAAAAAKBCYAAAAABQITAAAAgAKBCQAAAECBwAQAAACgQGACAAAAUCAwAQAAACgQmAAAAAAUCEwAAAAACgQmAAAAAAUCEwAAAIACgQkAAABAgcAEAAAAoEBgAgAAAFAgMAEAAAAoEJgAAAAAFAhMAAAAAAoEJgAAAAAFAhMAAACAAoEJAAAAQIHABAAAAKBAYAIAAABQIDABAAAAKBCYAAAAABQITAAAAAAKBCYAAAAABQITAAAAgAKBCQAAAECBwAQAAACgQGACAAAAUCAwAQAAACgQmAAAAAAUCEwAAAAACgQmAAAAAAUCEwAAAIACgQkAAABAgcAEAAAAoEBgAgAAAFAgMAEAAAAoEJgAAAAAFAhMAAAAAAoEJgAAAAAFAhMAAACAAoEJAAAAQIHABAAAAKBAYAIAAABQIDABAAAAKBCYAAAAABQITAAAAAAKBCYAAAAABQITAAAAgAKBCQAAAECBwAQAAACgQGACAAAAUCAwAQAAACgQmAAAAAAUCEwAAAAACgQmAAAAAAUCEwAAAIACgQkAAABAgcAEAAAAoEBgAgAAAFAgMAEAAAAoEJgAAAAAFAhMAAAAAAoEJgAAAAAFAhMAAACAAoEJAAAAQIHABAAAAKBAYAIAAABQIDABAAAAKBCYAAAAABQITAAAAAAKBCYAAAAABQITAAAAgAKBCQAAAECBwAQAAACgQGACAAAAUCAwAQAAACgQmAAAAAAUCEwAAAAACgQmAAAAAAUCEwAAAIACgQkAAABAgcAEAAAAoEBgAgAAAFAgMAEAAAAoEJgAAAAAFAhMAAAAAAoEJgAAAAAFAhMAAACAAoEJAAAAQIHABAAAAKBAYAIAAABQIDABAAAAKBCYAAAAABQITAAAAAAKBCYAAAAABQITAAAAgAKBCQAAAECBwAQAAACgQGACAAAAUCAwAQAAACgQmAAAAAAUCEwAAAAACgQmAAAAAAUCEwAAAIACgQkAAABAgcAEAAAAoEBgAgAAAFAgMAEAAAAoEJgAAAAAFAhMAAAAAAoEJgAAAAAFAhMAAACAAoEJAAAAQIHABAAAAKBAYAIAAABQIDABAAAAKBCYAAAAABQITAAAAAAKBCYAAAAABQITAAAAgAKBCQAAAECBwAQAAACgQGACAAAAUCAwAQAAACgQmAAAAAAUCEwAAAAACgQmAAAAAAUCEwAAAIACgQkAAABAgcAEAAAAoEBgAgAAAFAgMAEAAAAoEJgAAAAAFAhMAAAAAAoEJgAAAAAFAhMAAACAAoEJAAAAQIHABAAAAKBAYAIAAABQIDABAAAAKBCYAAAAABQITAAAAAAKBCYAAAAABQITAAAAgAKBCQAAAECBwAQAAACgQGACAAAAUCAwAQAAACgQmAAAAAAUCEwAAAAACgQmAAAAAAUCEwAAAIACgQkAAABAgcAEAAAAoEBgAgAAAFAgMAEAAAAoEJgAAAAAFAhMAAAAAAoEJgAAAAAFAhMAAACAAoEJAAAAQIHABAAAAKBAYAIAAABQIDABAAAAKBCYAAAAABQITAAAAAAKBCYAAAAABQITAAAAgAKBCQAAAECBwAQAAACgQGACAAAAUCAwAQAAACgQmAAAAAAUCEwAAAAACgQmAAAAAAUCEwAAAIACgQkAAABAgcAEAAAAoEBgAgAAAFAgMAEAAAAoEJgAAAAAFAhMAAAAAAoEJgAAAAAFAhMAAACAAoEJAAAAQIHABAAAAKBAYAIAAABQIDABAAAAKBCYAAAAABQITAAAAOrcwoULM3ny5Oy0006pVCq56667NvpnFixYkAMOOCBbb711dt999/z1X//1ZzAp1A+BCQAAQJ17//338+/+3b/Ldddd16vXv/LKKzn22GMzYcKELFmyJBdeeGHOPvvs/N3f/V0/Twr1o9LV1dVV9hAAAADURqVSyZ133pnjjjvuU1/z/e9/P3fffXf++Z//ufvcGWeckX/8x3/M448//lmMCQNeU9kDsN4HH3yQ3/3ud9l2221TqVTKHgcaWldXVzo6OrLTTjulWu3/hXbubwCoL319r7Bq1ap0dnb2yxzF9w4tLS1paWnZ7Gs//vjjOeqoozY4d/TRR+fGG2/MmjVr0tzcvNl/B9Q7gckA8bvf/S6jR48uewzYorz22mvZeeede3zNU089lXPOOSfVajUjR47MLbfc0uc3EO5vAKhPvXmvsGrVqgwe+kfJB6tq/vdvs802ee+99zY4d/HFF2f69Ombfe0333wzI0eO3ODcyJEjs3bt2rz99tvZcccdN/vvgHonMBkgtt122yTrfyhvt912JU8Dja29vT2jR4/uvu960tramvvvvz9DhgzJhRdemLvuuitf+9rX+vT3/eH+XpDttttmk2YGAGpvh31/9Innuz5Yk8437u7Ve4XOzs7kg1Vp2XFKUq3hqowP1uS9N+7+2L8ParG65EPF1Ssf7tZgRSysJzAZID78obTddtv1KTDp6kpWrOivqaAxbbXV+v/vzZuBUaNGdT9ubm5OU1Pff2z+4f7eRmACAANIZSMBR1+Cg8pWLRu9Xl90VdZ/FKiv/z7orVGjRuXNN9/c4Nzy5cvT1NSU4cOH1/zvg3okMKljXV3JoYcmixeXPQk0vra2tjzwwAO56KKLyh4FAGCzHXzwwfnFL36xwblf/epXOfDAA+1fAr+nVriOrVghLIHPQnt7e0455ZTMnTvXGwgA4BNVUkkl1RoefftYzHvvvZelS5dm6dKlSdbXBi9dujRtbW1Jkh/+8If55je/2f36M844I7/5zW9y7rnn5p//+Z9z00035cYbb8z5559fu/8oUOesMGkQy5YlQ4eWPQXUh/b2ZKedevfadevW5eSTT860adMyZsyY/h0MAGAT/b//9/9y+OGHdz8/99xzkyT/5b/8l9x888154403usOTJNltt91y77335i/+4i9y/fXXZ6eddsqPf/zjHH/88Z/57DBQCUwaxNChAhPorXXrev/a2267LYsXL05HR0dmzJiRM888M1OnTu2/4QCAulSpVFOp1HABfx+v9Z/+03/q3rT1k9x8880fOzdx4sT8wz/8Q18ngy2GwKSOvf/+ho8FJlB7J554YiZNmpQvf/nLefbZZzN27NiyRwIAemnwLhf3+PWVbZd84vn29vcybNjf9cdIQB2xhwnARgwePDj33HNPTjjhhLJHAQAGqA9XmNTyAMplhUmDeP/9DVecAJ+ur/dKU1NTRowY0T/DAAAAA5LApEHsvnvZEwAAwJarUqmkUulbs81GLli7awGbxDqvOjZkSNkTAAAAQGOywqSOrVjxh8cvv5zssEN5s0A96UutMABA71RT299H+902lE1g0iDUCkPv9aVW+EPHHntsli5dmueffz6nn356vvWtb9V8LgAAYOAQmAD04Jlnnsnpp5+epqam7L///rn11luzzTbblD0WAPB7PVUHf1ptcH+oebONlhwonbsQoAd77713Fi1alAULFuSggw7KnXfeWfZIAMAApFYYGo8VJg1CrTD0Xl/ulebm5u7HK1asyD777NMPEwEAAAONwKRBqBWG/jN//vx873vfS3Nzc77//e+XPQ4AMABVUk3Fpq/QUNyFdUytMHw2jjzyyCxZsiQnnHBC5syZU/Y4AADAZ8AKkzqmVhg2TV9qhVevXp2WlpYkybBhw9LZ2dmPkwEA9cqmr9B4BCYNQq0w9F5faoXnz5+fWbNmpVqtZsSIEbn55pv7bS4AAGDgEJgA9GDSpEmZOHFivvzlL+fee+/Nyy+/nHHjxmWvvfZKa2trkuQv//Ivc+SRR5Y8KQA0roFSHdyTSmrdbGOFCZRNYAKwEYMHD84999yTCy64oPvcsGHD8sgjj5Q3FAAA0K8EJg1CrTD0Xl/vlaampowYMWKDc++9914mTpyY1tbWXHfddfnc5z5XwwkBgLpTqdR0hUlXpVKzawGbRmDSINQKw2dr0aJFGT58eObNm5fp06fnxz/+cdkjAQAANeSDcXWsq6vsCWDLNXz48CTJ1772tSxdurTk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++6ZOXNmdtttt0ydOrWfJgQA6k6tm2205EDpBCYAPRg+fHimTJmSww47LNVqNT/60Y8yceLEjB8/Pg899FAOPvjg7lUnAABA4xCYAGzE2LFj09zcnLVr1+att97KmjVr0tbWlr322ivXXXdd2eMB0MB6qg1OVAcPKFpyoOEITBqEWmHovc2pFf7QFVdckfHjx/fDdAAAwEAgMGkQaoWhf3xSrfDKlStTqVSyyy67lD0eADBQ1LrZRksOlE5gUseGDCl7Amh8H9YKL1q0KA8++GB3rfAPfvCD7scAAEDjEZjUsY9unL1smZYc6K3NqRU+7bTT8qd/+qfZdddd+3VGAKDO2MMEGo7ApI4V92EQmEDvbE6t8Lvvvptnn302xxxzTP7pn/4pL774Yh5++OE0Nzf307QAQD3oSiVdNawC7pKYQOkEJgA9KNYKL126NLv/ftOgb33rWzn//POFJQAA0IAEJgA9eOqpp/K///f/TrVazQ477JDRo0fn29/+du65555cfPHFGTduXNkjAlDneqoOVhtcRwbApq833HBDZs2alTfeeCNjx47NtddemwkTJnzq62+55ZZceeWVeeGFFzJs2LAcc8wx+au/+qsMHz58cyaHhiEwaRBqhaH3+nKvtLa25v7778+QIUNy4YUX5q677sqPfvSjTJw4Me+9917/DQkA0Ae33nprzjnnnNxwww0ZP358fvKTn+QrX/lKnnvuuU9s9nvsscfyzW9+M9dcc00mT56c119/PWeccUZOPfXU3HnnnSV8BzDwCEzqWFfXHx6rFYb+MWrUqO7Hzc3NaWpqyo477ljiRADAgFTypq9XX311vvOd7+TUU09Nklx77bW5//77M3v27Fx++eUfe/2vf/3r7Lrrrjn77LOTJLvttltOP/30XHnllZs9OjSKatkDsOlWrCh7AthytLW15YEHHsikSZPKHgUA2IK0t7dvcKxevfpjr+ns7MxTTz2Vo446aoPzRx11VBYvXvyJ1z3kkEPy29/+Nvfee2+6urqybNmy3HHHHfnTP/3Tfvk+oB5ZYdIgnnkm0XIKvdOXWuH1r2/PKaeckrlz59rgFQD4ZJXK+qOW10syevToDU5ffPHFmT59+gbn3n777axbty4jR47c4PzIkSPz5ptvfuLlDznkkNxyyy2ZOnVqVq1albVr12bKlCn57//9v9fue4A6JzBpEEOGqBWG3upLrfC6dety8sknZ9q0aRkzZkz/DQUA8Alee+21bLfddt3PW1paPvW1lUJg09XV9bFzH3ruuedy9tlnZ9q0aTn66KPzxhtv5IILLsgZZ5yRG2+8sTbDQ50TmAD04LbbbsvixYvT0dGRGTNm5Mwzz8zSpUtz9913Z926dXnppZdyzTXXlD0mAFC2fmrJ2W677TYITD7J5z//+Wy11VYfW02yfPnyj606+dDll1+e8ePH54ILLkiSfOlLX8rQoUMzYcKEzJw5055tEIFJXfvoihKrS6B/nHjiiXnqqafyf//v/80uu+ySP/uzP8vUqVM/cfM0APg0qoPpT4MGDcoBBxyQ+fPn58/+7M+6z8+fPz9f/epXP/HPrFixIk1NG/5zcKuttkqyfmUKIDBpGGqFoff6cq8sWbIkb775Zh599NFcdtllueOOO3LSSSf133AAQH0quSXn3HPPzSmnnJIDDzwwBx98cObMmZO2tracccYZSZIf/vCHef311zNv3rwkyeTJk/Pf/tt/y+zZs7s/knPOOefkoIMOyk592ewNGpjApI599B99aoWhfzz++OPdO84fc8wxmTt3rsAEABhwpk6dmnfeeSeXXnpp3njjjYwbNy733ntvvvCFLyRJ3njjjbS1tXW//lvf+lY6Ojpy3XXX5bzzzsv222+fI444IldccUVZ3wIMOAKTOjZkSNkTQOP7t3/7t+7fsgwbNiz/+q//WvJEAMCA1E8tOX1x1lln5ayzzvrEr918880fO/fd73433/3ud/v898CWQmBSxz76M/Tll5MddihvFqgnfakV/qM/+qO0t7cnWR+efO5zn+vHyQAAgIFCYNIghg618Sv0Vl9qhf/jf/yPueqqq/LNb34z999/f8aPH99/gwEA9WsArDABaqta9gAAA9n++++fUaNGZcKECXnuuedy/PHHlz0SADAQVfvhAEplhQnARkyaNClLlizJb3/729x333054IADctZZZ6W9vT2HH354Lr7406siAdhyqA4GaCwCkwahVhh6ry/3yqpVq3LVVVflvvvuy6BBg5IkJ554YmbPnp3W1tZ+mhAAqDuV1PgjObW7FLBpBCZ1rKvrD4/VCkP/WLx4cQYPHpzJkydnyJAh+fGPf5xXX3015513XpYvX56ZM2fmkEMOKXtMAACgxgQmdWzFirIngMa3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AADwQWACAAAAAADgg8AEAAAAAADAB4EJAAAAAACADwITAAAAAAAAHwQmAAAAAAAAPghMAAAAAAAAfBCYAAAAAAAA+CAwAQAAAAAA8EFgAgAAAAAA4IPABAAAAAAAwAeBCQAAAAAAgA8CEwAAAAAAAB8EJgAAAAAAAD4ITAAAAAAAAHwQmAAAAAAAAPggMAEAAAAAAPBBYAIAAAAAAOCDwAQAAAAAAMAHgQkAAAAAAIAPAhMAAAAAAAAfBCYAAAAAAAA+CEwAAAAAAAB8EJgAAAAAAAD4IDABAAAAAADwQWACAAAAAADgg8AEAAAAAADAB4EJAAAAAACADwITAAAAAAAAHwQmAAAAAAAAPghMAAAAAAAAfBCYAAAAAAAA+CAwAQAAAAAA8EFgAgAAAAAA4IPABAAAAAAAwAeBCQAAAAAAgA8CEwAAAAAAAB8EJgAAAAAAAD4ITAAAAAAAAHwQmAAAAAAAAPggMAEAAAAAAPBBYAIAAAAAAOCDwAQAAAAAAMAHgQkAAAAAAIAPAhMAAAAAAAAfBCYAAAAAAAA+CEwAAAAAAAB8EJgAAAAAAAD4IDABAAAAAADwQWACAAAAAADgg8AEAAAAAADAB4EJAAAAAACADwITAAAAAAAAH/8POfSKmfVv8C8AAAAASUVORK5CYII=\n", "text/plain": [ "" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Image(f\"../outputs/scaled_1000/similarity-k{ksize}.matrix.png\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**TODO**: containment matrix" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## All-in-one figure" ] }, { "cell_type": "code", "execution_count": 122, "metadata": {}, "outputs": [], "source": [ "def difference_from_exact():\n", " all_methods = {}\n", " for k in (21, 31, 51):\n", " exact = pd.read_table(\n", " f\"../outputs/exact/SRR606249-k{k}.csv\",\n", " sep=\",\",\n", " header=None,\n", " names=(\"filename\", \"containment\", \"intersection\", \"|A|\"),\n", " usecols=(\"filename\", \"containment\"),\n", " )\n", " exact[\"filename\"] = exact[\"filename\"].str.replace(\n", " r\".*/(?P\\d+)-k\\d+.set\", lambda m: m.group(\"id\") + \".fa\"\n", " )\n", " exact.set_index(\"filename\", inplace=True) \n", " #all_methods.append(exact)\n", "\n", " smol = pd.read_table(\n", " f\"../outputs/smol_{scaled}/search-SRR606249-k{k}.csv\",\n", " sep=\",\",\n", " header=None,\n", " names=(\"filename\", \"containment\"),\n", " usecols=(\"filename\", \"containment\"),\n", " )\n", " smol[\"filename\"] = smol[\"filename\"].str.replace(\n", " r\".*/(?P\\d+).fa.*\", lambda m: m.group(\"id\") + \".fa\"\n", " )\n", " smol.set_index(\"filename\", inplace=True)\n", " #smol['containment'] = exact[\"containment\"] - smol['containment']\n", " smol['containment'] -= exact[\"containment\"]\n", " smol['method'] = 'smol, scaled=1000'\n", " smol['k'] = k\n", "\n", " all_methods[f'03_smol_{k}'] = smol\n", "\n", " for num in (1000, 10000):\n", " cmash_paper = pd.read_table(\n", " f\"../outputs/cmash_paper/SRR606249-k{ksize}-n{num}.csv\",\n", " sep=\",\",\n", " header=0,\n", " names=(\"filename\", \"intersection\", \"containment\", \"jaccard index\"),\n", " usecols=(\"filename\", \"containment\"),\n", " )\n", " cmash_paper.columns = [\"filename\"] + [c for c in cmash_paper.columns[1:]]\n", " cmash_paper[\"filename\"] = cmash_paper[\"filename\"].str.replace(\n", " r\".*/(?P\\d+).fa.*\", lambda m: m.group(\"id\") + \".fa\"\n", " )\n", " cmash_paper.set_index(\"filename\", inplace=True) \n", " #cmash_paper['containment'] = exact[\"containment\"] - cmash_paper['containment']\n", " cmash_paper['containment'] -= exact[\"containment\"]\n", " cmash_paper['method'] = f'CMash, n={num}'\n", " cmash_paper['k'] = k\n", "\n", " all_methods[f'02_cmash_{num}_{k}'] = cmash_paper\n", "\n", " if k <= 32: # mash doesn't support k>32\n", " mash_m1 = pd.read_table(\n", " f\"../outputs/mash_screen/SRR606249-k{k}-s{num}-m1.tsv\",\n", " header=None,\n", " names=(\n", " \"identity\",\n", " \"hashes\",\n", " \"median abundance\",\n", " \"p-value\",\n", " \"filename\",\n", " \"description\",\n", " ),\n", " usecols=[\"filename\", \"hashes\"],\n", " )\n", " mash_m1[\"filename\"] = mash_m1[\"filename\"].str.replace(\".*/\", \"\")\n", " mash_m1[\"containment\"] = mash_m1[\"hashes\"].apply(lambda x: eval(x))\n", " del mash_m1[\"hashes\"]\n", " mash_m1.set_index(\"filename\", inplace=True) \n", " #mash_m1['containment'] = exact[\"containment\"] - mash_m1['containment']\n", " mash_m1['containment'] -= exact[\"containment\"]\n", " mash_m1['method'] = f'Mash Screen, n={num}'\n", " mash_m1['k'] = k\n", "\n", " all_methods[f'01_mash_{num}_{k}'] = mash_m1\n", "\n", " return pd.concat([all_methods[c] for c in reversed(sorted(all_methods))])" ] }, { "cell_type": "code", "execution_count": 123, "metadata": {}, "outputs": [ { "data": { "image/png": "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P/64TzabTaNG/c3zGhT3WEVGIAgAAAAAAPxGVFQnJSQsl5TtaTNiDcHj6en6veGtpX/hQx+U/jUhSbrsssv1/PPTtHz5klzHEhKWKTg4WKtWrdfBg79r1KgH9Oab6xQcHFzsYxVZhQoE9+/fr/Hjx8vhcMhut2v69Olq0qSJ1zlOp1NTp07VJ598IovFohEjRqh///6SpKeeeko//vij59wff/xRr776qm677TbFxcVp5cqVqlevniTpqquu0nPPPVdu9wYAAAAAAErObg/RwIFDlZCwTJmZGQoKCtKgQcNMs4ZgRkaGpk59TgcO/CqbLUCNG1+sF154STt3fq05c2aqRYuW2rNntwICAjRhwhS98cZC7d//i+rVC9ff//6yqlWrprNnz+qf/3xZ+/btkSR169ZTQ4bcXaQ6NmxYq7feWqnAwCpyu12aMuUlXXxxEx04sF9z5vxDaWmpcrvdGjhwqHr0iFZCwnK9//5WOZ05qlIlSE88MV6XXXZFruv+/vsBzZkzS3/84VB2drbuvHOgevXqI0navv0Dvfbaq6pVq7ZuuOHGIr92l17aTJJybUojSe+//54mTHhektSoUWNdeWVzffHFZ7r11s7FPlaRVahA8LnnntOgQYMUExOjDRs2aNKkSYqPj/c6Z9OmTfr999+1detWORwO9e3bVx06dNBFF12kGTNmeM774YcfNHz4cEVF/W+YZt++fTVu3Lhyux8AAAAAAFD6evbsraSkTTp6NEV2e6h69Ig2uqRy8+WXn+vUqVNavny1JOnkyZOeYwcO/KoJE57XuHETNHPmdD3++Bi99tobqlcvXE888Yi2bdui3r37asmSRXK5XIqPX6WzZ8/owQfvVdOml6lDh5t8rmPevDmKj1+l8PD6ysrKksvlUk5OjsaPf1wjRoz0BGJ//OGQJHXv3ksDBw6RJO3Y8aVefvlFLViwxOuaOTk5ev75CXruuam6+OImOnv2jO67b6hatWqjWrVqafr0v+tf/1qsxo2baMWKpV59J0x4Sv/973/zrPW1115XUFDVAu/n6NEUhYdHeB7Xq1dfx46llOhYRVZhAsHU1FTt3btXb7zxhiQpOjpaL7zwgtLS0hQaGuo5LzExUf3795fValVoaKg6d+6sd999V/fff7/X9d5++2317t1bVapUKdf7AAAAAAAAZctms2n06LGaOHGcxowZK5vNZnRJ5aZZs8v0++8HNHPmdLVvf7VuvDHSc6xx44s9o+6uuOIKHT16RPXqhf//4+b6738PSpK+/vorPfroE7JYLKpevYY6d+6qr7/+qkiB4FVXXatp06YoKupmdegQqYYNL9Kvv/4ip9PpNTqudm27JOnHH/dp2bI3dPLkH7JarTp48Pdc1zx48Hf99tt+PffcM5627OxsHTiwXzabVZdffoUaN24iSerT53bNnx/nOW/q1Bl/vRwKUGECwSNHjig8PNzzj9hms6levXo6cuSIVyB45MgRNWjQwPM4IiJCKSneyWtWVpY2bdqkJUuWeLW/8847Sk5OVt26dTVmzBi1b++9TXlhwsJqFPGuAAAAAABAWejYsYPWrFmjunXrlvlzHTtmVUCA9zRTiyxl8lwWWXI9159dfHFjvfnmGn399Vf6/PNPtWDBq1qx4i3ZbFYFBQV5+gYEBPzlsU3Z2Vl/evy/e7JarbLZzj+2WCyy2QquQZJmzJipvXv36N//3qFHH31ITz31rMLDw2WxKFff7OxsTZw4TvPnL9KVVzbX8ePH1bt3N6/zAgKsstkssttDtHz5m7me7+OPP5LFYvGq/8/38fTTT3oCz79auHCJqlb93whBi8Uiq9X7HuvXr68TJ46qbt0wSdLx4ym69tprFRBgLfax8mS1WlW3bk2fz68wgWBp2rZtmxo0aKDmzZt72u666y499NBDCgwM1KeffqqRI0cqMTFRISG+rzGQmnpaLpe7LEoGAAAAAKDIUlNPKCysjtFlGCY19bSkgqeClobz02H/srOxyiYfcMud67n+7Nixo6pVq7Zuuqmjrr76evXt213p6Q45nS653fL0dbnccrvdXo9drvOPr7nmOm3YsE4tWrTWuXNn9d5772rUqL8pJ8clt9stp/P8edu3f6iPP/5QEyd673qck5Ojo0dTdMUVLXTFFS108OBB/fDDPl111bWyWm3aunWr15ThgIAAOZ1OhYXVU06OS6tXr/r/67j+dE2XGjRopKCgIG3evEndu/eSJP322wHVqVNHzZu30k8/Tdb+/QfUqFFjrVu31tMvJ8elF16YXuDr+ufncrv/91pc0KnTbVq79m2NGzdBBw/+rr179+q55/6unBxXsY+VJ5fLpePHT3keW62WAge2VZhAMCIiQkePHpXT6ZTNZpPT6dSxY8cUERGR67zDhw+rTZs2knKPGJSkNWvWKDY21qvtz58Y3HTTTYqIiNB//vMfXXfddWV0RwAAAAAAlJ29e7/XxInjNHXqDDVv3tLocsqd0fdfNySkTHYErlvIwKVffvlZ//rXXEmSy+XUkCF3q06duvr99998fo67775fs2fP0LBhAySd31Qkr006Dh06qOrVq+dqd7lc+vvfn9fp06dksVgVHh6uhx4arYCAAL300kzNnj1DS5YslMVi1cCBQ9S9ey/dd9+DeuCBYQoPr5/vhiABAQGaPn22XnllphISlsnpdCk0NFRTprykkJBQPfXUsxo3bqxq1apdrE073nvvXc2b94pOnTqpTz7ZruXLl2rWrLm65JJLNWjQMP39789rwIC+slqteuqpZxQcfP7ei3usIrO43e4KM+Rt6NChuuOOOzybirz99ttatmyZ1zlr167VO++8o4ULF3o2FVmxYoUaNWokSUpJSVH37t310UcfyW63e/odPXpU4eHn583v27dPd999tzZv3lykocWMEAQAAAAAVAROp1Njxoz4/w0N6isuboGp1tEr7/tPSflN9etfXGbXr6ieffZJjR49VhERDQo/GYb669eo34wQlKTnn39e48eP17x58/5/95jzwz0feOABPfLII2rdurViYmL03XffqWvXrpKkUaNGecJASVq3bp1uueUWrzBQkmbNmqU9e/bIarUqMDBQM2bMKJd1BgAAAAAAKG2JiZuUlpYmSUpLS1NS0mZFR8cYXFX5+fP9p6eb7/7Ly9///rLRJaCMVKgRghUdIwQBAAAAAEZLT0/TyJH3Kysr09NWpUqQ5s9fLLvd93Xy/VV6eppGjbpfmZn/u/+goKqaN29Rmd2/WUcIwn8UdYRg+W55AgAAAAAASiQ5ebtycrK92nJyspWcvN2gisrX+fvP8Woz0/0DpYFAEAAAAAAAP9KmTTu5XN47mLpcLrVu3c6YgspZ69bt5HQ6vdqcTqdp7h8oDQSCAAAAAAD4kV27vs21gYbNZtPu3d8aU1A52737W1mt3nGG1Wo1zf0DpYFAEAAAAAAAPxIV1UkBAd57hAYEBCoysqNBFZWvqKhOstm8799mCzDN/QOloULtMgwAAAAAAApmt4do4MBhWrFiqbKzsxQYWEWDBg0zxYYi0vn7b9fuKu3Y8YWnrX37q8v9/qdPfkKn0o+X+nVrhtTV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xKlixYj/v11Hf/11WJK0c+d2Pf7407JYLCpVqrRatbpDO3duz1Ug2LjxDXr11bGKirpVTZo0U5UqVfXHH7/L6XR6jY4rV84uSfr55/1asOADnTz5t6xWqw4fPpThmocPH9Kffx7Qiy8+72k7f/68Dh48IJvNqiuvvErVqtWQJN15592aOXOq57hx4yb893LIRrEJBOPi4hQRESGbzSZJstlsqlixouLi4rwCwbi4OFWuXNlzOzIyUvHx3slrWlqa1q5dq7lz53q1r1+/XrGxsapQoYKGDBmiRo0a5arG8PDSuXxUAAAAAADA3x07ZlVAgPc0U4sshXJfFlky3NfFqlevpiVLPtLOndv19ddf6r33pmvRomWy2awKDg72nBsQEPCf2zadP5920e1/H5PVapXNduG2xWKRzZZ9DZI0YcJE7du3V//73w49/vgjevbZFxQRESGLRRnOPX/+vEaNGq6ZM2fr6qvr6Pjx4+rUqY3XcQEBVtlsFtntoVq4cEmG+9u27XNZLBav+i9+HM8994wn8PyvWbPmqkSJf0cIWiwWWa3ej7FSpUo6cSJBFSqES5KOH4/XDTfcoIAAa577ipLValWFCmV8Pr7YBIIFafPmzapcubLq1KnjaevRo4ceeeQRBQYG6ssvv9Rjjz2mmJgYhYaG+nzdxMTTcrnchVEyAAAAAAAopi5Mh3V5tblVOPmAW+4M93WxY8cSVLZsOTVt2lzXXXeTunRpK4cjWU6nS263POe6XG653W6v2y7XhdvXX3+jVq9eqWuuqa9z587qk08+1qBBTyg93SW32y2n88JxW7d+pm3bPtOoUWO9akhPT1dCQryuuuoaXXXVNTp8+LB++mm/Gje+QVarTZs2bfKaMhwQECCn06nw8IpKT3dp+fKl/38d10XXdKly5csUHBysdevWqm3bDpKkP/88qPLly6tOnXr65ZcxOnDgoC67rJpWrlzhOS893aWXXx6f7fN68X253f8+F/9o0eJ2rVjxoYYPH6nDhw9p3759evHFV5Se7spzX1FyuVw6fvyU57bVasl2YFuxCQQjIyOVkJAgp9Mpm80mp9OpY8eOKTIyMsNxR48eVYMGDSRlHDEoSR999JG6du3q1VahQgXP102bNlVkZKR+/fVX3XjjjYX0iAAAAAAAwKWqQmiodOTTwrluNn7//Te98840SZLL5VSf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e+WVV+bZZ58d0vcFAAAAAMPNsDgyvHXr1tx5551JkqlTp+baa6/Nzp07z7pu27Zt6ezsTGtra2q1WubPn58tW7acdd1LL72UK664Ih/72Mf+67MDAAAAwEgyLHYIdnd3Z/Lkyacft7W15a233jrrup6enrS3t59+3N7enp6enrOu27BhQ774xS+e8dyBAwcyb968jBo1KgsXLsy8efPOe86JE8ef9z0AAAAAMJwMSRCcN29euru7z7m2Z8+eD/RnHT58OH/84x/zs5/97PRz11xzTV5++eVMmDAhBw8ezFe/+tV86EMfyvXXX39er93bezz1euMDnRcAAAAAPki1WtOAG9uGJAg+99xzA663t7fn0KFDaW1tTfLuTsBp06addV1bW9sZYbG7uzttbW1nXLNx48bcdNNNp18rScaP/88vYMqUKens7MzevXvPOwgCAAAAwEg3LL5DcPbs2Vm3bl2Sd4/27tu3Lx0dHWddN2vWrOzYsSNHjx5NvV7P+vXrM2fOnDOuefbZZ886Lnz48OE0Gu/u7Ovr68vu3btz1VVX/ZfeDQAAAAAMX8PiOwQXL16cZcuWZebMmanValmxYsXpXX2rV6/OpEmTsmDBgkyZMiVLlizJHXfckSSZPn16br311tOv86c//SknTpzIDTfccMbrb9++PV1dXRk1alT6+/tz2223pbOzc+jeIAAAAAAME02Nf2+dY1C+QxAAAACA4W6w7xAcFkeGAQAAAIChIQgCAAAAQEEEQQAAAAAoiCAIAAAAAAURBAEAAACgIIIgAAAAABREEAQAAACAggiCAAAAAFAQQRAAAAAACiIIAgAAAEBBBEEAAAAAKIggCAAAAAAFEQQBAAAAoCCCIAAAAAAURBAEAAAAgIIIggAAAABQEEEQAAAAAAoiCAIAAABAQQRBAAAAACiIIAgAAAAABREEAQAAAKAggiAAAAAAFEQQBAAAAICCCIIAAAAAUBBBEAAAAAAKIgjCB6S390jVIwAAAAAMShCED8Drr7+Wu+/+St54Y3/VowAAAAAMSBCEi9Tf3581ax5Okjz66M/T399f8UQAAAAA700QhIu0Zcvm9PX1JUn6+vqydevvqh0IAAAAYACCIFyEY8eOpqvrNzl16p0kyalT7+Spp55IX9+xiicDAAAAODdBEC7Crl0vp14/84hwvd6fXbtermgiAAAA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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "sns.set_palette(\"tab10\", n_colors=5)\n", "with FigureManager(figsize=(18, 18), show=True, filename=f\"../figures/containment.pdf\", nrows=2, sharey=True) as (fig, ax):\n", " plot_df = difference_from_exact()\n", " sns.boxenplot(x=\"k\", y=\"containment\", hue=\"method\", data=plot_df, ax=ax[0])\n", " ax[0].set_ylabel(f\"Difference to ground truth\")\n", " ax[0].text(0, 1.05, \"A\", transform=ax[0].transAxes, fontsize=22)\n", "\n", " sns.boxenplot(x=\"k\", y=\"containment\", hue=\"method\", data=plot_df.drop([f\"{i}.fa\" for i in low_coverage]), ax=ax[1])\n", " ax[1].set_ylabel(f\"Difference to ground truth\")\n", " ax[1].text(0, 1.05, \"B\", transform=ax[1].transAxes, fontsize=22)\n", "\n", " fig.tight_layout()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Scaled MinHash sizes for reference genomes in Shakya" ] }, { "cell_type": "code", "execution_count": 365, "metadata": {}, "outputs": [], "source": [ "from pathlib import Path\n", "import json\n", "\n", "sizes = {k: {} for k in (21,31,51)}\n", "for k in sizes:\n", " for sigf in Path(\"../outputs/smol_1000/refs/\").glob(f\"*-k{k}.smol\"):\n", " sig = json.loads(sigf.read_bytes())\n", " sizes[k][sigf.parts[-1].split(\"-\")[0]] = len(sig['hashes'])" ] }, { "cell_type": "code", "execution_count": 366, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAfkAAAD9CAYAAAC/UA5GAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/d3fzzAAAACXBIWXMAAAsTAAALEwEAmpwYAAAZ1klEQVR4nO3df3BU9b3/8dfuYZKYQNzsajAqX/KVqc7qnSm9eOX7nZGpg20zwGLwm9tGAgFvVabDhXbgMiW1Chao813KgFZg1NpRQyNtuQxCFviGe4eWmXgtdWz1FpdWiwml7ULMZjNCMHg5Od8/+JqvqSjJ7sme7Oc8H/9Izicnn3fGTz6vzzl7fgQcx3EEAACME/S6AAAAMDoIeQAADEXIAwBgKEIeAABDEfIAABiKkAcAwFBXDPl4PK6ZM2fqlltu0dtvvz24vaOjQ/X19aqpqVF9fb06OztHtQ0AAIzMFUP+7rvvVktLi2644YYh29euXauGhga1tbWpoaFBa9asGdU2AAAwMlcM+dtvv11VVVVDtqXTaSWTScViMUlSLBZTMplUT0/PqLQBAICRG5fNTqlUShMnTpRlWZIky7JUWVmpVColx3FcbwuHw278rgAA+EpWIT/WpdPnNDDA03oBAGYLBgOKRMZ/antWIV9VVaUzZ87Itm1ZliXbttXV1aWqqio5juN6GwAAGLmsbqGLRCKKRqNKJBKSpEQioWg0qnA4PCptAABg5AJXegvdhg0bdOjQIXV3d6uiokKhUEj79+/XiRMn1NTUpPfff1/l5eWKx+O66aabJGlU2kaC0/UAUPjS6W5FItd4XcaYdqXT9VcM+UJEyAP5x4QMNyWTx/Too6u1YcNGRaO3eV3OmHWlkOeJdz6VTnd7XQIMkkwe05Ili3X8+FtelwID2LatrVu3SJKeemqzbNv2uKLCRcj7EBMy3MSEDLcdONCq3t5eSVJvb68OHkx4W1ABI+R9hgkZbmNChpsymR7t3LlDFy70S5IuXOjXSy81q7c343FlhYmQ9xkmZLiJCRlua28/ooGBoQcfAwO22tuPeFRRYSPkfYQJGW5jQobbZsy4S8GgNWRbMGjpzju/6FFFhY2Q9xEmZLiNCRluC4UqNH9+o4qLSyRJxcXFamhYpFCowuPKChMh7yNMyHAbEzJGw+zZcxUKhSRJoVBYs2bFvC2ogBHyPsKEjNHAhAy3WZalZctWSJKWL18x+OIyjBwh7zNMyHAbEzJGw623/p2effZFHoSTI55450M8SQqjgSfeAfnHY21xWUzIAFD4eKwtLouABwDzEfIAABiKkAcAwFCEPAAAhiLkAQAwFCEPAIChCHkAAAxFyAMAYChCHgAAQxHyAAAYipAHAMBQhDwAAIYi5AEAMBQhDwCAoQh5AAAMRcgDAGAoQh4AAEMR8gAAGIqQBwDAUIQ8AACGIuQBADAUIQ8AgKEIeQAADJVzyP/iF7/QvHnzVFtbq7lz5+rQoUOSpI6ODtXX16umpkb19fXq7Owc3CfbNgAAMHwBx3GcbHd2HEd33HGHWlpadPPNN+v3v/+95s+fr9dff13333+/6urqVFtbq71792r37t1qbm6WJC1atCirtuFKp89pYCDrXwsAgIIQDAYUiYz/9PbcOwjq7NmzkqSzZ8+qsrJSmUxGyWRSsVhMkhSLxZRMJtXT06N0Op1VGwAAGJlxuewcCAT0xBNPaOnSpSotLVVfX5+eeeYZpVIpTZw4UZZlSZIsy1JlZaVSqZQcx8mqLRwOD7uuz1rVAADgFzmF/MWLF/XMM89o+/btmjZtml5//XWtWLFCGzdudKu+rHC6HgDgB1c6XZ9TyB8/flxdXV2aNm2aJGnatGm66qqrVFxcrDNnzsi2bVmWJdu21dXVpaqqKjmOk1UbAAAYmZw+k7/uuut0+vRpvfvuu5KkEydOqLu7W5MnT1Y0GlUikZAkJRIJRaNRhcNhRSKRrNoAAMDI5HR1vSTt27dPP/rRjxQIBCRJ3/zmN/WlL31JJ06cUFNTk95//32Vl5crHo/rpptukqSs24aL0/UAAD+40un6nEN+LCLkAQB+MOq30AEAgLGJkAcAwFCEPAAAhiLkAQAwFCEPAIChCHkArkinu70uAcDfIOQB5CyZPKYlSxbr+PG3vC4FwMcQ8gByYtu2tm7dIkl66qnNsm3b44oAfISQB5CTAwda1dvbK0nq7e3VwYMJbwsCMIiQ96k//vFtr0uAATKZHu3cuUMXLvRLki5c6NdLLzWrtzfjcWUwAdd55I6Q96EDB1q1evUKjriQs/b2IxoYGHp6fmDAVnv7EY8qgim4zsMdhLzPfPjhh3rhhR9Jkp5//ll9+OGHHleEQjZjxl0KBq0h24JBS3fe+UWPKoIJbNvW5s1xSdLmzf+b6zxyQMj7zObN8cE/GNu2tWXLRo8rQiELhSp0330LJF16C2UgENB99y1UKFThbWEoaPv371Umc+kjn0wmo/3793lcUeEi5H2ks/Ndvfbar4Zs+/WvX9XJk53eFAQjfPw9lua90xL5lsn0qKXlRUmXBpPjOGppeYHrPLJEyPvIT3/6k0/ZviPPlcAUmUyPfvazFn00IUuOfvrTnzAhI2uHDh3UxYsXh2y7ePGi/u3f/o9HFRU2Qt5H5s9fdNnt993XmOdKYAouvIPbAoFPa+E0UTYIeR+ZPLla//AP/2PItjvu+J+aPLnam4JQ8LjwDm77yldmy7KGjinLGqcvf3mWRxUVNkLeZ1auXD34B2RZllas+LbHFaGQhUIVmj+/UcXFJZKk4uJiNTQs4sI7ZC0UqtCCBffro4s5JWnhwvsZU1ki5H2mqKhI99//kCTpn/5piYqKijyuCIVu9uy5CoVCkqRQKKxZs2LeFoSCF4vVqqLiUqhXVEQ0Z849HldUuAh5H6qu/u9D/gvkwrIsLVu2QpK0fPmKT5xqBUbKsiytXLlakvQv/7KaMZUDQt5neJkIAPgHIe8zvEwEbmPhCLcxptxDyPsILxPBaGDhCLcxptxDyPsI9zTDbSwc4TbGlLsIeR/hnma4jYUj3MaYchch7yPc0wy3sXCE2xhT7iLkfYZ7muEmFo5wG2PKXYS8z3BPM9zGwhFuY0y5h5D3oVtv/Ts9++yLikZv87oUGMCyLMVi8yRJc+fOY+GInHEw4h5C3qcikWu8LgGGsG1bicTLkqTW1j3c0wyMIYS8T6XT3V6XAENwTzPcxsNw3EPI+1AyeUxLlizW8eNveV0KChz3NGM0sHB0DyHvM6yQ4SbuaYbbWDi6i5D3GVbIcBP3NMNtLBzdFXAcx8nlB1y4cEGPP/64Xn31VRUXF2vq1Klav369Ojo61NTUpN7eXoVCIcXjcVVXV0tS1m3DlU6f08BATr+WkTKZHv3zPz80uEKWpOLiEm3f/hz3oEKStHhxvc6dO5f3fsePH68XX/xZ3vvF2NPbm9HSpQ8yTw1TMBhQJDL+U9vH5drBD37wAxUXF6utrU2BQEDd3Zcu6Fq7dq0aGhpUW1urvXv3as2aNWpubs6pDbn5rBXyR7dAwd/OnTunw3t25L3fmfc25r1P5MeixfXqy3HheOFCvx54YOGI9ikbP17NLBxzC/m+vj69/PLLOnLkiAKBgCTpmmuuUTqdVjKZ1PPPPy9JisViWr9+vXp6euQ4TlZt4XA4l1KhS6dWd+78iaT/GtzGqVUAo6nv3Dm17GvJe78L7lmQ9z7HopxC/tSpUwqFQtq6dauOHj2qsrIyfetb31JJSYkmTpw4+AADy7JUWVmpVColx3GyahtJyH/WqQuTzJkzR2fPns3pZ2SzQp4wYYL279+fU7/A37r22glelwDDMKZyDPmLFy/q1KlTuvXWW7V69Wq9+eab+sY3vqEnn3zSrfqy4pfP5M+ePasdu/N/4VxjXUzvvZfb4gL4W4wpuM0PY2pUP5O//vrrNW7cOMVil54r/PnPf14VFRUqKSnRmTNnZNu2LMuSbdvq6upSVVWVHMfJqg0AAIxMTrfQhcNhTZ8+Xa+88oqkS1fGp9NpVVdXKxqNKpG4dJSZSCQUjUYVDocViUSyagMAACOT89X13/ve9/Twww8rHo9r3Lhx2rhxo8rLy/XYY4+pqalJ27dvV3l5ueLx+OA+2bYBAIDhyznkJ02apB07PnnLzZQpU7Rr167L7pNtGwAAGD6eeAcAgKEIeQAADEXIAwBgKEIeAABDEfIAABiKkAcAwFCEPAAAhiLkAQAwFCEPAIChCHkAAAyV82NtkZvGRV/T+b6+7Pevi7lYzfDV1c3Jar/SsjLtaP65y9UAAC6HkPfY+b4+zV25yesy8qZ18yqvSzDe4kVf1bm+81nvP/PeRherGb5sF47jy0r1YjPvuwAuh5AHDHOu77z2PjzL6zLypvbxg16XYLzGRV/V+RwWjgvuWeBiNcOXzcKxtKxUOwxaNBLyAIDPdL7vvO7dcK/XZeTFnkf2eF2Cq7jwDgAAQxHyAAAYipAHAMBQhDwAAIYi5AEAMBQhDwCAoQh5AAAMRcgDAGAoQh4AAEMR8gAAGIqQBwDAUIQ8AACGIuQBADAUIQ8AgKEIeQAADEXIAwBgKEIeAABDEfIAABhqnNcFAKZa1PiP6jv/gSd91z5+0JN+vVJXNyev/ZWVXqXmHf+a1z4laUHjP6rfozG155E9nvTrhXyPJ0kqKb1KLaMwpgh5YJT0nf9AP/lSxusyMAoW/rs3/faf/0D2V21vOseo6t81Oos3107Xb926VbfccovefvttSVJHR4fq6+tVU1Oj+vp6dXZ2Dn5vtm0AAGD4XDmSf+utt/TGG2/o+uuvH9y2du1aNTQ0qLa2Vnv37tWaNWvU3NycU9toW9D4NfWf78tLXx/XunlV3vv0kjenwsrUsuPnee8XALyUc8h/+OGHWrdunTZt2qTFixdLktLptJLJpJ5//nlJUiwW0/r169XT0yPHcbJqC4fDuZZ6Rf3n+9Q3/cFR7wceOPqc1xUAQN7lHPJPPvmk7rnnHk2aNGlwWyqV0sSJE2VZliTJsixVVlYqlUrJcZys2vIR8gAAmCSnkP/tb3+r3/3ud1q1amydbo5ExntdAsaga6+d4HUJMAjjCW4bjTGVU8i/9tprevfdd3X33XdLkk6fPq0HHnhA3/nOd3TmzBnZti3LsmTbtrq6ulRVVSXHcbJqG4l0+pwGBpxcfjUY6L33znpdAgzCeILbshlTwWDgMw9sc7q6fsmSJWpvb9fhw4d1+PBhXXfddfrxj3+s2bNnKxqNKpFISJISiYSi0ajC4bAikUhWbQAAYGRG7T75xx57TE1NTdq+fbvKy8sVj8dzbgMAAMPnasgfPnx48N9TpkzRrl27Lvt92bYBAIDh49n1AAAYipAHAMBQhDwAAIYi5AEAMBQhDwCAoQh5AAAMRcgDAGAoQh4AAEMR8gAAGIqQBwDAUIQ8AACGIuQBADAUIQ8AgKEIeQAADEXIAwBgKEIeAABDEfIAABiKkAcAwFCEPAAAhiLkAQAwFCEPAIChxnldAGCq/v5+/bLT9roMAD5GyH9Mf3+//usvSa/LAIDL6u/v18A7A16XgVFQqtJR+bmEPDBKSkpKdFf1B16XgVHw3B+9rgAYHkL+Y0pKSmTfcKvXZWA0/Pk/vK4AyFlJSYnsz/ERkJHeGJ0fy4V3AAAYipAHAMBQhDwAAIYi5AEAMBQhDwCAoQh5AAAMRcgDAGAoQh4AAEMR8gAAGCqnkM9kMnrooYdUU1OjuXPnatmyZerp6ZEkdXR0qL6+XjU1Naqvr1dnZ+fgftm2AQCA4csp5AOBgB588EG1tbWptbVVkyZN0qZNmyRJa9euVUNDg9ra2tTQ0KA1a9YM7pdtGwAAGL6cQj4UCmn69OmDX0+dOlV//etflU6nlUwmFYvFJEmxWEzJZFI9PT1ZtwEAgJFx7QU1AwMD2rlzp2bOnKlUKqWJEyfKsixJkmVZqqysVCqVkuM4WbWFw2G3SgUAwBdcC/n169ertLRUCxcuVDLp7TvZI5HxnvaPsenaayd4XQIMwniC20ZjTLkS8vF4XCdPntTTTz+tYDCoqqoqnTlzRrZty7Is2batrq4uVVVVyXGcrNpGIp0+p4EBZ8S/R0lpmXT0uRHvh7GvpLRM7713Nq99lpVepYX/ntcukSdlpVflfTxJUknpVerf9UHe+8XoK8lyTAWDgc88sM055Lds2aJjx47p2WefVVFRkSQpEokoGo0qkUiotrZWiURC0Wh08JR7tm2jrWXHz/PSz8fV1c3R3JWb8t6vV1o3r9Lu3fu9LiMvmnf8qyf91tXN0d6HZ3nStxdqHz/omzHV4uGYunfDvZ70nW97Htlj1HjKKeTfeecdPf3006qurtZ9990nSbrxxhu1bds2PfbYY2pqatL27dtVXl6ueDw+uF+2bQAAYPhyCvnPfe5z+sMf/nDZtilTpmjXrl2utgEAgOFz7cI7AGPD+LJS1T5+0Osy8mZ8WanXJRivtKxUex7Z43UZeVFq2HgKOI4z8ivUxrhsL7zzQuOir+l8X5/XZeRNaVmZdjTn/9oHDE9d3Rwd3rMj7/3OvLfRqM9B8f/V1c1Ry76WvPe74J4FvhhTo37hHXKTS+DV1c3Rjt0JF6sZnsa6mC/+eACg0BHyAAaNHz9eM+9t9KRfAO4j5AtY2fjxaqyLedIvzPTiiz8b0fefPNmhlSuXfWL75s3bNHlytUtVAcgWIV/Amkc4Ib/wwnNqbf3kxTPz5v0vNTY+4FZZ8JFf/eo/Lrv9179+lZCHpEsHBQvuWeBJvyDkfeXUqZOX3X7y5OW3A1cSCHxaS2Fc+IrRN9KDkfXrH9Ubb/zmE9u/8IVpeuSRdW6V5Rs5vYUOhWXRossfrTc2fj3PlcAUX/nK7MEXSn3Essbpy1/2zxP34C7mKXcR8j4yeXK1Jk36b0O2TZo0mdOqyFooVKEvfOH2Idv+/u9vVyhU4VFFKHTMU+4i5H0kk+nR6dOnh2w7fTql3t6MRxWh0GUyPfrP/3xjyLY33/wtYwpZY55yFyHvI+3tR/TJz0qd/7cdGLn29iNynIEh2xxngDGFrDFPuYuQ95EZM+5SMDj089Ng0NKdd37Ro4pQ6BhTcBtjyl2EvI+EQhWaP79RxcUlkqTi4mI1NCzi81NkjTEFtzGm3EXI+8zs2XMVCoUkSaFQWLNm5f9hOjALYwpuY0y5h5D3GcuytGzZCknS8uUrPnH7EzBSjCm4jTHlHt5C51PpdLcikWu8LgMGYUzBbYypK7vSW+gIeQAACtSVQp7T9QAAGIqQBwDAUIQ8AACGIuQBADAUIQ8AgKEIeZ9Kp7u9LgEAPhPzVO4IeR9KJo9pyZLFOn78La9LgUGYkOEm5il3EPI+Y9u2tm7dIkl66qnNsm3b44pgAiZkuIl5yj2EvM8cONCq3t5eSVJvb68OHkx4WxAKHhMy3MY85R5C3kcymR7t3LlDFy70S5IuXOjXSy81q7c343FlKGRMyHAT85S7CHkfaW8/ooGBoUdZAwO22tuPeFQRCh0TMtzGPOUuQt5HZsy4S8Hg0Lc5BYOW7rzzix5VhELHhAy3MU+5i5D3kVCoQvPnN6q4uESSVFxcrIaGRQqFKjyuDIWKCRluY55yFyHvM7Nnz1UoFJIkhUJhzZoV87YgFDQmZIwG5in3EPI+Y1mWli1bIUlavnyFLMu6wh7AZ2NChtuYp9zD++R9Kp3uViRyjddlwBDJ5DE9+uhqbdiwUdHobV6XA0MwT13Zld4nT8gDcAUTMpB/Vwp5TtcDcAUBD4w9YzLkOzo6VF9fr5qaGtXX16uzs9PrkgAAKDhjMuTXrl2rhoYGtbW1qaGhQWvWrPG6JAAACs6Y+0w+nU6rpqZGR48elWVZsm1b06dP16FDhxQOh4f1MzKZPj6TBwAYLxgMqKKi7FPbx+WxlmFJpVKaOHHi4C0TlmWpsrJSqVRq2CH/Wb8wAAB+MSZP1wMAgNyNuZCvqqrSmTNnBl9Xadu2urq6VFVV5XFlAAAUljEX8pFIRNFoVInEpddVJhIJRaPRYZ+qBwAAl4y5C+8k6cSJE2pqatL777+v8vJyxeNx3XTTTV6XBQBAQRmTIQ8AAHI35k7XAwAAdxDyAAAYipAHAMBQhDwAAIYi5AEAMNSYe6wt3JXJZPTtb39bf/rTn1RUVKTJkydr3bp1CofDisfjamtr01/+8he1trbq5ptv9rpcFIilS5fqz3/+s4LBoEpLS/Xoo48qGo0yppC1mTNnqqioSMXFxZKkVatWacaMGYypHHEkb7hAIKAHH3xQbW1tam1t1aRJk7Rp0yZJ0t13362WlhbdcMMNHleJQhOPx7Vv3z69/PLL+vrXv66HH35YEmMKufnhD3+ovXv3au/evZoxY4YkxlSuOJI3XCgU0vTp0we/njp1qnbu3ClJuv32270qCwVuwoQJg/8+d+6cAoGAJMYU3MeYyg0h7yMDAwPauXOnZs6c6XUpMMB3v/tdvfLKK3IcR88995zX5cAAq1atkuM4mjZtmlauXKny8nKvSyp4nK73kfXr16u0tFQLFy70uhQY4Pvf/75++ctfasWKFdq4caPX5aDAtbS0aN++fdq9e7ccx9G6deu8LskIhLxPxONxnTx5Uk888YSCQf63wz3z5s3T0aNHlclkvC4FBeyjN40WFRWpoaFBv/nNbzyuyAzM9j6wZcsWHTt2TNu2bVNRUZHX5aDA9fX1KZVKDX59+PBhXX311QqFQt4VhYJ2/vx5nT17VpLkOI4OHDigaDTqcVVm4AU1hnvnnXcUi8VUXV2tkpISSdKNN96obdu2acOGDTp06JC6u7tVUVGhUCik/fv3e1wxxrru7m4tXbpUH3zwgYLBoK6++mqtXr1at912G2MKWTl16pSWL18u27Y1MDCgKVOm6JFHHlFlZSVjKkeEPAAAhuJ0PQAAhiLkAQAwFCEPAIChCHkAAAxFyAMAYChCHgAAQxHyAAAY6v8C26PzKygOpyAAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "sig_sizes = pd.DataFrame(sizes)\n", "with FigureManager(figsize=(8, 4), show=True) as (fig, ax):\n", " sns.boxenplot(data=sig_sizes, ax=ax)" ] }, { "cell_type": "code", "execution_count": 368, "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", "
213151
count686868
mean3,2133,2273,229
std1,7291,7301,731
min503431489
25%1,9201,9181,946
50%2,6972,7272,682
75%4,1364,2704,237
max9,5009,5409,611
\n", "
" ], "text/plain": [ " 21 31 51\n", "count 68 68 68\n", "mean 3,213 3,227 3,229\n", "std 1,729 1,730 1,731\n", "min 503 431 489\n", "25% 1,920 1,918 1,946\n", "50% 2,697 2,727 2,682\n", "75% 4,136 4,270 4,237\n", "max 9,500 9,540 9,611" ] }, "execution_count": 368, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sig_sizes.describe().applymap(lambda x: \"{:,.0f}\".format(x))" ] }, { "cell_type": "code", "execution_count": 378, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "21 4911.0\n", "31 4899.8\n", "51 4973.6\n", "Name: 0.8, dtype: float64" ] }, "execution_count": 378, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sig_sizes.quantile(0.8)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Extras\n", "\n", "## Median abundance (sourmash and mash)\n", "\n", "mash also calculates abundance for each hash, so we can compare the median abundance reported by both mash and sourmash." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "mash_screen = pd.read_table(\n", " f\"../outputs/mash_screen/SRR606249-k{ksize}-s{num}-m1.tsv\",\n", " header=None,\n", " names=(\n", " \"identity\",\n", " \"hashes\",\n", " \"median abundance mash\",\n", " \"p-value\",\n", " \"filename\",\n", " \"description\",\n", " ),\n", " usecols=(\"hashes\", \"median abundance mash\", \"filename\"),\n", ")\n", "mash_screen[\"filename\"] = mash_screen[\"filename\"].str.replace(\".*/\", \"\")\n", "mash_screen[\"mash\"] = mash_screen[\"hashes\"].apply(lambda x: eval(x))\n", "del mash_screen[\"hashes\"]\n", "mash_screen.set_index(\"filename\", inplace=True)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "sourmash = pd.read_table(\n", " f\"../outputs/scaled_1000/SRR606249-k{ksize}.csv\",\n", " sep=\",\",\n", " usecols=[\"f_match\", \"median_abund\", \"filename\"],\n", ")\n", "sourmash.columns = (\"sourmash\", \"median abundance sourmash\", \"filename\")\n", "sourmash[\"filename\"] = sourmash[\"filename\"].str.replace(\n", " r\".*/(?P\\d+).sig\", lambda m: m.group(\"id\") + \".fa\"\n", ")\n", "sourmash.set_index(\"filename\", inplace=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Keeping only result where the difference in median abundance is at least 1. Also highlighting differences:\n", " - median abundance difference < 10\n", " - median abundance difference < 30\n", " - large containment differences (>0.05): gradient background\n", " \n", "**TODO** repeat this with the full containment, not only `f_match`" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "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", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
median abundance mash mash sourmash median abundance sourmash
0.fa321.0000000.99952027.000000
1.fa291.0000000.99864726.000000
2.fa141.0000001.00000012.000000
3.fa490.9990000.99813342.000000
4.fa90.9990000.9974468.000000
5.fa70.9960000.9866006.000000
6.fa60.9510000.9341015.000000
7.fa40.9360000.9059753.000000
8.fa190.9990000.94892416.000000
9.fa141.0000000.99748612.000000
10.fa190.9970000.98488816.000000
11.fa170.9980000.98729414.000000
12.fa331.0000000.99566528.000000
13.fa211.0000000.99815618.000000
14.fa141.0000000.99980212.000000
15.fa141.0000000.99972612.000000
16.fa70.9740000.9609596.000000
17.fa110.8230000.7676179.000000
18.fa191.0000001.00000017.000000
19.fa160.6560000.61566914.000000
20.fa80.2060000.1241286.000000
21.fa351.0000001.00000030.000000
22.fa291.0000000.99920626.000000
23.fa90.9940000.9853168.000000
24.fa91.0000000.9954598.000000
25.fa361.0000000.99874832.000000
26.fa101.0000000.9992218.000000
27.fa100.9880000.9742108.000000
28.fa250.9990000.99940522.000000
29.fa211.0000001.00000018.000000
30.fa171.0000000.92538214.000000
31.fa240.9990000.99755421.000000
32.fa70.9960000.9948376.000000
33.fa1090.9970001.000000101.000000
34.fa470.9960000.99416541.000000
35.fa100.9990000.9983559.000000
36.fa161.0000000.99932513.000000
37.fa141.0000000.99763412.000000
38.fa360.9970000.99911130.000000
39.fa221.0000000.99263718.000000
40.fa311.0000000.99748127.000000
41.fa330.9980000.99566429.000000
42.fa541.0000000.99599546.000000
43.fa531.0000000.99985846.000000
44.fa50.9710000.9571584.000000
45.fa80.9790000.9769127.000000
46.fa80.9860000.9251277.000000
47.fa60.9860000.9774005.000000
48.fa241.0000000.99943820.000000
49.fa100.9970000.7246096.000000
50.fa111.0000000.99909510.000000
51.fa490.9990000.99838242.000000
52.fa1080.9990000.41305628.000000
53.fa1131.0000000.91018093.000000
54.fa291.0000001.00000024.000000
55.fa200.8080000.74259617.000000
56.fa241.0000001.00000021.000000
57.fa171.0000000.99950615.000000
58.fa50.9510000.9401474.000000
59.fa471.0000000.55454528.000000
60.fa461.0000000.99870436.000000
61.fa180.9990000.99825815.000000
62.fa401.0000001.00000034.000000
63.fa60.9630000.4696453.000000
66.fa150.1870000.12554113.000000
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def highlight_diff(s):\n", " mdiff = np.abs(s[\"median abundance mash\"] - s[\"median abundance sourmash\"])\n", " cdiff = np.abs(s[\"mash\"] - s[\"sourmash\"])\n", "\n", " gradient_bg = \"background: repeating-linear-gradient(45deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2) 10px, rgba(0, 0, 0, 0.3) 10px, rgba(0, 0, 0, 0.3) 20px);\"\n", " bg = \"\"\n", " if cdiff >= 0.05:\n", " bg = gradient_bg\n", "\n", " if mdiff == 1:\n", " color = \"background-color: white\"\n", " elif mdiff < 10:\n", " color = \"background-color: yellow\"\n", " else:\n", " color = \"background-color: red; color:white\"\n", "\n", " return [bg + color] * 4\n", "\n", "\n", "abundances = pd.concat((mash_screen, sourmash), axis=1)\n", "with pd.option_context(\"display.max_rows\", None, \"show_dimensions\", True):\n", " diff = abundances[\"median abundance mash\"] - abundances[\"median abundance sourmash\"]\n", " display(abundances[diff.abs() >= 1].style.apply(highlight_diff, axis=1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Interactive similarity plot" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "data = np.load(f\"../outputs/scaled_1000/similarity-k{ksize}\")\n", "with open(f\"../outputs/scaled_1000/similarity-k{ksize}.labels.txt\", \"r\") as f:\n", " labels = f.readlines()" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "import scipy.cluster.hierarchy as sch\n", "\n", "Y = sch.linkage(data, method=\"single\") # centroid\n", "dendrolabels = [str(i) for i in range(len(labels))]\n", "# dendrolabels = labels\n", "Z1 = sch.dendrogram(Y, orientation=\"left\", labels=dendrolabels, no_labels=False)\n", "\n", "idx1 = Z1[\"leaves\"]\n", "data = data[idx1, :]\n", "data = data[:, idx1]" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [ { "data": {}, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.holoviews_exec.v0+json": "", "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "
\n", "
\n", "" ], "text/plain": [ ":HeatMap [columns,index] (value)" ] }, "execution_count": 26, "metadata": { "application/vnd.holoviews_exec.v0+json": { "id": "1960" } }, "output_type": "execute_result" } ], "source": [ "df = pd.DataFrame(data, index=labels, columns=labels)\n", "df.hvplot.heatmap(width=800, height=600, colormap=\"YlGnBu\", xaxis=None, yaxis=None)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## CMash with TST (new version)\n", "\n", "CMash outputs the filename and one column per k-size with the containment to each match.\n", "I built an index with `k=51` and queried with ranges `21-51-10` (ksizes `21,31,41,51`):" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "cmash_all = pd.read_table(\"../outputs/cmash/SRR606249.csv\", sep=\",\")\n", "cmash_all.columns = [\"filename\"] + [c for c in cmash_all.columns[1:]]\n", "cmash_all.set_index(\"filename\", inplace=True)\n", "columns = [c for c in cmash_all.columns if str(ksize) not in c]\n", "cmash_all.drop(columns=columns, inplace=True)\n", "cmash_all.columns = [\"cmash all \"] + cmash_all.columns\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But... It seems the results are different than building one DB for each ksize, and querying only that ksize. In some cases, it's more than a 40% difference...\n", "\n", "According to https://github.com/dkoslicki/CMash/issues/15#issuecomment-608057130, for now I should stick with:\n", "> should only be used when the training database is constructed with a k-mer size of K and the StreamingQueryDNADatabase.py is called with the k-range of `K-K-1`.\n", "\n", "which is the case for this this one:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "cmash = pd.read_table(f\"../outputs/cmash/SRR606249-k{ksize}-n{num}.csv\", sep=\",\")\n", "cmash.columns = [\"filename\"] + [c for c in cmash.columns[1:]]\n", "cmash.set_index(\"filename\", inplace=True)\n", "columns = [c for c in cmash.columns if str(ksize) not in c]\n", "cmash.drop(columns=columns, inplace=True)\n", "cmash.columns = [\"cmash \"] + cmash.columns" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [ { "data": { "text/plain": [ "filename\n", "47.fa 0.010000\n", "39.fa 0.010000\n", "13.fa 0.011000\n", "21.fa 0.011000\n", "14.fa 0.013000\n", "30.fa 0.013000\n", "40.fa 0.014000\n", "18.fa 0.016000\n", "2.fa 0.016000\n", "46.fa 0.017000\n", "45.fa 0.017000\n", "27.fa 0.018000\n", "63.fa 0.023000\n", "64.fa 0.028000\n", "7.fa 0.032000\n", "44.fa 0.035000\n", "55.fa 0.041000\n", "23.fa 0.058000\n", "67.fa 0.065000\n", "4.fa 0.073000\n", "5.fa 0.073000\n", "3.fa 0.090000\n", "25.fa 0.095000\n", "66.fa 0.117000\n", "20.fa 0.121000\n", "35.fa 0.139325\n", "19.fa 0.144000\n", "33.fa 0.151000\n", "31.fa 0.164000\n", "58.fa 0.230000\n", "51.fa 0.233000\n", "6.fa 0.250000\n", "17.fa 0.272000\n", "32.fa 0.281000\n", "49.fa 0.383000\n", "16.fa 0.510000\n", "dtype: float64" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cmash_diff = np.abs(cmash_all[f\"cmash all k={ksize}\"] - cmash[f\"cmash k={ksize}\"])\n", "cmash_diff[cmash_diff > 0.01].sort_values()" ] }, { "cell_type": "code", "execution_count": 30, "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", "
cmash paper cmash all k=21 cmash k=21
64.fa0.0150000.0440000.016000
66.fa0.1810000.2980000.181000
67.fa0.1980000.2660000.201000
20.fa0.2290000.3500000.229000
6.fa0.9450000.7180000.468000
16.fa0.9620000.9880000.478000
23.fa0.9820000.5760000.518000
49.fa0.9830000.9260000.543000
19.fa0.6300000.7780000.634000
17.fa0.8190000.9100000.638000
51.fa0.9880001.0000000.767000
55.fa0.7750000.7440000.785000
33.fa0.9870000.9860000.835000
31.fa0.9870001.0000000.836000
32.fa0.9850000.6040000.885000
25.fa0.9880001.0000000.905000
3.fa0.9880000.9980000.908000
7.fa0.9360000.9760000.944000
58.fa0.9450000.7220000.952000
44.fa0.9560000.9940000.959000
63.fa0.9630000.9960000.973000
35.fa0.9900000.8376750.977000
27.fa0.9710000.9980000.980000
47.fa0.9710000.9900000.980000
45.fa0.9720000.9980000.981000
46.fa0.9720000.9980000.981000
30.fa0.9900001.0000000.987000
21.fa0.9900001.0000000.989000
13.fa0.9890001.0000000.989000
39.fa0.9900001.0000000.990000
56.fa0.9880001.0000000.991000
60.fa0.9890001.0000000.991000
24.fa0.9870001.0000000.993000
9.fa0.9890001.0000000.995000
15.fa0.9900001.0000000.995000
10.fa0.9890001.0000000.996000
57.fa0.9890001.0000000.997000
52.fa0.9890001.0000000.997000
37.fa0.9890001.0000000.997000
41.fa0.9900001.0000000.998000
50.fa0.9900001.0000000.998000
29.fa0.9900001.0000000.998000
0.fa0.9900001.0000000.998000
38.fa0.9880001.0000000.998000
62.fa0.9900001.0000000.999000
26.fa0.9890000.9980000.999000
5.fa0.9890000.9260000.999000
4.fa0.9900000.9260000.999000
48.fa0.9900001.0000000.999000
43.fa0.9900001.0000001.000000
22.fa0.9900001.0000001.000000
12.fa0.9900001.0000001.000000
54.fa0.9900000.9980001.000000
59.fa0.9900001.0000001.000000
61.fa0.9900001.0000001.000000
8.fa0.9900001.0000001.000000
11.fa0.9900001.0000001.000000
28.fa0.9900000.9960001.000000
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "def highlight_diff_from_cmash_paper(s):\n", " diff = np.abs(s - s[\"cmash paper\"])\n", " colorized = []\n", " for v in diff:\n", " if v < 0.01:\n", " colorized.append(\"background-color: white\")\n", " elif v < 0.05:\n", " colorized.append(\"background-color: yellow\")\n", " elif v < 0.10:\n", " colorized.append(\"background-color: orange\")\n", " else:\n", " colorized.append(\"background-color: red\")\n", " return colorized\n", "\n", "\n", "with pd.option_context(\"display.max_rows\", None, \"show_dimensions\", True):\n", " df = pd.concat((cmash_paper, cmash_all, cmash), axis=1).sort_values(by=f\"cmash k={ksize}\")\n", " df = df[df.apply(lambda x: any(np.abs(x - x[\"cmash paper\"]) > 0.01), axis=1)]\n", " display(df.style.apply(highlight_diff_from_cmash_paper, axis=1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Difference to exact (4-plots version)" ] }, { "cell_type": "code", "execution_count": 304, "metadata": {}, "outputs": [], "source": [ "def data_for_num(num):\n", " all_methods = []\n", " for k in (21, 31, 51):\n", " exact = pd.read_table(\n", " f\"../outputs/exact/SRR606249-k{k}.csv\",\n", " sep=\",\",\n", " header=None,\n", " names=(\"filename\", \"containment\", \"intersection\", \"|A|\"),\n", " usecols=(\"filename\", \"containment\"),\n", " )\n", " exact[\"filename\"] = exact[\"filename\"].str.replace(\n", " r\".*/(?P\\d+)-k\\d+.set\", lambda m: m.group(\"id\") + \".fa\"\n", " )\n", " exact.set_index(\"filename\", inplace=True) \n", " #all_methods.append(exact)\n", "\n", " smol = pd.read_table(\n", " f\"../outputs/smol_{scaled}/search-SRR606249-k{k}.csv\",\n", " sep=\",\",\n", " header=None,\n", " names=(\"filename\", \"containment\"),\n", " usecols=(\"filename\", \"containment\"),\n", " )\n", " smol[\"filename\"] = smol[\"filename\"].str.replace(\n", " r\".*/(?P\\d+).fa.*\", lambda m: m.group(\"id\") + \".fa\"\n", " )\n", " smol.set_index(\"filename\", inplace=True)\n", " smol['containment'] = exact[\"containment\"] - smol['containment']\n", " smol['method'] = 'smol'\n", " smol['k'] = k\n", "\n", " all_methods.append(smol)\n", "\n", " cmash_paper = pd.read_table(\n", " f\"../outputs/cmash_paper/SRR606249-k{ksize}-n{num}.csv\",\n", " sep=\",\",\n", " header=0,\n", " names=(\"filename\", \"intersection\", \"containment\", \"jaccard index\"),\n", " usecols=(\"filename\", \"containment\"),\n", " )\n", " cmash_paper.columns = [\"filename\"] + [c for c in cmash_paper.columns[1:]]\n", " cmash_paper[\"filename\"] = cmash_paper[\"filename\"].str.replace(\n", " r\".*/(?P\\d+).fa.*\", lambda m: m.group(\"id\") + \".fa\"\n", " )\n", " cmash_paper.set_index(\"filename\", inplace=True) \n", " cmash_paper['containment'] = exact[\"containment\"] - cmash_paper['containment']\n", " cmash_paper['method'] = 'cmash'\n", " cmash_paper['k'] = k\n", "\n", " all_methods.append(cmash_paper)\n", "\n", " if k <= 32: # mash doesn't support k>32\n", " mash_m1 = pd.read_table(\n", " f\"../outputs/mash_screen/SRR606249-k{k}-s{num}-m1.tsv\",\n", " header=None,\n", " names=(\n", " \"identity\",\n", " \"hashes\",\n", " \"median abundance\",\n", " \"p-value\",\n", " \"filename\",\n", " \"description\",\n", " ),\n", " usecols=[\"filename\", \"hashes\"],\n", " )\n", " mash_m1[\"filename\"] = mash_m1[\"filename\"].str.replace(\".*/\", \"\")\n", " mash_m1[\"containment\"] = mash_m1[\"hashes\"].apply(lambda x: eval(x))\n", " del mash_m1[\"hashes\"]\n", " mash_m1.set_index(\"filename\", inplace=True) \n", " mash_m1['containment'] = exact[\"containment\"] - mash_m1['containment']\n", " mash_m1['method'] = 'mash'\n", " mash_m1['k'] = k\n", "\n", " all_methods.append(mash_m1)\n", "\n", " return pd.concat(all_methods)" ] }, { "cell_type": "code", "execution_count": 305, "metadata": {}, "outputs": [], "source": [ "def plot_for_num(num):\n", " plot_df = data_for_num(num)\n", "\n", " with FigureManager(figsize=(18, 12), show=True, filename=f\"../figures/containment_{num}.pdf\", ncols=2, sharey=True) as (fig, ax):\n", " sns.boxenplot(x=\"k\", y=\"containment\", hue=\"method\", data=plot_df, ax=ax[0])\n", " ax[0].set_ylabel(f\"Difference to ground truth\")\n", " ax[0].set_title(f\"Difference in estimates, all genomes\")\n", " ax[0].text(0.5, 1.05, \"A\", transform=ax[0].transAxes, fontsize=22)\n", "\n", " sns.boxenplot(x=\"k\", y=\"containment\", hue=\"method\", data=plot_df.drop([f\"{i}.fa\" for i in low_coverage]), ax=ax[1])\n", " ax[1].set_ylabel(f\"\") \n", " ax[1].set_title(f\"Difference in estimates, excluding low coverage genomes\")\n", " ax[1].text(0.5, 1.05, \"B\", transform=ax[1].transAxes, fontsize=22) \n", " \n", " fig.tight_layout()" ] }, { "cell_type": "code", "execution_count": 361, "metadata": {}, "outputs": [], "source": [ "def plot_4():\n", " with FigureManager(figsize=(18, 18), show=True, filename=f\"../figures/containment-4.pdf\", ncols=2, nrows=2, sharey=True) as (fig, ax):\n", " plot_df = data_for_num(1000)\n", " sns.boxenplot(x=\"k\", y=\"containment\", hue=\"method\", data=plot_df, ax=ax[0,0])\n", " ax[0,0].set_ylabel(f\"Difference to ground truth\")\n", " ax[0,0].set_title(f\"n=1000, scaled=1000\")\n", " ax[0,0].text(0.5, 1.05, \"A\", transform=ax[0,0].transAxes, fontsize=22)\n", "\n", " sns.boxenplot(x=\"k\", y=\"containment\", hue=\"method\", data=plot_df.drop([f\"{i}.fa\" for i in low_coverage]), ax=ax[0,1])\n", " ax[0,1].set_ylabel(f\"\") \n", " ax[0,1].set_title(f\"n=1000, scaled=1000, excluding low coverage genomes\")\n", " ax[0,1].text(0.5, 1.05, \"B\", transform=ax[0,1].transAxes, fontsize=22) \n", "\n", " plot_df = data_for_num(10000)\n", " sns.boxenplot(x=\"k\", y=\"containment\", hue=\"method\", data=plot_df, ax=ax[1,0])\n", " ax[1,0].set_ylabel(f\"Difference to ground truth\")\n", " ax[1,0].set_title(f\"n=10000, scaled=1000\")\n", " ax[1,0].text(0.5, 1.05, \"C\", transform=ax[1,0].transAxes, fontsize=22)\n", "\n", " sns.boxenplot(x=\"k\", y=\"containment\", hue=\"method\", data=plot_df.drop([f\"{i}.fa\" for i in low_coverage]), ax=ax[1,1])\n", " ax[1,1].set_ylabel(f\"\") \n", " ax[1,1].set_title(f\"n=10000, scaled=1000, excluding low coverage genomes\")\n", " ax[1,1].text(0.5, 1.05, \"D\", transform=ax[1,1].transAxes, fontsize=22) \n", "\n", " fig.tight_layout()" ] } ], "metadata": { "kernelspec": { "display_name": "Python [conda env:thesis] *", "language": "python", "name": "conda-env-thesis-py" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.8" } }, "nbformat": 4, "nbformat_minor": 4 }