<jupyter_start><jupyter_text>Analysis of clonesig power to distinguish close clones better by leveraging signaturesThe objective of this notebook is to illustrate a proof of concept case of Clonesig. Indeed, by leveraging two types of information for each mutation, the VAF and the mutation type (in association with mutational signatures), Clonesig should have increased power to distinguish clones close in CCF if they have distinct mutational patterns. To illustrate that, we have simulated tumor samples with 2 clones, with 10 distinct CCF distance (between $0.03$ and $0.9$), 30 distinct mutational signatures mixtures, with cosine distance between the two profiles linearly spaced between $0$ and $0.8$. For each case, the number of mutations varies among $\{30, 100, 300, 1000\}$, the diploid proportion of the genome $\{0.1, 0.5, 0.9\}$, and the sequencing depth $\{100, 500\}$. We observe then in which cases Clonesig is able to detect 2 clones. We compare this distinguishing power to the other methods that account for both mutation frequencies and signatures: Palimpsest, TrackSig and TrackSigFreq.<jupyter_code>%matplotlib inline

import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.patches import Patch
import seaborn as sns
import numpy as np
import pandas as pd
import os
from statsmodels.stats.multitest import multipletests
from pathlib import Path

pd.options.display.max_columns = 200

method_color_dict = {'ccube': '#548ebb', 'clonesig': '#fc9d53',
                     'deconstructsigs':'#793d66', 'palimpsest':'#e45683',
                     'pyclone': '#87d0bd', 'sciclone': '#e1f5aa',
                     'tracksig': '#c4c3f9', 'tracksigfreq': '#8942fc'}
hatch_dict = {'prefit': '/', 'cancertype': '.', 'cancer_type': '.',
             'all': '', 'all_nuclonal': '+'}
sns.set_context("poster", font_scale=2)
mpl.rcParams['hatch.linewidth'] = 3
pd.options.display.max_columns = 200
os.chdir('..')
output_path = '20200515_paper_figures/power_eval'
Path(output_path).mkdir(parents=True, exist_ok=True)
import warnings
warnings.filterwarnings("ignore")
from IPython.display import HTML

HTML('''<script>
code_show=true; 
function code_toggle() {
 if (code_show){
 $('div.input').hide();
 } else {
 $('div.input').show();
 }
 code_show = !code_show
} 
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Click here to toggle on/off the raw code."></form>''')
clonesig_res = pd.read_csv('20200513_eval_clonesig_power_2clones.csv', sep='\t')
clonesig_res = clonesig_res.assign(phi_dist=np.round(clonesig_res.phi_dist, 2))
clonesig_res = clonesig_res.assign(min_dist=np.round(clonesig_res.min_dist, 2))

clonesig_res.head()
clonesig_res = clonesig_res.assign(qmin_dist=pd.qcut(clonesig_res.min_dist, 10, labels=False))
clonesig_res_ = pd.merge(clonesig_res, clonesig_res.groupby('qmin_dist').min_dist.mean().round(2), left_on='qmin_dist', right_index=True)
#clonesig_res_.head()
uu=pd.pivot_table(index='phi_dist', columns='min_dist_y', values='score2C_auc', aggfunc='mean', data=clonesig_res_[clonesig_res_.method=="clonesig"]).sort_index(ascending=False)
uu
#uu=pd.pivot_table(index='phi_dist', columns='min_dist', values='accuracy', aggfunc='mean', data=clonesig_res)
sns.set_context('talk')
plt.figure(figsize=(10, 4))
ax=sns.heatmap(uu, cmap='PuOr_r', vmin=0.5, vmax=1, cbar_kws={'label': 'score2C_AUC'})
ax.set_xlabel("Cosine distance between\n the two clones signatures")
ax.set_ylabel("CCF difference\n between the two clones")
plt.savefig('{}/clonesig_separation_power.pdf'.format(output_path), bbox_inches='tight')

uu=pd.pivot_table(index='phi_dist', columns='nb_mut', values='score2C_auc', aggfunc='mean', data=clonesig_res_[clonesig_res_.method=="clonesig"]).sort_index(ascending=False)
sns.set_context('talk')
plt.figure(figsize=(12, 5))
ax=sns.heatmap(uu, cmap='PuOr_r', vmin=0.5, vmax=1, cbar_kws={'label': 'score2C_AUC'})
ax.set_xlabel("Number of observed mutations")
ax.set_ylabel("CCF difference\n between the two clones")
plt.savefig('{}/clonesig_separation_power_nbmut.pdf'.format(output_path), bbox_inches='tight')

uu=pd.pivot_table(index='phi_dist', columns='perc_diploid', values='score2C_auc', aggfunc='mean', data=clonesig_res_[clonesig_res_.method=="clonesig"]).sort_index(ascending=False)
sns.set_context('talk')
plt.figure(figsize=(12, 5))
ax=sns.heatmap(uu, cmap='PuOr_r', vmin=0.5, vmax=1, cbar_kws={'label': 'score2C_AUC'})

ax.set_xlabel("Diploid proportion of the genome")
ax.set_ylabel("CCF difference\n between the two clones")
plt.savefig('{}/separation_power_perc_dip.pdf'.format(output_path), bbox_inches='tight')

uu=pd.pivot_table(index='phi_dist', columns='depth', values='score2C_auc', aggfunc='mean', data=clonesig_res_[clonesig_res_.method=="clonesig"]).sort_index(ascending=False)
sns.set_context('talk')
plt.figure(figsize=(12, 5))
ax=sns.heatmap(uu, cmap='PuOr_r', vmin=0.5, vmax=1, cbar_kws={'label': 'score2C_AUC'})

ax.set_xlabel("Sequencing depth")
ax.set_ylabel("CCF difference\n between the two clones")
plt.savefig('{}/clonesig_separation_power_depth.pdf'.format(output_path), bbox_inches='tight')

uu=pd.pivot_table(index='phi_dist', columns='setting', values='score2C_auc', aggfunc='mean', data=clonesig_res_[clonesig_res_.method=="clonesig"]).sort_index(ascending=False)
sns.set_context('talk')
plt.figure(figsize=(12, 5))
ax=sns.heatmap(uu, cmap='PuOr_r', vmin=0.5, vmax=1, cbar_kws={'label': 'score2C_AUC'})

ax.set_xlabel("Input signature setting")
ax.set_ylabel("CCF difference\n between the two clones")
plt.savefig('{}/clonesig_separation_power_setting.pdf'.format(output_path), bbox_inches='tight')

clonesig_res = clonesig_res.assign(qmin_dist=pd.qcut(clonesig_res.min_dist, 10, labels=False))
clonesig_res_ = pd.merge(clonesig_res, clonesig_res.groupby('qmin_dist').min_dist.mean().round(2), left_on='qmin_dist', right_index=True)
aa=clonesig_res_.dropna(subset=['score2C_auc']).groupby(['nb_pi', 'nb_phi', 'depth', 'perc_diploid', 'nb_clones', 'nb_mut']).method.nunique().to_frame().reset_index()
aa = aa.assign(nb_method=aa.method).drop(columns=['method'])
clonesig_res_complete = pd.merge(clonesig_res_, aa, on=['nb_pi', 'nb_phi', 'depth', 'perc_diploid', 'nb_clones', 'nb_mut'])
clonesig_res_filter = clonesig_res_complete[clonesig_res_complete.nb_method==4]


method_name_dict = {'clonesig': 'CloneSig', 'tracksig': 'TrackSig',
                    'tracksigfreq': 'TrackSigFreq',
                    'palimpsest': 'Palimpsest'}



for method in ('clonesig', 'tracksig', 'tracksigfreq', 'palimpsest'):
    uu_1000=pd.pivot_table(index='phi_dist', columns='min_dist_y', values='score2C_auc', aggfunc='mean', data=clonesig_res_filter[(clonesig_res_filter.method==method)&(clonesig_res_filter.nb_mut==1000)]).sort_index(ascending=False)
    sns.set_context('talk')
    plt.figure(figsize=(10, 4))
    ax=sns.heatmap(uu_1000, cmap='PuOr_r', vmin=0.5, vmax=1, cbar_kws={'label': 'score2C_AUC'})
    ax.set_xlabel("Cosine distance between\n the two clones signatures")
    ax.set_ylabel("CCF difference\n between the two clones")
    ax.set_title('method {} 1000 mutations'.format(method_name_dict[method]))
    plt.savefig('{}/{}_separation_power_1000.pdf'.format(output_path, method),
                bbox_inches='tight')

for method in ('clonesig', 'tracksig', 'tracksigfreq', 'palimpsest'):
    uu_mut=pd.pivot_table(index='phi_dist', columns='nb_mut', values='score2C_auc', aggfunc='mean', data=clonesig_res_filter[(clonesig_res_filter.method==method)]).sort_index(ascending=False)
    sns.set_context('talk')
    plt.figure(figsize=(10, 4))
    ax=sns.heatmap(uu_mut, cmap='PuOr_r', vmin=0.5, vmax=1, cbar_kws={'label': 'score2C_AUC'})
    ax.set_xlabel("Number of observed mutations")
    ax.set_ylabel("CCF difference\n between the two clones")
    ax.set_title('method {}'.format(method_name_dict[method]))
    plt.savefig('{}/{}_separation_power_nb_mut_comp.pdf'.format(output_path, method),
                bbox_inches='tight')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1558570895057886, 'fraction_numerical': 0.022034109299141045, 'mean_word_length': 7.050100200400801, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '614696', 'license': 'CC-BY-4.0', 'n_tokens_mistral': 3101, 'n_tokens_neox': 2880, 'n_words': 535, 'path': 'paper_notebooks/clonesig_separation_power.ipynb', 'repo_name': 'judithabk6/Clonesig_analysis', 'size': '8033'}