diff --git a/bean/cli/execute.py b/bean/cli/execute.py index d9288d5..5917bd9 100755 --- a/bean/cli/execute.py +++ b/bean/cli/execute.py @@ -1,7 +1,7 @@ import argparse from bean.mapping.utils import get_input_parser_count as get_count_parser from bean.mapping.utils import get_input_parser as get_count_samples_parser -from bean.plotting.utils import parse_args as get_profile_parser +from bean.plotting.parser import parse_args as get_profile_parser from bean.qc.parser import parse_args as get_qc_parser from bean.annotate.utils import parse_args as get_filter_parser from bean.model.parser import parse_args as get_run_parser diff --git a/bean/cli/profile.py b/bean/cli/profile.py index 6336819..c780ccc 100755 --- a/bean/cli/profile.py +++ b/bean/cli/profile.py @@ -2,7 +2,7 @@ import os import papermill as pm import bean as be -from bean.plotting.utils import parse_args, check_args +from bean.plotting.utils import check_args def main(args): diff --git a/bean/notebooks/profile_editing_preference.ipynb b/bean/notebooks/profile_editing_preference.ipynb index 05dae33..ca4289f 100755 --- a/bean/notebooks/profile_editing_preference.ipynb +++ b/bean/notebooks/profile_editing_preference.ipynb @@ -34,7 +34,6 @@ "import matplotlib.pyplot as plt\n", "import matplotlib.patches as patches\n", "import seaborn as sns\n", - "import logomaker\n", "\n", "import bean as be\n", "from bean import Edit\n", @@ -101,11 +100,7 @@ ], "source": [ "cdata.samples[\"replicate\"] = cdata.samples[replicate_col]\n", - "cdata_bulk = cdata[:,cdata.samples[condition_col] == control_condition]\n", - "if len(cdata_bulk) == 0:\n", - " raise ValueError(\n", - " f\"No samples with bdata.samples['{condition_col}'] == {control_condition}\"\n", - " )" + "cdata_bulk = cdata[:,cdata.samples[condition_col] == control_condition]" ] }, { @@ -681,35 +676,24 @@ }, { "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "cedit_rates_df_ag = cedit_rates_df.loc[cedit_rates_df.base_change == cdata_bulk.uns['target_base_change'],:].reset_index(drop=True)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, + "execution_count": 1, "metadata": {}, "outputs": [ { - "data": { - "image/png": "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ruUWSxIHALp4Pbhv5hZaF1hmYUBERHRfFloZsDAgIiLSoyGfrmhOzOKuhLCwsBrPjv77cvDgQQDAN998g379+kGtVsPV1RWjR49GamqqaZMnIiJqQsyiMFi6dCmysrKQlZWFmJgYtGrVSvs6KysLQUFBWLp0KZ577jkMHz4cx48fx969e6FSqdC3b1+DHxBBRER0PzKZ8UtjZhZdCdUPmKj+b2tra7i7u2u3X7lyBeHh4VizZg0mTJigXb9u3ToEBgYiKioK69evb/C8iYio6Wrkn+9GM4vC4H4SEhLg4uJS4wEQVlZWiI+Ph0Ih3b3fREREACy2MmgUhcHZs2fRo0cPvXNGd+zY0QQZERFRU2epgw8bRWGQl5en9wFKRERED0pjHytgrEZRGLi4uODWrVtGHavRaGo857pMo4FdHR+HSUREZEnM4q6E++nRowfOnDkDfY912LBhA1566aVaj42OjtYObqxe4lcufpDpEhFRE9BQj102N42iMHj22Wdx8+ZNJCQk6KyvrKzEokWLUFRU+5SfERERyM/P11lCp8560CkTEVFjZ6GVQaPoSvD29sa8efMwadIk/PHHHxg+fDhu3bqFDz/8EJcvX8ZXX31V67FyuRzyu7oN7OQW90BJIiIykKUOPmwULQYA8Pbbb+Pzzz/HV199hR49euDpp5+GtbU1jh49Cl9fX1OnR0RETQwnODITYWFhCAsL07vthRdewAsvvNCwCRERkUVq5J/vRms0LQZERET04JldiwEREZFZsNAmAxYGREREeljq4EMWBkRERHo09kGExrLIwqCiqkqSOEVl0sQBAKWddP8UP13MliROfl6JJHEAIP1yjiRxWg5pL0kcAPj+snGzaerTxV0lSZxrt4oliQMAChtrSeK4OUg3S2hhaYVksRS20pyfjbV07/45hZr771QHSjtpzg0AWrtIc20CQElZpSRxXJs3jplnLbQusMzCgIiI6L4stDLgXQlERESkZfLCICwsDDKZrNbl4MGDAICDBw9i2LBhcHV1hUKhwCOPPIJFixahSqJuASIior+T1eN/jZnJC4OlS5ciKysLWVlZiImJQatWrbSvs7KyEBQUhPj4eAwaNAjt2rXDvn378Msvv2DOnDlYsmQJZs6caepTICKiJshSZz40eWGgVqvh7u4Od3d3qNVqWFtba1+7u7vj1q1bmDFj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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" + "ename": "IndentationError", + "evalue": "unexpected indent (4025401070.py, line 7)", + "output_type": "error", + "traceback": [ + "\u001b[1;36m Input \u001b[1;32mIn [1]\u001b[1;36m\u001b[0m\n\u001b[1;33m pos_by_pam = be.pl.editing_patterns.plot_by_pos_pam(cdata_bulk, cedit_rates_df_ag, pam_col, ax=axes[i])\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mIndentationError\u001b[0m\u001b[1;31m:\u001b[0m unexpected indent\n" + ] } ], "source": [ + "target_base_changes = cdata_bulk.uns['target_base_changes'].split(',')\n", "if pam_col is not None:\n", - " pos_by_pam = be.pl.editing_patterns.plot_by_pos_pam(cdata_bulk, cedit_rates_df_ag, pam_col)\n", - " if save_fig: \n", - " plt.savefig(f\"{output_prefix}_pos_by_pam.pdf\", bbox_inches = 'tight')\n", - " pos_by_pam.to_csv(f\"{output_prefix}_pos_by_pam.csv\")" + " be.pl.editing_patterns.plot_by_pos_pam(cdata_bulk, cedit_rates_df, target_base_changes, pam_col, save_fig=save_fig, save_path=\"{output_prefix}_pos_by_pam.pdf\")\n", + "else:\n", + " print(\"--pam-col not provided to `bean profile` so skipping the PAM by position output.\")" ] }, { @@ -726,111 +710,6 @@ "Draw relative editing efficiency +1 and -1 the positions. Note that the confidence of the result may depend on how diverse your libray is in terms of sequence context around edits." ] }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [], - "source": [ - "cedit_rates_df_ag_window = cedit_rates_df_ag.loc[(cedit_rates_df_ag.spacer_pos >= window_start) & (cedit_rates_df_ag.spacer_pos <= window_end)].copy()" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [], - "source": [ - "cedit_rates_df_ag_window[\"context\"] = cedit_rates_df_ag_window.apply(\n", - " lambda row: cdata_bulk.guides.loc[row.guide, \"reporter\"][\n", - " row.rel_pos - 1 : row.rel_pos + 2\n", - " ],\n", - " axis=1,\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [], - "source": [ - "con_mean_er = {}\n", - "bases = [\"A\", \"C\", \"G\", \"T\"]\n", - "\n", - "for i in range(3):\n", - "\n", - " cedit_rates_df_ag_window[f\"context_{i}\"] = cedit_rates_df_ag_window.context.map(lambda s: s[i])\n", - "\n", - " con_mean_er[i] = cedit_rates_df_ag_window.groupby(f\"context_{i}\")[\"rep_mean\"].mean()\n", - " con_mean_er[i] = con_mean_er[i].reindex(bases).fillna(0)" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{0: context_0\n", - " A 0.176958\n", - " C 0.410452\n", - " G 0.252429\n", - " T 0.566291\n", - " Name: rep_mean, dtype: float64,\n", - " 1: context_1\n", - " A 0.32484\n", - " Name: rep_mean, dtype: float64,\n", - " 2: context_2\n", - " A 0.271765\n", - " C 0.359757\n", - " G 0.319412\n", - " T 0.339770\n", - " Name: rep_mean, dtype: float64}" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "con_mean_er" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "target_df = pd.DataFrame([int(b == cdata_bulk.uns[\"target_base_change\"][0]) for b in bases], index=bases)\n", - "ic_tbl = pd.concat(\n", - " [\n", - " con_mean_er[0] / con_mean_er[0].sum(),\n", - " target_df,\n", - " con_mean_er[2] / con_mean_er[2].sum(),\n", - " ],\n", - " axis=1,\n", - ").T\n", - "\n", - "ic_tbl.index = [-1, 0, 1]" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [], - "source": [ - "ic_tbl.to_csv(f\"{output_prefix}_context.csv\")" - ] - }, { "cell_type": "code", "execution_count": 32, @@ -862,19 +741,16 @@ } ], "source": [ - "fig, ax = plt.subplots(figsize=(3,5))\n", - "\n", - "logomaker.Logo(ic_tbl, ax = ax)\n", - "ax.set_ylabel(\"Relative frequency\")\n", - "if save_fig: fig.savefig(f\"{output_prefix}_context_preference_{window_start}_{window_end}.pdf\")" + "context_tbl = be.pl.editing_patterns.plot_context_specificity(cdata_bulk, cedit_rates_df, target_base_changes=target_base_changes, window=(window_start, window_end), save_fig = save_fig, save_path = f\"{output_prefix}_context_preference_{window_start}_{window_end}.pdf\")\n", + "context_tbl.to_csv(f\"{output_prefix}_context.csv\")" ] } ], "metadata": { "kernelspec": { - "display_name": "jy_18loci", + "display_name": "Python 3", "language": "python", - "name": "jy_18loci" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -886,12 +762,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.12" - }, - "vscode": { - "interpreter": { - "hash": "4c3e1e0b99f5a0cffad18f6b0783b802f97f2dc306eb180584fe828b9d35f6d8" - } + "version": "3.9.13" } }, "nbformat": 4, diff --git a/bean/plotting/editing_patterns.py b/bean/plotting/editing_patterns.py index 95e7f75..3b6c9ea 100755 --- a/bean/plotting/editing_patterns.py +++ b/bean/plotting/editing_patterns.py @@ -1,11 +1,13 @@ from copy import deepcopy -from typing import Optional, Sequence, Dict, List, Union +from typing import Optional, Sequence, Dict, List, Union, Tuple import re -from ..framework.Edit import Edit +from bean import ReporterScreen +from bean.framework.Edit import Edit import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns +import logomaker from tqdm.auto import tqdm BASES = ["A", "T", "C", "G"] @@ -330,14 +332,16 @@ def plot_by_pos_behive( return axes, df -def get_position_by_pam_rates(bdata, edit_rates_df: pd.DataFrame, pam_col="5-nt PAM"): +def get_position_by_pam_rates( + bdata, edit_rates_df: pd.DataFrame, target_base_change: str, pam_col="5-nt PAM" +): edit_rates_df["pam"] = bdata.guides.loc[edit_rates_df.guide, pam_col].reset_index( drop=True ) edit_rates_df["pam23"] = edit_rates_df.pam.map(lambda s: s[1:3]) return pd.pivot( edit_rates_df.loc[ - (edit_rates_df.base_change == bdata.target_base_change), + (edit_rates_df.base_change == target_base_change), ["rep_mean", "pam23", "spacer_pos"], ] .groupby(["pam23", "spacer_pos"]) @@ -350,53 +354,42 @@ def get_position_by_pam_rates(bdata, edit_rates_df: pd.DataFrame, pam_col="5-nt def plot_by_pos_pam( - bdata, - edit_rates_df, - pam_col="5-nt PAM", - ax=None, - figsize=(6, 4), -): - """Plot position by PAM""" - pos_by_pam = get_position_by_pam_rates(bdata, edit_rates_df, pam_col) - if ax is None: - fig, ax = plt.subplots(figsize=figsize) - sns.heatmap(pos_by_pam, ax=ax, cmap="Blues") - ax.set_yticklabels(ax.get_yticklabels(), rotation=0) - return pos_by_pam - - -def plot_by_pos_pam_and_context(bdata, edit_rates_df, figsize=(6, 6)): - pos_by_pam = get_position_by_pam_rates(bdata, edit_rates_df) - fig, ax = plt.subplots(2, 1, figsize=figsize) - sns.scatterplot( - edit_rates_df.loc[(edit_rates_df.base_change == bdata.target_base_change)], - x="spacer_pos_ctxt", - y="rep_mean", - hue="context", - alpha=0.3, - ax=ax[0], - s=5, - rasterized=True, - ) - ax[0].legend(bbox_to_anchor=(1.02, 0.5), loc="center left", title="Context") - ax[0].set_xlabel("Protospacer position") - ax[0].set_xticks(list(range(1, 21))) - ax[0].set_xticklabels(list(range(1, 21))) - ax[0].set_ylabel(f"{bdata.target_base_change} editing rate") - ax[0].set_ylim((0, 1)) - ax[0].set_xlim((0.5, 20.5)) - - sns.heatmap(pos_by_pam, ax=ax[1], cmap="Blues", cbar=False) - ax[1].set_yticklabels(ax[1].get_yticklabels(), rotation=0) - cbax = fig.add_axes( - [0.85, 0.15, 0.02, 0.3], - ) - ax[1].set_ylabel("PAM") - ax[1].set_yticklabels([f"N{t.get_text()}" for t in ax[1].get_yticklabels()]) - ax[1].set_xlabel("Protospacer position") - fig.colorbar(ax[1].get_children()[0], cbax, label="editing rate") - plt.tight_layout() - return ax + bdata: ReporterScreen, + edit_rates_df: pd.DataFrame, + target_base_changes: List[str], + pam_col: str = "5-nt PAM", + axes=None, + figsize: Tuple[float, float] = (6, 4), + save_fig: bool = False, + save_path: Optional[str] = None, +) -> pd.DataFrame: + """Plot editing efficiency for each position x PAM combination.""" + if axes is None: + fig, axes = plt.subplots( + 1, + len(target_base_changes), + figsize=(figsize[0] * len(target_base_changes), figsize[1]), + ) + if len(target_base_changes) == 1: + axes = np.array([axes]) + pos_by_pam_basechanges = [] + for i, target_base_change in enumerate(target_base_changes): + edit_rates_df_base = edit_rates_df.loc[ + edit_rates_df.base_change == target_base_change, : + ].reset_index(drop=True) + pos_by_pam = get_position_by_pam_rates( + bdata, edit_rates_df_base, target_base_change, pam_col + ) + sns.heatmap(pos_by_pam, ax=axes[i], cmap="Blues") + axes[i].set_yticklabels(axes[i].get_yticklabels(), rotation=0) + axes[i].set_title(target_base_change) + pos_by_pam["base_change"] = target_base_change + pos_by_pam_basechanges.append(pos_by_pam) + if save_fig: + if save_path is None: + save_path = "bean_profile_pos_by_pam.pdf" + plt.savefig(save_path, bbox_inches="tight") + return pd.concat(pos_by_pam_basechanges, axis=0) def get_pam_preference( @@ -461,3 +454,78 @@ def plot_pam_preference( ax.set(xlabel=None, ylabel=None) ax.set_title("PAM preference") return ax + + +def plot_context_specificity( + bdata: ReporterScreen, + edit_rates_df: pd.DataFrame, + target_base_changes: List[str], + window: Tuple[int, int], + axes=None, + figsize: Tuple[float, float] = (3, 5), + save_fig: bool = False, + save_path: Optional[str] = None, +) -> pd.DataFrame: + window_start, window_end = window + if axes is None: + fig, axes = plt.subplots( + 1, + len(target_base_changes), + figsize=(figsize[0] * len(target_base_changes), figsize[1]), + ) + if len(target_base_changes) == 1: + axes = np.array([axes]) + save_tbls = [] + for j, target_base_change in enumerate(target_base_changes): + edit_rates_df_base = edit_rates_df.loc[ + edit_rates_df.base_change == target_base_change, : + ].reset_index(drop=True) + edit_rates_df_base_window = edit_rates_df_base.loc[ + (edit_rates_df_base.spacer_pos >= window_start) + & (edit_rates_df_base.spacer_pos <= window_end) + ].copy() + edit_rates_df_base_window["context"] = edit_rates_df_base_window.apply( + lambda row: bdata.guides.loc[row.guide, "reporter"][ + row.rel_pos - 1 : row.rel_pos + 2 + ], + axis=1, + ) + context_mean_edit_rate = {} + bases = ["A", "C", "G", "T"] + + for i in range(3): + edit_rates_df_base_window[f"context_{i}"] = ( + edit_rates_df_base_window.context.map(lambda s: s[i]) + ) + context_mean_edit_rate[i] = edit_rates_df_base_window.groupby( + f"context_{i}" + )["rep_mean"].mean() + context_mean_edit_rate[i] = ( + context_mean_edit_rate[i].reindex(bases).fillna(0) + ) + + target_df = pd.DataFrame( + [int(b == target_base_change[0]) for b in bases], index=bases + ) + ic_tbl = pd.concat( + [ + context_mean_edit_rate[0] / context_mean_edit_rate[0].sum(), + target_df, + context_mean_edit_rate[2] / context_mean_edit_rate[2].sum(), + ], + axis=1, + ).T + save_tbl = ic_tbl.transpose() + save_tbl["base_change"] = target_base_change + save_tbls.append(save_tbl) + ic_tbl.index = [-1, 0, 1] + logomaker.Logo(ic_tbl.astype(float), ax=axes[j]) + axes[j].set_ylabel("Relative frequency") + axes[j].set_title(target_base_change) + if save_fig: + if save_path is None: + save_path = ( + f"bean_profile_context_preference_{window_start}_{window_end}.pdf" + ) + fig.savefig(save_path, bbox_inches="tight") + return pd.concat(save_tbls, axis=0) diff --git a/bean/plotting/utils.py b/bean/plotting/utils.py index 4553fa9..897d0c8 100755 --- a/bean/plotting/utils.py +++ b/bean/plotting/utils.py @@ -1,58 +1,6 @@ import argparse import os - - -def parse_args(parser=None): - if parser is None: - parser = argparse.ArgumentParser() - parser.add_argument( - "bdata_path", help="Path to the ReporterScreen object to run QC on", type=str - ) - parser.add_argument( - "-o", - "--output-prefix", - help="Output prefix of editing pattern report (prefix.html, prefix.ipynb). If not provided, base name of `bdata_path` is used.", - type=str, - ) - parser.add_argument( - "--replicate-col", - help="Column name in `bdata.samples` that describes replicate ID.", - type=str, - default="replicate", - ) - parser.add_argument( - "--condition-col", - help="Column name in `bdata.samples` that describes experimental condition. (sorting bin, time, etc.)", - type=str, - default="condition", - ) - parser.add_argument( - "--pam-col", - help="Column name describing PAM of each gRNA in `bdata.guides`.", - type=str, - default=None, - ) - parser.add_argument( - "--control-condition", - help="Control condition where editing preference would be profiled at. Pre-filters data where `bdata.samples[condition_col] == control_condition`.", - type=str, - default="bulk", - ) - parser.add_argument( - "-w", - "--window-length", - help="Window length of editing window of maximal editing efficiency to be identified. This window is used to quantify context specificity within the window.", - type=int, - default=6, - ) - parser.add_argument( - "--save-fig", - action="store_true", - help="Save .pdf of the figures included in the report.", - ) - - return parser - +import bean as be def check_args(args): if args.output_prefix is None: @@ -63,6 +11,15 @@ def check_args(args): os.makedirs(args.output_prefix, exist_ok=True) if args.window_length < 1: raise ValueError(f"window_length {args.window_length} is too small.") - if args.window_length > 20: - raise ValueError(f"window_length {args.window_length} is too large.") + cdata = be.read_h5ad(args.bdata_path) + cdata.samples["replicate"] = cdata.samples[args.replicate_col] + cdata_bulk = cdata[:,cdata.samples[args.condition_col] == args.control_condition] + if len(cdata_bulk) == 0: + raise ValueError( + f"No samples with bdata.samples['{args.condition_col}'] == {args.control_condition}. Please check your input arguments --condition-col & --control-condition." + ) + if args.pam_col is not None and args.pam_col not in cdata.guides.columns: + raise ValueError( + f"Specified --pam-col `{args.pam_col}` does not exist in ReporterScreen.guides.columns ({cdata.guides.columns}). Please check your input. If you don't want PAM output, please do not provide --pam-col argument.s" + ) return args diff --git a/docs/profile.rst b/docs/profile.rst index 7d79464..ac8ba6e 100755 --- a/docs/profile.rst +++ b/docs/profile.rst @@ -7,6 +7,6 @@ Full parameters ================== .. argparse:: - :filename: ../bean/plotting/utils.py + :filename: ../bean/plotting/parser.py :func: parse_args :prog: bean profile \ No newline at end of file diff --git a/tests/data/var_mini_screen.h5ad b/tests/data/var_mini_screen.h5ad index cd6e680..cbac52b 100755 Binary files a/tests/data/var_mini_screen.h5ad and b/tests/data/var_mini_screen.h5ad differ diff --git a/tests/test_profile.py b/tests/test_profile.py index 98261aa..cd5c7cd 100644 --- a/tests/test_profile.py +++ b/tests/test_profile.py @@ -3,7 +3,7 @@ def test_profile_screen(): - cmd = "bean profile tests/data/var_mini_screen.h5ad " + cmd = "bean profile tests/data/var_mini_screen.h5ad --pam-col '5-nt PAM'" try: subprocess.check_output( cmd, @@ -13,8 +13,9 @@ def test_profile_screen(): except subprocess.CalledProcessError as exc: raise exc + def test_profile_screen_dualeditor(): - cmd = "bean profile tests/data/var_mini_screen_dual.h5ad " + cmd = "bean profile tests/data/var_mini_screen_dual.h5ad --pam-col '5-nt PAM'" try: subprocess.check_output( cmd, @@ -22,4 +23,4 @@ def test_profile_screen_dualeditor(): universal_newlines=True, ) except subprocess.CalledProcessError as exc: - raise exc \ No newline at end of file + raise exc